diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 7723ed4f..89652a35 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "2.18.0"
+ ".": "2.19.0"
}
diff --git a/.stats.yml b/.stats.yml
index fb63efe6..26721953 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,2 @@
configured_endpoints: 97
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-77e2e50c9fb438b08736da759f722f9d062ed3fad3183fb951eb1eee93fa93f5.yml
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/orb%2Forb-908960f165205e2874dd29322cc974df5ab10c7634ab9a342ab22047013de1b4.yml
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4e83b691..9082e3f1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,27 @@
# Changelog
+## 2.19.0 (2024-12-12)
+
+Full Changelog: [v2.18.0...v2.19.0](https://github.com/orbcorp/orb-python/compare/v2.18.0...v2.19.0)
+
+### Features
+
+* **api:** api update ([#459](https://github.com/orbcorp/orb-python/issues/459)) ([6bc521d](https://github.com/orbcorp/orb-python/commit/6bc521d596131d092db8ec463ef3f19fd6460006))
+
+
+### Chores
+
+* **internal:** add support for TypeAliasType ([#458](https://github.com/orbcorp/orb-python/issues/458)) ([b03a8ef](https://github.com/orbcorp/orb-python/commit/b03a8ef06e4207f2051fe9a073078a125ce3f1d6))
+* **internal:** bump pydantic dependency ([#455](https://github.com/orbcorp/orb-python/issues/455)) ([da23d38](https://github.com/orbcorp/orb-python/commit/da23d38f97aa2f474f56c25a2c2f5fc08a2dea3d))
+* **internal:** bump pyright ([#457](https://github.com/orbcorp/orb-python/issues/457)) ([2a4d14a](https://github.com/orbcorp/orb-python/commit/2a4d14a279018d5e5a8cffcbadddf347e567641d))
+* **internal:** version bump ([#451](https://github.com/orbcorp/orb-python/issues/451)) ([11a7427](https://github.com/orbcorp/orb-python/commit/11a7427530a285d2e2df2b3aa59964777015db01))
+* make the `Omit` type public ([#454](https://github.com/orbcorp/orb-python/issues/454)) ([f92f377](https://github.com/orbcorp/orb-python/commit/f92f37709f85b33a1f4aa3667bdd58601405be6c))
+
+
+### Documentation
+
+* **readme:** fix http client proxies example ([#456](https://github.com/orbcorp/orb-python/issues/456)) ([db48031](https://github.com/orbcorp/orb-python/commit/db48031ec6b0de13d04ab872eee657dbffcff556))
+
## 2.18.0 (2024-12-03)
Full Changelog: [v2.17.0...v2.18.0](https://github.com/orbcorp/orb-python/compare/v2.17.0...v2.18.0)
diff --git a/README.md b/README.md
index 0870cd51..acf67a22 100644
--- a/README.md
+++ b/README.md
@@ -397,18 +397,19 @@ can also get all the extra fields on the Pydantic model as a dict with
You can directly override the [httpx client](https://www.python-httpx.org/api/#client) to customize it for your use case, including:
-- Support for proxies
-- Custom transports
+- Support for [proxies](https://www.python-httpx.org/advanced/proxies/)
+- Custom [transports](https://www.python-httpx.org/advanced/transports/)
- Additional [advanced](https://www.python-httpx.org/advanced/clients/) functionality
```python
+import httpx
from orb import Orb, DefaultHttpxClient
client = Orb(
# Or use the `ORB_BASE_URL` env var
base_url="http://my.test.server.example.com:8083",
http_client=DefaultHttpxClient(
- proxies="http://my.test.proxy.example.com",
+ proxy="http://my.test.proxy.example.com",
transport=httpx.HTTPTransport(local_address="0.0.0.0"),
),
)
diff --git a/api.md b/api.md
index a387852d..f9a7248e 100644
--- a/api.md
+++ b/api.md
@@ -385,5 +385,5 @@ Methods:
- client.alerts.create_for_customer(customer_id, \*\*params) -> Alert
- client.alerts.create_for_external_customer(external_customer_id, \*\*params) -> Alert
- client.alerts.create_for_subscription(subscription_id, \*\*params) -> Alert
-- client.alerts.disable(alert_configuration_id) -> Alert
-- client.alerts.enable(alert_configuration_id) -> Alert
+- client.alerts.disable(alert_configuration_id, \*\*params) -> Alert
+- client.alerts.enable(alert_configuration_id, \*\*params) -> Alert
diff --git a/pyproject.toml b/pyproject.toml
index d8d75047..80cdb12d 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "orb-billing"
-version = "2.18.0"
+version = "2.19.0"
description = "The official Python library for the orb API"
dynamic = ["readme"]
license = "Apache-2.0"
@@ -10,7 +10,7 @@ authors = [
dependencies = [
"httpx>=0.23.0, <1",
"pydantic>=1.9.0, <3",
- "typing-extensions>=4.7, <5",
+ "typing-extensions>=4.10, <5",
"anyio>=3.5.0, <5",
"distro>=1.7.0, <2",
"sniffio",
diff --git a/requirements-dev.lock b/requirements-dev.lock
index 637727ec..a9f3cea1 100644
--- a/requirements-dev.lock
+++ b/requirements-dev.lock
@@ -62,13 +62,13 @@ platformdirs==3.11.0
# via virtualenv
pluggy==1.5.0
# via pytest
-pydantic==2.9.2
+pydantic==2.10.3
# via orb-billing
-pydantic-core==2.23.4
+pydantic-core==2.27.1
# via pydantic
pygments==2.18.0
# via rich
-pyright==1.1.389
+pyright==1.1.390
pytest==8.3.3
# via pytest-asyncio
pytest-asyncio==0.24.0
diff --git a/requirements.lock b/requirements.lock
index f452fd2d..844a8552 100644
--- a/requirements.lock
+++ b/requirements.lock
@@ -30,9 +30,9 @@ httpx==0.25.2
idna==3.4
# via anyio
# via httpx
-pydantic==2.9.2
+pydantic==2.10.3
# via orb-billing
-pydantic-core==2.23.4
+pydantic-core==2.27.1
# via pydantic
sniffio==1.3.0
# via anyio
diff --git a/src/orb/__init__.py b/src/orb/__init__.py
index 801a1e71..61ab6a9b 100644
--- a/src/orb/__init__.py
+++ b/src/orb/__init__.py
@@ -1,7 +1,7 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
from . import types
-from ._types import NOT_GIVEN, NoneType, NotGiven, Transport, ProxiesTypes
+from ._types import NOT_GIVEN, Omit, NoneType, NotGiven, Transport, ProxiesTypes
from ._utils import file_from_path
from ._client import Orb, Client, Stream, Timeout, AsyncOrb, Transport, AsyncClient, AsyncStream, RequestOptions
from ._models import BaseModel
@@ -48,6 +48,7 @@
"ProxiesTypes",
"NotGiven",
"NOT_GIVEN",
+ "Omit",
"OrbError",
"APIError",
"APIStatusError",
diff --git a/src/orb/_legacy_response.py b/src/orb/_legacy_response.py
index 02edaa22..4cbb4ddf 100644
--- a/src/orb/_legacy_response.py
+++ b/src/orb/_legacy_response.py
@@ -24,7 +24,7 @@
import pydantic
from ._types import NoneType
-from ._utils import is_given, extract_type_arg, is_annotated_type
+from ._utils import is_given, extract_type_arg, is_annotated_type, is_type_alias_type
from ._models import BaseModel, is_basemodel
from ._constants import RAW_RESPONSE_HEADER
from ._streaming import Stream, AsyncStream, is_stream_class_type, extract_stream_chunk_type
@@ -188,9 +188,15 @@ def elapsed(self) -> datetime.timedelta:
return self.http_response.elapsed
def _parse(self, *, to: type[_T] | None = None) -> R | _T:
+ cast_to = to if to is not None else self._cast_to
+
+ # unwrap `TypeAlias('Name', T)` -> `T`
+ if is_type_alias_type(cast_to):
+ cast_to = cast_to.__value__ # type: ignore[unreachable]
+
# unwrap `Annotated[T, ...]` -> `T`
- if to and is_annotated_type(to):
- to = extract_type_arg(to, 0)
+ if cast_to and is_annotated_type(cast_to):
+ cast_to = extract_type_arg(cast_to, 0)
if self._stream:
if to:
@@ -226,18 +232,12 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
return cast(
R,
stream_cls(
- cast_to=self._cast_to,
+ cast_to=cast_to,
response=self.http_response,
client=cast(Any, self._client),
),
)
- 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)
diff --git a/src/orb/_models.py b/src/orb/_models.py
index 6cb469e2..7a547ce5 100644
--- a/src/orb/_models.py
+++ b/src/orb/_models.py
@@ -46,6 +46,7 @@
strip_not_given,
extract_type_arg,
is_annotated_type,
+ is_type_alias_type,
strip_annotated_type,
)
from ._compat import (
@@ -428,6 +429,8 @@ def construct_type(*, value: object, type_: object) -> object:
# we allow `object` as the input type because otherwise, passing things like
# `Literal['value']` will be reported as a type error by type checkers
type_ = cast("type[object]", type_)
+ if is_type_alias_type(type_):
+ type_ = type_.__value__ # type: ignore[unreachable]
# unwrap `Annotated[T, ...]` -> `T`
if is_annotated_type(type_):
diff --git a/src/orb/_response.py b/src/orb/_response.py
index 5b17754b..20f3cd4d 100644
--- a/src/orb/_response.py
+++ b/src/orb/_response.py
@@ -25,7 +25,7 @@
import pydantic
from ._types import NoneType
-from ._utils import is_given, extract_type_arg, is_annotated_type, extract_type_var_from_base
+from ._utils import is_given, extract_type_arg, is_annotated_type, is_type_alias_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
@@ -126,9 +126,15 @@ def __repr__(self) -> str:
)
def _parse(self, *, to: type[_T] | None = None) -> R | _T:
+ cast_to = to if to is not None else self._cast_to
+
+ # unwrap `TypeAlias('Name', T)` -> `T`
+ if is_type_alias_type(cast_to):
+ cast_to = cast_to.__value__ # type: ignore[unreachable]
+
# unwrap `Annotated[T, ...]` -> `T`
- if to and is_annotated_type(to):
- to = extract_type_arg(to, 0)
+ if cast_to and is_annotated_type(cast_to):
+ cast_to = extract_type_arg(cast_to, 0)
if self._is_sse_stream:
if to:
@@ -164,18 +170,12 @@ def _parse(self, *, to: type[_T] | None = None) -> R | _T:
return cast(
R,
stream_cls(
- cast_to=self._cast_to,
+ cast_to=cast_to,
response=self.http_response,
client=cast(Any, self._client),
),
)
- 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)
diff --git a/src/orb/_types.py b/src/orb/_types.py
index de4bcc59..a7f6c8ac 100644
--- a/src/orb/_types.py
+++ b/src/orb/_types.py
@@ -194,10 +194,8 @@ def get(self, __key: str) -> str | None: ...
StrBytesIntFloat = Union[str, bytes, int, float]
# Note: copied from Pydantic
-# https://github.com/pydantic/pydantic/blob/32ea570bf96e84234d2992e1ddf40ab8a565925a/pydantic/main.py#L49
-IncEx: TypeAlias = Union[
- Set[int], Set[str], Mapping[int, Union["IncEx", Literal[True]]], Mapping[str, Union["IncEx", Literal[True]]]
-]
+# https://github.com/pydantic/pydantic/blob/6f31f8f68ef011f84357330186f603ff295312fd/pydantic/main.py#L79
+IncEx: TypeAlias = Union[Set[int], Set[str], Mapping[int, Union["IncEx", bool]], Mapping[str, Union["IncEx", bool]]]
PostParser = Callable[[Any], Any]
diff --git a/src/orb/_utils/__init__.py b/src/orb/_utils/__init__.py
index a7cff3c0..d4fda26f 100644
--- a/src/orb/_utils/__init__.py
+++ b/src/orb/_utils/__init__.py
@@ -39,6 +39,7 @@
is_iterable_type as is_iterable_type,
is_required_type as is_required_type,
is_annotated_type as is_annotated_type,
+ is_type_alias_type as is_type_alias_type,
strip_annotated_type as strip_annotated_type,
extract_type_var_from_base as extract_type_var_from_base,
)
diff --git a/src/orb/_utils/_typing.py b/src/orb/_utils/_typing.py
index c036991f..278749b1 100644
--- a/src/orb/_utils/_typing.py
+++ b/src/orb/_utils/_typing.py
@@ -1,8 +1,17 @@
from __future__ import annotations
+import sys
+import typing
+import typing_extensions
from typing import Any, TypeVar, Iterable, cast
from collections import abc as _c_abc
-from typing_extensions import Required, Annotated, get_args, get_origin
+from typing_extensions import (
+ TypeIs,
+ Required,
+ Annotated,
+ get_args,
+ get_origin,
+)
from .._types import InheritsGeneric
from .._compat import is_union as _is_union
@@ -36,6 +45,26 @@ def is_typevar(typ: type) -> bool:
return type(typ) == TypeVar # type: ignore
+_TYPE_ALIAS_TYPES: tuple[type[typing_extensions.TypeAliasType], ...] = (typing_extensions.TypeAliasType,)
+if sys.version_info >= (3, 12):
+ _TYPE_ALIAS_TYPES = (*_TYPE_ALIAS_TYPES, typing.TypeAliasType)
+
+
+def is_type_alias_type(tp: Any, /) -> TypeIs[typing_extensions.TypeAliasType]:
+ """Return whether the provided argument is an instance of `TypeAliasType`.
+
+ ```python
+ type Int = int
+ is_type_alias_type(Int)
+ # > True
+ Str = TypeAliasType("Str", str)
+ is_type_alias_type(Str)
+ # > True
+ ```
+ """
+ return isinstance(tp, _TYPE_ALIAS_TYPES)
+
+
# Extracts T from Annotated[T, ...] or from Required[Annotated[T, ...]]
def strip_annotated_type(typ: type) -> type:
if is_required_type(typ) or is_annotated_type(typ):
diff --git a/src/orb/_version.py b/src/orb/_version.py
index f9bd1bfb..9e5ea44f 100644
--- a/src/orb/_version.py
+++ b/src/orb/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "orb"
-__version__ = "2.18.0" # x-release-please-version
+__version__ = "2.19.0" # x-release-please-version
diff --git a/src/orb/resources/alerts.py b/src/orb/resources/alerts.py
index 36f800fa..14e32c00 100644
--- a/src/orb/resources/alerts.py
+++ b/src/orb/resources/alerts.py
@@ -11,7 +11,9 @@
from .. import _legacy_response
from ..types import (
alert_list_params,
+ alert_enable_params,
alert_update_params,
+ alert_disable_params,
alert_create_for_customer_params,
alert_create_for_subscription_params,
alert_create_for_external_customer_params,
@@ -431,6 +433,7 @@ def disable(
self,
alert_configuration_id: str,
*,
+ subscription_id: Optional[str] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -439,10 +442,15 @@ def disable(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
idempotency_key: str | None = None,
) -> Alert:
- """
- This endpoint can be used to disable an alert.
+ """This endpoint allows you to disable an alert.
+
+ To disable a plan-level alert for
+ a specific subscription, you must include the `subscription_id`. The
+ `subscription_id` is not required for customer or subscription level alerts.
Args:
+ subscription_id: Used to update the status of a plan alert scoped to this subscription_id
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -465,6 +473,7 @@ def disable(
extra_body=extra_body,
timeout=timeout,
idempotency_key=idempotency_key,
+ query=maybe_transform({"subscription_id": subscription_id}, alert_disable_params.AlertDisableParams),
),
cast_to=Alert,
)
@@ -473,6 +482,7 @@ def enable(
self,
alert_configuration_id: str,
*,
+ subscription_id: Optional[str] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -481,10 +491,15 @@ def enable(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
idempotency_key: str | None = None,
) -> Alert:
- """
- This endpoint can be used to enable an alert.
+ """This endpoint allows you to enable an alert.
+
+ To enable a plan-level alert for a
+ specific subscription, you must include the `subscription_id`. The
+ `subscription_id` is not required for customer or subscription level alerts.
Args:
+ subscription_id: Used to update the status of a plan alert scoped to this subscription_id
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -507,6 +522,7 @@ def enable(
extra_body=extra_body,
timeout=timeout,
idempotency_key=idempotency_key,
+ query=maybe_transform({"subscription_id": subscription_id}, alert_enable_params.AlertEnableParams),
),
cast_to=Alert,
)
@@ -912,6 +928,7 @@ async def disable(
self,
alert_configuration_id: str,
*,
+ subscription_id: Optional[str] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -920,10 +937,15 @@ async def disable(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
idempotency_key: str | None = None,
) -> Alert:
- """
- This endpoint can be used to disable an alert.
+ """This endpoint allows you to disable an alert.
+
+ To disable a plan-level alert for
+ a specific subscription, you must include the `subscription_id`. The
+ `subscription_id` is not required for customer or subscription level alerts.
Args:
+ subscription_id: Used to update the status of a plan alert scoped to this subscription_id
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -946,6 +968,9 @@ async def disable(
extra_body=extra_body,
timeout=timeout,
idempotency_key=idempotency_key,
+ query=await async_maybe_transform(
+ {"subscription_id": subscription_id}, alert_disable_params.AlertDisableParams
+ ),
),
cast_to=Alert,
)
@@ -954,6 +979,7 @@ async def enable(
self,
alert_configuration_id: str,
*,
+ subscription_id: Optional[str] | NotGiven = NOT_GIVEN,
# Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
# The extra values given here take precedence over values defined on the client or passed to this method.
extra_headers: Headers | None = None,
@@ -962,10 +988,15 @@ async def enable(
timeout: float | httpx.Timeout | None | NotGiven = NOT_GIVEN,
idempotency_key: str | None = None,
) -> Alert:
- """
- This endpoint can be used to enable an alert.
+ """This endpoint allows you to enable an alert.
+
+ To enable a plan-level alert for a
+ specific subscription, you must include the `subscription_id`. The
+ `subscription_id` is not required for customer or subscription level alerts.
Args:
+ subscription_id: Used to update the status of a plan alert scoped to this subscription_id
+
extra_headers: Send extra headers
extra_query: Add additional query parameters to the request
@@ -988,6 +1019,9 @@ async def enable(
extra_body=extra_body,
timeout=timeout,
idempotency_key=idempotency_key,
+ query=await async_maybe_transform(
+ {"subscription_id": subscription_id}, alert_enable_params.AlertEnableParams
+ ),
),
cast_to=Alert,
)
diff --git a/src/orb/types/__init__.py b/src/orb/types/__init__.py
index bbccb109..18c8b027 100644
--- a/src/orb/types/__init__.py
+++ b/src/orb/types/__init__.py
@@ -33,6 +33,7 @@
from .plan_create_params import PlanCreateParams as PlanCreateParams
from .plan_update_params import PlanUpdateParams as PlanUpdateParams
from .subscription_usage import SubscriptionUsage as SubscriptionUsage
+from .alert_enable_params import AlertEnableParams as AlertEnableParams
from .alert_update_params import AlertUpdateParams as AlertUpdateParams
from .event_ingest_params import EventIngestParams as EventIngestParams
from .event_search_params import EventSearchParams as EventSearchParams
@@ -40,6 +41,7 @@
from .invoice_list_params import InvoiceListParams as InvoiceListParams
from .price_create_params import PriceCreateParams as PriceCreateParams
from .price_update_params import PriceUpdateParams as PriceUpdateParams
+from .alert_disable_params import AlertDisableParams as AlertDisableParams
from .coupon_create_params import CouponCreateParams as CouponCreateParams
from .customer_list_params import CustomerListParams as CustomerListParams
from .evaluate_price_group import EvaluatePriceGroup as EvaluatePriceGroup
diff --git a/src/orb/types/alert_disable_params.py b/src/orb/types/alert_disable_params.py
new file mode 100644
index 00000000..dc4a9847
--- /dev/null
+++ b/src/orb/types/alert_disable_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import TypedDict
+
+__all__ = ["AlertDisableParams"]
+
+
+class AlertDisableParams(TypedDict, total=False):
+ subscription_id: Optional[str]
+ """Used to update the status of a plan alert scoped to this subscription_id"""
diff --git a/src/orb/types/alert_enable_params.py b/src/orb/types/alert_enable_params.py
new file mode 100644
index 00000000..b607505a
--- /dev/null
+++ b/src/orb/types/alert_enable_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import TypedDict
+
+__all__ = ["AlertEnableParams"]
+
+
+class AlertEnableParams(TypedDict, total=False):
+ subscription_id: Optional[str]
+ """Used to update the status of a plan alert scoped to this subscription_id"""
diff --git a/tests/api_resources/test_alerts.py b/tests/api_resources/test_alerts.py
index cb07e015..568aa4ea 100644
--- a/tests/api_resources/test_alerts.py
+++ b/tests/api_resources/test_alerts.py
@@ -318,14 +318,22 @@ def test_path_params_create_for_subscription(self, client: Orb) -> None:
@parametrize
def test_method_disable(self, client: Orb) -> None:
alert = client.alerts.disable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
+ )
+ assert_matches_type(Alert, alert, path=["response"])
+
+ @parametrize
+ def test_method_disable_with_all_params(self, client: Orb) -> None:
+ alert = client.alerts.disable(
+ alert_configuration_id="alert_configuration_id",
+ subscription_id="subscription_id",
)
assert_matches_type(Alert, alert, path=["response"])
@parametrize
def test_raw_response_disable(self, client: Orb) -> None:
response = client.alerts.with_raw_response.disable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
)
assert response.is_closed is True
@@ -336,7 +344,7 @@ def test_raw_response_disable(self, client: Orb) -> None:
@parametrize
def test_streaming_response_disable(self, client: Orb) -> None:
with client.alerts.with_streaming_response.disable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -352,20 +360,28 @@ def test_path_params_disable(self, client: Orb) -> None:
ValueError, match=r"Expected a non-empty value for `alert_configuration_id` but received ''"
):
client.alerts.with_raw_response.disable(
- "",
+ alert_configuration_id="",
)
@parametrize
def test_method_enable(self, client: Orb) -> None:
alert = client.alerts.enable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
+ )
+ assert_matches_type(Alert, alert, path=["response"])
+
+ @parametrize
+ def test_method_enable_with_all_params(self, client: Orb) -> None:
+ alert = client.alerts.enable(
+ alert_configuration_id="alert_configuration_id",
+ subscription_id="subscription_id",
)
assert_matches_type(Alert, alert, path=["response"])
@parametrize
def test_raw_response_enable(self, client: Orb) -> None:
response = client.alerts.with_raw_response.enable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
)
assert response.is_closed is True
@@ -376,7 +392,7 @@ def test_raw_response_enable(self, client: Orb) -> None:
@parametrize
def test_streaming_response_enable(self, client: Orb) -> None:
with client.alerts.with_streaming_response.enable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -392,7 +408,7 @@ def test_path_params_enable(self, client: Orb) -> None:
ValueError, match=r"Expected a non-empty value for `alert_configuration_id` but received ''"
):
client.alerts.with_raw_response.enable(
- "",
+ alert_configuration_id="",
)
@@ -696,14 +712,22 @@ async def test_path_params_create_for_subscription(self, async_client: AsyncOrb)
@parametrize
async def test_method_disable(self, async_client: AsyncOrb) -> None:
alert = await async_client.alerts.disable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
+ )
+ assert_matches_type(Alert, alert, path=["response"])
+
+ @parametrize
+ async def test_method_disable_with_all_params(self, async_client: AsyncOrb) -> None:
+ alert = await async_client.alerts.disable(
+ alert_configuration_id="alert_configuration_id",
+ subscription_id="subscription_id",
)
assert_matches_type(Alert, alert, path=["response"])
@parametrize
async def test_raw_response_disable(self, async_client: AsyncOrb) -> None:
response = await async_client.alerts.with_raw_response.disable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
)
assert response.is_closed is True
@@ -714,7 +738,7 @@ async def test_raw_response_disable(self, async_client: AsyncOrb) -> None:
@parametrize
async def test_streaming_response_disable(self, async_client: AsyncOrb) -> None:
async with async_client.alerts.with_streaming_response.disable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -730,20 +754,28 @@ async def test_path_params_disable(self, async_client: AsyncOrb) -> None:
ValueError, match=r"Expected a non-empty value for `alert_configuration_id` but received ''"
):
await async_client.alerts.with_raw_response.disable(
- "",
+ alert_configuration_id="",
)
@parametrize
async def test_method_enable(self, async_client: AsyncOrb) -> None:
alert = await async_client.alerts.enable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
+ )
+ assert_matches_type(Alert, alert, path=["response"])
+
+ @parametrize
+ async def test_method_enable_with_all_params(self, async_client: AsyncOrb) -> None:
+ alert = await async_client.alerts.enable(
+ alert_configuration_id="alert_configuration_id",
+ subscription_id="subscription_id",
)
assert_matches_type(Alert, alert, path=["response"])
@parametrize
async def test_raw_response_enable(self, async_client: AsyncOrb) -> None:
response = await async_client.alerts.with_raw_response.enable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
)
assert response.is_closed is True
@@ -754,7 +786,7 @@ async def test_raw_response_enable(self, async_client: AsyncOrb) -> None:
@parametrize
async def test_streaming_response_enable(self, async_client: AsyncOrb) -> None:
async with async_client.alerts.with_streaming_response.enable(
- "alert_configuration_id",
+ alert_configuration_id="alert_configuration_id",
) as response:
assert not response.is_closed
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
@@ -770,5 +802,5 @@ async def test_path_params_enable(self, async_client: AsyncOrb) -> None:
ValueError, match=r"Expected a non-empty value for `alert_configuration_id` but received ''"
):
await async_client.alerts.with_raw_response.enable(
- "",
+ alert_configuration_id="",
)
diff --git a/tests/test_models.py b/tests/test_models.py
index 6c5a7624..52caebb2 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -1,7 +1,7 @@
import json
from typing import Any, Dict, List, Union, Optional, cast
from datetime import datetime, timezone
-from typing_extensions import Literal, Annotated
+from typing_extensions import Literal, Annotated, TypeAliasType
import pytest
import pydantic
@@ -828,3 +828,19 @@ class B(BaseModel):
# if the discriminator details object stays the same between invocations then
# we hit the cache
assert UnionType.__discriminator__ is discriminator
+
+
+@pytest.mark.skipif(not PYDANTIC_V2, reason="TypeAliasType is not supported in Pydantic v1")
+def test_type_alias_type() -> None:
+ Alias = TypeAliasType("Alias", str)
+
+ class Model(BaseModel):
+ alias: Alias
+ union: Union[int, Alias]
+
+ m = construct_type(value={"alias": "foo", "union": "bar"}, type_=Model)
+ assert isinstance(m, Model)
+ assert isinstance(m.alias, str)
+ assert m.alias == "foo"
+ assert isinstance(m.union, str)
+ assert m.union == "bar"
diff --git a/tests/utils.py b/tests/utils.py
index 1fa786ba..b9278ac2 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -16,6 +16,7 @@
is_union_type,
extract_type_arg,
is_annotated_type,
+ is_type_alias_type,
)
from orb._compat import PYDANTIC_V2, field_outer_type, get_model_fields
from orb._models import BaseModel
@@ -51,6 +52,9 @@ def assert_matches_type(
path: list[str],
allow_none: bool = False,
) -> None:
+ if is_type_alias_type(type_):
+ type_ = type_.__value__
+
# unwrap `Annotated[T, ...]` -> `T`
if is_annotated_type(type_):
type_ = extract_type_arg(type_, 0)