fastapi-openapi-cli 0.1.0__py3-none-any.whl

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.
File without changes
@@ -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
File without changes
@@ -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,9 @@
1
+ fastapi_openapi_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ fastapi_openapi_cli/cli.py,sha256=PdsDhDc_AomkN2iso81rVzUuUfQSXG2plRN_pFwXctg,955
3
+ fastapi_openapi_cli/export.py,sha256=O8B3-Z36VQa3cDArEV9jqlJGIJuJsW20t5O9CySiXz0,609
4
+ fastapi_openapi_cli/loader.py,sha256=bXISysjE3j3FNX30ROA6Ny63VlwORuknXy2zhe5jWEg,717
5
+ fastapi_openapi_cli/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ fastapi_openapi_cli-0.1.0.dist-info/WHEEL,sha256=5w2T7AS2mz1-rW9CNagNYWRCaB0iQqBMYLwKdlgiR4Q,78
7
+ fastapi_openapi_cli-0.1.0.dist-info/entry_points.txt,sha256=86bM0XQ34sA4d8T65cql60I7RWZPp5VN9QXFM9tXJfY,65
8
+ fastapi_openapi_cli-0.1.0.dist-info/METADATA,sha256=f0LgpG3VWUV81RWgOjBX1EvOlIe-bmwfuPNhiby77-A,1741
9
+ fastapi_openapi_cli-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.9.7
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ fastapi-openapi = fastapi_openapi_cli.cli:app
3
+