add new firmware_upload api definition, not implemented yet
This commit is contained in:
parent
a13276f259
commit
44b6cc61e6
2 changed files with 74 additions and 3 deletions
|
@ -5,7 +5,7 @@ from django.db.models import Q
|
||||||
from ninja.security import HttpBearer
|
from ninja.security import HttpBearer
|
||||||
|
|
||||||
from c3nav import settings
|
from c3nav import settings
|
||||||
from c3nav.api.exceptions import APITokenInvalid, APIPermissionDenied
|
from c3nav.api.exceptions import APIPermissionDenied, APITokenInvalid
|
||||||
from c3nav.api.schema import APIErrorSchema
|
from c3nav.api.schema import APIErrorSchema
|
||||||
from c3nav.control.models import UserPermissions
|
from c3nav.control.models import UserPermissions
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
|
import base64
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
|
from django.db import transaction
|
||||||
from ninja import Field as APIField
|
from ninja import Field as APIField
|
||||||
|
from ninja import ModelSchema
|
||||||
from ninja import Router as APIRouter
|
from ninja import Router as APIRouter
|
||||||
from ninja import Schema
|
from ninja import Schema, UploadedFile
|
||||||
from ninja.pagination import paginate
|
from ninja.pagination import paginate
|
||||||
|
from pydantic import validator
|
||||||
|
|
||||||
from c3nav.api.newauth import auth_responses
|
from c3nav.api.newauth import BearerAuth, auth_permission_responses, auth_responses
|
||||||
from c3nav.mesh.dataformats import BoardType
|
from c3nav.mesh.dataformats import BoardType
|
||||||
from c3nav.mesh.messages import ChipType
|
from c3nav.mesh.messages import ChipType
|
||||||
from c3nav.mesh.models import FirmwareVersion
|
from c3nav.mesh.models import FirmwareVersion
|
||||||
|
@ -15,6 +19,7 @@ api_router = APIRouter(tags=["mesh"])
|
||||||
|
|
||||||
class FirmwareBuildSchema(Schema):
|
class FirmwareBuildSchema(Schema):
|
||||||
id: int
|
id: int
|
||||||
|
variant: str = APIField(..., example="c3uart")
|
||||||
chip: ChipType = APIField(..., example=ChipType.ESP32_C3.name)
|
chip: ChipType = APIField(..., example=ChipType.ESP32_C3.name)
|
||||||
sha256_hash: str = APIField(..., regex=r"^[0-9a-f]{64}$")
|
sha256_hash: str = APIField(..., regex=r"^[0-9a-f]{64}$")
|
||||||
url: str = APIField(..., alias="binary", example="/media/firmware/012345/firmware.bin")
|
url: str = APIField(..., alias="binary", example="/media/firmware/012345/firmware.bin")
|
||||||
|
@ -34,6 +39,12 @@ class FirmwareSchema(Schema):
|
||||||
created: datetime
|
created: datetime
|
||||||
builds: list[FirmwareBuildSchema]
|
builds: list[FirmwareBuildSchema]
|
||||||
|
|
||||||
|
@validator('builds')
|
||||||
|
def builds_variants_must_be_unique(cls, builds):
|
||||||
|
if len(set(build.variant for build in builds)) != len(builds):
|
||||||
|
raise ValueError("builds must have unique variant identifiers")
|
||||||
|
return builds
|
||||||
|
|
||||||
|
|
||||||
class Error(Schema):
|
class Error(Schema):
|
||||||
detail: str
|
detail: str
|
||||||
|
@ -53,3 +64,63 @@ def firmware_detail(request, firmware_id: int):
|
||||||
return FirmwareVersion.objects.get(id=firmware_id)
|
return FirmwareVersion.objects.get(id=firmware_id)
|
||||||
except FirmwareVersion.DoesNotExist:
|
except FirmwareVersion.DoesNotExist:
|
||||||
return 404, {"detail": "firmware not found"}
|
return 404, {"detail": "firmware not found"}
|
||||||
|
|
||||||
|
|
||||||
|
class Base64Bytes(bytes):
|
||||||
|
@classmethod
|
||||||
|
def __get_validators__(cls):
|
||||||
|
# one or more validators may be yielded which will be called in the
|
||||||
|
# order to validate the input, each validator will receive as an input
|
||||||
|
# the value returned from the previous validator
|
||||||
|
yield cls.validate
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def __modify_schema__(cls, field_schema):
|
||||||
|
# __modify_schema__ should mutate the dict it receives in place,
|
||||||
|
# the returned value will be ignored
|
||||||
|
field_schema.update(
|
||||||
|
# simplified regex here for brevity, see the wikipedia link above
|
||||||
|
pattern='^[A-Z]{1,2}[0-9][A-Z0-9]? ?[0-9][A-Z]{2}$',
|
||||||
|
# some example postcodes
|
||||||
|
examples=['SP11 9DG', 'w1j7bu'],
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def validate(cls, v):
|
||||||
|
if not isinstance(v, str):
|
||||||
|
raise TypeError('string required')
|
||||||
|
return cls(base64.b64decode(v.encode("ascii")))
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'PostCode({super().__repr__()})'
|
||||||
|
|
||||||
|
|
||||||
|
class UploadFirmwareBuildSchema(Schema):
|
||||||
|
variant: str = APIField(..., example="c3uart")
|
||||||
|
chip: ChipType = APIField(..., example=ChipType.ESP32_C3.name)
|
||||||
|
sha256_hash: str = APIField(..., regex=r"^[0-9a-f]{64}$")
|
||||||
|
boards: list[BoardType] = APIField(..., example=[BoardType.C3NAV_LOCATION_PCB_REV_0_2.name, ])
|
||||||
|
binary: bytes = APIField(..., example="base64", contentEncoding="base64")
|
||||||
|
|
||||||
|
@validator('binary')
|
||||||
|
def get_binary_base64(cls, binary):
|
||||||
|
return base64.b64decode(binary.encode())
|
||||||
|
|
||||||
|
|
||||||
|
class UploadFirmwareSchema(Schema):
|
||||||
|
project_name: str = APIField(..., example="c3nav_positioning")
|
||||||
|
version: str = APIField(..., example="499837d-dirty")
|
||||||
|
idf_version: str = APIField(..., example="v5.1-476-g3187b8b326")
|
||||||
|
builds: list[UploadFirmwareBuildSchema] = APIField(..., min_items=1)
|
||||||
|
|
||||||
|
@validator('builds')
|
||||||
|
def builds_variants_must_be_unique(cls, builds):
|
||||||
|
if len(set(build.variant for build in builds)) != len(builds):
|
||||||
|
raise ValueError("builds must have unique variant identifiers")
|
||||||
|
return builds
|
||||||
|
|
||||||
|
|
||||||
|
@api_router.post('/firmwares/upload', summary="Upload firmware", auth=BearerAuth(superuser=True),
|
||||||
|
response={200: FirmwareSchema, **auth_permission_responses})
|
||||||
|
def firmware_upload(request, firmware_data: UploadFirmwareSchema):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue