Spaces:
Sleeping
Sleeping
Download server/api/helper/code_runner.py from VashuTheGreat2/ML-Learner: direct link, hf CLI and curl.
- Browser
- Download file 3.9 kB
-
https://huggingface.co/spaces/VashuTheGreat2/ML-Learner/resolve/main/server/api/helper/code_runner.py
- Command line
-
hf download hf://spaces/VashuTheGreat2/ML-Learner/server/api/helper/code_runner.py
-
curl -L -o code_runner.py https://huggingface.co/spaces/VashuTheGreat2/ML-Learner/resolve/main/server/api/helper/code_runner.py
3.9 kB
| import subprocess | |
| import json | |
| from fastapi import HTTPException | |
| from sqlalchemy.orm import Session | |
| from db import Question | |
| from api.models.coding_models import RunCode | |
| # =========================== Helper function to run user code ================= | |
| async def code_runner(body: RunCode, db: Session): | |
| question = ( | |
| db.query(Question) | |
| .filter(Question.id == body.question_id) | |
| .first() | |
| ) | |
| if not question: | |
| raise HTTPException( | |
| status_code=404, | |
| detail="Question not found" | |
| ) | |
| test_cases = question.test_cases | |
| function_name = question.function_name | |
| runner_code = body.code + "\n\n" | |
| runner_code += """ | |
| import json | |
| import inspect | |
| # Helper to recursively convert PyTorch Tensors, NumPy arrays, etc. to clean Python structures | |
| def to_list_recursive(val): | |
| if hasattr(val, "tolist"): | |
| return to_list_recursive(val.tolist()) | |
| if isinstance(val, tuple): | |
| return [to_list_recursive(x) for x in val] | |
| if isinstance(val, list): | |
| return [to_list_recursive(x) for x in val] | |
| if isinstance(val, dict): | |
| return {k: to_list_recursive(v) for k, v in val.items()} | |
| if hasattr(val, "item") and callable(getattr(val, "item")): | |
| try: | |
| return val.item() | |
| except: | |
| pass | |
| return val | |
| # Helper to automatically cast input list arguments based on function type hints | |
| def prepare_args(func, raw_args): | |
| try: | |
| sig = inspect.signature(func) | |
| params = list(sig.parameters.values()) | |
| except Exception: | |
| return raw_args | |
| prepared = [] | |
| for i, arg in enumerate(raw_args): | |
| if i < len(params): | |
| param = params[i] | |
| annotation = param.annotation | |
| annotation_str = str(annotation) | |
| if "Tensor" in annotation_str or "tensor" in annotation_str: | |
| try: | |
| import torch | |
| if isinstance(arg, (list, tuple)): | |
| arg = torch.tensor(arg) | |
| except Exception: | |
| pass | |
| elif "ndarray" in annotation_str or "array" in annotation_str: | |
| try: | |
| import numpy as np | |
| if isinstance(arg, (list, tuple)): | |
| arg = np.array(arg) | |
| except Exception: | |
| pass | |
| prepared.append(arg) | |
| return prepared | |
| sol = Solution() | |
| results = [] | |
| """ | |
| for idx, tc in enumerate(test_cases): | |
| args = repr(tc["test"]) | |
| expected = repr(tc["expected_output"]) | |
| runner_code += f""" | |
| try: | |
| test_input = {args} | |
| prepared_input = prepare_args(sol.{function_name}, test_input) | |
| output = sol.{function_name}(*prepared_input) | |
| # Convert output recursively (handles single values, lists, and tuples of Tensors/Arrays) | |
| converted_output = to_list_recursive(output) | |
| passed = converted_output == {expected} | |
| results.append({{ | |
| "test_case": {idx + 1}, | |
| "input": test_input, | |
| "passed": passed, | |
| "expected": {expected}, | |
| "got": converted_output | |
| }}) | |
| except Exception as e: | |
| results.append({{ | |
| "test_case": {idx + 1}, | |
| "input": {args}, | |
| "passed": False, | |
| "error": str(e) | |
| }}) | |
| """ | |
| runner_code += """ | |
| print(json.dumps(results)) | |
| """ | |
| with open("public/run.py", "w", encoding="utf-8") as f: | |
| f.write(runner_code) | |
| res = subprocess.run( | |
| ["python", "public/run.py"], | |
| capture_output=True, | |
| text=True, | |
| timeout=10 | |
| ) | |
| if res.returncode != 0: | |
| raise RuntimeError(res.stderr or res.stdout) | |
| results = json.loads(res.stdout) | |
| total = len(results) | |
| passed = sum(1 for r in results if r.get("passed") is True) | |
| status = "Accepted" if passed == total else "Failed" | |
| return status, passed, total, results | |