add new firmware_upload api definition, not implemented yet

This commit is contained in:
Laura Klünder 2023-11-15 14:54:21 +01:00
parent a13276f259
commit 44b6cc61e6
2 changed files with 74 additions and 3 deletions

View file

@ -5,7 +5,7 @@ from django.db.models import Q
from ninja.security import HttpBearer
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.control.models import UserPermissions

View file

@ -1,11 +1,15 @@
import base64
from datetime import datetime
from django.db import transaction
from ninja import Field as APIField
from ninja import ModelSchema
from ninja import Router as APIRouter
from ninja import Schema
from ninja import Schema, UploadedFile
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.messages import ChipType
from c3nav.mesh.models import FirmwareVersion
@ -15,6 +19,7 @@ api_router = APIRouter(tags=["mesh"])
class FirmwareBuildSchema(Schema):
id: int
variant: str = APIField(..., example="c3uart")
chip: ChipType = APIField(..., example=ChipType.ESP32_C3.name)
sha256_hash: str = APIField(..., regex=r"^[0-9a-f]{64}$")
url: str = APIField(..., alias="binary", example="/media/firmware/012345/firmware.bin")
@ -34,6 +39,12 @@ class FirmwareSchema(Schema):
created: datetime
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):
detail: str
@ -53,3 +64,63 @@ def firmware_detail(request, firmware_id: int):
return FirmwareVersion.objects.get(id=firmware_id)
except FirmwareVersion.DoesNotExist:
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