Skip to content

Commit 9b5d63a

Browse files
committed
generate openapi spec
1 parent b5b1f7d commit 9b5d63a

File tree

4 files changed

+215
-0
lines changed

4 files changed

+215
-0
lines changed

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,10 @@ azure-functions-functionapp-deploy: ## deploy Azure Functions App
114114
--with backend,azure-functions \
115115
--without-hashes
116116
func azure functionapp publish $(shell jq -r '.FUNCTION_APP_NAME' < azure-functions.json)
117+
118+
# ---
119+
# OpenAPI Client
120+
# ---
121+
.PHONY: generate-openapi-spec
122+
generate-openapi-spec: ## generate OpenAPI spec
123+
poetry run python main.py generate-openapi-spec

docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- [FastAPI > Bigger Applications - Multiple Files](https://fastapi.tiangolo.com/tutorial/bigger-applications/)
1111
- [FastAPI > Request Body](https://fastapi.tiangolo.com/tutorial/body/)
1212
- [FastAPI > UploadFile class](https://fastapi.tiangolo.com/reference/uploadfile/)
13+
- [FastAPI > Extending OpenAPI](https://fastapi.tiangolo.com/how-to/extending-openapi/)
1314

1415
## Frontend
1516

main.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,24 @@ def frontend(
5555
)
5656

5757

58+
@app.command()
59+
def generate_openapi_spec(
60+
path: Annotated[str, typer.Option(help="Output file path")] = "./specs/openapi.json",
61+
):
62+
import json
63+
64+
from backend.fastapi import app
65+
66+
# create directory if not exists
67+
os.makedirs(os.path.dirname(path), exist_ok=True)
68+
69+
# generate OpenAPI spec
70+
with open(path, "w") as f:
71+
api_spec = app.openapi()
72+
f.write(json.dumps(api_spec, indent=2))
73+
logging.info(f"OpenAPI spec generated at {path}")
74+
75+
5876
if __name__ == "__main__":
5977
load_dotenv()
6078
app()

specs/openapi.json

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
{
2+
"openapi": "3.1.0",
3+
"info": {
4+
"title": "FastAPI",
5+
"version": "0.1.0"
6+
},
7+
"paths": {
8+
"/azure_openai/chat_completions/": {
9+
"post": {
10+
"tags": ["azure_openai"],
11+
"summary": "Create Chat Completions",
12+
"operationId": "create_chat_completions_azure_openai_chat_completions__post",
13+
"requestBody": {
14+
"content": {
15+
"application/json": {
16+
"schema": {
17+
"$ref": "#/components/schemas/ChatCompletionRequest"
18+
}
19+
}
20+
},
21+
"required": true
22+
},
23+
"responses": {
24+
"200": {
25+
"description": "Successful Response",
26+
"content": {
27+
"application/json": {
28+
"schema": {
29+
"$ref": "#/components/schemas/ChatCompletionResponse"
30+
}
31+
}
32+
}
33+
},
34+
"404": {
35+
"description": "Not found"
36+
},
37+
"422": {
38+
"description": "Validation Error",
39+
"content": {
40+
"application/json": {
41+
"schema": {
42+
"$ref": "#/components/schemas/HTTPValidationError"
43+
}
44+
}
45+
}
46+
}
47+
}
48+
}
49+
},
50+
"/document_intelligence/analyze_document/": {
51+
"post": {
52+
"tags": ["document_intelligence"],
53+
"summary": "Analyze Document",
54+
"operationId": "analyze_document_document_intelligence_analyze_document__post",
55+
"requestBody": {
56+
"content": {
57+
"multipart/form-data": {
58+
"schema": {
59+
"$ref": "#/components/schemas/Body_analyze_document_document_intelligence_analyze_document__post"
60+
}
61+
}
62+
},
63+
"required": true
64+
},
65+
"responses": {
66+
"200": {
67+
"description": "Successful Response",
68+
"content": {
69+
"application/json": {
70+
"schema": {
71+
"$ref": "#/components/schemas/AnalyzeDocumentResponse"
72+
}
73+
}
74+
}
75+
},
76+
"404": {
77+
"description": "Not found"
78+
},
79+
"422": {
80+
"description": "Validation Error",
81+
"content": {
82+
"application/json": {
83+
"schema": {
84+
"$ref": "#/components/schemas/HTTPValidationError"
85+
}
86+
}
87+
}
88+
}
89+
}
90+
}
91+
}
92+
},
93+
"components": {
94+
"schemas": {
95+
"AnalyzeDocumentResponse": {
96+
"properties": {
97+
"content": {
98+
"type": "string",
99+
"title": "Content"
100+
}
101+
},
102+
"type": "object",
103+
"required": ["content"],
104+
"title": "AnalyzeDocumentResponse"
105+
},
106+
"Body_analyze_document_document_intelligence_analyze_document__post": {
107+
"properties": {
108+
"file": {
109+
"type": "string",
110+
"format": "binary",
111+
"title": "File"
112+
}
113+
},
114+
"type": "object",
115+
"required": ["file"],
116+
"title": "Body_analyze_document_document_intelligence_analyze_document__post"
117+
},
118+
"ChatCompletionRequest": {
119+
"properties": {
120+
"content": {
121+
"type": "string",
122+
"title": "Content"
123+
},
124+
"stream": {
125+
"type": "boolean",
126+
"title": "Stream",
127+
"default": false
128+
}
129+
},
130+
"type": "object",
131+
"required": ["content"],
132+
"title": "ChatCompletionRequest"
133+
},
134+
"ChatCompletionResponse": {
135+
"properties": {
136+
"content": {
137+
"type": "string",
138+
"title": "Content"
139+
}
140+
},
141+
"type": "object",
142+
"required": ["content"],
143+
"title": "ChatCompletionResponse"
144+
},
145+
"HTTPValidationError": {
146+
"properties": {
147+
"detail": {
148+
"items": {
149+
"$ref": "#/components/schemas/ValidationError"
150+
},
151+
"type": "array",
152+
"title": "Detail"
153+
}
154+
},
155+
"type": "object",
156+
"title": "HTTPValidationError"
157+
},
158+
"ValidationError": {
159+
"properties": {
160+
"loc": {
161+
"items": {
162+
"anyOf": [
163+
{
164+
"type": "string"
165+
},
166+
{
167+
"type": "integer"
168+
}
169+
]
170+
},
171+
"type": "array",
172+
"title": "Location"
173+
},
174+
"msg": {
175+
"type": "string",
176+
"title": "Message"
177+
},
178+
"type": {
179+
"type": "string",
180+
"title": "Error Type"
181+
}
182+
},
183+
"type": "object",
184+
"required": ["loc", "msg", "type"],
185+
"title": "ValidationError"
186+
}
187+
}
188+
}
189+
}

0 commit comments

Comments
 (0)