Skip to content

Commit d0691ce

Browse files
committed
Corrected examples,added docs, added tests for Quart and increased version
1 parent afc337e commit d0691ce

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+585
-2203
lines changed

CHANGELOG.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ All notable changes to FastOpenAPI are documented in this file.
44

55
FastOpenAPI follows the [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) format.
66

7-
## [0.3.0] - Unreleased
7+
## [0.3.0] - 2025-03-15
88

99
### Added
1010
- `QuartRouter` for integration with the `Quart` framework.
11+
- Initial Documentation
12+
13+
### Changed
14+
- Import of routers. You can use `from fastopenapi.routers import YourRouter`
1115

1216
### Fixed
1317
- Fixed retrieving parameters for BaseModel as arguments in GET routes.
@@ -36,6 +40,6 @@ FastOpenAPI follows the [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
3640
## [0.1.0] - 2025-03-01
3741

3842
### Added
39-
- Initial release of the library.
43+
- Initial release of FastOpenAPI.
4044
- Implemented core modules: `base`, `falcon`, `flask`, `sanic`, `starlette`.
4145
- Added basic documentation and tests.

README.md

Lines changed: 180 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<img src="https://codecov.io/gh/mr-fatalyst/fastopenapi/branch/master/graph/badge.svg?token=USHR1I0CJB">
1313
<img src="https://img.shields.io/pypi/v/fastopenapi">
1414
<img src="https://img.shields.io/pypi/pyversions/fastopenapi">
15+
<img src="https://static.pepy.tech/badge/fastopenapi" alt="PyPI Downloads">
1516
</p>
1617

1718
---
@@ -39,153 +40,209 @@ pip install fastopenapi[starlette]
3940

4041
---
4142

42-
## ⚙️ Features
43-
- 📄 **Generate OpenAPI schemas** with Pydantic v2.
44-
- 🛡️ **Data validation** using Pydantic models.
45-
- 🛠️ **Supports multiple frameworks:** Falcon, Flask, Sanic, Starlette.
46-
-**Compatible with Pydantic v2.**
47-
48-
---
49-
5043
## 🛠️ Quick Start
5144

52-
### ![Falcon](https://img.shields.io/badge/Falcon-45b8d8?style=flat&logo=falcon&logoColor=white) Example
53-
<details>
54-
<summary>Click to expand</summary>
55-
56-
```python
57-
import falcon.asgi
58-
import uvicorn
59-
from pydantic import BaseModel
60-
61-
from fastopenapi.routers.falcon import FalconRouter
62-
63-
app = falcon.asgi.App()
64-
router = FalconRouter(app=app, docs_url="/docs/", openapi_version="3.0.0")
65-
66-
67-
class HelloResponse(BaseModel):
68-
message: str
69-
70-
71-
@router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse)
72-
async def hello(name: str):
73-
"""Say hello from Falcon"""
74-
return HelloResponse(message=f"Hello, {name}! It's Falcon!")
45+
### Step 1. Create an application
46+
47+
- Create the `main.py` file
48+
- Copy the code from an example
49+
- For some examples uvicorn is required (`pip install uvicorn`)
50+
51+
#### Examples:
52+
53+
- ![Falcon](https://img.shields.io/badge/Falcon-45b8d8?style=flat&logo=falcon&logoColor=white)
54+
<details>
55+
<summary>Click to expand the Falcon Example</summary>
56+
57+
```python
58+
import falcon.asgi
59+
import uvicorn
60+
from pydantic import BaseModel
61+
62+
from fastopenapi.routers import FalconRouter
63+
64+
app = falcon.asgi.App()
65+
router = FalconRouter(app=app, docs_url="/docs/", openapi_version="3.0.0")
66+
67+
68+
class HelloResponse(BaseModel):
69+
message: str
70+
71+
72+
@router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse)
73+
async def hello(name: str):
74+
"""Say hello from Falcon"""
75+
return HelloResponse(message=f"Hello, {name}! It's Falcon!")
76+
77+
78+
if __name__ == "__main__":
79+
uvicorn.run(app, host="127.0.0.1", port=8000)
80+
```
81+
</details>
82+
83+
- ![Flask](https://img.shields.io/badge/-Flask-000000?style=flat&logo=flask&logoColor=white)
84+
<details>
85+
<summary>Click to expand the Flask Example</summary>
86+
87+
```python
88+
from flask import Flask
89+
from pydantic import BaseModel
90+
91+
from fastopenapi.routers import FlaskRouter
92+
93+
app = Flask(__name__)
94+
router = FlaskRouter(app=app, docs_url="/docs/", openapi_version="3.0.0")
95+
96+
97+
class HelloResponse(BaseModel):
98+
message: str
99+
100+
101+
@router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse)
102+
def hello(name: str):
103+
"""Say hello from Flask"""
104+
return HelloResponse(message=f"Hello, {name}! It's Flask!")
105+
106+
107+
if __name__ == "__main__":
108+
app.run(port=8000)
109+
```
110+
</details>
111+
112+
- ![Quart](https://img.shields.io/badge/-Quart-4997D0?style=flat&logo=python&logoColor=white)
113+
<details>
114+
<summary>Click to expand the Quart Example</summary>
115+
116+
```python
117+
from pydantic import BaseModel
118+
from quart import Quart
119+
120+
from fastopenapi.routers import QuartRouter
121+
122+
app = Quart(__name__)
123+
router = QuartRouter(app=app, docs_url="/docs/", openapi_version="3.0.0")
124+
125+
126+
class HelloResponse(BaseModel):
127+
message: str
128+
129+
130+
@router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse)
131+
async def hello(name: str):
132+
"""Say hello from Quart"""
133+
return HelloResponse(message=f"Hello, {name}! It's Quart!")
134+
135+
136+
if __name__ == "__main__":
137+
app.run(port=8000)
138+
```
139+
</details>
140+
141+
- ![Sanic](https://img.shields.io/badge/-Sanic-00bfff?style=flat&logo=sanic&logoColor=white)
142+
<details>
143+
<summary>Click to expand the Sanic Example</summary>
144+
145+
```python
146+
from pydantic import BaseModel
147+
from sanic import Sanic
148+
149+
from fastopenapi.routers import SanicRouter
150+
151+
app = Sanic("MySanicApp")
152+
router = SanicRouter(app=app, docs_url="/docs/", openapi_version="3.0.0")
153+
154+
155+
class HelloResponse(BaseModel):
156+
message: str
157+
158+
159+
@router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse)
160+
async def hello(name: str):
161+
"""Say hello from Sanic"""
162+
return HelloResponse(message=f"Hello, {name}! It's Sanic!")
163+
164+
165+
if __name__ == "__main__":
166+
app.run(host="0.0.0.0", port=8000)
167+
```
168+
</details>
169+
170+
- ![Starlette](https://img.shields.io/badge/-Starlette-4B0082?style=flat&logo=fastapi&logoColor=white)
171+
<details>
172+
<summary>Click to expand the Starlette Example</summary>
173+
174+
```python
175+
import uvicorn
176+
from pydantic import BaseModel
177+
from starlette.applications import Starlette
178+
179+
from fastopenapi.routers import StarletteRouter
180+
181+
app = Starlette()
182+
router = StarletteRouter(app=app, docs_url="/docs/", openapi_version="3.0.0")
183+
184+
185+
class HelloResponse(BaseModel):
186+
message: str
187+
188+
189+
@router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse)
190+
async def hello(name: str):
191+
"""Say hello from Starlette"""
192+
return HelloResponse(message=f"Hello, {name}! It's Starlette!")
193+
194+
if __name__ == "__main__":
195+
uvicorn.run(app, host="127.0.0.1", port=8000)
196+
```
197+
</details>
198+
199+
### Step 2. Run the server
200+
201+
Launch the application:
75202

76-
77-
if __name__ == "__main__":
78-
uvicorn.run(app, host="127.0.0.1", port=8000)
203+
```bash
204+
python main.py
79205
```
80-
</details>
81-
82-
---
83-
84-
### ![Flask](https://img.shields.io/badge/-Flask-000000?style=flat-square&logo=flask&logoColor=white) Example
85-
<details>
86-
<summary>Click to expand</summary>
87-
88-
```python
89-
from flask import Flask
90-
from pydantic import BaseModel
91-
92-
from fastopenapi.routers.flask import FlaskRouter
93-
94-
app = Flask(__name__)
95-
router = FlaskRouter(app=app, docs_url="/docs/", openapi_version="3.0.0")
96-
97-
98-
class HelloResponse(BaseModel):
99-
message: str
100206

