Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions end_to_end_tests/functional_tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ def inline_spec_should_fail(
extra_args = []
with generate_client_from_inline_spec(
openapi_spec,
extra_args,
config,
extra_args=extra_args,
config=config,
filename_suffix=filename_suffix,
add_missing_sections=add_missing_sections,
raise_on_error=False,
Expand Down
15 changes: 10 additions & 5 deletions end_to_end_tests/generated_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ def import_symbol(self, module_path: str, name: str) -> Any:

def _run_command(
command: str,
*,
extra_args: list[str] | None = None,
openapi_document: str | Path | None = None,
url: str | None = None,
Expand All @@ -84,6 +85,7 @@ def _run_command(


def generate_client(
*,
openapi_document: str | Path,
extra_args: list[str] | None = None,
output_path: str = "my-test-api-client",
Expand All @@ -102,7 +104,9 @@ def generate_client(
args.extend(["--output-path", str(full_output_path)])
if overwrite:
args.append("--overwrite")
generator_result = _run_command("generate", args, openapi_document, raise_on_error=raise_on_error)
generator_result = _run_command(
"generate", extra_args=args, openapi_document=openapi_document, raise_on_error=raise_on_error
)
return GeneratedClientContext(
full_output_path,
generator_result,
Expand All @@ -113,6 +117,7 @@ def generate_client(

def generate_client_from_inline_spec(
openapi_spec: str,
*,
extra_args: list[str] | None = None,
config: str = "",
filename_suffix: str | None = None,
Expand Down Expand Up @@ -146,10 +151,10 @@ def generate_client_from_inline_spec(
extra_args = [*extra_args, "--config", config_file.name]

generated_client = generate_client(
file.name,
extra_args,
output_path,
base_module,
openapi_document=file.name,
extra_args=extra_args,
output_path=output_path,
base_module=base_module,
raise_on_error=raise_on_error,
)
os.unlink(file.name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,7 @@ client = AuthenticatedClient(
You can also disable certificate validation altogether, but beware that **this is a security risk**.

```python
client = AuthenticatedClient(
base_url="https://internal_api.example.com",
token="SuperSecretToken",
verify_ssl=False
)
client = AuthenticatedClient(base_url="https://internal_api.example.com", token="SuperSecretToken", verify_ssl=False)
```

Things to know:
Expand All @@ -81,13 +77,16 @@ There are more settings on the generated `Client` class which let you control mo
```python
from my_test_api_client import Client


def log_request(request):
print(f"Request event hook: {request.method} {request.url} - Waiting for response")


def log_response(response):
request = response.request
print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")


client = Client(
base_url="https://api.example.com",
httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
Expand Down
9 changes: 4 additions & 5 deletions end_to_end_tests/golden-records/escapes-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,7 @@ client = AuthenticatedClient(
You can also disable certificate validation altogether, but beware that **this is a security risk**.

```python
client = AuthenticatedClient(
base_url="https://internal_api.example.com",
token="SuperSecretToken",
verify_ssl=False
)
client = AuthenticatedClient(base_url="https://internal_api.example.com", token="SuperSecretToken", verify_ssl=False)
```

Things to know:
Expand All @@ -81,13 +77,16 @@ There are more settings on the generated `Client` class which let you control mo
```python
from escapes_client import Client


def log_request(request):
print(f"Request event hook: {request.method} {request.url} - Waiting for response")


def log_response(response):
request = response.request
print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")


client = Client(
base_url="https://api.example.com",
httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
Expand Down
9 changes: 4 additions & 5 deletions end_to_end_tests/golden-records/my-enum-api-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,7 @@ client = AuthenticatedClient(
You can also disable certificate validation altogether, but beware that **this is a security risk**.

```python
client = AuthenticatedClient(
base_url="https://internal_api.example.com",
token="SuperSecretToken",
verify_ssl=False
)
client = AuthenticatedClient(base_url="https://internal_api.example.com", token="SuperSecretToken", verify_ssl=False)
```

Things to know:
Expand All @@ -81,13 +77,16 @@ There are more settings on the generated `Client` class which let you control mo
```python
from my_enum_api_client import Client


def log_request(request):
print(f"Request event hook: {request.method} {request.url} - Waiting for response")


def log_response(response):
request = response.request
print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")


client = Client(
base_url="https://api.example.com",
httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
Expand Down
9 changes: 4 additions & 5 deletions end_to_end_tests/golden-records/my-test-api-client/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,7 @@ client = AuthenticatedClient(
You can also disable certificate validation altogether, but beware that **this is a security risk**.

```python
client = AuthenticatedClient(
base_url="https://internal_api.example.com",
token="SuperSecretToken",
verify_ssl=False
)
client = AuthenticatedClient(base_url="https://internal_api.example.com", token="SuperSecretToken", verify_ssl=False)
```

Things to know:
Expand All @@ -81,13 +77,16 @@ There are more settings on the generated `Client` class which let you control mo
```python
from my_test_api_client import Client


def log_request(request):
print(f"Request event hook: {request.method} {request.url} - Waiting for response")


def log_response(response):
request = response.request
print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")


client = Client(
base_url="https://api.example.com",
httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,7 @@ client = AuthenticatedClient(
You can also disable certificate validation altogether, but beware that **this is a security risk**.

```python
client = AuthenticatedClient(
base_url="https://internal_api.example.com",
token="SuperSecretToken",
verify_ssl=False
)
client = AuthenticatedClient(base_url="https://internal_api.example.com", token="SuperSecretToken", verify_ssl=False)
```

Things to know:
Expand All @@ -81,13 +77,16 @@ There are more settings on the generated `Client` class which let you control mo
```python
from test_3_1_features_client import Client


def log_request(request):
print(f"Request event hook: {request.method} {request.url} - Waiting for response")


def log_response(response):
request = response.request
print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")


client = Client(
base_url="https://api.example.com",
httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
Expand Down
22 changes: 13 additions & 9 deletions end_to_end_tests/test_end_to_end.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@


def _compare_directories(
*,
record: Path,
test_subject: Path,
expected_differences: dict[Path, str] | None = None,
Expand Down Expand Up @@ -59,8 +60,8 @@ def _compare_directories(

for sub_path in dc.common_dirs:
_compare_directories(
record / sub_path,
test_subject / sub_path,
record=record / sub_path,
test_subject=test_subject / sub_path,
expected_differences=expected_differences,
ignore=ignore,
depth=depth + 1,
Expand All @@ -80,7 +81,7 @@ def run_e2e_test(
*,
golden_record_path: str | None = None,
) -> Result:
with generate_client(openapi_document, extra_args, output_path) as g:
with generate_client(openapi_document=openapi_document, extra_args=extra_args, output_path=output_path) as g:
if golden_record_path:
gr_path = Path(__file__).parent / "golden-records" / golden_record_path
else:
Expand All @@ -90,7 +91,10 @@ def run_e2e_test(
# Use absolute paths for expected differences for easier comparisons
expected_differences = {g.output_path.joinpath(key): value for key, value in expected_differences.items()}
_compare_directories(
gr_path, g.output_path, expected_differences=expected_differences, expected_missing=expected_missing
record=gr_path,
test_subject=g.output_path,
expected_differences=expected_differences,
expected_missing=expected_missing,
)

result = subprocess.run(
Expand Down Expand Up @@ -146,7 +150,7 @@ def test_escapes_end_to_end():
)
def test_meta(meta: str, generated_file: str | None, expected_file: str | None):
with generate_client(
"3.1_specific.openapi.yaml",
openapi_document="3.1_specific.openapi.yaml",
extra_args=[f"--meta={meta}"],
output_path="test-3-1-features-client",
) as g:
Expand Down Expand Up @@ -220,7 +224,7 @@ def test_bad_url():
@pytest.mark.parametrize("document", ERROR_DOCUMENTS, ids=[path.stem for path in ERROR_DOCUMENTS])
def test_documents_with_errors(snapshot, document):
with generate_client(
document,
openapi_document=document,
extra_args=["--fail-on-warning"],
output_path="test-documents-with-errors",
raise_on_error=False,
Expand All @@ -234,8 +238,8 @@ def test_documents_with_errors(snapshot, document):
def test_custom_post_hooks():
config_path = Path(__file__).parent / "custom_post_hooks.config.yml"
with generate_client(
"baseline_openapi_3.0.json",
[f"--config={config_path}"],
openapi_document="baseline_openapi_3.0.json",
extra_args=[f"--config={config_path}"],
raise_on_error=False,
) as g:
assert g.generator_result.exit_code == 1
Expand Down Expand Up @@ -271,7 +275,7 @@ def test_update_integration_tests():
url=url,
config_path=config_path,
)
_compare_directories(source_path, temp_dir, ignore=["pyproject.toml"])
_compare_directories(record=source_path, test_subject=temp_dir, ignore=["pyproject.toml"])
result = subprocess.run(
[sys.executable, "-m", "mypy", str(temp_dir), "--strict"],
capture_output=True,
Expand Down
4 changes: 2 additions & 2 deletions fuzz/test_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,12 @@ def test_valid_openapi_never_generates_invalid_python(document: dict[str, Any],
document_path.write_text(json.dumps(document, ensure_ascii=False), encoding="utf-8")

config = Config.from_sources(
ConfigFile(
config_file=ConfigFile(
project_name_override="fuzz-client",
package_name_override="fuzz_client",
post_hooks=[],
),
meta_type,
meta_type=meta_type,
document_source=document_path,
file_encoding="utf-8",
overwrite=False,
Expand Down
9 changes: 4 additions & 5 deletions integration-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,7 @@ client = AuthenticatedClient(
You can also disable certificate validation altogether, but beware that **this is a security risk**.

```python
client = AuthenticatedClient(
base_url="https://internal_api.example.com",
token="SuperSecretToken",
verify_ssl=False
)
client = AuthenticatedClient(base_url="https://internal_api.example.com", token="SuperSecretToken", verify_ssl=False)
```

Things to know:
Expand All @@ -81,13 +77,16 @@ There are more settings on the generated `Client` class which let you control mo
```python
from integration_tests import Client


def log_request(request):
print(f"Request event hook: {request.method} {request.url} - Waiting for response")


def log_response(response):
request = response.request
print(f"Response event hook: {request.method} {request.url} - Status {response.status_code}")


client = Client(
base_url="https://api.example.com",
httpx_args={"event_hooks": {"request": [log_request], "response": [log_response]}},
Expand Down
10 changes: 9 additions & 1 deletion openapi_python_client/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,14 @@ def _process_config(
except Exception as err:
raise typer.BadParameter("Unable to parse config") from err

return Config.from_sources(config_file, meta_type, source, file_encoding, overwrite, output_path=output_path)
return Config.from_sources(
config_file=config_file,
meta_type=meta_type,
document_source=source,
file_encoding=file_encoding,
overwrite=overwrite,
output_path=output_path,
)


# noinspection PyUnusedLocal
Expand Down Expand Up @@ -123,6 +130,7 @@ def handle_errors(errors: Sequence[GeneratorError], fail_on_warning: bool = Fals

@app.command()
def generate(
*,
url: str | None = typer.Option(None, help="A URL to read the OpenAPI document from"),
path: Path | None = typer.Option(None, help="A path to the OpenAPI document"),
custom_template_path: Path | None = typer.Option(
Expand Down
1 change: 1 addition & 0 deletions openapi_python_client/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class Config:

@staticmethod
def from_sources(
*,
config_file: ConfigFile,
meta_type: MetaType,
document_source: Path | str,
Expand Down
2 changes: 2 additions & 0 deletions openapi_python_client/parser/properties/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ def _string_based_property(


def _property_from_ref(
*,
name: UntrustedString,
required: bool,
parent: oai.Schema | None,
Expand Down Expand Up @@ -141,6 +142,7 @@ def _property_from_ref(


def property_from_data( # noqa: PLR0911, PLR0912
*,
name: UntrustedString,
required: bool,
data: oai.Reference | oai.Schema,
Expand Down
1 change: 1 addition & 0 deletions openapi_python_client/parser/properties/any.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ class AnyProperty(PropertyProtocol):
@classmethod
def build(
cls,
*,
name: UntrustedString,
required: bool,
default: Any,
Expand Down
1 change: 1 addition & 0 deletions openapi_python_client/parser/properties/boolean.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class BooleanProperty(PropertyProtocol):
@classmethod
def build(
cls,
*,
name: oai.UntrustedString,
required: bool,
default: Any,
Expand Down
Loading
Loading