atlan-application-sdk 0.1.1rc31__py3-none-any.whl → 0.1.1rc33__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.
@@ -0,0 +1,70 @@
1
+ from typing import Optional
2
+
3
+ from pyatlan.client.aio.client import AsyncAtlanClient
4
+
5
+ from application_sdk.common.error_codes import ClientError
6
+ from application_sdk.constants import (
7
+ ATLAN_API_KEY,
8
+ ATLAN_API_TOKEN_GUID,
9
+ ATLAN_BASE_URL,
10
+ ATLAN_CLIENT_ID,
11
+ ATLAN_CLIENT_SECRET,
12
+ )
13
+ from application_sdk.observability.logger_adaptor import get_logger
14
+
15
+ logger = get_logger(__name__)
16
+
17
+
18
+ async def get_client(
19
+ base_url: Optional[str] = None,
20
+ api_key: Optional[str] = None,
21
+ api_token_guid: Optional[str] = None,
22
+ ) -> AsyncAtlanClient:
23
+ """
24
+ Returns an authenticated AsyncAtlanClient instance using provided parameters or environment variables.
25
+
26
+ Selects authentication method based on the presence of parameters or environment variables and validates the required configuration.
27
+ In general, the use of environment variables is recommended. Any parameters specified will override the environment variables.
28
+
29
+ Args:
30
+ base_url: Atlan base URL (overrides ATLAN_BASE_URL)
31
+ api_key: Atlan API key (overrides ATLAN_API_KEY)
32
+ api_token_guid: API token GUID (overrides API_TOKEN_GUID)
33
+ """
34
+ # Resolve final values (parameters override env vars)
35
+ final_token_guid = api_token_guid or ATLAN_API_TOKEN_GUID
36
+ final_base_url = base_url or ATLAN_BASE_URL
37
+ final_api_key = api_key or ATLAN_API_KEY
38
+
39
+ # Priority 1: Token-based auth (recommended for production)
40
+ if final_token_guid:
41
+ if final_base_url or final_api_key:
42
+ logger.warning(
43
+ "Token auth takes precedence - ignoring base_url/api_key parameters as well as ATLAN_BASE_URL and ATLAN_API_KEY environment variables."
44
+ )
45
+ return await _get_client_from_token(final_token_guid)
46
+
47
+ # Priority 2: API key + base URL auth
48
+ if not final_base_url:
49
+ raise ClientError(
50
+ "ATLAN_BASE_URL is required (via parameter or environment variable)"
51
+ )
52
+ if not final_api_key:
53
+ raise ClientError(
54
+ "ATLAN_API_KEY is required (via parameter or environment variable)"
55
+ )
56
+
57
+ logger.info("Using API key-based authentication")
58
+ return AsyncAtlanClient(base_url=final_base_url, api_key=final_api_key)
59
+
60
+
61
+ async def _get_client_from_token(api_token_guid: str):
62
+ if not ATLAN_CLIENT_ID:
63
+ raise ClientError(
64
+ f"{ClientError.AUTH_CONFIG_ERROR}: Environment variable CLIENT_ID is required when API_TOKEN_GUID is set."
65
+ )
66
+ if not ATLAN_CLIENT_SECRET:
67
+ raise ClientError(
68
+ f"{ClientError.AUTH_CONFIG_ERROR}: Environment variable CLIENT_SECRET is required when API_TOKEN_GUID is set."
69
+ )
70
+ return await AsyncAtlanClient.from_token_guid(guid=api_token_guid)
@@ -36,7 +36,7 @@ APPLICATION_NAME = os.getenv("ATLAN_APPLICATION_NAME", "default")
36
36
  #: Name of the deployment, used to distinguish between different deployments of the same application
37
37
  DEPLOYMENT_NAME = os.getenv("ATLAN_DEPLOYMENT_NAME", LOCAL_ENVIRONMENT)
38
38
  #: Host address for the application's HTTP server
