-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
100 lines (77 loc) · 2.91 KB
/
main.py
File metadata and controls
100 lines (77 loc) · 2.91 KB
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
"""
GitSage - Local Git management with AI-powered features.
Entry point for the FastAPI application.
"""
import logging
import os
import sys
from contextlib import asynccontextmanager
import uvicorn
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.responses import JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from app.api import commits, branches, status, ai, remotes
from app.core.config import settings
from app.core.exceptions import GitSageError
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
)
logger = logging.getLogger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
logger.info("GitSage starting up...")
yield
logger.info("GitSage shutting down.")
app = FastAPI(
title="GitSage",
description="Local Git management with AI-powered commit messages and error diagnosis.",
version="1.0.0",
lifespan=lifespan,
docs_url="/api/docs" if settings.DEBUG else None,
redoc_url=None,
)
# Security: Only allow localhost access since this is a self-hosted tool
app.add_middleware(
TrustedHostMiddleware,
allowed_hosts=["localhost", "127.0.0.1", "::1"],
)
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:8000", "http://127.0.0.1:8000"],
allow_credentials=False,
allow_methods=["GET", "POST"],
allow_headers=["Content-Type", "X-Requested-With"],
)
app.mount("/static", StaticFiles(directory="frontend/static"), name="static")
templates = Jinja2Templates(directory="frontend/templates")
# Register routers
app.include_router(commits.router, prefix="/api/commits", tags=["commits"])
app.include_router(branches.router, prefix="/api/branches", tags=["branches"])
app.include_router(status.router, prefix="/api/status", tags=["status"])
app.include_router(ai.router, prefix="/api/ai", tags=["ai"])
app.include_router(remotes.router, prefix="/api/remotes", tags=["remotes"])
@app.exception_handler(GitSageError)
async def gitsage_exception_handler(request: Request, exc: GitSageError):
return JSONResponse(status_code=exc.status_code, content={"detail": exc.message})
@app.exception_handler(Exception)
async def generic_exception_handler(request: Request, exc: Exception):
logger.error("Unhandled exception: %s", exc, exc_info=True)
return JSONResponse(status_code=500, content={"detail": "Internal server error."})
@app.get("/", include_in_schema=False)
async def index(request: Request):
return templates.TemplateResponse("index.html", {"request": request})
@app.get("/health")
async def health():
return {"status": "ok"}
if __name__ == "__main__":
uvicorn.run(
"main:app",
host="127.0.0.1",
port=settings.PORT,
reload=settings.DEBUG,
log_level="info",
)