airbyte-agent-amazon-ads 0.1.6__tar.gz → 0.1.11__tar.gz

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 (62) hide show
  1. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/AUTH.md +3 -3
  2. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/CHANGELOG.md +25 -0
  3. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/PKG-INFO +8 -7
  4. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/README.md +7 -6
  5. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/REFERENCE.md +71 -1
  6. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/__init__.py +20 -2
  7. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/connector_model_loader.py +138 -0
  8. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/executor/local_executor.py +3 -1
  9. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/introspection.py +222 -10
  10. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/base.py +3 -1
  11. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/components.py +5 -0
  12. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/extensions.py +71 -0
  13. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/types.py +1 -0
  14. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/connector.py +166 -38
  15. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/connector_model.py +1144 -2
  16. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/models.py +55 -0
  17. airbyte_agent_amazon_ads-0.1.11/airbyte_agent_amazon_ads/types.py +238 -0
  18. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/pyproject.toml +1 -1
  19. airbyte_agent_amazon_ads-0.1.6/airbyte_agent_amazon_ads/types.py +0 -48
  20. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/.gitignore +0 -0
  21. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/__init__.py +0 -0
  22. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/__init__.py +0 -0
  23. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/auth_strategies.py +0 -0
  24. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/auth_template.py +0 -0
  25. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/cloud_utils/__init__.py +0 -0
  26. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/cloud_utils/client.py +0 -0
  27. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/constants.py +0 -0
  28. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/exceptions.py +0 -0
  29. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/executor/__init__.py +0 -0
  30. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/executor/hosted_executor.py +0 -0
  31. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/executor/models.py +0 -0
  32. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/extensions.py +0 -0
  33. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/__init__.py +0 -0
  34. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/adapters/__init__.py +0 -0
  35. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/adapters/httpx_adapter.py +0 -0
  36. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/config.py +0 -0
  37. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/exceptions.py +0 -0
  38. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/protocols.py +0 -0
  39. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/response.py +0 -0
  40. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http_client.py +0 -0
  41. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/logging/__init__.py +0 -0
  42. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/logging/logger.py +0 -0
  43. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/logging/types.py +0 -0
  44. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/observability/__init__.py +0 -0
  45. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/observability/config.py +0 -0
  46. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/observability/models.py +0 -0
  47. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/observability/redactor.py +0 -0
  48. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/observability/session.py +0 -0
  49. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/performance/__init__.py +0 -0
  50. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/performance/instrumentation.py +0 -0
  51. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/performance/metrics.py +0 -0
  52. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/__init__.py +0 -0
  53. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/connector.py +0 -0
  54. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/operations.py +0 -0
  55. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/security.py +0 -0
  56. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/secrets.py +0 -0
  57. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/telemetry/__init__.py +0 -0
  58. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/telemetry/config.py +0 -0
  59. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/telemetry/events.py +0 -0
  60. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/telemetry/tracker.py +0 -0
  61. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/utils.py +0 -0
  62. {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.11}/airbyte_agent_amazon_ads/_vendored/connector_sdk/validation.py +0 -0
@@ -69,13 +69,13 @@ After creating the connector, execute operations using either the Python SDK or
69
69
  from airbyte_agent_amazon-ads import AmazonAdsConnector
70
70
 
71
71
  connector = AmazonAdsConnector(
72
- external_user_id="<your-scoped-token>",
72
+ external_user_id="<your_external_user_id>",
73
73
  airbyte_client_id="<your-client-id>",
74
74
  airbyte_client_secret="<your-client-secret>"
75
75
  )
76
76
 
77
77
  @agent.tool_plain # assumes you're using Pydantic AI
78
- @AmazonAdsConnector.describe
78
+ @AmazonAdsConnector.tool_utils
79
79
  async def amazon-ads_execute(entity: str, action: str, params: dict | None = None):
80
80
  return await connector.execute(entity, action, params or {})
