rowan-python 0.0.4__py3-none-any.whl → 1.0.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.
- rowan/__init__.py +7 -1
- rowan/calculation.py +11 -0
- rowan/client.py +46 -163
- rowan/constants.py +1 -0
- rowan/folder.py +97 -0
- rowan/utils.py +22 -1
- rowan/workflow.py +139 -0
- {rowan_python-0.0.4.dist-info → rowan_python-1.0.0.dist-info}/METADATA +6 -9
- rowan_python-1.0.0.dist-info/RECORD +11 -0
- {rowan_python-0.0.4.dist-info → rowan_python-1.0.0.dist-info}/WHEEL +1 -2
- rowan_python-0.0.4.dist-info/RECORD +0 -8
- rowan_python-0.0.4.dist-info/top_level.txt +0 -1
- {rowan_python-0.0.4.dist-info → rowan_python-1.0.0.dist-info/licenses}/LICENSE +0 -0
rowan/__init__.py
CHANGED
rowan/calculation.py
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import stjames
|
|
2
|
+
|
|
3
|
+
from .utils import api_client
|
|
4
|
+
|
|
5
|
+
class Calculation:
|
|
6
|
+
@classmethod
|
|
7
|
+
def retrieve(cls, uuid: stjames.UUID) -> dict:
|
|
8
|
+
with api_client() as client:
|
|
9
|
+
response = client.get(f"/calculation/{uuid}/stjames")
|
|
10
|
+
response.raise_for_status()
|
|
11
|
+
return response.json()
|
rowan/client.py
CHANGED
|
@@ -1,167 +1,50 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
1
|
import cctk
|
|
4
|
-
import httpx
|
|
5
|
-
from typing import Optional
|
|
6
2
|
import stjames
|
|
7
|
-
from dataclasses import dataclass, field
|
|
8
3
|
import time
|
|
4
|
+
from typing import Optional
|
|
9
5
|
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
headers=self.headers,
|
|
56
|
-
json={
|
|
57
|
-
"json_data": calc.model_dump(mode="json"),
|
|
58
|
-
"folder_uuid": folder_uuid,
|
|
59
|
-
},
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
elif type in ["pka", "conformers", "tautomers"]:
|
|
63
|
-
response = client.post(
|
|
64
|
-
f"{API_URL}/workflow",
|
|
65
|
-
headers=self.headers,
|
|
66
|
-
json={
|
|
67
|
-
"initial_molecule": molecule.model_dump(mode="json"),
|
|
68
|
-
"workflow_type": type,
|
|
69
|
-
"name": name,
|
|
70
|
-
"folder_uuid": folder_uuid,
|
|
71
|
-
"workflow_data": options,
|
|
72
|
-
},
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
response.raise_for_status()
|
|
76
|
-
response_dict = response.json()
|
|
77
|
-
calc_uuid = response_dict["uuid"]
|
|
78
|
-
|
|
79
|
-
if self.blocking:
|
|
80
|
-
while not self.is_finished(calc_uuid, type):
|
|
81
|
-
time.sleep(self.ping_interval)
|
|
82
|
-
result = self.get(calc_uuid, type)
|
|
83
|
-
|
|
84
|
-
if self.delete_when_finished:
|
|
85
|
-
self.delete(calc_uuid, type)
|
|
86
|
-
|
|
87
|
-
return result
|
|
88
|
-
|
|
89
|
-
else:
|
|
90
|
-
return calc_uuid
|
|
91
|
-
|
|
92
|
-
def is_finished(self, calc_uuid: str, type: str = "calculation") -> bool:
|
|
93
|
-
with httpx.Client() as client:
|
|
94
|
-
if type == "calculation":
|
|
95
|
-
response = client.get(f"{API_URL}/calculation/{calc_uuid}", headers=self.headers)
|
|
96
|
-
response.raise_for_status()
|
|
97
|
-
response_dict = response.json()
|
|
98
|
-
status = response_dict["status"]
|
|
99
|
-
|
|
100
|
-
elif type in ["pka", "conformers", "tautomers"]:
|
|
101
|
-
response = client.get(f"{API_URL}/workflow/{calc_uuid}", headers=self.headers)
|
|
102
|
-
response.raise_for_status()
|
|
103
|
-
response_dict = response.json()
|
|
104
|
-
status = response_dict["object_status"]
|
|
105
|
-
|
|
106
|
-
else:
|
|
107
|
-
raise ValueError(f"Unknown type ``{type}``!")
|
|
108
|
-
|
|
109
|
-
return status in [2, 3, 4]
|
|
110
|
-
|
|
111
|
-
def get(self, calc_uuid: str, type: str = "calculation") -> dict:
|
|
112
|
-
with httpx.Client() as client:
|
|
113
|
-
if type == "calculation":
|
|
114
|
-
stj_response = client.get(f"{API_URL}/calculation/{calc_uuid}/stjames", headers=self.headers)
|
|
115
|
-
stj_response.raise_for_status()
|
|
116
|
-
stj_dict = stj_response.json()
|
|
117
|
-
|
|
118
|
-
response = client.get(f"{API_URL}/calculation/{calc_uuid}", headers=self.headers)
|
|
119
|
-
response.raise_for_status()
|
|
120
|
-
response_dict = response.json()
|
|
121
|
-
|
|
122
|
-
# reformat
|
|
123
|
-
del response_dict["settings"]
|
|
124
|
-
response_dict["data"] = stj_dict
|
|
125
|
-
|
|
126
|
-
return response_dict
|
|
127
|
-
|
|
128
|
-
elif type in ["pka", "conformers", "tautomers"]:
|
|
129
|
-
response = client.get(f"{API_URL}/workflow/{calc_uuid}", headers=self.headers)
|
|
130
|
-
response.raise_for_status()
|
|
131
|
-
response_dict = response.json()
|
|
132
|
-
|
|
133
|
-
# reformat
|
|
134
|
-
response_dict["data"] = response_dict["object_data"]
|
|
135
|
-
del response_dict["object_data"]
|
|
136
|
-
del response_dict["status"]
|
|
137
|
-
|
|
138
|
-
return response_dict
|
|
139
|
-
|
|
140
|
-
else:
|
|
141
|
-
raise ValueError(f"Unknown type ``{type}``!")
|
|
142
|
-
|
|
143
|
-
def stop(self, calc_uuid: str, type: str = "calculation") -> None:
|
|
144
|
-
with httpx.Client() as client:
|
|
145
|
-
if type == "calculation":
|
|
146
|
-
response = client.post(f"{API_URL}/calculation/{calc_uuid}/stop", headers=self.headers)
|
|
147
|
-
response.raise_for_status()
|
|
148
|
-
|
|
149
|
-
elif type in ["pka", "conformers", "tautomers"]:
|
|
150
|
-
response = client.post(f"{API_URL}/workflow/{calc_uuid}/stop", headers=self.headers)
|
|
151
|
-
response.raise_for_status()
|
|
152
|
-
|
|
153
|
-
else:
|
|
154
|
-
raise ValueError(f"Unknown type ``{type}``!")
|
|
155
|
-
|
|
156
|
-
def delete(self, calc_uuid: str, type: str = "calculation") -> None:
|
|
157
|
-
with httpx.Client() as client:
|
|
158
|
-
if type == "calculation":
|
|
159
|
-
response = client.delete(f"{API_URL}/calculation/{calc_uuid}", headers=self.headers)
|
|
160
|
-
response.raise_for_status()
|
|
161
|
-
|
|
162
|
-
elif type in ["pka", "conformers", "tautomers"]:
|
|
163
|
-
response = client.delete(f"{API_URL}/folder/{calc_uuid}", headers=self.headers)
|
|
164
|
-
response.raise_for_status()
|
|
165
|
-
|
|
166
|
-
else:
|
|
167
|
-
raise ValueError(f"Unknown type ``{type}``!")
|
|
6
|
+
from .utils import cctk_to_stjames, smiles_to_stjames
|
|
7
|
+
from .workflow import Workflow
|
|
8
|
+
|
|
9
|
+
""" A high-level interface to submitting a calculation. """
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def compute(
|
|
13
|
+
molecule: str | cctk.Molecule | stjames.Molecule,
|
|
14
|
+
workflow_type: str,
|
|
15
|
+
name: str = "",
|
|
16
|
+
folder_uuid: Optional[stjames.UUID] = None,
|
|
17
|
+
blocking: bool = True,
|
|
18
|
+
ping_interval: int = 5,
|
|
19
|
+
**workflow_data,
|
|
20
|
+
) -> dict:
|
|
21
|
+
"""High-level function to compute and return workflows."""
|
|
22
|
+
|
|
23
|
+
if isinstance(molecule, str):
|
|
24
|
+
stjmol = smiles_to_stjames(molecule)
|
|
25
|
+
elif isinstance(molecule, cctk.Molecule):
|
|
26
|
+
stjmol = cctk_to_stjames(molecule)
|
|
27
|
+
elif isinstance(molecule, stjames.Molecule):
|
|
28
|
+
stjmol = molecule
|
|
29
|
+
else:
|
|
30
|
+
raise ValueError("Invalid type for `molecule`!")
|
|
31
|
+
|
|
32
|
+
result = Workflow.submit(
|
|
33
|
+
initial_molecule=stjmol,
|
|
34
|
+
workflow_type=workflow_type,
|
|
35
|
+
name=name,
|
|
36
|
+
folder_uuid=folder_uuid,
|
|
37
|
+
workflow_data=workflow_data,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
if blocking:
|
|
41
|
+
uuid = result["uuid"]
|
|
42
|
+
|
|
43
|
+
while not Workflow.is_finished(uuid):
|
|
44
|
+
time.sleep(ping_interval)
|
|
45
|
+
|
|
46
|
+
completed_result = Workflow.retrieve(uuid)
|
|
47
|
+
return completed_result
|
|
48
|
+
|
|
49
|
+
else:
|
|
50
|
+
return result
|
rowan/constants.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
API_URL = "https://api.rowansci.com"
|
rowan/folder.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import stjames
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from .utils import api_client
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Folder:
|
|
8
|
+
@classmethod
|
|
9
|
+
def create(
|
|
10
|
+
cls,
|
|
11
|
+
name: str,
|
|
12
|
+
parent_uuid: Optional[stjames.UUID] = None,
|
|
13
|
+
notes: str = "",
|
|
14
|
+
starred: bool = False,
|
|
15
|
+
public: bool = False,
|
|
16
|
+
) -> dict:
|
|
17
|
+
with api_client() as client:
|
|
18
|
+
response = client.post(
|
|
19
|
+
"/folder",
|
|
20
|
+
json={
|
|
21
|
+
"name": name,
|
|
22
|
+
"parent_uuid": parent_uuid,
|
|
23
|
+
"notes": notes,
|
|
24
|
+
"starred": starred,
|
|
25
|
+
"public": public,
|
|
26
|
+
},
|
|
27
|
+
)
|
|
28
|
+
response.raise_for_status()
|
|
29
|
+
return response.json()
|
|
30
|
+
|
|
31
|
+
@classmethod
|
|
32
|
+
def retrieve(cls, uuid: stjames.UUID) -> dict:
|
|
33
|
+
with api_client() as client:
|
|
34
|
+
response = client.get(f"/folder/{uuid}")
|
|
35
|
+
response.raise_for_status()
|
|
36
|
+
return response.json()
|
|
37
|
+
|
|
38
|
+
@classmethod
|
|
39
|
+
def update(
|
|
40
|
+
cls,
|
|
41
|
+
uuid: stjames.UUID,
|
|
42
|
+
name: Optional[str] = None,
|
|
43
|
+
parent_uuid: Optional[stjames.UUID] = None,
|
|
44
|
+
notes: Optional[str] = None,
|
|
45
|
+
starred: Optional[bool] = None,
|
|
46
|
+
public: Optional[bool] = None,
|
|
47
|
+
) -> None:
|
|
48
|
+
old_data = cls.retrieve(uuid)
|
|
49
|
+
|
|
50
|
+
new_data = {}
|
|
51
|
+
new_data["name"] = name if name is not None else old_data["name"]
|
|
52
|
+
new_data["parent_uuid"] = (
|
|
53
|
+
parent_uuid if parent_uuid is not None else old_data["parent_uuid"]
|
|
54
|
+
)
|
|
55
|
+
new_data["notes"] = notes if notes is not None else old_data["notes"]
|
|
56
|
+
new_data["starred"] = starred if starred is not None else old_data["starred"]
|
|
57
|
+
new_data["public"] = public if public is not None else old_data["public"]
|
|
58
|
+
|
|
59
|
+
with api_client() as client:
|
|
60
|
+
response = client.post(f"/folder/{uuid}", json=new_data)
|
|
61
|
+
response.raise_for_status()
|
|
62
|
+
return response.json()
|
|
63
|
+
|
|
64
|
+
@classmethod
|
|
65
|
+
def delete(cls, uuid: stjames.UUID) -> None:
|
|
66
|
+
with api_client() as client:
|
|
67
|
+
response = client.delete(f"/folder/{uuid}")
|
|
68
|
+
response.raise_for_status()
|
|
69
|
+
|
|
70
|
+
@classmethod
|
|
71
|
+
def list(
|
|
72
|
+
cls,
|
|
73
|
+
parent_uuid: Optional[stjames.UUID] = None,
|
|
74
|
+
name_contains: Optional[str] = None,
|
|
75
|
+
public: Optional[bool] = None,
|
|
76
|
+
starred: Optional[bool] = None,
|
|
77
|
+
page: int = 0,
|
|
78
|
+
size: int = 10,
|
|
79
|
+
):
|
|
80
|
+
params = {"page": page, "size": size}
|
|
81
|
+
|
|
82
|
+
if parent_uuid is not None:
|
|
83
|
+
params["parent_uuid"] = parent_uuid
|
|
84
|
+
|
|
85
|
+
if name_contains is not None:
|
|
86
|
+
params["name_contains"] = name_contains
|
|
87
|
+
|
|
88
|
+
if public is not None:
|
|
89
|
+
params["public"] = public
|
|
90
|
+
|
|
91
|
+
if starred is not None:
|
|
92
|
+
params["starred"] = starred
|
|
93
|
+
|
|
94
|
+
with api_client() as client:
|
|
95
|
+
response = client.get("/folder", params=params)
|
|
96
|
+
response.raise_for_status()
|
|
97
|
+
return response.json()
|
rowan/utils.py
CHANGED
|
@@ -2,9 +2,13 @@ import os
|
|
|
2
2
|
import cctk
|
|
3
3
|
import stjames
|
|
4
4
|
import numpy as np
|
|
5
|
+
from contextlib import contextmanager
|
|
6
|
+
import httpx
|
|
5
7
|
|
|
6
8
|
import rowan
|
|
7
9
|
|
|
10
|
+
from .constants import API_URL
|
|
11
|
+
|
|
8
12
|
|
|
9
13
|
def get_api_key() -> str:
|
|
10
14
|
api_key = os.environ.get("ROWAN_API_KEY")
|
|
@@ -24,10 +28,27 @@ def cctk_to_stjames(molecule: cctk.Molecule) -> stjames.Molecule:
|
|
|
24
28
|
|
|
25
29
|
atoms = list()
|
|
26
30
|
for i in range(molecule.num_atoms()):
|
|
27
|
-
atoms.append(
|
|
31
|
+
atoms.append(
|
|
32
|
+
stjames.Atom(atomic_number=atomic_numbers[i], position=geometry[i])
|
|
33
|
+
)
|
|
28
34
|
|
|
29
35
|
return stjames.Molecule(
|
|
30
36
|
atoms=atoms,
|
|
31
37
|
charge=molecule.charge,
|
|
32
38
|
multiplicity=molecule.multiplicity,
|
|
33
39
|
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def smiles_to_stjames(smiles: str) -> stjames.Molecule:
|
|
43
|
+
cmol = cctk.Molecule.new_from_smiles(smiles)
|
|
44
|
+
return cctk_to_stjames(cmol)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@contextmanager
|
|
48
|
+
def api_client():
|
|
49
|
+
"""Wraps `httpx.Client` with Rowan-specific kwargs."""
|
|
50
|
+
with httpx.Client(
|
|
51
|
+
base_url=API_URL,
|
|
52
|
+
headers={"X-API-Key": get_api_key()},
|
|
53
|
+
) as client:
|
|
54
|
+
yield client
|
rowan/workflow.py
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import stjames
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
from .utils import api_client
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Workflow:
|
|
9
|
+
@classmethod
|
|
10
|
+
def submit(
|
|
11
|
+
cls,
|
|
12
|
+
workflow_type: str,
|
|
13
|
+
initial_molecule: dict | stjames.Molecule,
|
|
14
|
+
workflow_data: dict,
|
|
15
|
+
name: Optional[str] = None,
|
|
16
|
+
folder_uuid: Optional[stjames.UUID] = None,
|
|
17
|
+
) -> dict:
|
|
18
|
+
if isinstance(initial_molecule, stjames.Molecule):
|
|
19
|
+
molecule_dict = initial_molecule.model_dump()
|
|
20
|
+
elif isinstance(initial_molecule, dict):
|
|
21
|
+
molecule_dict = initial_molecule
|
|
22
|
+
else:
|
|
23
|
+
raise ValueError("Invalid type for `initial_molecule`")
|
|
24
|
+
|
|
25
|
+
with api_client() as client:
|
|
26
|
+
response = client.post(
|
|
27
|
+
"/workflow",
|
|
28
|
+
json={
|
|
29
|
+
"name": name,
|
|
30
|
+
"folder_uuid": folder_uuid,
|
|
31
|
+
"initial_molecule": molecule_dict,
|
|
32
|
+
"workflow_type": workflow_type,
|
|
33
|
+
"workflow_data": workflow_data,
|
|
34
|
+
},
|
|
35
|
+
)
|
|
36
|
+
response.raise_for_status()
|
|
37
|
+
return response.json()
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def retrieve(cls, uuid: stjames.UUID) -> dict:
|
|
41
|
+
with api_client() as client:
|
|
42
|
+
response = client.get(f"/workflow/{uuid}")
|
|
43
|
+
response.raise_for_status()
|
|
44
|
+
return response.json()
|
|
45
|
+
|
|
46
|
+
@classmethod
|
|
47
|
+
def update(
|
|
48
|
+
cls,
|
|
49
|
+
uuid: stjames.UUID,
|
|
50
|
+
name: Optional[str] = None,
|
|
51
|
+
parent_uuid: Optional[stjames.UUID] = None,
|
|
52
|
+
notes: Optional[str] = None,
|
|
53
|
+
starred: Optional[bool] = None,
|
|
54
|
+
email_when_complete: Optional[bool] = None,
|
|
55
|
+
public: Optional[bool] = None,
|
|
56
|
+
) -> None:
|
|
57
|
+
old_data = cls.retrieve(uuid)
|
|
58
|
+
|
|
59
|
+
new_data = {}
|
|
60
|
+
new_data["name"] = name if name is not None else old_data["name"]
|
|
61
|
+
new_data["parent_uuid"] = (
|
|
62
|
+
parent_uuid if parent_uuid is not None else old_data["parent_uuid"]
|
|
63
|
+
)
|
|
64
|
+
new_data["notes"] = notes if notes is not None else old_data["notes"]
|
|
65
|
+
new_data["starred"] = starred if starred is not None else old_data["starred"]
|
|
66
|
+
new_data["email_when_complete"] = (
|
|
67
|
+
email_when_complete
|
|
68
|
+
if email_when_complete is not None
|
|
69
|
+
else old_data["email_when_complete"]
|
|
70
|
+
)
|
|
71
|
+
new_data["public"] = public if public is not None else old_data["public"]
|
|
72
|
+
|
|
73
|
+
with api_client() as client:
|
|
74
|
+
response = client.post(f"/workflow/{uuid}", json=new_data)
|
|
75
|
+
response.raise_for_status()
|
|
76
|
+
return response.json()
|
|
77
|
+
|
|
78
|
+
@classmethod
|
|
79
|
+
def status(cls, uuid: stjames.UUID) -> int:
|
|
80
|
+
data = cls.retrieve(uuid)
|
|
81
|
+
return data["object_status"]
|
|
82
|
+
|
|
83
|
+
@classmethod
|
|
84
|
+
def is_finished(cls, uuid: stjames.UUID) -> bool:
|
|
85
|
+
status = cls.status(uuid)
|
|
86
|
+
return status in {
|
|
87
|
+
stjames.Status.COMPLETED_OK.value,
|
|
88
|
+
stjames.Status.FAILED.value,
|
|
89
|
+
stjames.Status.STOPPED.value,
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@classmethod
|
|
93
|
+
def stop(cls, uuid: stjames.UUID) -> None:
|
|
94
|
+
with api_client() as client:
|
|
95
|
+
response = client.post(f"/workflow/{uuid}/stop")
|
|
96
|
+
response.raise_for_status()
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def delete(cls, uuid: stjames.UUID) -> None:
|
|
100
|
+
with api_client() as client:
|
|
101
|
+
response = client.delete(f"/workflow/{uuid}")
|
|
102
|
+
response.raise_for_status()
|
|
103
|
+
|
|
104
|
+
@classmethod
|
|
105
|
+
def list(
|
|
106
|
+
cls,
|
|
107
|
+
parent_uuid: Optional[stjames.UUID] = None,
|
|
108
|
+
name_contains: Optional[str] = None,
|
|
109
|
+
public: Optional[bool] = None,
|
|
110
|
+
starred: Optional[bool] = None,
|
|
111
|
+
object_status: Optional[int] = None,
|
|
112
|
+
object_type: Optional[str] = None,
|
|
113
|
+
page: int = 0,
|
|
114
|
+
size: int = 10,
|
|
115
|
+
):
|
|
116
|
+
params = {"page": page, "size": size}
|
|
117
|
+
|
|
118
|
+
if parent_uuid is not None:
|
|
119
|
+
params["parent_uuid"] = parent_uuid
|
|
120
|
+
|
|
121
|
+
if name_contains is not None:
|
|
122
|
+
params["name_contains"] = name_contains
|
|
123
|
+
|
|
124
|
+
if public is not None:
|
|
125
|
+
params["public"] = public
|
|
126
|
+
|
|
127
|
+
if starred is not None:
|
|
128
|
+
params["starred"] = starred
|
|
129
|
+
|
|
130
|
+
if object_status is not None:
|
|
131
|
+
params["object_status"] = object_status
|
|
132
|
+
|
|
133
|
+
if object_type is not None:
|
|
134
|
+
params["object_type"] = object_type
|
|
135
|
+
|
|
136
|
+
with api_client() as client:
|
|
137
|
+
response = client.get("/workflow", params=params)
|
|
138
|
+
response.raise_for_status()
|
|
139
|
+
return response.json()
|
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: rowan-python
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 1.0.0
|
|
4
4
|
Summary: Rowan Python Library
|
|
5
|
-
Author-email: Corin Wagen <corin@rowansci.com>
|
|
6
5
|
Project-URL: Homepage, https://github.com/rowansci/rowan-client
|
|
7
6
|
Project-URL: Bug Tracker, https://github.com/rowansci/rowan-client/issues
|
|
7
|
+
Author-email: Corin Wagen <corin@rowansci.com>
|
|
8
|
+
License-File: LICENSE
|
|
8
9
|
Requires-Python: >=3.8
|
|
9
10
|
Description-Content-Type: text/markdown
|
|
10
|
-
License-File: LICENSE
|
|
11
|
-
Requires-Dist: cctk >=0.2.18
|
|
12
|
-
Requires-Dist: httpx >=0.25
|
|
13
|
-
Requires-Dist: numpy >=1.24
|
|
14
|
-
Requires-Dist: stjames >=0.0.23
|
|
15
11
|
|
|
16
12
|
# Rowan Python Library
|
|
17
13
|
|
|
18
14
|
[](https://pypi.python.org/pypi/rowan-python)
|
|
19
|
-
[](https://pixi.sh)
|
|
16
|
+
[](https://github.com/charliermarsh/ruff)
|
|
20
17
|
|
|
21
18
|
The Rowan Python library provides convenient access to the Rowan API from applications written in the Python language.
|
|
22
19
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
rowan/__init__.py,sha256=9JmdQXDkbru5WDq4Slt-XWH2OP4888rYyhIoLQfKqGw,183
|
|
2
|
+
rowan/calculation.py,sha256=fdWbVF97bZ2BQOBEBERLmU8DpeFUrwkZttWDSMYqwk8,312
|
|
3
|
+
rowan/client.py,sha256=GQYwqZ3pZv7vH3QvfHKEWqLPklbr1QHbZtjKRpRmiIs,1282
|
|
4
|
+
rowan/constants.py,sha256=ZZvv3L0b2y3dMGlWGeaRmx40J5tBrpxNxvJgjP1TNjg,37
|
|
5
|
+
rowan/folder.py,sha256=W7-YnPxugqzIdw-t1sr-WjeSQa-x4IjZ2mV2DwIq3II,2965
|
|
6
|
+
rowan/utils.py,sha256=IMACnRJpjFns_DF-FZQDu8p8fbgu4C2dbDaxdGcSZQs,1405
|
|
7
|
+
rowan/workflow.py,sha256=An3CW9LlHxYByE4mRl1iYThYcIGry8TwTi5rgbAsEBc,4467
|
|
8
|
+
rowan_python-1.0.0.dist-info/METADATA,sha256=IgayeoNx2nNIrsHExXgGMUW7hJDArdRdK5rkZ4ro_Xs,1030
|
|
9
|
+
rowan_python-1.0.0.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
10
|
+
rowan_python-1.0.0.dist-info/licenses/LICENSE,sha256=i7ehYBS-6gGmbTcgU4mgk28pyOx2kScJ0kcx8n7bWLM,1084
|
|
11
|
+
rowan_python-1.0.0.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
rowan/__init__.py,sha256=0O7Cmo2Io01Uqqx9iL8xcWW0t0YfgwBX7RKxDPXnbVU,61
|
|
2
|
-
rowan/client.py,sha256=fsLcxyVDjAaOj2ryQfDUcIER5Ju38M3VbVj3ugmWWUE,6130
|
|
3
|
-
rowan/utils.py,sha256=AVldYWowm7g1Ffs7JhJY7X85goNuFHvMUel0zXguDrk,932
|
|
4
|
-
rowan_python-0.0.4.dist-info/LICENSE,sha256=i7ehYBS-6gGmbTcgU4mgk28pyOx2kScJ0kcx8n7bWLM,1084
|
|
5
|
-
rowan_python-0.0.4.dist-info/METADATA,sha256=LfixlqMZP5f-05FONQDI8aBxKO6lrZP9DOZLaW9EV44,1067
|
|
6
|
-
rowan_python-0.0.4.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
7
|
-
rowan_python-0.0.4.dist-info/top_level.txt,sha256=0B0BJ1GvTwD5rxpsHctrermP7PVk4SFaQb2syJpGQl8,6
|
|
8
|
-
rowan_python-0.0.4.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
rowan
|
|
File without changes
|