67 lines
1.4 KiB
Python
67 lines
1.4 KiB
Python
from pathlib import Path
|
|
|
|
from fastapi import FastAPI, Response, status
|
|
from fastapi.responses import JSONResponse
|
|
from pydantic import BaseModel
|
|
|
|
app = FastAPI()
|
|
data_path = Path(__file__).parent.resolve() / "data"
|
|
|
|
|
|
class Files(BaseModel):
|
|
files: list[str]
|
|
|
|
|
|
class Log(BaseModel):
|
|
start: int
|
|
size: int
|
|
total: int
|
|
content: str
|
|
end: bool
|
|
|
|
|
|
class Error(BaseModel):
|
|
error: str
|
|
|
|
|
|
@app.get("/", response_model=Files)
|
|
def list_logs():
|
|
return {"files": [path.name for path in data_path.glob("*.txt") if path.is_file()]}
|
|
|
|
|
|
@app.get(
|
|
"/log/{name}/",
|
|
response_model=Log,
|
|
responses={
|
|
400: {"model": Error},
|
|
404: {"model": Error},
|
|
},
|
|
)
|
|
def get_log(name: str, start: int = 0, size: int = 100):
|
|
path = data_path.joinpath(name)
|
|
|
|
# Prevent path traversal
|
|
if not path.is_relative_to(data_path):
|
|
return JSONResponse(
|
|
status_code=status.HTTP_400_BAD_REQUEST, content={"error": "Bad Request"}
|
|
)
|
|
|
|
if not path.is_file():
|
|
return JSONResponse(
|
|
status_code=status.HTTP_400_BAD_REQUEST, content={"error": "Log not found"}
|
|
)
|
|
|
|
with open(path) as f:
|
|
f.seek(start)
|
|
content = f.read(size)
|
|
|
|
total = path.stat().st_size
|
|
|
|
return {
|
|
"start": start,
|
|
"size": len(content),
|
|
"total": total,
|
|
"content": content,
|
|
"end": size + start >= total,
|
|
}
|