39
- APP_HOST = str(os.getenv("ATLAN_APP_HTTP_HOST", "localhost"))
39
+ APP_HOST = str(os.getenv("ATLAN_APP_HTTP_HOST", "0.0.0.0"))
40
40
  #: Port number for the application's HTTP server
41
41
  APP_PORT = int(os.getenv("ATLAN_APP_HTTP_PORT", "8000"))
42
42
  #: Tenant ID for multi-tenant applications
@@ -51,7 +51,12 @@ class ParquetInput(Input):
51
51
  Returns:
52
52
  Optional[str]: Path to the downloaded local file.
53
53
  """
54
- parquet_files = glob.glob(local_file_path)
54
+ # if the path is a directory, then check if the directory has any parquet files
55
+ parquet_files = []
56
+ if os.path.isdir(local_file_path):
57
+ parquet_files = glob.glob(os.path.join(local_file_path, "*.parquet"))
58
+ else:
59
+ parquet_files = glob.glob(local_file_path)
55
60
  if not parquet_files:
56
61
  if self.input_prefix:
57
62
  logger.info(
@@ -162,10 +167,9 @@ class ParquetInput(Input):
162
167
  await self.download_files(path)
163
168
  yield daft.read_parquet(path)
164
169
  else:
165
- path = f"{self.path}/*.parquet"
166
- if self.input_prefix and path:
167
- await self.download_files(path)
168
- yield daft.read_parquet(path)
170
+ if self.path and self.input_prefix:
171
+ await self.download_files(self.path)
172
+ yield daft.read_parquet(f"{self.path}/*.parquet")
169
173
 
170
174
  except Exception as error:
171
175
  logger.error(
@@ -0,0 +1,28 @@
1
+ from hypothesis import strategies as st
2
+
3
+ # Strategy for generating safe file path components
4
+ safe_path_strategy = st.text(
5
+ alphabet=st.characters(),
6
+ )
7
+
8
+ # Strategy for generating file names
9
+ file_name_strategy = st.builds(lambda name: f"{name}.parquet", name=safe_path_strategy)
10
+
11
+ # Strategy for generating lists of file names
12
+ file_names_strategy = st.lists(file_name_strategy, unique=True)
13
+
14
+ # Strategy for generating input prefixes
15
+ input_prefix_strategy = safe_path_strategy
16
+
17
+ # Strategy for generating chunk sizes
18
+ chunk_size_strategy = st.one_of(st.none(), st.integers(min_value=1, max_value=1000000))
19
+
20
+ # Strategy for generating complete ParquetInput configurations
21
+ parquet_input_config_strategy = st.fixed_dictionaries(
22
+ {
23
+ "path": safe_path_strategy,
24
+ "chunk_size": chunk_size_strategy,
25
+ "input_prefix": st.one_of(st.none(), input_prefix_strategy),
26
+ "file_names": st.one_of(st.none(), file_names_strategy),
27
+ }
28
+ )
@@ -2,4 +2,4 @@
2
2
  Version information for the application_sdk package.
3
3
  """
4
4
 
5
- __version__ = "0.1.1rc31"
5
+ __version__ = "0.1.1rc33"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atlan-application-sdk
3
- Version: 0.1.1rc31
3
+ Version: 0.1.1rc33
4
4
  Summary: Atlan Application SDK is a Python library for developing applications on the Atlan Platform
5
5
  Project-URL: Repository, https://github.com/atlanhq/application-sdk
6
6
  Project-URL: Documentation, https://github.com/atlanhq/application-sdk/README.md
@@ -26,12 +26,12 @@ Requires-Dist: fastapi[standard]>=0.115.0
26
26
  Requires-Dist: loguru>=0.7.3
27
27
  Requires-Dist: opentelemetry-exporter-otlp>=1.27.0
28
28
  Requires-Dist: psutil>=7.0.0
29
- Requires-Dist: pyatlan>=7.1.6
29
+ Requires-Dist: pyatlan>=8.0.0
30
30
  Requires-Dist: pydantic>=2.10.6
31
31
  Requires-Dist: python-dotenv>=1.1.0
