airbyte-source-azure-blob-storage 0.4.4__py3-none-any.whl → 0.5.0__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.

Potentially problematic release.


This version of airbyte-source-azure-blob-storage might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: airbyte-source-azure-blob-storage
3
- Version: 0.4.4
3
+ Version: 0.5.0
4
4
  Summary: Source implementation for Azure Blob Storage.
5
5
  Home-page: https://airbyte.com
6
6
  License: MIT
@@ -0,0 +1,10 @@
1
+ source_azure_blob_storage/__init__.py,sha256=Wx4PzvHg900-c2CpOOP1Wk0zcJpNVqJrkMnPtDcuaQM,319
2
+ source_azure_blob_storage/config_migrations.py,sha256=WKo5ETt4y09_cjfny3EH4filBsC48ltLMlQ_wLcxYVM,4229
3
+ source_azure_blob_storage/run.py,sha256=3rwgY4Qs-KdOKZanpiLmGsQzNW5gUEE9zmrizEpCs20,1999
4
+ source_azure_blob_storage/source.py,sha256=j5ibzjzX_gAi2kASpajoQ8ZMbnJ8LIwuSKChwk5i3vY,2420
5
+ source_azure_blob_storage/spec.py,sha256=f8LbmWWWLunVXLwFpZRZM4RoGeAuTfZAuweMWF4cipk,4694
6
+ source_azure_blob_storage/stream_reader.py,sha256=ZSMgiwy6dOsFAGPyDIwCS4SklNIRo7dKdwesWIrsCrQ,6674
7
+ airbyte_source_azure_blob_storage-0.5.0.dist-info/METADATA,sha256=SF2QaBcT4cUntad57HCrpfwXCUXy_sUDgO6KYV68V4M,6265
8
+ airbyte_source_azure_blob_storage-0.5.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
9
+ airbyte_source_azure_blob_storage-0.5.0.dist-info/entry_points.txt,sha256=75v_DA_Xu0qr0eqtEXyh8sPCqcL9eXKWY8UwdST3ANE,79
10
+ airbyte_source_azure_blob_storage-0.5.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.0
2
+ Generator: poetry-core 1.9.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -9,19 +9,18 @@ from typing import Any, List, Mapping
9
9
 
10
10
  from airbyte_cdk import AirbyteEntrypoint, Source, create_connector_config_control_message
11
11
 
12
+
12
13
  logger = logging.getLogger("airbyte_logger")
13
14
 
14
15
 
15
16
  class MigrateConfig(ABC):
16
17
  @classmethod
17
18
  @abstractmethod
18
- def should_migrate(cls, config: Mapping[str, Any]) -> bool:
19
- ...
19
+ def should_migrate(cls, config: Mapping[str, Any]) -> bool: ...
20
20
 
21
21
  @classmethod
22
22
  @abstractmethod
23
- def migrate_config(cls, config: Mapping[str, Any]) -> Mapping[str, Any]:
24
- ...
23
+ def migrate_config(cls, config: Mapping[str, Any]) -> Mapping[str, Any]: ...
25
24
 
26
25
  @classmethod
27
26
  def modify_and_save(cls, config_path: str, source: Source, config: Mapping[str, Any]) -> Mapping[str, Any]:
@@ -6,9 +6,10 @@
6
6
  from typing import Any, Dict, Literal, Optional, Union
7
7
 
8
8
  import dpath.util
9
+ from pydantic import AnyUrl, BaseModel, Field
10
+
9
11
  from airbyte_cdk import OneOfOptionConfig
10
12
  from airbyte_cdk.sources.file_based.config.abstract_file_based_spec import AbstractFileBasedSpec
11
- from pydantic import AnyUrl, BaseModel, Field
12
13
 
13
14
 
14
15
  class Oauth2(BaseModel):
@@ -35,6 +36,25 @@ class Oauth2(BaseModel):
35
36
  )
36
37
 
37
38
 
