mirror of
https://gitlab.com/megazordpobeda/DataRush.git
synced 2026-05-22 23:17:09 +00:00
its okay
This commit is contained in:
+6
-1
@@ -375,13 +375,18 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: ./services/checker
|
context: ./services/checker
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
restart: unless-stopped
|
env_file:
|
||||||
|
- path: ./infrastructure/checker/.env.template
|
||||||
|
required: true
|
||||||
|
- path: ./infrastructure/checker/.env
|
||||||
|
required: false
|
||||||
ports:
|
ports:
|
||||||
- name: web
|
- name: web
|
||||||
target: 8000
|
target: 8000
|
||||||
published: 8009
|
published: 8009
|
||||||
host_ip: 0.0.0.0
|
host_ip: 0.0.0.0
|
||||||
protocol: tcp
|
protocol: tcp
|
||||||
|
restart: unless-stopped
|
||||||
volumes:
|
volumes:
|
||||||
- type: bind
|
- type: bind
|
||||||
source: /var/run/docker.sock
|
source: /var/run/docker.sock
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
REGISTRY_LOGIN=devitq
|
||||||
|
REGISTRY_PASSWORD=14zQrbzDTM0WXK@CogMQikAvP74Rj4
|
||||||
@@ -19,6 +19,7 @@ from apps.task.models import (
|
|||||||
CompetitionTaskAttachment,
|
CompetitionTaskAttachment,
|
||||||
CompetitionTaskSubmission,
|
CompetitionTaskSubmission,
|
||||||
)
|
)
|
||||||
|
from apps.task.tasks import analyze_data_task
|
||||||
|
|
||||||
router = Router(tags=["competition"])
|
router = Router(tags=["competition"])
|
||||||
|
|
||||||
@@ -123,6 +124,7 @@ def submit_task(
|
|||||||
status=CompetitionTaskSubmission.StatusChoices.CHECKING,
|
status=CompetitionTaskSubmission.StatusChoices.CHECKING,
|
||||||
content=content,
|
content=content,
|
||||||
)
|
)
|
||||||
|
analyze_data_task.delay(submission_id=submission.id)
|
||||||
|
|
||||||
return TaskSubmissionOut(submission_id=submission.id)
|
return TaskSubmissionOut(submission_id=submission.id)
|
||||||
|
|
||||||
@@ -154,6 +156,4 @@ def get_submissions_history(request, competition_id: UUID, task_id: UUID):
|
|||||||
)
|
)
|
||||||
def get_task_attachments(request, competition_id: UUID, task_id: UUID):
|
def get_task_attachments(request, competition_id: UUID, task_id: UUID):
|
||||||
task = get_object_or_404(CompetitionTask, id=task_id)
|
task = get_object_or_404(CompetitionTask, id=task_id)
|
||||||
return status.OK, CompetitionTaskAttachment.objects.filter(
|
return status.OK, CompetitionTaskAttachment.objects.filter(task=task).all()
|
||||||
task=task
|
|
||||||
).all()
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import requests
|
import httpx
|
||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from django.core.files.base import ContentFile
|
from django.core.files.base import ContentFile
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ def analyze_data_task(self, submission_id):
|
|||||||
for f in submission.task.attachments.filter(public=True)
|
for f in submission.task.attachments.filter(public=True)
|
||||||
]
|
]
|
||||||
|
|
||||||
response = requests.post(
|
response = httpx.post(
|
||||||
f"{settings.CHECKER_API_ENDPOINT}/execute",
|
f"{settings.CHECKER_API_ENDPOINT}/execute",
|
||||||
files=[("files", (f.name, f)) for f in files]
|
files=[("files", (f.name, f)) for f in files]
|
||||||
+ [
|
+ [
|
||||||
@@ -40,10 +40,10 @@ def analyze_data_task(self, submission_id):
|
|||||||
)
|
)
|
||||||
submission.status = CompetitionTaskSubmission.StatusChoices.CHECKED
|
submission.status = CompetitionTaskSubmission.StatusChoices.CHECKED
|
||||||
|
|
||||||
except requests.exceptions.RequestException as e:
|
except httpx.RequestError as e:
|
||||||
self.retry(countdown=2**self.request.retries)
|
self.retry(countdown=2**self.request.retries)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
submission.result = {"error": str(e)}
|
submission.result = {"error": str(e), "success": False}
|
||||||
submission.status = CompetitionTaskSubmission.StatusChoices.CHECKED
|
submission.status = CompetitionTaskSubmission.StatusChoices.CHECKED
|
||||||
submission.earned_points = 0
|
submission.earned_points = 0
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
BASE_DIR = Path(__file__).resolve().parent
|
||||||
|
|
||||||
|
load_dotenv(BASE_DIR / ".env")
|
||||||
|
|
||||||
|
REGISTRY_LOGIN = os.getenv("REGISTRY_USERNAME", None)
|
||||||
|
|
||||||
|
REGISTRY_PASSWORD = os.getenv("REGISTRY_USERNAME", None)
|
||||||
|
|
||||||
|
REGISTRY_URL = os.getenv("REGISTRY_URL", "gitlab.prodcontest.ru:5050")
|
||||||
|
|
||||||
|
DOCKER_IMAGE = os.getenv(
|
||||||
|
"IMAGE", default="gitlab.prodcontest.ru:5050/team-15/project/custom-python"
|
||||||
|
)
|
||||||
+21
-15
@@ -10,19 +10,25 @@ import tempfile
|
|||||||
import logging
|
import logging
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
import re
|
import re
|
||||||
|
import config
|
||||||
app = FastAPI()
|
|
||||||
docker_client = docker.from_env()
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
|
||||||
|
|
||||||
|
|
||||||
DOCKER_IMAGE = "gitlab.python:3-slim"
|
|
||||||
CONTAINER_TIMEOUT = 60
|
CONTAINER_TIMEOUT = 60
|
||||||
MAX_FILE_SIZE = 4 * 1024 * 1024
|
MAX_FILE_SIZE = 4 * 1024 * 1024
|
||||||
ALLOWED_FILENAME_CHARS = r"[^a-zA-Z0-9_\-.]"
|
ALLOWED_FILENAME_CHARS = r"[^a-zA-Z0-9_\-.]"
|
||||||
|
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
docker_client = docker.from_env()
|
||||||
|
logger = logging.getLoggerQ(__name__)
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
docker_client.login(
|
||||||
|
username=config.REGISTRY_LOGIN,
|
||||||
|
password=config.REGISTRY_PASSWORD,
|
||||||
|
registry=config.REGISTRY_URL,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class FileDetails(BaseModel):
|
class FileDetails(BaseModel):
|
||||||
url: HttpUrl = Field(
|
url: HttpUrl = Field(
|
||||||
..., description="URL to download the file from (supports HTTP/HTTPS)"
|
..., description="URL to download the file from (supports HTTP/HTTPS)"
|
||||||
@@ -130,7 +136,7 @@ def run_container_safely(
|
|||||||
volumes[host_path] = {"bind": container_path, "mode": "ro"}
|
volumes[host_path] = {"bind": container_path, "mode": "ro"}
|
||||||
|
|
||||||
container = docker_client.containers.run(
|
container = docker_client.containers.run(
|
||||||
image=DOCKER_IMAGE,
|
image=config.DOCKER_IMAGE,
|
||||||
command=command,
|
command=command,
|
||||||
volumes=volumes,
|
volumes=volumes,
|
||||||
working_dir="/execution",
|
working_dir="/execution",
|
||||||
@@ -166,6 +172,14 @@ def run_container_safely(
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def validate_file_path(path: str) -> bool:
|
||||||
|
return (
|
||||||
|
not os.path.isabs(path)
|
||||||
|
and os.path.basename(path) == path
|
||||||
|
and all(c.isalnum() or c in {"_", "-", "."} for c in path)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/execute", response_model=ExecutionResponse)
|
@app.post("/execute", response_model=ExecutionResponse)
|
||||||
async def execute_code(request: ExecutionRequest) -> ExecutionResponse:
|
async def execute_code(request: ExecutionRequest) -> ExecutionResponse:
|
||||||
try:
|
try:
|
||||||
@@ -279,11 +293,3 @@ async def health_check() -> HealthCheckResponse:
|
|||||||
return HealthCheckResponse(status="healthy", docker="connected")
|
return HealthCheckResponse(status="healthy", docker="connected")
|
||||||
except docker.errors.DockerException:
|
except docker.errors.DockerException:
|
||||||
return HealthCheckResponse(status="degraded", docker="unavailable")
|
return HealthCheckResponse(status="degraded", docker="unavailable")
|
||||||
|
|
||||||
|
|
||||||
def validate_file_path(path: str) -> bool:
|
|
||||||
return (
|
|
||||||
not os.path.isabs(path)
|
|
||||||
and os.path.basename(path) == path
|
|
||||||
and all(c.isalnum() or c in {"_", "-", "."} for c in path)
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ dependencies = [
|
|||||||
"aiohttp>=3.11.13",
|
"aiohttp>=3.11.13",
|
||||||
"docker>=7.1.0",
|
"docker>=7.1.0",
|
||||||
"fastapi>=0.115.11",
|
"fastapi>=0.115.11",
|
||||||
|
"python-dotenv>=1.0.1",
|
||||||
"python-multipart>=0.0.20",
|
"python-multipart>=0.0.20",
|
||||||
"regex>=2024.11.6",
|
"regex>=2024.11.6",
|
||||||
"uvicorn>=0.34.0",
|
"uvicorn>=0.34.0",
|
||||||
|
|||||||
Reference in New Issue
Block a user