81
81
  ```
@@ -96,7 +96,7 @@ The Amazon-Ads connector requires the following configuration variables. These v
96
96
 
97
97
  | Variable | Type | Required | Default | Description |
98
98
  |----------|------|----------|---------|-------------|
99
- | `region_url` | `string` | Yes | https://advertising-api.amazon.com | The Amazon Ads API endpoint URL based on region:
99
+ | `region` | `string` | Yes | https://advertising-api.amazon.com | The Amazon Ads API endpoint URL based on region:
100
100
  - NA (North America): https://advertising-api.amazon.com
101
101
  - EU (Europe): https://advertising-api-eu.amazon.com
102
102
  - FE (Far East): https://advertising-api-fe.amazon.com
@@ -1,5 +1,30 @@
1
1
  # Amazon Ads changelog
2
2
 
3
+ ## [0.1.11] - 2026-01-26
4
+ - Updated connector definition (YAML version 1.0.3)
5
+ - Source commit: 74809153
6
+ - SDK version: 0.1.0
7
+
8
+ ## [0.1.10] - 2026-01-26
9
+ - Updated connector definition (YAML version 1.0.3)
10
+ - Source commit: b73c71e0
11
+ - SDK version: 0.1.0
12
+
13
+ ## [0.1.9] - 2026-01-24
14
+ - Updated connector definition (YAML version 1.0.3)
15
+ - Source commit: 609c1d86
16
+ - SDK version: 0.1.0
17
+
18
+ ## [0.1.8] - 2026-01-23
19
+ - Updated connector definition (YAML version 1.0.3)
20
+ - Source commit: 6b458f8d
21
+ - SDK version: 0.1.0
22
+
23
+ ## [0.1.7] - 2026-01-23
24
+ - Updated connector definition (YAML version 1.0.2)
25
+ - Source commit: 32c5ef46
26
+ - SDK version: 0.1.0
27
+
3
28
  ## [0.1.6] - 2026-01-23
4
29
  - Updated connector definition (YAML version 1.0.1)
5
30
  - Source commit: 416466da
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: airbyte-agent-amazon-ads
3
- Version: 0.1.6
3
+ Version: 0.1.11
4
4
  Summary: Airbyte Amazon-Ads Connector for AI platforms
5
5
  Project-URL: Homepage, https://github.com/airbytehq/airbyte-agent-connectors
6
6
  Project-URL: Documentation, https://docs.airbyte.com/ai-agents/
@@ -86,7 +86,7 @@ connector = AmazonAdsConnector(
86
86
  )
87
87
 
88
88
  @agent.tool_plain # assumes you're using Pydantic AI
89
- @AmazonAdsConnector.describe
89
+ @AmazonAdsConnector.tool_utils
90
90
  async def amazon-ads_execute(entity: str, action: str, params: dict | None = None):
91
91
  return await connector.execute(entity, action, params or {})
92
92
  ```
@@ -101,17 +101,18 @@ This example assumes you've already authenticated your connector with Airbyte. S
101
101
  from airbyte_agent_amazon-ads import AmazonAdsConnector
102
102
 
103
103
  connector = AmazonAdsConnector(
104
- external_user_id="<your-scoped-token>",
104
+ external_user_id="<your_external_user_id>",
105
105
  airbyte_client_id="<your-client-id>",
106
106
  airbyte_client_secret="<your-client-secret>"
107
107
  )
108
108
 
109
109
  @agent.tool_plain # assumes you're using Pydantic AI
110
- @AmazonAdsConnector.describe
110
+ @AmazonAdsConnector.tool_utils
111
111
  async def amazon-ads_execute(entity: str, action: str, params: dict | None = None):
112
112
  return await connector.execute(entity, action, params or {})
113
113
  ```
114
114
 
115
+
115
116
  ## Full documentation
116
117
 
117
118
  This connector supports the following entities and actions.
@@ -131,6 +132,6 @@ For the service's official API docs, see the [Amazon-Ads API reference](https://
131
132
 
132
133
  ## Version information
133
134
 
134
- - **Package version:** 0.1.6
135
- - **Connector version:** 1.0.1
136
- - **Generated with Connector SDK commit SHA:** 416466da4970ae5fd6c7f2c658a68e047e51efd9
135
+ - **Package version:** 0.1.11
136
+ - **Connector version:** 1.0.3
137
+ - **Generated with Connector SDK commit SHA:** 74809153299f81ed3e220538146012ee2abd2e0d
@@ -53,7 +53,7 @@ connector = AmazonAdsConnector(
53
53
  )
54
54
 
55
55
  @agent.tool_plain # assumes you're using Pydantic AI
56
- @AmazonAdsConnector.describe
56
+ @AmazonAdsConnector.tool_utils
57
57
  async def amazon-ads_execute(entity: str, action: str, params: dict | None = None):
58
58
  return await connector.execute(entity, action, params or {})
59
59
  ```
