airbyte-agent-stripe 0.5.28__py3-none-any.whl → 0.5.32__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- airbyte_agent_stripe/__init__.py +70 -70
- airbyte_agent_stripe/_vendored/connector_sdk/connector_model_loader.py +10 -2
- airbyte_agent_stripe/_vendored/connector_sdk/executor/local_executor.py +51 -1
- airbyte_agent_stripe/_vendored/connector_sdk/extensions.py +39 -0
- airbyte_agent_stripe/_vendored/connector_sdk/introspection.py +262 -0
- airbyte_agent_stripe/_vendored/connector_sdk/schema/components.py +2 -1
- airbyte_agent_stripe/_vendored/connector_sdk/schema/security.py +10 -0
- airbyte_agent_stripe/_vendored/connector_sdk/types.py +4 -0
- airbyte_agent_stripe/connector.py +88 -3
- airbyte_agent_stripe/models.py +662 -662
- {airbyte_agent_stripe-0.5.28.dist-info → airbyte_agent_stripe-0.5.32.dist-info}/METADATA +3 -3
- {airbyte_agent_stripe-0.5.28.dist-info → airbyte_agent_stripe-0.5.32.dist-info}/RECORD +13 -12
- {airbyte_agent_stripe-0.5.28.dist-info → airbyte_agent_stripe-0.5.32.dist-info}/WHEEL +0 -0
airbyte_agent_stripe/__init__.py
CHANGED
|
@@ -11,139 +11,139 @@ from .models import (
|
|
|
11
11
|
CustomerShipping,
|
|
12
12
|
CustomerSourcesDataItem,
|
|
13
13
|
CustomerSources,
|
|
14
|
-
CustomerInvoiceSettingsCustomFieldsItem,
|
|
15
|
-
CustomerInvoiceSettingsRenderingOptions,
|
|
16
|
-
CustomerInvoiceSettings,
|
|
17
|
-
CustomerAddress,
|
|
18
|
-
CustomerCashBalanceSettings,
|
|
19
|
-
CustomerCashBalance,
|
|
20
|
-
CustomerDiscountSource,
|
|
21
|
-
CustomerDiscount,
|
|
22
|
-
SubscriptionBillingCycleAnchorConfig,
|
|
23
|
-
SubscriptionPauseCollection,
|
|
24
14
|
SubscriptionBillingModeFlexible,
|
|
25
15
|
SubscriptionBillingMode,
|
|
26
16
|
SubscriptionPaymentSettings,
|
|
17
|
+
SubscriptionItemsDataItemBillingThresholds,
|
|
18
|
+
SubscriptionItemsDataItem,
|
|
19
|
+
SubscriptionItems,
|
|
20
|
+
SubscriptionBillingCycleAnchorConfig,
|
|
21
|
+
SubscriptionBillingThresholds,
|
|
27
22
|
SubscriptionDefaultTaxRatesItemFlatAmount,
|
|
28
23
|
SubscriptionDefaultTaxRatesItem,
|
|
29
24
|
SubscriptionCancellationDetails,
|
|
30
25
|
SubscriptionTrialSettingsEndBehavior,
|
|
31
26
|
SubscriptionTrialSettings,
|
|
32
|
-
SubscriptionBillingThresholds,
|
|
33
27
|
SubscriptionInvoiceSettingsIssuer,
|
|
34
28
|
SubscriptionInvoiceSettings,
|
|
35
29
|
SubscriptionAutomaticTaxLiability,
|
|
36
30
|
SubscriptionAutomaticTax,
|
|
37
|
-
|
|
38
|
-
SubscriptionItemsDataItem,
|
|
39
|
-
SubscriptionItems,
|
|
31
|
+
SubscriptionPauseCollection,
|
|
40
32
|
Subscription,
|
|
41
33
|
CustomerSubscriptions,
|
|
34
|
+
CustomerDiscountSource,
|
|
35
|
+
CustomerDiscount,
|
|
36
|
+
CustomerAddress,
|
|
37
|
+
CustomerInvoiceSettingsRenderingOptions,
|
|
38
|
+
CustomerInvoiceSettingsCustomFieldsItem,
|
|
39
|
+
CustomerInvoiceSettings,
|
|
40
|
+
CustomerCashBalanceSettings,
|
|
41
|
+
CustomerCashBalance,
|
|
42
42
|
Customer,
|
|
43
43
|
CustomerList,
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
InvoiceTotalTaxAmountsItem,
|
|
48
|
-
InvoiceTotalDiscountAmountsItem,
|
|
49
|
-
InvoiceAutomaticTaxLiability,
|
|
50
|
-
InvoiceAutomaticTax,
|
|
44
|
+
InvoiceCustomerTaxIdsItem,
|
|
45
|
+
InvoiceLastFinalizationError,
|
|
46
|
+
InvoiceCustomerAddress,
|
|
51
47
|
InvoiceStatusTransitions,
|
|
52
|
-
InvoiceLinesDataItemDiscountAmountsItem,
|
|
53
|
-
InvoiceLinesDataItemPeriod,
|
|
54
|
-
InvoiceLinesDataItem,
|
|
55
|
-
InvoiceLines,
|
|
56
48
|
InvoiceShippingDetailsAddress,
|
|
57
49
|
InvoiceShippingDetails,
|
|
58
|
-
InvoiceFromInvoice,
|
|
59
|
-
InvoiceCustomerAddress,
|
|
60
|
-
InvoiceThresholdReasonItemReasonsItem,
|
|
61
|
-
InvoiceThresholdReason,
|
|
62
|
-
InvoiceTotalPretaxCreditAmountsItem,
|
|
63
|
-
InvoicePaymentSettings,
|
|
64
|
-
InvoiceCustomerTaxIdsItem,
|
|
65
50
|
InvoiceRenderingPdf,
|
|
66
51
|
InvoiceRendering,
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
InvoicePayments,
|
|
72
|
-
InvoiceCustomerShippingAddress,
|
|
73
|
-
InvoiceCustomerShipping,
|
|
74
|
-
InvoiceDefaultTaxRatesItemFlatAmount,
|
|
75
|
-
InvoiceDefaultTaxRatesItem,
|
|
76
|
-
InvoiceCustomFieldsItem,
|
|
52
|
+
InvoiceLinesDataItemPeriod,
|
|
53
|
+
InvoiceLinesDataItemDiscountAmountsItem,
|
|
54
|
+
InvoiceLinesDataItem,
|
|
55
|
+
InvoiceLines,
|
|
77
56
|
InvoiceShippingCostTaxesItem,
|
|
78
57
|
InvoiceShippingCost,
|
|
58
|
+
InvoiceDefaultTaxRatesItemFlatAmount,
|
|
59
|
+
InvoiceDefaultTaxRatesItem,
|
|
60
|
+
InvoiceIssuer,
|
|
79
61
|
InvoiceTotalTaxesItem,
|
|
62
|
+
InvoicePaymentsDataItem,
|
|
63
|
+
InvoicePayments,
|
|
80
64
|
InvoiceParentSubscriptionDetails,
|
|
81
65
|
InvoiceParentQuoteDetails,
|
|
82
66
|
InvoiceParent,
|
|
67
|
+
InvoiceAutomaticTaxLiability,
|
|
68
|
+
InvoiceAutomaticTax,
|
|
69
|
+
InvoiceDiscountCoupon,
|
|
70
|
+
InvoiceDiscount,
|
|
71
|
+
InvoiceCustomFieldsItem,
|
|
72
|
+
InvoiceConfirmationSecret,
|
|
73
|
+
InvoiceTotalTaxAmountsItem,
|
|
74
|
+
InvoiceCustomerShippingAddress,
|
|
75
|
+
InvoiceCustomerShipping,
|
|
76
|
+
InvoiceThresholdReasonItemReasonsItem,
|
|
77
|
+
InvoiceThresholdReason,
|
|
78
|
+
InvoiceFromInvoice,
|
|
79
|
+
InvoiceSubscriptionDetails,
|
|
80
|
+
InvoiceTotalPretaxCreditAmountsItem,
|
|
81
|
+
InvoicePaymentSettings,
|
|
82
|
+
InvoiceTotalDiscountAmountsItem,
|
|
83
83
|
Invoice,
|
|
84
84
|
InvoiceList,
|
|
85
|
-
ChargeRefunds,
|
|
86
|
-
ChargeOutcome,
|
|
87
|
-
ChargePresentmentDetails,
|
|
88
85
|
ChargeFraudDetails,
|
|
86
|
+
ChargeOutcome,
|
|
89
87
|
ChargeBillingDetailsAddress,
|
|
90
88
|
ChargeBillingDetails,
|
|
89
|
+
ChargeRefunds,
|
|
90
|
+
ChargePaymentMethodDetailsCardExtendedAuthorization,
|
|
91
|
+
ChargePaymentMethodDetailsCardChecks,
|
|
91
92
|
ChargePaymentMethodDetailsCardNetworkToken,
|
|
92
93
|
ChargePaymentMethodDetailsCardIncrementalAuthorization,
|
|
93
94
|
ChargePaymentMethodDetailsCardMulticapture,
|
|
94
95
|
ChargePaymentMethodDetailsCardOvercapture,
|
|
95
|
-
ChargePaymentMethodDetailsCardChecks,
|
|
96
|
-
ChargePaymentMethodDetailsCardExtendedAuthorization,
|
|
97
96
|
ChargePaymentMethodDetailsCard,
|
|
98
97
|
ChargePaymentMethodDetails,
|
|
98
|
+
ChargePresentmentDetails,
|
|
99
99
|
Charge,
|
|
100
100
|
ChargeList,
|
|
101
101
|
SubscriptionList,
|
|
102
102
|
RefundDestinationDetailsBrBankTransfer,
|
|
103
103
|
RefundDestinationDetailsGbBankTransfer,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
RefundDestinationDetailsPaypal,
|
|
104
|
+
RefundDestinationDetailsMxBankTransfer,
|
|
105
|
+
RefundDestinationDetailsCard,
|
|
107
106
|
RefundDestinationDetailsSwish,
|
|
107
|
+
RefundDestinationDetailsJpBankTransfer,
|
|
108
108
|
RefundDestinationDetailsBlik,
|
|
109
|
-
|
|
109
|
+
RefundDestinationDetailsMultibanco,
|
|
110
110
|
RefundDestinationDetailsEuBankTransfer,
|
|
111
|
-
RefundDestinationDetailsCard,
|
|
112
111
|
RefundDestinationDetailsCrypto,
|
|
113
|
-
|
|
112
|
+
RefundDestinationDetailsP24,
|
|
113
|
+
RefundDestinationDetailsMbWay,
|
|
114
|
+
RefundDestinationDetailsPaypal,
|
|
114
115
|
RefundDestinationDetailsUsBankTransfer,
|
|
115
|
-
|
|
116
|
-
RefundDestinationDetailsJpBankTransfer,
|
|
116
|
+
RefundDestinationDetailsThBankTransfer,
|
|
117
117
|
RefundDestinationDetails,
|
|
118
118
|
RefundNextActionDisplayDetailsEmailSent,
|
|
119
119
|
RefundNextActionDisplayDetails,
|
|
120
120
|
RefundNextAction,
|
|
121
121
|
Refund,
|
|
122
122
|
RefundList,
|
|
123
|
+
ProductMarketingFeaturesItem,
|
|
123
124
|
ProductPackageDimensions,
|
|
124
125
|
ProductFeaturesItem,
|
|
125
|
-
ProductMarketingFeaturesItem,
|
|
126
126
|
Product,
|
|
127
127
|
ProductList,
|
|
128
128
|
ProductSearchResult,
|
|
129
|
-
BalanceAvailableItemSourceTypes,
|
|
130
|
-
BalanceAvailableItem,
|
|
131
|
-
BalanceInstantAvailableItemSourceTypes,
|
|
132
|
-
BalanceInstantAvailableItemNetAvailableItemSourceTypes,
|
|
133
|
-
BalanceInstantAvailableItemNetAvailableItem,
|
|
134
|
-
BalanceInstantAvailableItem,
|
|
135
|
-
BalanceIssuingAvailableItemSourceTypes,
|
|
136
|
-
BalanceIssuingAvailableItem,
|
|
137
|
-
BalanceIssuing,
|
|
138
|
-
BalancePendingItemSourceTypes,
|
|
139
|
-
BalancePendingItem,
|
|
140
129
|
BalanceConnectReservedItemSourceTypes,
|
|
141
130
|
BalanceConnectReservedItem,
|
|
142
|
-
|
|
143
|
-
|
|
131
|
+
BalanceAvailableItemSourceTypes,
|
|
132
|
+
BalanceAvailableItem,
|
|
144
133
|
BalanceRefundAndDisputePrefundingPendingItemSourceTypes,
|
|
145
134
|
BalanceRefundAndDisputePrefundingPendingItem,
|
|
135
|
+
BalanceRefundAndDisputePrefundingAvailableItemSourceTypes,
|
|
136
|
+
BalanceRefundAndDisputePrefundingAvailableItem,
|
|
146
137
|
BalanceRefundAndDisputePrefunding,
|
|
138
|
+
BalancePendingItemSourceTypes,
|
|
139
|
+
BalancePendingItem,
|
|
140
|
+
BalanceIssuingAvailableItemSourceTypes,
|
|
141
|
+
BalanceIssuingAvailableItem,
|
|
142
|
+
BalanceIssuing,
|
|
143
|
+
BalanceInstantAvailableItemNetAvailableItemSourceTypes,
|
|
144
|
+
BalanceInstantAvailableItemNetAvailableItem,
|
|
145
|
+
BalanceInstantAvailableItemSourceTypes,
|
|
146
|
+
BalanceInstantAvailableItem,
|
|
147
147
|
Balance,
|
|
148
148
|
BalanceTransactionFeeDetailsItem,
|
|
149
149
|
BalanceTransaction,
|
|
@@ -234,4 +234,4 @@ from .types import (
|
|
|
234
234
|
PayoutsGetParams
|
|
235
235
|
)
|
|
236
236
|
|
|
237
|
-
__all__ = ["StripeConnector", "StripeAuthConfig", "CustomerShippingAddress", "CustomerShipping", "CustomerSourcesDataItem", "CustomerSources", "
|
|
237
|
+
__all__ = ["StripeConnector", "StripeAuthConfig", "CustomerShippingAddress", "CustomerShipping", "CustomerSourcesDataItem", "CustomerSources", "SubscriptionBillingModeFlexible", "SubscriptionBillingMode", "SubscriptionPaymentSettings", "SubscriptionItemsDataItemBillingThresholds", "SubscriptionItemsDataItem", "SubscriptionItems", "SubscriptionBillingCycleAnchorConfig", "SubscriptionBillingThresholds", "SubscriptionDefaultTaxRatesItemFlatAmount", "SubscriptionDefaultTaxRatesItem", "SubscriptionCancellationDetails", "SubscriptionTrialSettingsEndBehavior", "SubscriptionTrialSettings", "SubscriptionInvoiceSettingsIssuer", "SubscriptionInvoiceSettings", "SubscriptionAutomaticTaxLiability", "SubscriptionAutomaticTax", "SubscriptionPauseCollection", "Subscription", "CustomerSubscriptions", "CustomerDiscountSource", "CustomerDiscount", "CustomerAddress", "CustomerInvoiceSettingsRenderingOptions", "CustomerInvoiceSettingsCustomFieldsItem", "CustomerInvoiceSettings", "CustomerCashBalanceSettings", "CustomerCashBalance", "Customer", "CustomerList", "InvoiceCustomerTaxIdsItem", "InvoiceLastFinalizationError", "InvoiceCustomerAddress", "InvoiceStatusTransitions", "InvoiceShippingDetailsAddress", "InvoiceShippingDetails", "InvoiceRenderingPdf", "InvoiceRendering", "InvoiceLinesDataItemPeriod", "InvoiceLinesDataItemDiscountAmountsItem", "InvoiceLinesDataItem", "InvoiceLines", "InvoiceShippingCostTaxesItem", "InvoiceShippingCost", "InvoiceDefaultTaxRatesItemFlatAmount", "InvoiceDefaultTaxRatesItem", "InvoiceIssuer", "InvoiceTotalTaxesItem", "InvoicePaymentsDataItem", "InvoicePayments", "InvoiceParentSubscriptionDetails", "InvoiceParentQuoteDetails", "InvoiceParent", "InvoiceAutomaticTaxLiability", "InvoiceAutomaticTax", "InvoiceDiscountCoupon", "InvoiceDiscount", "InvoiceCustomFieldsItem", "InvoiceConfirmationSecret", "InvoiceTotalTaxAmountsItem", "InvoiceCustomerShippingAddress", "InvoiceCustomerShipping", "InvoiceThresholdReasonItemReasonsItem", "InvoiceThresholdReason", "InvoiceFromInvoice", "InvoiceSubscriptionDetails", "InvoiceTotalPretaxCreditAmountsItem", "InvoicePaymentSettings", "InvoiceTotalDiscountAmountsItem", "Invoice", "InvoiceList", "ChargeFraudDetails", "ChargeOutcome", "ChargeBillingDetailsAddress", "ChargeBillingDetails", "ChargeRefunds", "ChargePaymentMethodDetailsCardExtendedAuthorization", "ChargePaymentMethodDetailsCardChecks", "ChargePaymentMethodDetailsCardNetworkToken", "ChargePaymentMethodDetailsCardIncrementalAuthorization", "ChargePaymentMethodDetailsCardMulticapture", "ChargePaymentMethodDetailsCardOvercapture", "ChargePaymentMethodDetailsCard", "ChargePaymentMethodDetails", "ChargePresentmentDetails", "Charge", "ChargeList", "SubscriptionList", "RefundDestinationDetailsBrBankTransfer", "RefundDestinationDetailsGbBankTransfer", "RefundDestinationDetailsMxBankTransfer", "RefundDestinationDetailsCard", "RefundDestinationDetailsSwish", "RefundDestinationDetailsJpBankTransfer", "RefundDestinationDetailsBlik", "RefundDestinationDetailsMultibanco", "RefundDestinationDetailsEuBankTransfer", "RefundDestinationDetailsCrypto", "RefundDestinationDetailsP24", "RefundDestinationDetailsMbWay", "RefundDestinationDetailsPaypal", "RefundDestinationDetailsUsBankTransfer", "RefundDestinationDetailsThBankTransfer", "RefundDestinationDetails", "RefundNextActionDisplayDetailsEmailSent", "RefundNextActionDisplayDetails", "RefundNextAction", "Refund", "RefundList", "ProductMarketingFeaturesItem", "ProductPackageDimensions", "ProductFeaturesItem", "Product", "ProductList", "ProductSearchResult", "BalanceConnectReservedItemSourceTypes", "BalanceConnectReservedItem", "BalanceAvailableItemSourceTypes", "BalanceAvailableItem", "BalanceRefundAndDisputePrefundingPendingItemSourceTypes", "BalanceRefundAndDisputePrefundingPendingItem", "BalanceRefundAndDisputePrefundingAvailableItemSourceTypes", "BalanceRefundAndDisputePrefundingAvailableItem", "BalanceRefundAndDisputePrefunding", "BalancePendingItemSourceTypes", "BalancePendingItem", "BalanceIssuingAvailableItemSourceTypes", "BalanceIssuingAvailableItem", "BalanceIssuing", "BalanceInstantAvailableItemNetAvailableItemSourceTypes", "BalanceInstantAvailableItemNetAvailableItem", "BalanceInstantAvailableItemSourceTypes", "BalanceInstantAvailableItem", "Balance", "BalanceTransactionFeeDetailsItem", "BalanceTransaction", "BalanceTransactionList", "PaymentIntent", "PaymentIntentList", "PaymentIntentSearchResult", "DisputeEvidenceDetails", "Dispute", "DisputeList", "PayoutTraceId", "Payout", "PayoutList", "CustomerSearchResult", "InvoiceSearchResult", "ChargeSearchResult", "SubscriptionSearchResult", "CustomersListResultMeta", "CustomersSearchResultMeta", "InvoicesListResultMeta", "ChargesListResultMeta", "SubscriptionsListResultMeta", "RefundsListResultMeta", "ProductsListResultMeta", "ProductsSearchResultMeta", "BalanceTransactionsListResultMeta", "PaymentIntentsListResultMeta", "PaymentIntentsSearchResultMeta", "DisputesListResultMeta", "PayoutsListResultMeta", "StripeExecuteResult", "StripeExecuteResultWithMeta", "CustomersListResult", "CustomersSearchResult", "InvoicesListResult", "ChargesListResult", "SubscriptionsListResult", "RefundsListResult", "ProductsListResult", "ProductsSearchResult", "BalanceTransactionsListResult", "PaymentIntentsListResult", "PaymentIntentsSearchResult", "DisputesListResult", "PayoutsListResult", "CustomersListParamsCreated", "InvoicesListParamsCreated", "ChargesListParamsCreated", "SubscriptionsListParamsAutomaticTax", "SubscriptionsListParamsCreated", "SubscriptionsListParamsCurrentPeriodEnd", "SubscriptionsListParamsCurrentPeriodStart", "RefundsListParamsCreated", "ProductsListParamsCreated", "BalanceTransactionsListParamsCreated", "PaymentIntentsListParamsCreated", "DisputesListParamsCreated", "PayoutsListParamsArrivalDate", "PayoutsListParamsCreated", "CustomersListParams", "CustomersGetParams", "CustomersSearchParams", "InvoicesListParams", "InvoicesGetParams", "InvoicesSearchParams", "ChargesListParams", "ChargesGetParams", "ChargesSearchParams", "SubscriptionsListParams", "SubscriptionsGetParams", "SubscriptionsSearchParams", "RefundsListParams", "RefundsGetParams", "ProductsListParams", "ProductsGetParams", "ProductsSearchParams", "BalanceGetParams", "BalanceTransactionsListParams", "BalanceTransactionsGetParams", "PaymentIntentsListParams", "PaymentIntentsGetParams", "PaymentIntentsSearchParams", "DisputesListParams", "DisputesGetParams", "PayoutsListParams", "PayoutsGetParams"]
|
|
@@ -393,16 +393,24 @@ def convert_openapi_to_connector_model(spec: OpenAPIConnector) -> ConnectorModel
|
|
|
393
393
|
for entity_name, endpoints_dict in entities_map.items():
|
|
394
394
|
actions = list(endpoints_dict.keys())
|
|
395
395
|
|
|
396
|
-
# Get schema from components if available
|
|
396
|
+
# Get schema and stream_name from components if available
|
|
397
397
|
schema = None
|
|
398
|
+
entity_stream_name = None
|
|
398
399
|
if spec.components:
|
|
399
400
|
# Look for a schema matching the entity name
|
|
400
401
|
for schema_name, schema_def in spec.components.schemas.items():
|
|
401
402
|
if schema_def.x_airbyte_entity_name == entity_name or schema_name.lower() == entity_name.lower():
|
|
402
403
|
schema = schema_def.model_dump(by_alias=True)
|
|
404
|
+
entity_stream_name = schema_def.x_airbyte_stream_name
|
|
403
405
|
break
|
|
404
406
|
|
|
405
|
-
entity = EntityDefinition(
|
|
407
|
+
entity = EntityDefinition(
|
|
408
|
+
name=entity_name,
|
|
409
|
+
stream_name=entity_stream_name,
|
|
410
|
+
actions=actions,
|
|
411
|
+
endpoints=endpoints_dict,
|
|
412
|
+
schema=schema,
|
|
413
|
+
)
|
|
406
414
|
entities.append(entity)
|
|
407
415
|
|
|
408
416
|
# Extract retry config from x-airbyte-retry-config extension
|
|
@@ -844,10 +844,58 @@ class LocalExecutor:
|
|
|
844
844
|
return self._extract_body(endpoint.body_fields, params)
|
|
845
845
|
return None
|
|
846
846
|
|
|
847
|
+
def _flatten_form_data(self, data: dict[str, Any], parent_key: str = "") -> dict[str, Any]:
|
|
848
|
+
"""Flatten nested dict/list structures into bracket notation for form encoding.
|
|
849
|
+
|
|
850
|
+
Stripe and similar APIs require nested arrays/objects to be encoded using bracket
|
|
851
|
+
notation when using application/x-www-form-urlencoded content type.
|
|
852
|
+
|
|
853
|
+
Args:
|
|
854
|
+
data: Nested dict with arrays/objects to flatten
|
|
855
|
+
parent_key: Parent key for nested structures (used in recursion)
|
|
856
|
+
|
|
857
|
+
Returns:
|
|
858
|
+
Flattened dict with bracket notation keys
|
|
859
|
+
|
|
860
|
+
Examples:
|
|
861
|
+
>>> _flatten_form_data({"items": [{"price": "p1", "qty": 1}]})
|
|
862
|
+
{"items[0][price]": "p1", "items[0][qty]": 1}
|
|
863
|
+
|
|
864
|
+
>>> _flatten_form_data({"customer": "cus_123", "metadata": {"key": "value"}})
|
|
865
|
+
{"customer": "cus_123", "metadata[key]": "value"}
|
|
866
|
+
"""
|
|
867
|
+
flattened = {}
|
|
868
|
+
|
|
869
|
+
for key, value in data.items():
|
|
870
|
+
new_key = f"{parent_key}[{key}]" if parent_key else key
|
|
871
|
+
|
|
872
|
+
if isinstance(value, dict):
|
|
873
|
+
# Recursively flatten nested dicts
|
|
874
|
+
flattened.update(self._flatten_form_data(value, new_key))
|
|
875
|
+
elif isinstance(value, list):
|
|
876
|
+
# Flatten arrays with indexed bracket notation
|
|
877
|
+
for i, item in enumerate(value):
|
|
878
|
+
indexed_key = f"{new_key}[{i}]"
|
|
879
|
+
if isinstance(item, dict):
|
|
880
|
+
# Nested dict in array - recurse
|
|
881
|
+
flattened.update(self._flatten_form_data(item, indexed_key))
|
|
882
|
+
elif isinstance(item, list):
|
|
883
|
+
# Nested list in array - recurse
|
|
884
|
+
flattened.update(self._flatten_form_data({str(i): item}, new_key))
|
|
885
|
+
else:
|
|
886
|
+
# Primitive value in array
|
|
887
|
+
flattened[indexed_key] = item
|
|
888
|
+
else:
|
|
889
|
+
# Primitive value - add directly
|
|
890
|
+
flattened[new_key] = value
|
|
891
|
+
|
|
892
|
+
return flattened
|
|
893
|
+
|
|
847
894
|
def _determine_request_format(self, endpoint: EndpointDefinition, body: dict[str, Any] | None) -> dict[str, Any]:
|
|
848
895
|
"""Determine json/data parameters for HTTP request.
|
|
849
896
|
|
|
850
897
|
GraphQL always uses JSON, regardless of content_type setting.
|
|
898
|
+
For form-encoded requests, nested structures are flattened into bracket notation.
|
|
851
899
|
|
|
852
900
|
Args:
|
|
853
901
|
endpoint: Endpoint definition
|
|
@@ -864,7 +912,9 @@ class LocalExecutor:
|
|
|
864
912
|
if is_graphql or endpoint.content_type.value == "application/json":
|
|
865
913
|
return {"json": body}
|
|
866
914
|
elif endpoint.content_type.value == "application/x-www-form-urlencoded":
|
|
867
|
-
|
|
915
|
+
# Flatten nested structures for form encoding
|
|
916
|
+
flattened_body = self._flatten_form_data(body)
|
|
917
|
+
return {"data": flattened_body}
|
|
868
918
|
|
|
869
919
|
return {}
|
|
870
920
|
|
|
@@ -159,6 +159,38 @@ Example:
|
|
|
159
159
|
```
|
|
160
160
|
"""
|
|
161
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
|
+
|
|
162
194
|
AIRBYTE_TOKEN_PATH = "x-airbyte-token-path"
|
|
163
195
|
"""
|
|
164
196
|
Extension: x-airbyte-token-path
|
|
@@ -548,6 +580,7 @@ def get_all_extension_names() -> list[str]:
|
|
|
548
580
|
AIRBYTE_ENTITY,
|
|
549
581
|
AIRBYTE_ACTION,
|
|
550
582
|
AIRBYTE_ENTITY_NAME,
|
|
583
|
+
AIRBYTE_STREAM_NAME,
|
|
551
584
|
AIRBYTE_TOKEN_PATH,
|
|
552
585
|
AIRBYTE_BODY_TYPE,
|
|
553
586
|
AIRBYTE_PATH_OVERRIDE,
|
|
@@ -594,6 +627,12 @@ EXTENSION_REGISTRY = {
|
|
|
594
627
|
"required": False,
|
|
595
628
|
"description": "Links schema to an entity/stream",
|
|
596
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
|
+
},
|
|
597
636
|
AIRBYTE_TOKEN_PATH: {
|
|
598
637
|
"location": "securityScheme",
|
|
599
638
|
"type": "string",
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shared introspection utilities for connector metadata.
|
|
3
|
+
|
|
4
|
+
This module provides utilities for introspecting connector metadata,
|
|
5
|
+
generating descriptions, and formatting parameter signatures. These
|
|
6
|
+
functions are used by both the runtime decorators and the generated
|
|
7
|
+
connector code.
|
|
8
|
+
|
|
9
|
+
The module is designed to work with any object conforming to the
|
|
10
|
+
ConnectorModel and EndpointDefinition interfaces from connector_sdk.types.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from typing import Any, Protocol
|
|
16
|
+
|
|
17
|
+
# Constants
|
|
18
|
+
MAX_EXAMPLE_QUESTIONS = 5 # Maximum number of example questions to include in description
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class EndpointProtocol(Protocol):
|
|
22
|
+
"""Protocol defining the expected interface for endpoint parameters.
|
|
23
|
+
|
|
24
|
+
This allows functions to work with any endpoint-like object
|
|
25
|
+
that has these attributes, including EndpointDefinition and mock objects.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
path_params: list[str]
|
|
29
|
+
path_params_schema: dict[str, dict[str, Any]]
|
|
30
|
+
query_params: list[str]
|
|
31
|
+
query_params_schema: dict[str, dict[str, Any]]
|
|
32
|
+
body_fields: list[str]
|
|
33
|
+
request_schema: dict[str, Any] | None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class EntityProtocol(Protocol):
|
|
37
|
+
"""Protocol defining the expected interface for entity definitions."""
|
|
38
|
+
|
|
39
|
+
name: str
|
|
40
|
+
actions: list[Any]
|
|
41
|
+
endpoints: dict[Any, EndpointProtocol]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class ConnectorModelProtocol(Protocol):
|
|
45
|
+
"""Protocol defining the expected interface for connector model parameters.
|
|
46
|
+
|
|
47
|
+
This allows functions to work with any connector-like object
|
|
48
|
+
that has these attributes, including ConnectorModel and mock objects.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def entities(self) -> list[EntityProtocol]: ...
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def openapi_spec(self) -> Any: ...
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def format_param_signature(endpoint: EndpointProtocol) -> str:
|
|
59
|
+
"""Format parameter signature for an endpoint action.
|
|
60
|
+
|
|
61
|
+
Returns a string like: (id*) or (limit?, starting_after?, email?)
|
|
62
|
+
where * = required, ? = optional
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
endpoint: Object conforming to EndpointProtocol (e.g., EndpointDefinition)
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Formatted parameter signature string
|
|
69
|
+
"""
|
|
70
|
+
params = []
|
|
71
|
+
|
|
72
|
+
# Defensive: safely access attributes with defaults for malformed endpoints
|
|
73
|
+
path_params = getattr(endpoint, "path_params", []) or []
|
|
74
|
+
query_params = getattr(endpoint, "query_params", []) or []
|
|
75
|
+
query_params_schema = getattr(endpoint, "query_params_schema", {}) or {}
|
|
76
|
+
body_fields = getattr(endpoint, "body_fields", []) or []
|
|
77
|
+
request_schema = getattr(endpoint, "request_schema", None)
|
|
78
|
+
|
|
79
|
+
# Path params (always required)
|
|
80
|
+
for name in path_params:
|
|
81
|
+
params.append(f"{name}*")
|
|
82
|
+
|
|
83
|
+
# Query params
|
|
84
|
+
for name in query_params:
|
|
85
|
+
schema = query_params_schema.get(name, {})
|
|
86
|
+
required = schema.get("required", False)
|
|
87
|
+
params.append(f"{name}{'*' if required else '?'}")
|
|
88
|
+
|
|
89
|
+
# Body fields
|
|
90
|
+
if request_schema:
|
|
91
|
+
required_fields = set(request_schema.get("required", []))
|
|
92
|
+
for name in body_fields:
|
|
93
|
+
params.append(f"{name}{'*' if name in required_fields else '?'}")
|
|
94
|
+
|
|
95
|
+
return f"({', '.join(params)})" if params else "()"
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def describe_entities(model: ConnectorModelProtocol) -> list[dict[str, Any]]:
|
|
99
|
+
"""Generate entity descriptions from ConnectorModel.
|
|
100
|
+
|
|
101
|
+
Returns a list of entity descriptions with detailed parameter information
|
|
102
|
+
for each action. This is used by generated connectors' describe() method.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
model: Object conforming to ConnectorModelProtocol (e.g., ConnectorModel)
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
List of entity description dicts with keys:
|
|
109
|
+
- entity_name: Name of the entity (e.g., "contacts", "deals")
|
|
110
|
+
- description: Entity description from the first endpoint
|
|
111
|
+
- available_actions: List of actions (e.g., ["list", "get", "create"])
|
|
112
|
+
- parameters: Dict mapping action -> list of parameter dicts
|
|
113
|
+
"""
|
|
114
|
+
entities = []
|
|
115
|
+
for entity_def in model.entities:
|
|
116
|
+
description = ""
|
|
117
|
+
parameters: dict[str, list[dict[str, Any]]] = {}
|
|
118
|
+
|
|
119
|
+
endpoints = getattr(entity_def, "endpoints", {}) or {}
|
|
120
|
+
if endpoints:
|
|
121
|
+
for action, endpoint in endpoints.items():
|
|
122
|
+
# Get description from first endpoint that has one
|
|
123
|
+
if not description:
|
|
124
|
+
endpoint_desc = getattr(endpoint, "description", None)
|
|
125
|
+
if endpoint_desc:
|
|
126
|
+
description = endpoint_desc
|
|
127
|
+
|
|
128
|
+
action_params: list[dict[str, Any]] = []
|
|
129
|
+
|
|
130
|
+
# Defensive: safely access endpoint attributes
|
|
131
|
+
path_params = getattr(endpoint, "path_params", []) or []
|
|
132
|
+
path_params_schema = getattr(endpoint, "path_params_schema", {}) or {}
|
|
133
|
+
query_params = getattr(endpoint, "query_params", []) or []
|
|
134
|
+
query_params_schema = getattr(endpoint, "query_params_schema", {}) or {}
|
|
135
|
+
body_fields = getattr(endpoint, "body_fields", []) or []
|
|
136
|
+
request_schema = getattr(endpoint, "request_schema", None)
|
|
137
|
+
|
|
138
|
+
# Path params (always required)
|
|
139
|
+
for param_name in path_params:
|
|
140
|
+
schema = path_params_schema.get(param_name, {})
|
|
141
|
+
action_params.append(
|
|
142
|
+
{
|
|
143
|
+
"name": param_name,
|
|
144
|
+
"in": "path",
|
|
145
|
+
"required": True,
|
|
146
|
+
"type": schema.get("type", "string"),
|
|
147
|
+
"description": schema.get("description", ""),
|
|
148
|
+
}
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
# Query params
|
|
152
|
+
for param_name in query_params:
|
|
153
|
+
schema = query_params_schema.get(param_name, {})
|
|
154
|
+
action_params.append(
|
|
155
|
+
{
|
|
156
|
+
"name": param_name,
|
|
157
|
+
"in": "query",
|
|
158
|
+
"required": schema.get("required", False),
|
|
159
|
+
"type": schema.get("type", "string"),
|
|
160
|
+
"description": schema.get("description", ""),
|
|
161
|
+
}
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
# Body fields
|
|
165
|
+
if request_schema:
|
|
166
|
+
required_fields = request_schema.get("required", [])
|
|
167
|
+
properties = request_schema.get("properties", {})
|
|
168
|
+
for param_name in body_fields:
|
|
169
|
+
prop = properties.get(param_name, {})
|
|
170
|
+
action_params.append(
|
|
171
|
+
{
|
|
172
|
+
"name": param_name,
|
|
173
|
+
"in": "body",
|
|
174
|
+
"required": param_name in required_fields,
|
|
175
|
+
"type": prop.get("type", "string"),
|
|
176
|
+
"description": prop.get("description", ""),
|
|
177
|
+
}
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
if action_params:
|
|
181
|
+
# Action is an enum, use .value to get string
|
|
182
|
+
action_key = action.value if hasattr(action, "value") else str(action)
|
|
183
|
+
parameters[action_key] = action_params
|
|
184
|
+
|
|
185
|
+
actions = getattr(entity_def, "actions", []) or []
|
|
186
|
+
entities.append(
|
|
187
|
+
{
|
|
188
|
+
"entity_name": entity_def.name,
|
|
189
|
+
"description": description,
|
|
190
|
+
"available_actions": [a.value if hasattr(a, "value") else str(a) for a in actions],
|
|
191
|
+
"parameters": parameters,
|
|
192
|
+
}
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
return entities
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def generate_tool_description(model: ConnectorModelProtocol) -> str:
|
|
199
|
+
"""Generate AI tool description from connector metadata.
|
|
200
|
+
|
|
201
|
+
Produces a detailed description that includes:
|
|
202
|
+
- Per-entity/action parameter signatures with required (*) and optional (?) markers
|
|
203
|
+
- Response structure documentation with pagination hints
|
|
204
|
+
- Example questions if available in the OpenAPI spec
|
|
205
|
+
|
|
206
|
+
This is used by the Connector.describe class method decorator to populate
|
|
207
|
+
function docstrings for AI framework integration.
|
|
208
|
+
|
|
209
|
+
Args:
|
|
210
|
+
model: Object conforming to ConnectorModelProtocol (e.g., ConnectorModel)
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
Formatted description string suitable for AI tool documentation
|
|
214
|
+
"""
|
|
215
|
+
lines = []
|
|
216
|
+
|
|
217
|
+
# Entity/action parameter details (including pagination params like limit, starting_after)
|
|
218
|
+
lines.append("ENTITIES AND PARAMETERS:")
|
|
219
|
+
for entity in model.entities:
|
|
220
|
+
lines.append(f" {entity.name}:")
|
|
221
|
+
actions = getattr(entity, "actions", []) or []
|
|
222
|
+
endpoints = getattr(entity, "endpoints", {}) or {}
|
|
223
|
+
for action in actions:
|
|
224
|
+
action_str = action.value if hasattr(action, "value") else str(action)
|
|
225
|
+
endpoint = endpoints.get(action)
|
|
226
|
+
if endpoint:
|
|
227
|
+
param_sig = format_param_signature(endpoint)
|
|
228
|
+
lines.append(f" - {action_str}{param_sig}")
|
|
229
|
+
else:
|
|
230
|
+
lines.append(f" - {action_str}()")
|
|
231
|
+
|
|
232
|
+
# Response structure (brief, includes pagination hint)
|
|
233
|
+
lines.append("")
|
|
234
|
+
lines.append("RESPONSE STRUCTURE:")
|
|
235
|
+
lines.append(" - list/search: {data: [...], meta: {has_more: bool}}")
|
|
236
|
+
lines.append(" - get: Returns entity directly (no envelope)")
|
|
237
|
+
lines.append(" To paginate: pass starting_after=<last_id> while has_more is true")
|
|
238
|
+
|
|
239
|
+
# Add example questions if available in openapi_spec
|
|
240
|
+
openapi_spec = getattr(model, "openapi_spec", None)
|
|
241
|
+
if openapi_spec:
|
|
242
|
+
info = getattr(openapi_spec, "info", None)
|
|
243
|
+
if info:
|
|
244
|
+
example_questions = getattr(info, "x_airbyte_example_questions", None)
|
|
245
|
+
if example_questions:
|
|
246
|
+
supported = getattr(example_questions, "supported", None)
|
|
247
|
+
if supported:
|
|
248
|
+
lines.append("")
|
|
249
|
+
lines.append("EXAMPLE QUESTIONS:")
|
|
250
|
+
for q in supported[:MAX_EXAMPLE_QUESTIONS]:
|
|
251
|
+
lines.append(f" - {q}")
|
|
252
|
+
|
|
253
|
+
# Generic parameter description for function signature
|
|
254
|
+
lines.append("")
|
|
255
|
+
lines.append("FUNCTION PARAMETERS:")
|
|
256
|
+
lines.append(" - entity: Entity name (string)")
|
|
257
|
+
lines.append(" - action: Operation to perform (string)")
|
|
258
|
+
lines.append(" - params: Operation parameters (dict) - see entity details above")
|
|
259
|
+
lines.append("")
|
|
260
|
+
lines.append("Parameter markers: * = required, ? = optional")
|
|
261
|
+
|
|
262
|
+
return "\n".join(lines)
|