Skip to content

Commit 7120d61

Browse files
committed
UUID to ObjectId conversion in apiserver
1 parent c05b628 commit 7120d61

File tree

3 files changed

+35
-23
lines changed

3 files changed

+35
-23
lines changed

src/apiserver/api_models.py

+3-7
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'],
22+
return Run(id=str(doc['_id']), toolchain_name=doc['toolchain_name'],
2723
user_id=doc['user_id'], contest_name=doc['contest_name'], problem_name=doc['problem_name'], status=doc['status'])

src/apiserver/db_models.py

+22-5
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': 'MongoDB ObjectID',
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

+10-11
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,13 @@ 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
"""
129128

130129
run = db.runs.find_one(projection=db_models.RunMainProj.FIELDS, filter={
131-
'id': run_id
130+
'_id': run_id
132131
})
133132
if run is None:
134133
raise fastapi.HTTPException(404, detail='RunNotFound')
@@ -139,13 +138,13 @@ def route_get_run(run_id: uuid.UUID, db: pymongo.database.Database = fastapi.Dep
139138
'description': "Run source is not available"
140139
}
141140
})
142-
def route_get_run_source(run_id: uuid.UUID, db: pymongo.database.Database = fastapi.Depends(db_connect)):
141+
def route_get_run_source(run_id: db_models.Id, db: pymongo.database.Database = fastapi.Depends(db_connect)):
143142
"""
144143
Returns run source as base64-encoded JSON string
145144
"""
146145

147146
doc = db.runs.find_one(projection=['source'], filter={
148-
'id': run_id
147+
'_id': run_id
149148
})
150149
if doc is None:
151150
raise fastapi.HTTPException(404, detail='RunNotFound')
@@ -154,7 +153,7 @@ def route_get_run_source(run_id: uuid.UUID, db: pymongo.database.Database = fast
154153
return base64.b64encode(doc['source'])
155154

156155
@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)):
156+
def route_run_patch(run_id: db_models.Id, patch: RunPatch, db: pymongo.database.Database = fastapi.Depends(db_connect)):
158157
"""
159158
Modifies existing run
160159

0 commit comments

Comments
 (0)