@@ -68,17 +68,18 @@ This example assumes you've already authenticated your connector with Airbyte. S
68
68
  from airbyte_agent_amazon-ads import AmazonAdsConnector
69
69
 
70
70
  connector = AmazonAdsConnector(
71
- external_user_id="<your-scoped-token>",
71
+ external_user_id="<your_external_user_id>",
72
72
  airbyte_client_id="<your-client-id>",
73
73
  airbyte_client_secret="<your-client-secret>"
74
74
  )
75
75
 
76
76
  @agent.tool_plain # assumes you're using Pydantic AI
77
- @AmazonAdsConnector.describe
77
+ @AmazonAdsConnector.tool_utils
78
78
  async def amazon-ads_execute(entity: str, action: str, params: dict | None = None):
79
79
  return await connector.execute(entity, action, params or {})
80
80
  ```
81
81
 
82
+
82
83
  ## Full documentation
83
84
 
84
85
  This connector supports the following entities and actions.
@@ -98,6 +99,6 @@ For the service's official API docs, see the [Amazon-Ads API reference](https://
98
99
 
99
100
  ## Version information
100
101
 
101
- - **Package version:** 0.1.6
102
- - **Connector version:** 1.0.1
103
- - **Generated with Connector SDK commit SHA:** 416466da4970ae5fd6c7f2c658a68e047e51efd9
102
+ - **Package version:** 0.1.11
103
+ - **Connector version:** 1.0.3
104
+ - **Generated with Connector SDK commit SHA:** 74809153299f81ed3e220538146012ee2abd2e0d
@@ -8,7 +8,7 @@ The Amazon-Ads connector supports the following entities and actions.
8
8
 
9
9
  | Entity | Actions |
10
10
  |--------|---------|
11
- | Profiles | [List](#profiles-list), [Get](#profiles-get) |
11
+ | Profiles | [List](#profiles-list), [Get](#profiles-get), [Search](#profiles-search) |
12
12
  | Portfolios | [List](#portfolios-list), [Get](#portfolios-get) |
13
13
  | Sponsored Product Campaigns | [List](#sponsored-product-campaigns-list), [Get](#sponsored-product-campaigns-get) |
14
14
 
@@ -119,6 +119,75 @@ curl --location 'https://api.airbyte.ai/api/v1/connectors/sources/{your_source_i
119
119
  | `accountInfo` | `object \| any` | |
120
120
 
121
121
 
122
+ </details>
123
+
124
+ ### Profiles Search
125
+
126
+ Search and filter profiles records powered by Airbyte's data sync. This often provides additional fields and operators beyond what the API natively supports, making it easier to narrow down results before performing further operations. Only available in hosted mode.
127
+
128
+ #### Python SDK
129
+
130
+ ```python
131
+ await amazon_ads.profiles.search(
132
+ query={"filter": {"eq": {"accountInfo": {}}}}
133
+ )
134
+ ```
135
+
136
+ #### API
137
+
138
+ ```bash
139
+ curl --location 'https://api.airbyte.ai/api/v1/connectors/sources/{your_source_id}/execute' \
140
+ --header 'Content-Type: application/json' \
141
+ --header 'Authorization: Bearer {your_auth_token}' \
142
+ --data '{
143
+ "entity": "profiles",
144
+ "action": "search",
145
+ "params": {
146
+ "query": {"filter": {"eq": {"accountInfo": {}}}}
147
+ }
148
+ }'
149
+ ```
150
+
151
+ #### Parameters
152
+
153
+ | Parameter Name | Type | Required | Description |
154
+ |----------------|------|----------|-------------|
155
+ | `query` | `object` | Yes | Filter and sort conditions. Supports operators: eq, neq, gt, gte, lt, lte, in, like, fuzzy, keyword, not, and, or |
156
+ | `query.filter` | `object` | No | Filter conditions |
157
+ | `query.sort` | `array` | No | Sort conditions |
158
+ | `limit` | `integer` | No | Maximum results to return (default 1000) |
159
+ | `cursor` | `string` | No | Pagination cursor from previous response's next_cursor |
160
+ | `fields` | `array` | No | Field paths to include in results |
161
+
162
+ #### Searchable Fields
163
+
164
+ | Field Name | Type | Description |
165
+ |------------|------|-------------|
166
+ | `accountInfo` | `object` | |
167
+ | `countryCode` | `string` | |
168
+ | `currencyCode` | `string` | |
169
+ | `dailyBudget` | `number` | |
170
+ | `profileId` | `integer` | |
171
+ | `timezone` | `string` | |
172
+
173
+ <details>
174
+ <summary><b>Response Schema</b></summary>
175
+
176
+ | Field Name | Type | Description |
177
+ |------------|------|-------------|
178
+ | `hits` | `array` | List of matching records |
179
+ | `hits[].id` | `string` | Record identifier |
180
+ | `hits[].score` | `number` | Relevance score |
181
+ | `hits[].data` | `object` | Record data containing the searchable fields listed above |
182
+ | `hits[].data.accountInfo` | `object` | |
183
+ | `hits[].data.countryCode` | `string` | |
184
+ | `hits[].data.currencyCode` | `string` | |
185
+ | `hits[].data.dailyBudget` | `number` | |
186
+ | `hits[].data.profileId` | `integer` | |
187
+ | `hits[].data.timezone` | `string` | |
188
+ | `next_cursor` | `string \| null` | Cursor for next page of results |
189
+ | `took_ms` | `number` | Query execution time in milliseconds |
190
+
122
191
  </details>
123
192
 
124
193
  ## Portfolios
@@ -311,3 +380,4 @@ curl --location 'https://api.airbyte.ai/api/v1/connectors/sources/{your_source_i
311
380
 
312
381
  </details>
313
382
 
383
+
@@ -19,7 +19,11 @@ from .models import (
19
19
  AmazonAdsExecuteResultWithMeta,
20
20
  ProfilesListResult,
21
21
  PortfoliosListResult,
22
- SponsoredProductCampaignsListResult
22
+ SponsoredProductCampaignsListResult,
23
+ AirbyteSearchHit,
24
+ AirbyteSearchResult,
25
+ ProfilesSearchData,
26
+ ProfilesSearchResult
23
27
  )
24
28
  from .types import (
25
29
  SponsoredProductCampaignsListParamsStatefilter,
@@ -28,7 +32,12 @@ from .types import (
28
32
  PortfoliosListParams,
29
33
  PortfoliosGetParams,
30
34
  SponsoredProductCampaignsListParams,
31
- SponsoredProductCampaignsGetParams
35
+ SponsoredProductCampaignsGetParams,
36
+ AirbyteSearchParams,
37
+ AirbyteSortOrder,
38
+ ProfilesSearchFilter,
39
+ ProfilesSearchQuery,
40
+ ProfilesCondition
32
41
  )
33
42
 
34
43
  __all__ = [
@@ -47,6 +56,10 @@ __all__ = [
47
56
  "ProfilesListResult",
48
57
  "PortfoliosListResult",
49
58
  "SponsoredProductCampaignsListResult",
59
+ "AirbyteSearchHit",
60
+ "AirbyteSearchResult",
61
+ "ProfilesSearchData",
62
+ "ProfilesSearchResult",
50
63
  "SponsoredProductCampaignsListParamsStatefilter",
51
64
  "ProfilesListParams",
52
65
  "ProfilesGetParams",
@@ -54,4 +67,9 @@ __all__ = [
54
67
  "PortfoliosGetParams",
55
68
  "SponsoredProductCampaignsListParams",
56
69
  "SponsoredProductCampaignsGetParams",
70
+ "AirbyteSearchParams",
71
+ "AirbyteSortOrder",
72
+ "ProfilesSearchFilter",
73
+ "ProfilesSearchQuery",
74
+ "ProfilesCondition",
57
75
  ]
@@ -62,6 +62,53 @@ class TokenExtractValidationError(ConnectorModelLoaderError):
62
62
  pass
63
63
 
64
64
 
65
+ # Expected auth_mapping keys for each auth type.
66
+ # These are the auth parameters that each security scheme expects, NOT the user's credential field names.
67
+ EXPECTED_AUTH_MAPPING_KEYS: dict[AuthType, set[str]] = {
68
+ AuthType.BEARER: {"token"},
69
+ AuthType.BASIC: {"username", "password"},
70
+ AuthType.API_KEY: {"api_key"},
71
+ AuthType.OAUTH2: {"access_token", "refresh_token", "client_id", "client_secret"},
72
+ }
73
+
74
+
75
+ def _validate_auth_mapping_keys(
76
+ auth_type: AuthType,
77
+ auth_config: AirbyteAuthConfig | None,
78
+ scheme_name: str = "default",
79
+ ) -> None:
80
+ """Validate that auth_mapping keys match expected parameters for the auth type.
81
+
82
+ The auth_mapping keys must be the parameters expected by the security scheme
83
+ (e.g., "token" for bearer), not the user's credential field names.
84
+
85
+ Args:
86
+ auth_type: The authentication type
87
+ auth_config: The x-airbyte-auth-config containing auth_mapping
88
+ scheme_name: Name of the security scheme for error messages
89
+
90
+ Raises:
91
+ InvalidOpenAPIError: If auth_mapping keys don't match expected parameters
92
+ """
93
+ if auth_config is None or auth_config.auth_mapping is None:
94
+ return # No explicit auth_mapping, will use defaults
95
+
96
+ expected_keys = EXPECTED_AUTH_MAPPING_KEYS.get(auth_type)
97
+ if expected_keys is None:
98
+ return # Unknown auth type, skip validation
99
+
100
+ actual_keys = set(auth_config.auth_mapping.keys())
101
+ invalid_keys = actual_keys - expected_keys
102
+
103
+ if invalid_keys:
104
+ raise InvalidOpenAPIError(
105
+ f"Invalid auth_mapping keys for {auth_type.value} auth in scheme '{scheme_name}': {invalid_keys}. "
106
+ f"Expected keys for {auth_type.value}: {sorted(expected_keys)}. "
107
+ f"Note: auth_mapping keys must be the auth parameters (e.g., 'token' for bearer), "
108
+ f'not your credential field names. Use template syntax to map: token: "${{your_field}}"'
109
+ )
110
+
111
+
65
112
  def extract_path_params(path: str) -> list[str]:
66
113
  """Extract parameter names from path template.
67
114
 
@@ -145,6 +192,87 @@ def _deproxy_schema(obj: Any) -> Any:
145
192
  return obj
146
193
 
147
194
 
195
+ def _type_includes(type_value: Any, target: str) -> bool:
196
+ if isinstance(type_value, list):
197
+ return target in type_value
198
+ return type_value == target
199
+
200
+
201
+ def _flatten_cache_properties(properties: dict[str, Any], prefix: str) -> list[str]:
202
+ entries: list[str] = []
203
+ for prop_name, prop in properties.items():
204
+ path = f"{prefix}{prop_name}" if prefix else prop_name
205
+ entries.append(path)
206
+
207
+ prop_type = getattr(prop, "type", None) if not isinstance(prop, dict) else prop.get("type")
208
+ prop_properties = getattr(prop, "properties", None) if not isinstance(prop, dict) else prop.get("properties")
209
+
210
+ if _type_includes(prop_type, "array"):
211
+ array_path = f"{path}[]"
212
+ entries.append(array_path)
213
+ if isinstance(prop_properties, dict):
214
+ entries.extend(_flatten_cache_properties(prop_properties, prefix=f"{array_path}."))
215
+ elif isinstance(prop_properties, dict):
216
+ entries.extend(_flatten_cache_properties(prop_properties, prefix=f"{path}."))
217
+
218
+ return entries
219
+
220
+
221
+ def _flatten_cache_field_paths(field: Any) -> list[str]:
222
+ field_name = getattr(field, "name", None) if not isinstance(field, dict) else field.get("name")
223
+ if not isinstance(field_name, str) or not field_name:
224
+ return []
225
+
226
+ field_type = getattr(field, "type", None) if not isinstance(field, dict) else field.get("type")
227
+ field_properties = getattr(field, "properties", None) if not isinstance(field, dict) else field.get("properties")
228
+
229
+ entries = [field_name]
230
+ if _type_includes(field_type, "array"):
231
+ array_path = f"{field_name}[]"
232
+ entries.append(array_path)
233
+ if isinstance(field_properties, dict):
234
+ entries.extend(_flatten_cache_properties(field_properties, prefix=f"{array_path}."))
235
+ elif isinstance(field_properties, dict):
236
+ entries.extend(_flatten_cache_properties(field_properties, prefix=f"{field_name}."))
237
+
238
+ return entries
239
+
240
+
241
+ def _dedupe_strings(values: list[str]) -> list[str]:
242
+ seen: set[str] = set()
243
+ ordered: list[str] = []
244
+ for value in values:
245
+ if value not in seen:
246
+ seen.add(value)
247
+ ordered.append(value)
248
+ return ordered
249
+
250
+
251
+ def _extract_search_field_paths(spec: OpenAPIConnector) -> dict[str, list[str]]:
252
+ cache_config = getattr(spec.info, "x_airbyte_cache", None)
253
+ entities = getattr(cache_config, "entities", None)
254
+ if not isinstance(entities, list):
255
+ return {}
256
+
257
+ search_fields: dict[str, list[str]] = {}
258
+ for entity in entities:
259
+ entity_name = getattr(entity, "entity", None) if not isinstance(entity, dict) else entity.get("entity")
260
+ if not isinstance(entity_name, str) or not entity_name:
261
+ continue
262
+
263
+ fields = getattr(entity, "fields", None) if not isinstance(entity, dict) else entity.get("fields")
264
+ if not isinstance(fields, list):
265
+ continue
266
+
267
+ field_paths: list[str] = []
268
+ for field in fields:
269
+ field_paths.extend(_flatten_cache_field_paths(field))
270
+
271
+ search_fields[entity_name] = _dedupe_strings(field_paths)
272
+
273
+ return search_fields
274
+
275
+
148
276
  def parse_openapi_spec(raw_config: dict) -> OpenAPIConnector:
149
277
  """Parse OpenAPI specification from YAML.
150
278
 
@@ -434,6 +562,8 @@ def convert_openapi_to_connector_model(spec: OpenAPIConnector) -> ConnectorModel
434
562
  if not connector_id:
435
563
  raise InvalidOpenAPIError("Missing required x-airbyte-connector-id field")
436
564
 
565
+ search_field_paths = _extract_search_field_paths(spec)
566
+
437
567
  # Create ConnectorModel
438
568
  model = ConnectorModel(
439
569
  id=connector_id,
@@ -444,6 +574,7 @@ def convert_openapi_to_connector_model(spec: OpenAPIConnector) -> ConnectorModel
444
574
  entities=entities,
445
575
  openapi_spec=spec,
446
576
  retry_config=retry_config,
577
+ search_field_paths=search_field_paths,
447
578
  )
448
579
 
449
580
  return model
@@ -840,6 +971,9 @@ def _parse_single_security_scheme(scheme: Any) -> AuthConfig:
840
971
  oauth2_config = _parse_oauth2_config(scheme)
841
972
  # Use explicit x-airbyte-auth-config if present, otherwise generate default
842
973
  auth_config_obj = scheme.x_airbyte_auth_config or _generate_default_auth_config(AuthType.OAUTH2)
974
+ # Validate auth_mapping keys if explicitly provided
975
+ if scheme.x_airbyte_auth_config:
976
+ _validate_auth_mapping_keys(AuthType.OAUTH2, scheme.x_airbyte_auth_config)
843
977
  return AuthConfig(
844
978
  type=AuthType.OAUTH2,
845
979
  config=oauth2_config,
@@ -850,6 +984,10 @@ def _parse_single_security_scheme(scheme: Any) -> AuthConfig:
850
984
  # Use explicit x-airbyte-auth-config if present, otherwise generate default
851
985
  auth_config_obj = scheme.x_airbyte_auth_config or _generate_default_auth_config(auth_type)
852
986
 
987
+ # Validate auth_mapping keys if explicitly provided
988
+ if scheme.x_airbyte_auth_config:
989
+ _validate_auth_mapping_keys(auth_type, scheme.x_airbyte_auth_config)
990
+
853
991
  return AuthConfig(
854
992
  type=auth_type,
855
993
  config=auth_config,
@@ -1032,7 +1032,9 @@ class LocalExecutor:
1032
1032
  if "variables" in graphql_config and graphql_config["variables"]:
1033
1033
  variables = self._interpolate_variables(graphql_config["variables"], params, param_defaults)
1034
1034
  # Filter out None values (optional fields not provided) - matches REST _extract_body() behavior
1035
- body["variables"] = {k: v for k, v in variables.items() if v is not None}
1035
+ # But preserve None for variables explicitly marked as nullable (e.g., to unassign a user)
1036
+ nullable_vars = set(graphql_config.get("x-airbyte-nullable-variables") or [])
1037
+ body["variables"] = {k: v for k, v in variables.items() if v is not None or k in nullable_vars}
1036
1038
 
1037
1039
  # Add operation name if specified
1038
1040
  if "operationName" in graphql_config: