Skip to content

Commit 9716693

Browse files
authored
Merge pull request #32 from msamsami/docs/improve-examples-and-clarity
📝 Improve documentation examples and clarity
2 parents c201d5a + 94126db commit 9716693

11 files changed

Lines changed: 83 additions & 60 deletions

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ app = FastAPI()
7171
app.add_middleware(MaintenanceModeMiddleware)
7272

7373
@app.get("/")
74-
def root():
74+
async def root():
7575
return {"message": "Hello World"}
7676
```
7777

docs/contributing.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
We welcome contributions from the community to help improve FastAPI Maintenance.
44

5-
First, you might want to see the basic ways to [help FastAPI Maintenance package and get help](help.md).
5+
First, you might want to see the basic ways to [help FastAPI Maintenance project and get help](help.md).
66

77
## Developing
88

@@ -49,7 +49,7 @@ We use pytest for testing. To run the tests and generate coverage reports:
4949
bash scripts/test.sh
5050
```
5151

52-
This command generates a directory `./htmlcov/`, if you open the file `./htmlcov/index.html` in your browser, you can explore interactively the regions of code that are covered by the tests, and notice if there is any region missing.
52+
This command generates a directory `./htmlcov/`. Open the file `./htmlcov/index.html` in your browser to interactively explore which regions of code are covered by tests and identify any missing coverage.
5353

5454
## Docs
5555

docs/help.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Help
22

3-
This section provides information on how to get help with FastAPI Maintenance and how you can contribute to the project.
3+
This section provides information on how to get help with FastAPI Maintenance and how you can support the project.
44

55
## Getting Help
66

docs/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ app = FastAPI()
7171
app.add_middleware(MaintenanceModeMiddleware)
7272