32
32
  Requires-Dist: uvloop>=0.21.0; sys_platform != 'win32'
33
33
  Provides-Extra: daft
34
- Requires-Dist: daft[sql]>=0.4.12; extra == 'daft'
34
+ Requires-Dist: daft>=0.4.12; extra == 'daft'
35
35
  Provides-Extra: iam-auth
36
36
  Requires-Dist: boto3>=1.38.6; extra == 'iam-auth'
37
37
  Provides-Extra: iceberg
@@ -1,6 +1,6 @@
1
1
  application_sdk/__init__.py,sha256=2e2mvmLJ5dxmJGPELtb33xwP-j6JMdoIuqKycEn7hjg,151
2
- application_sdk/constants.py,sha256=jN3-PvCYg4Ko45SyJWlFt3ilKypUzY395J0FB1x4XbU,9488
3
- application_sdk/version.py,sha256=XxupFe5OZ0YH8PhpwRAl6T6br2R7lWHBhTVe0h81h9U,88
2
+ application_sdk/constants.py,sha256=_Fmk9PgpM68chPDHHkgrs4Zg2KK4UCqqg7Oj9_u3WVo,9486
3
+ application_sdk/version.py,sha256=S2v-GGamis8Ciz___AuEVE_IfiBRwYHL3uV0kM3PWyU,88
4
4
  application_sdk/worker.py,sha256=dZLxPkAieCSw7XEWxzL-FRk0QAZm7vXQBICjZODy3B4,7488
5
5
  application_sdk/activities/__init__.py,sha256=EH5VTHcfGykIX7V1HsG0J1Z-1FbJEXTQOET0HdzFDjU,9519
6
6
  application_sdk/activities/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -14,6 +14,7 @@ application_sdk/activities/query_extraction/sql.py,sha256=xC-dC_so3D9yY88lSL2W8Q
14
14
  application_sdk/application/__init__.py,sha256=sUmng7msiUCPmQu1YY9gRvzXWviVKABVjKT3diPC6GM,7553
15
15
  application_sdk/application/metadata_extraction/sql.py,sha256=ohpV4qZ92uKRlH7I_8G67ocnWkZJAZCU_7XdvqYPiN4,7966
16
16
  application_sdk/clients/__init__.py,sha256=C9T84J7V6ZumcoWJPAxdd3tqSmbyciaGBJn-CaCCny0,1341
17
+ application_sdk/clients/async_atlan.py,sha256=RTgRbMw6zJWcv1C-7cU4ccaSW5XZsB5dcA1Tlkj32p8,2699
17
18
  application_sdk/clients/atlan.py,sha256=f2-Uk5KiPIDJEhGkfYctA_f3CwoVB_mWNBMVvxeLuY4,2684
18
19
  application_sdk/clients/atlan_auth.py,sha256=MQznmvVKrlOT_Tp232W4UrOupRrx9Dx9zQm3n1R7kD8,8938
19
20
  application_sdk/clients/sql.py,sha256=tW89SHuuWdU5jv8lDUP5AUCEpR2CF_5TyUvYDCBHses,17880
@@ -50,7 +51,7 @@ application_sdk/inputs/__init__.py,sha256=_d-cUhcDyoJTJR3PdQkC831go6VDw9AM6Bg7-q
50
51
  application_sdk/inputs/iceberg.py,sha256=xiv1kNtVx1k0h3ZJbJeXjZwdfBGSy9j9orYP_AyCYlI,2756
51
52
  application_sdk/inputs/json.py,sha256=J1CVz0YGQHDyq840TyoBHE7Baua2yIFHzsrybiZbeWk,6079
52
53
  application_sdk/inputs/objectstore.py,sha256=uOJW0uB3FrDmnyHFhAd23QOq3MKrAzhYdKCszdpMeF8,8219
