airbyte-agent-mailchimp 0.1.4__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 (57) hide show
  1. airbyte_agent_mailchimp/__init__.py +217 -0
  2. airbyte_agent_mailchimp/_vendored/__init__.py +1 -0
  3. airbyte_agent_mailchimp/_vendored/connector_sdk/__init__.py +82 -0
  4. airbyte_agent_mailchimp/_vendored/connector_sdk/auth_strategies.py +1120 -0
  5. airbyte_agent_mailchimp/_vendored/connector_sdk/auth_template.py +135 -0
  6. airbyte_agent_mailchimp/_vendored/connector_sdk/cloud_utils/__init__.py +5 -0
  7. airbyte_agent_mailchimp/_vendored/connector_sdk/cloud_utils/client.py +213 -0
  8. airbyte_agent_mailchimp/_vendored/connector_sdk/connector_model_loader.py +965 -0
  9. airbyte_agent_mailchimp/_vendored/connector_sdk/constants.py +78 -0
  10. airbyte_agent_mailchimp/_vendored/connector_sdk/exceptions.py +23 -0
  11. airbyte_agent_mailchimp/_vendored/connector_sdk/executor/__init__.py +31 -0
  12. airbyte_agent_mailchimp/_vendored/connector_sdk/executor/hosted_executor.py +196 -0
  13. airbyte_agent_mailchimp/_vendored/connector_sdk/executor/local_executor.py +1641 -0
  14. airbyte_agent_mailchimp/_vendored/connector_sdk/executor/models.py +190 -0
  15. airbyte_agent_mailchimp/_vendored/connector_sdk/extensions.py +693 -0
  16. airbyte_agent_mailchimp/_vendored/connector_sdk/http/__init__.py +37 -0
  17. airbyte_agent_mailchimp/_vendored/connector_sdk/http/adapters/__init__.py +9 -0
  18. airbyte_agent_mailchimp/_vendored/connector_sdk/http/adapters/httpx_adapter.py +251 -0
  19. airbyte_agent_mailchimp/_vendored/connector_sdk/http/config.py +98 -0
  20. airbyte_agent_mailchimp/_vendored/connector_sdk/http/exceptions.py +119 -0
  21. airbyte_agent_mailchimp/_vendored/connector_sdk/http/protocols.py +114 -0
  22. airbyte_agent_mailchimp/_vendored/connector_sdk/http/response.py +104 -0
  23. airbyte_agent_mailchimp/_vendored/connector_sdk/http_client.py +686 -0
  24. airbyte_agent_mailchimp/_vendored/connector_sdk/introspection.py +262 -0
  25. airbyte_agent_mailchimp/_vendored/connector_sdk/logging/__init__.py +11 -0
  26. airbyte_agent_mailchimp/_vendored/connector_sdk/logging/logger.py +264 -0
  27. airbyte_agent_mailchimp/_vendored/connector_sdk/logging/types.py +92 -0
  28. airbyte_agent_mailchimp/_vendored/connector_sdk/observability/__init__.py +11 -0
  29. airbyte_agent_mailchimp/_vendored/connector_sdk/observability/config.py +179 -0
  30. airbyte_agent_mailchimp/_vendored/connector_sdk/observability/models.py +19 -0
  31. airbyte_agent_mailchimp/_vendored/connector_sdk/observability/redactor.py +81 -0
  32. airbyte_agent_mailchimp/_vendored/connector_sdk/observability/session.py +103 -0
  33. airbyte_agent_mailchimp/_vendored/connector_sdk/performance/__init__.py +6 -0
  34. airbyte_agent_mailchimp/_vendored/connector_sdk/performance/instrumentation.py +57 -0
  35. airbyte_agent_mailchimp/_vendored/connector_sdk/performance/metrics.py +93 -0
  36. airbyte_agent_mailchimp/_vendored/connector_sdk/schema/__init__.py +75 -0
  37. airbyte_agent_mailchimp/_vendored/connector_sdk/schema/base.py +164 -0
  38. airbyte_agent_mailchimp/_vendored/connector_sdk/schema/components.py +239 -0
  39. airbyte_agent_mailchimp/_vendored/connector_sdk/schema/connector.py +120 -0
  40. airbyte_agent_mailchimp/_vendored/connector_sdk/schema/extensions.py +230 -0
  41. airbyte_agent_mailchimp/_vendored/connector_sdk/schema/operations.py +146 -0
  42. airbyte_agent_mailchimp/_vendored/connector_sdk/schema/security.py +223 -0
  43. airbyte_agent_mailchimp/_vendored/connector_sdk/secrets.py +182 -0
  44. airbyte_agent_mailchimp/_vendored/connector_sdk/telemetry/__init__.py +10 -0
  45. airbyte_agent_mailchimp/_vendored/connector_sdk/telemetry/config.py +32 -0
  46. airbyte_agent_mailchimp/_vendored/connector_sdk/telemetry/events.py +59 -0
  47. airbyte_agent_mailchimp/_vendored/connector_sdk/telemetry/tracker.py +155 -0
  48. airbyte_agent_mailchimp/_vendored/connector_sdk/types.py +245 -0
  49. airbyte_agent_mailchimp/_vendored/connector_sdk/utils.py +60 -0
  50. airbyte_agent_mailchimp/_vendored/connector_sdk/validation.py +822 -0
  51. airbyte_agent_mailchimp/connector.py +1378 -0
  52. airbyte_agent_mailchimp/connector_model.py +4749 -0
  53. airbyte_agent_mailchimp/models.py +956 -0
  54. airbyte_agent_mailchimp/types.py +164 -0
  55. airbyte_agent_mailchimp-0.1.4.dist-info/METADATA +119 -0
  56. airbyte_agent_mailchimp-0.1.4.dist-info/RECORD +57 -0
  57. airbyte_agent_mailchimp-0.1.4.dist-info/WHEEL +4 -0
