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.
- ol-datastar-0.0.1/PKG-INFO +18 -0
- ol-datastar-0.0.1/ol-datastar/__init__.py +1 -0
- ol-datastar-0.0.1/ol-datastar/datastar.py +74 -0
- ol-datastar-0.0.1/ol-datastar/frog_platform.py +107 -0
- ol-datastar-0.0.1/ol_datastar.egg-info/PKG-INFO +18 -0
- ol-datastar-0.0.1/ol_datastar.egg-info/SOURCES.txt +9 -0
- ol-datastar-0.0.1/ol_datastar.egg-info/dependency_links.txt +1 -0
- ol-datastar-0.0.1/ol_datastar.egg-info/requires.txt +7 -0
- ol-datastar-0.0.1/ol_datastar.egg-info/top_level.txt +1 -0
- ol-datastar-0.0.1/setup.cfg +4 -0
- ol-datastar-0.0.1/setup.py +53 -0
|
@@ -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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ol-datastar
|
|
@@ -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
|
+
)
|