airbyte-agent-hubspot 0.15.20__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airbyte_agent_hubspot/__init__.py +86 -0
- airbyte_agent_hubspot/_vendored/__init__.py +1 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/__init__.py +82 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/auth_strategies.py +1123 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/auth_template.py +135 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/cloud_utils/__init__.py +5 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/cloud_utils/client.py +213 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/connector_model_loader.py +957 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/constants.py +78 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/exceptions.py +23 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/executor/__init__.py +31 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/executor/hosted_executor.py +197 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/executor/local_executor.py +1504 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/executor/models.py +190 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/extensions.py +655 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/http/__init__.py +37 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/http/adapters/__init__.py +9 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/http/adapters/httpx_adapter.py +251 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/http/config.py +98 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/http/exceptions.py +119 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/http/protocols.py +114 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/http/response.py +102 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/http_client.py +679 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/logging/__init__.py +11 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/logging/logger.py +264 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/logging/types.py +92 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/observability/__init__.py +11 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/observability/models.py +19 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/observability/redactor.py +81 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/observability/session.py +94 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/performance/__init__.py +6 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/performance/instrumentation.py +57 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/performance/metrics.py +93 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/schema/__init__.py +75 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/schema/base.py +161 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/schema/components.py +238 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/schema/connector.py +131 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/schema/extensions.py +109 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/schema/operations.py +146 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/schema/security.py +213 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/secrets.py +182 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/telemetry/__init__.py +10 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/telemetry/config.py +32 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/telemetry/events.py +58 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/telemetry/tracker.py +151 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/types.py +241 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/utils.py +60 -0
- airbyte_agent_hubspot/_vendored/connector_sdk/validation.py +822 -0
- airbyte_agent_hubspot/connector.py +1104 -0
- airbyte_agent_hubspot/connector_model.py +2660 -0
- airbyte_agent_hubspot/models.py +438 -0
- airbyte_agent_hubspot/types.py +217 -0
- airbyte_agent_hubspot-0.15.20.dist-info/METADATA +105 -0
- airbyte_agent_hubspot-0.15.20.dist-info/RECORD +55 -0
- airbyte_agent_hubspot-0.15.20.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,1104 @@
|
|
|
1
|
+
"""
|
|
2
|
+
hubspot connector.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import TYPE_CHECKING, Any, overload
|
|
8
|
+
try:
|
|
9
|
+
from typing import Literal
|
|
10
|
+
except ImportError:
|
|
11
|
+
from typing_extensions import Literal
|
|
12
|
+
|
|
13
|
+
from .connector_model import HubspotConnectorModel
|
|
14
|
+
|
|
15
|
+
from .types import (
|
|
16
|
+
CompaniesGetParams,
|
|
17
|
+
CompaniesListParams,
|
|
18
|
+
CompaniesSearchParams,
|
|
19
|
+
CompaniesSearchParamsFiltergroupsItem,
|
|
20
|
+
CompaniesSearchParamsSortsItem,
|
|
21
|
+
ContactsGetParams,
|
|
22
|
+
ContactsListParams,
|
|
23
|
+
ContactsSearchParams,
|
|
24
|
+
ContactsSearchParamsFiltergroupsItem,
|
|
25
|
+
ContactsSearchParamsSortsItem,
|
|
26
|
+
DealsGetParams,
|
|
27
|
+
DealsListParams,
|
|
28
|
+
DealsSearchParams,
|
|
29
|
+
DealsSearchParamsFiltergroupsItem,
|
|
30
|
+
DealsSearchParamsSortsItem,
|
|
31
|
+
ObjectsGetParams,
|
|
32
|
+
ObjectsListParams,
|
|
33
|
+
SchemasGetParams,
|
|
34
|
+
SchemasListParams,
|
|
35
|
+
TicketsGetParams,
|
|
36
|
+
TicketsListParams,
|
|
37
|
+
TicketsSearchParams,
|
|
38
|
+
TicketsSearchParamsFiltergroupsItem,
|
|
39
|
+
TicketsSearchParamsSortsItem,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
if TYPE_CHECKING:
|
|
43
|
+
from .models import HubspotAuthConfig
|
|
44
|
+
# Import response models and envelope models at runtime
|
|
45
|
+
from .models import (
|
|
46
|
+
HubspotExecuteResult,
|
|
47
|
+
HubspotExecuteResultWithMeta,
|
|
48
|
+
ContactsListResult,
|
|
49
|
+
ContactsSearchResult,
|
|
50
|
+
CompaniesListResult,
|
|
51
|
+
CompaniesSearchResult,
|
|
52
|
+
DealsListResult,
|
|
53
|
+
DealsSearchResult,
|
|
54
|
+
TicketsListResult,
|
|
55
|
+
TicketsSearchResult,
|
|
56
|
+
SchemasListResult,
|
|
57
|
+
ObjectsListResult,
|
|
58
|
+
CRMObject,
|
|
59
|
+
Company,
|
|
60
|
+
Contact,
|
|
61
|
+
Deal,
|
|
62
|
+
Schema,
|
|
63
|
+
Ticket,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class HubspotConnector:
|
|
68
|
+
"""
|
|
69
|
+
Type-safe Hubspot API connector.
|
|
70
|
+
|
|
71
|
+
Auto-generated from OpenAPI specification with full type safety.
|
|
72
|
+
"""
|
|
73
|
+
|
|
74
|
+
connector_name = "hubspot"
|
|
75
|
+
connector_version = "0.1.2"
|
|
76
|
+
vendored_sdk_version = "0.1.0" # Version of vendored connector-sdk
|
|
77
|
+
|
|
78
|
+
# Map of (entity, action) -> has_extractors for envelope wrapping decision
|
|
79
|
+
_EXTRACTOR_MAP = {
|
|
80
|
+
("contacts", "list"): True,
|
|
81
|
+
("contacts", "get"): False,
|
|
82
|
+
("contacts", "search"): True,
|
|
83
|
+
("companies", "list"): True,
|
|
84
|
+
("companies", "get"): False,
|
|
85
|
+
("companies", "search"): True,
|
|
86
|
+
("deals", "list"): True,
|
|
87
|
+
("deals", "get"): False,
|
|
88
|
+
("deals", "search"): True,
|
|
89
|
+
("tickets", "list"): True,
|
|
90
|
+
("tickets", "get"): False,
|
|
91
|
+
("tickets", "search"): True,
|
|
92
|
+
("schemas", "list"): True,
|
|
93
|
+
("schemas", "get"): False,
|
|
94
|
+
("objects", "list"): True,
|
|
95
|
+
("objects", "get"): False,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
# Map of (entity, action) -> {python_param_name: api_param_name}
|
|
99
|
+
# Used to convert snake_case TypedDict keys to API parameter names in execute()
|
|
100
|
+
_PARAM_MAP = {
|
|
101
|
+
('contacts', 'list'): {'limit': 'limit', 'after': 'after', 'associations': 'associations', 'properties': 'properties', 'properties_with_history': 'propertiesWithHistory', 'archived': 'archived'},
|
|
102
|
+
('contacts', 'get'): {'contact_id': 'contactId', 'properties': 'properties', 'properties_with_history': 'propertiesWithHistory', 'associations': 'associations', 'id_property': 'idProperty', 'archived': 'archived'},
|
|
103
|
+
('contacts', 'search'): {'filter_groups': 'filterGroups', 'properties': 'properties', 'limit': 'limit', 'after': 'after', 'sorts': 'sorts', 'query': 'query'},
|
|
104
|
+
('companies', 'list'): {'limit': 'limit', 'after': 'after', 'associations': 'associations', 'properties': 'properties', 'properties_with_history': 'propertiesWithHistory', 'archived': 'archived'},
|
|
105
|
+
('companies', 'get'): {'company_id': 'companyId', 'properties': 'properties', 'properties_with_history': 'propertiesWithHistory', 'associations': 'associations', 'id_property': 'idProperty', 'archived': 'archived'},
|
|
106
|
+
('companies', 'search'): {'filter_groups': 'filterGroups', 'properties': 'properties', 'limit': 'limit', 'after': 'after', 'sorts': 'sorts', 'query': 'query'},
|
|
107
|
+
('deals', 'list'): {'limit': 'limit', 'after': 'after', 'associations': 'associations', 'properties': 'properties', 'properties_with_history': 'propertiesWithHistory', 'archived': 'archived'},
|
|
108
|
+
('deals', 'get'): {'deal_id': 'dealId', 'properties': 'properties', 'properties_with_history': 'propertiesWithHistory', 'associations': 'associations', 'id_property': 'idProperty', 'archived': 'archived'},
|
|
109
|
+
('deals', 'search'): {'filter_groups': 'filterGroups', 'properties': 'properties', 'limit': 'limit', 'after': 'after', 'sorts': 'sorts', 'query': 'query'},
|
|
110
|
+
('tickets', 'list'): {'limit': 'limit', 'after': 'after', 'associations': 'associations', 'properties': 'properties', 'properties_with_history': 'propertiesWithHistory', 'archived': 'archived'},
|
|
111
|
+
('tickets', 'get'): {'ticket_id': 'ticketId', 'properties': 'properties', 'properties_with_history': 'propertiesWithHistory', 'associations': 'associations', 'id_property': 'idProperty', 'archived': 'archived'},
|
|
112
|
+
('tickets', 'search'): {'filter_groups': 'filterGroups', 'properties': 'properties', 'limit': 'limit', 'after': 'after', 'sorts': 'sorts', 'query': 'query'},
|
|
113
|
+
('schemas', 'list'): {'archived': 'archived'},
|
|
114
|
+
('schemas', 'get'): {'object_type': 'objectType'},
|
|
115
|
+
('objects', 'list'): {'object_type': 'objectType', 'limit': 'limit', 'after': 'after', 'properties': 'properties', 'archived': 'archived', 'associations': 'associations', 'properties_with_history': 'propertiesWithHistory'},
|
|
116
|
+
('objects', 'get'): {'object_type': 'objectType', 'object_id': 'objectId', 'properties': 'properties', 'archived': 'archived', 'associations': 'associations', 'id_property': 'idProperty', 'properties_with_history': 'propertiesWithHistory'},
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
def __init__(
|
|
120
|
+
self,
|
|
121
|
+
auth_config: HubspotAuthConfig | None = None,
|
|
122
|
+
external_user_id: str | None = None,
|
|
123
|
+
airbyte_client_id: str | None = None,
|
|
124
|
+
airbyte_client_secret: str | None = None,
|
|
125
|
+
on_token_refresh: Any | None = None ):
|
|
126
|
+
"""
|
|
127
|
+
Initialize a new hubspot connector instance.
|
|
128
|
+
|
|
129
|
+
Supports both local and hosted execution modes:
|
|
130
|
+
- Local mode: Provide `auth_config` for direct API calls
|
|
131
|
+
- Hosted mode: Provide `external_user_id`, `airbyte_client_id`, and `airbyte_client_secret` for hosted execution
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
auth_config: Typed authentication configuration (required for local mode)
|
|
135
|
+
external_user_id: External user ID (required for hosted mode)
|
|
136
|
+
airbyte_client_id: Airbyte OAuth client ID (required for hosted mode)
|
|
137
|
+
airbyte_client_secret: Airbyte OAuth client secret (required for hosted mode)
|
|
138
|
+
on_token_refresh: Optional callback for OAuth2 token refresh persistence.
|
|
139
|
+
Called with new_tokens dict when tokens are refreshed. Can be sync or async.
|
|
140
|
+
Example: lambda tokens: save_to_database(tokens)
|
|
141
|
+
Examples:
|
|
142
|
+
# Local mode (direct API calls)
|
|
143
|
+
connector = HubspotConnector(auth_config=HubspotAuthConfig(client_id="...", client_secret="...", refresh_token="...", access_token="..."))
|
|
144
|
+
# Hosted mode (executed on Airbyte cloud)
|
|
145
|
+
connector = HubspotConnector(
|
|
146
|
+
external_user_id="user-123",
|
|
147
|
+
airbyte_client_id="client_abc123",
|
|
148
|
+
airbyte_client_secret="secret_xyz789"
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Local mode with OAuth2 token refresh callback
|
|
152
|
+
def save_tokens(new_tokens: dict) -> None:
|
|
153
|
+
# Persist updated tokens to your storage (file, database, etc.)
|
|
154
|
+
with open("tokens.json", "w") as f:
|
|
155
|
+
json.dump(new_tokens, f)
|
|
156
|
+
|
|
157
|
+
connector = HubspotConnector(
|
|
158
|
+
auth_config=HubspotAuthConfig(access_token="...", refresh_token="..."),
|
|
159
|
+
on_token_refresh=save_tokens
|
|
160
|
+
)
|
|
161
|
+
"""
|
|
162
|
+
# Hosted mode: external_user_id, airbyte_client_id, and airbyte_client_secret provided
|
|
163
|
+
if external_user_id and airbyte_client_id and airbyte_client_secret:
|
|
164
|
+
from ._vendored.connector_sdk.executor import HostedExecutor
|
|
165
|
+
self._executor = HostedExecutor(
|
|
166
|
+
external_user_id=external_user_id,
|
|
167
|
+
airbyte_client_id=airbyte_client_id,
|
|
168
|
+
airbyte_client_secret=airbyte_client_secret,
|
|
169
|
+
connector_definition_id=str(HubspotConnectorModel.id),
|
|
170
|
+
)
|
|
171
|
+
else:
|
|
172
|
+
# Local mode: auth_config required
|
|
173
|
+
if not auth_config:
|
|
174
|
+
raise ValueError(
|
|
175
|
+
"Either provide (external_user_id, airbyte_client_id, airbyte_client_secret) for hosted mode "
|
|
176
|
+
"or auth_config for local mode"
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
from ._vendored.connector_sdk.executor import LocalExecutor
|
|
180
|
+
|
|
181
|
+
# Build config_values dict from server variables
|
|
182
|
+
config_values = None
|
|
183
|
+
|
|
184
|
+
self._executor = LocalExecutor(
|
|
185
|
+
model=HubspotConnectorModel,
|
|
186
|
+
auth_config=auth_config.model_dump() if auth_config else None,
|
|
187
|
+
config_values=config_values,
|
|
188
|
+
on_token_refresh=on_token_refresh
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# Update base_url with server variables if provided
|
|
192
|
+
|
|
193
|
+
# Initialize entity query objects
|
|
194
|
+
self.contacts = ContactsQuery(self)
|
|
195
|
+
self.companies = CompaniesQuery(self)
|
|
196
|
+
self.deals = DealsQuery(self)
|
|
197
|
+
self.tickets = TicketsQuery(self)
|
|
198
|
+
self.schemas = SchemasQuery(self)
|
|
199
|
+
self.objects = ObjectsQuery(self)
|
|
200
|
+
|
|
201
|
+
# ===== TYPED EXECUTE METHOD (Recommended Interface) =====
|
|
202
|
+
|
|
203
|
+
@overload
|
|
204
|
+
async def execute(
|
|
205
|
+
self,
|
|
206
|
+
entity: Literal["contacts"],
|
|
207
|
+
action: Literal["list"],
|
|
208
|
+
params: "ContactsListParams"
|
|
209
|
+
) -> "ContactsListResult": ...
|
|
210
|
+
|
|
211
|
+
@overload
|
|
212
|
+
async def execute(
|
|
213
|
+
self,
|
|
214
|
+
entity: Literal["contacts"],
|
|
215
|
+
action: Literal["get"],
|
|
216
|
+
params: "ContactsGetParams"
|
|
217
|
+
) -> "Contact": ...
|
|
218
|
+
|
|
219
|
+
@overload
|
|
220
|
+
async def execute(
|
|
221
|
+
self,
|
|
222
|
+
entity: Literal["contacts"],
|
|
223
|
+
action: Literal["search"],
|
|
224
|
+
params: "ContactsSearchParams"
|
|
225
|
+
) -> "ContactsSearchResult": ...
|
|
226
|
+
|
|
227
|
+
@overload
|
|
228
|
+
async def execute(
|
|
229
|
+
self,
|
|
230
|
+
entity: Literal["companies"],
|
|
231
|
+
action: Literal["list"],
|
|
232
|
+
params: "CompaniesListParams"
|
|
233
|
+
) -> "CompaniesListResult": ...
|
|
234
|
+
|
|
235
|
+
@overload
|
|
236
|
+
async def execute(
|
|
237
|
+
self,
|
|
238
|
+
entity: Literal["companies"],
|
|
239
|
+
action: Literal["get"],
|
|
240
|
+
params: "CompaniesGetParams"
|
|
241
|
+
) -> "Company": ...
|
|
242
|
+
|
|
243
|
+
@overload
|
|
244
|
+
async def execute(
|
|
245
|
+
self,
|
|
246
|
+
entity: Literal["companies"],
|
|
247
|
+
action: Literal["search"],
|
|
248
|
+
params: "CompaniesSearchParams"
|
|
249
|
+
) -> "CompaniesSearchResult": ...
|
|
250
|
+
|
|
251
|
+
@overload
|
|
252
|
+
async def execute(
|
|
253
|
+
self,
|
|
254
|
+
entity: Literal["deals"],
|
|
255
|
+
action: Literal["list"],
|
|
256
|
+
params: "DealsListParams"
|
|
257
|
+
) -> "DealsListResult": ...
|
|
258
|
+
|
|
259
|
+
@overload
|
|
260
|
+
async def execute(
|
|
261
|
+
self,
|
|
262
|
+
entity: Literal["deals"],
|
|
263
|
+
action: Literal["get"],
|
|
264
|
+
params: "DealsGetParams"
|
|
265
|
+
) -> "Deal": ...
|
|
266
|
+
|
|
267
|
+
@overload
|
|
268
|
+
async def execute(
|
|
269
|
+
self,
|
|
270
|
+
entity: Literal["deals"],
|
|
271
|
+
action: Literal["search"],
|
|
272
|
+
params: "DealsSearchParams"
|
|
273
|
+
) -> "DealsSearchResult": ...
|
|
274
|
+
|
|
275
|
+
@overload
|
|
276
|
+
async def execute(
|
|
277
|
+
self,
|
|
278
|
+
entity: Literal["tickets"],
|
|
279
|
+
action: Literal["list"],
|
|
280
|
+
params: "TicketsListParams"
|
|
281
|
+
) -> "TicketsListResult": ...
|
|
282
|
+
|
|
283
|
+
@overload
|
|
284
|
+
async def execute(
|
|
285
|
+
self,
|
|
286
|
+
entity: Literal["tickets"],
|
|
287
|
+
action: Literal["get"],
|
|
288
|
+
params: "TicketsGetParams"
|
|
289
|
+
) -> "Ticket": ...
|
|
290
|
+
|
|
291
|
+
@overload
|
|
292
|
+
async def execute(
|
|
293
|
+
self,
|
|
294
|
+
entity: Literal["tickets"],
|
|
295
|
+
action: Literal["search"],
|
|
296
|
+
params: "TicketsSearchParams"
|
|
297
|
+
) -> "TicketsSearchResult": ...
|
|
298
|
+
|
|
299
|
+
@overload
|
|
300
|
+
async def execute(
|
|
301
|
+
self,
|
|
302
|
+
entity: Literal["schemas"],
|
|
303
|
+
action: Literal["list"],
|
|
304
|
+
params: "SchemasListParams"
|
|
305
|
+
) -> "SchemasListResult": ...
|
|
306
|
+
|
|
307
|
+
@overload
|
|
308
|
+
async def execute(
|
|
309
|
+
self,
|
|
310
|
+
entity: Literal["schemas"],
|
|
311
|
+
action: Literal["get"],
|
|
312
|
+
params: "SchemasGetParams"
|
|
313
|
+
) -> "Schema": ...
|
|
314
|
+
|
|
315
|
+
@overload
|
|
316
|
+
async def execute(
|
|
317
|
+
self,
|
|
318
|
+
entity: Literal["objects"],
|
|
319
|
+
action: Literal["list"],
|
|
320
|
+
params: "ObjectsListParams"
|
|
321
|
+
) -> "ObjectsListResult": ...
|
|
322
|
+
|
|
323
|
+
@overload
|
|
324
|
+
async def execute(
|
|
325
|
+
self,
|
|
326
|
+
entity: Literal["objects"],
|
|
327
|
+
action: Literal["get"],
|
|
328
|
+
params: "ObjectsGetParams"
|
|
329
|
+
) -> "CRMObject": ...
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
@overload
|
|
333
|
+
async def execute(
|
|
334
|
+
self,
|
|
335
|
+
entity: str,
|
|
336
|
+
action: str,
|
|
337
|
+
params: dict[str, Any]
|
|
338
|
+
) -> HubspotExecuteResult[Any] | HubspotExecuteResultWithMeta[Any, Any] | Any: ...
|
|
339
|
+
|
|
340
|
+
async def execute(
|
|
341
|
+
self,
|
|
342
|
+
entity: str,
|
|
343
|
+
action: str,
|
|
344
|
+
params: dict[str, Any] | None = None
|
|
345
|
+
) -> Any:
|
|
346
|
+
"""
|
|
347
|
+
Execute an entity operation with full type safety.
|
|
348
|
+
|
|
349
|
+
This is the recommended interface for blessed connectors as it:
|
|
350
|
+
- Uses the same signature as non-blessed connectors
|
|
351
|
+
- Provides full IDE autocomplete for entity/action/params
|
|
352
|
+
- Makes migration from generic to blessed connectors seamless
|
|
353
|
+
|
|
354
|
+
Args:
|
|
355
|
+
entity: Entity name (e.g., "customers")
|
|
356
|
+
action: Operation action (e.g., "create", "get", "list")
|
|
357
|
+
params: Operation parameters (typed based on entity+action)
|
|
358
|
+
|
|
359
|
+
Returns:
|
|
360
|
+
Typed response based on the operation
|
|
361
|
+
|
|
362
|
+
Example:
|
|
363
|
+
customer = await connector.execute(
|
|
364
|
+
entity="customers",
|
|
365
|
+
action="get",
|
|
366
|
+
params={"id": "cus_123"}
|
|
367
|
+
)
|
|
368
|
+
"""
|
|
369
|
+
from ._vendored.connector_sdk.executor import ExecutionConfig
|
|
370
|
+
|
|
371
|
+
# Remap parameter names from snake_case (TypedDict keys) to API parameter names
|
|
372
|
+
if params:
|
|
373
|
+
param_map = self._PARAM_MAP.get((entity, action), {})
|
|
374
|
+
if param_map:
|
|
375
|
+
params = {param_map.get(k, k): v for k, v in params.items()}
|
|
376
|
+
|
|
377
|
+
# Use ExecutionConfig for both local and hosted executors
|
|
378
|
+
config = ExecutionConfig(
|
|
379
|
+
entity=entity,
|
|
380
|
+
action=action,
|
|
381
|
+
params=params
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
result = await self._executor.execute(config)
|
|
385
|
+
|
|
386
|
+
if not result.success:
|
|
387
|
+
raise RuntimeError(f"Execution failed: {result.error}")
|
|
388
|
+
|
|
389
|
+
# Check if this operation has extractors configured
|
|
390
|
+
has_extractors = self._EXTRACTOR_MAP.get((entity, action), False)
|
|
391
|
+
|
|
392
|
+
if has_extractors:
|
|
393
|
+
# With extractors - return Pydantic envelope with data and meta
|
|
394
|
+
if result.meta is not None:
|
|
395
|
+
return HubspotExecuteResultWithMeta[Any, Any](
|
|
396
|
+
data=result.data,
|
|
397
|
+
meta=result.meta
|
|
398
|
+
)
|
|
399
|
+
else:
|
|
400
|
+
return HubspotExecuteResult[Any](data=result.data)
|
|
401
|
+
else:
|
|
402
|
+
# No extractors - return raw response data
|
|
403
|
+
return result.data
|
|
404
|
+
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
class ContactsQuery:
|
|
408
|
+
"""
|
|
409
|
+
Query class for Contacts entity operations.
|
|
410
|
+
"""
|
|
411
|
+
|
|
412
|
+
def __init__(self, connector: HubspotConnector):
|
|
413
|
+
"""Initialize query with connector reference."""
|
|
414
|
+
self._connector = connector
|
|
415
|
+
|
|
416
|
+
async def list(
|
|
417
|
+
self,
|
|
418
|
+
limit: int | None = None,
|
|
419
|
+
after: str | None = None,
|
|
420
|
+
associations: str | None = None,
|
|
421
|
+
properties: str | None = None,
|
|
422
|
+
properties_with_history: str | None = None,
|
|
423
|
+
archived: bool | None = None,
|
|
424
|
+
**kwargs
|
|
425
|
+
) -> ContactsListResult:
|
|
426
|
+
"""
|
|
427
|
+
Returns a paginated list of contacts
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
limit: The maximum number of results to display per page.
|
|
431
|
+
after: The paging cursor token of the last successfully read resource will be returned as the paging.next.after JSON property of a paged response containing more results.
|
|
432
|
+
associations: A comma separated list of associated object types to include in the response. Valid values are contacts, deals, tickets, and custom object type IDs or fully qualified names (e.g., "p12345_cars").
|
|
433
|
+
properties: A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
434
|
+
properties_with_history: A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored. Usage of this parameter will reduce the maximum number of companies that can be read by a single request.
|
|
435
|
+
archived: Whether to return only results that have been archived.
|
|
436
|
+
**kwargs: Additional parameters
|
|
437
|
+
|
|
438
|
+
Returns:
|
|
439
|
+
ContactsListResult
|
|
440
|
+
"""
|
|
441
|
+
params = {k: v for k, v in {
|
|
442
|
+
"limit": limit,
|
|
443
|
+
"after": after,
|
|
444
|
+
"associations": associations,
|
|
445
|
+
"properties": properties,
|
|
446
|
+
"propertiesWithHistory": properties_with_history,
|
|
447
|
+
"archived": archived,
|
|
448
|
+
**kwargs
|
|
449
|
+
}.items() if v is not None}
|
|
450
|
+
|
|
451
|
+
result = await self._connector.execute("contacts", "list", params)
|
|
452
|
+
# Cast generic envelope to concrete typed result
|
|
453
|
+
return ContactsListResult(
|
|
454
|
+
data=result.data,
|
|
455
|
+
meta=result.meta )
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
async def get(
|
|
460
|
+
self,
|
|
461
|
+
contact_id: str,
|
|
462
|
+
properties: str | None = None,
|
|
463
|
+
properties_with_history: str | None = None,
|
|
464
|
+
associations: str | None = None,
|
|
465
|
+
id_property: str | None = None,
|
|
466
|
+
archived: bool | None = None,
|
|
467
|
+
**kwargs
|
|
468
|
+
) -> Contact:
|
|
469
|
+
"""
|
|
470
|
+
Get a single contact by ID
|
|
471
|
+
|
|
472
|
+
Args:
|
|
473
|
+
contact_id: Contact ID
|
|
474
|
+
properties: A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
475
|
+
properties_with_history: A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
476
|
+
associations: A comma separated list of object types to retrieve associated IDs for. If any of the specified associations do not exist, they will be ignored.
|
|
477
|
+
id_property: The name of a property whose values are unique for this object.
|
|
478
|
+
archived: Whether to return only results that have been archived.
|
|
479
|
+
**kwargs: Additional parameters
|
|
480
|
+
|
|
481
|
+
Returns:
|
|
482
|
+
Contact
|
|
483
|
+
"""
|
|
484
|
+
params = {k: v for k, v in {
|
|
485
|
+
"contactId": contact_id,
|
|
486
|
+
"properties": properties,
|
|
487
|
+
"propertiesWithHistory": properties_with_history,
|
|
488
|
+
"associations": associations,
|
|
489
|
+
"idProperty": id_property,
|
|
490
|
+
"archived": archived,
|
|
491
|
+
**kwargs
|
|
492
|
+
}.items() if v is not None}
|
|
493
|
+
|
|
494
|
+
result = await self._connector.execute("contacts", "get", params)
|
|
495
|
+
return result
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
async def search(
|
|
500
|
+
self,
|
|
501
|
+
filter_groups: list[ContactsSearchParamsFiltergroupsItem] | None = None,
|
|
502
|
+
properties: list[str] | None = None,
|
|
503
|
+
limit: int | None = None,
|
|
504
|
+
after: str | None = None,
|
|
505
|
+
sorts: list[ContactsSearchParamsSortsItem] | None = None,
|
|
506
|
+
query: str | None = None,
|
|
507
|
+
**kwargs
|
|
508
|
+
) -> ContactsSearchResult:
|
|
509
|
+
"""
|
|
510
|
+
Search for contacts by filtering on properties, searching through associations, and sorting results.
|
|
511
|
+
|
|
512
|
+
Args:
|
|
513
|
+
filter_groups: Up to 6 groups of filters defining additional query criteria.
|
|
514
|
+
properties: A list of property names to include in the response.
|
|
515
|
+
limit: Maximum number of results to return
|
|
516
|
+
after: A paging cursor token for retrieving subsequent pages.
|
|
517
|
+
sorts: Sort criteria
|
|
518
|
+
query: The search query string, up to 3000 characters.
|
|
519
|
+
**kwargs: Additional parameters
|
|
520
|
+
|
|
521
|
+
Returns:
|
|
522
|
+
ContactsSearchResult
|
|
523
|
+
"""
|
|
524
|
+
params = {k: v for k, v in {
|
|
525
|
+
"filterGroups": filter_groups,
|
|
526
|
+
"properties": properties,
|
|
527
|
+
"limit": limit,
|
|
528
|
+
"after": after,
|
|
529
|
+
"sorts": sorts,
|
|
530
|
+
"query": query,
|
|
531
|
+
**kwargs
|
|
532
|
+
}.items() if v is not None}
|
|
533
|
+
|
|
534
|
+
result = await self._connector.execute("contacts", "search", params)
|
|
535
|
+
# Cast generic envelope to concrete typed result
|
|
536
|
+
return ContactsSearchResult(
|
|
537
|
+
data=result.data,
|
|
538
|
+
meta=result.meta )
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
class CompaniesQuery:
|
|
543
|
+
"""
|
|
544
|
+
Query class for Companies entity operations.
|
|
545
|
+
"""
|
|
546
|
+
|
|
547
|
+
def __init__(self, connector: HubspotConnector):
|
|
548
|
+
"""Initialize query with connector reference."""
|
|
549
|
+
self._connector = connector
|
|
550
|
+
|
|
551
|
+
async def list(
|
|
552
|
+
self,
|
|
553
|
+
limit: int | None = None,
|
|
554
|
+
after: str | None = None,
|
|
555
|
+
associations: str | None = None,
|
|
556
|
+
properties: str | None = None,
|
|
557
|
+
properties_with_history: str | None = None,
|
|
558
|
+
archived: bool | None = None,
|
|
559
|
+
**kwargs
|
|
560
|
+
) -> CompaniesListResult:
|
|
561
|
+
"""
|
|
562
|
+
Retrieve all companies, using query parameters to control the information that gets returned.
|
|
563
|
+
|
|
564
|
+
Args:
|
|
565
|
+
limit: The maximum number of results to display per page.
|
|
566
|
+
after: The paging cursor token of the last successfully read resource will be returned as the paging.next.after JSON property of a paged response containing more results.
|
|
567
|
+
associations: A comma separated list of associated object types to include in the response. Valid values are contacts, deals, tickets, and custom object type IDs or fully qualified names (e.g., "p12345_cars").
|
|
568
|
+
properties: A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
569
|
+
properties_with_history: A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored. Usage of this parameter will reduce the maximum number of companies that can be read by a single request.
|
|
570
|
+
archived: Whether to return only results that have been archived.
|
|
571
|
+
**kwargs: Additional parameters
|
|
572
|
+
|
|
573
|
+
Returns:
|
|
574
|
+
CompaniesListResult
|
|
575
|
+
"""
|
|
576
|
+
params = {k: v for k, v in {
|
|
577
|
+
"limit": limit,
|
|
578
|
+
"after": after,
|
|
579
|
+
"associations": associations,
|
|
580
|
+
"properties": properties,
|
|
581
|
+
"propertiesWithHistory": properties_with_history,
|
|
582
|
+
"archived": archived,
|
|
583
|
+
**kwargs
|
|
584
|
+
}.items() if v is not None}
|
|
585
|
+
|
|
586
|
+
result = await self._connector.execute("companies", "list", params)
|
|
587
|
+
# Cast generic envelope to concrete typed result
|
|
588
|
+
return CompaniesListResult(
|
|
589
|
+
data=result.data,
|
|
590
|
+
meta=result.meta )
|
|
591
|
+
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
async def get(
|
|
595
|
+
self,
|
|
596
|
+
company_id: str,
|
|
597
|
+
properties: str | None = None,
|
|
598
|
+
properties_with_history: str | None = None,
|
|
599
|
+
associations: str | None = None,
|
|
600
|
+
id_property: str | None = None,
|
|
601
|
+
archived: bool | None = None,
|
|
602
|
+
**kwargs
|
|
603
|
+
) -> Company:
|
|
604
|
+
"""
|
|
605
|
+
Get a single company by ID
|
|
606
|
+
|
|
607
|
+
Args:
|
|
608
|
+
company_id: Company ID
|
|
609
|
+
properties: A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
610
|
+
properties_with_history: A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
611
|
+
associations: A comma separated list of object types to retrieve associated IDs for. If any of the specified associations do not exist, they will be ignored.
|
|
612
|
+
id_property: The name of a property whose values are unique for this object.
|
|
613
|
+
archived: Whether to return only results that have been archived.
|
|
614
|
+
**kwargs: Additional parameters
|
|
615
|
+
|
|
616
|
+
Returns:
|
|
617
|
+
Company
|
|
618
|
+
"""
|
|
619
|
+
params = {k: v for k, v in {
|
|
620
|
+
"companyId": company_id,
|
|
621
|
+
"properties": properties,
|
|
622
|
+
"propertiesWithHistory": properties_with_history,
|
|
623
|
+
"associations": associations,
|
|
624
|
+
"idProperty": id_property,
|
|
625
|
+
"archived": archived,
|
|
626
|
+
**kwargs
|
|
627
|
+
}.items() if v is not None}
|
|
628
|
+
|
|
629
|
+
result = await self._connector.execute("companies", "get", params)
|
|
630
|
+
return result
|
|
631
|
+
|
|
632
|
+
|
|
633
|
+
|
|
634
|
+
async def search(
|
|
635
|
+
self,
|
|
636
|
+
filter_groups: list[CompaniesSearchParamsFiltergroupsItem] | None = None,
|
|
637
|
+
properties: list[str] | None = None,
|
|
638
|
+
limit: int | None = None,
|
|
639
|
+
after: str | None = None,
|
|
640
|
+
sorts: list[CompaniesSearchParamsSortsItem] | None = None,
|
|
641
|
+
query: str | None = None,
|
|
642
|
+
**kwargs
|
|
643
|
+
) -> CompaniesSearchResult:
|
|
644
|
+
"""
|
|
645
|
+
Search for companies by filtering on properties, searching through associations, and sorting results.
|
|
646
|
+
|
|
647
|
+
Args:
|
|
648
|
+
filter_groups: Up to 6 groups of filters defining additional query criteria.
|
|
649
|
+
properties: A list of property names to include in the response.
|
|
650
|
+
limit: Maximum number of results to return
|
|
651
|
+
after: A paging cursor token for retrieving subsequent pages.
|
|
652
|
+
sorts: Sort criteria
|
|
653
|
+
query: The search query string, up to 3000 characters.
|
|
654
|
+
**kwargs: Additional parameters
|
|
655
|
+
|
|
656
|
+
Returns:
|
|
657
|
+
CompaniesSearchResult
|
|
658
|
+
"""
|
|
659
|
+
params = {k: v for k, v in {
|
|
660
|
+
"filterGroups": filter_groups,
|
|
661
|
+
"properties": properties,
|
|
662
|
+
"limit": limit,
|
|
663
|
+
"after": after,
|
|
664
|
+
"sorts": sorts,
|
|
665
|
+
"query": query,
|
|
666
|
+
**kwargs
|
|
667
|
+
}.items() if v is not None}
|
|
668
|
+
|
|
669
|
+
result = await self._connector.execute("companies", "search", params)
|
|
670
|
+
# Cast generic envelope to concrete typed result
|
|
671
|
+
return CompaniesSearchResult(
|
|
672
|
+
data=result.data,
|
|
673
|
+
meta=result.meta )
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
|
|
677
|
+
class DealsQuery:
|
|
678
|
+
"""
|
|
679
|
+
Query class for Deals entity operations.
|
|
680
|
+
"""
|
|
681
|
+
|
|
682
|
+
def __init__(self, connector: HubspotConnector):
|
|
683
|
+
"""Initialize query with connector reference."""
|
|
684
|
+
self._connector = connector
|
|
685
|
+
|
|
686
|
+
async def list(
|
|
687
|
+
self,
|
|
688
|
+
limit: int | None = None,
|
|
689
|
+
after: str | None = None,
|
|
690
|
+
associations: str | None = None,
|
|
691
|
+
properties: str | None = None,
|
|
692
|
+
properties_with_history: str | None = None,
|
|
693
|
+
archived: bool | None = None,
|
|
694
|
+
**kwargs
|
|
695
|
+
) -> DealsListResult:
|
|
696
|
+
"""
|
|
697
|
+
Returns a paginated list of deals
|
|
698
|
+
|
|
699
|
+
Args:
|
|
700
|
+
limit: The maximum number of results to display per page.
|
|
701
|
+
after: The paging cursor token of the last successfully read resource will be returned as the paging.next.after JSON property of a paged response containing more results.
|
|
702
|
+
associations: A comma separated list of associated object types to include in the response. Valid values are contacts, deals, tickets, and custom object type IDs or fully qualified names (e.g., "p12345_cars").
|
|
703
|
+
properties: A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
704
|
+
properties_with_history: A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored. Usage of this parameter will reduce the maximum number of companies that can be read by a single request.
|
|
705
|
+
archived: Whether to return only results that have been archived.
|
|
706
|
+
**kwargs: Additional parameters
|
|
707
|
+
|
|
708
|
+
Returns:
|
|
709
|
+
DealsListResult
|
|
710
|
+
"""
|
|
711
|
+
params = {k: v for k, v in {
|
|
712
|
+
"limit": limit,
|
|
713
|
+
"after": after,
|
|
714
|
+
"associations": associations,
|
|
715
|
+
"properties": properties,
|
|
716
|
+
"propertiesWithHistory": properties_with_history,
|
|
717
|
+
"archived": archived,
|
|
718
|
+
**kwargs
|
|
719
|
+
}.items() if v is not None}
|
|
720
|
+
|
|
721
|
+
result = await self._connector.execute("deals", "list", params)
|
|
722
|
+
# Cast generic envelope to concrete typed result
|
|
723
|
+
return DealsListResult(
|
|
724
|
+
data=result.data,
|
|
725
|
+
meta=result.meta )
|
|
726
|
+
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
async def get(
|
|
730
|
+
self,
|
|
731
|
+
deal_id: str,
|
|
732
|
+
properties: str | None = None,
|
|
733
|
+
properties_with_history: str | None = None,
|
|
734
|
+
associations: str | None = None,
|
|
735
|
+
id_property: str | None = None,
|
|
736
|
+
archived: bool | None = None,
|
|
737
|
+
**kwargs
|
|
738
|
+
) -> Deal:
|
|
739
|
+
"""
|
|
740
|
+
Get a single deal by ID
|
|
741
|
+
|
|
742
|
+
Args:
|
|
743
|
+
deal_id: Deal ID
|
|
744
|
+
properties: A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
745
|
+
properties_with_history: A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
746
|
+
associations: A comma separated list of object types to retrieve associated IDs for. If any of the specified associations do not exist, they will be ignored.
|
|
747
|
+
id_property: The name of a property whose values are unique for this object.
|
|
748
|
+
archived: Whether to return only results that have been archived.
|
|
749
|
+
**kwargs: Additional parameters
|
|
750
|
+
|
|
751
|
+
Returns:
|
|
752
|
+
Deal
|
|
753
|
+
"""
|
|
754
|
+
params = {k: v for k, v in {
|
|
755
|
+
"dealId": deal_id,
|
|
756
|
+
"properties": properties,
|
|
757
|
+
"propertiesWithHistory": properties_with_history,
|
|
758
|
+
"associations": associations,
|
|
759
|
+
"idProperty": id_property,
|
|
760
|
+
"archived": archived,
|
|
761
|
+
**kwargs
|
|
762
|
+
}.items() if v is not None}
|
|
763
|
+
|
|
764
|
+
result = await self._connector.execute("deals", "get", params)
|
|
765
|
+
return result
|
|
766
|
+
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
async def search(
|
|
770
|
+
self,
|
|
771
|
+
filter_groups: list[DealsSearchParamsFiltergroupsItem] | None = None,
|
|
772
|
+
properties: list[str] | None = None,
|
|
773
|
+
limit: int | None = None,
|
|
774
|
+
after: str | None = None,
|
|
775
|
+
sorts: list[DealsSearchParamsSortsItem] | None = None,
|
|
776
|
+
query: str | None = None,
|
|
777
|
+
**kwargs
|
|
778
|
+
) -> DealsSearchResult:
|
|
779
|
+
"""
|
|
780
|
+
Search deals with filters and sorting
|
|
781
|
+
|
|
782
|
+
Args:
|
|
783
|
+
filter_groups: Up to 6 groups of filters defining additional query criteria.
|
|
784
|
+
properties: A list of property names to include in the response.
|
|
785
|
+
limit: Maximum number of results to return
|
|
786
|
+
after: A paging cursor token for retrieving subsequent pages.
|
|
787
|
+
sorts: Sort criteria
|
|
788
|
+
query: The search query string, up to 3000 characters.
|
|
789
|
+
**kwargs: Additional parameters
|
|
790
|
+
|
|
791
|
+
Returns:
|
|
792
|
+
DealsSearchResult
|
|
793
|
+
"""
|
|
794
|
+
params = {k: v for k, v in {
|
|
795
|
+
"filterGroups": filter_groups,
|
|
796
|
+
"properties": properties,
|
|
797
|
+
"limit": limit,
|
|
798
|
+
"after": after,
|
|
799
|
+
"sorts": sorts,
|
|
800
|
+
"query": query,
|
|
801
|
+
**kwargs
|
|
802
|
+
}.items() if v is not None}
|
|
803
|
+
|
|
804
|
+
result = await self._connector.execute("deals", "search", params)
|
|
805
|
+
# Cast generic envelope to concrete typed result
|
|
806
|
+
return DealsSearchResult(
|
|
807
|
+
data=result.data,
|
|
808
|
+
meta=result.meta )
|
|
809
|
+
|
|
810
|
+
|
|
811
|
+
|
|
812
|
+
class TicketsQuery:
|
|
813
|
+
"""
|
|
814
|
+
Query class for Tickets entity operations.
|
|
815
|
+
"""
|
|
816
|
+
|
|
817
|
+
def __init__(self, connector: HubspotConnector):
|
|
818
|
+
"""Initialize query with connector reference."""
|
|
819
|
+
self._connector = connector
|
|
820
|
+
|
|
821
|
+
async def list(
|
|
822
|
+
self,
|
|
823
|
+
limit: int | None = None,
|
|
824
|
+
after: str | None = None,
|
|
825
|
+
associations: str | None = None,
|
|
826
|
+
properties: str | None = None,
|
|
827
|
+
properties_with_history: str | None = None,
|
|
828
|
+
archived: bool | None = None,
|
|
829
|
+
**kwargs
|
|
830
|
+
) -> TicketsListResult:
|
|
831
|
+
"""
|
|
832
|
+
Returns a paginated list of tickets
|
|
833
|
+
|
|
834
|
+
Args:
|
|
835
|
+
limit: The maximum number of results to display per page.
|
|
836
|
+
after: The paging cursor token of the last successfully read resource will be returned as the paging.next.after JSON property of a paged response containing more results.
|
|
837
|
+
associations: A comma separated list of associated object types to include in the response. Valid values are contacts, deals, tickets, and custom object type IDs or fully qualified names (e.g., "p12345_cars").
|
|
838
|
+
properties: A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
839
|
+
properties_with_history: A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored. Usage of this parameter will reduce the maximum number of companies that can be read by a single request.
|
|
840
|
+
archived: Whether to return only results that have been archived.
|
|
841
|
+
**kwargs: Additional parameters
|
|
842
|
+
|
|
843
|
+
Returns:
|
|
844
|
+
TicketsListResult
|
|
845
|
+
"""
|
|
846
|
+
params = {k: v for k, v in {
|
|
847
|
+
"limit": limit,
|
|
848
|
+
"after": after,
|
|
849
|
+
"associations": associations,
|
|
850
|
+
"properties": properties,
|
|
851
|
+
"propertiesWithHistory": properties_with_history,
|
|
852
|
+
"archived": archived,
|
|
853
|
+
**kwargs
|
|
854
|
+
}.items() if v is not None}
|
|
855
|
+
|
|
856
|
+
result = await self._connector.execute("tickets", "list", params)
|
|
857
|
+
# Cast generic envelope to concrete typed result
|
|
858
|
+
return TicketsListResult(
|
|
859
|
+
data=result.data,
|
|
860
|
+
meta=result.meta )
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
|
|
864
|
+
async def get(
|
|
865
|
+
self,
|
|
866
|
+
ticket_id: str,
|
|
867
|
+
properties: str | None = None,
|
|
868
|
+
properties_with_history: str | None = None,
|
|
869
|
+
associations: str | None = None,
|
|
870
|
+
id_property: str | None = None,
|
|
871
|
+
archived: bool | None = None,
|
|
872
|
+
**kwargs
|
|
873
|
+
) -> Ticket:
|
|
874
|
+
"""
|
|
875
|
+
Get a single ticket by ID
|
|
876
|
+
|
|
877
|
+
Args:
|
|
878
|
+
ticket_id: Ticket ID
|
|
879
|
+
properties: A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
880
|
+
properties_with_history: A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
881
|
+
associations: A comma separated list of object types to retrieve associated IDs for. If any of the specified associations do not exist, they will be ignored.
|
|
882
|
+
id_property: The name of a property whose values are unique for this object.
|
|
883
|
+
archived: Whether to return only results that have been archived.
|
|
884
|
+
**kwargs: Additional parameters
|
|
885
|
+
|
|
886
|
+
Returns:
|
|
887
|
+
Ticket
|
|
888
|
+
"""
|
|
889
|
+
params = {k: v for k, v in {
|
|
890
|
+
"ticketId": ticket_id,
|
|
891
|
+
"properties": properties,
|
|
892
|
+
"propertiesWithHistory": properties_with_history,
|
|
893
|
+
"associations": associations,
|
|
894
|
+
"idProperty": id_property,
|
|
895
|
+
"archived": archived,
|
|
896
|
+
**kwargs
|
|
897
|
+
}.items() if v is not None}
|
|
898
|
+
|
|
899
|
+
result = await self._connector.execute("tickets", "get", params)
|
|
900
|
+
return result
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
|
|
904
|
+
async def search(
|
|
905
|
+
self,
|
|
906
|
+
filter_groups: list[TicketsSearchParamsFiltergroupsItem] | None = None,
|
|
907
|
+
properties: list[str] | None = None,
|
|
908
|
+
limit: int | None = None,
|
|
909
|
+
after: str | None = None,
|
|
910
|
+
sorts: list[TicketsSearchParamsSortsItem] | None = None,
|
|
911
|
+
query: str | None = None,
|
|
912
|
+
**kwargs
|
|
913
|
+
) -> TicketsSearchResult:
|
|
914
|
+
"""
|
|
915
|
+
Search for tickets by filtering on properties, searching through associations, and sorting results.
|
|
916
|
+
|
|
917
|
+
Args:
|
|
918
|
+
filter_groups: Up to 6 groups of filters defining additional query criteria.
|
|
919
|
+
properties: A list of property names to include in the response.
|
|
920
|
+
limit: Maximum number of results to return
|
|
921
|
+
after: A paging cursor token for retrieving subsequent pages.
|
|
922
|
+
sorts: Sort criteria
|
|
923
|
+
query: The search query string, up to 3000 characters.
|
|
924
|
+
**kwargs: Additional parameters
|
|
925
|
+
|
|
926
|
+
Returns:
|
|
927
|
+
TicketsSearchResult
|
|
928
|
+
"""
|
|
929
|
+
params = {k: v for k, v in {
|
|
930
|
+
"filterGroups": filter_groups,
|
|
931
|
+
"properties": properties,
|
|
932
|
+
"limit": limit,
|
|
933
|
+
"after": after,
|
|
934
|
+
"sorts": sorts,
|
|
935
|
+
"query": query,
|
|
936
|
+
**kwargs
|
|
937
|
+
}.items() if v is not None}
|
|
938
|
+
|
|
939
|
+
result = await self._connector.execute("tickets", "search", params)
|
|
940
|
+
# Cast generic envelope to concrete typed result
|
|
941
|
+
return TicketsSearchResult(
|
|
942
|
+
data=result.data,
|
|
943
|
+
meta=result.meta )
|
|
944
|
+
|
|
945
|
+
|
|
946
|
+
|
|
947
|
+
class SchemasQuery:
|
|
948
|
+
"""
|
|
949
|
+
Query class for Schemas entity operations.
|
|
950
|
+
"""
|
|
951
|
+
|
|
952
|
+
def __init__(self, connector: HubspotConnector):
|
|
953
|
+
"""Initialize query with connector reference."""
|
|
954
|
+
self._connector = connector
|
|
955
|
+
|
|
956
|
+
async def list(
|
|
957
|
+
self,
|
|
958
|
+
archived: bool | None = None,
|
|
959
|
+
**kwargs
|
|
960
|
+
) -> SchemasListResult:
|
|
961
|
+
"""
|
|
962
|
+
Returns all custom object schemas to discover available custom objects
|
|
963
|
+
|
|
964
|
+
Args:
|
|
965
|
+
archived: Whether to return only results that have been archived.
|
|
966
|
+
**kwargs: Additional parameters
|
|
967
|
+
|
|
968
|
+
Returns:
|
|
969
|
+
SchemasListResult
|
|
970
|
+
"""
|
|
971
|
+
params = {k: v for k, v in {
|
|
972
|
+
"archived": archived,
|
|
973
|
+
**kwargs
|
|
974
|
+
}.items() if v is not None}
|
|
975
|
+
|
|
976
|
+
result = await self._connector.execute("schemas", "list", params)
|
|
977
|
+
# Cast generic envelope to concrete typed result
|
|
978
|
+
return SchemasListResult(
|
|
979
|
+
data=result.data )
|
|
980
|
+
|
|
981
|
+
|
|
982
|
+
|
|
983
|
+
async def get(
|
|
984
|
+
self,
|
|
985
|
+
object_type: str,
|
|
986
|
+
**kwargs
|
|
987
|
+
) -> Schema:
|
|
988
|
+
"""
|
|
989
|
+
Get the schema for a specific custom object type
|
|
990
|
+
|
|
991
|
+
Args:
|
|
992
|
+
object_type: Fully qualified name or object type ID of your schema.
|
|
993
|
+
**kwargs: Additional parameters
|
|
994
|
+
|
|
995
|
+
Returns:
|
|
996
|
+
Schema
|
|
997
|
+
"""
|
|
998
|
+
params = {k: v for k, v in {
|
|
999
|
+
"objectType": object_type,
|
|
1000
|
+
**kwargs
|
|
1001
|
+
}.items() if v is not None}
|
|
1002
|
+
|
|
1003
|
+
result = await self._connector.execute("schemas", "get", params)
|
|
1004
|
+
return result
|
|
1005
|
+
|
|
1006
|
+
|
|
1007
|
+
|
|
1008
|
+
class ObjectsQuery:
|
|
1009
|
+
"""
|
|
1010
|
+
Query class for Objects entity operations.
|
|
1011
|
+
"""
|
|
1012
|
+
|
|
1013
|
+
def __init__(self, connector: HubspotConnector):
|
|
1014
|
+
"""Initialize query with connector reference."""
|
|
1015
|
+
self._connector = connector
|
|
1016
|
+
|
|
1017
|
+
async def list(
|
|
1018
|
+
self,
|
|
1019
|
+
object_type: str,
|
|
1020
|
+
limit: int | None = None,
|
|
1021
|
+
after: str | None = None,
|
|
1022
|
+
properties: str | None = None,
|
|
1023
|
+
archived: bool | None = None,
|
|
1024
|
+
associations: str | None = None,
|
|
1025
|
+
properties_with_history: str | None = None,
|
|
1026
|
+
**kwargs
|
|
1027
|
+
) -> ObjectsListResult:
|
|
1028
|
+
"""
|
|
1029
|
+
Read a page of objects. Control what is returned via the properties query param.
|
|
1030
|
+
|
|
1031
|
+
Args:
|
|
1032
|
+
object_type: Object type ID or fully qualified name (e.g., "cars" or "p12345_cars")
|
|
1033
|
+
limit: The maximum number of results to display per page.
|
|
1034
|
+
after: The paging cursor token of the last successfully read resource will be returned as the `paging.next.after` JSON property of a paged response containing more results.
|
|
1035
|
+
properties: A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
1036
|
+
archived: Whether to return only results that have been archived.
|
|
1037
|
+
associations: A comma separated list of object types to retrieve associated IDs for. If any of the specified associations do not exist, they will be ignored.
|
|
1038
|
+
properties_with_history: A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
1039
|
+
**kwargs: Additional parameters
|
|
1040
|
+
|
|
1041
|
+
Returns:
|
|
1042
|
+
ObjectsListResult
|
|
1043
|
+
"""
|
|
1044
|
+
params = {k: v for k, v in {
|
|
1045
|
+
"objectType": object_type,
|
|
1046
|
+
"limit": limit,
|
|
1047
|
+
"after": after,
|
|
1048
|
+
"properties": properties,
|
|
1049
|
+
"archived": archived,
|
|
1050
|
+
"associations": associations,
|
|
1051
|
+
"propertiesWithHistory": properties_with_history,
|
|
1052
|
+
**kwargs
|
|
1053
|
+
}.items() if v is not None}
|
|
1054
|
+
|
|
1055
|
+
result = await self._connector.execute("objects", "list", params)
|
|
1056
|
+
# Cast generic envelope to concrete typed result
|
|
1057
|
+
return ObjectsListResult(
|
|
1058
|
+
data=result.data,
|
|
1059
|
+
meta=result.meta )
|
|
1060
|
+
|
|
1061
|
+
|
|
1062
|
+
|
|
1063
|
+
async def get(
|
|
1064
|
+
self,
|
|
1065
|
+
object_type: str,
|
|
1066
|
+
object_id: str,
|
|
1067
|
+
properties: str | None = None,
|
|
1068
|
+
archived: bool | None = None,
|
|
1069
|
+
associations: str | None = None,
|
|
1070
|
+
id_property: str | None = None,
|
|
1071
|
+
properties_with_history: str | None = None,
|
|
1072
|
+
**kwargs
|
|
1073
|
+
) -> CRMObject:
|
|
1074
|
+
"""
|
|
1075
|
+
Read an Object identified by {objectId}. {objectId} refers to the internal object ID by default, or optionally any unique property value as specified by the idProperty query param. Control what is returned via the properties query param.
|
|
1076
|
+
|
|
1077
|
+
Args:
|
|
1078
|
+
object_type: Object type ID or fully qualified name
|
|
1079
|
+
object_id: Object record ID
|
|
1080
|
+
properties: A comma separated list of the properties to be returned in the response. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
1081
|
+
archived: Whether to return only results that have been archived.
|
|
1082
|
+
associations: A comma separated list of object types to retrieve associated IDs for. If any of the specified associations do not exist, they will be ignored.
|
|
1083
|
+
id_property: The name of a property whose values are unique for this object.
|
|
1084
|
+
properties_with_history: A comma separated list of the properties to be returned along with their history of previous values. If any of the specified properties are not present on the requested object(s), they will be ignored.
|
|
1085
|
+
**kwargs: Additional parameters
|
|
1086
|
+
|
|
1087
|
+
Returns:
|
|
1088
|
+
CRMObject
|
|
1089
|
+
"""
|
|
1090
|
+
params = {k: v for k, v in {
|
|
1091
|
+
"objectType": object_type,
|
|
1092
|
+
"objectId": object_id,
|
|
1093
|
+
"properties": properties,
|
|
1094
|
+
"archived": archived,
|
|
1095
|
+
"associations": associations,
|
|
1096
|
+
"idProperty": id_property,
|
|
1097
|
+
"propertiesWithHistory": properties_with_history,
|
|
1098
|
+
**kwargs
|
|
1099
|
+
}.items() if v is not None}
|
|
1100
|
+
|
|
1101
|
+
result = await self._connector.execute("objects", "get", params)
|
|
1102
|
+
return result
|
|
1103
|
+
|
|
1104
|
+
|