39
+ class ClientCredentials(BaseModel):
40
+ class Config(OneOfOptionConfig):
41
+ title = "Authenticate via Client Credentials"
42
+ discriminator = "auth_type"
43
+
44
+ auth_type: Literal["client_credentials"] = Field("client_credentials", const=True)
45
+ app_tenant_id: str = Field(title="Tenant ID", description="Tenant ID of the Microsoft Azure Application", airbyte_secret=True)
46
+ app_client_id: str = Field(
47
+ title="Client ID",
48
+ description="Client ID of your Microsoft developer application",
49
+ airbyte_secret=True,
50
+ )
51
+ app_client_secret: str = Field(
52
+ title="Client Secret",
53
+ description="Client Secret of your Microsoft developer application",
54
+ airbyte_secret=True,
55
+ )
56
+
57
+
38
58
  class StorageAccountKey(BaseModel):
39
59
  class Config(OneOfOptionConfig):
40
60
  title = "Authenticate via Storage Account Key"
@@ -60,7 +80,7 @@ class SourceAzureBlobStorageSpec(AbstractFileBasedSpec):
60
80
  def documentation_url(cls) -> AnyUrl:
61
81
  return AnyUrl("https://docs.airbyte.com/integrations/sources/azure-blob-storage", scheme="https")
62
82
 