207+
Once launched, the documentation will be available at:
101208

102-
@router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse)
103-
def hello(name: str):
104-
"""Say hello from Flask"""
105-
return HelloResponse(message=f"Hello, {name}! It's Flask!")
106-
107-
108-
if __name__ == "__main__":
109-
app.run(debug=True, port=8000)
110209
```
111-
</details>
210+
http://127.0.0.1:8000/docs/
211+
```
112212

113213
---
114214

115-
### ![Sanic](https://img.shields.io/badge/-Sanic-00bfff?style=flat-square&logo=sanic&logoColor=white) Example
116-
<details>
117-
<summary>Click to expand</summary>
118-
119-
```python
120-
from pydantic import BaseModel
121-
from sanic import Sanic
122-
123-
from fastopenapi.routers.sanic import SanicRouter
124-
125-
app = Sanic("MySanicApp")
126-
router = SanicRouter(app=app, docs_url="/docs/", openapi_version="3.0.0")
127-
128-
129-
class HelloResponse(BaseModel):
130-
message: str
131-
132-
133-
@router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse)
134-
async def hello(name: str):
135-
"""Say hello from Sanic"""
136-
return HelloResponse(message=f"Hello, {name}! It's Sanic!")
137-
138-
139-
if __name__ == "__main__":
140-
app.run(host="0.0.0.0", port=8000, debug=True)
141-
```
142-
</details>
215+
## ⚙️ Features
216+
- **Generate OpenAPI schemas** with Pydantic v2.
217+
- **Data validation** using Pydantic models.
218+
- **Supports multiple frameworks:** Falcon, Flask, Quart, Sanic, Starlette.
219+
- **Proxy routing provides FastAPI-style routing**
143220

