atlan-application-sdk 0.1.1rc26__py3-none-any.whl → 0.1.1rc27__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.
- application_sdk/constants.py +4 -3
- application_sdk/inputs/objectstore.py +4 -4
- application_sdk/inputs/parquet.py +14 -8
- application_sdk/inputs/secretstore.py +3 -2
- application_sdk/outputs/atlan_storage.py +0 -1
- application_sdk/outputs/objectstore.py +18 -0
- application_sdk/outputs/secretstore.py +2 -2
- application_sdk/version.py +1 -1
- {atlan_application_sdk-0.1.1rc26.dist-info → atlan_application_sdk-0.1.1rc27.dist-info}/METADATA +2 -2
- {atlan_application_sdk-0.1.1rc26.dist-info → atlan_application_sdk-0.1.1rc27.dist-info}/RECORD +13 -13
- {atlan_application_sdk-0.1.1rc26.dist-info → atlan_application_sdk-0.1.1rc27.dist-info}/licenses/NOTICE +1 -1
- {atlan_application_sdk-0.1.1rc26.dist-info → atlan_application_sdk-0.1.1rc27.dist-info}/WHEEL +0 -0
- {atlan_application_sdk-0.1.1rc26.dist-info → atlan_application_sdk-0.1.1rc27.dist-info}/licenses/LICENSE +0 -0
application_sdk/constants.py
CHANGED
|
@@ -27,11 +27,14 @@ from dotenv import load_dotenv
|
|
|
27
27
|
|
|
28
28
|
load_dotenv(dotenv_path=".env")
|
|
29
29
|
|
|
30
|
+
# Static Constants
|
|
31
|
+
LOCAL_ENVIRONMENT = "local"
|
|
32
|
+
|
|
30
33
|
# Application Constants
|
|
31
34
|
#: Name of the application, used for identification
|
|
32
35
|
APPLICATION_NAME = os.getenv("ATLAN_APPLICATION_NAME", "default")
|
|
33
36
|
#: Name of the deployment, used to distinguish between different deployments of the same application
|
|
34
|
-
DEPLOYMENT_NAME = os.getenv("ATLAN_DEPLOYMENT_NAME",
|
|
37
|
+
DEPLOYMENT_NAME = os.getenv("ATLAN_DEPLOYMENT_NAME", LOCAL_ENVIRONMENT)
|
|
35
38
|
#: Host address for the application's HTTP server
|
|
36
39
|
APP_HOST = str(os.getenv("ATLAN_APP_HTTP_HOST", "localhost"))
|
|
37
40
|
#: Port number for the application's HTTP server
|
|
@@ -46,8 +49,6 @@ APP_DASHBOARD_PORT = int(os.getenv("ATLAN_APP_DASHBOARD_PORT", "8000"))
|
|
|
46
49
|
SQL_SERVER_MIN_VERSION = os.getenv("ATLAN_SQL_SERVER_MIN_VERSION")
|
|
47
50
|
#: Path to the SQL queries directory
|
|
48
51
|
SQL_QUERIES_PATH = os.getenv("ATLAN_SQL_QUERIES_PATH", "app/sql")
|
|
49
|
-
#: Whether to use local development mode (used for instance to fetch secrets from the local state store)
|
|
50
|
-
LOCAL_DEVELOPMENT = os.getenv("ATLAN_LOCAL_DEVELOPMENT", "false").lower() == "true"
|
|
51
52
|
|
|
52
53
|
# Output Path Constants
|
|
53
54
|
#: Output path format for workflows (example: objectstore://bucket/artifacts/apps/{application_name}/workflows/{workflow_id}/{workflow_run_id})
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
4
|
import os
|
|
5
|
-
from typing import Dict, List,
|
|
5
|
+
from typing import Dict, List, Union
|
|
6
6
|
|
|
7
7
|
import orjson
|
|
8
8
|
from dapr.clients import DaprClient
|
|
@@ -27,7 +27,7 @@ class ObjectStoreInput:
|
|
|
27
27
|
cls,
|
|
28
28
|
operation: str,
|
|
29
29
|
metadata: Dict[str, str],
|
|
30
|
-
data:
|
|
30
|
+
data: Union[bytes, str] = "",
|
|
31
31
|
object_store_name: str = DEPLOYMENT_OBJECT_STORE_NAME,
|
|
32
32
|
) -> bytes:
|
|
33
33
|
"""
|
|
@@ -172,7 +172,7 @@ class ObjectStoreInput:
|
|
|
172
172
|
try:
|
|
173
173
|
# this takes care of listing from all type of storage - local as well as object stores
|
|
174
174
|
metadata = {"prefix": prefix, "fileName": prefix} if prefix else {}
|
|
175
|
-
data = json.dumps({"prefix": prefix}).encode("utf-8") if prefix else
|
|
175
|
+
data = json.dumps({"prefix": prefix}).encode("utf-8") if prefix else ""
|
|
176
176
|
|
|
177
177
|
response_data = cls._invoke_dapr_binding(
|
|
178
178
|
operation=cls.OBJECT_LIST_OPERATION,
|
|
@@ -233,7 +233,7 @@ class ObjectStoreInput:
|
|
|
233
233
|
"""
|
|
234
234
|
try:
|
|
235
235
|
metadata = {"key": file_path, "fileName": file_path}
|
|
236
|
-
data = json.dumps({"key": file_path}).encode("utf-8") if file_path else
|
|
236
|
+
data = json.dumps({"key": file_path}).encode("utf-8") if file_path else ""
|
|
237
237
|
|
|
238
238
|
response_data = cls._invoke_dapr_binding(
|
|
239
239
|
operation=cls.OBJECT_GET_OPERATION,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import glob
|
|
2
|
+
import os
|
|
2
3
|
from typing import TYPE_CHECKING, AsyncIterator, Iterator, List, Optional, Union
|
|
3
4
|
|
|
4
5
|
from application_sdk.inputs import Input
|
|
@@ -41,27 +42,32 @@ class ParquetInput(Input):
|
|
|
41
42
|
self.input_prefix = input_prefix
|
|
42
43
|
self.file_names = file_names
|
|
43
44
|
|
|
44
|
-
async def download_files(self,
|
|
45
|
+
async def download_files(self, local_file_path: str) -> Optional[str]:
|
|
45
46
|
"""Read a file from the object store.
|
|
46
47
|
|
|
47
48
|
Args:
|
|
48
|
-
|
|
49
|
+
local_file_path (str): Path to the local file in the temp directory.
|
|
49
50
|
|
|
50
51
|
Returns:
|
|
51
52
|
Optional[str]: Path to the downloaded local file.
|
|
52
53
|
"""
|
|
53
|
-
parquet_files = glob.glob(
|
|
54
|
+
parquet_files = glob.glob(local_file_path)
|
|
54
55
|
if not parquet_files:
|
|
55
56
|
if self.input_prefix:
|
|
56
57
|
logger.info(
|
|
57
|
-
f"Reading file from object store: {
|
|
58
|
-
)
|
|
59
|
-
ObjectStoreInput.download_files_from_object_store(
|
|
60
|
-
self.input_prefix, remote_file_path
|
|
58
|
+
f"Reading file from object store: {local_file_path} from {self.input_prefix}"
|
|
61
59
|
)
|
|
60
|
+
if os.path.isdir(local_file_path):
|
|
61
|
+
ObjectStoreInput.download_files_from_object_store(
|
|
62
|
+
self.input_prefix, local_file_path
|
|
63
|
+
)
|
|
64
|
+
else:
|
|
65
|
+
ObjectStoreInput.download_file_from_object_store(
|
|
66
|
+
self.input_prefix, local_file_path
|
|
67
|
+
)
|
|
62
68
|
else:
|
|
63
69
|
raise ValueError(
|
|
64
|
-
f"No parquet files found in {
|
|
70
|
+
f"No parquet files found in {local_file_path} and no input prefix provided"
|
|
65
71
|
)
|
|
66
72
|
|
|
67
73
|
async def get_dataframe(self) -> "pd.DataFrame":
|
|
@@ -8,9 +8,10 @@ from typing import Any, Dict
|
|
|
8
8
|
from dapr.clients import DaprClient
|
|
9
9
|
|
|
10
10
|
from application_sdk.constants import (
|
|
11
|
+
DEPLOYMENT_NAME,
|
|
11
12
|
DEPLOYMENT_SECRET_PATH,
|
|
12
13
|
DEPLOYMENT_SECRET_STORE_NAME,
|
|
13
|
-
|
|
14
|
+
LOCAL_ENVIRONMENT,
|
|
14
15
|
SECRET_STORE_NAME,
|
|
15
16
|
)
|
|
16
17
|
from application_sdk.observability.logger_adaptor import get_logger
|
|
@@ -41,7 +42,7 @@ class SecretStoreInput:
|
|
|
41
42
|
Returns:
|
|
42
43
|
Dict with processed secret data
|
|
43
44
|
"""
|
|
44
|
-
if
|
|
45
|
+
if DEPLOYMENT_NAME == LOCAL_ENVIRONMENT:
|
|
45
46
|
return {}
|
|
46
47
|
|
|
47
48
|
try:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Object store interface for the application."""
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
|
+
import shutil
|
|
4
5
|
|
|
5
6
|
from dapr.clients import DaprClient
|
|
6
7
|
from temporalio import activity
|
|
@@ -15,6 +16,22 @@ activity.logger = logger
|
|
|
15
16
|
class ObjectStoreOutput:
|
|
16
17
|
OBJECT_CREATE_OPERATION = "create"
|
|
17
18
|
|
|
19
|
+
@staticmethod
|
|
20
|
+
def _cleanup_local_path(path: str) -> None:
|
|
21
|
+
"""Remove a file or directory (recursively). Ignores if doesn't exist.
|
|
22
|
+
Args:
|
|
23
|
+
path (str): The path to the file or directory to remove.
|
|
24
|
+
"""
|
|
25
|
+
try:
|
|
26
|
+
if os.path.isfile(path) or os.path.islink(path):
|
|
27
|
+
os.remove(path)
|
|
28
|
+
elif os.path.isdir(path):
|
|
29
|
+
shutil.rmtree(path)
|
|
30
|
+
except FileNotFoundError:
|
|
31
|
+
pass # ignore if the file or directory doesn't exist
|
|
32
|
+
except Exception as e:
|
|
33
|
+
logger.warning(f"Error cleaning up {path}: {str(e)}")
|
|
34
|
+
|
|
18
35
|
@classmethod
|
|
19
36
|
async def push_file_to_object_store(
|
|
20
37
|
cls,
|
|
@@ -62,6 +79,7 @@ class ObjectStoreOutput:
|
|
|
62
79
|
f"Error pushing file {relative_path} to object store: {str(e)}"
|
|
63
80
|
)
|
|
64
81
|
raise e
|
|
82
|
+
cls._cleanup_local_path(file_path)
|
|
65
83
|
|
|
66
84
|
@classmethod
|
|
67
85
|
async def push_files_to_object_store(
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import uuid
|
|
4
4
|
from typing import Any, Dict
|
|
5
5
|
|
|
6
|
-
from application_sdk.constants import
|
|
6
|
+
from application_sdk.constants import DEPLOYMENT_NAME, LOCAL_ENVIRONMENT
|
|
7
7
|
from application_sdk.inputs.statestore import StateType
|
|
8
8
|
from application_sdk.outputs.statestore import StateStoreOutput
|
|
9
9
|
|
|
@@ -26,7 +26,7 @@ class SecretStoreOutput:
|
|
|
26
26
|
>>> SecretStoreOutput.save_secret({"username": "admin", "password": "password"})
|
|
27
27
|
"1234567890"
|
|
28
28
|
"""
|
|
29
|
-
if
|
|
29
|
+
if DEPLOYMENT_NAME == LOCAL_ENVIRONMENT:
|
|
30
30
|
# NOTE: (development) temporary solution to store the credentials in the state store.
|
|
31
31
|
# In production, dapr doesn't support creating secrets.
|
|
32
32
|
credential_guid = str(uuid.uuid4())
|
application_sdk/version.py
CHANGED
{atlan_application_sdk-0.1.1rc26.dist-info → atlan_application_sdk-0.1.1rc27.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: atlan-application-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.1rc27
|
|
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
|
|
@@ -31,7 +31,7 @@ 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:
|
|
34
|
+
Requires-Dist: daft[sql]>=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
|
{atlan_application_sdk-0.1.1rc26.dist-info → atlan_application_sdk-0.1.1rc27.dist-info}/RECORD
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
application_sdk/__init__.py,sha256=2e2mvmLJ5dxmJGPELtb33xwP-j6JMdoIuqKycEn7hjg,151
|
|
2
|
-
application_sdk/constants.py,sha256=
|
|
3
|
-
application_sdk/version.py,sha256=
|
|
2
|
+
application_sdk/constants.py,sha256=n7pIycAD8olbB-nzXTvKPahUiuT8tIAR4quj9VPLNg0,8980
|
|
3
|
+
application_sdk/version.py,sha256=are5jaXFs9oL9m2TQqMgiBrJuVelURMxLka4krzJ5YQ,88
|
|
4
4
|
application_sdk/worker.py,sha256=2fLjuKNJafhaQXrHzmxXYO22F4ZSc0igMjoxXVNBFfk,6167
|
|
5
5
|
application_sdk/activities/__init__.py,sha256=EH5VTHcfGykIX7V1HsG0J1Z-1FbJEXTQOET0HdzFDjU,9519
|
|
6
6
|
application_sdk/activities/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -45,9 +45,9 @@ application_sdk/handlers/sql.py,sha256=qyLbTG9HZYX5_PAsvoSKANVcK53JS3sLUrqXMgXr1
|
|
|
45
45
|
application_sdk/inputs/__init__.py,sha256=_d-cUhcDyoJTJR3PdQkC831go6VDw9AM6Bg7-qm3NHI,1900
|
|
46
46
|
application_sdk/inputs/iceberg.py,sha256=xiv1kNtVx1k0h3ZJbJeXjZwdfBGSy9j9orYP_AyCYlI,2756
|
|
47
47
|
application_sdk/inputs/json.py,sha256=J1CVz0YGQHDyq840TyoBHE7Baua2yIFHzsrybiZbeWk,6079
|
|
48
|
-
application_sdk/inputs/objectstore.py,sha256=
|
|
49
|
-
application_sdk/inputs/parquet.py,sha256=
|
|
50
|
-
application_sdk/inputs/secretstore.py,sha256=
|
|
48
|
+
application_sdk/inputs/objectstore.py,sha256=mOC5Bv10tZg9y4oikff_QViHSWZ_FHiotI9xdrlAIok,8781
|
|
49
|
+
application_sdk/inputs/parquet.py,sha256=Hsi6Nz_KwxFMB6DcHSQov5y_hRkoeN7e4xfpYwogveo,6346
|
|
50
|
+
application_sdk/inputs/secretstore.py,sha256=WPGvsPMLUaARvXA6JSa4uHp7tQcCW4NMIIUDQyM3F-I,3946
|
|
51
51
|
application_sdk/inputs/sql_query.py,sha256=1EREgea6kKNaMIyX2HLJgbJ07rtAgLasd9NyvDcdZok,10636
|
|
52
52
|
application_sdk/inputs/statestore.py,sha256=Ib87toiYzSEg7_7C0o6CeS-c0vsjaJqiIEIKwiwXAcE,2954
|
|
53
53
|
application_sdk/observability/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -58,13 +58,13 @@ application_sdk/observability/traces_adaptor.py,sha256=0eQJPN-tYA_dV8D3uEa5ZiX9g
|
|
|
58
58
|
application_sdk/observability/utils.py,sha256=MKEpT0WYtpATUgLgJDkGQaAP_t-jpDYMUKDfEvr8Phg,2448
|
|
59
59
|
application_sdk/observability/decorators/observability_decorator.py,sha256=JNrWNXT5W4klmlAc5b8C3_VBjDu0PI64W2ptr7LMzk4,8110
|
|
60
60
|
application_sdk/outputs/__init__.py,sha256=HX8VcN22xyrkoRWdjQj8TrC5dEUG7cPzOcvJhlprqAs,8415
|
|
61
|
-
application_sdk/outputs/atlan_storage.py,sha256=
|
|
61
|
+
application_sdk/outputs/atlan_storage.py,sha256=HQLbuyOZQC-GxYAiCVJakIJizTWy926tdMGOHvaBlD8,6029
|
|
62
62
|
application_sdk/outputs/eventstore.py,sha256=fEW1oo9ncKylF5uLXTgjyRQZCrj72Gta3CaeduSX8nw,5548
|
|
63
63
|
application_sdk/outputs/iceberg.py,sha256=IGtj5WDgqLu6vzDEvw5DLsKsjm29Krto3AHvWpemr0A,5311
|
|
64
64
|
application_sdk/outputs/json.py,sha256=xF-8mY3BZRRejip4s9npIUuFaAxgFmBQVaLMkrI_iCI,14117
|
|
65
|
-
application_sdk/outputs/objectstore.py,sha256=
|
|
65
|
+
application_sdk/outputs/objectstore.py,sha256=TJvgfkJpGRK129ttxY7qRYJ7ASKZA4R6-0BUA3Lk7mc,4450
|
|
66
66
|
application_sdk/outputs/parquet.py,sha256=A2EnEx1zWjaXk10u3eJusmWxGxt8WR7CHXDaJgsKpq0,11040
|
|
67
|
-
application_sdk/outputs/secretstore.py,sha256=
|
|
67
|
+
application_sdk/outputs/secretstore.py,sha256=JS9vUzb11leDpcMQSCnLJuE9Ww-9G3wMvCdUKBPaw9I,1342
|
|
68
68
|
application_sdk/outputs/statestore.py,sha256=erviUTNyK-iLPe03i4r-G-5D3uAWdRnkW83Hnu7wI7o,3854
|
|
69
69
|
application_sdk/server/__init__.py,sha256=KTqE1YPw_3WDVMWatJUuf9OOiobLM2K5SMaBrI62sCo,1568
|
|
70
70
|
application_sdk/server/fastapi/__init__.py,sha256=QiIaR43QhgJaLeKs5lTghfxCAGxVxFnYAudy47akbP4,27783
|
|
@@ -129,8 +129,8 @@ application_sdk/workflows/metadata_extraction/__init__.py,sha256=jHUe_ZBQ66jx8bg
|
|
|
129
129
|
application_sdk/workflows/metadata_extraction/sql.py,sha256=_NhszxIgmcQI6lVpjJoyJRFLwPYvJw1Dyqox_m9K2RA,11947
|
|
130
130
|
application_sdk/workflows/query_extraction/__init__.py,sha256=n066_CX5RpJz6DIxGMkKS3eGSRg03ilaCtsqfJWQb7Q,117
|
|
131
131
|
application_sdk/workflows/query_extraction/sql.py,sha256=kT_JQkLCRZ44ZpaC4QvPL6DxnRIIVh8gYHLqRbMI-hA,4826
|
|
132
|
-
atlan_application_sdk-0.1.
|
|
133
|
-
atlan_application_sdk-0.1.
|
|
134
|
-
atlan_application_sdk-0.1.
|
|
135
|
-
atlan_application_sdk-0.1.
|
|
136
|
-
atlan_application_sdk-0.1.
|
|
132
|
+
atlan_application_sdk-0.1.1rc27.dist-info/METADATA,sha256=pCLOauLHmtbMy_oEfXKXH_3GTXy9A577cgk8oLvWD_I,5473
|
|
133
|
+
atlan_application_sdk-0.1.1rc27.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
134
|
+
atlan_application_sdk-0.1.1rc27.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
135
|
+
atlan_application_sdk-0.1.1rc27.dist-info/licenses/NOTICE,sha256=A-XVVGt3KOYuuMmvSMIFkg534F1vHiCggEBp4Ez3wGk,1041
|
|
136
|
+
atlan_application_sdk-0.1.1rc27.dist-info/RECORD,,
|
|
@@ -19,7 +19,7 @@ Apache License 2.0 Dependencies:
|
|
|
19
19
|
- Apache Atlas (https://github.com/apache/atlas) under Apache-2.0 license
|
|
20
20
|
- Elasticsearch DSL (https://github.com/elastic/elasticsearch-dsl-py) under Apache-2.0 license
|
|
21
21
|
- orjson (https://github.com/ijl/orjson)
|
|
22
|
-
-
|
|
22
|
+
- daft (https://github.com/Eventual-Inc/Daft)
|
|
23
23
|
- pyiceberg (https://github.com/apache/iceberg-python)
|
|
24
24
|
- pyarrow (https://github.com/apache/arrow/tree/main/python)
|
|
25
25
|
- dapr (https://github.com/dapr/python-sdk/)
|
{atlan_application_sdk-0.1.1rc26.dist-info → atlan_application_sdk-0.1.1rc27.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|