mirror of
https://github.com/cloudflare/cloudflare-python.git
synced 2026-01-16 23:01:03 +00:00
feat: OpenAPI spec update via Stainless API (#99)
This commit is contained in:
parent
e689d46734
commit
a8e61f2e7a
6 changed files with 82 additions and 6 deletions
|
|
@ -1,7 +1,7 @@
|
|||
# File generated from our OpenAPI spec by Stainless.
|
||||
|
||||
from . import types
|
||||
from ._types import NoneType, Transport, ProxiesTypes
|
||||
from ._types import NOT_GIVEN, NoneType, NotGiven, Transport, ProxiesTypes
|
||||
from ._utils import file_from_path
|
||||
from ._client import (
|
||||
Client,
|
||||
|
|
@ -42,6 +42,8 @@ __all__ = [
|
|||
"NoneType",
|
||||
"Transport",
|
||||
"ProxiesTypes",
|
||||
"NotGiven",
|
||||
"NOT_GIVEN",
|
||||
"CloudflareError",
|
||||
"APIError",
|
||||
"APIStatusError",
|
||||
|
|
|
|||
|
|
@ -30,7 +30,16 @@ from ._types import (
|
|||
AnyMapping,
|
||||
HttpxRequestFiles,
|
||||
)
|
||||
from ._utils import is_list, is_given, is_mapping, parse_date, parse_datetime, strip_not_given
|
||||
from ._utils import (
|
||||
is_list,
|
||||
is_given,
|
||||
is_mapping,
|
||||
parse_date,
|
||||
parse_datetime,
|
||||
strip_not_given,
|
||||
extract_type_arg,
|
||||
is_annotated_type,
|
||||
)
|
||||
from ._compat import (
|
||||
PYDANTIC_V2,
|
||||
ConfigDict,
|
||||
|
|
@ -275,6 +284,9 @@ def construct_type(*, value: object, type_: type) -> object:
|
|||
|
||||
If the given value does not match the expected type then it is returned as-is.
|
||||
"""
|
||||
# unwrap `Annotated[T, ...]` -> `T`
|
||||
if is_annotated_type(type_):
|
||||
type_ = extract_type_arg(type_, 0)
|
||||
|
||||
# we need to use the origin class for any types that are subscripted generics
|
||||
# e.g. Dict[str, object]
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import httpx
|
|||
import pydantic
|
||||
|
||||
from ._types import NoneType
|
||||
from ._utils import is_given, extract_type_var_from_base
|
||||
from ._utils import is_given, extract_type_arg, is_annotated_type, extract_type_var_from_base
|
||||
from ._models import BaseModel, is_basemodel
|
||||
from ._constants import RAW_RESPONSE_HEADER, OVERRIDE_CAST_TO_HEADER
|
||||
from ._streaming import Stream, AsyncStream, is_stream_class_type, extract_stream_chunk_type
|
||||
|
|
@ -121,6 +121,10 @@ class BaseAPIResponse(Generic[R]):
|
|||
)
|
||||
|
||||
def _parse(self, *, to: type[_T] | None = None) -> R | _T:
|
||||
# unwrap `Annotated[T, ...]` -> `T`
|
||||
if to and is_annotated_type(to):
|
||||
to = extract_type_arg(to, 0)
|
||||
|
||||
if self._is_sse_stream:
|
||||
if to:
|
||||
if not is_stream_class_type(to):
|
||||
|
|
@ -162,6 +166,11 @@ class BaseAPIResponse(Generic[R]):
|
|||
)
|
||||
|
||||
cast_to = to if to is not None else self._cast_to
|
||||
|
||||
# unwrap `Annotated[T, ...]` -> `T`
|
||||
if is_annotated_type(cast_to):
|
||||
cast_to = extract_type_arg(cast_to, 0)
|
||||
|
||||
if cast_to is NoneType:
|
||||
return cast(R, None)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import json
|
||||
from typing import Any, Dict, List, Union, Optional, cast
|
||||
from datetime import datetime, timezone
|
||||
from typing_extensions import Literal
|
||||
from typing_extensions import Literal, Annotated
|
||||
|
||||
import pytest
|
||||
import pydantic
|
||||
from pydantic import Field
|
||||
|
||||
from cloudflare._compat import PYDANTIC_V2, parse_obj, model_dump, model_json
|
||||
from cloudflare._models import BaseModel
|
||||
from cloudflare._models import BaseModel, construct_type
|
||||
|
||||
|
||||
class BasicModel(BaseModel):
|
||||
|
|
@ -571,3 +571,15 @@ def test_type_compat() -> None:
|
|||
foo: Optional[str] = None
|
||||
|
||||
takes_pydantic(OurModel())
|
||||
|
||||
|
||||
def test_annotated_types() -> None:
|
||||
class Model(BaseModel):
|
||||
value: str
|
||||
|
||||
m = construct_type(
|
||||
value={"value": "foo"},
|
||||
type_=cast(Any, Annotated[Model, "random metadata"]),
|
||||
)
|
||||
assert isinstance(m, Model)
|
||||
assert m.value == "foo"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import json
|
||||
from typing import List
|
||||
from typing import List, cast
|
||||
from typing_extensions import Annotated
|
||||
|
||||
import httpx
|
||||
import pytest
|
||||
|
|
@ -157,3 +158,37 @@ async def test_async_response_parse_custom_model(async_client: AsyncCloudflare)
|
|||
obj = await response.parse(to=CustomModel)
|
||||
assert obj.foo == "hello!"
|
||||
assert obj.bar == 2
|
||||
|
||||
|
||||
def test_response_parse_annotated_type(client: Cloudflare) -> None:
|
||||
response = APIResponse(
|
||||
raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})),
|
||||
client=client,
|
||||
stream=False,
|
||||
stream_cls=None,
|
||||
cast_to=str,
|
||||
options=FinalRequestOptions.construct(method="get", url="/foo"),
|
||||
)
|
||||
|
||||
obj = response.parse(
|
||||
to=cast("type[CustomModel]", Annotated[CustomModel, "random metadata"]),
|
||||
)
|
||||
assert obj.foo == "hello!"
|
||||
assert obj.bar == 2
|
||||
|
||||
|
||||
async def test_async_response_parse_annotated_type(async_client: AsyncCloudflare) -> None:
|
||||
response = AsyncAPIResponse(
|
||||
raw=httpx.Response(200, content=json.dumps({"foo": "hello!", "bar": 2})),
|
||||
client=async_client,
|
||||
stream=False,
|
||||
stream_cls=None,
|
||||
cast_to=str,
|
||||
options=FinalRequestOptions.construct(method="get", url="/foo"),
|
||||
)
|
||||
|
||||
obj = await response.parse(
|
||||
to=cast("type[CustomModel]", Annotated[CustomModel, "random metadata"]),
|
||||
)
|
||||
assert obj.foo == "hello!"
|
||||
assert obj.bar == 2
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ from cloudflare._utils import (
|
|||
is_list,
|
||||
is_list_type,
|
||||
is_union_type,
|
||||
extract_type_arg,
|
||||
is_annotated_type,
|
||||
)
|
||||
from cloudflare._compat import PYDANTIC_V2, field_outer_type, get_model_fields
|
||||
from cloudflare._models import BaseModel
|
||||
|
|
@ -49,6 +51,10 @@ def assert_matches_type(
|
|||
path: list[str],
|
||||
allow_none: bool = False,
|
||||
) -> None:
|
||||
# unwrap `Annotated[T, ...]` -> `T`
|
||||
if is_annotated_type(type_):
|
||||
type_ = extract_type_arg(type_, 0)
|
||||
|
||||
if allow_none and value is None:
|
||||
return
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue