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.
Files changed (55) hide show
  1. airbyte_agent_hubspot/__init__.py +86 -0
  2. airbyte_agent_hubspot/_vendored/__init__.py +1 -0
  3. airbyte_agent_hubspot/_vendored/connector_sdk/__init__.py +82 -0
  4. airbyte_agent_hubspot/_vendored/connector_sdk/auth_strategies.py +1123 -0
  5. airbyte_agent_hubspot/_vendored/connector_sdk/auth_template.py +135 -0
  6. airbyte_agent_hubspot/_vendored/connector_sdk/cloud_utils/__init__.py +5 -0
  7. airbyte_agent_hubspot/_vendored/connector_sdk/cloud_utils/client.py +213 -0
  8. airbyte_agent_hubspot/_vendored/connector_sdk/connector_model_loader.py +957 -0
  9. airbyte_agent_hubspot/_vendored/connector_sdk/constants.py +78 -0
  10. airbyte_agent_hubspot/_vendored/connector_sdk/exceptions.py +23 -0
  11. airbyte_agent_hubspot/_vendored/connector_sdk/executor/__init__.py +31 -0
  12. airbyte_agent_hubspot/_vendored/connector_sdk/executor/hosted_executor.py +197 -0
  13. airbyte_agent_hubspot/_vendored/connector_sdk/executor/local_executor.py +1504 -0
  14. airbyte_agent_hubspot/_vendored/connector_sdk/executor/models.py +190 -0
  15. airbyte_agent_hubspot/_vendored/connector_sdk/extensions.py +655 -0
  16. airbyte_agent_hubspot/_vendored/connector_sdk/http/__init__.py +37 -0
  17. airbyte_agent_hubspot/_vendored/connector_sdk/http/adapters/__init__.py +9 -0
  18. airbyte_agent_hubspot/_vendored/connector_sdk/http/adapters/httpx_adapter.py +251 -0
  19. airbyte_agent_hubspot/_vendored/connector_sdk/http/config.py +98 -0
  20. airbyte_agent_hubspot/_vendored/connector_sdk/http/exceptions.py +119 -0
  21. airbyte_agent_hubspot/_vendored/connector_sdk/http/protocols.py +114 -0
  22. airbyte_agent_hubspot/_vendored/connector_sdk/http/response.py +102 -0
  23. airbyte_agent_hubspot/_vendored/connector_sdk/http_client.py +679 -0
  24. airbyte_agent_hubspot/_vendored/connector_sdk/logging/__init__.py +11 -0
  25. airbyte_agent_hubspot/_vendored/connector_sdk/logging/logger.py +264 -0
  26. airbyte_agent_hubspot/_vendored/connector_sdk/logging/types.py +92 -0
  27. airbyte_agent_hubspot/_vendored/connector_sdk/observability/__init__.py +11 -0
  28. airbyte_agent_hubspot/_vendored/connector_sdk/observability/models.py +19 -0
  29. airbyte_agent_hubspot/_vendored/connector_sdk/observability/redactor.py +81 -0
  30. airbyte_agent_hubspot/_vendored/connector_sdk/observability/session.py +94 -0
  31. airbyte_agent_hubspot/_vendored/connector_sdk/performance/__init__.py +6 -0
  32. airbyte_agent_hubspot/_vendored/connector_sdk/performance/instrumentation.py +57 -0
  33. airbyte_agent_hubspot/_vendored/connector_sdk/performance/metrics.py +93 -0
  34. airbyte_agent_hubspot/_vendored/connector_sdk/schema/__init__.py +75 -0
  35. airbyte_agent_hubspot/_vendored/connector_sdk/schema/base.py +161 -0
  36. airbyte_agent_hubspot/_vendored/connector_sdk/schema/components.py +238 -0
  37. airbyte_agent_hubspot/_vendored/connector_sdk/schema/connector.py +131 -0
  38. airbyte_agent_hubspot/_vendored/connector_sdk/schema/extensions.py +109 -0
  39. airbyte_agent_hubspot/_vendored/connector_sdk/schema/operations.py +146 -0
  40. airbyte_agent_hubspot/_vendored/connector_sdk/schema/security.py +213 -0
  41. airbyte_agent_hubspot/_vendored/connector_sdk/secrets.py +182 -0
  42. airbyte_agent_hubspot/_vendored/connector_sdk/telemetry/__init__.py +10 -0
  43. airbyte_agent_hubspot/_vendored/connector_sdk/telemetry/config.py +32 -0
  44. airbyte_agent_hubspot/_vendored/connector_sdk/telemetry/events.py +58 -0
  45. airbyte_agent_hubspot/_vendored/connector_sdk/telemetry/tracker.py +151 -0
  46. airbyte_agent_hubspot/_vendored/connector_sdk/types.py +241 -0
  47. airbyte_agent_hubspot/_vendored/connector_sdk/utils.py +60 -0
  48. airbyte_agent_hubspot/_vendored/connector_sdk/validation.py +822 -0
  49. airbyte_agent_hubspot/connector.py +1104 -0
  50. airbyte_agent_hubspot/connector_model.py +2660 -0
  51. airbyte_agent_hubspot/models.py +438 -0
  52. airbyte_agent_hubspot/types.py +217 -0
  53. airbyte_agent_hubspot-0.15.20.dist-info/METADATA +105 -0
  54. airbyte_agent_hubspot-0.15.20.dist-info/RECORD +55 -0
  55. 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
+