53
- application_sdk/inputs/parquet.py,sha256=Hsi6Nz_KwxFMB6DcHSQov5y_hRkoeN7e4xfpYwogveo,6346
54
+ application_sdk/inputs/parquet.py,sha256=j1O5uYZ2ok28iPYFpMoltKzJTDGmht7qoEjRKQ48P8E,6590
54
55
  application_sdk/inputs/secretstore.py,sha256=0H81CkbKj1KTU_wlPofpsAvPHs9YaOuKbRBmLRdiiNw,4583
55
56
  application_sdk/inputs/sql_query.py,sha256=1EREgea6kKNaMIyX2HLJgbJ07rtAgLasd9NyvDcdZok,10636
56
57
  application_sdk/inputs/statestore.py,sha256=ORWnv8ZCqC1wT4vlW4v5EemJT4oQ3t_DlpjKDAgTRTs,3117
@@ -99,6 +100,7 @@ application_sdk/test_utils/hypothesis/strategies/handlers/sql/sql_metadata.py,sh
99
100
  application_sdk/test_utils/hypothesis/strategies/handlers/sql/sql_preflight.py,sha256=e9uo6Bx5w_ZAEu6bDTWbMbmzqB0MYl2dH-JlXg3bkV8,2648
100
101
  application_sdk/test_utils/hypothesis/strategies/inputs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
102
  application_sdk/test_utils/hypothesis/strategies/inputs/json_input.py,sha256=9mPI585J4tfQTZiM_uoFXCq7qrLML7jwH5eDm_mzvm4,749
103
+ application_sdk/test_utils/hypothesis/strategies/inputs/parquet_input.py,sha256=qOi5En011KiOWAusP6dCvzr1rtC_sc2IkWfj7hWvSh0,950
102
104
  application_sdk/test_utils/hypothesis/strategies/outputs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
103
105
  application_sdk/test_utils/hypothesis/strategies/outputs/json_output.py,sha256=p9wotUJwc-Wmm54_qVG5Ivp_mgl7YTeAcQfC6RXlxCc,1835
104
106
  application_sdk/test_utils/hypothesis/strategies/outputs/statestore.py,sha256=gmYBwePNoSI_pl2WTXOClgkruzRwkOX_1SmBaUTha0c,2903
@@ -133,8 +135,8 @@ application_sdk/workflows/metadata_extraction/__init__.py,sha256=jHUe_ZBQ66jx8bg
133
135
  application_sdk/workflows/metadata_extraction/sql.py,sha256=_NhszxIgmcQI6lVpjJoyJRFLwPYvJw1Dyqox_m9K2RA,11947
134
136
  application_sdk/workflows/query_extraction/__init__.py,sha256=n066_CX5RpJz6DIxGMkKS3eGSRg03ilaCtsqfJWQb7Q,117
135
137
  application_sdk/workflows/query_extraction/sql.py,sha256=kT_JQkLCRZ44ZpaC4QvPL6DxnRIIVh8gYHLqRbMI-hA,4826
136
- atlan_application_sdk-0.1.1rc31.dist-info/METADATA,sha256=_Z91665V1flLl-gpTaVHsY3_1KYbmu_mucYaPc-yE78,5473
137
- atlan_application_sdk-0.1.1rc31.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
138
- atlan_application_sdk-0.1.1rc31.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
139
- atlan_application_sdk-0.1.1rc31.dist-info/licenses/NOTICE,sha256=A-XVVGt3KOYuuMmvSMIFkg534F1vHiCggEBp4Ez3wGk,1041
140
- atlan_application_sdk-0.1.1rc31.dist-info/RECORD,,
138
+ atlan_application_sdk-0.1.1rc33.dist-info/METADATA,sha256=wXJnZNtP3QrB6mv01MU9HhbVPtdamPBDnNt_oDrACAI,5468
139
+ atlan_application_sdk-0.1.1rc33.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
140
+ atlan_application_sdk-0.1.1rc33.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
141
+ atlan_application_sdk-0.1.1rc33.dist-info/licenses/NOTICE,sha256=A-XVVGt3KOYuuMmvSMIFkg534F1vHiCggEBp4Ez3wGk,1041
142
+ atlan_application_sdk-0.1.1rc33.dist-info/RECORD,,