Skip to content

Commit d21a122

Browse files
committed
Rollback dynamic schema loader
1 parent 52a2fe8 commit d21a122

File tree

4 files changed

+127
-158
lines changed

4 files changed

+127
-158
lines changed

airbyte_cdk/sources/declarative/declarative_component_schema.yaml

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,24 +1800,30 @@ definitions:
18001800
$parameters:
18011801
type: object
18021802
additionalProperties: true
1803+
SchemaFieldType:
1804+
title: Schema Field Type
1805+
description: (This component is experimental. Use at your own risk.) Represents a mapping between a current type and its corresponding target type for property.
1806+
type: object
1807+
required:
1808+
- field_type
1809+
properties:
1810+
field_type:
1811+
type: string
1812+
items:
1813+
"$ref": "#/definitions/SchemaFieldType"
18031814
ItemsTypeMap:
18041815
title: Types Map
18051816
description: (This component is experimental. Use at your own risk.) Represents a mapping between a current type and its corresponding target type for property.
18061817
type: object
18071818
required:
1808-
- items_type_pointer
1809-
- type_mapping
1819+
- target_type
18101820
properties:
1811-
property_name:
1821+
condition:
18121822
type: string
1813-
items_type_pointer:
1814-
title: Items Type Path
1815-
description: List of potentially nested fields describing the full path of the items type to extract.
1816-
type: array
1817-
items:
1818-
- type: string
1819-
type_mapping:
1820-
"$ref": "#/definitions/TypesMap"
1823+
interpolation_context:
1824+
- raw_schema
1825+
target_type:
1826+
"$ref": "#/definitions/SchemaFieldType"
18211827
TypesMap:
18221828
title: Types Map
18231829
description: (This component is experimental. Use at your own risk.) Represents a mapping between a current type and its corresponding target type.

airbyte_cdk/sources/declarative/models/declarative_component_schema.py

