109 lines
2.8 KiB
Python
109 lines
2.8 KiB
Python
|
import uuid
|
||
|
from pydantic import validator
|
||
|
import io
|
||
|
import os
|
||
|
from fastapi import UploadFile, Form
|
||
|
from pathlib import Path
|
||
|
from typing import IO, Any, List, Optional, Type
|
||
|
|
||
|
from fastapi import FastAPI
|
||
|
from sqlmodel import Field, Session, SQLModel, create_engine, select
|
||
|
from services.exoValidation import get_support_from_data
|
||
|
|
||
|
from services.io import add_fast_api_root, get_filename, get_or_create_dir, remove_fastapi_root
|
||
|
|
||
|
|
||
|
class FileFieldMeta(type):
|
||
|
def __getitem__(self, upload_root: str,) -> Type['FileField']:
|
||
|
return type('MyFieldValue', (FileField,), {'upload_root': upload_root})
|
||
|
|
||
|
|
||
|
class FileField(str, metaclass=FileFieldMeta):
|
||
|
upload_root: str
|
||
|
@classmethod
|
||
|
def __get_validators__(cls):
|
||
|
yield cls.validate
|
||
|
|
||
|
@classmethod
|
||
|
def validate(cls, value: str | IO, values):
|
||
|
print(cls.upload_root, cls.default_naming_field)
|
||
|
upload_root = get_or_create_dir(
|
||
|
add_fast_api_root(cls.upload_root))
|
||
|
|
||
|
if not isinstance(value, str):
|
||
|
value.seek(0)
|
||
|
|
||
|
is_binary = isinstance(value, io.BytesIO)
|
||
|
|
||
|
name = get_filename(value, 'exo_source.py')
|
||
|
|
||
|
parent = get_or_create_dir(os.path.join(
|
||
|
upload_root, values['id_code']))
|
||
|
|
||
|
mode = 'w+' if not is_binary else 'wb+'
|
||
|
|
||
|
path = os.path.join(parent, name)
|
||
|
with open(path, mode) as f:
|
||
|
f.write(value.read())
|
||
|
|
||
|
return remove_fastapi_root(path)
|
||
|
|
||
|
else:
|
||
|
if not os.path.exists(value):
|
||
|
raise ValueError('File does not exist')
|
||
|
return value
|
||
|
|
||
|
class Hero(SQLModel, table=True):
|
||
|
id: Optional[int] = Field(default=None, primary_key=True)
|
||
|
id_code : str
|
||
|
path: FileField['/testing', 'id_code']
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
class HeroCreate(SQLModel):
|
||
|
path: FileField[42]
|
||
|
|
||
|
class HeroRead(SQLModel):
|
||
|
id: int
|
||
|
id_code: str
|
||
|
path: str
|
||
|
|
||
|
|
||
|
sqlite_file_name = "testing.db"
|
||
|
sqlite_url = f"sqlite:///{sqlite_file_name}"
|
||
|
|
||
|
connect_args = {"check_same_thread": False}
|
||
|
engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
|
||
|
|
||
|
|
||
|
def create_db_and_tables():
|
||
|
SQLModel.metadata.create_all(engine)
|
||
|
|
||
|
|
||
|
app = FastAPI()
|
||
|
|
||
|
|
||
|
@app.on_event("startup")
|
||
|
def on_startup():
|
||
|
create_db_and_tables()
|
||
|
|
||
|
|
||
|
@app.get("/heroes/", response_model=List[HeroRead])
|
||
|
def read_heroes():
|
||
|
with Session(engine) as session:
|
||
|
heroes = session.exec(select(Hero)).all()
|
||
|
return heroes
|
||
|
|
||
|
@app.post("/heroes/", )
|
||
|
def create_hero(file: UploadFile, name: str = Form()):
|
||
|
with Session(engine) as session:
|
||
|
file_obj = file.file._file
|
||
|
db_hero = Hero(path=file_obj, id_code=name)
|
||
|
session.add(db_hero)
|
||
|
session.commit()
|
||
|
session.refresh(db_hero)
|
||
|
return "db_hero"
|
||
|
|
||
|
|