airbyte-agent-amazon-ads 0.1.6__tar.gz → 0.1.10__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.
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/AUTH.md +2 -2
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/CHANGELOG.md +20 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/PKG-INFO +7 -6
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/README.md +6 -5
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/REFERENCE.md +71 -1
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/__init__.py +20 -2
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/connector_model_loader.py +138 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/executor/local_executor.py +3 -1
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/introspection.py +222 -10
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/base.py +3 -1
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/components.py +5 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/extensions.py +71 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/types.py +1 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/connector.py +166 -38
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/connector_model.py +1144 -2
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/models.py +55 -0
- airbyte_agent_amazon_ads-0.1.10/airbyte_agent_amazon_ads/types.py +238 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/pyproject.toml +1 -1
- airbyte_agent_amazon_ads-0.1.6/airbyte_agent_amazon_ads/types.py +0 -48
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/.gitignore +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/auth_strategies.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/auth_template.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/cloud_utils/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/cloud_utils/client.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/constants.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/exceptions.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/executor/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/executor/hosted_executor.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/executor/models.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/extensions.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/adapters/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/adapters/httpx_adapter.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/config.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/exceptions.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/protocols.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http/response.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/http_client.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/logging/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/logging/logger.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/logging/types.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/observability/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/observability/config.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/observability/models.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/observability/redactor.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/observability/session.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/performance/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/performance/instrumentation.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/performance/metrics.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/connector.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/operations.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/schema/security.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/secrets.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/telemetry/__init__.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/telemetry/config.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/telemetry/events.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/telemetry/tracker.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/utils.py +0 -0
- {airbyte_agent_amazon_ads-0.1.6 → airbyte_agent_amazon_ads-0.1.10}/airbyte_agent_amazon_ads/_vendored/connector_sdk/validation.py +0 -0
|
@@ -75,7 +75,7 @@ connector = AmazonAdsConnector(
|
|
|
75
75
|
)
|
|
76
76
|
|
|
77
77
|
@agent.tool_plain # assumes you're using Pydantic AI
|
|
78
|
-
@AmazonAdsConnector.
|
|
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
|
-
| `
|
|
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,25 @@
|
|
|
1
1
|
# Amazon Ads changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.10] - 2026-01-26
|
|
4
|
+
- Updated connector definition (YAML version 1.0.3)
|
|
5
|
+
- Source commit: b73c71e0
|
|
6
|
+
- SDK version: 0.1.0
|
|
7
|
+
|
|
8
|
+
## [0.1.9] - 2026-01-24
|
|
9
|
+
- Updated connector definition (YAML version 1.0.3)
|
|
10
|
+
- Source commit: 609c1d86
|
|
11
|
+
- SDK version: 0.1.0
|
|
12
|
+
|
|
13
|
+
## [0.1.8] - 2026-01-23
|
|
14
|
+
- Updated connector definition (YAML version 1.0.3)
|
|
15
|
+
- Source commit: 6b458f8d
|
|
16
|
+
- SDK version: 0.1.0
|
|
17
|
+
|
|
18
|
+
## [0.1.7] - 2026-01-23
|
|
19
|
+
- Updated connector definition (YAML version 1.0.2)
|
|
20
|
+
- Source commit: 32c5ef46
|
|
21
|
+
- SDK version: 0.1.0
|
|
22
|
+
|
|
3
23
|
## [0.1.6] - 2026-01-23
|
|
4
24
|
- Updated connector definition (YAML version 1.0.1)
|
|
5
25
|
- Source commit: 416466da
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: airbyte-agent-amazon-ads
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
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.
|
|
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
|
```
|
|
@@ -107,11 +107,12 @@ connector = AmazonAdsConnector(
|
|
|
107
107
|
)
|
|
108
108
|
|
|
109
109
|
@agent.tool_plain # assumes you're using Pydantic AI
|
|
110
|
-
@AmazonAdsConnector.
|
|
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.
|
|
135
|
-
- **Connector version:** 1.0.
|
|
136
|
-
- **Generated with Connector SDK commit SHA:**
|
|
135
|
+
- **Package version:** 0.1.10
|
|
136
|
+
- **Connector version:** 1.0.3
|
|
137
|
+
- **Generated with Connector SDK commit SHA:** b73c71e077aea8d316f7161dbd5014d4fb9f3098
|
|
@@ -53,7 +53,7 @@ connector = AmazonAdsConnector(
|
|
|
53
53
|
)
|
|
54
54
|
|
|
55
55
|
@agent.tool_plain # assumes you're using Pydantic AI
|
|
56
|
-
@AmazonAdsConnector.
|
|
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
|
```
|
|
@@ -74,11 +74,12 @@ connector = AmazonAdsConnector(
|
|
|
74
74
|
)
|
|
75
75
|
|
|
76
76
|
@agent.tool_plain # assumes you're using Pydantic AI
|
|
77
|
-
@AmazonAdsConnector.
|
|
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.
|
|
102
|
-
- **Connector version:** 1.0.
|
|
103
|
-
- **Generated with Connector SDK commit SHA:**
|
|
102
|
+
- **Package version:** 0.1.10
|
|
103
|
+
- **Connector version:** 1.0.3
|
|
104
|
+
- **Generated with Connector SDK commit SHA:** b73c71e077aea8d316f7161dbd5014d4fb9f3098
|
|
@@ -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
|
-
|
|
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:
|