From 0d484cce6589c90f2ea9f089785a8c71dc93edb1 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 02:25:36 +0000 Subject: [PATCH] SDK regeneration --- .fern/metadata.json | 5 +- README.md | 10 +- pyproject.toml | 5 +- src/pipedream/accounts/client.py | 40 +- src/pipedream/accounts/raw_client.py | 10 + src/pipedream/actions/client.py | 30 -- src/pipedream/app_categories/client.py | 12 - src/pipedream/apps/client.py | 12 - src/pipedream/client.py | 20 +- src/pipedream/components/client.py | 24 - src/pipedream/core/client_wrapper.py | 8 +- src/pipedream/core/http_client.py | 216 +++++--- src/pipedream/core/http_response.py | 6 +- src/pipedream/core/jsonable_encoder.py | 8 + src/pipedream/core/pydantic_utilities.py | 304 ++++++++++- src/pipedream/deployed_triggers/client.py | 66 --- src/pipedream/file_stash/client.py | 6 - src/pipedream/oauth_tokens/client.py | 6 - src/pipedream/project_environment/client.py | 24 - src/pipedream/projects/client.py | 42 -- src/pipedream/tokens/client.py | 26 +- src/pipedream/tokens/raw_client.py | 10 + src/pipedream/triggers/client.py | 30 -- src/pipedream/types/configurable_prop.py | 498 +++++++++++++----- .../configurable_prop_airtable_base_id.py | 9 +- .../configurable_prop_airtable_field_id.py | 9 +- .../configurable_prop_airtable_table_id.py | 9 +- .../configurable_prop_airtable_view_id.py | 9 +- .../types/configurable_prop_alert.py | 2 +- .../types/configurable_prop_apphook.py | 22 +- src/pipedream/types/configurable_prop_base.py | 74 +-- src/pipedream/types/configurable_prop_dir.py | 4 +- .../configurable_prop_discord_channel.py | 9 +- ...configurable_prop_discord_channel_array.py | 11 +- src/pipedream/types/configurable_prop_http.py | 11 +- .../types/configure_prop_response.py | 10 +- .../types/configured_prop_value_app.py | 4 +- .../types/configured_prop_value_sql.py | 13 +- src/pipedream/types/dynamic_props.py | 9 +- src/pipedream/types/http_request_body.py | 4 +- src/pipedream/types/prop_option_nested.py | 2 +- src/pipedream/types/proxy_response_binary.py | 2 +- src/pipedream/types/reload_props_response.py | 6 +- src/pipedream/types/timer_interval.py | 9 +- src/pipedream/types/tool_annotations.py | 57 +- src/pipedream/usage/client.py | 6 - src/pipedream/users/client.py | 12 - tests/utils/test_http_client.py | 203 ++++++- 48 files changed, 1233 insertions(+), 691 deletions(-) diff --git a/.fern/metadata.json b/.fern/metadata.json index e8e81e2..03203ce 100644 --- a/.fern/metadata.json +++ b/.fern/metadata.json @@ -1,7 +1,7 @@ { "cliVersion": "3.5.0", "generatorName": "fernapi/fern-python-sdk", - "generatorVersion": "4.45.0", + "generatorVersion": "4.54.4", "generatorConfig": { "client": { "class_name": "Client", @@ -9,5 +9,6 @@ "exported_class_name": "Pipedream", "exported_filename": "pipedream.py" } - } + }, + "sdkVersion": "1.1.12" } \ No newline at end of file diff --git a/README.md b/README.md index 3df45ed..300cfa8 100644 --- a/README.md +++ b/README.md @@ -40,9 +40,6 @@ from pipedream import Pipedream client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.actions.run( id="id", @@ -61,9 +58,6 @@ from pipedream import AsyncPipedream client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -101,9 +95,6 @@ from pipedream import Pipedream client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) response = client.apps.list( after="after", @@ -165,6 +156,7 @@ client = Pipedream( ) response = client.actions.with_raw_response.run(...) print(response.headers) # access the response headers +print(response.status_code) # access the response status code print(response.data) # access the underlying object pager = client.apps.list(...) print(pager.response) # access the typed response for the first page diff --git a/pyproject.toml b/pyproject.toml index f751d0e..38a36b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ dynamic = ["version"] [tool.poetry] name = "pipedream" -version = "1.1.11" +version = "1.1.12" description = "" readme = "README.md" authors = [] @@ -19,6 +19,9 @@ classifiers = [ "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: 3.15", "Operating System :: OS Independent", "Operating System :: POSIX", "Operating System :: MacOS", diff --git a/src/pipedream/accounts/client.py b/src/pipedream/accounts/client.py index 79d552f..0ffe4dd 100644 --- a/src/pipedream/accounts/client.py +++ b/src/pipedream/accounts/client.py @@ -79,9 +79,6 @@ def list( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) response = client.accounts.list( external_user_id="external_user_id", @@ -118,6 +115,7 @@ def create( external_user_id: typing.Optional[str] = None, oauth_app_id: typing.Optional[str] = None, name: typing.Optional[str] = OMIT, + account_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Account: """ @@ -142,6 +140,9 @@ def create( name : typing.Optional[str] Optional name for the account + account_id : typing.Optional[str] + An existing account ID to reconnect. When provided, the account's credentials are updated instead of creating a new account. Must belong to the same external user and project environment as the connect token, and match the app identified by app_slug. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -156,9 +157,6 @@ def create( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.accounts.create( external_user_id="external_user_id", @@ -175,6 +173,7 @@ def create( external_user_id=external_user_id, oauth_app_id=oauth_app_id, name=name, + account_id=account_id, request_options=request_options, ) return _response.data @@ -210,9 +209,6 @@ def retrieve( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.accounts.retrieve( account_id="account_id", @@ -245,9 +241,6 @@ def delete(self, account_id: str, *, request_options: typing.Optional[RequestOpt client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.accounts.delete( account_id="account_id", @@ -277,9 +270,6 @@ def delete_by_app(self, app_id: str, *, request_options: typing.Optional[Request client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.accounts.delete_by_app( app_id="app_id", @@ -357,9 +347,6 @@ async def list( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -403,6 +390,7 @@ async def create( external_user_id: typing.Optional[str] = None, oauth_app_id: typing.Optional[str] = None, name: typing.Optional[str] = OMIT, + account_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Account: """ @@ -427,6 +415,9 @@ async def create( name : typing.Optional[str] Optional name for the account + account_id : typing.Optional[str] + An existing account ID to reconnect. When provided, the account's credentials are updated instead of creating a new account. Must belong to the same external user and project environment as the connect token, and match the app identified by app_slug. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -443,9 +434,6 @@ async def create( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -468,6 +456,7 @@ async def main() -> None: external_user_id=external_user_id, oauth_app_id=oauth_app_id, name=name, + account_id=account_id, request_options=request_options, ) return _response.data @@ -505,9 +494,6 @@ async def retrieve( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -548,9 +534,6 @@ async def delete(self, account_id: str, *, request_options: typing.Optional[Requ client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -588,9 +571,6 @@ async def delete_by_app(self, app_id: str, *, request_options: typing.Optional[R client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/accounts/raw_client.py b/src/pipedream/accounts/raw_client.py index 9539d78..a0059b1 100644 --- a/src/pipedream/accounts/raw_client.py +++ b/src/pipedream/accounts/raw_client.py @@ -132,6 +132,7 @@ def create( external_user_id: typing.Optional[str] = None, oauth_app_id: typing.Optional[str] = None, name: typing.Optional[str] = OMIT, + account_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Account]: """ @@ -156,6 +157,9 @@ def create( name : typing.Optional[str] Optional name for the account + account_id : typing.Optional[str] + An existing account ID to reconnect. When provided, the account's credentials are updated instead of creating a new account. Must belong to the same external user and project environment as the connect token, and match the app identified by app_slug. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -176,6 +180,7 @@ def create( "cfmap_json": cfmap_json, "connect_token": connect_token, "name": name, + "account_id": account_id, }, headers={ "content-type": "application/json", @@ -466,6 +471,7 @@ async def create( external_user_id: typing.Optional[str] = None, oauth_app_id: typing.Optional[str] = None, name: typing.Optional[str] = OMIT, + account_id: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Account]: """ @@ -490,6 +496,9 @@ async def create( name : typing.Optional[str] Optional name for the account + account_id : typing.Optional[str] + An existing account ID to reconnect. When provided, the account's credentials are updated instead of creating a new account. Must belong to the same external user and project environment as the connect token, and match the app identified by app_slug. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -510,6 +519,7 @@ async def create( "cfmap_json": cfmap_json, "connect_token": connect_token, "name": name, + "account_id": account_id, }, headers={ "content-type": "application/json", diff --git a/src/pipedream/actions/client.py b/src/pipedream/actions/client.py index 7846394..b2debbd 100644 --- a/src/pipedream/actions/client.py +++ b/src/pipedream/actions/client.py @@ -82,9 +82,6 @@ def list( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) response = client.actions.list( after="after", @@ -136,9 +133,6 @@ def retrieve( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.actions.retrieve( component_id="component_id", @@ -211,9 +205,6 @@ def configure_prop( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.actions.configure_prop( id="id", @@ -283,9 +274,6 @@ def reload_props( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.actions.reload_props( id="id", @@ -349,9 +337,6 @@ def run( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.actions.run( id="id", @@ -435,9 +420,6 @@ async def list( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -498,9 +480,6 @@ async def retrieve( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -581,9 +560,6 @@ async def configure_prop( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -661,9 +637,6 @@ async def reload_props( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -735,9 +708,6 @@ async def run( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/app_categories/client.py b/src/pipedream/app_categories/client.py index 93cebd8..b66dd78 100644 --- a/src/pipedream/app_categories/client.py +++ b/src/pipedream/app_categories/client.py @@ -44,9 +44,6 @@ def list(self, *, request_options: typing.Optional[RequestOptions] = None) -> Li client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.app_categories.list() """ @@ -76,9 +73,6 @@ def retrieve(self, id: str, *, request_options: typing.Optional[RequestOptions] client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.app_categories.retrieve( id="id", @@ -125,9 +119,6 @@ async def list(self, *, request_options: typing.Optional[RequestOptions] = None) client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -167,9 +158,6 @@ async def retrieve( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/apps/client.py b/src/pipedream/apps/client.py index 1d56cbf..4115c7b 100644 --- a/src/pipedream/apps/client.py +++ b/src/pipedream/apps/client.py @@ -92,9 +92,6 @@ def list( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) response = client.apps.list( after="after", @@ -150,9 +147,6 @@ def retrieve(self, app_id: str, *, request_options: typing.Optional[RequestOptio client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.apps.retrieve( app_id="app_id", @@ -243,9 +237,6 @@ async def list( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -310,9 +301,6 @@ async def retrieve(self, app_id: str, *, request_options: typing.Optional[Reques client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/client.py b/src/pipedream/client.py index 097a503..6d33b28 100644 --- a/src/pipedream/client.py +++ b/src/pipedream/client.py @@ -6,11 +6,11 @@ import typing import httpx -from .types.project_environment import ProjectEnvironment from .core.api_error import ApiError from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from .core.oauth_token_provider import AsyncOAuthTokenProvider, OAuthTokenProvider from .environment import PipedreamEnvironment +from .types.project_environment import ProjectEnvironment if typing.TYPE_CHECKING: from .accounts.client import AccountsClient, AsyncAccountsClient @@ -78,9 +78,6 @@ class Client: client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) # or ... @@ -101,6 +98,7 @@ def __init__( environment: PipedreamEnvironment = PipedreamEnvironment.PROD, project_id: str, project_environment: typing.Optional[ProjectEnvironment] = os.getenv("PIPEDREAM_PROJECT_ENVIRONMENT"), + headers: typing.Optional[typing.Dict[str, str]] = None, timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.Client] = None, @@ -115,6 +113,7 @@ def __init__( environment: PipedreamEnvironment = PipedreamEnvironment.PROD, project_id: str, project_environment: typing.Optional[ProjectEnvironment] = os.getenv("PIPEDREAM_PROJECT_ENVIRONMENT"), + headers: typing.Optional[typing.Dict[str, str]] = None, timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.Client] = None, @@ -127,6 +126,7 @@ def __init__( environment: PipedreamEnvironment = PipedreamEnvironment.PROD, project_id: str, project_environment: typing.Optional[ProjectEnvironment] = os.getenv("PIPEDREAM_PROJECT_ENVIRONMENT"), + headers: typing.Optional[typing.Dict[str, str]] = None, client_id: typing.Optional[str] = os.getenv("PIPEDREAM_CLIENT_ID"), client_secret: typing.Optional[str] = os.getenv("PIPEDREAM_CLIENT_SECRET"), token: typing.Optional[typing.Callable[[], str]] = None, @@ -143,6 +143,7 @@ def __init__( base_url=_get_base_url(base_url=base_url, environment=environment), project_id=project_id, project_environment=project_environment, + headers=headers, httpx_client=httpx_client if httpx_client is not None else httpx.Client(timeout=_defaulted_timeout, follow_redirects=follow_redirects) @@ -159,6 +160,7 @@ def __init__( base_url=_get_base_url(base_url=base_url, environment=environment), project_id=project_id, project_environment=project_environment, + headers=headers, httpx_client=httpx.Client(timeout=_defaulted_timeout, follow_redirects=follow_redirects) if follow_redirects is not None else httpx.Client(timeout=_defaulted_timeout), @@ -169,6 +171,7 @@ def __init__( base_url=_get_base_url(base_url=base_url, environment=environment), project_id=project_id, project_environment=project_environment, + headers=headers, token=_token_getter_override if _token_getter_override is not None else oauth_token_provider.get_token, httpx_client=httpx_client if httpx_client is not None @@ -366,9 +369,6 @@ class AsyncClient: client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) # or ... @@ -389,6 +389,7 @@ def __init__( environment: PipedreamEnvironment = PipedreamEnvironment.PROD, project_id: str, project_environment: typing.Optional[ProjectEnvironment] = os.getenv("PIPEDREAM_PROJECT_ENVIRONMENT"), + headers: typing.Optional[typing.Dict[str, str]] = None, timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.AsyncClient] = None, @@ -403,6 +404,7 @@ def __init__( environment: PipedreamEnvironment = PipedreamEnvironment.PROD, project_id: str, project_environment: typing.Optional[ProjectEnvironment] = os.getenv("PIPEDREAM_PROJECT_ENVIRONMENT"), + headers: typing.Optional[typing.Dict[str, str]] = None, timeout: typing.Optional[float] = None, follow_redirects: typing.Optional[bool] = True, httpx_client: typing.Optional[httpx.AsyncClient] = None, @@ -415,6 +417,7 @@ def __init__( environment: PipedreamEnvironment = PipedreamEnvironment.PROD, project_id: str, project_environment: typing.Optional[ProjectEnvironment] = os.getenv("PIPEDREAM_PROJECT_ENVIRONMENT"), + headers: typing.Optional[typing.Dict[str, str]] = None, client_id: typing.Optional[str] = os.getenv("PIPEDREAM_CLIENT_ID"), client_secret: typing.Optional[str] = os.getenv("PIPEDREAM_CLIENT_SECRET"), token: typing.Optional[typing.Callable[[], str]] = None, @@ -431,6 +434,7 @@ def __init__( base_url=_get_base_url(base_url=base_url, environment=environment), project_id=project_id, project_environment=project_environment, + headers=headers, httpx_client=httpx_client if httpx_client is not None else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects) @@ -447,6 +451,7 @@ def __init__( base_url=_get_base_url(base_url=base_url, environment=environment), project_id=project_id, project_environment=project_environment, + headers=headers, httpx_client=httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects) if follow_redirects is not None else httpx.AsyncClient(timeout=_defaulted_timeout), @@ -457,6 +462,7 @@ def __init__( base_url=_get_base_url(base_url=base_url, environment=environment), project_id=project_id, project_environment=project_environment, + headers=headers, token=_token_getter_override, async_token=oauth_token_provider.get_token, httpx_client=httpx_client diff --git a/src/pipedream/components/client.py b/src/pipedream/components/client.py index 95cf678..8b2f545 100644 --- a/src/pipedream/components/client.py +++ b/src/pipedream/components/client.py @@ -85,9 +85,6 @@ def list( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) response = client.components.list( after="after", @@ -147,9 +144,6 @@ def retrieve( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.components.retrieve( component_id="component_id", @@ -222,9 +216,6 @@ def configure_prop( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.components.configure_prop( id="id", @@ -294,9 +285,6 @@ def reload_props( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.components.reload_props( id="id", @@ -384,9 +372,6 @@ async def list( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -455,9 +440,6 @@ async def retrieve( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -538,9 +520,6 @@ async def configure_prop( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -618,9 +597,6 @@ async def reload_props( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/core/client_wrapper.py b/src/pipedream/core/client_wrapper.py index 0bce8a3..951a4ae 100644 --- a/src/pipedream/core/client_wrapper.py +++ b/src/pipedream/core/client_wrapper.py @@ -26,11 +26,15 @@ def __init__( self._timeout = timeout def get_headers(self) -> typing.Dict[str, str]: + import platform + headers: typing.Dict[str, str] = { - "User-Agent": "pipedream/1.1.11", + "User-Agent": "pipedream/1.1.12", "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": "pipedream", - "X-Fern-SDK-Version": "1.1.11", + "X-Fern-SDK-Version": "1.1.12", **(self.get_custom_headers() or {}), } if self._project_environment is not None: diff --git a/src/pipedream/core/http_client.py b/src/pipedream/core/http_client.py index f4a7c07..7c6c936 100644 --- a/src/pipedream/core/http_client.py +++ b/src/pipedream/core/http_client.py @@ -5,7 +5,6 @@ import re import time import typing -import urllib.parse from contextlib import asynccontextmanager, contextmanager from random import random @@ -123,6 +122,30 @@ def _should_retry(response: httpx.Response) -> bool: return response.status_code >= 500 or response.status_code in retryable_400s +def _build_url(base_url: str, path: typing.Optional[str]) -> str: + """ + Build a full URL by joining a base URL with a path. + + This function correctly handles base URLs that contain path prefixes (e.g., tenant-based URLs) + by using string concatenation instead of urllib.parse.urljoin(), which would incorrectly + strip path components when the path starts with '/'. + + Example: + >>> _build_url("https://cloud.example.com/org/tenant/api", "/users") + 'https://cloud.example.com/org/tenant/api/users' + + Args: + base_url: The base URL, which may contain path prefixes. + path: The path to append. Can be None or empty string. + + Returns: + The full URL with base_url and path properly joined. + """ + if not path: + return base_url + return f"{base_url.rstrip('/')}/{path.lstrip('/')}" + + def _maybe_filter_none_from_multipart_data( data: typing.Optional[typing.Any], request_files: typing.Optional[RequestFiles], @@ -192,8 +215,19 @@ def get_request_body( # If both data and json are None, we send json data in the event extra properties are specified json_body = maybe_filter_request_body(json, request_options, omit) - # If you have an empty JSON body, you should just send None - return (json_body if json_body != {} else None), data_body if data_body != {} else None + has_additional_body_parameters = bool( + request_options is not None and request_options.get("additional_body_parameters") + ) + + # Only collapse empty dict to None when the body was not explicitly provided + # and there are no additional body parameters. This preserves explicit empty + # bodies (e.g., when an endpoint has a request body type but all fields are optional). + if json_body == {} and json is None and not has_additional_body_parameters: + json_body = None + if data_body == {} and data is None and not has_additional_body_parameters: + data_body = None + + return json_body, data_body class HttpClient: @@ -237,7 +271,7 @@ def request( ] = None, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, request_options: typing.Optional[RequestOptions] = None, - retries: int = 2, + retries: int = 0, omit: typing.Optional[typing.Any] = None, force_multipart: typing.Optional[bool] = None, ) -> httpx.Response: @@ -261,9 +295,29 @@ def request( data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart) + # Compute encoded params separately to avoid passing empty list to httpx + # (httpx strips existing query params from URL when params=[] is passed) + _encoded_params = encode_query( + jsonable_encoder( + remove_none_from_dict( + remove_omit_from_dict( + { + **(params if params is not None else {}), + **( + request_options.get("additional_query_parameters", {}) or {} + if request_options is not None + else {} + ), + }, + omit, + ) + ) + ) + ) + response = self.httpx_client.request( method=method, - url=urllib.parse.urljoin(f"{base_url}/", path), + url=_build_url(base_url, path), headers=jsonable_encoder( remove_none_from_dict( { @@ -273,23 +327,7 @@ def request( } ) ), - params=encode_query( - jsonable_encoder( - remove_none_from_dict( - remove_omit_from_dict( - { - **(params if params is not None else {}), - **( - request_options.get("additional_query_parameters", {}) or {} - if request_options is not None - else {} - ), - }, - omit, - ) - ) - ) - ), + params=_encoded_params if _encoded_params else None, json=json_body, data=data_body, content=content, @@ -297,9 +335,9 @@ def request( timeout=timeout, ) - max_retries: int = request_options.get("max_retries", 0) if request_options is not None else 0 + max_retries: int = request_options.get("max_retries", 2) if request_options is not None else 2 if _should_retry(response=response): - if max_retries > retries: + if retries < max_retries: time.sleep(_retry_timeout(response=response, retries=retries)) return self.request( path=path, @@ -336,7 +374,7 @@ def stream( ] = None, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, request_options: typing.Optional[RequestOptions] = None, - retries: int = 2, + retries: int = 0, omit: typing.Optional[typing.Any] = None, force_multipart: typing.Optional[bool] = None, ) -> typing.Iterator[httpx.Response]: @@ -360,9 +398,29 @@ def stream( data_body = _maybe_filter_none_from_multipart_data(data_body, request_files, force_multipart) + # Compute encoded params separately to avoid passing empty list to httpx + # (httpx strips existing query params from URL when params=[] is passed) + _encoded_params = encode_query( + jsonable_encoder( + remove_none_from_dict( + remove_omit_from_dict( + { + **(params if params is not None else {}), + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + }, + omit, + ) + ) + ) + ) + with self.httpx_client.stream( method=method, - url=urllib.parse.urljoin(f"{base_url}/", path), + url=_build_url(base_url, path), headers=jsonable_encoder( remove_none_from_dict( { @@ -372,23 +430,7 @@ def stream( } ) ), - params=encode_query( - jsonable_encoder( - remove_none_from_dict( - remove_omit_from_dict( - { - **(params if params is not None else {}), - **( - request_options.get("additional_query_parameters", {}) - if request_options is not None - else {} - ), - }, - omit, - ) - ) - ) - ), + params=_encoded_params if _encoded_params else None, json=json_body, data=data_body, content=content, @@ -446,7 +488,7 @@ async def request( ] = None, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, request_options: typing.Optional[RequestOptions] = None, - retries: int = 2, + retries: int = 0, omit: typing.Optional[typing.Any] = None, force_multipart: typing.Optional[bool] = None, ) -> httpx.Response: @@ -473,10 +515,30 @@ async def request( # Get headers (supports async token providers) _headers = await self._get_headers() + # Compute encoded params separately to avoid passing empty list to httpx + # (httpx strips existing query params from URL when params=[] is passed) + _encoded_params = encode_query( + jsonable_encoder( + remove_none_from_dict( + remove_omit_from_dict( + { + **(params if params is not None else {}), + **( + request_options.get("additional_query_parameters", {}) or {} + if request_options is not None + else {} + ), + }, + omit, + ) + ) + ) + ) + # Add the input to each of these and do None-safety checks response = await self.httpx_client.request( method=method, - url=urllib.parse.urljoin(f"{base_url}/", path), + url=_build_url(base_url, path), headers=jsonable_encoder( remove_none_from_dict( { @@ -486,23 +548,7 @@ async def request( } ) ), - params=encode_query( - jsonable_encoder( - remove_none_from_dict( - remove_omit_from_dict( - { - **(params if params is not None else {}), - **( - request_options.get("additional_query_parameters", {}) or {} - if request_options is not None - else {} - ), - }, - omit, - ) - ) - ) - ), + params=_encoded_params if _encoded_params else None, json=json_body, data=data_body, content=content, @@ -510,9 +556,9 @@ async def request( timeout=timeout, ) - max_retries: int = request_options.get("max_retries", 0) if request_options is not None else 0 + max_retries: int = request_options.get("max_retries", 2) if request_options is not None else 2 if _should_retry(response=response): - if max_retries > retries: + if retries < max_retries: await asyncio.sleep(_retry_timeout(response=response, retries=retries)) return await self.request( path=path, @@ -548,7 +594,7 @@ async def stream( ] = None, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, request_options: typing.Optional[RequestOptions] = None, - retries: int = 2, + retries: int = 0, omit: typing.Optional[typing.Any] = None, force_multipart: typing.Optional[bool] = None, ) -> typing.AsyncIterator[httpx.Response]: @@ -575,9 +621,29 @@ async def stream( # Get headers (supports async token providers) _headers = await self._get_headers() + # Compute encoded params separately to avoid passing empty list to httpx + # (httpx strips existing query params from URL when params=[] is passed) + _encoded_params = encode_query( + jsonable_encoder( + remove_none_from_dict( + remove_omit_from_dict( + { + **(params if params is not None else {}), + **( + request_options.get("additional_query_parameters", {}) + if request_options is not None + else {} + ), + }, + omit=omit, + ) + ) + ) + ) + async with self.httpx_client.stream( method=method, - url=urllib.parse.urljoin(f"{base_url}/", path), + url=_build_url(base_url, path), headers=jsonable_encoder( remove_none_from_dict( { @@ -587,23 +653,7 @@ async def stream( } ) ), - params=encode_query( - jsonable_encoder( - remove_none_from_dict( - remove_omit_from_dict( - { - **(params if params is not None else {}), - **( - request_options.get("additional_query_parameters", {}) - if request_options is not None - else {} - ), - }, - omit=omit, - ) - ) - ) - ), + params=_encoded_params if _encoded_params else None, json=json_body, data=data_body, content=content, diff --git a/src/pipedream/core/http_response.py b/src/pipedream/core/http_response.py index 2479747..00bb109 100644 --- a/src/pipedream/core/http_response.py +++ b/src/pipedream/core/http_response.py @@ -9,7 +9,7 @@ class BaseHttpResponse: - """Minimalist HTTP response wrapper that exposes response headers.""" + """Minimalist HTTP response wrapper that exposes response headers and status code.""" _response: httpx.Response @@ -20,6 +20,10 @@ def __init__(self, response: httpx.Response): def headers(self) -> Dict[str, str]: return dict(self._response.headers) + @property + def status_code(self) -> int: + return self._response.status_code + class HttpResponse(Generic[T], BaseHttpResponse): """HTTP response wrapper that exposes response headers and data.""" diff --git a/src/pipedream/core/jsonable_encoder.py b/src/pipedream/core/jsonable_encoder.py index afee366..f8beaea 100644 --- a/src/pipedream/core/jsonable_encoder.py +++ b/src/pipedream/core/jsonable_encoder.py @@ -30,6 +30,10 @@ def jsonable_encoder(obj: Any, custom_encoder: Optional[Dict[Any, Callable[[Any], Any]]] = None) -> Any: custom_encoder = custom_encoder or {} + # Generated SDKs use Ellipsis (`...`) as the sentinel value for "OMIT". + # OMIT values should be excluded from serialized payloads. + if obj is Ellipsis: + return None if custom_encoder: if type(obj) in custom_encoder: return custom_encoder[type(obj)](obj) @@ -70,6 +74,8 @@ def jsonable_encoder(obj: Any, custom_encoder: Optional[Dict[Any, Callable[[Any] allowed_keys = set(obj.keys()) for key, value in obj.items(): if key in allowed_keys: + if value is Ellipsis: + continue encoded_key = jsonable_encoder(key, custom_encoder=custom_encoder) encoded_value = jsonable_encoder(value, custom_encoder=custom_encoder) encoded_dict[encoded_key] = encoded_value @@ -77,6 +83,8 @@ def jsonable_encoder(obj: Any, custom_encoder: Optional[Dict[Any, Callable[[Any] if isinstance(obj, (list, set, frozenset, GeneratorType, tuple)): encoded_list = [] for item in obj: + if item is Ellipsis: + continue encoded_list.append(jsonable_encoder(item, custom_encoder=custom_encoder)) return encoded_list diff --git a/src/pipedream/core/pydantic_utilities.py b/src/pipedream/core/pydantic_utilities.py index 185e5c4..789081b 100644 --- a/src/pipedream/core/pydantic_utilities.py +++ b/src/pipedream/core/pydantic_utilities.py @@ -2,10 +2,35 @@ # nopycln: file import datetime as dt +import inspect +import json +import logging from collections import defaultdict -from typing import Any, Callable, ClassVar, Dict, List, Mapping, Optional, Set, Tuple, Type, TypeVar, Union, cast +from dataclasses import asdict +from typing import ( + TYPE_CHECKING, + Any, + Callable, + ClassVar, + Dict, + List, + Mapping, + Optional, + Set, + Tuple, + Type, + TypeVar, + Union, + cast, +) import pydantic +import typing_extensions + +_logger = logging.getLogger(__name__) + +if TYPE_CHECKING: + from .http_sse._models import ServerSentEvent IS_PYDANTIC_V2 = pydantic.VERSION.startswith("2.") @@ -36,8 +61,212 @@ Model = TypeVar("Model", bound=pydantic.BaseModel) +def _get_discriminator_and_variants(type_: Type[Any]) -> Tuple[Optional[str], Optional[List[Type[Any]]]]: + """ + Extract the discriminator field name and union variants from a discriminated union type. + Supports Annotated[Union[...], Field(discriminator=...)] patterns. + Returns (discriminator, variants) or (None, None) if not a discriminated union. + """ + origin = typing_extensions.get_origin(type_) + + if origin is typing_extensions.Annotated: + args = typing_extensions.get_args(type_) + if len(args) >= 2: + inner_type = args[0] + # Check annotations for discriminator + discriminator = None + for annotation in args[1:]: + if hasattr(annotation, "discriminator"): + discriminator = getattr(annotation, "discriminator", None) + break + + if discriminator: + inner_origin = typing_extensions.get_origin(inner_type) + if inner_origin is Union: + variants = list(typing_extensions.get_args(inner_type)) + return discriminator, variants + return None, None + + +def _get_field_annotation(model: Type[Any], field_name: str) -> Optional[Type[Any]]: + """Get the type annotation of a field from a Pydantic model.""" + if IS_PYDANTIC_V2: + fields = getattr(model, "model_fields", {}) + field_info = fields.get(field_name) + if field_info: + return cast(Optional[Type[Any]], field_info.annotation) + else: + fields = getattr(model, "__fields__", {}) + field_info = fields.get(field_name) + if field_info: + return cast(Optional[Type[Any]], field_info.outer_type_) + return None + + +def _find_variant_by_discriminator( + variants: List[Type[Any]], + discriminator: str, + discriminator_value: Any, +) -> Optional[Type[Any]]: + """Find the union variant that matches the discriminator value.""" + for variant in variants: + if not (inspect.isclass(variant) and issubclass(variant, pydantic.BaseModel)): + continue + + disc_annotation = _get_field_annotation(variant, discriminator) + if disc_annotation and is_literal_type(disc_annotation): + literal_args = get_args(disc_annotation) + if literal_args and literal_args[0] == discriminator_value: + return variant + return None + + +def _is_string_type(type_: Type[Any]) -> bool: + """Check if a type is str or Optional[str].""" + if type_ is str: + return True + + origin = typing_extensions.get_origin(type_) + if origin is Union: + args = typing_extensions.get_args(type_) + # Optional[str] = Union[str, None] + non_none_args = [a for a in args if a is not type(None)] + if len(non_none_args) == 1 and non_none_args[0] is str: + return True + + return False + + +def parse_sse_obj(sse: "ServerSentEvent", type_: Type[T]) -> T: + """ + Parse a ServerSentEvent into the appropriate type. + + Handles two scenarios based on where the discriminator field is located: + + 1. Data-level discrimination: The discriminator (e.g., 'type') is inside the 'data' payload. + The union describes the data content, not the SSE envelope. + -> Returns: json.loads(data) parsed into the type + + Example: ChatStreamResponse with discriminator='type' + Input: ServerSentEvent(event="message", data='{"type": "content-delta", ...}', id="") + Output: ContentDeltaEvent (parsed from data, SSE envelope stripped) + + 2. Event-level discrimination: The discriminator (e.g., 'event') is at the SSE event level. + The union describes the full SSE event structure. + -> Returns: SSE envelope with 'data' field JSON-parsed only if the variant expects non-string + + Example: JobStreamResponse with discriminator='event' + Input: ServerSentEvent(event="ERROR", data='{"code": "FAILED", ...}', id="123") + Output: JobStreamResponse_Error with data as ErrorData object + + But for variants where data is str (like STATUS_UPDATE): + Input: ServerSentEvent(event="STATUS_UPDATE", data='{"status": "processing"}', id="1") + Output: JobStreamResponse_StatusUpdate with data as string (not parsed) + + Args: + sse: The ServerSentEvent object to parse + type_: The target discriminated union type + + Returns: + The parsed object of type T + + Note: + This function is only available in SDK contexts where http_sse module exists. + """ + sse_event = asdict(sse) + discriminator, variants = _get_discriminator_and_variants(type_) + + if discriminator is None or variants is None: + # Not a discriminated union - parse the data field as JSON + data_value = sse_event.get("data") + if isinstance(data_value, str) and data_value: + try: + parsed_data = json.loads(data_value) + return parse_obj_as(type_, parsed_data) + except json.JSONDecodeError as e: + _logger.warning( + "Failed to parse SSE data field as JSON: %s, data: %s", + e, + data_value[:100] if len(data_value) > 100 else data_value, + ) + return parse_obj_as(type_, sse_event) + + data_value = sse_event.get("data") + + # Check if discriminator is at the top level (event-level discrimination) + if discriminator in sse_event: + # Case 2: Event-level discrimination + # Find the matching variant to check if 'data' field needs JSON parsing + disc_value = sse_event.get(discriminator) + matching_variant = _find_variant_by_discriminator(variants, discriminator, disc_value) + + if matching_variant is not None: + # Check what type the variant expects for 'data' + data_type = _get_field_annotation(matching_variant, "data") + if data_type is not None and not _is_string_type(data_type): + # Variant expects non-string data - parse JSON + if isinstance(data_value, str) and data_value: + try: + parsed_data = json.loads(data_value) + new_object = dict(sse_event) + new_object["data"] = parsed_data + return parse_obj_as(type_, new_object) + except json.JSONDecodeError as e: + _logger.warning( + "Failed to parse SSE data field as JSON for event-level discrimination: %s, data: %s", + e, + data_value[:100] if len(data_value) > 100 else data_value, + ) + # Either no matching variant, data is string type, or JSON parse failed + return parse_obj_as(type_, sse_event) + + else: + # Case 1: Data-level discrimination + # The discriminator is inside the data payload - extract and parse data only + if isinstance(data_value, str) and data_value: + try: + parsed_data = json.loads(data_value) + return parse_obj_as(type_, parsed_data) + except json.JSONDecodeError as e: + _logger.warning( + "Failed to parse SSE data field as JSON for data-level discrimination: %s, data: %s", + e, + data_value[:100] if len(data_value) > 100 else data_value, + ) + return parse_obj_as(type_, sse_event) + + def parse_obj_as(type_: Type[T], object_: Any) -> T: - dealiased_object = convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read") + # convert_and_respect_annotation_metadata is required for TypedDict aliasing. + # + # For Pydantic models, whether we should pre-dealias depends on how the model encodes aliasing: + # - If the model uses real Pydantic aliases (pydantic.Field(alias=...)), then we must pass wire keys through + # unchanged so Pydantic can validate them. + # - If the model encodes aliasing only via FieldMetadata annotations, then we MUST pre-dealias because Pydantic + # will not recognize those aliases during validation. + if inspect.isclass(type_) and issubclass(type_, pydantic.BaseModel): + has_pydantic_aliases = False + if IS_PYDANTIC_V2: + for field_name, field_info in getattr(type_, "model_fields", {}).items(): # type: ignore[attr-defined] + alias = getattr(field_info, "alias", None) + if alias is not None and alias != field_name: + has_pydantic_aliases = True + break + else: + for field in getattr(type_, "__fields__", {}).values(): + alias = getattr(field, "alias", None) + name = getattr(field, "name", None) + if alias is not None and name is not None and alias != name: + has_pydantic_aliases = True + break + + dealiased_object = ( + object_ + if has_pydantic_aliases + else convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read") + ) + else: + dealiased_object = convert_and_respect_annotation_metadata(object_=object_, annotation=type_, direction="read") if IS_PYDANTIC_V2: adapter = pydantic.TypeAdapter(type_) # type: ignore[attr-defined] return adapter.validate_python(dealiased_object) @@ -59,6 +288,43 @@ class UniversalBaseModel(pydantic.BaseModel): protected_namespaces=(), ) + @pydantic.model_validator(mode="before") # type: ignore[attr-defined] + @classmethod + def _coerce_field_names_to_aliases(cls, data: Any) -> Any: + """ + Accept Python field names in input by rewriting them to their Pydantic aliases, + while avoiding silent collisions when a key could refer to multiple fields. + """ + if not isinstance(data, Mapping): + return data + + fields = getattr(cls, "model_fields", {}) # type: ignore[attr-defined] + name_to_alias: Dict[str, str] = {} + alias_to_name: Dict[str, str] = {} + + for name, field_info in fields.items(): + alias = getattr(field_info, "alias", None) or name + name_to_alias[name] = alias + if alias != name: + alias_to_name[alias] = name + + # Detect ambiguous keys: a key that is an alias for one field and a name for another. + ambiguous_keys = set(alias_to_name.keys()).intersection(set(name_to_alias.keys())) + for key in ambiguous_keys: + if key in data and name_to_alias[key] not in data: + raise ValueError( + f"Ambiguous input key '{key}': it is both a field name and an alias. " + "Provide the explicit alias key to disambiguate." + ) + + original_keys = set(data.keys()) + rewritten: Dict[str, Any] = dict(data) + for name, alias in name_to_alias.items(): + if alias != name and name in original_keys and alias not in rewritten: + rewritten[alias] = rewritten.pop(name) + + return rewritten + @pydantic.model_serializer(mode="plain", when_used="json") # type: ignore[attr-defined] def serialize_model(self) -> Any: # type: ignore[name-defined] serialized = self.dict() # type: ignore[attr-defined] @@ -71,6 +337,40 @@ class Config: smart_union = True json_encoders = {dt.datetime: serialize_datetime} + @pydantic.root_validator(pre=True) + def _coerce_field_names_to_aliases(cls, values: Any) -> Any: + """ + Pydantic v1 equivalent of _coerce_field_names_to_aliases. + """ + if not isinstance(values, Mapping): + return values + + fields = getattr(cls, "__fields__", {}) + name_to_alias: Dict[str, str] = {} + alias_to_name: Dict[str, str] = {} + + for name, field in fields.items(): + alias = getattr(field, "alias", None) or name + name_to_alias[name] = alias + if alias != name: + alias_to_name[alias] = name + + ambiguous_keys = set(alias_to_name.keys()).intersection(set(name_to_alias.keys())) + for key in ambiguous_keys: + if key in values and name_to_alias[key] not in values: + raise ValueError( + f"Ambiguous input key '{key}': it is both a field name and an alias. " + "Provide the explicit alias key to disambiguate." + ) + + original_keys = set(values.keys()) + rewritten: Dict[str, Any] = dict(values) + for name, alias in name_to_alias.items(): + if alias != name and name in original_keys and alias not in rewritten: + rewritten[alias] = rewritten.pop(name) + + return rewritten + @classmethod def model_construct(cls: Type["Model"], _fields_set: Optional[Set[str]] = None, **values: Any) -> "Model": dealiased_object = convert_and_respect_annotation_metadata(object_=values, annotation=cls, direction="read") diff --git a/src/pipedream/deployed_triggers/client.py b/src/pipedream/deployed_triggers/client.py index ad8b433..30c545a 100644 --- a/src/pipedream/deployed_triggers/client.py +++ b/src/pipedream/deployed_triggers/client.py @@ -78,9 +78,6 @@ def list( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) response = client.deployed_triggers.list( after="after", @@ -131,9 +128,6 @@ def retrieve( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.deployed_triggers.retrieve( trigger_id="trigger_id", @@ -191,9 +185,6 @@ def update( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.deployed_triggers.update( trigger_id="trigger_id", @@ -245,9 +236,6 @@ def delete( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.deployed_triggers.delete( trigger_id="trigger_id", @@ -298,9 +286,6 @@ def list_events( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.deployed_triggers.list_events( trigger_id="trigger_id", @@ -340,9 +325,6 @@ def list_workflows( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.deployed_triggers.list_workflows( trigger_id="trigger_id", @@ -389,9 +371,6 @@ def update_workflows( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.deployed_triggers.update_workflows( trigger_id="trigger_id", @@ -431,9 +410,6 @@ def list_webhooks( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.deployed_triggers.list_webhooks( trigger_id="trigger_id", @@ -480,9 +456,6 @@ def update_webhooks( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.deployed_triggers.update_webhooks( trigger_id="trigger_id", @@ -529,9 +502,6 @@ def retrieve_webhook( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.deployed_triggers.retrieve_webhook( trigger_id="trigger_id", @@ -578,9 +548,6 @@ def regenerate_webhook_signing_key( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.deployed_triggers.regenerate_webhook_signing_key( trigger_id="trigger_id", @@ -655,9 +622,6 @@ async def list( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -717,9 +681,6 @@ async def retrieve( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -785,9 +746,6 @@ async def update( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -847,9 +805,6 @@ async def delete( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -908,9 +863,6 @@ async def list_events( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -958,9 +910,6 @@ async def list_workflows( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -1015,9 +964,6 @@ async def update_workflows( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -1065,9 +1011,6 @@ async def list_webhooks( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -1122,9 +1065,6 @@ async def update_webhooks( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -1179,9 +1119,6 @@ async def retrieve_webhook( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -1236,9 +1173,6 @@ async def regenerate_webhook_signing_key( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/file_stash/client.py b/src/pipedream/file_stash/client.py index f0469a8..8dcac90 100644 --- a/src/pipedream/file_stash/client.py +++ b/src/pipedream/file_stash/client.py @@ -46,9 +46,6 @@ def download_file( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.file_stash.download_file( s_3_key="s3_key", @@ -99,9 +96,6 @@ async def download_file( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/oauth_tokens/client.py b/src/pipedream/oauth_tokens/client.py index 852e27e..4e6acd4 100644 --- a/src/pipedream/oauth_tokens/client.py +++ b/src/pipedream/oauth_tokens/client.py @@ -60,9 +60,6 @@ def create( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.oauth_tokens.create( client_id="client_id", @@ -126,9 +123,6 @@ async def create( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/project_environment/client.py b/src/pipedream/project_environment/client.py index 95d9d1b..f0e29c6 100644 --- a/src/pipedream/project_environment/client.py +++ b/src/pipedream/project_environment/client.py @@ -48,9 +48,6 @@ def retrieve_webhook(self, *, request_options: typing.Optional[RequestOptions] = client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.project_environment.retrieve_webhook() """ @@ -82,9 +79,6 @@ def update_webhook( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.project_environment.update_webhook( url="url", @@ -112,9 +106,6 @@ def delete_webhook(self, *, request_options: typing.Optional[RequestOptions] = N client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.project_environment.delete_webhook() """ @@ -143,9 +134,6 @@ def regenerate_webhook_signing_key( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.project_environment.regenerate_webhook_signing_key() """ @@ -190,9 +178,6 @@ async def retrieve_webhook(self, *, request_options: typing.Optional[RequestOpti client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -232,9 +217,6 @@ async def update_webhook( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -270,9 +252,6 @@ async def delete_webhook(self, *, request_options: typing.Optional[RequestOption client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -309,9 +288,6 @@ async def regenerate_webhook_signing_key( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/projects/client.py b/src/pipedream/projects/client.py index 1469544..38d0e45 100644 --- a/src/pipedream/projects/client.py +++ b/src/pipedream/projects/client.py @@ -69,9 +69,6 @@ def list( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) response = client.projects.list( after="after", @@ -127,9 +124,6 @@ def create( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.projects.create( name="name", @@ -167,9 +161,6 @@ def retrieve(self, project_id: str, *, request_options: typing.Optional[RequestO client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.projects.retrieve( project_id="project_id", @@ -200,9 +191,6 @@ def delete(self, project_id: str, *, request_options: typing.Optional[RequestOpt client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.projects.delete( project_id="project_id", @@ -255,9 +243,6 @@ def update( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.projects.update( project_id="project_id", @@ -300,9 +285,6 @@ def update_logo( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.projects.update_logo( project_id="project_id", @@ -332,9 +314,6 @@ def retrieve_info(self, *, request_options: typing.Optional[RequestOptions] = No client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.projects.retrieve_info() """ @@ -399,9 +378,6 @@ async def list( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -468,9 +444,6 @@ async def create( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -516,9 +489,6 @@ async def retrieve(self, project_id: str, *, request_options: typing.Optional[Re client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -557,9 +527,6 @@ async def delete(self, project_id: str, *, request_options: typing.Optional[Requ client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -620,9 +587,6 @@ async def update( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -673,9 +637,6 @@ async def update_logo( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -713,9 +674,6 @@ async def retrieve_info(self, *, request_options: typing.Optional[RequestOptions client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/tokens/client.py b/src/pipedream/tokens/client.py index 584efaa..053070f 100644 --- a/src/pipedream/tokens/client.py +++ b/src/pipedream/tokens/client.py @@ -84,9 +84,6 @@ def create( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.tokens.create( external_user_id="external_user_id", @@ -110,6 +107,7 @@ def validate( ctok: ConnectToken, *, app_id: str, + account_id: typing.Optional[str] = None, oauth_app_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ValidateTokenResponse: @@ -123,6 +121,9 @@ def validate( app_id : str The app ID to validate against + account_id : typing.Optional[str] + An existing account ID to reconnect. Must belong to the app identified by app_id. + oauth_app_id : typing.Optional[str] The OAuth app ID to validate against (if the token is for an OAuth app) @@ -140,18 +141,16 @@ def validate( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.tokens.validate( ctok="ctok", app_id="app_id", + account_id="account_id", oauth_app_id="oauth_app_id", ) """ _response = self._raw_client.validate( - ctok, app_id=app_id, oauth_app_id=oauth_app_id, request_options=request_options + ctok, app_id=app_id, account_id=account_id, oauth_app_id=oauth_app_id, request_options=request_options ) return _response.data @@ -229,9 +228,6 @@ async def create( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -261,6 +257,7 @@ async def validate( ctok: ConnectToken, *, app_id: str, + account_id: typing.Optional[str] = None, oauth_app_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> ValidateTokenResponse: @@ -274,6 +271,9 @@ async def validate( app_id : str The app ID to validate against + account_id : typing.Optional[str] + An existing account ID to reconnect. Must belong to the app identified by app_id. + oauth_app_id : typing.Optional[str] The OAuth app ID to validate against (if the token is for an OAuth app) @@ -293,9 +293,6 @@ async def validate( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -303,6 +300,7 @@ async def main() -> None: await client.tokens.validate( ctok="ctok", app_id="app_id", + account_id="account_id", oauth_app_id="oauth_app_id", ) @@ -310,6 +308,6 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.validate( - ctok, app_id=app_id, oauth_app_id=oauth_app_id, request_options=request_options + ctok, app_id=app_id, account_id=account_id, oauth_app_id=oauth_app_id, request_options=request_options ) return _response.data diff --git a/src/pipedream/tokens/raw_client.py b/src/pipedream/tokens/raw_client.py index 5592355..b75beaa 100644 --- a/src/pipedream/tokens/raw_client.py +++ b/src/pipedream/tokens/raw_client.py @@ -122,6 +122,7 @@ def validate( ctok: ConnectToken, *, app_id: str, + account_id: typing.Optional[str] = None, oauth_app_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[ValidateTokenResponse]: @@ -135,6 +136,9 @@ def validate( app_id : str The app ID to validate against + account_id : typing.Optional[str] + An existing account ID to reconnect. Must belong to the app identified by app_id. + oauth_app_id : typing.Optional[str] The OAuth app ID to validate against (if the token is for an OAuth app) @@ -151,6 +155,7 @@ def validate( method="GET", params={ "app_id": app_id, + "account_id": account_id, "oauth_app_id": oauth_app_id, }, request_options=request_options, @@ -286,6 +291,7 @@ async def validate( ctok: ConnectToken, *, app_id: str, + account_id: typing.Optional[str] = None, oauth_app_id: typing.Optional[str] = None, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[ValidateTokenResponse]: @@ -299,6 +305,9 @@ async def validate( app_id : str The app ID to validate against + account_id : typing.Optional[str] + An existing account ID to reconnect. Must belong to the app identified by app_id. + oauth_app_id : typing.Optional[str] The OAuth app ID to validate against (if the token is for an OAuth app) @@ -315,6 +324,7 @@ async def validate( method="GET", params={ "app_id": app_id, + "account_id": account_id, "oauth_app_id": oauth_app_id, }, request_options=request_options, diff --git a/src/pipedream/triggers/client.py b/src/pipedream/triggers/client.py index 64d8825..9bb4bef 100644 --- a/src/pipedream/triggers/client.py +++ b/src/pipedream/triggers/client.py @@ -81,9 +81,6 @@ def list( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) response = client.triggers.list( after="after", @@ -135,9 +132,6 @@ def retrieve( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.triggers.retrieve( component_id="component_id", @@ -210,9 +204,6 @@ def configure_prop( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.triggers.configure_prop( id="id", @@ -282,9 +273,6 @@ def reload_props( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.triggers.reload_props( id="id", @@ -357,9 +345,6 @@ def deploy( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.triggers.deploy( id="id", @@ -445,9 +430,6 @@ async def list( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -508,9 +490,6 @@ async def retrieve( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -591,9 +570,6 @@ async def configure_prop( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -671,9 +647,6 @@ async def reload_props( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -754,9 +727,6 @@ async def deploy( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/types/configurable_prop.py b/src/pipedream/types/configurable_prop.py index 4da3e67..929eda9 100644 --- a/src/pipedream/types/configurable_prop.py +++ b/src/pipedream/types/configurable_prop.py @@ -39,7 +39,7 @@ class ConfigurableProp_Alert(UniversalBaseModel): type: typing.Literal["alert"] = "alert" alert_type: typing_extensions.Annotated[ - typing.Optional[ConfigurablePropAlertType], FieldMetadata(alias="alertType") + typing.Optional[ConfigurablePropAlertType], FieldMetadata(alias="alertType"), pydantic.Field(alias="alertType") ] = None content: str name: str @@ -47,12 +47,22 @@ class ConfigurableProp_Alert(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -77,12 +87,22 @@ class ConfigurableProp_Any(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -106,12 +126,22 @@ class ConfigurableProp_App(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -136,12 +166,22 @@ class ConfigurableProp_Boolean(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -164,12 +204,22 @@ class ConfigurableProp_DataStore(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -188,7 +238,9 @@ class ConfigurableProp_Dir(UniversalBaseModel): type: typing.Literal["dir"] = "dir" access_mode: typing_extensions.Annotated[ - typing.Optional[ConfigurablePropDirAccessMode], FieldMetadata(alias="accessMode") + typing.Optional[ConfigurablePropDirAccessMode], + FieldMetadata(alias="accessMode"), + pydantic.Field(alias="accessMode"), ] = None sync: typing.Optional[bool] = None name: str @@ -196,12 +248,22 @@ class ConfigurableProp_Dir(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -227,12 +289,22 @@ class ConfigurableProp_InterfaceTimer(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -250,10 +322,10 @@ class ConfigurableProp_InterfaceApphook(UniversalBaseModel): """ type: typing.Literal["$.interface.apphook"] = "$.interface.apphook" - app_prop: typing_extensions.Annotated[str, FieldMetadata(alias="appProp")] - event_names: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="eventNames")] = ( - None - ) + app_prop: typing_extensions.Annotated[str, FieldMetadata(alias="appProp"), pydantic.Field(alias="appProp")] + event_names: typing_extensions.Annotated[ + typing.Optional[typing.List[str]], FieldMetadata(alias="eventNames"), pydantic.Field(alias="eventNames") + ] = None remote: typing.Optional[bool] = None static: typing.Optional[typing.List[typing.Any]] = None name: str @@ -261,12 +333,22 @@ class ConfigurableProp_InterfaceApphook(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -293,12 +375,22 @@ class ConfigurableProp_IntegerArray(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -316,18 +408,30 @@ class ConfigurableProp_InterfaceHttp(UniversalBaseModel): """ type: typing.Literal["$.interface.http"] = "$.interface.http" - custom_response: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="customResponse")] = None + custom_response: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="customResponse"), pydantic.Field(alias="customResponse") + ] = None name: str label: typing.Optional[str] = None description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -351,12 +455,22 @@ class ConfigurableProp_HttpRequest(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -379,12 +493,22 @@ class ConfigurableProp_ServiceDb(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -410,12 +534,22 @@ class ConfigurableProp_Sql(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -433,18 +567,28 @@ class ConfigurableProp_AirtableBaseId(UniversalBaseModel): """ type: typing.Literal["$.airtable.baseId"] = "$.airtable.baseId" - app_prop: typing_extensions.Annotated[str, FieldMetadata(alias="appProp")] + app_prop: typing_extensions.Annotated[str, FieldMetadata(alias="appProp"), pydantic.Field(alias="appProp")] name: str label: typing.Optional[str] = None description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -462,18 +606,30 @@ class ConfigurableProp_AirtableTableId(UniversalBaseModel): """ type: typing.Literal["$.airtable.tableId"] = "$.airtable.tableId" - base_id_prop: typing_extensions.Annotated[str, FieldMetadata(alias="baseIdProp")] + base_id_prop: typing_extensions.Annotated[ + str, FieldMetadata(alias="baseIdProp"), pydantic.Field(alias="baseIdProp") + ] name: str label: typing.Optional[str] = None description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -491,18 +647,30 @@ class ConfigurableProp_AirtableViewId(UniversalBaseModel): """ type: typing.Literal["$.airtable.viewId"] = "$.airtable.viewId" - table_id_prop: typing_extensions.Annotated[str, FieldMetadata(alias="tableIdProp")] + table_id_prop: typing_extensions.Annotated[ + str, FieldMetadata(alias="tableIdProp"), pydantic.Field(alias="tableIdProp") + ] name: str label: typing.Optional[str] = None description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -520,18 +688,30 @@ class ConfigurableProp_AirtableFieldId(UniversalBaseModel): """ type: typing.Literal["$.airtable.fieldId"] = "$.airtable.fieldId" - table_id_prop: typing_extensions.Annotated[str, FieldMetadata(alias="tableIdProp")] + table_id_prop: typing_extensions.Annotated[ + str, FieldMetadata(alias="tableIdProp"), pydantic.Field(alias="tableIdProp") + ] name: str label: typing.Optional[str] = None description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -549,18 +729,28 @@ class ConfigurableProp_DiscordChannel(UniversalBaseModel): """ type: typing.Literal["$.discord.channel"] = "$.discord.channel" - app_prop: typing_extensions.Annotated[str, FieldMetadata(alias="appProp")] + app_prop: typing_extensions.Annotated[str, FieldMetadata(alias="appProp"), pydantic.Field(alias="appProp")] name: str label: typing.Optional[str] = None description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -578,18 +768,30 @@ class ConfigurableProp_DiscordChannelArray(UniversalBaseModel): """ type: typing.Literal["$.discord.channel[]"] = "$.discord.channel[]" - app_prop: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="appProp")] = None + app_prop: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="appProp"), pydantic.Field(alias="appProp") + ] = None name: str label: typing.Optional[str] = None description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -616,12 +818,22 @@ class ConfigurableProp_Integer(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -646,12 +858,22 @@ class ConfigurableProp_Object(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -678,12 +900,22 @@ class ConfigurableProp_String(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 @@ -710,12 +942,22 @@ class ConfigurableProp_StringArray(UniversalBaseModel): description: typing.Optional[str] = None optional: typing.Optional[bool] = None disabled: typing.Optional[bool] = None - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = None + read_only: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="readOnly"), pydantic.Field(alias="readOnly") + ] = None hidden: typing.Optional[bool] = None - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = None - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = None - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = None - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = None + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="remoteOptions"), pydantic.Field(alias="remoteOptions") + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="useQuery"), pydantic.Field(alias="useQuery") + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="reloadProps"), pydantic.Field(alias="reloadProps") + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], FieldMetadata(alias="withLabel"), pydantic.Field(alias="withLabel") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/configurable_prop_airtable_base_id.py b/src/pipedream/types/configurable_prop_airtable_base_id.py index 322ca16..dbecf66 100644 --- a/src/pipedream/types/configurable_prop_airtable_base_id.py +++ b/src/pipedream/types/configurable_prop_airtable_base_id.py @@ -10,10 +10,11 @@ class ConfigurablePropAirtableBaseId(ConfigurablePropBase): - app_prop: typing_extensions.Annotated[str, FieldMetadata(alias="appProp")] = pydantic.Field() - """ - The name of the app prop that provides Airtable authentication - """ + app_prop: typing_extensions.Annotated[ + str, + FieldMetadata(alias="appProp"), + pydantic.Field(alias="appProp", description="The name of the app prop that provides Airtable authentication"), + ] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/configurable_prop_airtable_field_id.py b/src/pipedream/types/configurable_prop_airtable_field_id.py index a2fa882..57b1768 100644 --- a/src/pipedream/types/configurable_prop_airtable_field_id.py +++ b/src/pipedream/types/configurable_prop_airtable_field_id.py @@ -10,10 +10,11 @@ class ConfigurablePropAirtableFieldId(ConfigurablePropBase): - table_id_prop: typing_extensions.Annotated[str, FieldMetadata(alias="tableIdProp")] = pydantic.Field() - """ - The name of the prop that provides the Airtable table ID - """ + table_id_prop: typing_extensions.Annotated[ + str, + FieldMetadata(alias="tableIdProp"), + pydantic.Field(alias="tableIdProp", description="The name of the prop that provides the Airtable table ID"), + ] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/configurable_prop_airtable_table_id.py b/src/pipedream/types/configurable_prop_airtable_table_id.py index a6be428..4bd65d2 100644 --- a/src/pipedream/types/configurable_prop_airtable_table_id.py +++ b/src/pipedream/types/configurable_prop_airtable_table_id.py @@ -10,10 +10,11 @@ class ConfigurablePropAirtableTableId(ConfigurablePropBase): - base_id_prop: typing_extensions.Annotated[str, FieldMetadata(alias="baseIdProp")] = pydantic.Field() - """ - The name of the prop that provides the Airtable base ID - """ + base_id_prop: typing_extensions.Annotated[ + str, + FieldMetadata(alias="baseIdProp"), + pydantic.Field(alias="baseIdProp", description="The name of the prop that provides the Airtable base ID"), + ] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/configurable_prop_airtable_view_id.py b/src/pipedream/types/configurable_prop_airtable_view_id.py index 7d265b8..016bb2c 100644 --- a/src/pipedream/types/configurable_prop_airtable_view_id.py +++ b/src/pipedream/types/configurable_prop_airtable_view_id.py @@ -10,10 +10,11 @@ class ConfigurablePropAirtableViewId(ConfigurablePropBase): - table_id_prop: typing_extensions.Annotated[str, FieldMetadata(alias="tableIdProp")] = pydantic.Field() - """ - The name of the prop that provides the Airtable table ID - """ + table_id_prop: typing_extensions.Annotated[ + str, + FieldMetadata(alias="tableIdProp"), + pydantic.Field(alias="tableIdProp", description="The name of the prop that provides the Airtable table ID"), + ] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/configurable_prop_alert.py b/src/pipedream/types/configurable_prop_alert.py index 0e5e5fd..306292d 100644 --- a/src/pipedream/types/configurable_prop_alert.py +++ b/src/pipedream/types/configurable_prop_alert.py @@ -12,7 +12,7 @@ class ConfigurablePropAlert(ConfigurablePropBase): alert_type: typing_extensions.Annotated[ - typing.Optional[ConfigurablePropAlertType], FieldMetadata(alias="alertType") + typing.Optional[ConfigurablePropAlertType], FieldMetadata(alias="alertType"), pydantic.Field(alias="alertType") ] = None content: str = pydantic.Field() """ diff --git a/src/pipedream/types/configurable_prop_apphook.py b/src/pipedream/types/configurable_prop_apphook.py index 7847505..9b12b95 100644 --- a/src/pipedream/types/configurable_prop_apphook.py +++ b/src/pipedream/types/configurable_prop_apphook.py @@ -10,18 +10,16 @@ class ConfigurablePropApphook(ConfigurablePropBase): - app_prop: typing_extensions.Annotated[str, FieldMetadata(alias="appProp")] = pydantic.Field() - """ - The name of the app prop that this apphook depends on - """ - - event_names: typing_extensions.Annotated[typing.Optional[typing.List[str]], FieldMetadata(alias="eventNames")] = ( - pydantic.Field(default=None) - ) - """ - List of event names to listen for - """ - + app_prop: typing_extensions.Annotated[ + str, + FieldMetadata(alias="appProp"), + pydantic.Field(alias="appProp", description="The name of the app prop that this apphook depends on"), + ] + event_names: typing_extensions.Annotated[ + typing.Optional[typing.List[str]], + FieldMetadata(alias="eventNames"), + pydantic.Field(alias="eventNames", description="List of event names to listen for"), + ] = None remote: typing.Optional[bool] = pydantic.Field(default=None) """ Whether this apphook is remote diff --git a/src/pipedream/types/configurable_prop_base.py b/src/pipedream/types/configurable_prop_base.py index 72a61d9..89ae8ca 100644 --- a/src/pipedream/types/configurable_prop_base.py +++ b/src/pipedream/types/configurable_prop_base.py @@ -38,45 +38,51 @@ class ConfigurablePropBase(UniversalBaseModel): If true, this prop will be ignored. """ - read_only: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnly")] = pydantic.Field( - default=None - ) - """ - If true, this prop is read-only — its value is either fixed by the component author (`static`) or the prop is purely informational (e.g. `alert`, `dir`). Connect clients should render it without treating it as a configurable input. - """ - + read_only: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="readOnly"), + pydantic.Field( + alias="readOnly", + description="If true, this prop is read-only — its value is either fixed by the component author (`static`) or the prop is purely informational (e.g. `alert`, `dir`). Connect clients should render it without treating it as a configurable input.", + ), + ] = None hidden: typing.Optional[bool] = pydantic.Field(default=None) """ If true, should not expose this prop to the user """ - remote_options: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="remoteOptions")] = ( - pydantic.Field(default=None) - ) - """ - If true, call `configureComponent` for this prop to load remote options. It is safe, and preferred, given a returned list of { label: string; value: any } objects to set the prop value to { __lv: { label: string; value: any } }. This way, on load, you can access label for the value without necessarily reloading these options - """ - - use_query: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="useQuery")] = pydantic.Field( - default=None - ) - """ - If true, calls to `configureComponent` for this prop support receiving a `query` parameter to filter remote options - """ - - reload_props: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="reloadProps")] = ( - pydantic.Field(default=None) - ) - """ - If true, after setting a value for this prop, a call to `reloadComponentProps` is required as the component has dynamic configurable props dependent on this one - """ - - with_label: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="withLabel")] = pydantic.Field( - default=None - ) - """ - If true, you must save the configured prop value as a "label-value" object which should look like: { __lv: { label: string; value: any } } because the execution needs to access the label - """ + remote_options: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="remoteOptions"), + pydantic.Field( + alias="remoteOptions", + description="If true, call `configureComponent` for this prop to load remote options. It is safe, and preferred, given a returned list of { label: string; value: any } objects to set the prop value to { __lv: { label: string; value: any } }. This way, on load, you can access label for the value without necessarily reloading these options", + ), + ] = None + use_query: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="useQuery"), + pydantic.Field( + alias="useQuery", + description="If true, calls to `configureComponent` for this prop support receiving a `query` parameter to filter remote options", + ), + ] = None + reload_props: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="reloadProps"), + pydantic.Field( + alias="reloadProps", + description="If true, after setting a value for this prop, a call to `reloadComponentProps` is required as the component has dynamic configurable props dependent on this one", + ), + ] = None + with_label: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="withLabel"), + pydantic.Field( + alias="withLabel", + description='If true, you must save the configured prop value as a "label-value" object which should look like: { __lv: { label: string; value: any } } because the execution needs to access the label', + ), + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/configurable_prop_dir.py b/src/pipedream/types/configurable_prop_dir.py index 700bfdc..ee6363e 100644 --- a/src/pipedream/types/configurable_prop_dir.py +++ b/src/pipedream/types/configurable_prop_dir.py @@ -12,7 +12,9 @@ class ConfigurablePropDir(ConfigurablePropBase): access_mode: typing_extensions.Annotated[ - typing.Optional[ConfigurablePropDirAccessMode], FieldMetadata(alias="accessMode") + typing.Optional[ConfigurablePropDirAccessMode], + FieldMetadata(alias="accessMode"), + pydantic.Field(alias="accessMode"), ] = None sync: typing.Optional[bool] = pydantic.Field(default=None) """ diff --git a/src/pipedream/types/configurable_prop_discord_channel.py b/src/pipedream/types/configurable_prop_discord_channel.py index e8c025f..38a6edd 100644 --- a/src/pipedream/types/configurable_prop_discord_channel.py +++ b/src/pipedream/types/configurable_prop_discord_channel.py @@ -10,10 +10,11 @@ class ConfigurablePropDiscordChannel(ConfigurablePropBase): - app_prop: typing_extensions.Annotated[str, FieldMetadata(alias="appProp")] = pydantic.Field() - """ - The name of the app prop that provides Discord authentication - """ + app_prop: typing_extensions.Annotated[ + str, + FieldMetadata(alias="appProp"), + pydantic.Field(alias="appProp", description="The name of the app prop that provides Discord authentication"), + ] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/configurable_prop_discord_channel_array.py b/src/pipedream/types/configurable_prop_discord_channel_array.py index 7c5af21..11d6e11 100644 --- a/src/pipedream/types/configurable_prop_discord_channel_array.py +++ b/src/pipedream/types/configurable_prop_discord_channel_array.py @@ -10,12 +10,11 @@ class ConfigurablePropDiscordChannelArray(ConfigurablePropBase): - app_prop: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="appProp")] = pydantic.Field( - default=None - ) - """ - The name of the app prop that provides Discord authentication - """ + app_prop: typing_extensions.Annotated[ + typing.Optional[str], + FieldMetadata(alias="appProp"), + pydantic.Field(alias="appProp", description="The name of the app prop that provides Discord authentication"), + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/configurable_prop_http.py b/src/pipedream/types/configurable_prop_http.py index c9276b6..6a49c4d 100644 --- a/src/pipedream/types/configurable_prop_http.py +++ b/src/pipedream/types/configurable_prop_http.py @@ -10,12 +10,11 @@ class ConfigurablePropHttp(ConfigurablePropBase): - custom_response: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="customResponse")] = ( - pydantic.Field(default=None) - ) - """ - Whether this HTTP interface allows custom responses - """ + custom_response: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="customResponse"), + pydantic.Field(alias="customResponse", description="Whether this HTTP interface allows custom responses"), + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/configure_prop_response.py b/src/pipedream/types/configure_prop_response.py index 54ad6c5..70e5300 100644 --- a/src/pipedream/types/configure_prop_response.py +++ b/src/pipedream/types/configure_prop_response.py @@ -17,12 +17,10 @@ class ConfigurePropResponse(UniversalBaseModel): options: typing.Optional[ConfigurePropOptions] = None string_options: typing_extensions.Annotated[ - typing.Optional[typing.List[str]], FieldMetadata(alias="stringOptions") - ] = pydantic.Field(default=None) - """ - Available options for the configured prop - """ - + typing.Optional[typing.List[str]], + FieldMetadata(alias="stringOptions"), + pydantic.Field(alias="stringOptions", description="Available options for the configured prop"), + ] = None observations: typing.Optional[typing.List[Observation]] = None context: typing.Optional[typing.Dict[str, typing.Any]] = pydantic.Field(default=None) """ diff --git a/src/pipedream/types/configured_prop_value_app.py b/src/pipedream/types/configured_prop_value_app.py index acafb83..4aaf2db 100644 --- a/src/pipedream/types/configured_prop_value_app.py +++ b/src/pipedream/types/configured_prop_value_app.py @@ -10,7 +10,9 @@ class ConfiguredPropValueApp(UniversalBaseModel): - auth_provision_id: typing_extensions.Annotated[AccountId, FieldMetadata(alias="authProvisionId")] + auth_provision_id: typing_extensions.Annotated[ + AccountId, FieldMetadata(alias="authProvisionId"), pydantic.Field(alias="authProvisionId") + ] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/configured_prop_value_sql.py b/src/pipedream/types/configured_prop_value_sql.py index 81eb9ad..2020b30 100644 --- a/src/pipedream/types/configured_prop_value_sql.py +++ b/src/pipedream/types/configured_prop_value_sql.py @@ -24,12 +24,13 @@ class ConfiguredPropValueSql(UniversalBaseModel): The list of parameters for the prepared statement """ - use_prepared_statements: typing_extensions.Annotated[bool, FieldMetadata(alias="usePreparedStatements")] = ( - pydantic.Field() - ) - """ - Whether to use prepared statements for the query or not - """ + use_prepared_statements: typing_extensions.Annotated[ + bool, + FieldMetadata(alias="usePreparedStatements"), + pydantic.Field( + alias="usePreparedStatements", description="Whether to use prepared statements for the query or not" + ), + ] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/dynamic_props.py b/src/pipedream/types/dynamic_props.py index e5b93ba..8c80452 100644 --- a/src/pipedream/types/dynamic_props.py +++ b/src/pipedream/types/dynamic_props.py @@ -20,11 +20,10 @@ class DynamicProps(UniversalBaseModel): """ configurable_props: typing_extensions.Annotated[ - typing.Optional[typing.List[ConfigurableProp]], FieldMetadata(alias="configurableProps") - ] = pydantic.Field(default=None) - """ - The updated configurable properties - """ + typing.Optional[typing.List[ConfigurableProp]], + FieldMetadata(alias="configurableProps"), + pydantic.Field(alias="configurableProps", description="The updated configurable properties"), + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/http_request_body.py b/src/pipedream/types/http_request_body.py index fe1fcde..3f5a006 100644 --- a/src/pipedream/types/http_request_body.py +++ b/src/pipedream/types/http_request_body.py @@ -17,7 +17,9 @@ class HttpRequestBody(UniversalBaseModel): """ type: typing.Optional[HttpRequestBodyType] = None - content_type: typing_extensions.Annotated[typing.Optional[str], FieldMetadata(alias="contentType")] = None + content_type: typing_extensions.Annotated[ + typing.Optional[str], FieldMetadata(alias="contentType"), pydantic.Field(alias="contentType") + ] = None fields: typing.Optional[typing.List[HttpRequestField]] = None mode: typing.Optional[HttpRequestBodyMode] = None raw: typing.Optional[str] = None diff --git a/src/pipedream/types/prop_option_nested.py b/src/pipedream/types/prop_option_nested.py index 806bf7c..0305616 100644 --- a/src/pipedream/types/prop_option_nested.py +++ b/src/pipedream/types/prop_option_nested.py @@ -14,7 +14,7 @@ class PropOptionNested(UniversalBaseModel): A configuration option for a component's prop (nested under `__lv`) """ - lv: typing_extensions.Annotated[PropOption, FieldMetadata(alias="__lv")] + lv: typing_extensions.Annotated[PropOption, FieldMetadata(alias="__lv"), pydantic.Field(alias="__lv")] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/proxy_response_binary.py b/src/pipedream/types/proxy_response_binary.py index e799429..da2f3e8 100644 --- a/src/pipedream/types/proxy_response_binary.py +++ b/src/pipedream/types/proxy_response_binary.py @@ -1,3 +1,3 @@ # This file was auto-generated by Fern from our API Definition. -ProxyResponseBinary = str +ProxyResponseBinary = bytes diff --git a/src/pipedream/types/reload_props_response.py b/src/pipedream/types/reload_props_response.py index 6a138c5..017a707 100644 --- a/src/pipedream/types/reload_props_response.py +++ b/src/pipedream/types/reload_props_response.py @@ -21,9 +21,9 @@ class ReloadPropsResponse(UniversalBaseModel): Any errors that occurred during configuration """ - dynamic_props: typing_extensions.Annotated[typing.Optional[DynamicProps], FieldMetadata(alias="dynamicProps")] = ( - None - ) + dynamic_props: typing_extensions.Annotated[ + typing.Optional[DynamicProps], FieldMetadata(alias="dynamicProps"), pydantic.Field(alias="dynamicProps") + ] = None if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/timer_interval.py b/src/pipedream/types/timer_interval.py index 36981c8..58cf141 100644 --- a/src/pipedream/types/timer_interval.py +++ b/src/pipedream/types/timer_interval.py @@ -13,10 +13,11 @@ class TimerInterval(UniversalBaseModel): Timer configuration using interval in seconds """ - interval_seconds: typing_extensions.Annotated[int, FieldMetadata(alias="intervalSeconds")] = pydantic.Field() - """ - Interval in seconds for timer execution - """ + interval_seconds: typing_extensions.Annotated[ + int, + FieldMetadata(alias="intervalSeconds"), + pydantic.Field(alias="intervalSeconds", description="Interval in seconds for timer execution"), + ] if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 diff --git a/src/pipedream/types/tool_annotations.py b/src/pipedream/types/tool_annotations.py index a66f513..dcada6f 100644 --- a/src/pipedream/types/tool_annotations.py +++ b/src/pipedream/types/tool_annotations.py @@ -13,34 +13,35 @@ class ToolAnnotations(UniversalBaseModel): Optional properties describing component behavior """ - destructive_hint: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="destructiveHint")] = ( - pydantic.Field(default=None) - ) - """ - If true, the component may perform destructive updates to its environment. If false, the component performs only additive updates. - """ - - idempotent_hint: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="idempotentHint")] = ( - pydantic.Field(default=None) - ) - """ - If true, calling the component repeatedly with the same arguments will have no additional effect on the its environment. - """ - - open_world_hint: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="openWorldHint")] = ( - pydantic.Field(default=None) - ) - """ - If true, this component may interact with an “open world” of external entities. If false, the component's domain of interaction is closed. For example, the world of a web search component is open, whereas that of a memory component is not. - """ - - read_only_hint: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="readOnlyHint")] = ( - pydantic.Field(default=None) - ) - """ - If true, the component does not modify its environment. - """ - + destructive_hint: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="destructiveHint"), + pydantic.Field( + alias="destructiveHint", + description="If true, the component may perform destructive updates to its environment. If false, the component performs only additive updates.", + ), + ] = None + idempotent_hint: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="idempotentHint"), + pydantic.Field( + alias="idempotentHint", + description="If true, calling the component repeatedly with the same arguments will have no additional effect on the its environment.", + ), + ] = None + open_world_hint: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="openWorldHint"), + pydantic.Field( + alias="openWorldHint", + description="If true, this component may interact with an “open world” of external entities. If false, the component's domain of interaction is closed. For example, the world of a web search component is open, whereas that of a memory component is not.", + ), + ] = None + read_only_hint: typing_extensions.Annotated[ + typing.Optional[bool], + FieldMetadata(alias="readOnlyHint"), + pydantic.Field(alias="readOnlyHint", description="If true, the component does not modify its environment."), + ] = None title: typing.Optional[str] = pydantic.Field(default=None) """ A human-readable title for the component. diff --git a/src/pipedream/usage/client.py b/src/pipedream/usage/client.py index a6386ac..925486d 100644 --- a/src/pipedream/usage/client.py +++ b/src/pipedream/usage/client.py @@ -51,9 +51,6 @@ def list( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.usage.list( start_ts=1, @@ -109,9 +106,6 @@ async def list( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/src/pipedream/users/client.py b/src/pipedream/users/client.py index 816f1a6..090d619 100644 --- a/src/pipedream/users/client.py +++ b/src/pipedream/users/client.py @@ -48,9 +48,6 @@ def delete_external_user( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) client.users.delete_external_user( external_user_id="external_user_id", @@ -99,9 +96,6 @@ def list( client = Pipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) response = client.users.list( after="after", @@ -158,9 +152,6 @@ async def delete_external_user( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) @@ -217,9 +208,6 @@ async def list( client = AsyncPipedream( project_id="YOUR_PROJECT_ID", - project_environment="YOUR_PROJECT_ENVIRONMENT", - client_id="YOUR_CLIENT_ID", - client_secret="YOUR_CLIENT_SECRET", ) diff --git a/tests/utils/test_http_client.py b/tests/utils/test_http_client.py index 50f2759..3576329 100644 --- a/tests/utils/test_http_client.py +++ b/tests/utils/test_http_client.py @@ -1,9 +1,49 @@ # This file was auto-generated by Fern from our API Definition. -from pipedream.core.http_client import get_request_body, remove_none_from_dict +from typing import Any, Dict + +import pytest + +from pipedream.core.http_client import ( + AsyncHttpClient, + HttpClient, + _build_url, + get_request_body, + remove_none_from_dict, +) from pipedream.core.request_options import RequestOptions +# Stub clients for testing HttpClient and AsyncHttpClient +class _DummySyncClient: + """A minimal stub for httpx.Client that records request arguments.""" + + def __init__(self) -> None: + self.last_request_kwargs: Dict[str, Any] = {} + + def request(self, **kwargs: Any) -> "_DummyResponse": + self.last_request_kwargs = kwargs + return _DummyResponse() + + +class _DummyAsyncClient: + """A minimal stub for httpx.AsyncClient that records request arguments.""" + + def __init__(self) -> None: + self.last_request_kwargs: Dict[str, Any] = {} + + async def request(self, **kwargs: Any) -> "_DummyResponse": + self.last_request_kwargs = kwargs + return _DummyResponse() + + +class _DummyResponse: + """A minimal stub for httpx.Response.""" + + status_code = 200 + headers: Dict[str, str] = {} + + def get_request_options() -> RequestOptions: return {"additional_body_parameters": {"see you": "later"}} @@ -52,17 +92,30 @@ def test_get_none_request_body() -> None: def test_get_empty_json_request_body() -> None: + """Test that implicit empty bodies (json=None) are collapsed to None.""" unrelated_request_options: RequestOptions = {"max_retries": 3} json_body, data_body = get_request_body(json=None, data=None, request_options=unrelated_request_options, omit=None) assert json_body is None assert data_body is None - json_body_extras, data_body_extras = get_request_body( - json={}, data=None, request_options=unrelated_request_options, omit=None - ) - assert json_body_extras is None - assert data_body_extras is None +def test_explicit_empty_json_body_is_preserved() -> None: + """Test that explicit empty bodies (json={}) are preserved and sent as {}. + + This is important for endpoints where the request body is required but all + fields are optional. The server expects valid JSON ({}) not an empty body. + """ + unrelated_request_options: RequestOptions = {"max_retries": 3} + + # Explicit json={} should be preserved + json_body, data_body = get_request_body(json={}, data=None, request_options=unrelated_request_options, omit=None) + assert json_body == {} + assert data_body is None + + # Explicit data={} should also be preserved + json_body2, data_body2 = get_request_body(json=None, data={}, request_options=unrelated_request_options, omit=None) + assert json_body2 is None + assert data_body2 == {} def test_json_body_preserves_none_values() -> None: @@ -107,3 +160,141 @@ def test_remove_none_from_dict_empty_dict() -> None: def test_remove_none_from_dict_all_none() -> None: """Test that remove_none_from_dict handles dict with all None values.""" assert remove_none_from_dict({"a": None, "b": None}) == {} + + +def test_http_client_does_not_pass_empty_params_list() -> None: + """Test that HttpClient passes params=None when params are empty. + + This prevents httpx from stripping existing query parameters from the URL, + which happens when params=[] or params={} is passed. + """ + dummy_client = _DummySyncClient() + http_client = HttpClient( + httpx_client=dummy_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + ) + + # Use a path with query params (e.g., pagination cursor URL) + http_client.request( + path="resource?after=123", + method="GET", + params=None, + request_options=None, + ) + + # We care that httpx receives params=None, not [] or {} + assert "params" in dummy_client.last_request_kwargs + assert dummy_client.last_request_kwargs["params"] is None + + # Verify the query string in the URL is preserved + url = str(dummy_client.last_request_kwargs["url"]) + assert "after=123" in url, f"Expected query param 'after=123' in URL, got: {url}" + + +def test_http_client_passes_encoded_params_when_present() -> None: + """Test that HttpClient passes encoded params when params are provided.""" + dummy_client = _DummySyncClient() + http_client = HttpClient( + httpx_client=dummy_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com/resource", + ) + + http_client.request( + path="", + method="GET", + params={"after": "456"}, + request_options=None, + ) + + params = dummy_client.last_request_kwargs["params"] + # For a simple dict, encode_query should give a single (key, value) tuple + assert params == [("after", "456")] + + +@pytest.mark.asyncio +async def test_async_http_client_does_not_pass_empty_params_list() -> None: + """Test that AsyncHttpClient passes params=None when params are empty. + + This prevents httpx from stripping existing query parameters from the URL, + which happens when params=[] or params={} is passed. + """ + dummy_client = _DummyAsyncClient() + http_client = AsyncHttpClient( + httpx_client=dummy_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com", + async_base_headers=None, + ) + + # Use a path with query params (e.g., pagination cursor URL) + await http_client.request( + path="resource?after=123", + method="GET", + params=None, + request_options=None, + ) + + # We care that httpx receives params=None, not [] or {} + assert "params" in dummy_client.last_request_kwargs + assert dummy_client.last_request_kwargs["params"] is None + + # Verify the query string in the URL is preserved + url = str(dummy_client.last_request_kwargs["url"]) + assert "after=123" in url, f"Expected query param 'after=123' in URL, got: {url}" + + +@pytest.mark.asyncio +async def test_async_http_client_passes_encoded_params_when_present() -> None: + """Test that AsyncHttpClient passes encoded params when params are provided.""" + dummy_client = _DummyAsyncClient() + http_client = AsyncHttpClient( + httpx_client=dummy_client, # type: ignore[arg-type] + base_timeout=lambda: None, + base_headers=lambda: {}, + base_url=lambda: "https://example.com/resource", + async_base_headers=None, + ) + + await http_client.request( + path="", + method="GET", + params={"after": "456"}, + request_options=None, + ) + + params = dummy_client.last_request_kwargs["params"] + # For a simple dict, encode_query should give a single (key, value) tuple + assert params == [("after", "456")] + + +def test_basic_url_joining() -> None: + """Test basic URL joining with a simple base URL and path.""" + result = _build_url("https://api.example.com", "/users") + assert result == "https://api.example.com/users" + + +def test_basic_url_joining_trailing_slash() -> None: + """Test basic URL joining with a simple base URL and path.""" + result = _build_url("https://api.example.com/", "/users") + assert result == "https://api.example.com/users" + + +def test_preserves_base_url_path_prefix() -> None: + """Test that path prefixes in base URL are preserved. + + This is the critical bug fix - urllib.parse.urljoin() would strip + the path prefix when the path starts with '/'. + """ + result = _build_url("https://cloud.example.com/org/tenant/api", "/users") + assert result == "https://cloud.example.com/org/tenant/api/users" + + +def test_preserves_base_url_path_prefix_trailing_slash() -> None: + """Test that path prefixes in base URL are preserved.""" + result = _build_url("https://cloud.example.com/org/tenant/api/", "/users") + assert result == "https://cloud.example.com/org/tenant/api/users"