144221
---
145222

146-
### ![Starlette](https://img.shields.io/badge/-Starlette-ff4785?style=flat-square&logo=starlette&logoColor=white) Example
147-
<details>
148-
<summary>Click to expand</summary>
149-
150-
```python
151-
import uvicorn
152-
from pydantic import BaseModel
153-
from starlette.applications import Starlette
223+
## 📖 Documentation
154224

155-
from fastopenapi.routers.starlette import StarletteRouter
225+
Explore the [Docs](https://github.com/mr-fatalyst/fastopenapi/blob/master/docs/en/index.md) for an overview of FastOpenAPI, its core components, and usage guidelines. The documentation is continuously updated and improved.
156226

157-
app = Starlette()
158-
router = StarletteRouter(app=app, docs_url="/docs/", openapi_version="3.0.0")
227+
---
159228

229+
## 📂 Advanced Examples
160230

161-
class HelloResponse(BaseModel):
162-
message: str
231+
Examples of integration and detailed usage for each framework are available in the [`examples`](https://github.com/mr-fatalyst/fastopenapi/tree/master/examples) directory.
163232

233+
---
164234

165-
@router.get("/hello", tags=["Hello"], status_code=200, response_model=HelloResponse)
166-
async def hello(name: str):
167-
"""Say hello from Starlette"""
168-
return HelloResponse(message=f"Hello, {name}! It's Starlette!")
235+
## ✅ Development Recommendations
169236

170-
if __name__ == "__main__":
171-
uvicorn.run(app, host="127.0.0.1", port=8000)
172-
```
173-
</details>
237+
- Use Pydantic models for strict typing and data validation.
238+
- Follow the project structure similar to provided examples for easy scalability.
239+
- Regularly update dependencies and monitor library updates for new features.
174240

175241
---
176242

177-
## 🛡️ **Type Safety with Pydantic v2**
178-
```python
179-
from pydantic import BaseModel
243+
## 🛠️ Contributing
180244

181-
class User(BaseModel):
182-
id: int
183-
name: str
184-
185-
@router.post("/api/v1/users/")
186-
def create_user(user: User) -> User:
187-
return user
188-
```
245+
If you have suggestions or find a bug, please open an issue or create a pull request on GitHub.
189246

190247
---
191248

docs/en/architecture.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Architecture
2+
3+
FastOpenAPI uses modular architecture:
4+
5+
- **BaseRouter**: Abstract base class providing routing and schema generation.
6+
- **Framework Routers**: Specific routers inheriting BaseRouter.
7+
8+
## File Structure
9+
10+
```
11+
fastopenapi/
12+
├── base_router.py
13+
└── routers/
14+
├── falcon.py
15+
├── flask.py
16+
├── quart.py
17+
├── sanic.py
18+
└── starlette.py
19+
```
20+
---
21+
[<< Back](index.md)

0 commit comments

Comments
 (0)