Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge from upstream main #224

Merged
merged 2 commits into from
Jan 10, 2025
Merged
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
66 changes: 66 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -13,6 +13,72 @@ Programmatic usage of this project (e.g., importing it as a Python module) and t

The 0.x prefix used in versions for this project is to indicate that breaking changes are expected frequently (several times a year). Breaking changes will increment the minor number, all other changes will increment the patch number. You can track the progress toward 1.0 [here](https://github.com/openapi-generators/openapi-python-client/projects/2).

## 0.23.0 (2024-12-24)

### Breaking Changes

#### Delete fewer files with `--overwrite`

`--overwrite` will no longer delete the entire output directory before regenerating. Instead, it will only delete
specific, known directories within that directory. Right now, that is only the generated `models` and `api` directories.

Other generated files, like `README.md`, will be overwritten. Extra files and directories outside of those listed above
will be left untouched, so you can any extra modules or files around while still updating `pyproject.toml` automatically.

Closes #1105.

### Features

- Support httpx 0.28 (#1172)

#### Add `generate_all_tags` config option

You can now, optionally, generate **duplicate** endpoint functions/modules using _every_ tag for an endpoint,
not just the first one, by setting `generate_all_tags: true` in your configuration file.

### Fixes

- Support Typer 0.14 and 0.15 (#1173)

#### Fix minimum `attrs` version

The minimum `attrs` dependency version was incorrectly set to 21.3.0. This has been corrected to 22.2.0, the minimum
supported version since `openapi-python-client` 0.19.1.

Closes #1084, thanks @astralblue!

#### Fix compatibility with Pydantic 2.10+

##1176 by @Viicos

Set `defer_build` to models that we know will fail to build, and call `model_rebuild`
in the `__init__.py` file.

## 0.22.0 (2024-11-23)

### Breaking Changes

#### Drop support for Python 3.8

Python 3.8 is no longer supported. "New" 3.9 syntax, like generics on builtin collections, is used both in the generator
and the generated code.

#### `type` is now a reserved field name

Because `type` is used in type annotations now, it is no longer a valid field name. Fields which were previously named
`type` will be renamed to `type_`.

### Features

- Support Ruff 0.8 (#1169)

## 0.21.7 (2024-10-28)

### Fixes

- allow required fields list to be specified as empty (#651) (#1149)
- import cast for required const properties, since it's used in the template (#1153)

## 0.21.6 (2024-10-20)

### Features
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -111,6 +111,16 @@ literal_enums: true

This is especially useful if enum values, when transformed to their Python names, end up conflicting due to case sensitivity or special symbols.

### generate_all_tags

`openapi-python-client` generates module names within the `api` module based on the OpenAPI `tags` of each endpoint.
By default, only the _first_ tag is generated. If you want to generate **duplicate** endpoint functions using _every_ tag
listed, you can enable this option:

```yaml
generate_all_tags: true
```

### project_name_override and package_name_override

Used to change the name of generated client library project/package. If the project name is changed but an override for the package name
14 changes: 14 additions & 0 deletions end_to_end_tests/__snapshots__/test_end_to_end.ambr
Original file line number Diff line number Diff line change
@@ -1,4 +1,18 @@
# serializer version: 1
# name: test_documents_with_errors[bad-status-code]
'''
Generating /test-documents-with-errors
Warning(s) encountered while generating. Client was generated, but some pieces may be missing

WARNING parsing GET / within default.

Invalid response status code abcdef (not a valid HTTP status code), response will be omitted from generated client


If you believe this was a mistake or this tool is missing a feature you need, please open an issue at https://github.com/openapi-generators/openapi-python-client/issues/new/choose

'''
# ---
# name: test_documents_with_errors[circular-body-ref]
'''
Generating /test-documents-with-errors
4 changes: 1 addition & 3 deletions end_to_end_tests/baseline_openapi_3.0.json
Original file line number Diff line number Diff line change
@@ -1163,9 +1163,7 @@
},
"/tag_with_number": {
"get": {
"tags": [
"1"
],
"tags": ["1", "2"],
"responses": {
"200": {
"description": "Success"
4 changes: 1 addition & 3 deletions end_to_end_tests/baseline_openapi_3.1.yaml
Original file line number Diff line number Diff line change
@@ -1155,9 +1155,7 @@ info:
},
"/tag_with_number": {
"get": {
"tags": [
"1"
],
"tags": ["1", "2"],
"responses": {
"200": {
"description": "Success"
1 change: 1 addition & 0 deletions end_to_end_tests/config.yml
Original file line number Diff line number Diff line change
@@ -11,3 +11,4 @@ class_overrides:
field_prefix: attr_
content_type_overrides:
openapi/python/client: application/json
generate_all_tags: true
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Contains methods for accessing the API"""

from typing import Type

from .bodies import BodiesEndpoints
from .config import ConfigEndpoints
from .default import DefaultEndpoints
@@ -13,59 +11,64 @@
from .parameters import ParametersEndpoints
from .responses import ResponsesEndpoints
from .tag1 import Tag1Endpoints
from .tag2 import Tag2Endpoints
from .tests import TestsEndpoints
from .true_ import True_Endpoints


class MyTestApiClientApi:
@classmethod
def bodies(cls) -> Type[BodiesEndpoints]:
def bodies(cls) -> type[BodiesEndpoints]:
return BodiesEndpoints

@classmethod
def tests(cls) -> Type[TestsEndpoints]:
def tests(cls) -> type[TestsEndpoints]:
return TestsEndpoints

@classmethod
def defaults(cls) -> Type[DefaultsEndpoints]:
def defaults(cls) -> type[DefaultsEndpoints]:
return DefaultsEndpoints

@classmethod
def enums(cls) -> Type[EnumsEndpoints]:
def enums(cls) -> type[EnumsEndpoints]:
return EnumsEndpoints

@classmethod
def responses(cls) -> Type[ResponsesEndpoints]:
def responses(cls) -> type[ResponsesEndpoints]:
return ResponsesEndpoints

@classmethod
def default(cls) -> Type[DefaultEndpoints]:
def default(cls) -> type[DefaultEndpoints]:
return DefaultEndpoints

@classmethod
def parameters(cls) -> Type[ParametersEndpoints]:
def parameters(cls) -> type[ParametersEndpoints]:
return ParametersEndpoints

@classmethod
def tag1(cls) -> Type[Tag1Endpoints]:
def tag1(cls) -> type[Tag1Endpoints]:
return Tag1Endpoints

@classmethod
def location(cls) -> Type[LocationEndpoints]:
def tag2(cls) -> type[Tag2Endpoints]:
return Tag2Endpoints

@classmethod
def location(cls) -> type[LocationEndpoints]:
return LocationEndpoints

@classmethod
def true_(cls) -> Type[True_Endpoints]:
def true_(cls) -> type[True_Endpoints]:
return True_Endpoints

@classmethod
def naming(cls) -> Type[NamingEndpoints]:
def naming(cls) -> type[NamingEndpoints]:
return NamingEndpoints

@classmethod
def parameter_references(cls) -> Type[ParameterReferencesEndpoints]:
def parameter_references(cls) -> type[ParameterReferencesEndpoints]:
return ParameterReferencesEndpoints

@classmethod
def config(cls) -> Type[ConfigEndpoints]:
def config(cls) -> type[ConfigEndpoints]:
return ConfigEndpoints
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Contains methods for accessing the API Endpoints"""

import types

from . import get_tag_with_number


class Tag2Endpoints:
@classmethod
def get_tag_with_number(cls) -> types.ModuleType:
return get_tag_with_number
14 changes: 14 additions & 0 deletions end_to_end_tests/documents_with_errors/bad-status-code.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
openapi: "3.1.0"
info:
title: "There's something wrong with me"
version: "0.1.0"
paths:
"/":
get:
responses:
"abcdef":
description: "Successful Response"
content:
"application/json":
schema:
const: "Why have a fixed response? I dunno"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, ForwardRef, List, Union
from typing import Any, ForwardRef, Union

from end_to_end_tests.functional_tests.helpers import (
assert_model_decode_encode,
@@ -65,9 +65,9 @@ def test_array_of_object(self, ModelWithArrayOfObjects, SimpleObject):
)

def test_type_hints(self, ModelWithArrayOfAny, ModelWithArrayOfInts, ModelWithArrayOfObjects, Unset):
assert_model_property_type_hint(ModelWithArrayOfAny, "array_prop", Union[List[Any], Unset])
assert_model_property_type_hint(ModelWithArrayOfInts, "array_prop", Union[List[int], Unset])
assert_model_property_type_hint(ModelWithArrayOfObjects, "array_prop", Union[List[ForwardRef("SimpleObject")], Unset])
assert_model_property_type_hint(ModelWithArrayOfAny, "array_prop", Union[list[Any], Unset])
assert_model_property_type_hint(ModelWithArrayOfInts, "array_prop", Union[list[int], Unset])
assert_model_property_type_hint(ModelWithArrayOfObjects, "array_prop", Union[list["SimpleObject"], Unset]) # type: ignore


@with_generated_client_fixture(
@@ -133,16 +133,16 @@ def test_prefix_items_and_regular_items(self, ModelWithMixedItems, SimpleObject)
)

def test_type_hints(self, ModelWithSinglePrefixItem, ModelWithPrefixItems, ModelWithMixedItems, Unset):
assert_model_property_type_hint(ModelWithSinglePrefixItem, "array_prop", Union[List[str], Unset])
assert_model_property_type_hint(ModelWithSinglePrefixItem, "array_prop", Union[list[str], Unset])
assert_model_property_type_hint(
ModelWithPrefixItems,
"array_prop",
Union[List[Union[ForwardRef("SimpleObject"), str]], Unset],
Union[list[Union[ForwardRef("SimpleObject"), str]], Unset],
)
assert_model_property_type_hint(
ModelWithMixedItems,
"array_prop",
Union[List[Union[ForwardRef("SimpleObject"), str]], Unset],
Union[list[Union[ForwardRef("SimpleObject"), str]], Unset],
)
# Note, this test is asserting the current behavior which, due to limitations of the implementation
# (see: https://github.com/openapi-generators/openapi-python-client/pull/1130), is not really doing
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from http import HTTPStatus
from typing import Any, Dict, Optional, Union
from typing import Any, Optional, Union

import httpx

@@ -12,10 +12,10 @@
def _get_kwargs(
*,
body: JsonLikeBody,
) -> Dict[str, Any]:
headers: Dict[str, Any] = {}
) -> dict[str, Any]:
headers: dict[str, Any] = {}

_kwargs: Dict[str, Any] = {
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/bodies/json-like",
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from http import HTTPStatus
from typing import Any, Dict, Optional, Union
from typing import Any, Optional, Union

import httpx

@@ -19,10 +19,10 @@ def _get_kwargs(
PostBodiesMultipleDataBody,
PostBodiesMultipleFilesBody,
],
) -> Dict[str, Any]:
headers: Dict[str, Any] = {}
) -> dict[str, Any]:
headers: dict[str, Any] = {}

_kwargs: Dict[str, Any] = {
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/bodies/multiple",
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from http import HTTPStatus
from typing import Any, Dict, Optional, Union
from typing import Any, Optional, Union

import httpx

@@ -12,10 +12,10 @@
def _get_kwargs(
*,
body: AModel,
) -> Dict[str, Any]:
headers: Dict[str, Any] = {}
) -> dict[str, Any]:
headers: dict[str, Any] = {}

_kwargs: Dict[str, Any] = {
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/bodies/refs",
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from http import HTTPStatus
from typing import Any, Dict, Optional, Union, cast
from typing import Any, Optional, Union, cast

import httpx

@@ -11,10 +11,10 @@
def _get_kwargs(
*,
body: str,
) -> Dict[str, Any]:
headers: Dict[str, Any] = {}
) -> dict[str, Any]:
headers: dict[str, Any] = {}

_kwargs: Dict[str, Any] = {
_kwargs: dict[str, Any] = {
"method": "post",
"url": "/config/content-type-override",
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from http import HTTPStatus
from typing import Any, Dict, Optional, Union
from typing import Any, Optional, Union

import httpx

@@ -11,14 +11,14 @@
def _get_kwargs(
*,
common: Union[Unset, str] = UNSET,
) -> Dict[str, Any]:
params: Dict[str, Any] = {}
) -> dict[str, Any]:
params: dict[str, Any] = {}

params["common"] = common

params = {k: v for k, v in params.items() if v is not UNSET and v is not None}

_kwargs: Dict[str, Any] = {
_kwargs: dict[str, Any] = {
"method": "get",
"url": "/common_parameters",
"params": params,
Loading
Loading