@@ -0,0 +1,693 @@
1
+ """
2
+ Airbyte OpenAPI Extensions - Single Source of Truth
3
+
4
+ This module defines all custom Airbyte extensions to the OpenAPI 3.0 specification.
5
+ These extensions are prefixed with 'x-airbyte-' to follow OpenAPI vendor extension
6
+ conventions and avoid conflicts with other extensions.
7
+
8
+ All extension names, valid values, and related types are centralized here to ensure
9
+ consistency across the codebase.
10
+
11
+ Usage:
12
+ from .extensions import AIRBYTE_CONNECTOR_NAME, AIRBYTE_ENTITY, ActionType
13
+
14
+ # In Pydantic models
15
+ x_entity: Optional[str] = Field(None, alias=AIRBYTE_ENTITY)
16
+
17
+ # In tests and validation
18
+ assert operation.get(AIRBYTE_ACTION) in ActionType.__members__.values()
19
+ """
20
+
21
+ from enum import Enum
22
+ from typing import Literal
23
+
24
+ # =============================================================================
25
+ # Extension Name Constants
26
+ # =============================================================================
27
+
28
+ AIRBYTE_CONNECTOR_NAME = "x-airbyte-connector-name"
29
+ """
30
+ Extension: x-airbyte-connector-name
31
+ Location: OpenAPI Info object
32
+ Type: string
33
+ Required: No (but recommended)
34
+
35
+ Description:
36
+ Specifies the unique identifier/name for this connector. This is used to identify
37
+ the connector in Airbyte's catalog and runtime systems.
38
+
39
+ Example:
40
+ ```yaml
41
+ info:
42
+ title: Stripe API
43
+ version: 1.0.0
44
+ x-airbyte-connector-name: stripe
45
+ ```
46
+ """
47
+
48
+ AIRBYTE_EXTERNAL_DOCUMENTATION_URLS = "x-airbyte-external-documentation-urls"
49
+ """
50
+ Extension: x-airbyte-external-documentation-urls
51
+ Location: OpenAPI Info object
52
+ Type: list
53
+ Required: Yes
54
+
55
+ Description:
56
+ List of objects that contain external documentation URLs relevant to the connector. Each object includes:
57
+ - type: Type of documentation (e.g., "api_reference", "other", etc.)
58
+ - title: Human-readable title for the documentation link
59
+ - url: The actual URL to the external documentation
60
+
61
+ Example:
62
+ ```yaml
63
+ info:
64
+ title: Stripe API
65
+ version: 1.0.0
66
+ x-airbyte-external-documentation-urls:
67
+ - type: api_reference
68
+ title: Stripe API Reference
69
+ url: https://stripe.com/docs/api
70
+ - type: authentication_guide
71
+ title: Stripe APIN Authentication Guide
72
+ url: https://docs.stripe.com/api/authentication
73
+ ```
74
+ """
75
+
76
+ AIRBYTE_ENTITY = "x-airbyte-entity"
77
+ """
78
+ Extension: x-airbyte-entity
79
+ Location: Operation object (on individual HTTP operations)
80
+ Type: string
81
+ Required: Yes (for operations that should be exposed as Airbyte streams)
82
+
83
+ Description:
84
+ Identifies which logical entity/stream this operation belongs to. Operations
85
+ with the same x-airbyte-entity value are grouped together to form a single
86
+ Airbyte stream. The entity name is used as the stream name.
87
+
88
+ Example:
89
+ ```yaml
90
+ paths:
91
+ /customers:
92
+ get:
93
+ x-airbyte-entity: customers
94
+ x-airbyte-action: list
95
+ ```
96
+ """
97
+
98
+ AIRBYTE_ACTION = "x-airbyte-action"
99
+ """
100
+ Extension: x-airbyte-action
101
+ Location: Operation object (on individual HTTP operations)
102
+ Type: string (enum - see ActionType)
103
+ Required: Yes (for operations that should be exposed as Airbyte streams)
104
+ Valid Values: get, list, create, update, delete
105
+
106
+ Description:
107
+ Specifies the semantic intent of this operation within its entity. This helps
108
+ Airbyte understand how to map REST operations to stream operations and determine
109
+ which operation to use for syncing data.
110
+
111
+ Action Semantics:
112
+ - list: Fetch multiple records (paginated, used for syncing)
113
+ - get: Fetch a single record by ID
114
+ - create: Create a new record
115
+ - update: Update an existing record
116
+ - delete: Delete a record
117
+
118
+ Example:
119
+ ```yaml
120
+ paths:
121
+ /customers:
122
+ get:
123
+ x-airbyte-entity: customers
124
+ x-airbyte-action: list
125
+ post:
126
+ x-airbyte-entity: customers
127
+ x-airbyte-action: create
128
+ /customers/{id}:
129
+ get:
130
+ x-airbyte-entity: customers
131
+ x-airbyte-action: get
132
+ ```
133
+ """
134
+
135
+ AIRBYTE_ENTITY_NAME = "x-airbyte-entity-name"
136
+ """
137
+ Extension: x-airbyte-entity-name
138
+ Location: Schema object (in components.schemas)
139
+ Type: string
140
+ Required: No (but recommended for entity schemas)
141
+
142
+ Description:
143
+ Links a schema definition to a logical entity/stream. This helps identify which
144
+ schema represents the main data model for a particular entity, especially when
145
+ multiple schemas might reference the same entity.
146
+
147
+ Example:
148
+ ```yaml
149
+ components:
150
+ schemas:
151
+ Customer:
152
+ type: object
153
+ x-airbyte-entity-name: customers
154
+ properties:
155
+ id:
156
+ type: string
157
+ name:
158
+ type: string
159
+ ```
160
+ """
161
+
162
+ AIRBYTE_STREAM_NAME = "x-airbyte-stream-name"
163
+ """
164
+ Extension: x-airbyte-stream-name
165
+ Location: Schema object (in components.schemas)
166
+ Type: string
167
+ Required: No
168
+
169
+ Description:
170
+ Specifies the Airbyte stream name for cache lookup purposes. This maps the entity
171
+ to the corresponding Airbyte stream, enabling cache-based data retrieval. When
172
+ specified, the EntityDefinition.stream_name field will be populated with this value.
173
+
174
+ This extension is placed on Schema objects alongside x-airbyte-entity-name, following
175
+ the same pattern. The stream name is an entity-level property (not operation-level)
176
+ since an entity maps to exactly one Airbyte stream.
177
+
178
+ Example:
179
+ ```yaml
180
+ components:
181
+ schemas:
182
+ Customer:
183
+ type: object
184
+ x-airbyte-entity-name: customers
185
+ x-airbyte-stream-name: customers
186
+ properties:
187
+ id:
188
+ type: string
189
+ name:
190
+ type: string
191
+ ```
192
+ """
193
+
194
+ AIRBYTE_TOKEN_PATH = "x-airbyte-token-path"
195
+ """
196
+ Extension: x-airbyte-token-path
197
+ Location: SecurityScheme object (in components.securitySchemes)
198
+ Type: string
199
+ Required: No
200
+
201
+ Description:
202
+ JSON path expression to extract the authentication token from the auth response.
203
+ Used for complex authentication flows where the token is nested in the response.
204
+
205
+ Example:
206
+ ```yaml
207
+ components:
208
+ securitySchemes:
209
+ oauth2Auth:
210
+ type: oauth2
211
+ flows:
212
+ clientCredentials:
213
+ tokenUrl: https://api.example.com/oauth/token
214
+ x-airbyte-token-path: $.access_token
215
+ ```
216
+ """
217
+
218
+ AIRBYTE_BODY_TYPE = "x-airbyte-body-type"
219
+ """
220
+ Extension: x-airbyte-body-type
221
+ Location: RequestBody object (in components.requestBodies or operation.requestBody)
222
+ Type: BodyTypeConfig (Union of typed Pydantic models: GraphQLBodyConfig)
223
+ Required: No
224
+ Validation: Strict - enforced at Pydantic model level
225
+
226
+ Description:
227
+ Specifies the type and configuration of request body format. Currently supports
228
+ "graphql" for GraphQL queries/mutations. The extension uses strongly-typed Pydantic
229
+ models for validation and contains both the type and type-specific configuration
230
+ in a nested structure. Designed to be extensible to support other body types in
231
+ the future (ie XML/SOAP, MessagePack).
232
+
233
+ Structure:
234
+ - type: Body type (currently "graphql")
235
+ - For type="graphql":
236
+ - query: GraphQL query/mutation string (required)
237
+ - variables: Variables dict with template placeholders (optional)
238
+ - operationName: Operation name for multi-operation queries (optional)
239
+ - default_fields: Default fields to select if not provided in params (optional)
240
+
241
+ Example:
242
+ ```yaml
243
+ paths:
244
+ /graphql:
245
+ post:
246
+ requestBody:
247
+ x-airbyte-body-type:
248
+ type: graphql
249
+ query: "query($owner: String!) { repository(owner: $owner) { name } }"
250
+ variables:
251
+ owner: "{{ owner }}"
252
+ ```
253
+ """
254
+
255
+ AIRBYTE_PATH_OVERRIDE = "x-airbyte-path-override"
256
+ """
257
+ Extension: x-airbyte-path-override
258
+ Location: Operation object (on individual HTTP operations)
259
+ Type: PathOverrideConfig (strongly-typed Pydantic model)
260
+ Required: No
261
+ Validation: Strict - enforced at Pydantic model level
262
+
263
+ Description:
264
+ Overrides the HTTP path used for actual requests when the OpenAPI path differs
265
+ from the real API endpoint. Common for GraphQL APIs where multiple entities
266
+ need unique OpenAPI paths but query the same HTTP endpoint.
267
+
268
+ This allows multiple operations (e.g., repositories→search, issues→search) to
269
+ have distinct entity-action mappings in the OpenAPI spec while all sending
270
+ requests to the same physical endpoint (e.g., /graphql).
271
+
272
+ Structure:
273
+ - path: Actual HTTP path to use (required, must start with '/')
274
+
275
+ Example:
276
+ ```yaml
277
+ paths:
278
+ /graphql:repositories: # OpenAPI path (for uniqueness)
279
+ post:
280
+ x-airbyte-entity: repositories
281
+ x-airbyte-action: search
282
+ x-airbyte-path-override:
283
+ path: /graphql # Actual HTTP endpoint
284
+ /graphql:issues: # Different OpenAPI path
285
+ post:
286
+ x-airbyte-entity: issues
287
+ x-airbyte-action: search
288
+ x-airbyte-path-override:
289
+ path: /graphql # Same actual endpoint
290
+ ```
291
+ """
292
+
293
+ AIRBYTE_RECORD_EXTRACTOR = "x-airbyte-record-extractor"
294
+ """
295
+ Extension: x-airbyte-record-extractor
296
+ Location: Operation object (on individual HTTP operations)
297
+ Type: string (JSONPath expression)
298
+ Required: No
299
+
300
+ Description:
301
+ Specifies a JSONPath expression to extract actual record data from API
302
+ response envelopes. Many APIs wrap responses in metadata structures
303
+ (pagination info, request IDs, etc.). This extension tells the executor
304
+ where to find the actual records.
305
+
306
+ Return type is automatically inferred from x-airbyte-action:
307
+ - list, search actions: Returns array ([] if path not found)
308
+ - get, create, update, delete actions: Returns single record (None if path not found)
309
+
310
+ Example:
311
+ ```yaml
312
+ paths:
313
+ /v2/users:
314
+ get:
315
+ x-airbyte-entity: users
316
+ x-airbyte-action: list
317
+ x-airbyte-record-extractor: $.users
318
+ ```
319
+
320
+ API Response:
321
+ ```json
322
+ {
323
+ "requestId": "abc123",
324
+ "users": [{"id": "1"}, {"id": "2"}]
325
+ }
326
+ ```
327
+
328
+ Executor Returns: [{"id": "1"}, {"id": "2"}]
329
+ """
330
+
331
+ AIRBYTE_META_EXTRACTOR = "x-airbyte-meta-extractor"
332
+ """
333
+ Extension: x-airbyte-meta-extractor
334
+ Location: Operation object (on individual HTTP operations)
335
+ Type: dict[str, str] (field name → JSONPath expression)
336
+ Required: No
337
+
338
+ Description:
339
+ Extracts metadata (pagination info, request IDs, etc.) from API responses.
340
+ Each key in the dict becomes a field in ExecutionResult.meta, with its value
341
+ being a JSONPath expression that extracts data from the original response.
342
+
343
+ Supports two usage patterns:
344
+
345
+ Pattern 1: Extract entire nested object (when all fields are grouped together)
346
+ Pattern 2: Extract individual fields (when fields are scattered across response)
347
+
348
+ Metadata is extracted from the original full response before record extraction,
349
+ ensuring access to envelope metadata that may be removed during record extraction.
350
+
351
+ Usage Pattern 1 (Extract nested object):
352
+ ```yaml
353
+ paths:
354
+ /v2/users:
355
+ get:
356
+ x-airbyte-resource: users
357
+ x-airbyte-verb: list
358
+ x-airbyte-record-extractor: $.users
359
+ x-airbyte-meta-extractor:
360
+ pagination: $.records # Extracts entire nested object
361
+ ```
362
+
363
+ API Response:
364
+ ```json
365
+ {
366
+ "requestId": "abc123",
367
+ "records": {
368
+ "cursor": "next_page_token",
369
+ "totalRecords": 100,
370
+ "currentPageSize": 20
371
+ },
372
+ "users": [{"id": "1"}, {"id": "2"}]
373
+ }
374
+ ```
375
+
376
+ Executor Returns:
377
+ - data: [{"id": "1"}, {"id": "2"}]
378
+ - meta: {"pagination": {"cursor": "next_page_token", "totalRecords": 100, "currentPageSize": 20}}
379
+
380
+ Usage Pattern 2 (Extract individual fields):
381
+ ```yaml
382
+ paths:
383
+ /v1/customers:
384
+ get:
385
+ x-airbyte-resource: customers
386
+ x-airbyte-verb: list
387
+ x-airbyte-record-extractor: $.data
388
+ x-airbyte-meta-extractor:
389
+ cursor: $.records.cursor
390
+ total_count: $.records.totalRecords
391
+ request_id: $.requestId
392
+ has_more: $.has_more
393
+ ```
394
+
395
+ API Response:
396
+ ```json
397
+ {
398
+ "requestId": "xyz789",
399
+ "records": {"cursor": "abc", "totalRecords": 50},
400
+ "has_more": true,
401
+ "data": [{"id": "cus_1"}, {"id": "cus_2"}]
402
+ }
403
+ ```
404
+
405
+ Executor Returns:
406
+ - data: [{"id": "cus_1"}, {"id": "cus_2"}]
407
+ - meta: {"cursor": "abc", "total_count": 50, "request_id": "xyz789", "has_more": true}
408
+
409
+ Behavior:
410
+ - Missing paths return None for that field (does not crash)
411
+ - Invalid JSONPath logs warning and returns None for that field
412
+ - Extraction happens before record extraction to access full response envelope
413
+ """
414
+
415
+ AIRBYTE_FILE_URL = "x-airbyte-file-url"
416
+ """
417
+ Extension: x-airbyte-file-url
418
+ Location: Operation object (on individual HTTP operations with x-airbyte-action: download)
419
+ Type: string
420
+ Required: Yes (when x-airbyte-action is "download")
421
+
422
+ Description:
423
+ Specifies which field in the metadata response contains the download URL. Used with
424
+ the 'download' action to perform a two-step file retrieval: first fetch metadata,
425
+ then extract and download from the URL field specified here.
426
+
427
+ The field path can be a simple field name (e.g., "content_url") or a nested path
428
+ using dot notation (e.g., "data.download_link"). The URL must be absolute.
429
+
430
+ Example:
431
+ ```yaml
432
+ paths:
433
+ /articles/{article_id}/attachments/{attachment_id}:
434
+ get:
435
+ x-airbyte-entity: article_attachments
436
+ x-airbyte-action: download
437
+ x-airbyte-file-url: content_url
438
+ responses:
439
+ "200":
440
+ content:
441
+ application/json:
442
+ schema:
443
+ type: object
444
+ properties:
445
+ id:
446
+ type: integer
447
+ content_url:
448
+ type: string
449
+ description: URL to download the file
450
+ ```
451
+ """
452
+
453
+ AIRBYTE_TOKEN_EXTRACT = "x-airbyte-token-extract"
454
+ """
455
+ Extension: x-airbyte-token-extract
456
+ Location: SecurityScheme object (in components.securitySchemes, under oauth2)
457
+ Type: list[str]
458
+ Required: No
459
+
460
+ Description:
461
+ Specifies which fields to extract from OAuth2 token responses and use as server
462
+ variables. This is useful for APIs like Salesforce where the token response includes
463
+ dynamic values (e.g., instance_url) needed to construct API URLs.
464
+
465
+ When token refresh occurs, the SDK:
466
+ 1. Extracts the specified fields from the token response
467
+ 2. Updates config_values with extracted values
468
+ 3. Re-renders the base_url with updated server variables
469
+ 4. Includes extracted fields in on_token_refresh callback for persistence
470
+
471
+ Precedence rules (highest wins):
472
+ 1. Server variable `default` in YAML (lowest)
473
+ 2. User-provided `config_values` at init (optional, may be unset)
474
+ 3. Token-extracted values via `x-airbyte-token-extract` (highest)
475
+
476
+ Validation (at connector load time):
477
+ - Error if extracted field doesn't match a defined server variable
478
+ - Error if duplicate fields in x-airbyte-token-extract
479
+
480
+ Example:
481
+ ```yaml
482
+ servers:
483
+ - url: "{instance_url}/services/data/v59.0"
484
+ variables:
485
+ instance_url:
486
+ default: "https://login.salesforce.com"
487
+
488
+ components:
489
+ securitySchemes:
490
+ oauth2:
491
+ type: oauth2
492
+ flows:
493
+ authorizationCode:
494
+ tokenUrl: https://login.salesforce.com/services/oauth2/token
495
+ refreshUrl: https://login.salesforce.com/services/oauth2/token
496
+ scopes: {}
497
+ x-airbyte-token-extract:
498
+ - instance_url # Extract from token response → updates {instance_url}
499
+ ```
500
+ """
501
+
502
+
503
+ # =============================================================================
504
+ # Enums and Type Definitions
505
+ # =============================================================================
506
+
507
+
508
+ class ActionType(str, Enum):
509
+ """
510
+ Valid values for x-airbyte-action extension.
511
+
512
+ These actions represent the semantic operations that can be performed on an entity.
513
+ """
514
+
515
+ GET = "get"
516
+ """Fetch a single record by identifier"""
517
+
518
+ LIST = "list"
519
+ """Fetch multiple records (typically paginated, used for data syncing)"""
520
+
521
+ CREATE = "create"
522
+ """Create a new record"""
523
+
524
+ UPDATE = "update"
525
+ """Update an existing record"""
526
+
527
+ DELETE = "delete"
528
+ """Delete a record"""
529
+
530
+ API_SEARCH = "api_search"
531
+ """Search for records matching specific query criteria via API"""
532
+
533
+ DOWNLOAD = "download"
534
+ """Download file content from a URL specified in the metadata response"""
535
+
536
+
537
+ class BodyType(str, Enum):
538
+ """
539
+ Valid values for x-airbyte-body-type extension.
540
+
541
+ These types represent the supported request body formats.
542
+ """
543
+
544
+ GRAPHQL = "graphql"
545
+ """GraphQL query/mutation format"""
546
+
547
+
548
+ # Type alias for use in Pydantic models
549
+ ActionTypeLiteral = Literal["get", "list", "create", "update", "delete", "api_search", "download"]
550
+
551
+
552
+ # =============================================================================
553
+ # Validation Helpers
554
+ # =============================================================================
555
+
556
+
557
+ def is_valid_action(action: str) -> bool:
558
+ """
559
+ Check if a string is a valid Airbyte action.
560
+
561
+ Args:
562
+ action: The action string to validate
563
+
564
+ Returns:
565
+ True if the action is valid, False otherwise
566
+ """
567
+ return action in [a.value for a in ActionType]
568
+
569
+
570
+ def get_all_extension_names() -> list[str]:
571
+ """
572
+ Get a list of all defined Airbyte extension names.
573
+
574
+ Returns:
575
+ List of extension name constants
576
+ """
577
+ return [
578
+ AIRBYTE_CONNECTOR_NAME,
579
+ AIRBYTE_EXTERNAL_DOCUMENTATION_URLS,
580
+ AIRBYTE_ENTITY,
581
+ AIRBYTE_ACTION,
582
+ AIRBYTE_ENTITY_NAME,
583
+ AIRBYTE_STREAM_NAME,
584
+ AIRBYTE_TOKEN_PATH,
585
+ AIRBYTE_BODY_TYPE,
586
+ AIRBYTE_PATH_OVERRIDE,
587
+ AIRBYTE_RECORD_EXTRACTOR,
588
+ AIRBYTE_META_EXTRACTOR,
589
+ AIRBYTE_FILE_URL,
590
+ AIRBYTE_TOKEN_EXTRACT,
591
+ ]
592
+
593
+
594
+ # =============================================================================
595
+ # Extension Registry
596
+ # =============================================================================
597
+
598
+ EXTENSION_REGISTRY = {
599
+ AIRBYTE_CONNECTOR_NAME: {
600
+ "location": "info",
601
+ "type": "string",
602
+ "required": False,
603
+ "description": "Unique identifier for the connector",
604
+ },
605
+ AIRBYTE_EXTERNAL_DOCUMENTATION_URLS: {
606
+ "location": "info",
607
+ "type": "list",
608
+ "required": True,
609
+ "description": "List of external documentation URLs relevant to the connector",
610
+ },
611
+ AIRBYTE_ENTITY: {
612
+ "location": "operation",
613
+ "type": "string",
614
+ "required": True,
615
+ "description": "Entity/stream name this operation belongs to",
616
+ },
617
+ AIRBYTE_ACTION: {
618
+ "location": "operation",
619
+ "type": "string",
620
+ "required": True,
621
+ "enum": [a.value for a in ActionType],
622
+ "description": "Semantic operation type",
623
+ },
624
+ AIRBYTE_ENTITY_NAME: {
625
+ "location": "schema",
626
+ "type": "string",
627
+ "required": False,
628
+ "description": "Links schema to an entity/stream",
629
+ },
630
+ AIRBYTE_STREAM_NAME: {
631
+ "location": "schema",
632
+ "type": "string",
633
+ "required": False,
634
+ "description": "Maps entity to Airbyte stream for cache lookup",
635
+ },
636
+ AIRBYTE_TOKEN_PATH: {
637
+ "location": "securityScheme",
638
+ "type": "string",
639
+ "required": False,
640
+ "description": "JSON path to extract token from auth response",
641
+ },
642
+ AIRBYTE_BODY_TYPE: {
643
+ "location": "requestBody",
644
+ "type": "BodyTypeConfig",
645
+ "model": "Union[GraphQLBodyConfig]",
646
+ "required": False,
647
+ "validation": "strict",
648
+ "description": "Body type and configuration (strongly-typed Pydantic models, extensible for future body types)",
649
+ },
650
+ AIRBYTE_PATH_OVERRIDE: {
651
+ "location": "operation",
652
+ "type": "PathOverrideConfig",
653
+ "model": "PathOverrideConfig",
654
+ "required": False,
655
+ "validation": "strict",
656
+ "description": "Override actual HTTP path when OpenAPI path differs from real endpoint (strongly-typed Pydantic model)",
657
+ },
658
+ AIRBYTE_RECORD_EXTRACTOR: {
659
+ "location": "operation",
660
+ "type": "string",
661
+ "required": False,
662
+ "description": "JSONPath expression to extract records from response envelopes",
663
+ },
664
+ AIRBYTE_META_EXTRACTOR: {
665
+ "location": "operation",
666
+ "type": "dict[str, str]",
667
+ "required": False,
668
+ "description": (
669
+ "Dictionary mapping field names to JSONPath expressions for extracting metadata (pagination, request IDs, etc.) from response envelopes"
670
+ ),
671
+ },
672
+ AIRBYTE_FILE_URL: {
673
+ "location": "operation",
674
+ "type": "string",
675
+ "required": "conditional", # Required when action is 'download'
676
+ "description": "Field in metadata response containing download URL (required for download action)",
677
+ },
678
+ AIRBYTE_TOKEN_EXTRACT: {
679
+ "location": "securityScheme",
680
+ "type": "list[str]",
681
+ "required": False,
682
+ "description": "List of fields to extract from OAuth2 token responses and use as server variables",
683
+ },
684
+ }
685
+ """
686
+ Complete registry of all Airbyte extensions with metadata.
687
+
688
+ This can be used for:
689
+ - Validation
690
+ - Documentation generation
691
+ - Runtime introspection
692
+ - Tool development
693
+ """