diff --git a/pyproject.toml b/pyproject.toml index 1c46323..c93c57d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "pipedream" [tool.poetry] name = "pipedream" -version = "1.0.10" +version = "1.0.11" description = "" readme = "README.md" authors = [] diff --git a/src/pipedream/client.py b/src/pipedream/client.py index 6f4accc..cfb7782 100644 --- a/src/pipedream/client.py +++ b/src/pipedream/client.py @@ -6,7 +6,7 @@ import typing import httpx -from .types.project_environment import ProjectEnvironment +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 diff --git a/src/pipedream/core/client_wrapper.py b/src/pipedream/core/client_wrapper.py index f05bb5d..4612be5 100644 --- a/src/pipedream/core/client_wrapper.py +++ b/src/pipedream/core/client_wrapper.py @@ -3,7 +3,7 @@ import typing import httpx -from ..types.project_environment import ProjectEnvironment +from .._.types.project_environment import ProjectEnvironment from .http_client import AsyncHttpClient, HttpClient @@ -27,10 +27,10 @@ def __init__( def get_headers(self) -> typing.Dict[str, str]: headers: typing.Dict[str, str] = { - "User-Agent": "pipedream/1.0.10", + "User-Agent": "pipedream/1.0.11", "X-Fern-Language": "Python", "X-Fern-SDK-Name": "pipedream", - "X-Fern-SDK-Version": "1.0.10", + "X-Fern-SDK-Version": "1.0.11", **(self.get_custom_headers() or {}), } if self._project_environment is not None: diff --git a/src/pipedream/core/http_sse/_api.py b/src/pipedream/core/http_sse/_api.py deleted file mode 100644 index f900b3b..0000000 --- a/src/pipedream/core/http_sse/_api.py +++ /dev/null @@ -1,112 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import re -from contextlib import asynccontextmanager, contextmanager -from typing import Any, AsyncGenerator, AsyncIterator, Iterator, cast - -import httpx -from ._decoders import SSEDecoder -from ._exceptions import SSEError -from ._models import ServerSentEvent - - -class EventSource: - def __init__(self, response: httpx.Response) -> None: - self._response = response - - def _check_content_type(self) -> None: - content_type = self._response.headers.get("content-type", "").partition(";")[0] - if "text/event-stream" not in content_type: - raise SSEError( - f"Expected response header Content-Type to contain 'text/event-stream', got {content_type!r}" - ) - - def _get_charset(self) -> str: - """Extract charset from Content-Type header, fallback to UTF-8.""" - content_type = self._response.headers.get("content-type", "") - - # Parse charset parameter using regex - charset_match = re.search(r"charset=([^;\s]+)", content_type, re.IGNORECASE) - if charset_match: - charset = charset_match.group(1).strip("\"'") - # Validate that it's a known encoding - try: - # Test if the charset is valid by trying to encode/decode - "test".encode(charset).decode(charset) - return charset - except (LookupError, UnicodeError): - # If charset is invalid, fall back to UTF-8 - pass - - # Default to UTF-8 if no charset specified or invalid charset - return "utf-8" - - @property - def response(self) -> httpx.Response: - return self._response - - def iter_sse(self) -> Iterator[ServerSentEvent]: - self._check_content_type() - decoder = SSEDecoder() - charset = self._get_charset() - - buffer = "" - for chunk in self._response.iter_bytes(): - # Decode chunk using detected charset - text_chunk = chunk.decode(charset, errors="replace") - buffer += text_chunk - - # Process complete lines - while "\n" in buffer: - line, buffer = buffer.split("\n", 1) - line = line.rstrip("\r") - sse = decoder.decode(line) - # when we reach a "\n\n" => line = '' - # => decoder will attempt to return an SSE Event - if sse is not None: - yield sse - - # Process any remaining data in buffer - if buffer.strip(): - line = buffer.rstrip("\r") - sse = decoder.decode(line) - if sse is not None: - yield sse - - async def aiter_sse(self) -> AsyncGenerator[ServerSentEvent, None]: - self._check_content_type() - decoder = SSEDecoder() - lines = cast(AsyncGenerator[str, None], self._response.aiter_lines()) - try: - async for line in lines: - line = line.rstrip("\n") - sse = decoder.decode(line) - if sse is not None: - yield sse - finally: - await lines.aclose() - - -@contextmanager -def connect_sse(client: httpx.Client, method: str, url: str, **kwargs: Any) -> Iterator[EventSource]: - headers = kwargs.pop("headers", {}) - headers["Accept"] = "text/event-stream" - headers["Cache-Control"] = "no-store" - - with client.stream(method, url, headers=headers, **kwargs) as response: - yield EventSource(response) - - -@asynccontextmanager -async def aconnect_sse( - client: httpx.AsyncClient, - method: str, - url: str, - **kwargs: Any, -) -> AsyncIterator[EventSource]: - headers = kwargs.pop("headers", {}) - headers["Accept"] = "text/event-stream" - headers["Cache-Control"] = "no-store" - - async with client.stream(method, url, headers=headers, **kwargs) as response: - yield EventSource(response) diff --git a/src/pipedream/core/http_sse/_decoders.py b/src/pipedream/core/http_sse/_decoders.py deleted file mode 100644 index 339b089..0000000 --- a/src/pipedream/core/http_sse/_decoders.py +++ /dev/null @@ -1,61 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -from typing import List, Optional - -from ._models import ServerSentEvent - - -class SSEDecoder: - def __init__(self) -> None: - self._event = "" - self._data: List[str] = [] - self._last_event_id = "" - self._retry: Optional[int] = None - - def decode(self, line: str) -> Optional[ServerSentEvent]: - # See: https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation # noqa: E501 - - if not line: - if not self._event and not self._data and not self._last_event_id and self._retry is None: - return None - - sse = ServerSentEvent( - event=self._event, - data="\n".join(self._data), - id=self._last_event_id, - retry=self._retry, - ) - - # NOTE: as per the SSE spec, do not reset last_event_id. - self._event = "" - self._data = [] - self._retry = None - - return sse - - if line.startswith(":"): - return None - - fieldname, _, value = line.partition(":") - - if value.startswith(" "): - value = value[1:] - - if fieldname == "event": - self._event = value - elif fieldname == "data": - self._data.append(value) - elif fieldname == "id": - if "\0" in value: - pass - else: - self._last_event_id = value - elif fieldname == "retry": - try: - self._retry = int(value) - except (TypeError, ValueError): - pass - else: - pass # Field is ignored. - - return None diff --git a/src/pipedream/core/http_sse/_exceptions.py b/src/pipedream/core/http_sse/_exceptions.py deleted file mode 100644 index 81605a8..0000000 --- a/src/pipedream/core/http_sse/_exceptions.py +++ /dev/null @@ -1,7 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import httpx - - -class SSEError(httpx.TransportError): - pass diff --git a/src/pipedream/core/http_sse/_models.py b/src/pipedream/core/http_sse/_models.py deleted file mode 100644 index 1af57f8..0000000 --- a/src/pipedream/core/http_sse/_models.py +++ /dev/null @@ -1,17 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import json -from dataclasses import dataclass -from typing import Any, Optional - - -@dataclass(frozen=True) -class ServerSentEvent: - event: str = "message" - data: str = "" - id: str = "" - retry: Optional[int] = None - - def json(self) -> Any: - """Parse the data field as JSON.""" - return json.loads(self.data) diff --git a/src/pipedream/deployed_triggers/__init__.py b/src/pipedream/deployed_triggers/__init__.py index 5cde020..ea68d27 100644 --- a/src/pipedream/deployed_triggers/__init__.py +++ b/src/pipedream/deployed_triggers/__init__.py @@ -2,3 +2,33 @@ # isort: skip_file +import typing +from importlib import import_module + +if typing.TYPE_CHECKING: + from .types import DeployedTriggersListRequestEmitterType +_dynamic_imports: typing.Dict[str, str] = {"DeployedTriggersListRequestEmitterType": ".types"} + + +def __getattr__(attr_name: str) -> typing.Any: + module_name = _dynamic_imports.get(attr_name) + if module_name is None: + raise AttributeError(f"No {attr_name} found in _dynamic_imports for module name -> {__name__}") + try: + module = import_module(module_name, __package__) + if module_name == f".{attr_name}": + return module + else: + return getattr(module, attr_name) + except ImportError as e: + raise ImportError(f"Failed to import {attr_name} from {module_name}: {e}") from e + except AttributeError as e: + raise AttributeError(f"Failed to get {attr_name} from {module_name}: {e}") from e + + +def __dir__(): + lazy_attrs = list(_dynamic_imports.keys()) + return sorted(lazy_attrs) + + +__all__ = ["DeployedTriggersListRequestEmitterType"] diff --git a/src/pipedream/deployed_triggers/client.py b/src/pipedream/deployed_triggers/client.py index 2a9e05e..8ebd853 100644 --- a/src/pipedream/deployed_triggers/client.py +++ b/src/pipedream/deployed_triggers/client.py @@ -6,12 +6,12 @@ from ..core.pagination import AsyncPager, SyncPager from ..core.request_options import RequestOptions from ..types.configured_props import ConfiguredProps -from ..types.deployed_component import DeployedComponent from ..types.emitted_event import EmittedEvent -from ..types.get_trigger_response_data import GetTriggerResponseData +from ..types.emitter import Emitter from ..types.get_trigger_webhooks_response import GetTriggerWebhooksResponse from ..types.get_trigger_workflows_response import GetTriggerWorkflowsResponse from .raw_client import AsyncRawDeployedTriggersClient, RawDeployedTriggersClient +from .types.deployed_triggers_list_request_emitter_type import DeployedTriggersListRequestEmitterType # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -39,8 +39,9 @@ def list( after: typing.Optional[str] = None, before: typing.Optional[str] = None, limit: typing.Optional[int] = None, + emitter_type: typing.Optional[DeployedTriggersListRequestEmitterType] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> SyncPager[DeployedComponent]: + ) -> SyncPager[Emitter]: """ Retrieve all deployed triggers for a specific external user @@ -58,12 +59,15 @@ def list( limit : typing.Optional[int] The maximum number of results to return + emitter_type : typing.Optional[DeployedTriggersListRequestEmitterType] + Filter deployed triggers by emitter type (defaults to 'source' if not provided) + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - SyncPager[DeployedComponent] + SyncPager[Emitter] deployed triggers listed Examples @@ -81,6 +85,7 @@ def list( before="before", limit=1, external_user_id="external_user_id", + emitter_type="source", ) for item in response: yield item @@ -89,12 +94,17 @@ def list( yield page """ return self._raw_client.list( - external_user_id=external_user_id, after=after, before=before, limit=limit, request_options=request_options + external_user_id=external_user_id, + after=after, + before=before, + limit=limit, + emitter_type=emitter_type, + request_options=request_options, ) def retrieve( self, trigger_id: str, *, external_user_id: str, request_options: typing.Optional[RequestOptions] = None - ) -> GetTriggerResponseData: + ) -> Emitter: """ Get details of a specific deployed trigger by its ID @@ -110,7 +120,7 @@ def retrieve( Returns ------- - GetTriggerResponseData + Emitter deployed trigger retrieved Examples @@ -142,7 +152,7 @@ def update( configured_props: typing.Optional[ConfiguredProps] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> GetTriggerResponseData: + ) -> Emitter: """ Modify the configuration of a deployed trigger, including active status @@ -166,7 +176,7 @@ def update( Returns ------- - GetTriggerResponseData + Emitter deployed trigger updated Examples @@ -501,8 +511,9 @@ async def list( after: typing.Optional[str] = None, before: typing.Optional[str] = None, limit: typing.Optional[int] = None, + emitter_type: typing.Optional[DeployedTriggersListRequestEmitterType] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncPager[DeployedComponent]: + ) -> AsyncPager[Emitter]: """ Retrieve all deployed triggers for a specific external user @@ -520,12 +531,15 @@ async def list( limit : typing.Optional[int] The maximum number of results to return + emitter_type : typing.Optional[DeployedTriggersListRequestEmitterType] + Filter deployed triggers by emitter type (defaults to 'source' if not provided) + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncPager[DeployedComponent] + AsyncPager[Emitter] deployed triggers listed Examples @@ -548,6 +562,7 @@ async def main() -> None: before="before", limit=1, external_user_id="external_user_id", + emitter_type="source", ) async for item in response: yield item @@ -560,12 +575,17 @@ async def main() -> None: asyncio.run(main()) """ return await self._raw_client.list( - external_user_id=external_user_id, after=after, before=before, limit=limit, request_options=request_options + external_user_id=external_user_id, + after=after, + before=before, + limit=limit, + emitter_type=emitter_type, + request_options=request_options, ) async def retrieve( self, trigger_id: str, *, external_user_id: str, request_options: typing.Optional[RequestOptions] = None - ) -> GetTriggerResponseData: + ) -> Emitter: """ Get details of a specific deployed trigger by its ID @@ -581,7 +601,7 @@ async def retrieve( Returns ------- - GetTriggerResponseData + Emitter deployed trigger retrieved Examples @@ -621,7 +641,7 @@ async def update( configured_props: typing.Optional[ConfiguredProps] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> GetTriggerResponseData: + ) -> Emitter: """ Modify the configuration of a deployed trigger, including active status @@ -645,7 +665,7 @@ async def update( Returns ------- - GetTriggerResponseData + Emitter deployed trigger updated Examples diff --git a/src/pipedream/deployed_triggers/raw_client.py b/src/pipedream/deployed_triggers/raw_client.py index 36e78ac..633899f 100644 --- a/src/pipedream/deployed_triggers/raw_client.py +++ b/src/pipedream/deployed_triggers/raw_client.py @@ -13,14 +13,14 @@ from ..core.serialization import convert_and_respect_annotation_metadata from ..errors.too_many_requests_error import TooManyRequestsError from ..types.configured_props import ConfiguredProps -from ..types.deployed_component import DeployedComponent from ..types.emitted_event import EmittedEvent +from ..types.emitter import Emitter from ..types.get_trigger_events_response import GetTriggerEventsResponse from ..types.get_trigger_response import GetTriggerResponse -from ..types.get_trigger_response_data import GetTriggerResponseData from ..types.get_trigger_webhooks_response import GetTriggerWebhooksResponse from ..types.get_trigger_workflows_response import GetTriggerWorkflowsResponse from ..types.get_triggers_response import GetTriggersResponse +from .types.deployed_triggers_list_request_emitter_type import DeployedTriggersListRequestEmitterType # this is used as the default value for optional parameters OMIT = typing.cast(typing.Any, ...) @@ -37,8 +37,9 @@ def list( after: typing.Optional[str] = None, before: typing.Optional[str] = None, limit: typing.Optional[int] = None, + emitter_type: typing.Optional[DeployedTriggersListRequestEmitterType] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> SyncPager[DeployedComponent]: + ) -> SyncPager[Emitter]: """ Retrieve all deployed triggers for a specific external user @@ -56,12 +57,15 @@ def list( limit : typing.Optional[int] The maximum number of results to return + emitter_type : typing.Optional[DeployedTriggersListRequestEmitterType] + Filter deployed triggers by emitter type (defaults to 'source' if not provided) + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - SyncPager[DeployedComponent] + SyncPager[Emitter] deployed triggers listed """ _response = self._client_wrapper.httpx_client.request( @@ -72,6 +76,7 @@ def list( "before": before, "limit": limit, "external_user_id": external_user_id, + "emitter_type": emitter_type, }, request_options=request_options, ) @@ -95,6 +100,7 @@ def list( after=_parsed_next, before=before, limit=limit, + emitter_type=emitter_type, request_options=request_options, ) return SyncPager( @@ -118,7 +124,7 @@ def list( def retrieve( self, trigger_id: str, *, external_user_id: str, request_options: typing.Optional[RequestOptions] = None - ) -> HttpResponse[GetTriggerResponseData]: + ) -> HttpResponse[Emitter]: """ Get details of a specific deployed trigger by its ID @@ -134,7 +140,7 @@ def retrieve( Returns ------- - HttpResponse[GetTriggerResponseData] + HttpResponse[Emitter] deployed trigger retrieved """ _response = self._client_wrapper.httpx_client.request( @@ -181,7 +187,7 @@ def update( configured_props: typing.Optional[ConfiguredProps] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[GetTriggerResponseData]: + ) -> HttpResponse[Emitter]: """ Modify the configuration of a deployed trigger, including active status @@ -205,7 +211,7 @@ def update( Returns ------- - HttpResponse[GetTriggerResponseData] + HttpResponse[Emitter] deployed trigger updated """ _response = self._client_wrapper.httpx_client.request( @@ -637,8 +643,9 @@ async def list( after: typing.Optional[str] = None, before: typing.Optional[str] = None, limit: typing.Optional[int] = None, + emitter_type: typing.Optional[DeployedTriggersListRequestEmitterType] = None, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncPager[DeployedComponent]: + ) -> AsyncPager[Emitter]: """ Retrieve all deployed triggers for a specific external user @@ -656,12 +663,15 @@ async def list( limit : typing.Optional[int] The maximum number of results to return + emitter_type : typing.Optional[DeployedTriggersListRequestEmitterType] + Filter deployed triggers by emitter type (defaults to 'source' if not provided) + request_options : typing.Optional[RequestOptions] Request-specific configuration. Returns ------- - AsyncPager[DeployedComponent] + AsyncPager[Emitter] deployed triggers listed """ _response = await self._client_wrapper.httpx_client.request( @@ -672,6 +682,7 @@ async def list( "before": before, "limit": limit, "external_user_id": external_user_id, + "emitter_type": emitter_type, }, request_options=request_options, ) @@ -697,6 +708,7 @@ async def _get_next(): after=_parsed_next, before=before, limit=limit, + emitter_type=emitter_type, request_options=request_options, ) @@ -721,7 +733,7 @@ async def _get_next(): async def retrieve( self, trigger_id: str, *, external_user_id: str, request_options: typing.Optional[RequestOptions] = None - ) -> AsyncHttpResponse[GetTriggerResponseData]: + ) -> AsyncHttpResponse[Emitter]: """ Get details of a specific deployed trigger by its ID @@ -737,7 +749,7 @@ async def retrieve( Returns ------- - AsyncHttpResponse[GetTriggerResponseData] + AsyncHttpResponse[Emitter] deployed trigger retrieved """ _response = await self._client_wrapper.httpx_client.request( @@ -784,7 +796,7 @@ async def update( configured_props: typing.Optional[ConfiguredProps] = OMIT, name: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[GetTriggerResponseData]: + ) -> AsyncHttpResponse[Emitter]: """ Modify the configuration of a deployed trigger, including active status @@ -808,7 +820,7 @@ async def update( Returns ------- - AsyncHttpResponse[GetTriggerResponseData] + AsyncHttpResponse[Emitter] deployed trigger updated """ _response = await self._client_wrapper.httpx_client.request( diff --git a/src/pipedream/core/http_sse/__init__.py b/src/pipedream/deployed_triggers/types/__init__.py similarity index 71% rename from src/pipedream/core/http_sse/__init__.py rename to src/pipedream/deployed_triggers/types/__init__.py index 730e5a3..6846d0c 100644 --- a/src/pipedream/core/http_sse/__init__.py +++ b/src/pipedream/deployed_triggers/types/__init__.py @@ -6,15 +6,9 @@ from importlib import import_module if typing.TYPE_CHECKING: - from ._api import EventSource, aconnect_sse, connect_sse - from ._exceptions import SSEError - from ._models import ServerSentEvent + from .deployed_triggers_list_request_emitter_type import DeployedTriggersListRequestEmitterType _dynamic_imports: typing.Dict[str, str] = { - "EventSource": "._api", - "SSEError": "._exceptions", - "ServerSentEvent": "._models", - "aconnect_sse": "._api", - "connect_sse": "._api", + "DeployedTriggersListRequestEmitterType": ".deployed_triggers_list_request_emitter_type" } @@ -39,4 +33,4 @@ def __dir__(): return sorted(lazy_attrs) -__all__ = ["EventSource", "SSEError", "ServerSentEvent", "aconnect_sse", "connect_sse"] +__all__ = ["DeployedTriggersListRequestEmitterType"] diff --git a/src/pipedream/deployed_triggers/types/deployed_triggers_list_request_emitter_type.py b/src/pipedream/deployed_triggers/types/deployed_triggers_list_request_emitter_type.py new file mode 100644 index 0000000..ba302e0 --- /dev/null +++ b/src/pipedream/deployed_triggers/types/deployed_triggers_list_request_emitter_type.py @@ -0,0 +1,5 @@ +# This file was auto-generated by Fern from our API Definition. + +import typing + +DeployedTriggersListRequestEmitterType = typing.Union[typing.Literal["source", "timer", "http", "email"], typing.Any] diff --git a/src/pipedream/oauth_tokens/client.py b/src/pipedream/oauth_tokens/client.py index 18a5de5..3dca46c 100644 --- a/src/pipedream/oauth_tokens/client.py +++ b/src/pipedream/oauth_tokens/client.py @@ -27,7 +27,12 @@ def with_raw_response(self) -> RawOauthTokensClient: return self._raw_client def create( - self, *, client_id: str, client_secret: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + client_id: str, + client_secret: str, + scope: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> CreateOAuthTokenResponse: """ Exchange OAuth credentials for an access token @@ -38,6 +43,9 @@ def create( client_secret : str + scope : typing.Optional[str] + Optional space-separated scopes for the access token. Defaults to '*'. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -62,7 +70,7 @@ def create( ) """ _response = self._raw_client.create( - client_id=client_id, client_secret=client_secret, request_options=request_options + client_id=client_id, client_secret=client_secret, scope=scope, request_options=request_options ) return _response.data @@ -83,7 +91,12 @@ def with_raw_response(self) -> AsyncRawOauthTokensClient: return self._raw_client async def create( - self, *, client_id: str, client_secret: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + client_id: str, + client_secret: str, + scope: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> CreateOAuthTokenResponse: """ Exchange OAuth credentials for an access token @@ -94,6 +107,9 @@ async def create( client_secret : str + scope : typing.Optional[str] + Optional space-separated scopes for the access token. Defaults to '*'. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -126,6 +142,6 @@ async def main() -> None: asyncio.run(main()) """ _response = await self._raw_client.create( - client_id=client_id, client_secret=client_secret, request_options=request_options + client_id=client_id, client_secret=client_secret, scope=scope, request_options=request_options ) return _response.data diff --git a/src/pipedream/oauth_tokens/raw_client.py b/src/pipedream/oauth_tokens/raw_client.py index 8fc2cb4..30fa1b7 100644 --- a/src/pipedream/oauth_tokens/raw_client.py +++ b/src/pipedream/oauth_tokens/raw_client.py @@ -19,7 +19,12 @@ def __init__(self, *, client_wrapper: SyncClientWrapper): self._client_wrapper = client_wrapper def create( - self, *, client_id: str, client_secret: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + client_id: str, + client_secret: str, + scope: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> HttpResponse[CreateOAuthTokenResponse]: """ Exchange OAuth credentials for an access token @@ -30,6 +35,9 @@ def create( client_secret : str + scope : typing.Optional[str] + Optional space-separated scopes for the access token. Defaults to '*'. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -44,6 +52,7 @@ def create( json={ "client_id": client_id, "client_secret": client_secret, + "scope": scope, "grant_type": "client_credentials", }, headers={ @@ -73,7 +82,12 @@ def __init__(self, *, client_wrapper: AsyncClientWrapper): self._client_wrapper = client_wrapper async def create( - self, *, client_id: str, client_secret: str, request_options: typing.Optional[RequestOptions] = None + self, + *, + client_id: str, + client_secret: str, + scope: typing.Optional[str] = OMIT, + request_options: typing.Optional[RequestOptions] = None, ) -> AsyncHttpResponse[CreateOAuthTokenResponse]: """ Exchange OAuth credentials for an access token @@ -84,6 +98,9 @@ async def create( client_secret : str + scope : typing.Optional[str] + Optional space-separated scopes for the access token. Defaults to '*'. + request_options : typing.Optional[RequestOptions] Request-specific configuration. @@ -98,6 +115,7 @@ async def create( json={ "client_id": client_id, "client_secret": client_secret, + "scope": scope, "grant_type": "client_credentials", }, headers={ diff --git a/src/pipedream/triggers/client.py b/src/pipedream/triggers/client.py index faf4a2a..ce49049 100644 --- a/src/pipedream/triggers/client.py +++ b/src/pipedream/triggers/client.py @@ -8,7 +8,7 @@ from ..types.component import Component from ..types.configure_prop_response import ConfigurePropResponse from ..types.configured_props import ConfiguredProps -from ..types.deploy_trigger_response_data import DeployTriggerResponseData +from ..types.emitter import Emitter from ..types.reload_props_response import ReloadPropsResponse from .raw_client import AsyncRawTriggersClient, RawTriggersClient @@ -282,9 +282,10 @@ def deploy( external_user_id: str, configured_props: typing.Optional[ConfiguredProps] = OMIT, dynamic_props_id: typing.Optional[str] = OMIT, + workflow_id: typing.Optional[str] = OMIT, webhook_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> DeployTriggerResponseData: + ) -> Emitter: """ Deploy a trigger to listen for and emit events @@ -301,6 +302,9 @@ def deploy( dynamic_props_id : typing.Optional[str] The ID for dynamic props + workflow_id : typing.Optional[str] + Optional ID of a workflow to receive trigger events + webhook_url : typing.Optional[str] Optional webhook URL to receive trigger events @@ -309,7 +313,7 @@ def deploy( Returns ------- - DeployTriggerResponseData + Emitter trigger deployed Examples @@ -332,6 +336,7 @@ def deploy( external_user_id=external_user_id, configured_props=configured_props, dynamic_props_id=dynamic_props_id, + workflow_id=workflow_id, webhook_url=webhook_url, request_options=request_options, ) @@ -639,9 +644,10 @@ async def deploy( external_user_id: str, configured_props: typing.Optional[ConfiguredProps] = OMIT, dynamic_props_id: typing.Optional[str] = OMIT, + workflow_id: typing.Optional[str] = OMIT, webhook_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> DeployTriggerResponseData: + ) -> Emitter: """ Deploy a trigger to listen for and emit events @@ -658,6 +664,9 @@ async def deploy( dynamic_props_id : typing.Optional[str] The ID for dynamic props + workflow_id : typing.Optional[str] + Optional ID of a workflow to receive trigger events + webhook_url : typing.Optional[str] Optional webhook URL to receive trigger events @@ -666,7 +675,7 @@ async def deploy( Returns ------- - DeployTriggerResponseData + Emitter trigger deployed Examples @@ -697,6 +706,7 @@ async def main() -> None: external_user_id=external_user_id, configured_props=configured_props, dynamic_props_id=dynamic_props_id, + workflow_id=workflow_id, webhook_url=webhook_url, request_options=request_options, ) diff --git a/src/pipedream/triggers/raw_client.py b/src/pipedream/triggers/raw_client.py index abeb4de..32c6029 100644 --- a/src/pipedream/triggers/raw_client.py +++ b/src/pipedream/triggers/raw_client.py @@ -16,7 +16,7 @@ from ..types.configure_prop_response import ConfigurePropResponse from ..types.configured_props import ConfiguredProps from ..types.deploy_trigger_response import DeployTriggerResponse -from ..types.deploy_trigger_response_data import DeployTriggerResponseData +from ..types.emitter import Emitter from ..types.get_component_response import GetComponentResponse from ..types.get_components_response import GetComponentsResponse from ..types.reload_props_response import ReloadPropsResponse @@ -361,9 +361,10 @@ def deploy( external_user_id: str, configured_props: typing.Optional[ConfiguredProps] = OMIT, dynamic_props_id: typing.Optional[str] = OMIT, + workflow_id: typing.Optional[str] = OMIT, webhook_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> HttpResponse[DeployTriggerResponseData]: + ) -> HttpResponse[Emitter]: """ Deploy a trigger to listen for and emit events @@ -380,6 +381,9 @@ def deploy( dynamic_props_id : typing.Optional[str] The ID for dynamic props + workflow_id : typing.Optional[str] + Optional ID of a workflow to receive trigger events + webhook_url : typing.Optional[str] Optional webhook URL to receive trigger events @@ -388,7 +392,7 @@ def deploy( Returns ------- - HttpResponse[DeployTriggerResponseData] + HttpResponse[Emitter] trigger deployed """ _response = self._client_wrapper.httpx_client.request( @@ -401,6 +405,7 @@ def deploy( object_=configured_props, annotation=ConfiguredProps, direction="write" ), "dynamic_props_id": dynamic_props_id, + "workflow_id": workflow_id, "webhook_url": webhook_url, }, headers={ @@ -776,9 +781,10 @@ async def deploy( external_user_id: str, configured_props: typing.Optional[ConfiguredProps] = OMIT, dynamic_props_id: typing.Optional[str] = OMIT, + workflow_id: typing.Optional[str] = OMIT, webhook_url: typing.Optional[str] = OMIT, request_options: typing.Optional[RequestOptions] = None, - ) -> AsyncHttpResponse[DeployTriggerResponseData]: + ) -> AsyncHttpResponse[Emitter]: """ Deploy a trigger to listen for and emit events @@ -795,6 +801,9 @@ async def deploy( dynamic_props_id : typing.Optional[str] The ID for dynamic props + workflow_id : typing.Optional[str] + Optional ID of a workflow to receive trigger events + webhook_url : typing.Optional[str] Optional webhook URL to receive trigger events @@ -803,7 +812,7 @@ async def deploy( Returns ------- - AsyncHttpResponse[DeployTriggerResponseData] + AsyncHttpResponse[Emitter] trigger deployed """ _response = await self._client_wrapper.httpx_client.request( @@ -816,6 +825,7 @@ async def deploy( object_=configured_props, annotation=ConfiguredProps, direction="write" ), "dynamic_props_id": dynamic_props_id, + "workflow_id": workflow_id, "webhook_url": webhook_url, }, headers={ diff --git a/src/pipedream/types/__init__.py b/src/pipedream/types/__init__.py index e88ab8c..584cdbe 100644 --- a/src/pipedream/types/__init__.py +++ b/src/pipedream/types/__init__.py @@ -71,10 +71,10 @@ from .create_token_response import CreateTokenResponse from .delete_trigger_opts import DeleteTriggerOpts from .deploy_trigger_response import DeployTriggerResponse - from .deploy_trigger_response_data import DeployTriggerResponseData from .deployed_component import DeployedComponent from .dynamic_props import DynamicProps from .emitted_event import EmittedEvent + from .emitter import Emitter, Emitter_DeployedComponent, Emitter_HttpInterface, Emitter_TimerInterface from .error_response import ErrorResponse from .get_accounts_response import GetAccountsResponse from .get_app_category_response import GetAppCategoryResponse @@ -84,7 +84,6 @@ from .get_components_response import GetComponentsResponse from .get_trigger_events_response import GetTriggerEventsResponse from .get_trigger_response import GetTriggerResponse - from .get_trigger_response_data import GetTriggerResponseData from .get_trigger_webhooks_response import GetTriggerWebhooksResponse from .get_trigger_workflows_response import GetTriggerWorkflowsResponse from .get_triggers_response import GetTriggersResponse @@ -180,10 +179,13 @@ "CreateTokenResponse": ".create_token_response", "DeleteTriggerOpts": ".delete_trigger_opts", "DeployTriggerResponse": ".deploy_trigger_response", - "DeployTriggerResponseData": ".deploy_trigger_response_data", "DeployedComponent": ".deployed_component", "DynamicProps": ".dynamic_props", "EmittedEvent": ".emitted_event", + "Emitter": ".emitter", + "Emitter_DeployedComponent": ".emitter", + "Emitter_HttpInterface": ".emitter", + "Emitter_TimerInterface": ".emitter", "ErrorResponse": ".error_response", "GetAccountsResponse": ".get_accounts_response", "GetAppCategoryResponse": ".get_app_category_response", @@ -193,7 +195,6 @@ "GetComponentsResponse": ".get_components_response", "GetTriggerEventsResponse": ".get_trigger_events_response", "GetTriggerResponse": ".get_trigger_response", - "GetTriggerResponseData": ".get_trigger_response_data", "GetTriggerWebhooksResponse": ".get_trigger_webhooks_response", "GetTriggerWorkflowsResponse": ".get_trigger_workflows_response", "GetTriggersResponse": ".get_triggers_response", @@ -313,10 +314,13 @@ def __dir__(): "CreateTokenResponse", "DeleteTriggerOpts", "DeployTriggerResponse", - "DeployTriggerResponseData", "DeployedComponent", "DynamicProps", "EmittedEvent", + "Emitter", + "Emitter_DeployedComponent", + "Emitter_HttpInterface", + "Emitter_TimerInterface", "ErrorResponse", "GetAccountsResponse", "GetAppCategoryResponse", @@ -326,7 +330,6 @@ def __dir__(): "GetComponentsResponse", "GetTriggerEventsResponse", "GetTriggerResponse", - "GetTriggerResponseData", "GetTriggerWebhooksResponse", "GetTriggerWorkflowsResponse", "GetTriggersResponse", diff --git a/src/pipedream/types/backend_client_opts.py b/src/pipedream/types/backend_client_opts.py index 9ed37b8..8c0ee71 100644 --- a/src/pipedream/types/backend_client_opts.py +++ b/src/pipedream/types/backend_client_opts.py @@ -26,6 +26,11 @@ class BackendClientOpts(UniversalBaseModel): The API URL to use """ + scope: typing.Optional[str] = pydantic.Field(default=None) + """ + Optional space-separated scopes for the access token. Defaults to '*'. + """ + 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/deploy_trigger_response.py b/src/pipedream/types/deploy_trigger_response.py index 3ef2b0b..03fc556 100644 --- a/src/pipedream/types/deploy_trigger_response.py +++ b/src/pipedream/types/deploy_trigger_response.py @@ -4,7 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .deploy_trigger_response_data import DeployTriggerResponseData +from .emitter import Emitter class DeployTriggerResponse(UniversalBaseModel): @@ -12,7 +12,7 @@ class DeployTriggerResponse(UniversalBaseModel): Response received after deploying a trigger """ - data: DeployTriggerResponseData + data: Emitter 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/deploy_trigger_response_data.py b/src/pipedream/types/deploy_trigger_response_data.py deleted file mode 100644 index 3a175e2..0000000 --- a/src/pipedream/types/deploy_trigger_response_data.py +++ /dev/null @@ -1,9 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from .deployed_component import DeployedComponent -from .http_interface import HttpInterface -from .timer_interface import TimerInterface - -DeployTriggerResponseData = typing.Union[DeployedComponent, HttpInterface, TimerInterface] diff --git a/src/pipedream/types/deployed_component.py b/src/pipedream/types/deployed_component.py index e8cb682..815e7dc 100644 --- a/src/pipedream/types/deployed_component.py +++ b/src/pipedream/types/deployed_component.py @@ -28,6 +28,11 @@ class DeployedComponent(UniversalBaseModel): The ID of the component that was deployed """ + component_key: typing.Optional[str] = pydantic.Field(default=None) + """ + The component key (name) that was deployed + """ + configurable_props: typing.List[ConfigurableProp] = pydantic.Field() """ The configurable properties of the component @@ -59,10 +64,7 @@ class DeployedComponent(UniversalBaseModel): The name slug of the deployed component """ - callback_observations: typing.Optional[typing.Optional[typing.Any]] = pydantic.Field(default=None) - """ - Callback observations for the deployed component - """ + callback_observations: typing.Optional[typing.Optional[typing.Any]] = 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/emitter.py b/src/pipedream/types/emitter.py new file mode 100644 index 0000000..cd4962f --- /dev/null +++ b/src/pipedream/types/emitter.py @@ -0,0 +1,89 @@ +# This file was auto-generated by Fern from our API Definition. + +from __future__ import annotations + +import typing + +import pydantic +from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel +from .configurable_prop import ConfigurableProp +from .configured_props import ConfiguredProps + + +class Emitter_DeployedComponent(UniversalBaseModel): + """ + A component/interface that emits events + """ + + type: typing.Literal["DeployedComponent"] = "DeployedComponent" + id: str + owner_id: str + component_id: str + component_key: typing.Optional[str] = None + configurable_props: typing.List[ConfigurableProp] + configured_props: ConfiguredProps + active: bool + created_at: int + updated_at: int + name: str + name_slug: str + callback_observations: typing.Optional[typing.Optional[typing.Any]] = None + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class Emitter_HttpInterface(UniversalBaseModel): + """ + A component/interface that emits events + """ + + type: typing.Literal["HttpInterface"] = "HttpInterface" + id: str + key: str + endpoint_url: str + custom_response: bool + created_at: int + updated_at: int + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +class Emitter_TimerInterface(UniversalBaseModel): + """ + A component/interface that emits events + """ + + type: typing.Literal["TimerInterface"] = "TimerInterface" + id: str + interval_seconds: typing.Optional[float] = None + cron: typing.Optional[str] = None + timezone: str + schedule_changed_at: int + created_at: int + updated_at: int + + if IS_PYDANTIC_V2: + model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 + else: + + class Config: + frozen = True + smart_union = True + extra = pydantic.Extra.allow + + +Emitter = typing.Union[Emitter_DeployedComponent, Emitter_HttpInterface, Emitter_TimerInterface] diff --git a/src/pipedream/types/get_trigger_response.py b/src/pipedream/types/get_trigger_response.py index 977f20e..2ff36f7 100644 --- a/src/pipedream/types/get_trigger_response.py +++ b/src/pipedream/types/get_trigger_response.py @@ -4,7 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .get_trigger_response_data import GetTriggerResponseData +from .emitter import Emitter class GetTriggerResponse(UniversalBaseModel): @@ -12,7 +12,7 @@ class GetTriggerResponse(UniversalBaseModel): Response received when retrieving a deployed trigger """ - data: GetTriggerResponseData + data: Emitter 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/get_trigger_response_data.py b/src/pipedream/types/get_trigger_response_data.py deleted file mode 100644 index 5817054..0000000 --- a/src/pipedream/types/get_trigger_response_data.py +++ /dev/null @@ -1,9 +0,0 @@ -# This file was auto-generated by Fern from our API Definition. - -import typing - -from .deployed_component import DeployedComponent -from .http_interface import HttpInterface -from .timer_interface import TimerInterface - -GetTriggerResponseData = typing.Union[DeployedComponent, HttpInterface, TimerInterface] diff --git a/src/pipedream/types/get_triggers_response.py b/src/pipedream/types/get_triggers_response.py index 19d13ab..e0b7e30 100644 --- a/src/pipedream/types/get_triggers_response.py +++ b/src/pipedream/types/get_triggers_response.py @@ -4,7 +4,7 @@ import pydantic from ..core.pydantic_utilities import IS_PYDANTIC_V2, UniversalBaseModel -from .deployed_component import DeployedComponent +from .emitter import Emitter from .page_info import PageInfo @@ -13,7 +13,7 @@ class GetTriggersResponse(UniversalBaseModel): Response received when listing deployed triggers """ - data: typing.List[DeployedComponent] + data: typing.List[Emitter] page_info: PageInfo if IS_PYDANTIC_V2: diff --git a/src/pipedream/types/http_interface.py b/src/pipedream/types/http_interface.py index 7c32c5f..f485f53 100644 --- a/src/pipedream/types/http_interface.py +++ b/src/pipedream/types/http_interface.py @@ -24,7 +24,7 @@ class HttpInterface(UniversalBaseModel): The timestamp when the HTTP interface was created (epoch milliseconds) """ - updated_at: typing.Optional[int] = pydantic.Field(default=None) + updated_at: int = pydantic.Field() """ The timestamp when the HTTP interface was last updated (epoch milliseconds) """ diff --git a/src/pipedream/types/run_action_response.py b/src/pipedream/types/run_action_response.py index e223088..bfa834c 100644 --- a/src/pipedream/types/run_action_response.py +++ b/src/pipedream/types/run_action_response.py @@ -12,21 +12,9 @@ class RunActionResponse(UniversalBaseModel): The response received after running an action. See https://pipedream.com/docs/components/api#returning-data-from-steps for more details. """ - exports: typing.Optional[typing.Optional[typing.Any]] = pydantic.Field(default=None) - """ - The key-value pairs resulting from calls to `$.export` - """ - - os: typing.Optional[typing.Optional[typing.Any]] = pydantic.Field(default=None) - """ - Any logs produced during the execution of the action - """ - - ret: typing.Optional[typing.Optional[typing.Any]] = pydantic.Field(default=None) - """ - The value returned by the action - """ - + exports: typing.Optional[typing.Optional[typing.Any]] = None + os: typing.Optional[typing.Optional[typing.Any]] = None + ret: typing.Optional[typing.Optional[typing.Any]] = None stash_id: typing.Optional[StashId] = None if IS_PYDANTIC_V2: diff --git a/src/pipedream/types/timer_interface.py b/src/pipedream/types/timer_interface.py index ee2a0f8..bb103cc 100644 --- a/src/pipedream/types/timer_interface.py +++ b/src/pipedream/types/timer_interface.py @@ -25,7 +25,7 @@ class TimerInterface(UniversalBaseModel): The timestamp when the timer interface was created (epoch milliseconds) """ - updated_at: typing.Optional[int] = pydantic.Field(default=None) + updated_at: int = pydantic.Field() """ The timestamp when the timer interface was last updated (epoch milliseconds) """