Skip to content

Commit 3fe28ea

Browse files
committed
refactor: makefile revision
1 parent 719b457 commit 3fe28ea

3 files changed

Lines changed: 111 additions & 2 deletions

File tree

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ up:
44
down:
55
docker compose down
66

7-
migrate:
7+
migrate: # e. g. make revision name="add auth"
88
docker compose exec backend alembic upgrade head
99

10+
revision:
11+
docker compose exec backend alembic revision -m "$(name)"
12+
1013
dev:
1114
docker compose -f docker-compose.dev.yaml up --build -d

backend/app/api/v1/routes/events.py

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1-
from fastapi import APIRouter, Depends, HTTPException, status
1+
import yaml
2+
from fastapi import (
3+
APIRouter,
4+
Depends,
5+
HTTPException,
6+
Query,
7+
Response,
8+
status,
9+
)
10+
from fastapi.responses import JSONResponse
211
from sqlalchemy.orm import Session
312

413
from app.core.database import get_db
514
from app.modules.events import crud as event_crud
615
from app.modules.events.schemas import EventCreate, EventOut
16+
from app.modules.events.service import generate_json_schema_for_event
717
from app.modules.fields.crud import get_fields_by_ids
818
from app.modules.tags.crud import get_or_create_tags
919

@@ -111,3 +121,48 @@ def delete_event_route(event_id: int, db: Session = Depends(get_db)):
111121
if db_event is None:
112122
raise HTTPException(status_code=404, detail="Event not found")
113123
return db_event
124+
125+
126+
@router.get("/events/{event_id}/schema.json", response_class=JSONResponse)
127+
def get_event_json_schema(
128+
event_id: int,
129+
include_descriptions: bool = Query(True),
130+
include_examples: bool = Query(True),
131+
additional_properties: bool = Query(True),
132+
db: Session = Depends(get_db),
133+
):
134+
db_event = event_crud.get_event(db=db, event_id=event_id)
135+
if not db_event:
136+
raise HTTPException(status_code=404, detail="Event not found")
137+
138+
event = EventOut.model_validate(db_event)
139+
schema = generate_json_schema_for_event(
140+
event,
141+
include_descriptions=include_descriptions,
142+
include_examples=include_examples,
143+
additional_properties=additional_properties,
144+
)
145+
return schema
146+
147+
148+
@router.get("/events/{event_id}/schema.yaml")
149+
def get_event_yaml_schema(
150+
event_id: int,
151+
include_descriptions: bool = Query(True),
152+
include_examples: bool = Query(True),
153+
additional_properties: bool = Query(True),
154+
db: Session = Depends(get_db),
155+
):
156+
db_event = event_crud.get_event(db=db, event_id=event_id)
157+
if not db_event:
158+
raise HTTPException(status_code=404, detail="Event not found")
159+
160+
event = EventOut.model_validate(db_event)
161+
schema = generate_json_schema_for_event(
162+
event,
163+
include_descriptions=include_descriptions,
164+
include_examples=include_examples,
165+
additional_properties=additional_properties,
166+
)
167+
yaml_data = yaml.dump(schema, sort_keys=False)
168+
return Response(content=yaml_data, media_type="application/x-yaml")
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from app.modules.events.schemas import EventOut
2+
3+
4+
def map_field_type_to_openapi(field_type: str) -> dict:
5+
return {
6+
"string": {"type": "string"},
7+
"integer": {"type": "integer", "format": "int32"},
8+
"number": {"type": "number", "format": "float"},
9+
"boolean": {"type": "boolean"},
10+
"object": {"type": "object"},
11+
"array": {"type": "array"},
12+
}.get(field_type, {"type": "string"})
13+
14+
15+
def generate_json_schema_for_event(
16+
event: EventOut,
17+
*,
18+
additional_properties: bool = True,
19+
include_descriptions: bool = True,
20+
include_examples: bool = True,
21+
) -> dict:
22+
schema = {
23+
"type": "object",
24+
"additionalProperties": additional_properties,
25+
"properties": {},
26+
"required": [],
27+
}
28+
29+
for field in event.fields:
30+
field_type_info = map_field_type_to_openapi(field.field_type)
31+
32+
field_schema = {"type": field_type_info["type"]}
33+
if "format" in field_type_info:
34+
field_schema["format"] = field_type_info["format"]
35+
36+
if include_descriptions and field.description:
37+
field_schema["description"] = field.description
38+
39+
if include_examples and field.example is not None:
40+
field_schema["example"] = field.example
41+
42+
schema["properties"][field.name] = field_schema
43+
44+
# if not field.optional:
45+
if True:
46+
schema["required"].append(field.name)
47+
48+
if not schema["required"]:
49+
del schema["required"]
50+
51+
return schema

0 commit comments

Comments
 (0)