fastapi-openapi-cli 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.
@@ -0,0 +1,110 @@
1
+ Metadata-Version: 2.3
2
+ Name: fastapi-openapi-cli
3
+ Version: 0.1.0
4
+ Summary: CLI tool to export FastAPI OpenAPI specifications
5
+ Author: Hector Castro
6
+ Author-email: Hector Castro <hectcastro@gmail.com>
7
+ License: Apache-2.0
8
+ Requires-Dist: fastapi>=0.115.0
9
+ Requires-Dist: typer>=0.15.0
10
+ Requires-Dist: pyyaml>=6.0.2
11
+ Requires-Python: >=3.12
12
+ Description-Content-Type: text/markdown
13
+
14
+ # fastapi-openapi-cli
15
+
16
+ A command-line tool to export OpenAPI specifications from FastAPI applications.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ uv add fastapi-openapi-cli
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ### Basic Usage
27
+
28
+ Export OpenAPI spec to `stdout`:
29
+
30
+ ```bash
31
+ fastapi-openapi --app myapp.main:app
32
+ ```
33
+
34
+ Export to JSON File:
35
+
36
+ ```bash
37
+ fastapi-openapi --app myapp.main:app -o openapi.json
38
+ ```
39
+
40
+ Export to YAML File:
41
+
42
+ ```bash
43
+ fastapi-openapi --app myapp.main:app -o openapi.yaml
44
+ ```
45
+
46
+ ## Development
47
+
48
+ ### Setup
49
+
50
+ This project uses [uv](https://github.com/astral-sh/uv) for dependency management:
51
+
52
+ ```bash
53
+ # Clone the repository
54
+ git clone https://github.com/hectcastro/fastapi-openapi-cli.git
55
+ cd fastapi-openapi-cli
56
+
57
+ # Install dependencies
58
+ uv sync
59
+ ```
60
+
61
+ ### Running Tests
62
+
63
+ ```bash
64
+ # Run all tests with coverage
65
+ make test
66
+
67
+ # Run specific test file
68
+ uv run pytest tests/test_cli.py
69
+
70
+ # Run without coverage
71
+ uv run pytest --no-cov
72
+ ```
73
+
74
+ ### Linting and Formatting
75
+
76
+ ```bash
77
+ # Check code with ruff
78
+ make lint
79
+
80
+ # Format code
81
+ make format
82
+ ```
83
+
84
+ ### Type Checking
85
+
86
+ ```bash
87
+ # Run type checking with ty
88
+ make types
89
+ ```
90
+
91
+ ### Dependency Analysis
92
+
93
+ ```bash
94
+ # Check for dependency issues with deptry
95
+ make deps
96
+ ```
97
+
98
+ ### CI Pipeline
99
+
100
+ ```bash
101
+ # Run all checks (lint, types, tests) - same as CI
102
+ make ci
103
+ ```
104
+
105
+ ### Running the CLI Locally
106
+
107
+ ```bash
108
+ # Run the CLI in development
109
+ uv run fastapi-openapi --app tests.fixtures.sample_app:app
110
+ ```
@@ -0,0 +1,97 @@
1
+ # fastapi-openapi-cli
2
+
3
+ A command-line tool to export OpenAPI specifications from FastAPI applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ uv add fastapi-openapi-cli
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Basic Usage
14
+
15
+ Export OpenAPI spec to `stdout`:
16
+
17
+ ```bash
18
+ fastapi-openapi --app myapp.main:app
19
+ ```
20
+
21
+ Export to JSON File:
22
+
23
+ ```bash
24
+ fastapi-openapi --app myapp.main:app -o openapi.json
25
+ ```
26
+
27
+ Export to YAML File:
28
+
29
+ ```bash
30
+ fastapi-openapi --app myapp.main:app -o openapi.yaml
31
+ ```
32
+
33
+ ## Development
34
+
35
+ ### Setup
36
+
37
+ This project uses [uv](https://github.com/astral-sh/uv) for dependency management:
38
+
39
+ ```bash
40
+ # Clone the repository
41
+ git clone https://github.com/hectcastro/fastapi-openapi-cli.git
42
+ cd fastapi-openapi-cli
43
+
44
+ # Install dependencies
45
+ uv sync
46
+ ```
47
+
48
+ ### Running Tests
49
+
50
+ ```bash
51
+ # Run all tests with coverage
52
+ make test
53
+
54
+ # Run specific test file
55
+ uv run pytest tests/test_cli.py
56
+
57
+ # Run without coverage
58
+ uv run pytest --no-cov
59
+ ```
60
+
61
+ ### Linting and Formatting
62
+
63
+ ```bash
64
+ # Check code with ruff
65
+ make lint
66
+
67
+ # Format code
68
+ make format
69
+ ```
70
+
71
+ ### Type Checking
72
+
73
+ ```bash
74
+ # Run type checking with ty
75
+ make types
76
+ ```
77
+
78
+ ### Dependency Analysis
79
+
80
+ ```bash
81
+ # Check for dependency issues with deptry
82
+ make deps
83
+ ```
84
+
85
+ ### CI Pipeline
86
+
87
+ ```bash
88
+ # Run all checks (lint, types, tests) - same as CI
89
+ make ci
90
+ ```
91
+
92
+ ### Running the CLI Locally
93
+
94
+ ```bash
95
+ # Run the CLI in development
96
+ uv run fastapi-openapi --app tests.fixtures.sample_app:app
97
+ ```
@@ -0,0 +1,66 @@
1
+ [project]
2
+ name = "fastapi-openapi-cli"
3
+ version = "0.1.0"
4
+ description = "CLI tool to export FastAPI OpenAPI specifications"
5
+ readme = "README.md"
6
+ license = { text = "Apache-2.0" }
7
+ authors = [{ name = "Hector Castro", email = "hectcastro@gmail.com" }]
8
+ requires-python = ">=3.12"
9
+ dependencies = ["fastapi>=0.115.0", "typer>=0.15.0", "pyyaml>=6.0.2"]
10
+
11
+ [project.scripts]
12
+ fastapi-openapi = "fastapi_openapi_cli.cli:app"
13
+
14
+ [dependency-groups]
15
+ dev = [
16
+ "pytest>=8.3.0",
17
+ "pytest-cov>=6.0.0",
18
+ "ruff>=0.8.0",
19
+ "ty>=0.0.1a25",
20
+ "deptry>=0.21.0",
21
+ ]
22
+
23
+ [build-system]
24
+ requires = ["uv_build>=0.9.7,<0.10.0"]
25
+ build-backend = "uv_build"
26
+
27
+ [tool.ruff]
28
+ line-length = 100
29
+ target-version = "py312"
30
+ lint.select = [
31
+ "E", # pycodestyle errors
32
+ "W", # pycodestyle warnings
33
+ "F", # pyflakes
34
+ "I", # isort
35
+ "N", # pep8-naming
36
+ "UP", # pyupgrade
37
+ "B", # flake8-bugbear
38
+ "C4", # flake8-comprehensions
39
+ "SIM", # flake8-simplify
40
+ "TC", # flake8-type-checking
41
+ ]
42
+
43
+ [tool.pytest.ini_options]
44
+ testpaths = ["tests"]
45
+ pythonpath = ["src"]
46
+ addopts = [
47
+ "--cov=fastapi_openapi_cli",
48
+ "--cov-report=term-missing",
49
+ "--cov-report=html",
50
+ "--cov-fail-under=100",
51
+ ]
52
+
53
+ [tool.coverage.run]
54
+ source = ["src"]
55
+ omit = ["*/tests/*"]
56
+
57
+ [tool.coverage.report]
58
+ exclude_lines = [
59
+ "pragma: no cover",
60
+ "if __name__ == .__main__.:",
61
+ "if TYPE_CHECKING:",
62
+ ]
63
+
64
+ [tool.deptry]
65
+ extend_exclude = ["tests"]
66
+ known_first_party = ["fastapi_openapi_cli"]
@@ -0,0 +1,31 @@
1
+ import typer
2
+
3
+ from fastapi_openapi_cli.export import export_openapi
4
+ from fastapi_openapi_cli.loader import AppLoadError, load_app
5
+
6
+ app = typer.Typer(
7
+ name="fastapi-openapi",
8
+ help="CLI tool to export FastAPI OpenAPI specifications",
9
+ no_args_is_help=True,
10
+ )
11
+
12
+
13
+ @app.command()
14
+ def export(
15
+ app_path: str = typer.Option(..., "--app", "-a", help="FastAPI app path (e.g., module:app)"),
16
+ output: str | None = typer.Option(
17
+ None, "--output", "-o", help="Output file path (default: stdout)"
18
+ ),
19
+ ) -> None:
20
+ """
21
+ Export the OpenAPI specification from a FastAPI application.
22
+
23
+ Supports both JSON and YAML formats. Format is auto-detected from file extension.
24
+ If no output file is specified, outputs JSON to stdout.
25
+ """
26
+ try:
27
+ fastapi_app = load_app(app_path)
28
+ export_openapi(fastapi_app, output)
29
+ except AppLoadError as e:
30
+ typer.echo(str(e), err=True)
31
+ raise typer.Exit(code=1) from e
@@ -0,0 +1,26 @@
1
+ import json
2
+ from pathlib import Path
3
+
4
+ import yaml
5
+ from fastapi import FastAPI
6
+
7
+
8
+ def get_openapi_spec(app: FastAPI) -> dict:
9
+ return app.openapi()
10
+
11
+
12
+ def export_openapi(app: FastAPI, output_path: str | None) -> None:
13
+ spec = get_openapi_spec(app)
14
+
15
+ if output_path is None:
16
+ print(json.dumps(spec, indent=2))
17
+ return
18
+
19
+ output_file = Path(output_path)
20
+
21
+ if output_file.suffix in {".yaml", ".yml"}:
22
+ with output_file.open("w") as f:
23
+ yaml.safe_dump(spec, f, sort_keys=False)
24
+ else:
25
+ with output_file.open("w") as f:
26
+ json.dump(spec, f, indent=2)
@@ -0,0 +1,28 @@
1
+ import importlib
2
+
3
+ from fastapi import FastAPI
4
+
5
+
6
+ class AppLoadError(Exception):
7
+ pass
8
+
9
+
10
+ def load_app(app_path: str) -> FastAPI:
11
+ module_path, app_name = app_path.split(":")
12
+
13
+ try:
14
+ module = importlib.import_module(module_path)
15
+ except ModuleNotFoundError as e:
16
+ raise AppLoadError(f"Could not import module '{module_path}': {e}") from e
17
+
18
+ try:
19
+ app = getattr(module, app_name)
20
+ except AttributeError as e:
21
+ raise AppLoadError(f"Module '{module_path}' has no attribute '{app_name}'") from e
22
+
23
+ if not isinstance(app, FastAPI):
24
+ raise AppLoadError(
25
+ f"Attribute '{app_name}' in module '{module_path}' is not a FastAPI instance"
26
+ )
27
+
28
+ return app