navix/backend/main.py
2025-07-03 07:13:48 +03:00

95 lines
2.2 KiB
Python

from fastapi import FastAPI, APIRouter
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
import os
from dotenv import load_dotenv
import yaml
from pathlib import Path
from pydantic import BaseModel
from minio import Minio
app = FastAPI()
router = APIRouter()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
load_dotenv()
# ENV
MINIO_ENDPOINT = os.getenv("MINIO_ENDPOINT")
MINIO_ACCESS_KEY = os.getenv("MINIO_ACCESS_KEY")
MINIO_SECRET_KEY = os.getenv("MINIO_SECRET_KEY")
MINIO_BUCKET = os.getenv("MINIO_BUCKET")
minio_client = Minio(
MINIO_ENDPOINT,
access_key=MINIO_ACCESS_KEY,
secret_key=MINIO_SECRET_KEY,
secure=True
)
BUCKET = MINIO_BUCKET or "navix-icons"
@router.get("/")
def root():
return {"message": "Welcome to the FastAPI application!"}
APPS_FILE = Path(__file__).parent / "apps.yaml"
@router.get("/apps")
def get_apps():
if not APPS_FILE.exists():
return {"error": "apps.yaml not found"}
with open(APPS_FILE, "r") as f:
return yaml.safe_load(f)
class AppData(BaseModel):
name: str
icon: str
description: str
url: str
class AppEntry(BaseModel):
section: str
app: AppData
@router.post("/add_app")
def add_app(entry: AppEntry):
if not APPS_FILE.exists():
current = {"sections": []}
else:
with open(APPS_FILE, "r") as f:
current = yaml.safe_load(f) or {"sections": []}
for section in current["sections"]:
if section["name"] == entry.section:
section["apps"].append(entry.app.dict())
break
else:
current["sections"].append({
"name": entry.section,
"apps": [entry.app.dict()]
})
with open(APPS_FILE, "w") as f:
yaml.safe_dump(current, f)
return {"status": "added"}
@router.get("/icon/{filename}")
def get_public_icon_url(filename: str):
url = f"https://{MINIO_ENDPOINT}/{BUCKET}/{filename}"
return JSONResponse(content={"url": url})
app.include_router(router, prefix="/api")
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)