Lines changed: 97 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,9 @@ class OAuthAuthenticator(BaseModel):
604604
scopes: Optional[List[str]] = Field(
605605
None,
606606
description="List of scopes that should be granted to the access token.",
607-
examples=[["crm.list.read", "crm.objects.contacts.read", "crm.schema.contacts.read"]],
607+
examples=[
608+
["crm.list.read", "crm.objects.contacts.read", "crm.schema.contacts.read"]
609+
],
608610
title="Scopes",
609611
)
610612
token_expiry_date: Optional[str] = Field(
@@ -736,6 +738,44 @@ class HttpResponseFilter(BaseModel):
736738
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
737739

738740

741+
class SchemaFieldType(BaseModel):
742+
field_type: str
743+
items: Optional[SchemaFieldType] = None
744+
745+
746+
class ItemsTypeMap(BaseModel):
747+
condition: Optional[str] = None
748+
target_type: SchemaFieldType
749+
750+
751+
class TypesMap(BaseModel):
752+
target_type: Union[str, List[str]]
753+
current_type: Union[str, List[str]]
754+
condition: Optional[str] = None
755+
items_type: Optional[ItemsTypeMap] = None
756+
757+
758+
class SchemaTypeIdentifier(BaseModel):
759+
type: Optional[Literal["SchemaTypeIdentifier"]] = None
760+
schema_pointer: Optional[List[str]] = Field(
761+
[],
762+
description="List of nested fields defining the schema field path to extract. Defaults to [].",
763+
title="Schema Path",
764+
)
765+
key_pointer: List[str] = Field(
766+
...,
767+
description="List of potentially nested fields describing the full path of the field key to extract.",
768+
title="Key Path",
769+
)
770+
type_pointer: Optional[List[str]] = Field(
771+
None,
772+
description="List of potentially nested fields describing the full path of the field type to extract.",
773+
title="Type Path",
774+
)
775+
types_mapping: Optional[List[TypesMap]] = None
776+
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
777+
778+
739779
class InlineSchemaLoader(BaseModel):
740780
type: Literal["InlineSchemaLoader"]
741781
schema_: Optional[Dict[str, Any]] = Field(
@@ -1008,24 +1048,28 @@ class OAuthConfigSpecification(BaseModel):
10081048
class Config:
10091049
extra = Extra.allow
10101050

1011-
oauth_user_input_from_connector_config_specification: Optional[Dict[str, Any]] = Field(
1012-
None,
1013-
description="OAuth specific blob. This is a Json Schema used to validate Json configurations used as input to OAuth.\nMust be a valid non-nested JSON that refers to properties from ConnectorSpecification.connectionSpecification\nusing special annotation 'path_in_connector_config'.\nThese are input values the user is entering through the UI to authenticate to the connector, that might also shared\nas inputs for syncing data via the connector.\nExamples:\nif no connector values is shared during oauth flow, oauth_user_input_from_connector_config_specification=[]\nif connector values such as 'app_id' inside the top level are used to generate the API url for the oauth flow,\n oauth_user_input_from_connector_config_specification={\n app_id: {\n type: string\n path_in_connector_config: ['app_id']\n }\n }\nif connector values such as 'info.app_id' nested inside another object are used to generate the API url for the oauth flow,\n oauth_user_input_from_connector_config_specification={\n app_id: {\n type: string\n path_in_connector_config: ['info', 'app_id']\n }\n }",
1014-
examples=[
1015-
{"app_id": {"type": "string", "path_in_connector_config": ["app_id"]}},
1016-
{
1017-
"app_id": {
1018-
"type": "string",
1019-
"path_in_connector_config": ["info", "app_id"],
1020-
}
1021-
},
1022-
],
1023-
title="OAuth user input",
1051+
oauth_user_input_from_connector_config_specification: Optional[Dict[str, Any]] = (
1052+
Field(
1053+
None,
1054+
description="OAuth specific blob. This is a Json Schema used to validate Json configurations used as input to OAuth.\nMust be a valid non-nested JSON that refers to properties from ConnectorSpecification.connectionSpecification\nusing special annotation 'path_in_connector_config'.\nThese are input values the user is entering through the UI to authenticate to the connector, that might also shared\nas inputs for syncing data via the connector.\nExamples:\nif no connector values is shared during oauth flow, oauth_user_input_from_connector_config_specification=[]\nif connector values such as 'app_id' inside the top level are used to generate the API url for the oauth flow,\n oauth_user_input_from_connector_config_specification={\n app_id: {\n type: string\n path_in_connector_config: ['app_id']\n }\n }\nif connector values such as 'info.app_id' nested inside another object are used to generate the API url for the oauth flow,\n oauth_user_input_from_connector_config_specification={\n app_id: {\n type: string\n path_in_connector_config: ['info', 'app_id']\n }\n }",
1055+
examples=[
1056+
{"app_id": {"type": "string", "path_in_connector_config": ["app_id"]}},
1057+
{
1058+
"app_id": {
1059+
"type": "string",
1060+
"path_in_connector_config": ["info", "app_id"],
1061+
}
1062+
},
1063+
],
1064+
title="OAuth user input",
1065+
)
10241066
)
1025-
oauth_connector_input_specification: Optional[OauthConnectorInputSpecification] = Field(
1026-
None,
1027-
description='The DeclarativeOAuth specific blob.\nPertains to the fields defined by the connector relating to the OAuth flow.\n\nInterpolation capabilities:\n- The variables placeholders are declared as `{{my_var}}`.\n- The nested resolution variables like `{{ {{my_nested_var}} }}` is allowed as well.\n\n- The allowed interpolation context is:\n + base64Encoder - encode to `base64`, {{ {{my_var_a}}:{{my_var_b}} | base64Encoder }}\n + base64Decorer - decode from `base64` encoded string, {{ {{my_string_variable_or_string_value}} | base64Decoder }}\n + urlEncoder - encode the input string to URL-like format, {{ https://test.host.com/endpoint | urlEncoder}}\n + urlDecorer - decode the input url-encoded string into text format, {{ urlDecoder:https%3A%2F%2Fairbyte.io | urlDecoder}}\n + codeChallengeS256 - get the `codeChallenge` encoded value to provide additional data-provider specific authorisation values, {{ {{state_value}} | codeChallengeS256 }}\n\nExamples:\n - The TikTok Marketing DeclarativeOAuth spec:\n {\n "oauth_connector_input_specification": {\n "type": "object",\n "additionalProperties": false,\n "properties": {\n "consent_url": "https://ads.tiktok.com/marketing_api/auth?{{client_id_key}}={{client_id_value}}&{{redirect_uri_key}}={{ {{redirect_uri_value}} | urlEncoder}}&{{state_key}}={{state_value}}",\n "access_token_url": "https://business-api.tiktok.com/open_api/v1.3/oauth2/access_token/",\n "access_token_params": {\n "{{ auth_code_key }}": "{{ auth_code_value }}",\n "{{ client_id_key }}": "{{ client_id_value }}",\n "{{ client_secret_key }}": "{{ client_secret_value }}"\n },\n "access_token_headers": {\n "Content-Type": "application/json",\n "Accept": "application/json"\n },\n "extract_output": ["data.access_token"],\n "client_id_key": "app_id",\n "client_secret_key": "secret",\n "auth_code_key": "auth_code"\n }\n }\n }',
1028-
title="DeclarativeOAuth Connector Specification",
1067+
oauth_connector_input_specification: Optional[OauthConnectorInputSpecification] = (
1068+
Field(
1069+
None,
1070+
description='The DeclarativeOAuth specific blob.\nPertains to the fields defined by the connector relating to the OAuth flow.\n\nInterpolation capabilities:\n- The variables placeholders are declared as `{{my_var}}`.\n- The nested resolution variables like `{{ {{my_nested_var}} }}` is allowed as well.\n\n- The allowed interpolation context is:\n + base64Encoder - encode to `base64`, {{ {{my_var_a}}:{{my_var_b}} | base64Encoder }}\n + base64Decorer - decode from `base64` encoded string, {{ {{my_string_variable_or_string_value}} | base64Decoder }}\n + urlEncoder - encode the input string to URL-like format, {{ https://test.host.com/endpoint | urlEncoder}}\n + urlDecorer - decode the input url-encoded string into text format, {{ urlDecoder:https%3A%2F%2Fairbyte.io | urlDecoder}}\n + codeChallengeS256 - get the `codeChallenge` encoded value to provide additional data-provider specific authorisation values, {{ {{state_value}} | codeChallengeS256 }}\n\nExamples:\n - The TikTok Marketing DeclarativeOAuth spec:\n {\n "oauth_connector_input_specification": {\n "type": "object",\n "additionalProperties": false,\n "properties": {\n "consent_url": "https://ads.tiktok.com/marketing_api/auth?{{client_id_key}}={{client_id_value}}&{{redirect_uri_key}}={{ {{redirect_uri_value}} | urlEncoder}}&{{state_key}}={{state_value}}",\n "access_token_url": "https://business-api.tiktok.com/open_api/v1.3/oauth2/access_token/",\n "access_token_params": {\n "{{ auth_code_key }}": "{{ auth_code_value }}",\n "{{ client_id_key }}": "{{ client_id_value }}",\n "{{ client_secret_key }}": "{{ client_secret_value }}"\n },\n "access_token_headers": {\n "Content-Type": "application/json",\n "Accept": "application/json"\n },\n "extract_output": ["data.access_token"],\n "client_id_key": "app_id",\n "client_secret_key": "secret",\n "auth_code_key": "auth_code"\n }\n }\n }',
1071+
title="DeclarativeOAuth Connector Specification",
1072+
)
10291073
)
10301074
complete_oauth_output_specification: Optional[Dict[str, Any]] = Field(
10311075
None,
@@ -1043,7 +1087,9 @@ class Config:
10431087
complete_oauth_server_input_specification: Optional[Dict[str, Any]] = Field(
10441088
None,
10451089
description="OAuth specific blob. This is a Json Schema used to validate Json configurations persisted as Airbyte Server configurations.\nMust be a valid non-nested JSON describing additional fields configured by the Airbyte Instance or Workspace Admins to be used by the\nserver when completing an OAuth flow (typically exchanging an auth code for refresh token).\nExamples:\n complete_oauth_server_input_specification={\n client_id: {\n type: string\n },\n client_secret: {\n type: string\n }\n }",
1046-
examples=[{"client_id": {"type": "string"}, "client_secret": {"type": "string"}}],
1090+
examples=[
1091+
{"client_id": {"type": "string"}, "client_secret": {"type": "string"}}
1092+
],
10471093
title="OAuth input specification",
10481094
)
10491095
complete_oauth_server_output_specification: Optional[Dict[str, Any]] = Field(
@@ -1629,7 +1675,9 @@ class RecordSelector(BaseModel):
16291675
description="Responsible for filtering records to be emitted by the Source.",
16301676
title="Record Filter",
16311677
)
1632-
schema_normalization: Optional[Union[SchemaNormalization, CustomSchemaNormalization]] = Field(
1678+
schema_normalization: Optional[
1679+
Union[SchemaNormalization, CustomSchemaNormalization]
1680+
] = Field(
16331681
SchemaNormalization.None_,
16341682
description="Responsible for normalization according to the schema.",
16351683
title="Schema Normalization",
@@ -1803,12 +1851,16 @@ class Config:
18031851
description="Component used to coordinate how records are extracted across stream slices and request pages.",
18041852
title="Retriever",
18051853
)
1806-
incremental_sync: Optional[Union[CustomIncrementalSync, DatetimeBasedCursor]] = Field(
1807-
None,
1808-
description="Component used to fetch data incrementally based on a time field in the data.",
1809-
title="Incremental Sync",
1854+
incremental_sync: Optional[Union[CustomIncrementalSync, DatetimeBasedCursor]] = (
1855+
Field(
1856+
None,
1857+
description="Component used to fetch data incrementally based on a time field in the data.",
1858+
title="Incremental Sync",
1859+
)
1860+
)
1861+
name: Optional[str] = Field(
1862+
"", description="The stream name.", example=["Users"], title="Name"
18101863
)
1811-
name: Optional[str] = Field("", description="The stream name.", example=["Users"], title="Name")
18121864
primary_key: Optional[PrimaryKey] = Field(
18131865
"", description="The primary key of the stream.", title="Primary Key"
18141866
)
@@ -1993,44 +2045,6 @@ class HttpRequester(BaseModel):
19932045
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
19942046

19952047

1996-
class ItemsTypeMap(BaseModel):
1997-
property_name: Optional[str] = None
1998-
items_type_pointer: List[str] = Field(
1999-
...,
2000-
description="List of potentially nested fields describing the full path of the items type to extract.",
2001-
title="Items Type Path",
2002-
)
2003-
type_mapping: TypesMap
2004-
2005-
2006-
class TypesMap(BaseModel):
2007-
target_type: Union[str, List[str]]
2008-
current_type: Union[str, List[str]]
2009-
condition: Optional[str] = None
2010-
items_type: Optional[ItemsTypeMap] = None
2011-
2012-
2013-
class SchemaTypeIdentifier(BaseModel):
2014-
type: Optional[Literal["SchemaTypeIdentifier"]] = None
2015-
schema_pointer: Optional[List[str]] = Field(
2016-
[],
2017-
description="List of nested fields defining the schema field path to extract. Defaults to [].",
2018-
title="Schema Path",
2019-
)
2020-
key_pointer: List[str] = Field(
2021-
...,
2022-
description="List of potentially nested fields describing the full path of the field key to extract.",
2023-
title="Key Path",
2024-
)
2025-
type_pointer: Optional[List[str]] = Field(
2026-
None,
2027-
description="List of potentially nested fields describing the full path of the field type to extract.",
2028-
title="Type Path",
2029-
)
2030-
types_mapping: Optional[List[TypesMap]] = None
2031-
parameters: Optional[Dict[str, Any]] = Field(None, alias="$parameters")
2032-
2033-
20342048
class DynamicSchemaLoader(BaseModel):
20352049
type: Literal["DynamicSchemaLoader"]
20362050
retriever: Union[AsyncRetriever, CustomRetriever, SimpleRetriever] = Field(
@@ -2118,7 +2132,11 @@ class SimpleRetriever(BaseModel):
21182132
CustomPartitionRouter,
21192133
ListPartitionRouter,
21202134
SubstreamPartitionRouter,
2121-
List[Union[CustomPartitionRouter, ListPartitionRouter, SubstreamPartitionRouter]],
2135+
List[
2136+
Union[
2137+
CustomPartitionRouter, ListPartitionRouter, SubstreamPartitionRouter
2138+
]
2139+
],
21222140
]
21232141
] = Field(
21242142
[],
@@ -2162,7 +2180,9 @@ class AsyncRetriever(BaseModel):
21622180
)
21632181
download_extractor: Optional[
21642182
Union[CustomRecordExtractor, DpathExtractor, ResponseToFileExtractor]
2165-
] = Field(None, description="Responsible for fetching the records from provided urls.")
2183+
] = Field(
2184+
None, description="Responsible for fetching the records from provided urls."
2185+
)
21662186
creation_requester: Union[CustomRequester, HttpRequester] = Field(
21672187
...,
21682188
description="Requester component that describes how to prepare HTTP requests to send to the source API to create the async server-side job.",
@@ -2196,7 +2216,11 @@ class AsyncRetriever(BaseModel):
21962216
CustomPartitionRouter,
21972217
ListPartitionRouter,
21982218
SubstreamPartitionRouter,
2199-
List[Union[CustomPartitionRouter, ListPartitionRouter, SubstreamPartitionRouter]],
2219+
List[
2220+
Union[
2221+
CustomPartitionRouter, ListPartitionRouter, SubstreamPartitionRouter
2222+
]
2223+
],
22002224
]
22012225
] = Field(
22022226
[],
@@ -2264,20 +2288,22 @@ class DynamicDeclarativeStream(BaseModel):
22642288
stream_template: DeclarativeStream = Field(
22652289
..., description="Reference to the stream template.", title="Stream Template"
22662290
)
2267-
components_resolver: Union[HttpComponentsResolver, ConfigComponentsResolver] = Field(
2268-
...,
2269-
description="Component resolve and populates stream templates with components values.",
2270-
title="Components Resolver",
2291+
components_resolver: Union[HttpComponentsResolver, ConfigComponentsResolver] = (
2292+
Field(
2293+
...,
2294+
description="Component resolve and populates stream templates with components values.",
2295+
title="Components Resolver",
2296+
)
22712297
)
22722298

22732299

2300+
SchemaFieldType.update_forward_refs()
22742301
CompositeErrorHandler.update_forward_refs()
22752302
DeclarativeSource1.update_forward_refs()
22762303
DeclarativeSource2.update_forward_refs()
22772304
SelectiveAuthenticator.update_forward_refs()
22782305
DeclarativeStream.update_forward_refs()
22792306
SessionTokenAuthenticator.update_forward_refs()
2280-
ItemsTypeMap.update_forward_refs()
22812307
DynamicSchemaLoader.update_forward_refs()
22822308
SimpleRetriever.update_forward_refs()
22832309
AsyncRetriever.update_forward_refs()

airbyte_cdk/sources/declarative/parsers/model_to_component_factory.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1911,8 +1911,8 @@ def create_items_type_map(
19111911
def create_types_map(self, model: TypesMapModel, config: Config, **kwargs: Any) -> TypesMap:
19121912
items_type = (
19131913
self._create_component_from_model(model=model.items_type, config=config)
1914-
if model.items_type
1915-
else None
1914+
if isinstance(model.items_type, ItemsTypeMapModel)
1915+
else model.items_type
19161916
)
19171917

19181918
return TypesMap(

0 commit comments

Comments
 (0)