Skip to content

Commit b77e71f

Browse files
added new features, fixed cdn bug
1 parent 1653e3a commit b77e71f

17 files changed

+3696
-32
lines changed

MANIFEST.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
include README.md
2+
include LICENSE
3+
recursive-include fastapi_docshield/static *

README.md

Lines changed: 162 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ pip install -e .
3434

3535
## Quick Usage
3636

37+
### Single User
38+
3739
```python
3840
from fastapi import FastAPI
3941
from fastapi_docshield import DocShield
@@ -44,13 +46,145 @@ app = FastAPI()
4446
def read_root():
4547
return {"Hello": "World"}
4648

47-
# Add protection to docs
49+
# Add protection to docs with a single user
4850
DocShield(
4951
app=app,
5052
credentials={"admin": "password123"}
5153
)
5254
```
5355

56+
### Multiple Users
57+
58+
```python
59+
from fastapi import FastAPI
60+
from fastapi_docshield import DocShield
61+
62+
app = FastAPI()
63+
64+
@app.get("/")
65+
def read_root():
66+
return {"Hello": "World"}
67+
68+
# Add protection to docs with multiple users
69+
DocShield(
70+
app=app,
71+
credentials={
72+
"admin": "admin_password",
73+
"developer": "dev_password",
74+
"viewer": "viewer_password"
75+
}
76+
)
77+
```
78+
79+
### CDN Fallback Mode (Default)
80+
81+
```python
82+
from fastapi import FastAPI
83+
from fastapi_docshield import DocShield
84+
85+
app = FastAPI()
86+
87+
# Default mode: Use CDN with automatic fallback to local files
88+
DocShield(
89+
app=app,
90+
credentials={"admin": "password123"},
91+
use_cdn_fallback=True # Default - automatically falls back to local if CDN fails
92+
)
93+
```
94+
95+
### Prefer Local Files
96+
97+
```python
98+
from fastapi import FastAPI
99+
from fastapi_docshield import DocShield
100+
101+
app = FastAPI()
102+
103+
# Always use local files instead of CDN
104+
DocShield(
105+
app=app,
106+
credentials={"admin": "password123"},
107+
prefer_local=True # Serve documentation from bundled static files
108+
)
109+
```
110+
111+
### CDN Only (No Fallback)
112+
113+
```python
114+
from fastapi import FastAPI
115+
from fastapi_docshield import DocShield
116+
117+
app = FastAPI()
118+
119+
# Use CDN without fallback (original behavior)
120+
DocShield(
121+
app=app,
122+
credentials={"admin": "password123"},
123+
use_cdn_fallback=False # Disable fallback, CDN only
124+
)
125+
```
126+
127+
### Custom CSS and JavaScript
128+
129+
```python
130+
from fastapi import FastAPI
131+
from fastapi_docshield import DocShield
132+
import requests
133+
134+
app = FastAPI()
135+
136+
# Load dark theme CSS from external source
137+
# You can use https://github.com/georgekhananaev/fastapi-swagger-dark
138+
dark_theme_url = "https://raw.githubusercontent.com/georgekhananaev/fastapi-swagger-dark/main/src/fastapi_swagger_dark/swagger_ui_dark.min.css"
139+
custom_css = requests.get(dark_theme_url).text
140+
141+
# Custom JavaScript for analytics
142+
custom_js = """
143+
console.log('📊 Documentation accessed at:', new Date().toISOString());
144+
document.addEventListener('DOMContentLoaded', function() {
145+
console.log('Dark theme loaded!');
146+
});
147+
"""
148+
149+
# Apply with custom styling
150+
DocShield(
151+
app=app,
152+
credentials={"admin": "password123"},
153+
custom_css=custom_css,
154+
custom_js=custom_js
155+
)
156+
```
157+
158+
#### Using with fastapi-swagger-dark
159+
160+
For a complete dark theme solution, you can use the [fastapi-swagger-dark](https://github.com/georgekhananaev/fastapi-swagger-dark) package:
161+
162+
```python
163+
from fastapi import FastAPI
164+
from fastapi_docshield import DocShield
165+
import requests
166+
167+
app = FastAPI()
168+
169+
# Fetch dark theme CSS
170+
response = requests.get(
171+
"https://raw.githubusercontent.com/georgekhananaev/fastapi-swagger-dark/main/src/fastapi_swagger_dark/swagger_ui_dark.min.css"
172+
)
173+
dark_css = response.text
174+
175+
DocShield(
176+
app=app,
177+
credentials={"admin": "password123"},
178+
custom_css=dark_css # Apply dark theme
179+
)
180+
```
181+
182+
See [examples/custom_styling.py](examples/custom_styling.py) for more customization examples including:
183+
- ✨ Minimal clean theme
184+
- 🏢 Corporate theme with analytics
185+
- 📖 ReDoc customization
186+
- 🎨 Custom branding
187+
54188
## Running Demo
55189

56190
```bash
@@ -80,9 +214,36 @@ pytest --cov=fastapi_docshield
80214
- Protect Swagger UI, ReDoc, and OpenAPI JSON endpoints
81215
- Customizable endpoint URLs
82216
- Multiple username/password combinations
217+
- **Automatic CDN fallback** - Falls back to local files if CDN is unavailable
218+
- **Local file preference option** - Serve documentation from local files for better reliability
219+
- **Custom CSS and JavaScript injection** - Fully customize the look and behavior of documentation
220+
- **Resilient documentation** - Works even when CDN is down or blocked
83221
- Tested on Python 3.7-3.13
84222
- Compatible with uv package manager
85223

224+
## Changelog
225+
226+
### Version 0.2.0 (2025-08-17)
227+
- **Added**: Custom CSS and JavaScript injection support
228+
- New `custom_css` parameter to inject custom styles into documentation pages
229+
- New `custom_js` parameter to inject custom JavaScript for enhanced functionality
230+
- Complete customization examples for dark theme, minimal theme, corporate branding, and analytics
231+
- Support for both Swagger UI and ReDoc customization
232+
- **Added**: Automatic CDN fallback to local files for better reliability
233+
- Documentation now automatically falls back to bundled static files if CDN is unavailable
234+
- New `prefer_local` option to always serve from local files
235+
- New `use_cdn_fallback` option to control fallback behavior
236+
- Bundled Swagger UI and ReDoc static files for offline capability
237+
- **Fixed**: Static file URL bug that caused blank documentation pages
238+
- Previously, when no custom CDN URLs were provided, the package would pass `None` values to FastAPI's documentation functions
239+
- This resulted in HTML with `href="None"` and `src="None"`, causing white/blank pages
240+
- Now properly handles default CDN URLs when custom URLs are not specified
241+
242+
### Version 0.1.0 (2025-01-15)
243+
- Initial release
244+
- Basic HTTP authentication for FastAPI documentation endpoints
245+
- Support for multiple users
246+
86247
## License
87248

88249
MIT License - Copyright (c) 2025 George Khananaev

examples/advanced_example.py

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,35 @@ async def read_users_me(token: str = Depends(oauth2_scheme)):
5454
user = fake_users_db[token]
5555
return user
5656

57-
# Protect the docs with DocShield - using custom URLs and UI resources
57+
# Protect the docs with DocShield - showcasing various features
5858
DocShield(
5959
app=app,
6060
credentials={
6161
"admin": "admin123", # Credentials for accessing the docs
62+
"dev": "dev456" # Multiple users supported
6263
},
6364
docs_url="/api/docs", # Custom docs URL
6465
redoc_url="/api/redoc", # Custom redoc URL
6566
openapi_url="/api/openapi.json", # Custom OpenAPI JSON URL
6667

67-
# Optional: custom Swagger UI and ReDoc resources
68-
swagger_js_url="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui-bundle.js",
69-
swagger_css_url="https://cdn.jsdelivr.net/npm/swagger-ui-dist@5/swagger-ui.css",
70-
redoc_js_url="https://cdn.jsdelivr.net/npm/redoc@next/bundles/redoc.standalone.js"
68+
# New in v0.2.0: CDN fallback options
69+
use_cdn_fallback=True, # Automatically fallback to local files if CDN fails (default: True)
70+
prefer_local=False, # Set to True to always use local files instead of CDN
71+
72+
# New in v0.2.0: Custom CSS and JavaScript injection
73+
custom_css="""
74+
/* Custom branding example */
75+
.swagger-ui .topbar {
76+
background-color: #2c3e50;
77+
}
78+
.swagger-ui .topbar .download-url-wrapper {
79+
display: none;
80+
}
81+
""",
82+
custom_js="""
83+
console.log('Advanced API Documentation Loaded');
84+
// Add custom functionality here
85+
"""
7186
)
7287

7388
# Run with: uvicorn advanced_example:app --reload

0 commit comments

Comments
 (0)