diff --git a/.fern/metadata.json b/.fern/metadata.json index 3d72628..d6ba897 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -23,6 +23,6 @@ } ] }, - "originGitCommit": "786b643cc0bf17aff1114597108246b5cf8af395", - "sdkVersion": "1.2.4" + "originGitCommit": "c7ae462826a6e814bff92fd1ae9fc8c18b8359ba", + "sdkVersion": "1.2.5" } \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index bda43d0..c2268b5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -240,14 +240,14 @@ files = [ [[package]] name = "certifi" -version = "2026.5.20" +version = "2026.6.17" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" groups = ["main"] files = [ - {file = "certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897"}, - {file = "certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d"}, + {file = "certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db"}, + {file = "certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432"}, ] [[package]] diff --git a/pyproject.toml b/pyproject.toml index 279d823..900d0e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ dynamic = ["version"] [tool.poetry] name = "schematichq" -version = "1.2.4" +version = "1.2.5" description = "" readme = "README.md" authors = [] diff --git a/reference.md b/reference.md index c2f7baf..decafbd 100644 --- a/reference.md +++ b/reference.md @@ -2749,6 +2749,7 @@ client.billing.list_billing_prices( ], interval="interval", is_active=True, + plan_version_id="plan_version_id", price=1000000, product_id="product_id", product_ids=[ @@ -2825,6 +2826,14 @@ client.billing.list_billing_prices(
+**plan_version_id:** `typing.Optional[str]` — Filter for prices belonging to a specific plan version (e.g. the latest published version) + +
+
+ +
+
+ **price:** `typing.Optional[int]`
@@ -3206,6 +3215,7 @@ client.billing.list_billing_product_prices( ], interval="interval", is_active=True, + plan_version_id="plan_version_id", price=1000000, product_id="product_id", product_ids=[ @@ -3282,6 +3292,14 @@ client.billing.list_billing_product_prices(
+**plan_version_id:** `typing.Optional[str]` — Filter for prices belonging to a specific plan version (e.g. the latest published version) + +
+
+ +
+
+ **price:** `typing.Optional[int]`
@@ -21771,6 +21789,74 @@ client.webhooks.delete_webhook(
+ +
+ + +
client.webhooks.send_test_webhook_action(...) -> SendTestWebhookActionResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```python +from schematic import Schematic +from schematic.environment import SchematicEnvironment + +client = Schematic( + api_key="", + environment=SchematicEnvironment.DEFAULT, +) + +client.webhooks.send_test_webhook_action( + webhook_id="webhook_id", + request_type="subscription.trial.ended", +) + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**webhook_id:** `str` — webhook_id + +
+
+ +
+
+ +**request_type:** `WebhookRequestType` + +
+
+ +
+
+ +**request_options:** `typing.Optional[RequestOptions]` — Request-specific configuration. + +
+
+
+
+ +
diff --git a/src/schematic/__init__.py b/src/schematic/__init__.py index 9b8f5c7..1072af4 100644 --- a/src/schematic/__init__.py +++ b/src/schematic/__init__.py @@ -82,6 +82,7 @@ CheckoutSettingsResponseData, CheckoutSubscription, ClerkIntegrationConfig, + CompanyCreditBalance, CompanyCreditBalanceResponseData, CompanyDetailResponseData, CompanyEventPeriodMetricsResponseData, @@ -353,6 +354,7 @@ SubscriptionType, TemporaryAccessTokenResourceType, TemporaryAccessTokenResponseData, + TestWebhookResponseData, TimeSeriesGranularity, TopFeatureByUsageResponseData, TopFeaturesByUsageResponseData, @@ -761,6 +763,7 @@ ListWebhookEventsResponse, ListWebhooksParams, ListWebhooksResponse, + SendTestWebhookActionResponse, UpdateWebhookResponse, ) _dynamic_imports: typing.Dict[str, str] = { @@ -849,6 +852,7 @@ "CheckoutSettingsResponseData": ".types", "CheckoutSubscription": ".types", "ClerkIntegrationConfig": ".types", + "CompanyCreditBalance": ".types", "CompanyCreditBalanceResponseData": ".types", "CompanyDetailResponseData": ".types", "CompanyEventPeriodMetricsResponseData": ".types", @@ -1391,6 +1395,7 @@ "SchematicConfig": ".client", "SchematicEnvironment": ".environment", "SegmentStatusResp": ".types", + "SendTestWebhookActionResponse": ".webhooks", "SkippedEntitlementErrorResponseData": ".types", "SkippedEntitlementResponseData": ".types", "SoftDeleteBillingCreditResponse": ".credits", @@ -1403,6 +1408,7 @@ "SubscriptionType": ".types", "TemporaryAccessTokenResourceType": ".types", "TemporaryAccessTokenResponseData": ".types", + "TestWebhookResponseData": ".types", "TimeSeriesGranularity": ".types", "TopFeatureByUsageResponseData": ".types", "TopFeaturesByUsageResponseData": ".types", @@ -1610,6 +1616,7 @@ def __dir__(): "CheckoutSettingsResponseData", "CheckoutSubscription", "ClerkIntegrationConfig", + "CompanyCreditBalance", "CompanyCreditBalanceResponseData", "CompanyDetailResponseData", "CompanyEventPeriodMetricsResponseData", @@ -2152,6 +2159,7 @@ def __dir__(): "SchematicConfig", "SchematicEnvironment", "SegmentStatusResp", + "SendTestWebhookActionResponse", "SkippedEntitlementErrorResponseData", "SkippedEntitlementResponseData", "SoftDeleteBillingCreditResponse", @@ -2164,6 +2172,7 @@ def __dir__(): "SubscriptionType", "TemporaryAccessTokenResourceType", "TemporaryAccessTokenResponseData", + "TestWebhookResponseData", "TimeSeriesGranularity", "TopFeatureByUsageResponseData", "TopFeaturesByUsageResponseData", diff --git a/src/schematic/billing/client.py b/src/schematic/billing/client.py index eb242ec..28cadde 100644 --- a/src/schematic/billing/client.py +++ b/src/schematic/billing/client.py @@ -792,6 +792,7 @@ def list_billing_prices( ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, interval: typing.Optional[str] = None, is_active: typing.Optional[bool] = None, + plan_version_id: typing.Optional[str] = None, price: typing.Optional[int] = None, product_id: typing.Optional[str] = None, product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, @@ -823,6 +824,9 @@ def list_billing_prices( is_active : typing.Optional[bool] Filter for active prices on active products (defaults to true if not specified) + plan_version_id : typing.Optional[str] + Filter for prices belonging to a specific plan version (e.g. the latest published version) + price : typing.Optional[int] product_id : typing.Optional[str] @@ -868,6 +872,7 @@ def list_billing_prices( ids=["ids"], interval="interval", is_active=True, + plan_version_id="plan_version_id", price=1000000, product_id="product_id", product_ids=["product_ids"], @@ -887,6 +892,7 @@ def list_billing_prices( ids=ids, interval=interval, is_active=is_active, + plan_version_id=plan_version_id, price=price, product_id=product_id, product_ids=product_ids, @@ -1054,6 +1060,7 @@ def list_billing_product_prices( ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, interval: typing.Optional[str] = None, is_active: typing.Optional[bool] = None, + plan_version_id: typing.Optional[str] = None, price: typing.Optional[int] = None, product_id: typing.Optional[str] = None, product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, @@ -1085,6 +1092,9 @@ def list_billing_product_prices( is_active : typing.Optional[bool] Filter for active prices on active products (defaults to true if not specified) + plan_version_id : typing.Optional[str] + Filter for prices belonging to a specific plan version (e.g. the latest published version) + price : typing.Optional[int] product_id : typing.Optional[str] @@ -1130,6 +1140,7 @@ def list_billing_product_prices( ids=["ids"], interval="interval", is_active=True, + plan_version_id="plan_version_id", price=1000000, product_id="product_id", product_ids=["product_ids"], @@ -1149,6 +1160,7 @@ def list_billing_product_prices( ids=ids, interval=interval, is_active=is_active, + plan_version_id=plan_version_id, price=price, product_id=product_id, product_ids=product_ids, @@ -2451,6 +2463,7 @@ async def list_billing_prices( ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, interval: typing.Optional[str] = None, is_active: typing.Optional[bool] = None, + plan_version_id: typing.Optional[str] = None, price: typing.Optional[int] = None, product_id: typing.Optional[str] = None, product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, @@ -2482,6 +2495,9 @@ async def list_billing_prices( is_active : typing.Optional[bool] Filter for active prices on active products (defaults to true if not specified) + plan_version_id : typing.Optional[str] + Filter for prices belonging to a specific plan version (e.g. the latest published version) + price : typing.Optional[int] product_id : typing.Optional[str] @@ -2532,6 +2548,7 @@ async def main() -> None: ids=["ids"], interval="interval", is_active=True, + plan_version_id="plan_version_id", price=1000000, product_id="product_id", product_ids=["product_ids"], @@ -2554,6 +2571,7 @@ async def main() -> None: ids=ids, interval=interval, is_active=is_active, + plan_version_id=plan_version_id, price=price, product_id=product_id, product_ids=product_ids, @@ -2737,6 +2755,7 @@ async def list_billing_product_prices( ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, interval: typing.Optional[str] = None, is_active: typing.Optional[bool] = None, + plan_version_id: typing.Optional[str] = None, price: typing.Optional[int] = None, product_id: typing.Optional[str] = None, product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, @@ -2768,6 +2787,9 @@ async def list_billing_product_prices( is_active : typing.Optional[bool] Filter for active prices on active products (defaults to true if not specified) + plan_version_id : typing.Optional[str] + Filter for prices belonging to a specific plan version (e.g. the latest published version) + price : typing.Optional[int] product_id : typing.Optional[str] @@ -2818,6 +2840,7 @@ async def main() -> None: ids=["ids"], interval="interval", is_active=True, + plan_version_id="plan_version_id", price=1000000, product_id="product_id", product_ids=["product_ids"], @@ -2840,6 +2863,7 @@ async def main() -> None: ids=ids, interval=interval, is_active=is_active, + plan_version_id=plan_version_id, price=price, product_id=product_id, product_ids=product_ids, diff --git a/src/schematic/billing/raw_client.py b/src/schematic/billing/raw_client.py index 16f4a44..b485cdf 100644 --- a/src/schematic/billing/raw_client.py +++ b/src/schematic/billing/raw_client.py @@ -1606,6 +1606,7 @@ def list_billing_prices( ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, interval: typing.Optional[str] = None, is_active: typing.Optional[bool] = None, + plan_version_id: typing.Optional[str] = None, price: typing.Optional[int] = None, product_id: typing.Optional[str] = None, product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, @@ -1637,6 +1638,9 @@ def list_billing_prices( is_active : typing.Optional[bool] Filter for active prices on active products (defaults to true if not specified) + plan_version_id : typing.Optional[str] + Filter for prices belonging to a specific plan version (e.g. the latest published version) + price : typing.Optional[int] product_id : typing.Optional[str] @@ -1678,6 +1682,7 @@ def list_billing_prices( "ids": ids, "interval": interval, "is_active": is_active, + "plan_version_id": plan_version_id, "price": price, "product_id": product_id, "product_ids": product_ids, @@ -2055,6 +2060,7 @@ def list_billing_product_prices( ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, interval: typing.Optional[str] = None, is_active: typing.Optional[bool] = None, + plan_version_id: typing.Optional[str] = None, price: typing.Optional[int] = None, product_id: typing.Optional[str] = None, product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, @@ -2086,6 +2092,9 @@ def list_billing_product_prices( is_active : typing.Optional[bool] Filter for active prices on active products (defaults to true if not specified) + plan_version_id : typing.Optional[str] + Filter for prices belonging to a specific plan version (e.g. the latest published version) + price : typing.Optional[int] product_id : typing.Optional[str] @@ -2127,6 +2136,7 @@ def list_billing_product_prices( "ids": ids, "interval": interval, "is_active": is_active, + "plan_version_id": plan_version_id, "price": price, "product_id": product_id, "product_ids": product_ids, @@ -4507,6 +4517,7 @@ async def list_billing_prices( ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, interval: typing.Optional[str] = None, is_active: typing.Optional[bool] = None, + plan_version_id: typing.Optional[str] = None, price: typing.Optional[int] = None, product_id: typing.Optional[str] = None, product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, @@ -4538,6 +4549,9 @@ async def list_billing_prices( is_active : typing.Optional[bool] Filter for active prices on active products (defaults to true if not specified) + plan_version_id : typing.Optional[str] + Filter for prices belonging to a specific plan version (e.g. the latest published version) + price : typing.Optional[int] product_id : typing.Optional[str] @@ -4579,6 +4593,7 @@ async def list_billing_prices( "ids": ids, "interval": interval, "is_active": is_active, + "plan_version_id": plan_version_id, "price": price, "product_id": product_id, "product_ids": product_ids, @@ -4956,6 +4971,7 @@ async def list_billing_product_prices( ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, interval: typing.Optional[str] = None, is_active: typing.Optional[bool] = None, + plan_version_id: typing.Optional[str] = None, price: typing.Optional[int] = None, product_id: typing.Optional[str] = None, product_ids: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None, @@ -4987,6 +5003,9 @@ async def list_billing_product_prices( is_active : typing.Optional[bool] Filter for active prices on active products (defaults to true if not specified) + plan_version_id : typing.Optional[str] + Filter for prices belonging to a specific plan version (e.g. the latest published version) + price : typing.Optional[int] product_id : typing.Optional[str] @@ -5028,6 +5047,7 @@ async def list_billing_product_prices( "ids": ids, "interval": interval, "is_active": is_active, + "plan_version_id": plan_version_id, "price": price, "product_id": product_id, "product_ids": product_ids, diff --git a/src/schematic/billing/types/list_billing_prices_params.py b/src/schematic/billing/types/list_billing_prices_params.py index efa4a69..88c83bd 100644 --- a/src/schematic/billing/types/list_billing_prices_params.py +++ b/src/schematic/billing/types/list_billing_prices_params.py @@ -46,6 +46,11 @@ class ListBillingPricesParams(UniversalBaseModel): Page offset (default 0) """ + plan_version_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Filter for prices belonging to a specific plan version (e.g. the latest published version) + """ + price: typing.Optional[int] = None product_id: typing.Optional[str] = None product_ids: typing.Optional[typing.List[str]] = None diff --git a/src/schematic/billing/types/list_billing_product_prices_params.py b/src/schematic/billing/types/list_billing_product_prices_params.py index 8727f29..c71ca9f 100644 --- a/src/schematic/billing/types/list_billing_product_prices_params.py +++ b/src/schematic/billing/types/list_billing_product_prices_params.py @@ -46,6 +46,11 @@ class ListBillingProductPricesParams(UniversalBaseModel): Page offset (default 0) """ + plan_version_id: typing.Optional[str] = pydantic.Field(default=None) + """ + Filter for prices belonging to a specific plan version (e.g. the latest published version) + """ + price: typing.Optional[int] = None product_id: typing.Optional[str] = None product_ids: typing.Optional[typing.List[str]] = None diff --git a/src/schematic/core/client_wrapper.py b/src/schematic/core/client_wrapper.py index c123af8..376eaa0 100644 --- a/src/schematic/core/client_wrapper.py +++ b/src/schematic/core/client_wrapper.py @@ -27,12 +27,12 @@ def get_headers(self) -> typing.Dict[str, str]: import platform headers: typing.Dict[str, str] = { - "User-Agent": "schematichq/1.2.4", + "User-Agent": "schematichq/1.2.5", "X-Fern-Language": "Python", "X-Fern-Runtime": f"python/{platform.python_version()}", "X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}", "X-Fern-SDK-Name": "schematichq", - "X-Fern-SDK-Version": "1.2.4", + "X-Fern-SDK-Version": "1.2.5", **(self.get_custom_headers() or {}), } headers["X-Schematic-Api-Key"] = self.api_key diff --git a/src/schematic/types/__init__.py b/src/schematic/types/__init__.py index a924857..31003e4 100644 --- a/src/schematic/types/__init__.py +++ b/src/schematic/types/__init__.py @@ -81,6 +81,7 @@ from .checkout_settings_response_data import CheckoutSettingsResponseData from .checkout_subscription import CheckoutSubscription from .clerk_integration_config import ClerkIntegrationConfig + from .company_credit_balance import CompanyCreditBalance from .company_credit_balance_response_data import CompanyCreditBalanceResponseData from .company_detail_response_data import CompanyDetailResponseData from .company_event_period_metrics_response_data import CompanyEventPeriodMetricsResponseData @@ -354,6 +355,7 @@ from .subscription_type import SubscriptionType from .temporary_access_token_resource_type import TemporaryAccessTokenResourceType from .temporary_access_token_response_data import TemporaryAccessTokenResponseData + from .test_webhook_response_data import TestWebhookResponseData from .time_series_granularity import TimeSeriesGranularity from .top_feature_by_usage_response_data import TopFeatureByUsageResponseData from .top_features_by_usage_response_data import TopFeaturesByUsageResponseData @@ -467,6 +469,7 @@ "CheckoutSettingsResponseData": ".checkout_settings_response_data", "CheckoutSubscription": ".checkout_subscription", "ClerkIntegrationConfig": ".clerk_integration_config", + "CompanyCreditBalance": ".company_credit_balance", "CompanyCreditBalanceResponseData": ".company_credit_balance_response_data", "CompanyDetailResponseData": ".company_detail_response_data", "CompanyEventPeriodMetricsResponseData": ".company_event_period_metrics_response_data", @@ -738,6 +741,7 @@ "SubscriptionType": ".subscription_type", "TemporaryAccessTokenResourceType": ".temporary_access_token_resource_type", "TemporaryAccessTokenResponseData": ".temporary_access_token_response_data", + "TestWebhookResponseData": ".test_webhook_response_data", "TimeSeriesGranularity": ".time_series_granularity", "TopFeatureByUsageResponseData": ".top_feature_by_usage_response_data", "TopFeaturesByUsageResponseData": ".top_features_by_usage_response_data", @@ -875,6 +879,7 @@ def __dir__(): "CheckoutSettingsResponseData", "CheckoutSubscription", "ClerkIntegrationConfig", + "CompanyCreditBalance", "CompanyCreditBalanceResponseData", "CompanyDetailResponseData", "CompanyEventPeriodMetricsResponseData", @@ -1146,6 +1151,7 @@ def __dir__(): "SubscriptionType", "TemporaryAccessTokenResourceType", "TemporaryAccessTokenResponseData", + "TestWebhookResponseData", "TimeSeriesGranularity", "TopFeatureByUsageResponseData", "TopFeaturesByUsageResponseData", diff --git a/src/schematic/types/account_member_permission.py b/src/schematic/types/account_member_permission.py index a05bbef..693e716 100644 --- a/src/schematic/types/account_member_permission.py +++ b/src/schematic/types/account_member_permission.py @@ -4,7 +4,6 @@ AccountMemberPermission = typing.Union[ typing.Literal[ - "billing_credits_edit", "companies_edit", "company_users_edit", "components_edit", diff --git a/src/schematic/types/check_flags_response_data.py b/src/schematic/types/check_flags_response_data.py index 5c84d91..c804a4a 100644 --- a/src/schematic/types/check_flags_response_data.py +++ b/src/schematic/types/check_flags_response_data.py @@ -5,10 +5,16 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel from .check_flag_response_data import CheckFlagResponseData +from .company_credit_balance import CompanyCreditBalance from .datastream_company_plan import DatastreamCompanyPlan class CheckFlagsResponseData(UniversalBaseModel): + credit_balances: typing.Optional[typing.Dict[str, CompanyCreditBalance]] = pydantic.Field(default=None) + """ + Lease-aware credit balances keyed by credit ID, covering every credit type the company holds a balance in + """ + flags: typing.List[CheckFlagResponseData] plan: typing.Optional[DatastreamCompanyPlan] = None diff --git a/src/schematic/types/company_credit_balance.py b/src/schematic/types/company_credit_balance.py new file mode 100644 index 0000000..472e0db --- /dev/null +++ b/src/schematic/types/company_credit_balance.py @@ -0,0 +1,32 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class CompanyCreditBalance(UniversalBaseModel): + remaining: float = pydantic.Field() + """ + Remaining credit, excluding any open lease hold (the value SDKs gate on) + """ + + reserved: float = pydantic.Field() + """ + Amount held by the company's open credit lease, 0 when none is open + """ + + settled: float = pydantic.Field() + """ + Spendable balance including the open lease hold (remaining + reserved) + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/schematic/types/company_subscription_response_data.py b/src/schematic/types/company_subscription_response_data.py index 80ecdb7..91c1c3a 100644 --- a/src/schematic/types/company_subscription_response_data.py +++ b/src/schematic/types/company_subscription_response_data.py @@ -20,6 +20,7 @@ class CompanySubscriptionResponseData(UniversalBaseModel): discounts: typing.List[BillingSubscriptionDiscountView] expired_at: typing.Optional[dt.datetime] = None interval: str + is_initial: bool latest_invoice: typing.Optional[InvoiceResponseData] = None payment_method: typing.Optional[PaymentMethodResponseData] = None products: typing.List[BillingProductForSubscriptionResponseData] diff --git a/src/schematic/types/feature_entitlement.py b/src/schematic/types/feature_entitlement.py index a05f081..5b076e7 100644 --- a/src/schematic/types/feature_entitlement.py +++ b/src/schematic/types/feature_entitlement.py @@ -16,6 +16,11 @@ class FeatureEntitlement(UniversalBaseModel): If the company has a numeric entitlement for this feature, the allocated amount """ + consumption_rate: typing.Optional[float] = pydantic.Field(default=None) + """ + If the company has a credit-based entitlement for this feature, the credit cost per unit of usage + """ + credit_id: typing.Optional[str] = pydantic.Field(default=None) """ If the company has a credit-based entitlement for this feature, the ID of the credit @@ -51,6 +56,11 @@ class FeatureEntitlement(UniversalBaseModel): If the feature is event-based, the name of the event tracked for usage """ + event_subtype: typing.Optional[str] = pydantic.Field(default=None) + """ + For event-based or credit-metered feature entitlements, the event subtype whose usage is tracked + """ + feature_id: str = pydantic.Field() """ The ID of the feature diff --git a/src/schematic/types/rulesengine_feature_entitlement.py b/src/schematic/types/rulesengine_feature_entitlement.py index b592231..f236814 100644 --- a/src/schematic/types/rulesengine_feature_entitlement.py +++ b/src/schematic/types/rulesengine_feature_entitlement.py @@ -16,6 +16,11 @@ class RulesengineFeatureEntitlement(UniversalBaseModel): If the company has a numeric entitlement for this feature, the allocated amount """ + consumption_rate: typing.Optional[float] = pydantic.Field(default=None) + """ + If the company has a credit-based entitlement for this feature, the credit cost per unit of usage + """ + credit_id: typing.Optional[str] = pydantic.Field(default=None) """ If the company has a credit-based entitlement for this feature, the ID of the credit @@ -51,6 +56,11 @@ class RulesengineFeatureEntitlement(UniversalBaseModel): If the feature is event-based, the name of the event tracked for usage """ + event_subtype: typing.Optional[str] = pydantic.Field(default=None) + """ + For event-based or credit-metered feature entitlements, the event subtype whose usage is tracked + """ + feature_id: str = pydantic.Field() """ The ID of the feature diff --git a/src/schematic/types/test_webhook_response_data.py b/src/schematic/types/test_webhook_response_data.py new file mode 100644 index 0000000..28cd96d --- /dev/null +++ b/src/schematic/types/test_webhook_response_data.py @@ -0,0 +1,20 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel + + +class TestWebhookResponseData(UniversalBaseModel): + response_code: int + success: bool + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow diff --git a/src/schematic/webhooks/__init__.py b/src/schematic/webhooks/__init__.py index f3b8204..fa4102f 100644 --- a/src/schematic/webhooks/__init__.py +++ b/src/schematic/webhooks/__init__.py @@ -19,6 +19,7 @@ ListWebhookEventsResponse, ListWebhooksParams, ListWebhooksResponse, + SendTestWebhookActionResponse, UpdateWebhookResponse, ) _dynamic_imports: typing.Dict[str, str] = { @@ -34,6 +35,7 @@ "ListWebhookEventsResponse": ".types", "ListWebhooksParams": ".types", "ListWebhooksResponse": ".types", + "SendTestWebhookActionResponse": ".types", "UpdateWebhookResponse": ".types", } @@ -72,5 +74,6 @@ def __dir__(): "ListWebhookEventsResponse", "ListWebhooksParams", "ListWebhooksResponse", + "SendTestWebhookActionResponse", "UpdateWebhookResponse", ] diff --git a/src/schematic/webhooks/client.py b/src/schematic/webhooks/client.py index 19d4fb3..c89581f 100644 --- a/src/schematic/webhooks/client.py +++ b/src/schematic/webhooks/client.py @@ -17,6 +17,7 @@ from .types.get_webhook_response import GetWebhookResponse from .types.list_webhook_events_response import ListWebhookEventsResponse from .types.list_webhooks_response import ListWebhooksResponse +from .types.send_test_webhook_action_response import SendTestWebhookActionResponse from .types.update_webhook_response import UpdateWebhookResponse # this is used as the default value for optional parameters @@ -395,6 +396,46 @@ def delete_webhook( _response = self._raw_client.delete_webhook(webhook_id, request_options=request_options) return _response.data + def send_test_webhook_action( + self, + webhook_id: str, + *, + request_type: WebhookRequestType, + request_options: typing.Optional[RequestOptions] = None, + ) -> SendTestWebhookActionResponse: + """ + Parameters + ---------- + webhook_id : str + webhook_id + + request_type : WebhookRequestType + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SendTestWebhookActionResponse + OK + + Examples + -------- + from schematic import Schematic + + client = Schematic( + api_key="YOUR_API_KEY", + ) + client.webhooks.send_test_webhook_action( + webhook_id="webhook_id", + request_type="subscription.trial.ended", + ) + """ + _response = self._raw_client.send_test_webhook_action( + webhook_id, request_type=request_type, request_options=request_options + ) + return _response.data + def count_webhooks( self, *, @@ -877,6 +918,54 @@ async def main() -> None: _response = await self._raw_client.delete_webhook(webhook_id, request_options=request_options) return _response.data + async def send_test_webhook_action( + self, + webhook_id: str, + *, + request_type: WebhookRequestType, + request_options: typing.Optional[RequestOptions] = None, + ) -> SendTestWebhookActionResponse: + """ + Parameters + ---------- + webhook_id : str + webhook_id + + request_type : WebhookRequestType + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + SendTestWebhookActionResponse + OK + + Examples + -------- + import asyncio + + from schematic import AsyncSchematic + + client = AsyncSchematic( + api_key="YOUR_API_KEY", + ) + + + async def main() -> None: + await client.webhooks.send_test_webhook_action( + webhook_id="webhook_id", + request_type="subscription.trial.ended", + ) + + + asyncio.run(main()) + """ + _response = await self._raw_client.send_test_webhook_action( + webhook_id, request_type=request_type, request_options=request_options + ) + return _response.data + async def count_webhooks( self, *, diff --git a/src/schematic/webhooks/raw_client.py b/src/schematic/webhooks/raw_client.py index 81afbe6..cd85f14 100644 --- a/src/schematic/webhooks/raw_client.py +++ b/src/schematic/webhooks/raw_client.py @@ -29,6 +29,7 @@ from .types.get_webhook_response import GetWebhookResponse from .types.list_webhook_events_response import ListWebhookEventsResponse from .types.list_webhooks_response import ListWebhooksResponse +from .types.send_test_webhook_action_response import SendTestWebhookActionResponse from .types.update_webhook_response import UpdateWebhookResponse from pydantic import ValidationError @@ -949,6 +950,119 @@ def delete_webhook( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) + def send_test_webhook_action( + self, + webhook_id: str, + *, + request_type: WebhookRequestType, + request_options: typing.Optional[RequestOptions] = None, + ) -> HttpResponse[SendTestWebhookActionResponse]: + """ + Parameters + ---------- + webhook_id : str + webhook_id + + request_type : WebhookRequestType + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + HttpResponse[SendTestWebhookActionResponse] + OK + """ + _response = self._client_wrapper.httpx_client.request( + f"webhooks/{jsonable_encoder(webhook_id)}/test", + method="POST", + json={ + "request_type": request_type, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + SendTestWebhookActionResponse, + parse_obj_as( + type_=SendTestWebhookActionResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + def count_webhooks( self, *, @@ -1978,6 +2092,119 @@ async def delete_webhook( status_code=_response.status_code, headers=dict(_response.headers), body=_response_json ) + async def send_test_webhook_action( + self, + webhook_id: str, + *, + request_type: WebhookRequestType, + request_options: typing.Optional[RequestOptions] = None, + ) -> AsyncHttpResponse[SendTestWebhookActionResponse]: + """ + Parameters + ---------- + webhook_id : str + webhook_id + + request_type : WebhookRequestType + + request_options : typing.Optional[RequestOptions] + Request-specific configuration. + + Returns + ------- + AsyncHttpResponse[SendTestWebhookActionResponse] + OK + """ + _response = await self._client_wrapper.httpx_client.request( + f"webhooks/{jsonable_encoder(webhook_id)}/test", + method="POST", + json={ + "request_type": request_type, + }, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) + try: + if 200 <= _response.status_code < 300: + _data = typing.cast( + SendTestWebhookActionResponse, + parse_obj_as( + type_=SendTestWebhookActionResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, data=_data) + if _response.status_code == 400: + raise BadRequestError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 401: + raise UnauthorizedError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 403: + raise ForbiddenError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 404: + raise NotFoundError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + if _response.status_code == 500: + raise InternalServerError( + headers=dict(_response.headers), + body=typing.cast( + types_api_error_ApiError, + parse_obj_as( + type_=types_api_error_ApiError, # type: ignore + object_=_response.json(), + ), + ), + ) + _response_json = _response.json() + except JSONDecodeError: + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.text + ) + except ValidationError as e: + raise ParsingError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e + ) + raise core_api_error_ApiError( + status_code=_response.status_code, headers=dict(_response.headers), body=_response_json + ) + async def count_webhooks( self, *, diff --git a/src/schematic/webhooks/types/__init__.py b/src/schematic/webhooks/types/__init__.py index bff22ec..bd7dbc2 100644 --- a/src/schematic/webhooks/types/__init__.py +++ b/src/schematic/webhooks/types/__init__.py @@ -18,6 +18,7 @@ from .list_webhook_events_response import ListWebhookEventsResponse from .list_webhooks_params import ListWebhooksParams from .list_webhooks_response import ListWebhooksResponse + from .send_test_webhook_action_response import SendTestWebhookActionResponse from .update_webhook_response import UpdateWebhookResponse _dynamic_imports: typing.Dict[str, str] = { "CountWebhookEventsParams": ".count_webhook_events_params", @@ -32,6 +33,7 @@ "ListWebhookEventsResponse": ".list_webhook_events_response", "ListWebhooksParams": ".list_webhooks_params", "ListWebhooksResponse": ".list_webhooks_response", + "SendTestWebhookActionResponse": ".send_test_webhook_action_response", "UpdateWebhookResponse": ".update_webhook_response", } @@ -70,5 +72,6 @@ def __dir__(): "ListWebhookEventsResponse", "ListWebhooksParams", "ListWebhooksResponse", + "SendTestWebhookActionResponse", "UpdateWebhookResponse", ] diff --git a/src/schematic/webhooks/types/send_test_webhook_action_response.py b/src/schematic/webhooks/types/send_test_webhook_action_response.py new file mode 100644 index 0000000..c19a71e --- /dev/null +++ b/src/schematic/webhooks/types/send_test_webhook_action_response.py @@ -0,0 +1,24 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +import pydantic +from ...core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from ...types.test_webhook_response_data import TestWebhookResponseData + + +class SendTestWebhookActionResponse(UniversalBaseModel): + data: TestWebhookResponseData + params: typing.Dict[str, typing.Any] = pydantic.Field() + """ + Input parameters + """ + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow