File size: 2,216 Bytes
6da6be7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a5ef538
6da6be7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from __future__ import annotations

from typing import List
from datetime import datetime

from fastapi import FastAPI, UploadFile, File, HTTPException
from pydantic import BaseModel
from fastapi.responses import PlainTextResponse

from .document_service import (
    save_document,
    list_documents,
    get_document,
    read_content,
)
from src.log import get_logger


class DocumentInfo(BaseModel):
    id: int
    original_name: str
    file_path: str
    created_at: datetime

    class Config:
        from_attributes = True


class DocumentDetail(DocumentInfo):
    content: str


def create_app() -> FastAPI:
    app = FastAPI(title="LLM Backend API")
    log = get_logger(__name__)

    @app.post("/users/{username}/documents", response_model=DocumentInfo)
    async def upload(username: str, file: UploadFile = File(...)) -> DocumentInfo:
        log.info("Uploading document %s for %s", file.filename, username)
        doc = save_document(username, file)
        return DocumentInfo.model_validate(doc.__data__)

    @app.get("/users/{username}/documents", response_model=List[DocumentInfo])
    async def list_docs(username: str) -> List[DocumentInfo]:
        docs = list_documents(username)
        return [DocumentInfo.model_validate(d.__data__) for d in docs]

    @app.get("/users/{username}/documents/{doc_id}", response_model=DocumentDetail)
    async def inspect(username: str, doc_id: int) -> DocumentDetail:
        doc = get_document(username, doc_id)
        if not doc:
            raise HTTPException(status_code=404, detail="Document not found")
        content = read_content(doc)
        data = DocumentDetail.model_validate(doc.__data__)
        data.content = content
        return data

    @app.get("/users/{username}/documents/{doc_id}/raw", response_class=PlainTextResponse)
    async def download(username: str, doc_id: int) -> PlainTextResponse:
        doc = get_document(username, doc_id)
        if not doc:
            raise HTTPException(status_code=404, detail="Document not found")
        return PlainTextResponse(read_content(doc))

    return app


app = create_app()

if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="0.0.0.0", port=8000)