aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Hassan Abouelela <[email protected]>2023-03-15 04:52:51 +0400
committerGravatar Hassan Abouelela <[email protected]>2023-03-15 04:52:51 +0400
commitbc4981b85de45a858cf60ff511cae6d0f474a1ef (patch)
tree2eef466d202eea17f390db5d5b00970c6971c5c9
parentAdd Multi-version Capability (diff)
Add Multiple Version Eval To API
Adds a version argument to the eval API, and a GET endpoint to retrieve all enabled versions. Signed-off-by: Hassan Abouelela <[email protected]>
-rw-r--r--pyproject.toml2
-rw-r--r--snekbox/api/resources/eval.py40
-rw-r--r--snekbox/nsjail.py9
3 files changed, 48 insertions, 3 deletions
diff --git a/pyproject.toml b/pyproject.toml
index a0ccf8a..a258843 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -70,5 +70,5 @@ force-exclude = "snekbox/config_pb2.py"
line_length = 100
profile = "black"
skip_gitignore = true
-src_paths = ["snekbox"]
+src_paths = ["snekbox", "scripts"]
extend_skip = ["snekbox/config_pb2.py"]
diff --git a/snekbox/api/resources/eval.py b/snekbox/api/resources/eval.py
index 9a53577..30f95ab 100644
--- a/snekbox/api/resources/eval.py
+++ b/snekbox/api/resources/eval.py
@@ -9,10 +9,13 @@ from snekbox.nsjail import NsJail
__all__ = ("EvalResource",)
+from scripts.python_version import get_all_versions
from snekbox.snekio import FileAttachment, ParsingError
log = logging.getLogger(__name__)
+_VERSION_DISPLAY_NAMES = [version.display_name for version in get_all_versions()[0]]
+
class EvalResource:
"""
@@ -29,6 +32,10 @@ class EvalResource:
"properties": {
"input": {"type": "string"},
"args": {"type": "array", "items": {"type": "string"}},
+ "version": {
+ "type": "string",
+ "oneOf": [{"const": name} for name in _VERSION_DISPLAY_NAMES],
+ },
"files": {
"type": "array",
"items": {
@@ -54,6 +61,29 @@ class EvalResource:
def __init__(self, nsjail: NsJail):
self.nsjail = nsjail
+ @validate(
+ resp_schema={
+ "versions": {"type": "array", "items": {"type": "str"}},
+ }
+ )
+ def on_get(self, _: falcon.Request, resp: falcon.Response) -> None:
+ """
+ Get information about the server.
+
+ Response format:
+ >>> {
+ ... "versions": ["Python 3.9", "Python 3.10", "Python 3.12 Beta 1"]
+ ... }
+
+ Status codes:
+
+ - 200
+ Success.
+ """
+ resp.media = {
+ "versions": _VERSION_DISPLAY_NAMES,
+ }
+
@validate(REQ_SCHEMA)
def on_post(self, req: falcon.Request, resp: falcon.Response) -> None:
"""
@@ -123,10 +153,20 @@ class EvalResource:
if "input" in body:
body.setdefault("args", ["-c"])
body["args"].append(body["input"])
+
+ # Parse a version from the request body, or use the default version
+ all_versions, selected_version = get_all_versions()
+ if "version" in body:
+ for version in all_versions:
+ if version.display_name == body["version"]:
+ selected_version = version
+ break
+
try:
result = self.nsjail.python3(
py_args=body["args"],
files=[FileAttachment.from_dict(file) for file in body.get("files", [])],
+ version=selected_version,
)
except ParsingError as e:
raise falcon.HTTPBadRequest(title="Request file is invalid", description=str(e))
diff --git a/snekbox/nsjail.py b/snekbox/nsjail.py
index f014850..d3417b4 100644
--- a/snekbox/nsjail.py
+++ b/snekbox/nsjail.py
@@ -9,6 +9,7 @@ from typing import Iterable, TypeVar
from google.protobuf import text_format
+from scripts.python_version import Version
from snekbox import DEBUG, utils
from snekbox.config_pb2 import NsJailConfig
from snekbox.filesystem import Size
@@ -177,6 +178,7 @@ class NsJail:
def python3(
self,
py_args: Iterable[str],
+ version: Version,
files: Iterable[FileAttachment] = (),
nsjail_args: Iterable[str] = (),
) -> EvalResult:
@@ -185,6 +187,7 @@ class NsJail:
Args:
py_args: Arguments to pass to Python.
+ version: The python version to perform the eval with.
files: FileAttachments to write to the sandbox prior to running Python.
nsjail_args: Overrides for the NsJail configuration.
"""
@@ -218,10 +221,12 @@ class NsJail:
self.config_path,
"--log",
nsj_log.name,
+ "-E",
+ f"PYTHONPATH=/snekbox/user_base/lib/python{version.version_name}/site-packages",
*nsjail_args,
"--",
- self.config.exec_bin.path,
- *self.config.exec_bin.arg,
+ f"/usr/local/bin/python{version.version_name}",
+ *["-BSqu"],
# Filter out empty strings at start of py_args
# (causes issues with python cli)
*iter_lstrip(py_args),