63
- credentials: Union[Oauth2, StorageAccountKey] = Field(
83
+ credentials: Union[Oauth2, ClientCredentials, StorageAccountKey] = Field(
64
84
  title="Authentication",
65
85
  description="Credentials for connecting to the Azure Blob Storage",
66
86
  discriminator="auth_type",
@@ -3,22 +3,62 @@
3
3
 
4
4
  import logging
5
5
  from io import IOBase
6
- from typing import Iterable, List, Optional, Union
6
+ from typing import Any, Iterable, List, Mapping, MutableMapping, Optional, Union
7
7
 
8
8
  import pytz
9
+ from azure.core.credentials import AccessToken, TokenCredential
10
+ from azure.core.exceptions import ResourceNotFoundError
11
+ from azure.storage.blob import BlobServiceClient, ContainerClient
12
+ from smart_open import open
13
+
9
14
  from airbyte_cdk import AirbyteTracedException, FailureType
10
15
  from airbyte_cdk.sources.file_based.file_based_stream_reader import AbstractFileBasedStreamReader, FileReadMode
11
16
  from airbyte_cdk.sources.file_based.remote_file import RemoteFile
12
17
  from airbyte_cdk.sources.streams.http.requests_native_auth import Oauth2Authenticator
13
- from azure.core.credentials import AccessToken
14
- from azure.core.exceptions import ResourceNotFoundError
15
- from azure.storage.blob import BlobServiceClient, ContainerClient
16
- from smart_open import open
17
18
 
18
19
  from .spec import SourceAzureBlobStorageSpec
19
20
 
20
21
 
21
- class AzureOauth2Authenticator(Oauth2Authenticator):
22
+ class AzureClientCredentialsAuthenticator(Oauth2Authenticator, TokenCredential):
23
+ def __init__(self, tenant_id: str, client_id: str, client_secret: str, **kwargs):
24
+ super().__init__(
25
+ token_refresh_endpoint=f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token",
26
+ client_id=client_id,
27
+ client_secret=client_secret,
28
+ grant_type="client_credentials",
29
+ scopes=["https://storage.azure.com/.default"],
30
+ refresh_token=None,
31
+ )
32
+
33
+ def build_refresh_request_body(self) -> Mapping[str, Any]:
34
+ """
35
+ Returns the request body to set on the refresh request
36
+
37
+ Override to define additional parameters
38
+ """
39
+ payload: MutableMapping[str, Any] = {
40
+ "grant_type": self.get_grant_type(),
41
+ "client_id": self.get_client_id(),
42
+ "client_secret": self.get_client_secret(),
43
+ }
44
+
45
+ if self.get_scopes():
46
+ payload["scope"] = " ".join(self.get_scopes())
47
+
48
+ if self.get_refresh_request_body():
49
+ for key, val in self.get_refresh_request_body().items():
50
+ # We defer to existing oauth constructs over custom configured fields
51
+ if key not in payload:
52
+ payload[key] = val
53
+
54
+ return payload
55
+
56
+ def get_token(self, *args, **kwargs) -> AccessToken:
57
+ """Parent class handles Oauth Refresh token logic."""
58
+ return AccessToken(token=self.get_access_token(), expires_on=int(self.get_token_expiry_date().timestamp()))
59
+
60
+
61
+ class AzureOauth2Authenticator(Oauth2Authenticator, TokenCredential):
22
62
  """
23
63
  Authenticator for Azure Blob Storage SDK to align with azure.core.credentials.TokenCredential protocol
24
64
  """
@@ -62,17 +102,24 @@ class SourceAzureBlobStorageStreamReader(AbstractFileBasedStreamReader):
62
102
  return BlobServiceClient(self.account_url, credential=self._credentials)
63
103
 
64
104
  @property
65
- def azure_credentials(self) -> Union[str, AzureOauth2Authenticator]:
105
+ def azure_credentials(self) -> Union[str, AzureOauth2Authenticator, AzureClientCredentialsAuthenticator]:
66
106
  if not self._credentials:
67
107
  if self.config.credentials.auth_type == "storage_account_key":
68
108
  self._credentials = self.config.credentials.azure_blob_storage_account_key
69
- else:
109
+ elif self.config.credentials.auth_type == "oauth2":
70
110
  self._credentials = AzureOauth2Authenticator(
71
111
  token_refresh_endpoint=f"https://login.microsoftonline.com/{self.config.credentials.tenant_id}/oauth2/v2.0/token",
72
112
  client_id=self.config.credentials.client_id,
73
113
  client_secret=self.config.credentials.client_secret,
74
114
  refresh_token=self.config.credentials.refresh_token,
75
115
  )
116
+ elif self.config.credentials.auth_type == "client_credentials":
117
+ self._credentials = AzureClientCredentialsAuthenticator(
118
+ tenant_id=self.config.credentials.app_tenant_id,
119
+ client_id=self.config.credentials.app_client_id,
120
+ client_secret=self.config.credentials.app_client_secret,
121
+ )
122
+
76
123
  return self._credentials
77
124
 
78
125
  def get_matching_files(
@@ -1,10 +0,0 @@
1
- source_azure_blob_storage/__init__.py,sha256=Wx4PzvHg900-c2CpOOP1Wk0zcJpNVqJrkMnPtDcuaQM,319
2
- source_azure_blob_storage/config_migrations.py,sha256=SAcp-Eh8vuu6LgzgmfhRqhpoqWdvE3jBDmfYTlJLHko,4244
3
- source_azure_blob_storage/run.py,sha256=3rwgY4Qs-KdOKZanpiLmGsQzNW5gUEE9zmrizEpCs20,1999
4
- source_azure_blob_storage/source.py,sha256=j5ibzjzX_gAi2kASpajoQ8ZMbnJ8LIwuSKChwk5i3vY,2420
5
- source_azure_blob_storage/spec.py,sha256=rKIdL4DRezxZOXS7dvIvhoxsSJgXBWzEq8Xs5uTAbco,3944
6
- source_azure_blob_storage/stream_reader.py,sha256=VvskbMNdwCjN4AsZ8rI8FX18bM_wrmTq87FG6XCAIlg,4589
7
- airbyte_source_azure_blob_storage-0.4.4.dist-info/METADATA,sha256=56ZI8NbJkLnF3RCxrYC6pHzZHYmyXVokOrwVPrn1mJo,6265
8
- airbyte_source_azure_blob_storage-0.4.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
9
- airbyte_source_azure_blob_storage-0.4.4.dist-info/entry_points.txt,sha256=75v_DA_Xu0qr0eqtEXyh8sPCqcL9eXKWY8UwdST3ANE,79
10
- airbyte_source_azure_blob_storage-0.4.4.dist-info/RECORD,,