feat: OpenAPI spec update via Stainless API (#99)

This commit is contained in:
stainless-app[bot] 2024-03-08 15:50:28 +00:00
parent e689d46734
commit a8e61f2e7a
6 changed files with 82 additions and 6 deletions

View file

@ -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",

View file

@ -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]

View file

@ -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)

View file

@ -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"

View file

@ -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

View file

@ -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