diff --git a/.fernignore b/.fernignore index e76b5b7..d4a6c0b 100644 --- a/.fernignore +++ b/.fernignore @@ -18,6 +18,7 @@ src/pipedream/pipedream.py # Custom Proxy files src/pipedream/proxy/client.py +src/pipedream/proxy/raw_client.py # Custom Workflow files src/pipedream/workflows/__init__.py diff --git a/README.md b/README.md index ea4d0a3..4db038a 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,21 @@ The Pipedream Python library provides convenient access to the Pipedream APIs from Python. +## Table of Contents + +- [Installation](#installation) +- [Reference](#reference) +- [Usage](#usage) +- [Async Client](#async-client) +- [Exception Handling](#exception-handling) +- [Pagination](#pagination) +- [Advanced](#advanced) + - [Access Raw Response Data](#access-raw-response-data) + - [Retries](#retries) + - [Timeouts](#timeouts) + - [Custom Client](#custom-client) +- [Contributing](#contributing) + ## Installation ```sh @@ -89,14 +104,7 @@ client = Pipedream( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", ) -response = client.apps.list( - after="after", - before="before", - limit=1, - q="q", - sort_key="name", - sort_direction="asc", -) +response = client.apps.list() for item in response: yield item # alternatively, you can paginate page-by-page diff --git a/poetry.lock b/poetry.lock index fef3795..a19d7e2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -38,13 +38,13 @@ trio = ["trio (>=0.26.1)"] [[package]] name = "certifi" -version = "2025.10.5" +version = "2025.11.12" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.7" files = [ - {file = "certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de"}, - {file = "certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43"}, + {file = "certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b"}, + {file = "certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316"}, ] [[package]] @@ -60,13 +60,13 @@ files = [ [[package]] name = "exceptiongroup" -version = "1.3.0" +version = "1.3.1" description = "Backport of PEP 654 (exception groups)" optional = false python-versions = ">=3.7" files = [ - {file = "exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10"}, - {file = "exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88"}, + {file = "exceptiongroup-1.3.1-py3-none-any.whl", hash = "sha256:a7a39a3bd276781e98394987d3a5701d0c4edffb633bb7a5144577f82c773598"}, + {file = "exceptiongroup-1.3.1.tar.gz", hash = "sha256:8b412432c6055b0b7d14c310000ae93352ed6754f70fa8f7c34141f91c4e3219"}, ] [package.dependencies] diff --git a/pyproject.toml b/pyproject.toml index c93c57d..2af2770 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "pipedream" [tool.poetry] name = "pipedream" -version = "1.0.11" +version = "1.0.12" description = "" readme = "README.md" authors = [] diff --git a/src/pipedream/accounts/client.py b/src/pipedream/accounts/client.py index 84f3fdf..4c97f9d 100644 --- a/src/pipedream/accounts/client.py +++ b/src/pipedream/accounts/client.py @@ -82,15 +82,7 @@ def list( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", ) - response = client.accounts.list( - external_user_id="external_user_id", - oauth_app_id="oauth_app_id", - after="after", - before="before", - limit=1, - app="app", - include_credentials=True, - ) + response = client.accounts.list() for item in response: yield item # alternatively, you can paginate page-by-page @@ -160,8 +152,6 @@ def create( client_secret="YOUR_CLIENT_SECRET", ) client.accounts.create( - external_user_id="external_user_id", - oauth_app_id="oauth_app_id", app_slug="app_slug", cfmap_json="cfmap_json", connect_token="connect_token", @@ -215,7 +205,6 @@ def retrieve( ) client.accounts.retrieve( account_id="account_id", - include_credentials=True, ) """ _response = self._raw_client.retrieve( @@ -363,15 +352,7 @@ async def list( async def main() -> None: - response = await client.accounts.list( - external_user_id="external_user_id", - oauth_app_id="oauth_app_id", - after="after", - before="before", - limit=1, - app="app", - include_credentials=True, - ) + response = await client.accounts.list() async for item in response: yield item @@ -450,8 +431,6 @@ async def create( async def main() -> None: await client.accounts.create( - external_user_id="external_user_id", - oauth_app_id="oauth_app_id", app_slug="app_slug", cfmap_json="cfmap_json", connect_token="connect_token", @@ -513,7 +492,6 @@ async def retrieve( async def main() -> None: await client.accounts.retrieve( account_id="account_id", - include_credentials=True, ) diff --git a/src/pipedream/actions/client.py b/src/pipedream/actions/client.py index cebb494..5f86f30 100644 --- a/src/pipedream/actions/client.py +++ b/src/pipedream/actions/client.py @@ -80,13 +80,7 @@ def list( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", ) - response = client.actions.list( - after="after", - before="before", - limit=1, - q="q", - app="app", - ) + response = client.actions.list() for item in response: yield item # alternatively, you can paginate page-by-page @@ -431,13 +425,7 @@ async def list( async def main() -> None: - response = await client.actions.list( - after="after", - before="before", - limit=1, - q="q", - app="app", - ) + response = await client.actions.list() async for item in response: yield item diff --git a/src/pipedream/actions/raw_client.py b/src/pipedream/actions/raw_client.py index 1637a43..47bb1ed 100644 --- a/src/pipedream/actions/raw_client.py +++ b/src/pipedream/actions/raw_client.py @@ -426,7 +426,7 @@ def run( ), "dynamic_props_id": dynamic_props_id, "stash_id": convert_and_respect_annotation_metadata( - object_=stash_id, annotation=RunActionOptsStashId, direction="write" + object_=stash_id, annotation=typing.Optional[RunActionOptsStashId], direction="write" ), }, headers={ @@ -866,7 +866,7 @@ async def run( ), "dynamic_props_id": dynamic_props_id, "stash_id": convert_and_respect_annotation_metadata( - object_=stash_id, annotation=RunActionOptsStashId, direction="write" + object_=stash_id, annotation=typing.Optional[RunActionOptsStashId], direction="write" ), }, headers={ diff --git a/src/pipedream/apps/client.py b/src/pipedream/apps/client.py index 512d8df..5d44a36 100644 --- a/src/pipedream/apps/client.py +++ b/src/pipedream/apps/client.py @@ -83,14 +83,7 @@ def list( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", ) - response = client.apps.list( - after="after", - before="before", - limit=1, - q="q", - sort_key="name", - sort_direction="asc", - ) + response = client.apps.list() for item in response: yield item # alternatively, you can paginate page-by-page @@ -219,14 +212,7 @@ async def list( async def main() -> None: - response = await client.apps.list( - after="after", - before="before", - limit=1, - q="q", - sort_key="name", - sort_direction="asc", - ) + response = await client.apps.list() async for item in response: yield item diff --git a/src/pipedream/client.py b/src/pipedream/client.py index 6f4accc..514ef44 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 OAuthTokenProvider from .environment import PipedreamEnvironment +from .types.project_environment import ProjectEnvironment if typing.TYPE_CHECKING: from .accounts.client import AccountsClient, AsyncAccountsClient diff --git a/src/pipedream/components/client.py b/src/pipedream/components/client.py index a68c358..2004396 100644 --- a/src/pipedream/components/client.py +++ b/src/pipedream/components/client.py @@ -83,14 +83,7 @@ def list( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", ) - response = client.components.list( - after="after", - before="before", - limit=1, - q="q", - app="app", - component_type="trigger", - ) + response = client.components.list() for item in response: yield item # alternatively, you can paginate page-by-page @@ -379,14 +372,7 @@ async def list( async def main() -> None: - response = await client.components.list( - after="after", - before="before", - limit=1, - q="q", - app="app", - component_type="trigger", - ) + response = await client.components.list() async for item in response: yield item diff --git a/src/pipedream/core/client_wrapper.py b/src/pipedream/core/client_wrapper.py index d1cbb05..b75073a 100644 --- a/src/pipedream/core/client_wrapper.py +++ b/src/pipedream/core/client_wrapper.py @@ -27,10 +27,10 @@ def __init__( def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { - "User-Agent": "pipedream/1.0.11", + "User-Agent": "pipedream/1.0.12", "X-Fern-Language": "Python", "X-Fern-SDK-Name": "pipedream", - "X-Fern-SDK-Version": "1.0.11", + "X-Fern-SDK-Version": "1.0.12", **(self.get_custom_headers() or {}), } if self._project_environment is not None: diff --git a/src/pipedream/deployed_triggers/client.py b/src/pipedream/deployed_triggers/client.py index ea92f4e..d7ae086 100644 --- a/src/pipedream/deployed_triggers/client.py +++ b/src/pipedream/deployed_triggers/client.py @@ -81,11 +81,7 @@ def list( client_secret="YOUR_CLIENT_SECRET", ) response = client.deployed_triggers.list( - after="after", - before="before", - limit=1, external_user_id="external_user_id", - emitter_type="email", ) for item in response: yield item @@ -151,6 +147,7 @@ def update( active: typing.Optional[bool] = OMIT, configured_props: typing.Optional[ConfiguredProps] = OMIT, name: typing.Optional[str] = OMIT, + emit_on_deploy: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Emitter: """ @@ -171,6 +168,9 @@ def update( name : typing.Optional[str] The name of the trigger + emit_on_deploy : typing.Optional[bool] + Whether the trigger should emit events during deployment + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -200,6 +200,7 @@ def update( active=active, configured_props=configured_props, name=name, + emit_on_deploy=emit_on_deploy, request_options=request_options, ) return _response.data @@ -245,7 +246,6 @@ def delete( client.deployed_triggers.delete( trigger_id="trigger_id", external_user_id="external_user_id", - ignore_hook_errors=True, ) """ _response = self._raw_client.delete( @@ -298,7 +298,6 @@ def list_events( client.deployed_triggers.list_events( trigger_id="trigger_id", external_user_id="external_user_id", - n=1, ) """ _response = self._raw_client.list_events( @@ -558,11 +557,7 @@ async def list( async def main() -> None: response = await client.deployed_triggers.list( - after="after", - before="before", - limit=1, external_user_id="external_user_id", - emitter_type="email", ) async for item in response: yield item @@ -640,6 +635,7 @@ async def update( active: typing.Optional[bool] = OMIT, configured_props: typing.Optional[ConfiguredProps] = OMIT, name: typing.Optional[str] = OMIT, + emit_on_deploy: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Emitter: """ @@ -660,6 +656,9 @@ async def update( name : typing.Optional[str] The name of the trigger + emit_on_deploy : typing.Optional[bool] + Whether the trigger should emit events during deployment + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -697,6 +696,7 @@ async def main() -> None: active=active, configured_props=configured_props, name=name, + emit_on_deploy=emit_on_deploy, request_options=request_options, ) return _response.data @@ -747,7 +747,6 @@ async def main() -> None: await client.deployed_triggers.delete( trigger_id="trigger_id", external_user_id="external_user_id", - ignore_hook_errors=True, ) @@ -808,7 +807,6 @@ async def main() -> None: await client.deployed_triggers.list_events( trigger_id="trigger_id", external_user_id="external_user_id", - n=1, ) diff --git a/src/pipedream/deployed_triggers/raw_client.py b/src/pipedream/deployed_triggers/raw_client.py index 4b2e576..dab281a 100644 --- a/src/pipedream/deployed_triggers/raw_client.py +++ b/src/pipedream/deployed_triggers/raw_client.py @@ -186,6 +186,7 @@ def update( active: typing.Optional[bool] = OMIT, configured_props: typing.Optional[ConfiguredProps] = OMIT, name: typing.Optional[str] = OMIT, + emit_on_deploy: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Emitter]: """ @@ -206,6 +207,9 @@ def update( name : typing.Optional[str] The name of the trigger + emit_on_deploy : typing.Optional[bool] + Whether the trigger should emit events during deployment + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -226,6 +230,7 @@ def update( object_=configured_props, annotation=ConfiguredProps, direction="write" ), "name": name, + "emit_on_deploy": emit_on_deploy, }, headers={ "content-type": "application/json", @@ -795,6 +800,7 @@ async def update( active: typing.Optional[bool] = OMIT, configured_props: typing.Optional[ConfiguredProps] = OMIT, name: typing.Optional[str] = OMIT, + emit_on_deploy: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Emitter]: """ @@ -815,6 +821,9 @@ async def update( name : typing.Optional[str] The name of the trigger + emit_on_deploy : typing.Optional[bool] + Whether the trigger should emit events during deployment + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -835,6 +844,7 @@ async def update( object_=configured_props, annotation=ConfiguredProps, direction="write" ), "name": name, + "emit_on_deploy": emit_on_deploy, }, headers={ "content-type": "application/json", diff --git a/src/pipedream/proxy/client.py b/src/pipedream/proxy/client.py index bdcb3f2..afef844 100644 --- a/src/pipedream/proxy/client.py +++ b/src/pipedream/proxy/client.py @@ -2,6 +2,8 @@ import base64 import typing +from collections.abc import AsyncIterator, Iterator +from urllib.parse import parse_qs, urlencode, urlparse, urlunparse from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper from ..core.request_options import RequestOptions @@ -12,6 +14,15 @@ OMIT = typing.cast(typing.Any, ...) +def _add_params_to_url(url: str, params: typing.Dict[str, typing.Any]) -> str: + parsed = urlparse(url) + existing_params = parse_qs(parsed.query) + for key, value in params.items(): + existing_params[key] = value if isinstance(value, list) else [value] + new_query = urlencode(existing_params, doseq=True) + return urlunparse(parsed._replace(query=new_query)) + + class ProxyClient: def __init__(self, *, client_wrapper: SyncClientWrapper): @@ -37,7 +48,7 @@ def get( account_id: str, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, params: typing.Optional[typing.Dict[str, typing.Any]] = None, - ) -> ProxyResponse: + ) -> typing.Union[ProxyResponse, typing.Iterator[bytes]]: """ Parameters ---------- @@ -58,8 +69,8 @@ def get( Returns ------- - ProxyResponse - proxy request successful + typing.Union[ProxyResponse, typing.Iterator[bytes]] + ProxyResponse for JSON content, Iterator[bytes] for binary content Examples -------- @@ -75,26 +86,40 @@ def get( url="https://example.com/api/endpoint", external_user_id="external_user_id", account_id="account_id", - headers={"Extra-Downstream-Header": "some value"} + headers={"Extra-Downstream-Header": "some value"}, params={"limit": 10}, ) """ + if params: + url = _add_params_to_url(url, params) url_64 = base64.urlsafe_b64encode(url.encode()).decode() downstream_headers = { f"x-pd-proxy-{header}": value for header, value in (headers or {}).items() } request_options = RequestOptions( - additional_headers=downstream_headers, - additional_query_parameters=params, - ) - _response = self._raw_client.get( + additional_headers=downstream_headers, ) + ctx = self._raw_client.get( url_64, external_user_id=external_user_id, account_id=account_id, request_options=request_options, ) - return _response.data + _response = ctx.__enter__() + data = _response.data + + if not isinstance(data, Iterator): + ctx.__exit__(None, None, None) + return data + + def _stream() -> typing.Iterator[bytes]: + try: + for chunk in data: + yield chunk + finally: + ctx.__exit__(None, None, None) + + return _stream() def post( self, @@ -108,7 +133,7 @@ def post( typing.Optional[typing.Any], ]] = None, params: typing.Optional[typing.Dict[str, typing.Any]] = None, - ) -> ProxyResponse: + ) -> typing.Union[ProxyResponse, typing.Iterator[bytes]]: """ Parameters ---------- @@ -132,8 +157,8 @@ def post( Returns ------- - ProxyResponse - proxy request successful + typing.Union[ProxyResponse, typing.Iterator[bytes]] + ProxyResponse for JSON content, Iterator[bytes] for binary content Examples -------- @@ -153,23 +178,37 @@ def post( body={"key": "value"}, ) """ + if params: + url = _add_params_to_url(url, params) url_64 = base64.urlsafe_b64encode(url.encode()).decode() downstream_headers = { f"x-pd-proxy-{header}": value for header, value in (headers or {}).items() } request_options = RequestOptions( - additional_headers=downstream_headers, - additional_query_parameters=params, - ) - _response = self._raw_client.post( + additional_headers=downstream_headers, ) + ctx = self._raw_client.post( url_64, external_user_id=external_user_id, account_id=account_id, request=body or {}, request_options=request_options, ) - return _response.data + _response = ctx.__enter__() + data = _response.data + + if not isinstance(data, Iterator): + ctx.__exit__(None, None, None) + return data + + def _stream() -> typing.Iterator[bytes]: + try: + for chunk in data: + yield chunk + finally: + ctx.__exit__(None, None, None) + + return _stream() def put( self, @@ -183,7 +222,7 @@ def put( typing.Optional[typing.Any], ]] = None, params: typing.Optional[typing.Dict[str, typing.Any]] = None, - ) -> ProxyResponse: + ) -> typing.Union[ProxyResponse, typing.Iterator[bytes]]: """ Parameters ---------- @@ -207,8 +246,8 @@ def put( Returns ------- - ProxyResponse - proxy request successful + typing.Union[ProxyResponse, typing.Iterator[bytes]] + ProxyResponse for JSON content, Iterator[bytes] for binary content Examples -------- @@ -228,23 +267,37 @@ def put( body={"key": "value"}, ) """ + if params: + url = _add_params_to_url(url, params) url_64 = base64.urlsafe_b64encode(url.encode()).decode() downstream_headers = { f"x-pd-proxy-{header}": value for header, value in (headers or {}).items() } request_options = RequestOptions( - additional_headers=downstream_headers, - additional_query_parameters=params, - ) - _response = self._raw_client.put( + additional_headers=downstream_headers, ) + ctx = self._raw_client.put( url_64, external_user_id=external_user_id, account_id=account_id, request=body or {}, request_options=request_options, ) - return _response.data + _response = ctx.__enter__() + data = _response.data + + if not isinstance(data, Iterator): + ctx.__exit__(None, None, None) + return data + + def _stream() -> typing.Iterator[bytes]: + try: + for chunk in data: + yield chunk + finally: + ctx.__exit__(None, None, None) + + return _stream() def delete( self, @@ -254,7 +307,7 @@ def delete( account_id: str, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, params: typing.Optional[typing.Dict[str, typing.Any]] = None, - ) -> ProxyResponse: + ) -> typing.Union[ProxyResponse, typing.Iterator[bytes]]: """ Parameters ---------- @@ -275,8 +328,8 @@ def delete( Returns ------- - ProxyResponse - proxy request successful + typing.Union[ProxyResponse, typing.Iterator[bytes]] + ProxyResponse for JSON content, Iterator[bytes] for binary content Examples -------- @@ -295,22 +348,36 @@ def delete( headers={"Extra-Downstream-Header": "some value"} ) """ + if params: + url = _add_params_to_url(url, params) url_64 = base64.urlsafe_b64encode(url.encode()).decode() downstream_headers = { f"x-pd-proxy-{header}": value for header, value in (headers or {}).items() } request_options = RequestOptions( - additional_headers=downstream_headers, - additional_query_parameters=params, - ) - _response = self._raw_client.delete( + additional_headers=downstream_headers, ) + ctx = self._raw_client.delete( url_64, external_user_id=external_user_id, account_id=account_id, request_options=request_options, ) - return _response.data + _response = ctx.__enter__() + data = _response.data + + if not isinstance(data, Iterator): + ctx.__exit__(None, None, None) + return data + + def _stream() -> typing.Iterator[bytes]: + try: + for chunk in data: + yield chunk + finally: + ctx.__exit__(None, None, None) + + return _stream() def patch( self, @@ -324,7 +391,7 @@ def patch( typing.Optional[typing.Any], ]] = None, params: typing.Optional[typing.Dict[str, typing.Any]] = None, - ) -> ProxyResponse: + ) -> typing.Union[ProxyResponse, typing.Iterator[bytes]]: """ Parameters ---------- @@ -348,8 +415,8 @@ def patch( Returns ------- - ProxyResponse - proxy request successful + typing.Union[ProxyResponse, typing.Iterator[bytes]] + ProxyResponse for JSON content, Iterator[bytes] for binary content Examples -------- @@ -369,23 +436,37 @@ def patch( body={"key": "value"}, ) """ + if params: + url = _add_params_to_url(url, params) url_64 = base64.urlsafe_b64encode(url.encode()).decode() downstream_headers = { f"x-pd-proxy-{header}": value for header, value in (headers or {}).items() } request_options = RequestOptions( - additional_headers=downstream_headers, - additional_query_parameters=params, - ) - _response = self._raw_client.patch( + additional_headers=downstream_headers, ) + ctx = self._raw_client.patch( url_64, external_user_id=external_user_id, account_id=account_id, request=body or {}, request_options=request_options, ) - return _response.data + _response = ctx.__enter__() + data = _response.data + + if not isinstance(data, Iterator): + ctx.__exit__(None, None, None) + return data + + def _stream() -> typing.Iterator[bytes]: + try: + for chunk in data: + yield chunk + finally: + ctx.__exit__(None, None, None) + + return _stream() class AsyncProxyClient: @@ -413,7 +494,7 @@ async def get( account_id: str, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, params: typing.Optional[typing.Dict[str, typing.Any]] = None, - ) -> ProxyResponse: + ) -> typing.Union[ProxyResponse, typing.AsyncIterator[bytes]]: """ Parameters ---------- @@ -434,8 +515,8 @@ async def get( Returns ------- - ProxyResponse - proxy request successful + typing.Union[ProxyResponse, typing.AsyncIterator[bytes]] + ProxyResponse for JSON content, AsyncIterator[bytes] for binary content Examples -------- @@ -456,28 +537,43 @@ async def main() -> None: url="https://example.com/api/endpoint", external_user_id="external_user_id", account_id="account_id", - headers={"Extra-Downstream-Header": "some value"} + headers={"Extra-Downstream-Header": "some value"}, params={"limit": 10}, ) asyncio.run(main()) """ + if params: + url = _add_params_to_url(url, params) url_64 = base64.urlsafe_b64encode(url.encode()).decode() downstream_headers = { f"x-pd-proxy-{header}": value for header, value in (headers or {}).items() } request_options = RequestOptions( - additional_headers=downstream_headers, - additional_query_parameters=params, - ) - _response = await self._raw_client.get( + additional_headers=downstream_headers, ) + ctx = self._raw_client.get( url_64, external_user_id=external_user_id, account_id=account_id, - request_options=request_options) - return _response.data + request_options=request_options, + ) + _response = await ctx.__aenter__() + data = _response.data + + if not isinstance(data, AsyncIterator): + await ctx.__aexit__(None, None, None) + return data + + async def _stream() -> typing.AsyncIterator[bytes]: + try: + async for chunk in data: + yield chunk + finally: + await ctx.__aexit__(None, None, None) + + return _stream() async def post( self, @@ -491,7 +587,7 @@ async def post( typing.Optional[typing.Any], ]] = None, params: typing.Optional[typing.Dict[str, typing.Any]] = None, - ) -> ProxyResponse: + ) -> typing.Union[ProxyResponse, typing.AsyncIterator[bytes]]: """ Parameters ---------- @@ -515,8 +611,8 @@ async def post( Returns ------- - ProxyResponse - proxy request successful + typing.Union[ProxyResponse, typing.AsyncIterator[bytes]] + ProxyResponse for JSON content, AsyncIterator[bytes] for binary content Examples -------- @@ -544,23 +640,37 @@ async def main() -> None: asyncio.run(main()) """ + if params: + url = _add_params_to_url(url, params) url_64 = base64.urlsafe_b64encode(url.encode()).decode() downstream_headers = { f"x-pd-proxy-{header}": value for header, value in (headers or {}).items() } request_options = RequestOptions( - additional_headers=downstream_headers, - additional_query_parameters=params, - ) - _response = await self._raw_client.post( + additional_headers=downstream_headers, ) + ctx = self._raw_client.post( url_64, external_user_id=external_user_id, account_id=account_id, request=body or {}, request_options=request_options, ) - return _response.data + _response = await ctx.__aenter__() + data = _response.data + + if not isinstance(data, AsyncIterator): + await ctx.__aexit__(None, None, None) + return data + + async def _stream() -> typing.AsyncIterator[bytes]: + try: + async for chunk in data: + yield chunk + finally: + await ctx.__aexit__(None, None, None) + + return _stream() async def put( self, @@ -574,7 +684,7 @@ async def put( typing.Optional[typing.Any], ]] = None, params: typing.Optional[typing.Dict[str, typing.Any]] = None, - ) -> ProxyResponse: + ) -> typing.Union[ProxyResponse, typing.AsyncIterator[bytes]]: """ Parameters ---------- @@ -598,8 +708,8 @@ async def put( Returns ------- - ProxyResponse - proxy request successful + typing.Union[ProxyResponse, typing.AsyncIterator[bytes]] + ProxyResponse for JSON content, AsyncIterator[bytes] for binary content Examples -------- @@ -627,23 +737,37 @@ async def main() -> None: asyncio.run(main()) """ + if params: + url = _add_params_to_url(url, params) url_64 = base64.urlsafe_b64encode(url.encode()).decode() downstream_headers = { f"x-pd-proxy-{header}": value for header, value in (headers or {}).items() } request_options = RequestOptions( - additional_headers=downstream_headers, - additional_query_parameters=params, - ) - _response = await self._raw_client.put( + additional_headers=downstream_headers, ) + ctx = self._raw_client.put( url_64, external_user_id=external_user_id, account_id=account_id, request=body or {}, request_options=request_options, ) - return _response.data + _response = await ctx.__aenter__() + data = _response.data + + if not isinstance(data, AsyncIterator): + await ctx.__aexit__(None, None, None) + return data + + async def _stream() -> typing.AsyncIterator[bytes]: + try: + async for chunk in data: + yield chunk + finally: + await ctx.__aexit__(None, None, None) + + return _stream() async def delete( self, @@ -653,7 +777,7 @@ async def delete( account_id: str, headers: typing.Optional[typing.Dict[str, typing.Any]] = None, params: typing.Optional[typing.Dict[str, typing.Any]] = None, - ) -> ProxyResponse: + ) -> typing.Union[ProxyResponse, typing.AsyncIterator[bytes]]: """ Parameters ---------- @@ -674,8 +798,8 @@ async def delete( Returns ------- - ProxyResponse - proxy request successful + typing.Union[ProxyResponse, typing.AsyncIterator[bytes]] + ProxyResponse for JSON content, AsyncIterator[bytes] for binary content Examples -------- @@ -702,21 +826,36 @@ async def main() -> None: asyncio.run(main()) """ + if params: + url = _add_params_to_url(url, params) url_64 = base64.urlsafe_b64encode(url.encode()).decode() downstream_headers = { f"x-pd-proxy-{header}": value for header, value in (headers or {}).items() } request_options = RequestOptions( - additional_headers=downstream_headers, - additional_query_parameters=params, - ) - _response = await self._raw_client.delete( + additional_headers=downstream_headers, ) + ctx = self._raw_client.delete( url_64, external_user_id=external_user_id, account_id=account_id, - request_options=request_options) - return _response.data + request_options=request_options, + ) + _response = await ctx.__aenter__() + data = _response.data + + if not isinstance(data, AsyncIterator): + await ctx.__aexit__(None, None, None) + return data + + async def _stream() -> typing.AsyncIterator[bytes]: + try: + async for chunk in data: + yield chunk + finally: + await ctx.__aexit__(None, None, None) + + return _stream() async def patch( self, @@ -730,7 +869,7 @@ async def patch( typing.Optional[typing.Any], ]] = None, params: typing.Optional[typing.Dict[str, typing.Any]] = None, - ) -> ProxyResponse: + ) -> typing.Union[ProxyResponse, typing.AsyncIterator[bytes]]: """ Parameters ---------- @@ -754,8 +893,8 @@ async def patch( Returns ------- - ProxyResponse - proxy request successful + typing.Union[ProxyResponse, typing.AsyncIterator[bytes]] + ProxyResponse for JSON content, AsyncIterator[bytes] for binary content Examples -------- @@ -783,20 +922,34 @@ async def main() -> None: asyncio.run(main()) """ + if params: + url = _add_params_to_url(url, params) url_64 = base64.urlsafe_b64encode(url.encode()).decode() downstream_headers = { f"x-pd-proxy-{header}": value for header, value in (headers or {}).items() } request_options = RequestOptions( - additional_headers=downstream_headers, - additional_query_parameters=params, - ) - _response = await self._raw_client.patch( + additional_headers=downstream_headers, ) + ctx = self._raw_client.patch( url_64, external_user_id=external_user_id, account_id=account_id, request=body or {}, request_options=request_options, ) - return _response.data + _response = await ctx.__aenter__() + data = _response.data + + if not isinstance(data, AsyncIterator): + await ctx.__aexit__(None, None, None) + return data + + async def _stream() -> typing.AsyncIterator[bytes]: + try: + async for chunk in data: + yield chunk + finally: + await ctx.__aexit__(None, None, None) + + return _stream() diff --git a/src/pipedream/proxy/raw_client.py b/src/pipedream/proxy/raw_client.py index 6825954..45771a1 100644 --- a/src/pipedream/proxy/raw_client.py +++ b/src/pipedream/proxy/raw_client.py @@ -1,5 +1,6 @@ # This file was auto-generated by Fern from our API Definition. +import contextlib import typing from json.decoder import JSONDecodeError @@ -17,9 +18,11 @@ class RawProxyClient: + def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper + @contextlib.contextmanager def get( self, url_64: str, @@ -27,7 +30,8 @@ def get( external_user_id: str, account_id: str, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[ProxyResponse]: + ) -> typing.Iterator[HttpResponse[typing.Union[ProxyResponse, + typing.Iterator[bytes]]]]: """ Forward an authenticated GET request to an external API using an external user's account credentials @@ -43,50 +47,83 @@ def get( The account ID to use for authentication request_options : typing.Optional[RequestOptions] - Request-specific configuration. + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. Returns ------- - HttpResponse[ProxyResponse] + typing.Iterator[HttpResponse[typing.Union[ProxyResponse, typing.Iterator[bytes]]]] proxy request successful """ - _response = self._client_wrapper.httpx_client.request( - f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", - method="GET", - params={ - "external_user_id": external_user_id, - "account_id": account_id, - }, - request_options=request_options, - ) - try: - if _response is None or not _response.text.strip(): - return HttpResponse(response=_response, data=None) - if 200 <= _response.status_code < 300: - _data = typing.cast( - ProxyResponse, - parse_obj_as( - type_=ProxyResponse, # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 429: - raise TooManyRequestsError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - + with self._client_wrapper.httpx_client.stream( + f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", + method="GET", + params={ + "external_user_id": external_user_id, + "account_id": account_id, + }, + request_options=request_options, + ) as _response: + + def _handle_response() -> HttpResponse[typing.Union[ + ProxyResponse, typing.Iterator[bytes]]]: + try: + if 200 <= _response.status_code < 300: + content_type = _response.headers.get( + "content-type", "").lower() + is_json = "application/json" in content_type or not content_type + + if is_json: + _response.read() + if not _response.text.strip(): + return HttpResponse(response=_response, + data=None) + _data = typing.cast( + ProxyResponse, + parse_obj_as( + type_=ProxyResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + else: + _chunk_size = request_options.get( + "chunk_size", + None) if request_options is not None else None + return HttpResponse(response=_response, + data=_response.iter_bytes( + chunk_size=_chunk_size)) + _response.read() + _error_content_type = _response.headers.get( + "content-type", "").lower() + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[ + typing.Any], # type: ignore + object_=_response.json() + if "application/json" + in _error_content_type else _response.text, + ), + ), + ) + if "application/json" in _error_content_type: + _response_body = _response.json() + else: + _response_body = _response.text + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text) + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_body) + + yield _handle_response() + + @contextlib.contextmanager def post( self, url_64: str, @@ -95,7 +132,8 @@ def post( account_id: str, request: typing.Dict[str, typing.Optional[typing.Any]], request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[ProxyResponse]: + ) -> typing.Iterator[HttpResponse[typing.Union[ProxyResponse, + typing.Iterator[bytes]]]]: """ Forward an authenticated POST request to an external API using an external user's account credentials @@ -113,55 +151,88 @@ def post( request : typing.Dict[str, typing.Optional[typing.Any]] request_options : typing.Optional[RequestOptions] - Request-specific configuration. + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. Returns ------- - HttpResponse[ProxyResponse] + typing.Iterator[HttpResponse[typing.Union[ProxyResponse, typing.Iterator[bytes]]]] proxy request successful """ - _response = self._client_wrapper.httpx_client.request( - f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", - method="POST", - params={ - "external_user_id": external_user_id, - "account_id": account_id, - }, - json=request, - headers={ - "content-type": "application/json", - }, - request_options=request_options, - omit=OMIT, - ) - try: - if _response is None or not _response.text.strip(): - return HttpResponse(response=_response, data=None) - if 200 <= _response.status_code < 300: - _data = typing.cast( - ProxyResponse, - parse_obj_as( - type_=ProxyResponse, # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 429: - raise TooManyRequestsError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - + with self._client_wrapper.httpx_client.stream( + f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", + method="POST", + params={ + "external_user_id": external_user_id, + "account_id": account_id, + }, + json=request, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) as _response: + + def _handle_response() -> HttpResponse[typing.Union[ + ProxyResponse, typing.Iterator[bytes]]]: + try: + if 200 <= _response.status_code < 300: + content_type = _response.headers.get( + "content-type", "").lower() + is_json = "application/json" in content_type or not content_type + + if is_json: + _response.read() + if not _response.text.strip(): + return HttpResponse(response=_response, + data=None) + _data = typing.cast( + ProxyResponse, + parse_obj_as( + type_=ProxyResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + else: + _chunk_size = request_options.get( + "chunk_size", + None) if request_options is not None else None + return HttpResponse(response=_response, + data=_response.iter_bytes( + chunk_size=_chunk_size)) + _response.read() + _error_content_type = _response.headers.get( + "content-type", "").lower() + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[ + typing.Any], # type: ignore + object_=_response.json() + if "application/json" + in _error_content_type else _response.text, + ), + ), + ) + if "application/json" in _error_content_type: + _response_body = _response.json() + else: + _response_body = _response.text + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text) + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_body) + + yield _handle_response() + + @contextlib.contextmanager def put( self, url_64: str, @@ -170,7 +241,8 @@ def put( account_id: str, request: typing.Dict[str, typing.Optional[typing.Any]], request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[ProxyResponse]: + ) -> typing.Iterator[HttpResponse[typing.Union[ProxyResponse, + typing.Iterator[bytes]]]]: """ Forward an authenticated PUT request to an external API using an external user's account credentials @@ -188,55 +260,88 @@ def put( request : typing.Dict[str, typing.Optional[typing.Any]] request_options : typing.Optional[RequestOptions] - Request-specific configuration. + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. Returns ------- - HttpResponse[ProxyResponse] + typing.Iterator[HttpResponse[typing.Union[ProxyResponse, typing.Iterator[bytes]]]] proxy request successful """ - _response = self._client_wrapper.httpx_client.request( - f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", - method="PUT", - params={ - "external_user_id": external_user_id, - "account_id": account_id, - }, - json=request, - headers={ - "content-type": "application/json", - }, - request_options=request_options, - omit=OMIT, - ) - try: - if _response is None or not _response.text.strip(): - return HttpResponse(response=_response, data=None) - if 200 <= _response.status_code < 300: - _data = typing.cast( - ProxyResponse, - parse_obj_as( - type_=ProxyResponse, # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 429: - raise TooManyRequestsError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - + with self._client_wrapper.httpx_client.stream( + f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", + method="PUT", + params={ + "external_user_id": external_user_id, + "account_id": account_id, + }, + json=request, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) as _response: + + def _handle_response() -> HttpResponse[typing.Union[ + ProxyResponse, typing.Iterator[bytes]]]: + try: + if 200 <= _response.status_code < 300: + content_type = _response.headers.get( + "content-type", "").lower() + is_json = "application/json" in content_type or not content_type + + if is_json: + _response.read() + if not _response.text.strip(): + return HttpResponse(response=_response, + data=None) + _data = typing.cast( + ProxyResponse, + parse_obj_as( + type_=ProxyResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + else: + _chunk_size = request_options.get( + "chunk_size", + None) if request_options is not None else None + return HttpResponse(response=_response, + data=_response.iter_bytes( + chunk_size=_chunk_size)) + _response.read() + _error_content_type = _response.headers.get( + "content-type", "").lower() + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[ + typing.Any], # type: ignore + object_=_response.json() + if "application/json" + in _error_content_type else _response.text, + ), + ), + ) + if "application/json" in _error_content_type: + _response_body = _response.json() + else: + _response_body = _response.text + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text) + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_body) + + yield _handle_response() + + @contextlib.contextmanager def delete( self, url_64: str, @@ -244,7 +349,8 @@ def delete( external_user_id: str, account_id: str, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[ProxyResponse]: + ) -> typing.Iterator[HttpResponse[typing.Union[ProxyResponse, + typing.Iterator[bytes]]]]: """ Forward an authenticated DELETE request to an external API using an external user's account credentials @@ -260,50 +366,83 @@ def delete( The account ID to use for authentication request_options : typing.Optional[RequestOptions] - Request-specific configuration. + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. Returns ------- - HttpResponse[ProxyResponse] + typing.Iterator[HttpResponse[typing.Union[ProxyResponse, typing.Iterator[bytes]]]] proxy request successful """ - _response = self._client_wrapper.httpx_client.request( - f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", - method="DELETE", - params={ - "external_user_id": external_user_id, - "account_id": account_id, - }, - request_options=request_options, - ) - try: - if _response is None or not _response.text.strip(): - return HttpResponse(response=_response, data=None) - if 200 <= _response.status_code < 300: - _data = typing.cast( - ProxyResponse, - parse_obj_as( - type_=ProxyResponse, # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 429: - raise TooManyRequestsError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - + with self._client_wrapper.httpx_client.stream( + f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", + method="DELETE", + params={ + "external_user_id": external_user_id, + "account_id": account_id, + }, + request_options=request_options, + ) as _response: + + def _handle_response() -> HttpResponse[typing.Union[ + ProxyResponse, typing.Iterator[bytes]]]: + try: + if 200 <= _response.status_code < 300: + content_type = _response.headers.get( + "content-type", "").lower() + is_json = "application/json" in content_type or not content_type + + if is_json: + _response.read() + if not _response.text.strip(): + return HttpResponse(response=_response, + data=None) + _data = typing.cast( + ProxyResponse, + parse_obj_as( + type_=ProxyResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + else: + _chunk_size = request_options.get( + "chunk_size", + None) if request_options is not None else None + return HttpResponse(response=_response, + data=_response.iter_bytes( + chunk_size=_chunk_size)) + _response.read() + _error_content_type = _response.headers.get( + "content-type", "").lower() + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[ + typing.Any], # type: ignore + object_=_response.json() + if "application/json" + in _error_content_type else _response.text, + ), + ), + ) + if "application/json" in _error_content_type: + _response_body = _response.json() + else: + _response_body = _response.text + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text) + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_body) + + yield _handle_response() + + @contextlib.contextmanager def patch( self, url_64: str, @@ -312,7 +451,8 @@ def patch( account_id: str, request: typing.Dict[str, typing.Optional[typing.Any]], request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[ProxyResponse]: + ) -> typing.Iterator[HttpResponse[typing.Union[ProxyResponse, + typing.Iterator[bytes]]]]: """ Forward an authenticated PATCH request to an external API using an external user's account credentials @@ -330,60 +470,94 @@ def patch( request : typing.Dict[str, typing.Optional[typing.Any]] request_options : typing.Optional[RequestOptions] - Request-specific configuration. + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. Returns ------- - HttpResponse[ProxyResponse] + typing.Iterator[HttpResponse[typing.Union[ProxyResponse, typing.Iterator[bytes]]]] proxy request successful """ - _response = self._client_wrapper.httpx_client.request( - f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", - method="PATCH", - params={ - "external_user_id": external_user_id, - "account_id": account_id, - }, - json=request, - headers={ - "content-type": "application/json", - }, - request_options=request_options, - omit=OMIT, - ) - try: - if _response is None or not _response.text.strip(): - return HttpResponse(response=_response, data=None) - if 200 <= _response.status_code < 300: - _data = typing.cast( - ProxyResponse, - parse_obj_as( - type_=ProxyResponse, # type: ignore - object_=_response.json(), - ), - ) - return HttpResponse(response=_response, data=_data) - if _response.status_code == 429: - raise TooManyRequestsError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + with self._client_wrapper.httpx_client.stream( + f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", + method="PATCH", + params={ + "external_user_id": external_user_id, + "account_id": account_id, + }, + json=request, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) as _response: + + def _handle_response() -> HttpResponse[typing.Union[ + ProxyResponse, typing.Iterator[bytes]]]: + try: + if 200 <= _response.status_code < 300: + content_type = _response.headers.get( + "content-type", "").lower() + is_json = "application/json" in content_type or not content_type + + if is_json: + _response.read() + if not _response.text.strip(): + return HttpResponse(response=_response, + data=None) + _data = typing.cast( + ProxyResponse, + parse_obj_as( + type_=ProxyResponse, # type: ignore + object_=_response.json(), + ), + ) + return HttpResponse(response=_response, data=_data) + else: + _chunk_size = request_options.get( + "chunk_size", + None) if request_options is not None else None + return HttpResponse(response=_response, + data=_response.iter_bytes( + chunk_size=_chunk_size)) + _response.read() + _error_content_type = _response.headers.get( + "content-type", "").lower() + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[ + typing.Any], # type: ignore + object_=_response.json() + if "application/json" + in _error_content_type else _response.text, + ), + ), + ) + if "application/json" in _error_content_type: + _response_body = _response.json() + else: + _response_body = _response.text + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text) + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_body) + + yield _handle_response() class AsyncRawProxyClient: + def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper + @contextlib.asynccontextmanager async def get( self, url_64: str, @@ -391,7 +565,8 @@ async def get( external_user_id: str, account_id: str, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[ProxyResponse]: + ) -> typing.AsyncIterator[AsyncHttpResponse[typing.Union[ + ProxyResponse, typing.AsyncIterator[bytes]]]]: """ Forward an authenticated GET request to an external API using an external user's account credentials @@ -407,50 +582,85 @@ async def get( The account ID to use for authentication request_options : typing.Optional[RequestOptions] - Request-specific configuration. + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. Returns ------- - AsyncHttpResponse[ProxyResponse] + typing.AsyncIterator[AsyncHttpResponse[typing.Union[ProxyResponse, typing.AsyncIterator[bytes]]]] proxy request successful """ - _response = await self._client_wrapper.httpx_client.request( - f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", - method="GET", - params={ - "external_user_id": external_user_id, - "account_id": account_id, - }, - request_options=request_options, - ) - try: - if _response is None or not _response.text.strip(): - return AsyncHttpResponse(response=_response, data=None) - if 200 <= _response.status_code < 300: - _data = typing.cast( - ProxyResponse, - parse_obj_as( - type_=ProxyResponse, # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 429: - raise TooManyRequestsError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - + async with self._client_wrapper.httpx_client.stream( + f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", + method="GET", + params={ + "external_user_id": external_user_id, + "account_id": account_id, + }, + request_options=request_options, + ) as _response: + + async def _handle_response() -> AsyncHttpResponse[typing.Union[ + ProxyResponse, typing.AsyncIterator[bytes]]]: + try: + if 200 <= _response.status_code < 300: + content_type = _response.headers.get( + "content-type", "").lower() + is_json = "application/json" in content_type or not content_type + + if is_json: + await _response.aread() + if not _response.text.strip(): + return AsyncHttpResponse(response=_response, + data=None) + _data = typing.cast( + ProxyResponse, + parse_obj_as( + type_=ProxyResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, + data=_data) + else: + _chunk_size = request_options.get( + "chunk_size", + None) if request_options is not None else None + return AsyncHttpResponse( + response=_response, + data=_response.aiter_bytes( + chunk_size=_chunk_size)) + await _response.aread() + _error_content_type = _response.headers.get( + "content-type", "").lower() + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[ + typing.Any], # type: ignore + object_=_response.json() + if "application/json" + in _error_content_type else _response.text, + ), + ), + ) + if "application/json" in _error_content_type: + _response_body = _response.json() + else: + _response_body = _response.text + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text) + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_body) + + yield await _handle_response() + + @contextlib.asynccontextmanager async def post( self, url_64: str, @@ -459,7 +669,8 @@ async def post( account_id: str, request: typing.Dict[str, typing.Optional[typing.Any]], request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[ProxyResponse]: + ) -> typing.AsyncIterator[AsyncHttpResponse[typing.Union[ + ProxyResponse, typing.AsyncIterator[bytes]]]]: """ Forward an authenticated POST request to an external API using an external user's account credentials @@ -477,55 +688,90 @@ async def post( request : typing.Dict[str, typing.Optional[typing.Any]] request_options : typing.Optional[RequestOptions] - Request-specific configuration. + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. Returns ------- - AsyncHttpResponse[ProxyResponse] + typing.AsyncIterator[AsyncHttpResponse[typing.Union[ProxyResponse, typing.AsyncIterator[bytes]]]] proxy request successful """ - _response = await self._client_wrapper.httpx_client.request( - f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", - method="POST", - params={ - "external_user_id": external_user_id, - "account_id": account_id, - }, - json=request, - headers={ - "content-type": "application/json", - }, - request_options=request_options, - omit=OMIT, - ) - try: - if _response is None or not _response.text.strip(): - return AsyncHttpResponse(response=_response, data=None) - if 200 <= _response.status_code < 300: - _data = typing.cast( - ProxyResponse, - parse_obj_as( - type_=ProxyResponse, # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 429: - raise TooManyRequestsError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - + async with self._client_wrapper.httpx_client.stream( + f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", + method="POST", + params={ + "external_user_id": external_user_id, + "account_id": account_id, + }, + json=request, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) as _response: + + async def _handle_response() -> AsyncHttpResponse[typing.Union[ + ProxyResponse, typing.AsyncIterator[bytes]]]: + try: + if 200 <= _response.status_code < 300: + content_type = _response.headers.get( + "content-type", "").lower() + is_json = "application/json" in content_type or not content_type + + if is_json: + await _response.aread() + if not _response.text.strip(): + return AsyncHttpResponse(response=_response, + data=None) + _data = typing.cast( + ProxyResponse, + parse_obj_as( + type_=ProxyResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, + data=_data) + else: + _chunk_size = request_options.get( + "chunk_size", + None) if request_options is not None else None + return AsyncHttpResponse( + response=_response, + data=_response.aiter_bytes( + chunk_size=_chunk_size)) + await _response.aread() + _error_content_type = _response.headers.get( + "content-type", "").lower() + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[ + typing.Any], # type: ignore + object_=_response.json() + if "application/json" + in _error_content_type else _response.text, + ), + ), + ) + if "application/json" in _error_content_type: + _response_body = _response.json() + else: + _response_body = _response.text + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text) + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_body) + + yield await _handle_response() + + @contextlib.asynccontextmanager async def put( self, url_64: str, @@ -534,7 +780,8 @@ async def put( account_id: str, request: typing.Dict[str, typing.Optional[typing.Any]], request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[ProxyResponse]: + ) -> typing.AsyncIterator[AsyncHttpResponse[typing.Union[ + ProxyResponse, typing.AsyncIterator[bytes]]]]: """ Forward an authenticated PUT request to an external API using an external user's account credentials @@ -552,55 +799,90 @@ async def put( request : typing.Dict[str, typing.Optional[typing.Any]] request_options : typing.Optional[RequestOptions] - Request-specific configuration. + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. Returns ------- - AsyncHttpResponse[ProxyResponse] + typing.AsyncIterator[AsyncHttpResponse[typing.Union[ProxyResponse, typing.AsyncIterator[bytes]]]] proxy request successful """ - _response = await self._client_wrapper.httpx_client.request( - f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", - method="PUT", - params={ - "external_user_id": external_user_id, - "account_id": account_id, - }, - json=request, - headers={ - "content-type": "application/json", - }, - request_options=request_options, - omit=OMIT, - ) - try: - if _response is None or not _response.text.strip(): - return AsyncHttpResponse(response=_response, data=None) - if 200 <= _response.status_code < 300: - _data = typing.cast( - ProxyResponse, - parse_obj_as( - type_=ProxyResponse, # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 429: - raise TooManyRequestsError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - + async with self._client_wrapper.httpx_client.stream( + f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", + method="PUT", + params={ + "external_user_id": external_user_id, + "account_id": account_id, + }, + json=request, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) as _response: + + async def _handle_response() -> AsyncHttpResponse[typing.Union[ + ProxyResponse, typing.AsyncIterator[bytes]]]: + try: + if 200 <= _response.status_code < 300: + content_type = _response.headers.get( + "content-type", "").lower() + is_json = "application/json" in content_type or not content_type + + if is_json: + await _response.aread() + if not _response.text.strip(): + return AsyncHttpResponse(response=_response, + data=None) + _data = typing.cast( + ProxyResponse, + parse_obj_as( + type_=ProxyResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, + data=_data) + else: + _chunk_size = request_options.get( + "chunk_size", + None) if request_options is not None else None + return AsyncHttpResponse( + response=_response, + data=_response.aiter_bytes( + chunk_size=_chunk_size)) + await _response.aread() + _error_content_type = _response.headers.get( + "content-type", "").lower() + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[ + typing.Any], # type: ignore + object_=_response.json() + if "application/json" + in _error_content_type else _response.text, + ), + ), + ) + if "application/json" in _error_content_type: + _response_body = _response.json() + else: + _response_body = _response.text + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text) + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_body) + + yield await _handle_response() + + @contextlib.asynccontextmanager async def delete( self, url_64: str, @@ -608,7 +890,8 @@ async def delete( external_user_id: str, account_id: str, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[ProxyResponse]: + ) -> typing.AsyncIterator[AsyncHttpResponse[typing.Union[ + ProxyResponse, typing.AsyncIterator[bytes]]]]: """ Forward an authenticated DELETE request to an external API using an external user's account credentials @@ -624,50 +907,85 @@ async def delete( The account ID to use for authentication request_options : typing.Optional[RequestOptions] - Request-specific configuration. + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. Returns ------- - AsyncHttpResponse[ProxyResponse] + typing.AsyncIterator[AsyncHttpResponse[typing.Union[ProxyResponse, typing.AsyncIterator[bytes]]]] proxy request successful """ - _response = await self._client_wrapper.httpx_client.request( - f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", - method="DELETE", - params={ - "external_user_id": external_user_id, - "account_id": account_id, - }, - request_options=request_options, - ) - try: - if _response is None or not _response.text.strip(): - return AsyncHttpResponse(response=_response, data=None) - if 200 <= _response.status_code < 300: - _data = typing.cast( - ProxyResponse, - parse_obj_as( - type_=ProxyResponse, # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 429: - raise TooManyRequestsError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) - + async with self._client_wrapper.httpx_client.stream( + f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", + method="DELETE", + params={ + "external_user_id": external_user_id, + "account_id": account_id, + }, + request_options=request_options, + ) as _response: + + async def _handle_response() -> AsyncHttpResponse[typing.Union[ + ProxyResponse, typing.AsyncIterator[bytes]]]: + try: + if 200 <= _response.status_code < 300: + content_type = _response.headers.get( + "content-type", "").lower() + is_json = "application/json" in content_type or not content_type + + if is_json: + await _response.aread() + if not _response.text.strip(): + return AsyncHttpResponse(response=_response, + data=None) + _data = typing.cast( + ProxyResponse, + parse_obj_as( + type_=ProxyResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, + data=_data) + else: + _chunk_size = request_options.get( + "chunk_size", + None) if request_options is not None else None + return AsyncHttpResponse( + response=_response, + data=_response.aiter_bytes( + chunk_size=_chunk_size)) + await _response.aread() + _error_content_type = _response.headers.get( + "content-type", "").lower() + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[ + typing.Any], # type: ignore + object_=_response.json() + if "application/json" + in _error_content_type else _response.text, + ), + ), + ) + if "application/json" in _error_content_type: + _response_body = _response.json() + else: + _response_body = _response.text + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text) + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_body) + + yield await _handle_response() + + @contextlib.asynccontextmanager async def patch( self, url_64: str, @@ -676,7 +994,8 @@ async def patch( account_id: str, request: typing.Dict[str, typing.Optional[typing.Any]], request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[ProxyResponse]: + ) -> typing.AsyncIterator[AsyncHttpResponse[typing.Union[ + ProxyResponse, typing.AsyncIterator[bytes]]]]: """ Forward an authenticated PATCH request to an external API using an external user's account credentials @@ -694,51 +1013,85 @@ async def patch( request : typing.Dict[str, typing.Optional[typing.Any]] request_options : typing.Optional[RequestOptions] - Request-specific configuration. + Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response. Returns ------- - AsyncHttpResponse[ProxyResponse] + typing.AsyncIterator[AsyncHttpResponse[typing.Union[ProxyResponse, typing.AsyncIterator[bytes]]]] proxy request successful """ - _response = await self._client_wrapper.httpx_client.request( - f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", - method="PATCH", - params={ - "external_user_id": external_user_id, - "account_id": account_id, - }, - json=request, - headers={ - "content-type": "application/json", - }, - request_options=request_options, - omit=OMIT, - ) - try: - if _response is None or not _response.text.strip(): - return AsyncHttpResponse(response=_response, data=None) - if 200 <= _response.status_code < 300: - _data = typing.cast( - ProxyResponse, - parse_obj_as( - type_=ProxyResponse, # type: ignore - object_=_response.json(), - ), - ) - return AsyncHttpResponse(response=_response, data=_data) - if _response.status_code == 429: - raise TooManyRequestsError( - headers=dict(_response.headers), - body=typing.cast( - typing.Optional[typing.Any], - parse_obj_as( - type_=typing.Optional[typing.Any], # type: ignore - object_=_response.json(), - ), - ), - ) - _response_json = _response.json() - except JSONDecodeError: - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text) - raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json) + async with self._client_wrapper.httpx_client.stream( + f"v1/connect/{jsonable_encoder(self._client_wrapper._project_id)}/proxy/{jsonable_encoder(url_64)}", + method="PATCH", + params={ + "external_user_id": external_user_id, + "account_id": account_id, + }, + json=request, + headers={ + "content-type": "application/json", + }, + request_options=request_options, + omit=OMIT, + ) as _response: + + async def _handle_response() -> AsyncHttpResponse[typing.Union[ + ProxyResponse, typing.AsyncIterator[bytes]]]: + try: + if 200 <= _response.status_code < 300: + content_type = _response.headers.get( + "content-type", "").lower() + is_json = "application/json" in content_type or not content_type + + if is_json: + await _response.aread() + if not _response.text.strip(): + return AsyncHttpResponse(response=_response, + data=None) + _data = typing.cast( + ProxyResponse, + parse_obj_as( + type_=ProxyResponse, # type: ignore + object_=_response.json(), + ), + ) + return AsyncHttpResponse(response=_response, + data=_data) + else: + _chunk_size = request_options.get( + "chunk_size", + None) if request_options is not None else None + return AsyncHttpResponse( + response=_response, + data=_response.aiter_bytes( + chunk_size=_chunk_size)) + await _response.aread() + _error_content_type = _response.headers.get( + "content-type", "").lower() + if _response.status_code == 429: + raise TooManyRequestsError( + headers=dict(_response.headers), + body=typing.cast( + typing.Optional[typing.Any], + parse_obj_as( + type_=typing.Optional[ + typing.Any], # type: ignore + object_=_response.json() + if "application/json" + in _error_content_type else _response.text, + ), + ), + ) + if "application/json" in _error_content_type: + _response_body = _response.json() + else: + _response_body = _response.text + except JSONDecodeError: + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response.text) + raise ApiError(status_code=_response.status_code, + headers=dict(_response.headers), + body=_response_body) + + yield await _handle_response() diff --git a/src/pipedream/tokens/client.py b/src/pipedream/tokens/client.py index f37eccf..cbe1c64 100644 --- a/src/pipedream/tokens/client.py +++ b/src/pipedream/tokens/client.py @@ -132,7 +132,6 @@ def validate( client.tokens.validate( ctok="ctok", app_id="app_id", - oauth_app_id="oauth_app_id", ) """ _response = self._raw_client.validate( @@ -273,7 +272,6 @@ async def main() -> None: await client.tokens.validate( ctok="ctok", app_id="app_id", - oauth_app_id="oauth_app_id", ) diff --git a/src/pipedream/triggers/client.py b/src/pipedream/triggers/client.py index 85a6646..17e518e 100644 --- a/src/pipedream/triggers/client.py +++ b/src/pipedream/triggers/client.py @@ -79,13 +79,7 @@ def list( client_id="YOUR_CLIENT_ID", client_secret="YOUR_CLIENT_SECRET", ) - response = client.triggers.list( - after="after", - before="before", - limit=1, - q="q", - app="app", - ) + response = client.triggers.list() for item in response: yield item # alternatively, you can paginate page-by-page @@ -305,6 +299,7 @@ def deploy( dynamic_props_id: typing.Optional[str] = OMIT, workflow_id: typing.Optional[str] = OMIT, webhook_url: typing.Optional[str] = OMIT, + emit_on_deploy: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Emitter: """ @@ -332,6 +327,9 @@ def deploy( webhook_url : typing.Optional[str] Optional webhook URL to receive trigger events + emit_on_deploy : typing.Optional[bool] + Whether the trigger should emit events during the deploy hook execution. Defaults to true if not specified. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -363,6 +361,7 @@ def deploy( dynamic_props_id=dynamic_props_id, workflow_id=workflow_id, webhook_url=webhook_url, + emit_on_deploy=emit_on_deploy, request_options=request_options, ) return _response.data @@ -436,13 +435,7 @@ async def list( async def main() -> None: - response = await client.triggers.list( - after="after", - before="before", - limit=1, - q="q", - app="app", - ) + response = await client.triggers.list() async for item in response: yield item @@ -690,6 +683,7 @@ async def deploy( dynamic_props_id: typing.Optional[str] = OMIT, workflow_id: typing.Optional[str] = OMIT, webhook_url: typing.Optional[str] = OMIT, + emit_on_deploy: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> Emitter: """ @@ -717,6 +711,9 @@ async def deploy( webhook_url : typing.Optional[str] Optional webhook URL to receive trigger events + emit_on_deploy : typing.Optional[bool] + Whether the trigger should emit events during the deploy hook execution. Defaults to true if not specified. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -756,6 +753,7 @@ async def main() -> None: dynamic_props_id=dynamic_props_id, workflow_id=workflow_id, webhook_url=webhook_url, + emit_on_deploy=emit_on_deploy, request_options=request_options, ) return _response.data diff --git a/src/pipedream/triggers/raw_client.py b/src/pipedream/triggers/raw_client.py index 0d5da95..93ac6c6 100644 --- a/src/pipedream/triggers/raw_client.py +++ b/src/pipedream/triggers/raw_client.py @@ -384,6 +384,7 @@ def deploy( dynamic_props_id: typing.Optional[str] = OMIT, workflow_id: typing.Optional[str] = OMIT, webhook_url: typing.Optional[str] = OMIT, + emit_on_deploy: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[Emitter]: """ @@ -411,6 +412,9 @@ def deploy( webhook_url : typing.Optional[str] Optional webhook URL to receive trigger events + emit_on_deploy : typing.Optional[bool] + Whether the trigger should emit events during the deploy hook execution. Defaults to true if not specified. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -432,6 +436,7 @@ def deploy( "dynamic_props_id": dynamic_props_id, "workflow_id": workflow_id, "webhook_url": webhook_url, + "emit_on_deploy": emit_on_deploy, }, headers={ "content-type": "application/json", @@ -829,6 +834,7 @@ async def deploy( dynamic_props_id: typing.Optional[str] = OMIT, workflow_id: typing.Optional[str] = OMIT, webhook_url: typing.Optional[str] = OMIT, + emit_on_deploy: typing.Optional[bool] = OMIT, request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[Emitter]: """ @@ -856,6 +862,9 @@ async def deploy( webhook_url : typing.Optional[str] Optional webhook URL to receive trigger events + emit_on_deploy : typing.Optional[bool] + Whether the trigger should emit events during the deploy hook execution. Defaults to true if not specified. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -877,6 +886,7 @@ async def deploy( "dynamic_props_id": dynamic_props_id, "workflow_id": workflow_id, "webhook_url": webhook_url, + "emit_on_deploy": emit_on_deploy, }, headers={ "content-type": "application/json", diff --git a/src/pipedream/types/__init__.py b/src/pipedream/types/__init__.py index 1484a49..6063ee7 100644 --- a/src/pipedream/types/__init__.py +++ b/src/pipedream/types/__init__.py @@ -102,6 +102,7 @@ from .prop_option_nested import PropOptionNested from .prop_option_value import PropOptionValue from .proxy_response import ProxyResponse + from .proxy_response_binary import ProxyResponseBinary from .reload_props_opts import ReloadPropsOpts from .reload_props_response import ReloadPropsResponse from .run_action_opts_stash_id import RunActionOptsStashId @@ -214,6 +215,7 @@ "PropOptionNested": ".prop_option_nested", "PropOptionValue": ".prop_option_value", "ProxyResponse": ".proxy_response", + "ProxyResponseBinary": ".proxy_response_binary", "ReloadPropsOpts": ".reload_props_opts", "ReloadPropsResponse": ".reload_props_response", "RunActionOptsStashId": ".run_action_opts_stash_id", @@ -350,6 +352,7 @@ def __dir__(): "PropOptionNested", "PropOptionValue", "ProxyResponse", + "ProxyResponseBinary", "ReloadPropsOpts", "ReloadPropsResponse", "RunActionOptsStashId", diff --git a/src/pipedream/types/deployed_component.py b/src/pipedream/types/deployed_component.py index 39ba6c2..b628be7 100644 --- a/src/pipedream/types/deployed_component.py +++ b/src/pipedream/types/deployed_component.py @@ -69,6 +69,11 @@ class DeployedComponent(UniversalBaseModel): Callback observations for the deployed component """ + emit_on_deploy: typing.Optional[bool] = pydantic.Field(default=None) + """ + Whether the trigger emits events during the deploy hook execution. When false, the $emit function is disabled during deploy hook execution. Defaults to true. + """ + if IS_PYDANTIC_V2: model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 else: diff --git a/src/pipedream/types/emitter.py b/src/pipedream/types/emitter.py index cd4962f..9f1c407 100644 --- a/src/pipedream/types/emitter.py +++ b/src/pipedream/types/emitter.py @@ -28,6 +28,7 @@ class Emitter_DeployedComponent(UniversalBaseModel): name: str name_slug: str callback_observations: typing.Optional[typing.Optional[typing.Any]] = None + emit_on_deploy: typing.Optional[bool] = 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/proxy_response_binary.py b/src/pipedream/types/proxy_response_binary.py new file mode 100644 index 0000000..e799429 --- /dev/null +++ b/src/pipedream/types/proxy_response_binary.py @@ -0,0 +1,3 @@ +# This file was auto-generated by Fern from our API Definition. + +ProxyResponseBinary = str