7373
@app.get("/")
74-
def root():
74+
async def root():
7575
return {"message": "Hello World"}
7676
```
7777

docs/tutorial/advanced-usage.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
# Advanced Usage
22

3-
This section covers advanced usage patterns and integration scenarios for the FastAPI Maintenance package. These advanced usage patterns demonstrate how FastAPI Maintenance can be integrated into complex systems and workflows.
3+
This section covers advanced usage patterns and integration scenarios, demonstrating how FastAPI Maintenance can be integrated into complex systems and workflows.
44

55
## Combining Multiple Features
66

77
You can combine various features of FastAPI Maintenance for sophisticated maintenance scenarios:
88

99
```python
10-
from fastapi import FastAPI, Request, Depends
10+
from fastapi import FastAPI, Request
1111
from fastapi.responses import JSONResponse
1212
from fastapi_maintenance import (
1313
MaintenanceModeMiddleware,
@@ -62,6 +62,8 @@ async def update_system():
6262
You can use FastAPI's events to configure maintenance mode during application startup and shutdown:
6363

6464
```python
65+
from contextlib import asynccontextmanager
66+
6567
from fastapi import FastAPI
6668
from fastapi_maintenance import (
6769
MaintenanceModeMiddleware,
@@ -72,18 +74,16 @@ from fastapi_maintenance import (
7274
# Configure backend
7375
configure_backend("file", file_path="maintenance_mode.txt")
7476

75-
app = FastAPI()
76-
app.add_middleware(MaintenanceModeMiddleware)
77-
78-
@app.on_event("startup")
79-
async def startup_event():
80-
# Clear any maintenance mode from previous crashes on startup
77+
@asynccontextmanager
78+
async def lifespan(app: FastAPI):
79+
# Startup: Clear any maintenance mode from previous crashes
8180
await set_maintenance_mode(False)
82-
83-
@app.on_event("shutdown")
84-
async def shutdown_event():
85-
# Enable maintenance mode during shutdown
81+
yield
82+
# Shutdown: Enable maintenance mode
8683
await set_maintenance_mode(True)
84+
85+
app = FastAPI(lifespan=lifespan)
86+
app.add_middleware(MaintenanceModeMiddleware)
8787
```
8888

8989
## Integration with Other Middleware

docs/tutorial/backends.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Backend Options
22

3-
FastAPI Maintenance provides flexible backend storage options for managing the maintenance mode state. This allows you to store the maintenance mode state in different ways depending on your application's needs.
3+
FastAPI Maintenance provides flexible backend storage options for managing the maintenance mode state. This allows you to store and read the maintenance mode state in different ways depending on your application's needs.
44

55
## Available Backends
66

77
The package currently includes two built-in backend options:
88

9-
1. **Environment Variable Backend** (default): Uses environment variables to store the maintenance mode state
9+
1. **Environment Variable Backend** (default): Reads the maintenance mode state from environment variables
1010
2. **Local File Backend**: Uses a local file to store the maintenance mode state
1111

1212
## Environment Variable Backend
@@ -41,7 +41,7 @@ The environment variable backend is **read-only** at runtime. This means:
4141

4242
- You can only set the maintenance mode state *before* starting your application.
4343
- Direct calls to `set_maintenance_mode()` will log a warning and have no effect.
44-
- However, context manager `maintenance_mode_on()` **will work as expected for the duration of the context block**. They achieve this by using a temporary, in-memory override of the maintenance state. The actual environment variable is not changed. This allows you to temporarily simulate maintenance mode changes even with the environment variable backend.
44+
- However, context manager `maintenance_mode_on()` **will work as expected for the duration of the context block**. It achieves this by using a temporary, in-memory override of the maintenance state. The actual environment variable is not changed. This allows you to temporarily simulate maintenance mode changes even with the environment variable backend.
4545

4646
Use this backend when you primarily manage maintenance mode state externally (e.g., via deployment scripts or orchestration tools) but still want the flexibility of temporary overrides within your code using context managers.
4747

docs/tutorial/cli.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ Use the CLI in monitoring scripts:
110110
#!/bin/bash
111111

112112
# Check maintenance status and act accordingly
113+
# Note: This script relies on the CLI output containing "ON" for active maintenance
113114
if fastapi-maintenance status --backend env --var-name PROD_MAINTENANCE_MODE | grep -q "ON"; then
114115
echo "Application is in maintenance mode"
115116
exit 1
@@ -128,14 +129,11 @@ Integrate with deployment automation:
128129

129130
# Check if maintenance mode is active before deployment
130131
echo "Checking maintenance mode status..."
131-
fastapi-maintenance status --backend file --file-path /app/maintenance.txt
132132

133-
# The exit code can be used in conditional logic
134-
if [ $? -eq 0 ]; then
135-
echo "Status check completed successfully"
136-
else
137-
echo "Failed to check maintenance status"
138-
exit 1
133+
STATUS=$(fastapi-maintenance status --backend file --file-path /app/maintenance.txt)
134+
135+
if echo "$STATUS" | grep -q "ON"; then
136+
echo "Warning: Application is in maintenance mode"
139137
fi
140138
```
141139

docs/tutorial/context-manager.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ FastAPI Maintenance provides an async context manager that temporarily enables m
66
- Application deployments
77
- Data imports or exports
88
- Content synchronization and updates
9-
- System updates
109
- User permission and role updates
11-
- Rolling out new features
1210
- Temporarily disabling services during critical operations
1311

1412
## Basic Usage
@@ -115,9 +113,11 @@ async def custom_maintenance_operation():
115113

116114
## Nesting Context Managers
117115

118-
You can nest the `maintenance_mode_on` context manager. When nesting, the innermost context will maintain the state established by the outer context:
116+
You can nest the `maintenance_mode_on` context manager. When nesting, maintenance mode remains ON throughout all nested contexts until the outermost context exits:
119117

120118
```python
119+
from fastapi_maintenance import maintenance_mode_on, get_maintenance_mode
120+
121121
async def complex_operation():
122122
# Start with maintenance OFF
123123
assert not await get_maintenance_mode()

docs/tutorial/custom-exemptions.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ The handler function must:
6363
# Synchronous handler
6464
def is_exempt(request: Request) -> bool:
6565
# Logic here
66-
return True/False
66+
return True # or False
6767

6868
# Asynchronous handler
6969
async def is_exempt(request: Request) -> bool:
7070
# Async logic here
71-
return True/False
71+
return True # or False
7272
```
7373

7474
### Return Value
@@ -79,7 +79,7 @@ The return value determines how the request is handled:
7979

8080
### Execution Context
8181

82-
The handler runs for every request when maintenance middleware is in place, so:
82+
The handler is evaluated for every request that reaches the maintenance middleware, so:
8383
- Keep it lightweight to avoid performance issues
8484
- Handle all exceptions internally
8585
- Avoid side effects that could impact other requests
@@ -112,7 +112,10 @@ def is_exempt(request: Request) -> bool:
112112
client_host = request.client.host if request.client else None
113113

114114
# Exempt localhost and internal network
115-
if client_host in ["127.0.0.1", "::1"] or client_host.startswith("10."):
115+
if client_host and (
116+
client_host in ["127.0.0.1", "::1"]
117+
or client_host.startswith("10.")
118+
):
116119
return True
117120

118121
return False

docs/tutorial/custom-responses.md

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ from fastapi_maintenance import MaintenanceModeMiddleware
5656

5757
app = FastAPI()
5858

59-
async def custom_maintenance_response(request: Request) -> JSONResponse:
59+
def custom_maintenance_response(request: Request) -> JSONResponse:
6060
return JSONResponse(
6161
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
6262
content={
@@ -86,7 +86,7 @@ from fastapi_maintenance import MaintenanceModeMiddleware
8686

8787
app = FastAPI()
8888

89-
async def html_maintenance_page(request: Request) -> HTMLResponse:
89+
def html_maintenance_page(request: Request) -> HTMLResponse:
9090
html_content = """
9191
<!DOCTYPE html>
9292
<html>
@@ -153,7 +153,7 @@ from fastapi_maintenance import MaintenanceModeMiddleware
153153

154154
app = FastAPI()
155155

156-
async def content_negotiated_response(request: Request) -> Response:
156+
def content_negotiated_response(request: Request) -> Response:
157157
accept = request.headers.get("accept", "")
158158

159159
# Return HTML for browser requests
@@ -191,11 +191,15 @@ app = FastAPI()
191191
# Set up templates
192192
templates = Jinja2Templates(directory="templates")
193193

194-
async def template_maintenance_page(request: Request) -> Response:
194+
def template_maintenance_page(request: Request) -> Response:
195195
# Pass data to the template
196196
return templates.TemplateResponse(
197197
"maintenance.html",
198-
{"request": request, "site_name": "My API", "estimated_time": "2 hours"},
198+
{
199+
"request": request,
200+
"site_name": "My API",
201+
"estimated_time": "2 hours",
202+
},
199203
status_code=503
200204
)
201205

@@ -238,7 +242,7 @@ from fastapi_maintenance import MaintenanceModeMiddleware
238242

239243
app = FastAPI()
240244

241-
async def path_aware_response(request: Request) -> JSONResponse:
245+
def path_aware_response(request: Request) -> JSONResponse:
242246
# Customize message based on path
243247
path = request.url.path
244248

@@ -259,3 +263,41 @@ app.add_middleware(
259263
response_handler=path_aware_response
260264
)
261265
```
266+
267+
### Async Response Handler
268+
269+
When you need to fetch maintenance information from a database or external service, you can use an async response handler:
270+
271+
```python
272+
from fastapi import FastAPI, Request
273+
from fastapi.responses import JSONResponse
274+
from fastapi_maintenance import MaintenanceModeMiddleware
275+
import httpx
276+
277+
app = FastAPI()
278+
279+
async def async_maintenance_response(request: Request) -> JSONResponse:
280+
# Fetch maintenance status from external status page API
281+
async with httpx.AsyncClient() as client:
282+
try:
283+
response = await client.get("https://status.example.com/api/maintenance")
284+
status_data = response.json()
285+
estimated_end = status_data.get("estimated_end", "unknown")
286+
except:
287+
estimated_end = "unknown"
288+
289+
return JSONResponse(
290+
content={
291+
"status": "maintenance",
292+
"message": "Service temporarily unavailable",
293+
"estimated_completion": estimated_end
294+
},
295+
status_code=503,
296+
headers={"Retry-After": "1800"}
297+
)
298+
299+
app.add_middleware(
300+
MaintenanceModeMiddleware,
301+
response_handler=async_maintenance_response
302+
)
303+
```

0 commit comments

Comments
 (0)