updated contact_api.nix and how the api is

This commit is contained in:
2026-01-21 22:03:31 -05:00
parent e75a3ef9c6
commit 88c2f1b139
2 changed files with 24 additions and 14 deletions

View File

@@ -1,5 +1,6 @@
"""FastAPI interface for Contact database.""" """FastAPI interface for Contact database."""
import logging
import shutil import shutil
import subprocess import subprocess
import tempfile import tempfile
@@ -14,8 +15,11 @@ import uvicorn
from fastapi import FastAPI from fastapi import FastAPI
from python.api.routers import contact_router, create_frontend_router from python.api.routers import contact_router, create_frontend_router
from python.common import configure_logger
from python.orm.base import get_postgres_engine from python.orm.base import get_postgres_engine
logger = logging.getLogger(__name__)
def create_app(frontend_dir: Path | None = None) -> FastAPI: def create_app(frontend_dir: Path | None = None) -> FastAPI:
"""Create and configure the FastAPI application.""" """Create and configure the FastAPI application."""
@@ -32,16 +36,13 @@ def create_app(frontend_dir: Path | None = None) -> FastAPI:
app.include_router(contact_router) app.include_router(contact_router)
if frontend_dir: if frontend_dir:
print(f"Serving frontend from {frontend_dir}") logger.info(f"Serving frontend from {frontend_dir}")
frontend_router = create_frontend_router(frontend_dir) frontend_router = create_frontend_router(frontend_dir)
app.include_router(frontend_router) app.include_router(frontend_router)
return app return app
cli = typer.Typer()
def build_frontend(source_dir: Path | None, cache_dir: Path | None = None) -> Path | None: def build_frontend(source_dir: Path | None, cache_dir: Path | None = None) -> Path | None:
"""Run npm build and copy output to a temp directory. """Run npm build and copy output to a temp directory.
@@ -58,10 +59,10 @@ def build_frontend(source_dir: Path | None, cache_dir: Path | None = None) -> Pa
return None return None
if not source_dir.exists(): if not source_dir.exists():
error = f"Error: Frontend directory {source_dir} does not exist" error = f"Frontend directory {source_dir} does not exist"
raise FileExistsError(error) raise FileExistsError(error)
print(f"Building frontend from {source_dir}...") logger.info("Building frontend from %s...", source_dir)
# Copy source to a writable temp directory # Copy source to a writable temp directory
build_dir = Path(tempfile.mkdtemp(prefix="contact_frontend_build_")) build_dir = Path(tempfile.mkdtemp(prefix="contact_frontend_build_"))
@@ -82,15 +83,15 @@ def build_frontend(source_dir: Path | None, cache_dir: Path | None = None) -> Pa
output_dir = Path(tempfile.mkdtemp(prefix="contact_frontend_")) output_dir = Path(tempfile.mkdtemp(prefix="contact_frontend_"))
shutil.copytree(dist_dir, output_dir, dirs_exist_ok=True) shutil.copytree(dist_dir, output_dir, dirs_exist_ok=True)
print(f"Frontend built and copied to {output_dir}") logger.info(f"Frontend built and copied to {output_dir}")
shutil.rmtree(build_dir) shutil.rmtree(build_dir)
return output_dir return output_dir
@cli.command()
def serve( def serve(
host: Annotated[str, typer.Option("--host", "-h", help="Host to bind to")],
frontend_dir: Annotated[ frontend_dir: Annotated[
Path | None, Path | None,
typer.Option( typer.Option(
@@ -99,15 +100,18 @@ def serve(
help="Frontend source directory. If provided, runs npm build and serves from temp dir.", help="Frontend source directory. If provided, runs npm build and serves from temp dir.",
), ),
] = None, ] = None,
host: Annotated[str, typer.Option("--host", "-h", help="Host to bind to")] = "0.0.0.0",
port: Annotated[int, typer.Option("--port", "-p", help="Port to bind to")] = 8000, port: Annotated[int, typer.Option("--port", "-p", help="Port to bind to")] = 8000,
log_level: Annotated[str, typer.Option("--log-level", "-l", help="Log level")] = "INFO",
) -> None: ) -> None:
"""Start the Contact API server.""" """Start the Contact API server."""
serve_dir = build_frontend(frontend_dir) configure_logger(log_level)
cache_dir = Path(environ["HOME"]) / ".npm"
serve_dir = build_frontend(frontend_dir, cache_dir=cache_dir)
app = create_app(frontend_dir=serve_dir) app = create_app(frontend_dir=serve_dir)
uvicorn.run(app, host=host, port=port) uvicorn.run(app, host=host, port=port)
if __name__ == "__main__": if __name__ == "__main__":
cli() typer.run(serve)

View File

@@ -15,18 +15,25 @@
]; ];
requires = [ "postgresql.service" ]; requires = [ "postgresql.service" ];
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
path = [
pkgs.nodejs
pkgs.coreutils
pkgs.bash
];
environment = { environment = {
PYTHONPATH = "${inputs.self}"; PYTHONPATH = "${inputs.self}";
POSTGRES_DB = "richie"; POSTGRES_DB = "richie";
POSTGRES_HOST = "/run/postgresql"; POSTGRES_HOST = "/run/postgresql";
POSTGRES_USER = "richie"; POSTGRES_USER = "richie";
FRONTEND_DIR = "/home/richie/dotfiles/frontend/dist/"; POSTGRES_PORT = "5432";
HOME = "/var/lib/contact-api";
}; };
serviceConfig = { serviceConfig = {
Type = "simple"; Type = "simple";
ExecStart = "${pkgs.my_python}/bin/fastapi run ${inputs.self}/python/api/contact_api.py --port 8069"; ExecStart = "${pkgs.my_python}/bin/python -m python.api.main --host 192.168.90.40 --port 8069 --frontend-dir ${inputs.self}/frontend";
StateDirectory = "contact-api";
Restart = "on-failure"; Restart = "on-failure";
RestartSec = "5s"; RestartSec = "5s";
StandardOutput = "journal"; StandardOutput = "journal";
@@ -38,7 +45,6 @@
PrivateTmp = true; PrivateTmp = true;
ReadOnlyPaths = [ ReadOnlyPaths = [
"${inputs.self}" "${inputs.self}"
"/home/richie/dotfiles/frontend/dist/"
]; ];
}; };
}; };