Skip to content

Commit 90643ec

Browse files
committed
Merge remote-tracking branch 'origin/main'
2 parents 5b3e039 + 95d9104 commit 90643ec

File tree

5 files changed

+119
-10
lines changed

5 files changed

+119
-10
lines changed

src/openapi_python_generator/__main__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
)
2020
@click.option(
2121
"--env-token-name",
22-
default="access_token",
22+
default=None,
2323
show_default=True,
2424
help="Name of the environment variable that contains the token. If you set this, the code expects this environment "
2525
"variable to be set and will raise an error if it is not.",

src/openapi_python_generator/generate_data.py

+41-9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import httpx
88
import isort
99
import orjson
10+
import yaml
1011
from black import NothingChanged
1112
from httpx import ConnectError
1213
from httpx import ConnectTimeout
@@ -45,30 +46,61 @@ def write_code(path: Path, content) -> None:
4546

4647
def get_open_api(source: Union[str, Path]) -> OpenAPI:
4748
"""
48-
Tries to fetch the openapi.json file from the web or load from a local file. Returns the according OpenAPI object.
49-
:param source:
50-
:return:
49+
Tries to fetch the openapi specification file from the web or load from a local file.
50+
Supports both JSON and YAML formats. Returns the according OpenAPI object.
51+
52+
Args:
53+
source: URL or file path to the OpenAPI specification
54+
55+
Returns:
56+
OpenAPI: Parsed OpenAPI specification object
57+
58+
Raises:
59+
FileNotFoundError: If the specified file cannot be found
60+
ConnectError: If the URL cannot be accessed
61+
ValidationError: If the specification is invalid
62+
JSONDecodeError/YAMLError: If the file cannot be parsed
5163
"""
5264
try:
65+
# Handle remote files
5366
if not isinstance(source, Path) and (
54-
source.startswith("http://") or source.startswith("https://")
67+
source.startswith("http://") or source.startswith("https://")
5568
):
56-
return OpenAPI(**orjson.loads(httpx.get(source).text))
69+
content = httpx.get(source).text
70+
# Try JSON first, then YAML for remote files
71+
try:
72+
return OpenAPI(**orjson.loads(content))
73+
except orjson.JSONDecodeError:
74+
return OpenAPI(**yaml.safe_load(content))
5775

76+
# Handle local files
5877
with open(source, "r") as f:
5978
file_content = f.read()
60-
return OpenAPI(**orjson.loads(file_content))
79+
80+
# Try JSON first
81+
try:
82+
return OpenAPI(**orjson.loads(file_content))
83+
except orjson.JSONDecodeError:
84+
# If JSON fails, try YAML
85+
try:
86+
return OpenAPI(**yaml.safe_load(file_content))
87+
except yaml.YAMLError as e:
88+
click.echo(
89+
f"File {source} is neither a valid JSON nor YAML file: {str(e)}"
90+
)
91+
raise
92+
6193
except FileNotFoundError:
6294
click.echo(
63-
f"File {source} not found. Please make sure to pass the path to the OpenAPI 3.0 specification."
95+
f"File {source} not found. Please make sure to pass the path to the OpenAPI specification."
6496
)
6597
raise
6698
except (ConnectError, ConnectTimeout):
6799
click.echo(f"Could not connect to {source}.")
68100
raise ConnectError(f"Could not connect to {source}.") from None
69-
except (ValidationError, orjson.JSONDecodeError):
101+
except ValidationError:
70102
click.echo(
71-
f"File {source} is not a valid OpenAPI 3.0 specification, or there may be a problem with your JSON."
103+
f"File {source} is not a valid OpenAPI 3.0 specification."
72104
)
73105
raise
74106

tests/regression/test_issue_71.py

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import pytest
2+
from click.testing import CliRunner
3+
4+
from openapi_python_generator.common import HTTPLibrary
5+
from openapi_python_generator.generate_data import generate_data
6+
from tests.conftest import test_data_folder
7+
from tests.conftest import test_result_path
8+
9+
10+
@pytest.fixture
11+
def runner() -> CliRunner:
12+
"""Fixture for invoking command-line interfaces."""
13+
return CliRunner()
14+
15+
16+
@pytest.mark.parametrize(
17+
"library",
18+
[HTTPLibrary.httpx, HTTPLibrary.aiohttp, HTTPLibrary.requests],
19+
)
20+
def test_issue_71(runner: CliRunner, model_data_with_cleanup, library) -> None:
21+
"""
22+
https://github.com/MarcoMuellner/openapi-python-generator/issues/7
23+
"""
24+
assert (
25+
generate_data(test_data_folder / "issue_71.json", test_result_path, library)
26+
is None
27+
)

tests/test_data/issue_71.json

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"openapi": "3.0.1",
3+
"info": {
4+
"version": "1.0",
5+
"title": "Title"
6+
},
7+
"paths": {
8+
"/dummy": {
9+
"get": {
10+
"summary": "Dummy endpoint",
11+
"responses": {
12+
"200": {
13+
"description": "Successful response"
14+
}
15+
}
16+
}
17+
}
18+
},
19+
"components": {
20+
"schemas": {
21+
"Registry": {
22+
"type": "string",
23+
"enum": [
24+
"A",
25+
"B",
26+
""
27+
]
28+
}
29+
}
30+
}
31+
}

tests/test_generate_data.py

+19
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import shutil
22

33
import pytest
4+
import yaml
45
from httpx import ConnectError
6+
from orjson import orjson
57
from pydantic import ValidationError
68

79
from openapi_python_generator.common import HTTPLibrary
@@ -16,14 +18,31 @@
1618

1719

1820
def test_get_open_api(model_data):
21+
# Test JSON file
1922
assert get_open_api(test_data_path) == model_data
2023

24+
# Create YAML version of the test file
25+
yaml_path = test_data_path.with_suffix('.yaml')
26+
with open(test_data_path) as f:
27+
json_content = orjson.loads(f.read())
28+
with open(yaml_path, 'w') as f:
29+
yaml.dump(json_content, f)
30+
31+
# Test YAML file
32+
assert get_open_api(yaml_path) == model_data
33+
34+
# Cleanup YAML file
35+
yaml_path.unlink()
36+
37+
# Test remote file failure
2138
with pytest.raises(ConnectError):
2239
assert get_open_api("http://localhost:8080/api/openapi.json")
2340

41+
# Test invalid OpenAPI spec
2442
with pytest.raises(ValidationError):
2543
assert get_open_api(test_data_folder / "failing_api.json")
2644

45+
# Test non-existent file
2746
with pytest.raises(FileNotFoundError):
2847
assert get_open_api(test_data_folder / "file_does_not_exist.json")
2948

0 commit comments

Comments
 (0)