Skip to content

Commit 7ec76bf

Browse files
authored
Try #370:
2 parents 44aa4ab + 2c9cf88 commit 7ec76bf

File tree

3 files changed

+37
-26
lines changed

3 files changed

+37
-26
lines changed

src/apiserver/api_models.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
from __future__ import annotations
2-
import uuid
32
import pydantic
43
import typing
54
import db_models
@@ -11,17 +10,14 @@ class ApiVersion(pydantic.BaseModel):
1110

1211

1312
class Run(pydantic.BaseModel):
14-
id: uuid.UUID
15-
"""
16-
Run identifier, unique in the system.
17-
"""
13+
id: str
1814
toolchain_name: str
1915
problem_name: str
20-
user_id: uuid.UUID
16+
user_id: str
2117
contest_name: str
2218
status: typing.Mapping[str, str] = pydantic.Field(default_factory=dict)
2319

2420
@staticmethod
2521
def from_db(doc: db_models.RunMainProj) -> Run:
26-
return Run(id=doc['id'], toolchain_name=doc['toolchain_name'],
27-
user_id=doc['user_id'], contest_name=doc['contest_name'], problem_name=doc['problem_name'], status=doc['status'])
22+
return Run(id=str(doc['_id']), toolchain_name=doc['toolchain_name'],
23+
user_id=str(doc['user_id']), contest_name=doc['contest_name'], problem_name=doc['problem_name'], status=doc['status'])

src/apiserver/db_models.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,28 @@
1-
import uuid
1+
from bson import ObjectId
22
from enum import Enum
3-
import time
43
import typing
54
from pydantic import BaseModel, Field
65

76

7+
class Id(ObjectId):
8+
@classmethod
9+
def __get_validators__(cls):
10+
yield cls.validate
11+
12+
@classmethod
13+
def validate(cls, v):
14+
if not isinstance(v, ObjectId):
15+
raise TypeError('ObjectId required')
16+
return str(v)
17+
18+
@classmethod
19+
def __modify_schema__(cls, schema):
20+
schema.update({
21+
'Title': 'Object ID',
22+
'type': 'string'
23+
})
24+
25+
826
class RunPhase(Enum):
927
"""
1028
# QUEUED
@@ -24,10 +42,9 @@ class RunPhase(Enum):
2442

2543

2644
class RunMainProj(BaseModel):
27-
id: uuid.UUID
2845
toolchain_name: str
2946
problem_name: str
30-
user_id: uuid.UUID
47+
user_id: Id
3148
contest_name: str
3249
phase: str # RunPhase
3350
status: typing.Mapping[str, str] = Field(default_factory=dict)
@@ -37,7 +54,7 @@ class RunMainProj(BaseModel):
3754
"""
3855

3956

40-
RunMainProj.FIELDS = ['id', 'toolchain_name',
57+
RunMainProj.FIELDS = ['toolchain_name',
4158
'problem_name', 'user_id', 'contest_name', 'status']
4259

4360

src/apiserver/routes.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import fastapi
22
import db_models
33
import api_models
4-
import uuid
54
import typing
65
import base64
76
import pymongo
7+
from bson import ObjectId
88
import pydantic
99

1010

@@ -97,15 +97,14 @@ def route_submit(params: RunSubmitSimpleParams, db: pymongo.database.Database =
9797
fields of request body; `id` will be real id of this run.
9898
"""
9999

100-
run_uuid = uuid.uuid4()
101-
user_id = uuid.UUID('12345678123456781234567812345678')
102-
doc_main = db_models.RunMainProj(id=run_uuid, toolchain_name=params.toolchain,
100+
user_id = ObjectId('507f1f77bcf86cd799439011')
101+
doc_main = db_models.RunMainProj(toolchain_name=params.toolchain,
103102
problem_name=params.problem, user_id=user_id, contest_name=params.contest, phase=str(db_models.RunPhase.QUEUED))
104103
doc_source = db_models.RunSourceProj(
105104
source=base64.b64decode(params.code))
106105
doc = {**dict(doc_main), **dict(doc_source)}
107-
db.runs.insert_one(doc)
108-
return api_models.Run(id=run_uuid, toolchain_name=params.toolchain, problem_name=params.problem, user_id=user_id, contest_name=params.contest)
106+
result = db.runs.insert_one(doc)
107+
return api_models.Run(id=str(result.inserted_id), toolchain_name=params.toolchain, problem_name=params.problem, user_id=str(user_id), contest_name=params.contest)
109108

110109
@app.get('/runs', response_model=typing.List[api_models.Run],
111110
operation_id='listRuns')
@@ -122,13 +121,12 @@ def route_list_runs(db: pymongo.database.Database = fastapi.Depends(db_connect))
122121
return runs
123122

124123
@app.get('/runs/{run_id}', response_model=api_models.Run, operation_id='getRun')
125-
def route_get_run(run_id: uuid.UUID, db: pymongo.database.Database = fastapi.Depends(db_connect)):
124+
def route_get_run(run_id: str, db: pymongo.database.Database = fastapi.Depends(db_connect)):
126125
"""
127126
Loads run by id
128127
"""
129-
130128
run = db.runs.find_one(projection=db_models.RunMainProj.FIELDS, filter={
131-
'id': run_id
129+
'_id': ObjectId(run_id)
132130
})
133131
if run is None:
134132
raise fastapi.HTTPException(404, detail='RunNotFound')
@@ -139,13 +137,13 @@ def route_get_run(run_id: uuid.UUID, db: pymongo.database.Database = fastapi.Dep
139137
'description': "Run source is not available"
140138
}
141139
})
142-
def route_get_run_source(run_id: uuid.UUID, db: pymongo.database.Database = fastapi.Depends(db_connect)):
140+
def route_get_run_source(run_id: str, db: pymongo.database.Database = fastapi.Depends(db_connect)):
143141
"""
144142
Returns run source as base64-encoded JSON string
145143
"""
146144

147145
doc = db.runs.find_one(projection=['source'], filter={
148-
'id': run_id
146+
'_id': ObjectId(run_id)
149147
})
150148
if doc is None:
151149
raise fastapi.HTTPException(404, detail='RunNotFound')
@@ -154,7 +152,7 @@ def route_get_run_source(run_id: uuid.UUID, db: pymongo.database.Database = fast
154152
return base64.b64encode(doc['source'])
155153

156154
@app.patch('/runs/{run_id}', response_model=api_models.Run, operation_id='patchRun')
157-
def route_run_patch(run_id: uuid.UUID, patch: RunPatch, db: pymongo.database.Database = fastapi.Depends(db_connect)):
155+
def route_run_patch(run_id: str, patch: RunPatch, db: pymongo.database.Database = fastapi.Depends(db_connect)):
158156
"""
159157
Modifies existing run
160158
@@ -177,7 +175,7 @@ def route_run_patch(run_id: uuid.UUID, patch: RunPatch, db: pymongo.database.Dat
177175
"RunPatch.status[*] must have length exactly 2")
178176
p['$set'][f"status.{status_to_add[0]}"] = status_to_add[1]
179177
updated_run = db.runs.find_one_and_update(
180-
{'id': run_id}, p, projection=db_models.RunMainProj.FIELDS, return_document=pymongo.ReturnDocument.AFTER)
178+
{'_id': ObjectId(run_id)}, p, projection=db_models.RunMainProj.FIELDS, return_document=pymongo.ReturnDocument.AFTER)
181179
if updated_run is None:
182180
raise fastapi.HTTPException(404, 'RunNotFound')
183181
return updated_run

0 commit comments

Comments
 (0)