Silicon Valley - Admin commited on
Commit
53b7d1b
·
1 Parent(s): 49a61bb

Enhance server.py and Dockerfile for improved API documentation and static file handling

Browse files

- Added a new static directory for serving Swagger UI files.
- Introduced an endpoint to serve the Swagger UI and OpenAPI specification.
- Updated requirements.txt to include PyYAML for YAML file handling.
- Modified Dockerfile to create a directory for static files during the build process.

Files changed (4) hide show
  1. Dockerfile +3 -0
  2. requirements.txt +2 -1
  3. server.py +16 -6
  4. static/swagger.html +37 -0
Dockerfile CHANGED
@@ -15,6 +15,9 @@ COPY requirements.txt .
15
  RUN pip install --no-cache-dir --upgrade pip && \
16
  pip install --no-cache-dir -r requirements.txt
17
 
 
 
 
18
  # Copiar el resto de los archivos
19
  COPY . .
20
 
 
15
  RUN pip install --no-cache-dir --upgrade pip && \
16
  pip install --no-cache-dir -r requirements.txt
17
 
18
+ # Crear directorio para archivos estáticos
19
+ RUN mkdir -p /code/static
20
+
21
  # Copiar el resto de los archivos
22
  COPY . .
23
 
requirements.txt CHANGED
@@ -8,4 +8,5 @@ python-json-logger==2.0.7
8
  prometheus-client==0.17.1
9
  pydantic==1.10.13
10
  python-dotenv==1.0.0
11
- uvicorn==0.24.0
 
 
8
  prometheus-client==0.17.1
9
  pydantic==1.10.13
10
  python-dotenv==1.0.0
11
+ uvicorn==0.24.0
12
+ PyYAML==6.0.1
server.py CHANGED
@@ -4,9 +4,11 @@ import secrets
4
  import logging
5
  import asyncio
6
  import json
 
 
7
  from typing import Tuple
8
 
9
- from quart import Quart, websocket, request
10
  from quart_schema import QuartSchema, validate_request, validate_response
11
  from quart_cors import cors
12
  from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware
@@ -33,6 +35,11 @@ app.logger.setLevel(LOG_LEVEL)
33
 
34
  broker = SessionBroker()
35
 
 
 
 
 
 
36
  # Modelos de datos
37
  @dataclass
38
  class Status:
@@ -78,6 +85,14 @@ class ErrorResponse:
78
  error: str
79
 
80
  # Rutas API
 
 
 
 
 
 
 
 
81
  @app.get("/status")
82
  @validate_response(Status)
83
  async def status() -> Status:
@@ -163,11 +178,6 @@ async def write(data: Write) -> Tuple[WriteResponse | ErrorResponse, int]:
163
  except asyncio.TimeoutError:
164
  return ErrorResponse('Timeout when waiting for client.'), 500
165
 
166
- # Agregar un endpoint de health check y root
167
- @app.route("/")
168
- async def root():
169
- return {"message": "Kaio API Server", "version": VERSION}
170
-
171
  @app.route("/health")
172
  async def health_check():
173
  return {"status": "healthy"}
 
4
  import logging
5
  import asyncio
6
  import json
7
+ import yaml
8
+ from pathlib import Path
9
  from typing import Tuple
10
 
11
+ from quart import Quart, websocket, request, send_from_directory
12
  from quart_schema import QuartSchema, validate_request, validate_response
13
  from quart_cors import cors
14
  from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware
 
35
 
36
  broker = SessionBroker()
37
 
38
+ # Cargar OpenAPI spec
39
+ OPENAPI_PATH = Path(__file__).parent / "openapi.yaml"
40
+ with open(OPENAPI_PATH) as f:
41
+ openapi_spec = yaml.safe_load(f)
42
+
43
  # Modelos de datos
44
  @dataclass
45
  class Status:
 
85
  error: str
86
 
87
  # Rutas API
88
+ @app.route('/')
89
+ async def swagger_ui():
90
+ return await send_from_directory('static', 'swagger.html')
91
+
92
+ @app.route('/openapi.yaml')
93
+ async def openapi():
94
+ return openapi_spec
95
+
96
  @app.get("/status")
97
  @validate_response(Status)
98
  async def status() -> Status:
 
178
  except asyncio.TimeoutError:
179
  return ErrorResponse('Timeout when waiting for client.'), 500
180
 
 
 
 
 
 
181
  @app.route("/health")
182
  async def health_check():
183
  return {"status": "healthy"}
static/swagger.html ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Kaio API - Swagger UI</title>
6
+ <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/[email protected]/swagger-ui.css">
7
+ <link rel="icon" type="image/png" href="https://cdn.jsdelivr.net/npm/[email protected]/favicon-32x32.png" sizes="32x32" />
8
+ <style>
9
+ html { box-sizing: border-box; overflow: -moz-scrollbars-vertical; overflow-y: scroll; }
10
+ *, *:before, *:after { box-sizing: inherit; }
11
+ body { margin: 0; background: #fafafa; }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <div id="swagger-ui"></div>
16
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/swagger-ui-bundle.js"></script>
17
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/swagger-ui-standalone-preset.js"></script>
18
+ <script>
19
+ window.onload = function() {
20
+ const ui = SwaggerUIBundle({
21
+ url: "/openapi.yaml",
22
+ dom_id: '#swagger-ui',
23
+ deepLinking: true,
24
+ presets: [
25
+ SwaggerUIBundle.presets.apis,
26
+ SwaggerUIStandalonePreset
27
+ ],
28
+ plugins: [
29
+ SwaggerUIBundle.plugins.DownloadUrl
30
+ ],
31
+ layout: "StandaloneLayout"
32
+ });
33
+ window.ui = ui;
34
+ };
35
+ </script>
36
+ </body>
37
+ </html>