66from pathlib import Path
77
88from dotenv import load_dotenv
9- from fastapi import FastAPI
10- from fastapi .responses import FileResponse , HTMLResponse
9+ from fastapi import FastAPI , Request
10+ from fastapi .responses import FileResponse , HTMLResponse , JSONResponse
1111from fastapi .staticfiles import StaticFiles
1212from slowapi .errors import RateLimitExceeded
1313from starlette .middleware .trustedhost import TrustedHostMiddleware
1414
1515from server .routers import dynamic , index , ingest
16+ from server .server_config import templates
1617from server .server_utils import lifespan , limiter , rate_limit_exception_handler
1718
1819# Load environment variables from .env file
1920load_dotenv ()
2021
2122# Initialize the FastAPI application with lifespan
22- app = FastAPI (lifespan = lifespan )
23+ app = FastAPI (lifespan = lifespan , docs_url = None , redoc_url = None )
2324app .state .limiter = limiter
2425
2526# Register the custom exception handler for rate limits
4849async def health_check () -> dict [str , str ]:
4950 """Health check endpoint to verify that the server is running.
5051
51- Returns
52- -------
53- dict[str, str]
54- A JSON object with a "status" key indicating the server's health status.
52+ **Returns**
53+
54+ - **dict[str, str]**: A JSON object with a "status" key indicating the server's health status.
5555
5656 """
5757 return {"status" : "healthy" }
@@ -61,43 +61,103 @@ async def health_check() -> dict[str, str]:
6161async def head_root () -> HTMLResponse :
6262 """Respond to HTTP HEAD requests for the root URL.
6363
64- Mirrors the headers and status code of the index page.
64+ **This endpoint mirrors the headers and status code of the index page**
65+ for HTTP HEAD requests, providing a lightweight way to check if the server
66+ is responding without downloading the full page content.
67+
68+ **Returns**
6569
66- Returns
67- -------
68- HTMLResponse
69- An empty HTML response with appropriate headers.
70+ - **HTMLResponse**: An empty HTML response with appropriate headers
7071
7172 """
7273 return HTMLResponse (content = None , headers = {"content-type" : "text/html; charset=utf-8" })
7374
7475
7576@app .get ("/robots.txt" , include_in_schema = False )
7677async def robots () -> FileResponse :
77- """Serve the ``robots.txt`` file to guide search engine crawlers.
78+ """Serve the robots.txt file to guide search engine crawlers.
79+
80+ **This endpoint serves the ``robots.txt`` file located in the static directory**
81+ to provide instructions to search engine crawlers about which parts of the site
82+ they should or should not index.
83+
84+ **Returns**
7885
79- Returns
80- -------
81- FileResponse
82- The ``robots.txt`` file located in the static directory.
86+ - **FileResponse**: The ``robots.txt`` file located in the static directory
8387
8488 """
8589 return FileResponse ("static/robots.txt" )
8690
8791
8892@app .get ("/llms.txt" )
8993async def llm_txt () -> FileResponse :
90- """Serve the ``llms .txt`` file to provide information about the site to LLMs.
94+ """Serve the llm .txt file to provide information about the site to LLMs.
9195
92- Returns
93- -------
94- FileResponse
95- The ``llms.txt`` file located in the static directory.
96+ **This endpoint serves the ``llms.txt`` file located in the static directory**
97+ to provide information about the site to Large Language Models (LLMs)
98+ and other AI systems that may be crawling the site.
99+
100+ **Returns**
101+
102+ - **FileResponse**: The ``llms.txt`` file located in the static directory
96103
97104 """
98105 return FileResponse ("static/llms.txt" )
99106
100107
108+ @app .get ("/docs" , response_class = HTMLResponse , include_in_schema = False )
109+ async def custom_swagger_ui (request : Request ) -> HTMLResponse :
110+ """Serve custom Swagger UI documentation.
111+
112+ **This endpoint serves a custom Swagger UI interface**
113+ for the API documentation, providing an interactive way to explore
114+ and test the available endpoints.
115+
116+ **Parameters**
117+
118+ - **request** (`Request`): The incoming HTTP request
119+
120+ **Returns**
121+
122+ - **HTMLResponse**: Custom Swagger UI documentation page
123+
124+ """
125+ return templates .TemplateResponse ("swagger_ui.jinja" , {"request" : request })
126+
127+
128+ @app .get ("/api" , include_in_schema = True )
129+ def openapi_json_get () -> JSONResponse :
130+ """Return the OpenAPI schema.
131+
132+ **This endpoint returns the OpenAPI schema (openapi.json)**
133+ that describes the API structure, endpoints, and data models
134+ for documentation and client generation purposes.
135+
136+ **Returns**
137+
138+ - **JSONResponse**: The OpenAPI schema as JSON
139+
140+ """
141+ return JSONResponse (app .openapi ())
142+
143+
144+ @app .api_route ("/api" , methods = ["POST" , "PUT" , "DELETE" , "OPTIONS" , "HEAD" ], include_in_schema = False )
145+ @app .api_route ("/api/" , methods = ["GET" , "POST" , "PUT" , "DELETE" , "OPTIONS" , "HEAD" ], include_in_schema = False )
146+ def openapi_json () -> JSONResponse :
147+ """Return the OpenAPI schema for various HTTP methods.
148+
149+ **This endpoint returns the OpenAPI schema (openapi.json)**
150+ for multiple HTTP methods, providing API documentation
151+ for clients that may use different request methods.
152+
153+ **Returns**
154+
155+ - **JSONResponse**: The OpenAPI schema as JSON
156+
157+ """
158+ return JSONResponse (app .openapi ())
159+
160+
101161# Include routers for modular endpoints
102162app .include_router (index )
103163app .include_router (ingest )
0 commit comments