ol-datastar 0.0.1__tar.gz

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,18 @@
1
+ Metadata-Version: 2.1
2
+ Name: ol-datastar
3
+ Version: 0.0.1
4
+ Summary: Helpful utilities for working with Datastar projects
5
+ Home-page: https://cosmicfrog.com
6
+ Author: Optilogic
7
+ License: MIT
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.11
12
+ Requires-Dist: numpy>=1.26.4
13
+ Requires-Dist: pandas>=2.1.0
14
+ Requires-Dist: sqlalchemy>=2.0.27
15
+ Requires-Dist: optilogic>=2.13.0
16
+ Requires-Dist: PyJWT>=2.8.0
17
+ Requires-Dist: httpx>=0.24.1
18
+ Requires-Dist: psycopg2-binary>=2.9.9
@@ -0,0 +1 @@
1
+ from .datastar import Datastar
@@ -0,0 +1,74 @@
1
+ """
2
+ Helper functions for working with Datastar projects
3
+ """
4
+
5
+ import os
6
+ import sys
7
+ from typing import Dict, List, Optional, Tuple, Any
8
+ from .frog_platform import OptilogicClient
9
+
10
+ # pylint: disable=logging-fstring-interpolation
11
+
12
+ DSTAR_IDLE_TRANSACTION_TIMEOUT = os.getenv("DSTAR_IDLE_TRANSACTION_TIMEOUT", 1800)
13
+ ATLAS_API_BASE_URL = os.getenv("ATLAS_API_BASE_URL", "https://api.optilogic.app/v0")
14
+
15
+ class Datastar:
16
+ """
17
+ Datastar class with helper functions for accessing Datastar projects
18
+ """
19
+
20
+ # This allows app key to be set once for all instances, makes utilities easier to write
21
+ class_app_key = None
22
+
23
+ # Helper method for setting up app key
24
+ @classmethod
25
+ def __set_app_key__(
26
+ cls,
27
+ app_key: Optional[str],
28
+ raise_if_not_found: Optional[bool] = True
29
+ ) -> str:
30
+ """
31
+ Helper method for setting up app key.
32
+
33
+ There are 4 ways to set the app key:
34
+ 1) Passed in argument when opening a model e.g. FrogModel(app_key="my_app_key", model_name="my_model")
35
+ 2) Set via class variable (used for all instances of FrogModel, used in utilities)
36
+ 3) Via Enviroment var, in Andromeda (if running in Andromeda)
37
+ 4) Via app.key file (when running locally, place file in folder with your script)
38
+
39
+ Args:
40
+ app_key: Optional app key
41
+
42
+ Returns:
43
+ App key
44
+
45
+ """
46
+ try:
47
+ found_app_key = app_key or cls.class_app_key or os.environ.get("OPTILOGIC_JOB_APPKEY")
48
+
49
+ if not found_app_key:
50
+ initial_script_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
51
+ file_path = os.path.join(initial_script_dir, "app.key")
52
+ if os.path.exists(file_path):
53
+ with open(file_path, "r", encoding="utf-8") as file:
54
+ found_app_key = file.read().strip()
55
+
56
+ if not found_app_key and raise_if_not_found:
57
+ raise ValueError("App key not found. Please provide a valid app key.")
58
+
59
+ return found_app_key
60
+ except Exception as e:
61
+ # cls.log.exception(f"Error setting app key: {e}", exc_info=True)
62
+ raise ValueError(f"Error setting app key: {e}")
63
+
64
+ def __init__(
65
+ self,
66
+ project_name: Optional[str] = None,
67
+ connection_string: Optional[str] = None,
68
+ application_name: str = "Datastar User Library",
69
+ app_key: Optional[str] = None
70
+ ) -> None:
71
+ pass
72
+
73
+
74
+
@@ -0,0 +1,107 @@
1
+ """
2
+ Functions to facilitate interactions with Optilogic platform using 'optilogic' library
3
+ """
4
+
5
+ import os
6
+ import json
7
+ import logging
8
+ import time
9
+ from typing import Tuple
10
+ import optilogic
11
+
12
+
13
+ class OptilogicClient:
14
+ """
15
+ Wrapper for optilogic module for consumption in Cosmic Frog services
16
+ """
17
+
18
+ def __init__(self, username=None, appkey=None, logger=logging.getLogger()):
19
+ # Detect if being run in Andromeda
20
+ job_app_key = os.environ.get("OPTILOGIC_JOB_APPKEY")
21
+
22
+ if appkey and not username:
23
+ # Use supplied key
24
+ self.api = optilogic.pioneer.Api(auth_legacy=False, appkey=appkey)
25
+ elif appkey and username:
26
+ # Use supplied key & name
27
+ self.api = optilogic.pioneer.Api(auth_legacy=False, appkey=appkey, un=username)
28
+ elif job_app_key:
29
+ # Running on Andromeda
30
+ self.api = optilogic.pioneer.Api(auth_legacy=False)
31
+ else:
32
+ raise ValueError("OptilogicClient could not authenticate")
33
+
34
+ self.logger = logger
35
+
36
+ def model_exists(self, model_name: str) -> bool:
37
+ """
38
+ Returns True if a given model exists, False otherwise
39
+ """
40
+ try:
41
+ return self.api.storagename_database_exists(model_name)
42
+ except Exception as e: # pylint: disable=broad-exception-caught
43
+ self.logger.error(f"Exception in cosmicfrog: {e}")
44
+ return False
45
+
46
+ def get_connection_string(self, model_name: str) -> Tuple[bool, str]:
47
+
48
+ # TODO: There are two connection string fetch functions, see also frog_dbtools
49
+
50
+ try:
51
+ rv = {"message": "error getting connection string"}
52
+ if not self.api.storagename_database_exists(model_name):
53
+ return False, ""
54
+
55
+ connection_info = self.api.sql_connection_info(model_name)
56
+
57
+ return True, connection_info["connectionStrings"]["url"]
58
+
59
+ except Exception as e:
60
+ self.logger.error(f"Exception in cosmicfrog: {e}")
61
+ return False, ""
62
+
63
+ def create_model_synchronous(self, model_name: str, model_template: str):
64
+ try:
65
+ new_model = self.api.database_create(name=model_name, template=model_template)
66
+
67
+ status = "success"
68
+ rv = {}
69
+ if "crash" in new_model:
70
+ status = "error"
71
+ rv["message"] = json.loads(new_model["response_body"])["message"]
72
+ rv["httpStatus"] = new_model["resp"].status_code
73
+ else:
74
+ while not self.api.storagename_database_exists(model_name):
75
+ self.logger.info(f"creating {model_name}")
76
+ time.sleep(3.0)
77
+ connections = self.api.sql_connection_info(model_name)
78
+ rv["model"] = new_model
79
+ rv["connection"] = connections
80
+
81
+ return status, rv
82
+
83
+ except Exception as e:
84
+ return "exception", e
85
+
86
+
87
+ def delete_model_api(self, model_name: str) -> dict:
88
+ """
89
+ Delete a model from the platform
90
+
91
+ Args:
92
+ model_name (str): Name of the model to delete
93
+
94
+ Returns:
95
+ dict: Status of the operation
96
+ """
97
+ if not model_name:
98
+ return {"status": "error", "message": "Model name is required"}
99
+
100
+ try:
101
+ response = self.api.storage_delete(name=model_name)
102
+ if response.get('result', 'error') == 'error':
103
+ return {"status": "error", "message": response.get('message', '')}
104
+
105
+ return {"status": "success", "message": f"Model {model_name} deleted successfully"}
106
+ except Exception as e:
107
+ return {"status": "error", "message": str(e)}
@@ -0,0 +1,18 @@
1
+ Metadata-Version: 2.1
2
+ Name: ol-datastar
3
+ Version: 0.0.1
4
+ Summary: Helpful utilities for working with Datastar projects
5
+ Home-page: https://cosmicfrog.com
6
+ Author: Optilogic
7
+ License: MIT
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.11
12
+ Requires-Dist: numpy>=1.26.4
13
+ Requires-Dist: pandas>=2.1.0
14
+ Requires-Dist: sqlalchemy>=2.0.27
15
+ Requires-Dist: optilogic>=2.13.0
16
+ Requires-Dist: PyJWT>=2.8.0
17
+ Requires-Dist: httpx>=0.24.1
18
+ Requires-Dist: psycopg2-binary>=2.9.9
@@ -0,0 +1,9 @@
1
+ setup.py
2
+ ol-datastar/__init__.py
3
+ ol-datastar/datastar.py
4
+ ol-datastar/frog_platform.py
5
+ ol_datastar.egg-info/PKG-INFO
6
+ ol_datastar.egg-info/SOURCES.txt
7
+ ol_datastar.egg-info/dependency_links.txt
8
+ ol_datastar.egg-info/requires.txt
9
+ ol_datastar.egg-info/top_level.txt
@@ -0,0 +1,7 @@
1
+ numpy>=1.26.4
2
+ pandas>=2.1.0
3
+ sqlalchemy>=2.0.27
4
+ optilogic>=2.13.0
5
+ PyJWT>=2.8.0
6
+ httpx>=0.24.1
7
+ psycopg2-binary>=2.9.9
@@ -0,0 +1 @@
1
+ ol-datastar
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,53 @@
1
+ """
2
+ Library setup file
3
+ """
4
+ import subprocess
5
+ from setuptools import setup
6
+
7
+
8
+ try:
9
+ subprocess.check_output(['pip', 'show', 'psycopg2'])
10
+ PSYCOPG2_INSTALLED = True
11
+ except subprocess.CalledProcessError:
12
+ PSYCOPG2_INSTALLED = False
13
+
14
+
15
+ install_requires = [
16
+ "numpy>=1.26.4",
17
+ "pandas>=2.1.0",
18
+ "sqlalchemy>=2.0.27",
19
+ "optilogic>=2.13.0",
20
+ "PyJWT>=2.8.0",
21
+ "httpx>=0.24.1"
22
+ ]
23
+
24
+ # If psycopg2 is not installed let's check if we should use the binary version instead
25
+ if not PSYCOPG2_INSTALLED:
26
+ import os
27
+
28
+ # Look for USE_PSYCOPG2_BINARY, if not set, default to True, otherwise, use the value
29
+ USE_BINARY = os.getenv('USE_PSYCOPG2_BINARY', 'True').lower() == 'true'
30
+
31
+ if USE_BINARY:
32
+ install_requires.append('psycopg2-binary>=2.9.9')
33
+ else:
34
+ install_requires.append('psycopg2>=2.9.9')
35
+
36
+
37
+ setup(
38
+ name="ol-datastar",
39
+ include_package_data=True,
40
+ version="0.0.1",
41
+ description="Helpful utilities for working with Datastar projects",
42
+ url="https://cosmicfrog.com",
43
+ author="Optilogic",
44
+ packages=["ol-datastar"],
45
+ license="MIT",
46
+ install_requires=install_requires,
47
+ classifiers=[
48
+ "License :: OSI Approved :: MIT License",
49
+ "Programming Language :: Python :: 3",
50
+ "Operating System :: OS Independent",
51
+ ],
52
+ python_requires=">=3.11",
53
+ )