stoplight-fastapi 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stoplight_fastapi-0.1.0/LICENSE +19 -0
- stoplight_fastapi-0.1.0/PKG-INFO +129 -0
- stoplight_fastapi-0.1.0/README.md +96 -0
- stoplight_fastapi-0.1.0/pyproject.toml +204 -0
- stoplight_fastapi-0.1.0/src/stoplight_fastapi/__init__.py +7 -0
- stoplight_fastapi-0.1.0/src/stoplight_fastapi/__version__.py +6 -0
- stoplight_fastapi-0.1.0/src/stoplight_fastapi/py.typed +0 -0
- stoplight_fastapi-0.1.0/src/stoplight_fastapi/stoplight.py +132 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tho Nguyen
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
|
6
|
+
software and associated documentation files (the "Software"), to deal in the Software
|
|
7
|
+
without restriction, including without limitation the rights to use, copy, modify, merge,
|
|
8
|
+
publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
|
|
9
|
+
to whom the Software is furnished to do so, subject to the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be included in all copies or
|
|
12
|
+
substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
|
15
|
+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
|
16
|
+
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
|
17
|
+
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
|
18
|
+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
19
|
+
DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stoplight-fastapi
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Seamlessly integrate Stoplight Elements for beautiful, interactive API documentation in FastAPI.
|
|
5
|
+
Keywords: fastapi,api,documentation,stoplight,openapi,interactive-docs,api-docs,rest-api,swagger
|
|
6
|
+
Author: Tho Nguyen
|
|
7
|
+
Author-email: Tho Nguyen <contact@naiwaaa.simplelogin.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Framework :: FastAPI
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Intended Audience :: Information Technology
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Topic :: Documentation
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
+
Classifier: Typing :: Typed
|
|
26
|
+
Requires-Dist: fastapi>=0.115.0
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Project-URL: Homepage, https://codeberg.org/naiwaaa/stoplight-fastapi
|
|
29
|
+
Project-URL: Documentation, https://codeberg.org/naiwaaa/stoplight-fastapi
|
|
30
|
+
Project-URL: Repository, https://codeberg.org/naiwaaa/stoplight-fastapi
|
|
31
|
+
Project-URL: Issues, https://codeberg.org/naiwaaa/stoplight-fastapi/issues
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# Stoplight Elements API Documentation Plugin for FastAPI
|
|
35
|
+
|
|
36
|
+
[](https://pypi.python.org/pypi/stoplight-fastapi)
|
|
37
|
+
[](https://codeberg.org/naiwaaa/stoplight-fastapi)
|
|
38
|
+
[](https://codeberg.org/naiwaaa/stoplight-fastapi/src/branch/main/LICENSE)
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
Install `stoplight-fastapi` using your preferred package manager:
|
|
43
|
+
|
|
44
|
+
### Using uv (recommended)
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
uv add stoplight-fastapi
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Using pip
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install stoplight-fastapi
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Requirements
|
|
57
|
+
|
|
58
|
+
- Python 3.10 or higher
|
|
59
|
+
- FastAPI 0.115.0 or higher
|
|
60
|
+
|
|
61
|
+
## Quick Start
|
|
62
|
+
|
|
63
|
+
### Basic Setup
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from fastapi import FastAPI
|
|
67
|
+
from stoplight_fastapi import get_stoplight_api_reference
|
|
68
|
+
|
|
69
|
+
app = FastAPI(
|
|
70
|
+
title="My API",
|
|
71
|
+
description="Welcome to My Awesome API.",
|
|
72
|
+
version="1.0.0",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
@app.get("/items/{item_id}")
|
|
76
|
+
def read_item(item_id: int, q: str = None):
|
|
77
|
+
"""Get an item by ID."""
|
|
78
|
+
return {"item_id": item_id, "q": q}
|
|
79
|
+
|
|
80
|
+
@app.get("/stoplight", include_in_schema=False)
|
|
81
|
+
def get_stoplight_html():
|
|
82
|
+
"""Render API documentation with Stoplight Elements."""
|
|
83
|
+
return get_stoplight_api_reference(
|
|
84
|
+
openapi_url=app.openapi_url,
|
|
85
|
+
title=app.title,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
if __name__ == "__main__":
|
|
89
|
+
import uvicorn
|
|
90
|
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Then visit `http://localhost:8000/stoplight` to view your API documentation.
|
|
94
|
+
|
|
95
|
+
### Advanced Configuration
|
|
96
|
+
|
|
97
|
+
Customize the Stoplight Elements UI with
|
|
98
|
+
[advanced options](https://docs.stoplight.io/docs/elements/b074dc47b2826-elements-configuration-options):
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from stoplight_fastapi import get_stoplight_api_reference, StoplightConfig
|
|
102
|
+
|
|
103
|
+
@app.get("/docs", include_in_schema=False)
|
|
104
|
+
def get_stoplight_html():
|
|
105
|
+
"""Advanced Stoplight Elements configuration."""
|
|
106
|
+
return get_stoplight_api_reference(
|
|
107
|
+
openapi_url=app.openapi_url,
|
|
108
|
+
stoplight_config=StoplightConfig(
|
|
109
|
+
router="hash", # Enable hash-based routing for shareable links
|
|
110
|
+
layout="stacked", # Choose between 'sidebar', 'responsive', and 'stacked' layouts
|
|
111
|
+
# Additional Stoplight configuration options available
|
|
112
|
+
),
|
|
113
|
+
)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Live Example
|
|
117
|
+
|
|
118
|
+

|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
uv run https://codeberg.org/naiwaaa/stoplight-fastapi/raw/branch/main/scripts/playground.py
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Visit `http://localhost:8000/stoplight` to see Stoplight Elements in action.
|
|
125
|
+
|
|
126
|
+
## Resources
|
|
127
|
+
|
|
128
|
+
- [FastAPI Documentation](https://fastapi.tiangolo.com)
|
|
129
|
+
- [Stoplight Elements Documentation](https://docs.stoplight.io/docs/elements/d6a8ba3f3c186-stoplight-elements)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Stoplight Elements API Documentation Plugin for FastAPI
|
|
2
|
+
|
|
3
|
+
[](https://pypi.python.org/pypi/stoplight-fastapi)
|
|
4
|
+
[](https://codeberg.org/naiwaaa/stoplight-fastapi)
|
|
5
|
+
[](https://codeberg.org/naiwaaa/stoplight-fastapi/src/branch/main/LICENSE)
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Install `stoplight-fastapi` using your preferred package manager:
|
|
10
|
+
|
|
11
|
+
### Using uv (recommended)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
uv add stoplight-fastapi
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Using pip
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
pip install stoplight-fastapi
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Requirements
|
|
24
|
+
|
|
25
|
+
- Python 3.10 or higher
|
|
26
|
+
- FastAPI 0.115.0 or higher
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
### Basic Setup
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from fastapi import FastAPI
|
|
34
|
+
from stoplight_fastapi import get_stoplight_api_reference
|
|
35
|
+
|
|
36
|
+
app = FastAPI(
|
|
37
|
+
title="My API",
|
|
38
|
+
description="Welcome to My Awesome API.",
|
|
39
|
+
version="1.0.0",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
@app.get("/items/{item_id}")
|
|
43
|
+
def read_item(item_id: int, q: str = None):
|
|
44
|
+
"""Get an item by ID."""
|
|
45
|
+
return {"item_id": item_id, "q": q}
|
|
46
|
+
|
|
47
|
+
@app.get("/stoplight", include_in_schema=False)
|
|
48
|
+
def get_stoplight_html():
|
|
49
|
+
"""Render API documentation with Stoplight Elements."""
|
|
50
|
+
return get_stoplight_api_reference(
|
|
51
|
+
openapi_url=app.openapi_url,
|
|
52
|
+
title=app.title,
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
if __name__ == "__main__":
|
|
56
|
+
import uvicorn
|
|
57
|
+
uvicorn.run(app, host="0.0.0.0", port=8000)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Then visit `http://localhost:8000/stoplight` to view your API documentation.
|
|
61
|
+
|
|
62
|
+
### Advanced Configuration
|
|
63
|
+
|
|
64
|
+
Customize the Stoplight Elements UI with
|
|
65
|
+
[advanced options](https://docs.stoplight.io/docs/elements/b074dc47b2826-elements-configuration-options):
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from stoplight_fastapi import get_stoplight_api_reference, StoplightConfig
|
|
69
|
+
|
|
70
|
+
@app.get("/docs", include_in_schema=False)
|
|
71
|
+
def get_stoplight_html():
|
|
72
|
+
"""Advanced Stoplight Elements configuration."""
|
|
73
|
+
return get_stoplight_api_reference(
|
|
74
|
+
openapi_url=app.openapi_url,
|
|
75
|
+
stoplight_config=StoplightConfig(
|
|
76
|
+
router="hash", # Enable hash-based routing for shareable links
|
|
77
|
+
layout="stacked", # Choose between 'sidebar', 'responsive', and 'stacked' layouts
|
|
78
|
+
# Additional Stoplight configuration options available
|
|
79
|
+
),
|
|
80
|
+
)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Live Example
|
|
84
|
+
|
|
85
|
+

|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
uv run https://codeberg.org/naiwaaa/stoplight-fastapi/raw/branch/main/scripts/playground.py
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Visit `http://localhost:8000/stoplight` to see Stoplight Elements in action.
|
|
92
|
+
|
|
93
|
+
## Resources
|
|
94
|
+
|
|
95
|
+
- [FastAPI Documentation](https://fastapi.tiangolo.com)
|
|
96
|
+
- [Stoplight Elements Documentation](https://docs.stoplight.io/docs/elements/d6a8ba3f3c186-stoplight-elements)
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.10.2,<0.11.0"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "stoplight-fastapi"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Seamlessly integrate Stoplight Elements for beautiful, interactive API documentation in FastAPI."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
keywords = [
|
|
11
|
+
"fastapi",
|
|
12
|
+
"api",
|
|
13
|
+
"documentation",
|
|
14
|
+
"stoplight",
|
|
15
|
+
"openapi",
|
|
16
|
+
"interactive-docs",
|
|
17
|
+
"api-docs",
|
|
18
|
+
"rest-api",
|
|
19
|
+
"swagger",
|
|
20
|
+
]
|
|
21
|
+
license = "MIT"
|
|
22
|
+
license-files = ["LICENSE"]
|
|
23
|
+
authors = [
|
|
24
|
+
{ name = "Tho Nguyen", email = "contact@naiwaaa.simplelogin.com" },
|
|
25
|
+
]
|
|
26
|
+
classifiers = [
|
|
27
|
+
"Framework :: FastAPI",
|
|
28
|
+
"Intended Audience :: Developers",
|
|
29
|
+
"Intended Audience :: Information Technology",
|
|
30
|
+
"License :: OSI Approved :: MIT License",
|
|
31
|
+
"Operating System :: OS Independent",
|
|
32
|
+
"Programming Language :: Python",
|
|
33
|
+
"Programming Language :: Python :: 3",
|
|
34
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
35
|
+
"Programming Language :: Python :: 3.10",
|
|
36
|
+
"Programming Language :: Python :: 3.11",
|
|
37
|
+
"Programming Language :: Python :: 3.12",
|
|
38
|
+
"Programming Language :: Python :: 3.13",
|
|
39
|
+
"Programming Language :: Python :: 3.14",
|
|
40
|
+
"Topic :: Documentation",
|
|
41
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
42
|
+
"Typing :: Typed",
|
|
43
|
+
]
|
|
44
|
+
requires-python = ">=3.10"
|
|
45
|
+
dependencies = [
|
|
46
|
+
"fastapi>=0.115.0",
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[project.urls]
|
|
50
|
+
Homepage = "https://codeberg.org/naiwaaa/stoplight-fastapi"
|
|
51
|
+
Documentation = "https://codeberg.org/naiwaaa/stoplight-fastapi"
|
|
52
|
+
Repository = "https://codeberg.org/naiwaaa/stoplight-fastapi"
|
|
53
|
+
Issues = "https://codeberg.org/naiwaaa/stoplight-fastapi/issues"
|
|
54
|
+
|
|
55
|
+
[dependency-groups]
|
|
56
|
+
dev = [
|
|
57
|
+
"ipykernel>=7.2.0",
|
|
58
|
+
"uvicorn>=0.41.0",
|
|
59
|
+
# code quality
|
|
60
|
+
"ruff>=0.15.1",
|
|
61
|
+
"mypy[dmypy,faster-cache]>=1.19.1",
|
|
62
|
+
# tests
|
|
63
|
+
"hypothesis>=6.151.6",
|
|
64
|
+
"inline-snapshot>=0.31.1",
|
|
65
|
+
"pytest>=9.0.2",
|
|
66
|
+
"pytest-asyncio>=1.3.0",
|
|
67
|
+
"pytest-benchmark>=5.2.3",
|
|
68
|
+
"pytest-cov>=7.0.0",
|
|
69
|
+
"pytest-instafail>=0.5.0",
|
|
70
|
+
"pytest-memray>=1.8.0",
|
|
71
|
+
"pytest-mock>=3.15.1",
|
|
72
|
+
"pytest-randomly>=4.0.1",
|
|
73
|
+
"pytest-sugar>=1.1.1",
|
|
74
|
+
"pytest-timeout>=2.4.0",
|
|
75
|
+
"pytest-xdist>=3.8.0",
|
|
76
|
+
"respx>=0.22.0",
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
[tool.mypy]
|
|
80
|
+
exclude = [".cache/", ".venv/"]
|
|
81
|
+
# disallow dynamic typing
|
|
82
|
+
disallow_any_unimported = true
|
|
83
|
+
disallow_any_expr = false
|
|
84
|
+
disallow_any_decorated = true
|
|
85
|
+
disallow_any_explicit = false
|
|
86
|
+
disallow_any_generics = true
|
|
87
|
+
disallow_subclassing_any = true
|
|
88
|
+
# untyped definitions and calls
|
|
89
|
+
disallow_untyped_calls = true
|
|
90
|
+
disallow_untyped_defs = true
|
|
91
|
+
disallow_incomplete_defs = true
|
|
92
|
+
check_untyped_defs = true
|
|
93
|
+
disallow_untyped_decorators = true
|
|
94
|
+
# none and optional handling
|
|
95
|
+
implicit_optional = false
|
|
96
|
+
strict_optional = true
|
|
97
|
+
# configuring warnings
|
|
98
|
+
warn_redundant_casts = true
|
|
99
|
+
warn_unused_ignores = true
|
|
100
|
+
warn_no_return = true
|
|
101
|
+
warn_return_any = true
|
|
102
|
+
warn_unreachable = true
|
|
103
|
+
# miscellaneous strictness flags
|
|
104
|
+
allow_redefinition = false
|
|
105
|
+
enable_error_code = [
|
|
106
|
+
"redundant-self",
|
|
107
|
+
"redundant-expr",
|
|
108
|
+
"possibly-undefined",
|
|
109
|
+
"truthy-bool",
|
|
110
|
+
"truthy-iterable",
|
|
111
|
+
"ignore-without-code",
|
|
112
|
+
"unused-awaitable",
|
|
113
|
+
"unused-ignore",
|
|
114
|
+
"explicit-override",
|
|
115
|
+
"mutable-override",
|
|
116
|
+
"unimported-reveal",
|
|
117
|
+
"exhaustive-match",
|
|
118
|
+
]
|
|
119
|
+
implicit_reexport = false
|
|
120
|
+
strict_concatenate = true
|
|
121
|
+
strict_equality = true
|
|
122
|
+
strict_equality_for_none = true
|
|
123
|
+
strict = true
|
|
124
|
+
# configuring error messages
|
|
125
|
+
show_error_context = true
|
|
126
|
+
show_column_numbers = true
|
|
127
|
+
# incremental mode
|
|
128
|
+
cache_dir = ".cache/mypy"
|
|
129
|
+
# advanced options
|
|
130
|
+
plugins = []
|
|
131
|
+
|
|
132
|
+
[tool.pytest.ini_options]
|
|
133
|
+
addopts = [
|
|
134
|
+
# general
|
|
135
|
+
"--exitfirst",
|
|
136
|
+
"--strict",
|
|
137
|
+
"--failed-first",
|
|
138
|
+
# reporting
|
|
139
|
+
"--durations=5",
|
|
140
|
+
"-vv",
|
|
141
|
+
"--no-header",
|
|
142
|
+
"-ra",
|
|
143
|
+
"--showlocals",
|
|
144
|
+
"--junitxml=.cache/pytest/report.xml",
|
|
145
|
+
# collection
|
|
146
|
+
"--ignore-glob=**/fixtures/*",
|
|
147
|
+
"--import-mode=importlib",
|
|
148
|
+
"--doctest-modules",
|
|
149
|
+
"--doctest-continue-on-failure",
|
|
150
|
+
# pytest-benchmark
|
|
151
|
+
"--benchmark-warmup=on",
|
|
152
|
+
"--benchmark-disable-gc",
|
|
153
|
+
"--benchmark-storage=file://./.cache/benchmarks",
|
|
154
|
+
"--benchmark-sort=mean",
|
|
155
|
+
"--benchmark-columns=min,mean,stddev,outliers,rounds,iterations",
|
|
156
|
+
"--benchmark-disable",
|
|
157
|
+
# pytest-cov
|
|
158
|
+
"--cov",
|
|
159
|
+
"--cov-report=term-missing:skip-covered",
|
|
160
|
+
"--cov-report=xml:.cache/pytest/coverage.xml",
|
|
161
|
+
"--cov-config=pyproject.toml",
|
|
162
|
+
# pytest-instafail
|
|
163
|
+
"--instafail",
|
|
164
|
+
# pytest-memray
|
|
165
|
+
"--memray",
|
|
166
|
+
"--most-allocations=5",
|
|
167
|
+
# pytest-timeout
|
|
168
|
+
"--timeout=15",
|
|
169
|
+
# pytest-xdist
|
|
170
|
+
"-n=auto",
|
|
171
|
+
# hypothesis
|
|
172
|
+
"--hypothesis-show-statistics",
|
|
173
|
+
"--hypothesis-explain",
|
|
174
|
+
]
|
|
175
|
+
cache_dir = ".cache/pytest"
|
|
176
|
+
doctest_optionflags = "NUMBER IGNORE_EXCEPTION_DETAIL"
|
|
177
|
+
pythonpath = ["."]
|
|
178
|
+
markers = [
|
|
179
|
+
"slow: marks tests as slow",
|
|
180
|
+
"network: marks tests that require network access",
|
|
181
|
+
]
|
|
182
|
+
testpaths = ["tests"]
|
|
183
|
+
# pytest-asyncio
|
|
184
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
185
|
+
|
|
186
|
+
[tool.coverage.run]
|
|
187
|
+
source = ["src/", "tests/"]
|
|
188
|
+
branch = true
|
|
189
|
+
data_file = ".cache/pytest/coverage"
|
|
190
|
+
relative_files = true
|
|
191
|
+
|
|
192
|
+
[tool.coverage.report]
|
|
193
|
+
fail_under = 0
|
|
194
|
+
show_missing = true
|
|
195
|
+
skip_covered = true
|
|
196
|
+
exclude_also = [
|
|
197
|
+
"raise NotImplementedError",
|
|
198
|
+
"if __name__ == .__main__.:",
|
|
199
|
+
]
|
|
200
|
+
|
|
201
|
+
[tool.commitizen]
|
|
202
|
+
name = "cz_conventional_commits"
|
|
203
|
+
version_scheme = "pep440"
|
|
204
|
+
version_provider = "uv"
|
|
File without changes
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Annotated, Literal
|
|
5
|
+
|
|
6
|
+
from annotated_doc import Doc
|
|
7
|
+
from fastapi.responses import HTMLResponse
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
_default_style = "<style>body { margin: 0; padding: 0; height: 100vh; }</style>"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True, kw_only=True, slots=True)
|
|
14
|
+
class StoplightConfig:
|
|
15
|
+
"""Stoplight Elements configuration options.
|
|
16
|
+
|
|
17
|
+
Read more about it in the
|
|
18
|
+
[Stoplight Elements Configuration Options document](https://docs.stoplight.io/docs/elements/b074dc47b2826-elements-configuration-options)
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
base_path: str | None = None
|
|
22
|
+
hide_internal: bool = False
|
|
23
|
+
hide_try_it: bool = False
|
|
24
|
+
hide_try_it_panel: bool = False
|
|
25
|
+
hide_schemas: bool = False
|
|
26
|
+
hide_export: bool = False
|
|
27
|
+
try_it_cors_proxy: str | None = None
|
|
28
|
+
try_it_credentials_policy: Literal["omit", "include", "same-origin"] = "omit"
|
|
29
|
+
layout: Literal["sidebar", "responsive", "stacked"] = "sidebar"
|
|
30
|
+
logo: str | None = None
|
|
31
|
+
router: Literal["history", "hash", "memory", "static"] = "hash"
|
|
32
|
+
|
|
33
|
+
def to_html_attributes(self) -> list[str]:
|
|
34
|
+
attributes: list[str] = []
|
|
35
|
+
|
|
36
|
+
for field in self.__annotations__:
|
|
37
|
+
value = getattr(self, field)
|
|
38
|
+
if value:
|
|
39
|
+
attributes.append(f'{field.replace("_", "")}="{value}"')
|
|
40
|
+
|
|
41
|
+
return attributes
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_stoplight_api_reference(
|
|
45
|
+
*,
|
|
46
|
+
openapi_url: Annotated[
|
|
47
|
+
str | None,
|
|
48
|
+
Doc(
|
|
49
|
+
"""
|
|
50
|
+
The OpenAPI URL that Stoplight Elements should load and use.
|
|
51
|
+
"""
|
|
52
|
+
),
|
|
53
|
+
],
|
|
54
|
+
title: Annotated[
|
|
55
|
+
str,
|
|
56
|
+
Doc(
|
|
57
|
+
"""
|
|
58
|
+
The HTML `<title>` content, normally shown in the browser tab.
|
|
59
|
+
|
|
60
|
+
Defaults to "Stoplight Elements" if not provided.
|
|
61
|
+
"""
|
|
62
|
+
),
|
|
63
|
+
] = "Stoplight Elements",
|
|
64
|
+
stoplight_js_url: Annotated[
|
|
65
|
+
str,
|
|
66
|
+
Doc(
|
|
67
|
+
"""
|
|
68
|
+
The URL to use to load the Stoplight Elements JavaScript.
|
|
69
|
+
"""
|
|
70
|
+
),
|
|
71
|
+
] = "https://unpkg.com/@stoplight/elements/web-components.min.js",
|
|
72
|
+
stoplight_css_url: Annotated[
|
|
73
|
+
str,
|
|
74
|
+
Doc(
|
|
75
|
+
"""
|
|
76
|
+
The URL to use to load the Stoplight Elements CSS.
|
|
77
|
+
"""
|
|
78
|
+
),
|
|
79
|
+
] = "https://unpkg.com/@stoplight/elements/styles.min.css",
|
|
80
|
+
stoplight_favicon_url: Annotated[
|
|
81
|
+
str,
|
|
82
|
+
Doc(
|
|
83
|
+
"""
|
|
84
|
+
The URL of the favicon to use. It is normally shown in the browser tab.
|
|
85
|
+
"""
|
|
86
|
+
),
|
|
87
|
+
] = "https://fastapi.tiangolo.com/img/favicon.png",
|
|
88
|
+
stoplight_config: Annotated[
|
|
89
|
+
StoplightConfig | None,
|
|
90
|
+
Doc(
|
|
91
|
+
"""
|
|
92
|
+
Configuration options for Stoplight Elements.
|
|
93
|
+
|
|
94
|
+
Read more about it in the
|
|
95
|
+
[Stoplight Elements Configuration Options document](https://docs.stoplight.io/docs/elements/b074dc47b2826-elements-configuration-options)
|
|
96
|
+
"""
|
|
97
|
+
),
|
|
98
|
+
] = None,
|
|
99
|
+
style: Annotated[
|
|
100
|
+
str,
|
|
101
|
+
Doc(
|
|
102
|
+
"""
|
|
103
|
+
Additional CSS styles to apply to the page.
|
|
104
|
+
|
|
105
|
+
By default, it sets the body to have no margin or padding and a height of
|
|
106
|
+
100vh.
|
|
107
|
+
"""
|
|
108
|
+
),
|
|
109
|
+
] = _default_style,
|
|
110
|
+
) -> HTMLResponse:
|
|
111
|
+
config = stoplight_config or StoplightConfig()
|
|
112
|
+
|
|
113
|
+
html = f"""
|
|
114
|
+
<!DOCTYPE html>
|
|
115
|
+
<html>
|
|
116
|
+
<head>
|
|
117
|
+
<meta charset="utf-8"/>
|
|
118
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
|
|
119
|
+
<title>{title or "Stoplight Elements"}</title>
|
|
120
|
+
<link rel="shortcut icon" href="{stoplight_favicon_url}">
|
|
121
|
+
<link rel="stylesheet" href="{stoplight_css_url}">
|
|
122
|
+
<script src="{stoplight_js_url}" crossorigin></script>
|
|
123
|
+
|
|
124
|
+
{style}
|
|
125
|
+
</head>
|
|
126
|
+
<body>
|
|
127
|
+
<elements-api apiDescriptionUrl="{openapi_url}" {" ".join(config.to_html_attributes())}/>
|
|
128
|
+
</body>
|
|
129
|
+
</html>
|
|
130
|
+
""" # noqa: E501
|
|
131
|
+
|
|
132
|
+
return HTMLResponse(html)
|