cdiam-cli 0.1.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.
- cdiam_cli/__init__.py +2 -0
- cdiam_cli/__main__.py +5 -0
- cdiam_cli/api/__init__.py +4 -0
- cdiam_cli/api/api_action.py +131 -0
- cdiam_cli/api/download.py +28 -0
- cdiam_cli/api/settings.py +59 -0
- cdiam_cli/api/utils.py +0 -0
- cdiam_cli/helper/__init__.py +3 -0
- cdiam_cli/helper/curl_helper.py +42 -0
- cdiam_cli/helper/json_helper.py +6 -0
- cdiam_cli/helper/yaml_helper.py +10 -0
- cdiam_cli/main.py +15 -0
- cdiam_cli/schemas/__init__.py +1 -0
- cdiam_cli/schemas/schemas.py +213 -0
- cdiam_cli-0.1.0.dist-info/LICENSE.md +21 -0
- cdiam_cli-0.1.0.dist-info/METADATA +56 -0
- cdiam_cli-0.1.0.dist-info/RECORD +19 -0
- cdiam_cli-0.1.0.dist-info/WHEEL +4 -0
- cdiam_cli-0.1.0.dist-info/entry_points.txt +3 -0
cdiam_cli/__init__.py
ADDED
cdiam_cli/__main__.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import click
|
|
3
|
+
from cdiam_cli.helper import yaml_helper, curl_helper
|
|
4
|
+
import subprocess
|
|
5
|
+
from typing import Union, Callable, Any, Dict, overload, Literal
|
|
6
|
+
from .settings import read_api_endpoint, read_api_token
|
|
7
|
+
from cdiam_cli.schemas import AnalysisResult
|
|
8
|
+
from cdiam_cli.schemas import ParamsRequestGetTaskStatus
|
|
9
|
+
from cdiam_cli.schemas import AnalysisResultRead
|
|
10
|
+
from time import sleep
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def wait_task(task_id: str):
|
|
14
|
+
while True:
|
|
15
|
+
sleep(5)
|
|
16
|
+
print("Load status info")
|
|
17
|
+
res = run(
|
|
18
|
+
ParamsRequestGetTaskStatus(api="get_task_status", task_id=task_id).dict()
|
|
19
|
+
)
|
|
20
|
+
status = AnalysisResultRead(**res)
|
|
21
|
+
|
|
22
|
+
if status.task is None:
|
|
23
|
+
raise Exception("Task FAILURE")
|
|
24
|
+
if status.task.status == "FAILURE":
|
|
25
|
+
raise Exception("Task FAILURE")
|
|
26
|
+
if status.task.status == "SUCCESS":
|
|
27
|
+
break
|
|
28
|
+
return status
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def parse_and_wait_task(process: Any):
|
|
32
|
+
analysis_result: AnalysisResult = AnalysisResult(**process)
|
|
33
|
+
assert analysis_result.task_id is not None
|
|
34
|
+
print(analysis_result)
|
|
35
|
+
status = wait_task(task_id=analysis_result.task_id)
|
|
36
|
+
print(status)
|
|
37
|
+
return status
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@overload
|
|
41
|
+
def run(
|
|
42
|
+
params: Union[str, Dict[Any, Any]],
|
|
43
|
+
modify_params_callback: Union[Callable[[Any], Any], None] = None,
|
|
44
|
+
wait_as_analysis: Literal[False] = False,
|
|
45
|
+
) -> Any: ...
|
|
46
|
+
@overload
|
|
47
|
+
def run(
|
|
48
|
+
params: Union[str, Dict[Any, Any]],
|
|
49
|
+
modify_params_callback: Union[Callable[[Any], Any], None] = None,
|
|
50
|
+
wait_as_analysis: Literal[True] = True,
|
|
51
|
+
) -> AnalysisResult: ...
|
|
52
|
+
def run(
|
|
53
|
+
params: Union[str, Dict[Any, Any]],
|
|
54
|
+
modify_params_callback: Union[Callable[[Any], Any], None] = None,
|
|
55
|
+
wait_as_analysis: bool = False,
|
|
56
|
+
):
|
|
57
|
+
"""
|
|
58
|
+
Runs an API call with the provided parameters and returns the API response.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
params (Union[str, Dict[Any, Any]]): The API parameters, either as a path to a JSON or YAML file, or as a dictionary.
|
|
62
|
+
More details about api schemas can be found in the documentation at https://c-diam.com/api/schemas/docs or if you are using different endpoint you can find it at https://<your-end-point>/api/schemas/docs.
|
|
63
|
+
modify_params_callback (Union[Callable[[Any], Any], None]): An optional callback function to modify the API parameters before the call.
|
|
64
|
+
wait_as_analysis (bool): If True, the function will wait for the API task to complete and return the analysis result.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Any: The API response, or an AnalysisResult if wait_as_analysis is True.
|
|
68
|
+
|
|
69
|
+
Raises:
|
|
70
|
+
Exception: If the API call fails.
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
if isinstance(params, str):
|
|
74
|
+
if params.endswith(".json"):
|
|
75
|
+
with open(params) as f:
|
|
76
|
+
data = json.load(f)
|
|
77
|
+
else:
|
|
78
|
+
data = yaml_helper.read(params)
|
|
79
|
+
if modify_params_callback is not None:
|
|
80
|
+
data = modify_params_callback(data)
|
|
81
|
+
else:
|
|
82
|
+
data = params
|
|
83
|
+
|
|
84
|
+
if data["api"] in ["upload_matrix"]: # type: ignore
|
|
85
|
+
form_data = curl_helper.convert_json_to_form_data(data)
|
|
86
|
+
command = curl_helper.generate_curl_form_command(
|
|
87
|
+
form_data, endpoint=f"{read_api_endpoint()}/api_public/{data['api']}" # type: ignore
|
|
88
|
+
)
|
|
89
|
+
else:
|
|
90
|
+
command = curl_helper.generate_curl_json_command(
|
|
91
|
+
data, endpoint=f"{read_api_endpoint()}/api_public/{data['api']}" # type: ignore
|
|
92
|
+
)
|
|
93
|
+
command.append("-b")
|
|
94
|
+
command.append(f"cdiam_session_token={read_api_token()}")
|
|
95
|
+
|
|
96
|
+
process = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
97
|
+
process.check_returncode()
|
|
98
|
+
output = json.loads(process.stdout.decode())
|
|
99
|
+
if "detail" in output:
|
|
100
|
+
raise Exception(output)
|
|
101
|
+
|
|
102
|
+
if wait_as_analysis:
|
|
103
|
+
output = parse_and_wait_task(output)
|
|
104
|
+
|
|
105
|
+
return output
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
@click.command()
|
|
109
|
+
@click.argument("params", type=click.Path(exists=True), required=True)
|
|
110
|
+
def call_api(params: str):
|
|
111
|
+
"""
|
|
112
|
+
Calls the API with the provided parameters and returns the API response.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
params (str): The path to a JSON or YAML file containing the API parameters. More details about api schemas can be found in the documentation at https://c-diam.com/api/schemas/docs or if you are using different endpoint you can find it at https://<your-end-point>/api/schemas/docs.
|
|
116
|
+
Returns:
|
|
117
|
+
str: The API response.
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
Exception: If the API call fails.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
process = run(params)
|
|
124
|
+
return_code = process.returncode
|
|
125
|
+
|
|
126
|
+
if return_code == 0:
|
|
127
|
+
click.echo(process.stdout.decode())
|
|
128
|
+
return process.stdout.decode()
|
|
129
|
+
else:
|
|
130
|
+
click.echo(process.stdout.decode())
|
|
131
|
+
raise Exception(process.stderr.decode())
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import requests
|
|
3
|
+
import pandas as pd
|
|
4
|
+
from urllib.request import urlopen
|
|
5
|
+
from .settings import read_api_endpoint, read_api_token
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@click.command()
|
|
9
|
+
@click.argument("object_id", type=str)
|
|
10
|
+
def download_data(object_id: str):
|
|
11
|
+
"""This api download data of given objec_id"""
|
|
12
|
+
res = requests.get(
|
|
13
|
+
f"{read_api_endpoint()}/data/data/download-file/{object_id}",
|
|
14
|
+
cookies={"cdiam_session_token": read_api_token()},
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
if res.status_code != 200:
|
|
18
|
+
print(res.json())
|
|
19
|
+
else:
|
|
20
|
+
for url in res.json()["url"]:
|
|
21
|
+
response = urlopen(url)
|
|
22
|
+
file_name = response.headers.get_filename()
|
|
23
|
+
with requests.get(url, stream=True) as r:
|
|
24
|
+
r.raise_for_status()
|
|
25
|
+
with open(file_name, "wb") as f:
|
|
26
|
+
for chunk in r.iter_content(chunk_size=8192):
|
|
27
|
+
if chunk:
|
|
28
|
+
f.write(chunk)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import click
|
|
2
|
+
import os
|
|
3
|
+
from os.path import expanduser
|
|
4
|
+
import json
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_path_settings():
|
|
8
|
+
home = expanduser("~")
|
|
9
|
+
return os.path.join(home, ".cdiam_cli")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def read_api_endpoint():
|
|
13
|
+
if not os.path.exists(get_path_settings()):
|
|
14
|
+
raise Exception("Run save-settings first")
|
|
15
|
+
with open(get_path_settings(), "r") as f:
|
|
16
|
+
settings = json.load(f)
|
|
17
|
+
if "endpoint" not in settings:
|
|
18
|
+
raise Exception(
|
|
19
|
+
"Cannot found endpoint setting. Please run save-settings first"
|
|
20
|
+
)
|
|
21
|
+
return settings["endpoint"]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def read_api_token():
|
|
25
|
+
if not os.path.exists(get_path_settings()):
|
|
26
|
+
raise Exception("Run save-settings first")
|
|
27
|
+
with open(get_path_settings(), "r") as f:
|
|
28
|
+
settings = json.load(f)
|
|
29
|
+
if "token" not in settings:
|
|
30
|
+
raise Exception(
|
|
31
|
+
"Cannot found token setting. Please run save-settings first"
|
|
32
|
+
)
|
|
33
|
+
return settings["token"]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class HiddenPassword(object):
|
|
37
|
+
def __init__(self, password=""):
|
|
38
|
+
self.password = password
|
|
39
|
+
|
|
40
|
+
def __str__(self):
|
|
41
|
+
return "*" * len(self.password)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@click.command()
|
|
45
|
+
def save_token():
|
|
46
|
+
"""This api save your endpoint and your token in your machine"""
|
|
47
|
+
endpoint = click.prompt(
|
|
48
|
+
"Please enter the server endpoint E.g. https://c-diam.com/api", type=str
|
|
49
|
+
)
|
|
50
|
+
value = click.prompt("Please enter the token", type=HiddenPassword, hide_input=True)
|
|
51
|
+
with open(get_path_settings(), "w") as f:
|
|
52
|
+
json.dump(
|
|
53
|
+
{
|
|
54
|
+
"endpoint": endpoint,
|
|
55
|
+
"token": value.password,
|
|
56
|
+
},
|
|
57
|
+
f,
|
|
58
|
+
)
|
|
59
|
+
print(f"Save settings at {get_path_settings()}")
|
cdiam_cli/api/utils.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from typing import Any, Dict
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def _convert(data: Any, ret: Dict[str, str], key: str):
|
|
6
|
+
if isinstance(data, dict):
|
|
7
|
+
for k in data.keys():
|
|
8
|
+
_convert(data[k], ret, f"{key}[{k}]" if key != "" else k)
|
|
9
|
+
elif isinstance(data, list):
|
|
10
|
+
for index, k in enumerate(data):
|
|
11
|
+
_convert(data[index], ret, f"{key}[{index}]")
|
|
12
|
+
else:
|
|
13
|
+
if data is not None:
|
|
14
|
+
ret[key] = data
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def generate_curl_form_command(form_data: Dict[str, str], endpoint: str):
|
|
18
|
+
command = ["curl", "-X", "POST", "-H", "Content-Type: multipart/form-data"]
|
|
19
|
+
for k, v in form_data.items():
|
|
20
|
+
|
|
21
|
+
command.append("-F")
|
|
22
|
+
if v is None or v.startswith("@"):
|
|
23
|
+
command.append(f'{k}={"null" if v is None else v}')
|
|
24
|
+
else:
|
|
25
|
+
command.append(f'{k}="{v}"')
|
|
26
|
+
|
|
27
|
+
command.append(endpoint)
|
|
28
|
+
return command
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def generate_curl_json_command(json_data: Dict[str, str], endpoint: str):
|
|
32
|
+
command = ["curl", "-X", "POST", "-H", "Content-Type: application/json"]
|
|
33
|
+
command.append("-d")
|
|
34
|
+
command.append(json.dumps(json_data))
|
|
35
|
+
command.append(endpoint)
|
|
36
|
+
return command
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def convert_json_to_form_data(json_object: Any):
|
|
40
|
+
ret = {}
|
|
41
|
+
_convert(json_object, ret, "")
|
|
42
|
+
return ret
|
cdiam_cli/main.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .schemas import *
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
from typing import Literal, Optional
|
|
3
|
+
from sqlmodel import (
|
|
4
|
+
Field,
|
|
5
|
+
SQLModel,
|
|
6
|
+
ForeignKeyConstraint,
|
|
7
|
+
Column,
|
|
8
|
+
DateTime,
|
|
9
|
+
func,
|
|
10
|
+
Relationship,
|
|
11
|
+
UniqueConstraint,
|
|
12
|
+
BigInteger,
|
|
13
|
+
)
|
|
14
|
+
import sqlalchemy as sa
|
|
15
|
+
from pydantic import validator, BaseModel
|
|
16
|
+
from datetime import datetime
|
|
17
|
+
from typing import Union, Callable, ClassVar, Optional, List, Dict, Any
|
|
18
|
+
import json
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ProjectSettings(BaseModel):
|
|
22
|
+
class Config:
|
|
23
|
+
orm_mode = True
|
|
24
|
+
|
|
25
|
+
cpdb: List[str] = []
|
|
26
|
+
enrichment: List[str] = []
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def encode_settings(settings: Union[Dict[str, Any], "ProjectSettings"]) -> str:
|
|
30
|
+
return ProjectSettings.parse_obj(settings).json()
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def decode_setting(settings: str) -> "ProjectSettings":
|
|
34
|
+
if settings is None:
|
|
35
|
+
settings = "{}"
|
|
36
|
+
return ProjectSettings.parse_obj(json.loads(settings))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class ProjectBase(SQLModel):
|
|
40
|
+
name: str = Field(max_length=128, nullable=False)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class Project(ProjectBase, table=True):
|
|
44
|
+
__tablename__: ClassVar[Union[str, Callable[..., str]]] = "project"
|
|
45
|
+
id: str = Field(
|
|
46
|
+
max_length=128, nullable=False, primary_key=True, index=True, unique=True
|
|
47
|
+
)
|
|
48
|
+
tombstone: Optional[bool] = Field(
|
|
49
|
+
default=False,
|
|
50
|
+
nullable=False,
|
|
51
|
+
description="Deleted marker of the project. True = deleted",
|
|
52
|
+
)
|
|
53
|
+
time_created: datetime = Field(
|
|
54
|
+
default=None,
|
|
55
|
+
sa_column=Column(DateTime(timezone=True), server_default=func.now()),
|
|
56
|
+
description="Time added",
|
|
57
|
+
)
|
|
58
|
+
is_public: bool = Field(
|
|
59
|
+
default=False,
|
|
60
|
+
nullable=False,
|
|
61
|
+
description="If the project is public",
|
|
62
|
+
)
|
|
63
|
+
delete_date: Optional[datetime] = Field(
|
|
64
|
+
default=None, sa_column=Column(sa.DateTime(timezone=True), nullable=True)
|
|
65
|
+
)
|
|
66
|
+
settings: Optional[str] = Field(
|
|
67
|
+
default=None,
|
|
68
|
+
max_length=10240,
|
|
69
|
+
nullable=True,
|
|
70
|
+
)
|
|
71
|
+
storage_used: int = Field(
|
|
72
|
+
sa_column=Column(BigInteger),
|
|
73
|
+
nullable=True,
|
|
74
|
+
description="Non-zero expression values",
|
|
75
|
+
)
|
|
76
|
+
created_by: str = Field(
|
|
77
|
+
max_length=128,
|
|
78
|
+
nullable=False,
|
|
79
|
+
index=True,
|
|
80
|
+
foreign_key="user.email",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
@validator("settings")
|
|
84
|
+
def validate_settings(cls, v: str):
|
|
85
|
+
if v == "nan":
|
|
86
|
+
v = "{}"
|
|
87
|
+
if v is None:
|
|
88
|
+
v = "{}"
|
|
89
|
+
return ProjectSettings.encode_settings(ProjectSettings.decode_setting(v))
|
|
90
|
+
|
|
91
|
+
@validator("tombstone")
|
|
92
|
+
def validate_tombstone(cls, v):
|
|
93
|
+
if not v:
|
|
94
|
+
return False
|
|
95
|
+
return v
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class ParamsRequestGetTaskStatus(BaseModel):
|
|
99
|
+
"""
|
|
100
|
+
Represents the parameters for a request to get the status of an analysis task.
|
|
101
|
+
|
|
102
|
+
:param api: The API endpoint being called, which should be "get_task_status".
|
|
103
|
+
:param task_id: The unique identifier of the analysis task.
|
|
104
|
+
"""
|
|
105
|
+
|
|
106
|
+
api: Literal["get_task_status"]
|
|
107
|
+
task_id: str
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class TaskStatus(BaseModel):
|
|
111
|
+
status: str = "UNKNOWN"
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class AnalysisResultBase(SQLModel):
|
|
115
|
+
result_id: str = Field(
|
|
116
|
+
max_length=128,
|
|
117
|
+
nullable=False,
|
|
118
|
+
primary_key=True,
|
|
119
|
+
description="ID of the analysis",
|
|
120
|
+
)
|
|
121
|
+
data_id: str = Field(max_length=128, nullable=False, description="ID of the data")
|
|
122
|
+
analysis: int = Field(
|
|
123
|
+
nullable=False,
|
|
124
|
+
foreign_key="analysis_catalog.id",
|
|
125
|
+
description="Reference to the analysis",
|
|
126
|
+
)
|
|
127
|
+
task_id: str = Field(
|
|
128
|
+
max_length=128,
|
|
129
|
+
nullable=False,
|
|
130
|
+
sa_column_kwargs={"server_default": ""},
|
|
131
|
+
description="ID of task in celery",
|
|
132
|
+
)
|
|
133
|
+
args: str = Field(
|
|
134
|
+
max_length=10240,
|
|
135
|
+
default="{}",
|
|
136
|
+
nullable=False,
|
|
137
|
+
description="Args of the analysis",
|
|
138
|
+
sa_column_kwargs={"server_default": "{}"},
|
|
139
|
+
)
|
|
140
|
+
project_id: str = Field(
|
|
141
|
+
max_length=128,
|
|
142
|
+
nullable=False,
|
|
143
|
+
description="ID of project this analysis belong to",
|
|
144
|
+
)
|
|
145
|
+
user_email: Optional[str] = Field(max_length=256, nullable=True)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class AnalysisCatalogBase(SQLModel):
|
|
149
|
+
name: str = Field(nullable=False, description="Name of the analysis")
|
|
150
|
+
description: Optional[str] = Field(
|
|
151
|
+
max_length=4096, description="Detailed information about this analysis"
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
class AnalysisCatalog(AnalysisCatalogBase, table=True):
|
|
156
|
+
"""
|
|
157
|
+
This table stores available analyses type
|
|
158
|
+
that the App supports.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
__tablename__: ClassVar[Union[str, Callable[..., str]]] = "analysis_catalog"
|
|
162
|
+
id: int = Field(primary_key=True)
|
|
163
|
+
time_created: datetime = Field(
|
|
164
|
+
sa_column=Column(DateTime(timezone=True), server_default=func.now()),
|
|
165
|
+
description="Time added",
|
|
166
|
+
)
|
|
167
|
+
time_modified: datetime = Field(
|
|
168
|
+
sa_column=Column(
|
|
169
|
+
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
|
170
|
+
),
|
|
171
|
+
description="Time modified",
|
|
172
|
+
)
|
|
173
|
+
"""A list of all analysis results of this type"""
|
|
174
|
+
results: List["AnalysisResult"] = Relationship(back_populates="analysis_orm")
|
|
175
|
+
|
|
176
|
+
__table_args__ = (UniqueConstraint("name", name="_name_analysis_uc"),)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
class AnalysisResultRead(AnalysisResultBase):
|
|
180
|
+
"""
|
|
181
|
+
A response model of an anlysis result
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
time_created: datetime
|
|
185
|
+
time_modified: datetime
|
|
186
|
+
task: Optional[TaskStatus]
|
|
187
|
+
result_data_status: Optional[str]
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
class AnalysisResult(AnalysisResultBase, table=True):
|
|
191
|
+
__tablename__: ClassVar[Union[str, Callable[..., str]]] = "analysis_result"
|
|
192
|
+
__table_args__ = (
|
|
193
|
+
ForeignKeyConstraint(
|
|
194
|
+
["project_id"], ["project.id"], onupdate="CASCADE", ondelete="CASCADE"
|
|
195
|
+
),
|
|
196
|
+
)
|
|
197
|
+
"""
|
|
198
|
+
This table stores all analyses that had been produced for a data
|
|
199
|
+
The analysis reference points to the description of the analysis.
|
|
200
|
+
The result_id reference points to the detail result of the analysis
|
|
201
|
+
"""
|
|
202
|
+
time_created: datetime = Field(
|
|
203
|
+
sa_column=Column(DateTime(timezone=True), server_default=func.now()),
|
|
204
|
+
description="Time added",
|
|
205
|
+
)
|
|
206
|
+
time_modified: datetime = Field(
|
|
207
|
+
sa_column=Column(
|
|
208
|
+
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
|
209
|
+
),
|
|
210
|
+
description="Time modified",
|
|
211
|
+
)
|
|
212
|
+
"""An object of the analysis type"""
|
|
213
|
+
analysis_orm: AnalysisCatalog = Relationship(back_populates="results")
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [year] [fullname]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: cdiam-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary:
|
|
5
|
+
Author: tungtp99
|
|
6
|
+
Author-email: tungtp181199@gmail.com
|
|
7
|
+
Requires-Python: >=3.9,<4.0
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Requires-Dist: click (>=8.1.7,<9.0.0)
|
|
14
|
+
Requires-Dist: datetime (>=5.5,<6.0)
|
|
15
|
+
Requires-Dist: idna (==3.4)
|
|
16
|
+
Requires-Dist: numpy (>=1.24.0,<2.0.0)
|
|
17
|
+
Requires-Dist: pandas (>=2.1.0,<3.0.0)
|
|
18
|
+
Requires-Dist: pydantic (==1.10.2)
|
|
19
|
+
Requires-Dist: pymysql (==1.0.2)
|
|
20
|
+
Requires-Dist: pyyaml (>=6.0.1,<7.0.0)
|
|
21
|
+
Requires-Dist: sqlalchemy (==1.4.41)
|
|
22
|
+
Requires-Dist: sqlalchemy2-stubs (==0.0.2a27)
|
|
23
|
+
Requires-Dist: sqlmodel (==0.0.8)
|
|
24
|
+
Requires-Dist: tabulate (>=0.9.0,<0.10.0)
|
|
25
|
+
Requires-Dist: typing-extensions (==4.3.0)
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# CDIAM CLI
|
|
29
|
+
|
|
30
|
+
This is a repository for CDIAM CLI. .
|
|
31
|
+
|
|
32
|
+
## Getting Started
|
|
33
|
+
|
|
34
|
+
To get started with this project, follow these steps:
|
|
35
|
+
|
|
36
|
+
### From source
|
|
37
|
+
1. Clone the repository: `git clone github.com/C-DIAM/cdiam-cli.git`
|
|
38
|
+
2. Install: `poetry install` install poetry with https://python-poetry.org/docs/
|
|
39
|
+
|
|
40
|
+
### From pypip
|
|
41
|
+
Run `pip install cdiam-cli`
|
|
42
|
+
|
|
43
|
+
### View CLI command
|
|
44
|
+
Run `cdiam_cli --help`
|
|
45
|
+
|
|
46
|
+
## Features
|
|
47
|
+
|
|
48
|
+
- Save token: `python -m cdiam_cli save-token` must provide server endpoint E.g. https://c-diam.com/api and TOKEN get from CDIAM APP
|
|
49
|
+
- Call API: `python -m cdiam_cli call-api <PATH_TO_YAML_OR_JSON_PARAMS>` more detail about params schemas at `<SERVER_ENPOINT>/schemas/docs` E.g. https://c-diam.com/api/schemas/docs
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
## License
|
|
54
|
+
|
|
55
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
56
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
cdiam_cli/__init__.py,sha256=l-JuiCyzHd3V4eHoqkmcY_Nd1sO-ussLwHa-j3DRqIQ,41
|
|
2
|
+
cdiam_cli/__main__.py,sha256=4f6fIZLpDuYD98xz6n5b2FrX010KvaAQwc1rVAHQmeo,58
|
|
3
|
+
cdiam_cli/api/__init__.py,sha256=SCn87hjuHQY4bdjkQi7-tqYewHGAsz0v_UVmSBWkxu4,126
|
|
4
|
+
cdiam_cli/api/api_action.py,sha256=i0POWLu_l--tKVTZqIZd09_7lYuEHpEs0a5lSB0OIh4,4783
|
|
5
|
+
cdiam_cli/api/download.py,sha256=SkjNkOK2S1ZsDvZfrKGyP5npJO60HJ_iL4aqC1Yk7lE,952
|
|
6
|
+
cdiam_cli/api/settings.py,sha256=0uPZnZ6PeeR021qOSuK_qdYMHQncGprwrXQXRB9iM40,1743
|
|
7
|
+
cdiam_cli/api/utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
cdiam_cli/helper/__init__.py,sha256=FTxjsSTmb2rBBQEAYelHTpBiRtSlAqlzo37hDutmY9Y,79
|
|
9
|
+
cdiam_cli/helper/curl_helper.py,sha256=d2OBC7Gx6Oi9kIOdsF4bbUaI1KxTSEkeReqYZo7YxbU,1286
|
|
10
|
+
cdiam_cli/helper/json_helper.py,sha256=gwkld-m-VsYSlaPoy9_NRlAkqCs3AKC-yY_E2JsVW_8,112
|
|
11
|
+
cdiam_cli/helper/yaml_helper.py,sha256=pv6PdG9ypNoaeCMVqWT8tOtpX0MX8hyCUrVoZ1lg1Wc,237
|
|
12
|
+
cdiam_cli/main.py,sha256=lEAXShfuBeS7hWqeMwYOGAxmt9eFCMZJQ7tn8wkcwx4,212
|
|
13
|
+
cdiam_cli/schemas/__init__.py,sha256=_zaWR_nECK5Q6BZOOenPISZi4PN_mwF71I7NU6By4_A,24
|
|
14
|
+
cdiam_cli/schemas/schemas.py,sha256=Gi6DFNL2EffG2-j1x40kmKmIMQUKrs97Q9acoVRVpwk,6497
|
|
15
|
+
cdiam_cli-0.1.0.dist-info/LICENSE.md,sha256=Qv2ilebwoUtMJnRsZwRy729xS5JZQzLauJ0tQzkAkTA,1088
|
|
16
|
+
cdiam_cli-0.1.0.dist-info/METADATA,sha256=odMxVND7t0KdWbxsDo3ipVAW6GCsF3qvTa6RndeEL38,1714
|
|
17
|
+
cdiam_cli-0.1.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
18
|
+
cdiam_cli-0.1.0.dist-info/entry_points.txt,sha256=-ZGdMDIC0hzdXhN9GRgfq_dqsF7fi4GoS8LIoJfMeko,55
|
|
19
|
+
cdiam_cli-0.1.0.dist-info/RECORD,,
|