rowan-python 0.0.5__tar.gz → 1.0.0__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,39 @@
1
+ # This workflow will upload a Python Package using Twine when a release is created
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
3
+
4
+ # This workflow uses actions that are not certified by GitHub.
5
+ # They are provided by a third-party and are governed by
6
+ # separate terms of service, privacy policy, and support
7
+ # documentation.
8
+
9
+ name: Upload Python Package
10
+
11
+ on:
12
+ release:
13
+ types: [published]
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ deploy:
20
+
21
+ runs-on: ubuntu-latest
22
+
23
+ steps:
24
+ - uses: actions/checkout@v3
25
+ - name: Set up Python
26
+ uses: actions/setup-python@v3
27
+ with:
28
+ python-version: '3.x'
29
+ - name: Install dependencies
30
+ run: |
31
+ python -m pip install --upgrade pip
32
+ pip install build
33
+ - name: Build package
34
+ run: python -m build
35
+ - name: Publish package
36
+ uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
37
+ with:
38
+ user: __token__
39
+ password: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,17 @@
1
+ .DS_Store
2
+ *.pyc
3
+ #pyproject.toml
4
+ *.swp
5
+ dist/*
6
+ MANIFEST
7
+ __pycache__/
8
+ *.py[cod]
9
+ build/*
10
+ *.egg-info
11
+
12
+ *.lprof
13
+
14
+ .ipynb_checkpoints/*
15
+ .ipynb_checkpoints
16
+
17
+ test*
@@ -1,22 +1,19 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.3
2
2
  Name: rowan-python
3
- Version: 0.0.5
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
  [![pypi](https://img.shields.io/pypi/v/rowan-python.svg)](https://pypi.python.org/pypi/rowan-python)
19
- [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json)](https://github.com/charliermarsh/ruff)
15
+ [![pixi](https://img.shields.io/badge/Powered_by-Pixi-facc15)](https://pixi.sh)
16
+ [![ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json)](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
 
@@ -1,7 +1,8 @@
1
1
  # Rowan Python Library
2
2
 
3
3
  [![pypi](https://img.shields.io/pypi/v/rowan-python.svg)](https://pypi.python.org/pypi/rowan-python)
4
- [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json)](https://github.com/charliermarsh/ruff)
4
+ [![pixi](https://img.shields.io/badge/Powered_by-Pixi-facc15)](https://pixi.sh)
5
+ [![ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json)](https://github.com/charliermarsh/ruff)
5
6
 
6
7
  The Rowan Python library provides convenient access to the Rowan API from applications written in the Python language.
7
8
 
@@ -0,0 +1,18 @@
1
+ import cctk
2
+ import rowan
3
+
4
+ rowan.api_key = "rowan-sk..."
5
+ client = rowan.Client()
6
+
7
+ # load molecule by name (cctk can also load in a variety of file formats)
8
+ molecule = cctk.Molecule.new_from_name("cyclobutane")
9
+
10
+ # run calculation remotely and return result
11
+ result = client.compute(
12
+ molecule,
13
+ name="opt cyclobutane",
14
+ method="b97-3c",
15
+ tasks=["optimize", "charge", "dipole"]
16
+ )
17
+
18
+ print(result)
@@ -0,0 +1,37 @@
1
+ [project]
2
+ name = "rowan-python"
3
+ version = "1.0.0"
4
+ description = "Rowan Python Library"
5
+ readme = "README.md"
6
+ requires-python = ">=3.8"
7
+ authors = [
8
+ { name = "Corin Wagen", email = "corin@rowansci.com" },
9
+ ]
10
+
11
+ [project.urls]
12
+ "Homepage" = "https://github.com/rowansci/rowan-client"
13
+ "Bug Tracker" = "https://github.com/rowansci/rowan-client/issues"
14
+
15
+ [build-system]
16
+ build-backend = "hatchling.build"
17
+ requires = ["hatchling"]
18
+
19
+ [tool.pixi.project]
20
+ channels = ["conda-forge"]
21
+ platforms = ["linux-64", "osx-arm64"]
22
+
23
+ [tool.pixi.pypi-dependencies]
24
+ rowan-python = { path = ".", editable = true }
25
+ stjames = ">=0.0.42"
26
+
27
+ [tool.pixi.tasks]
28
+
29
+ [tool.pixi.dependencies]
30
+ cctk = ">=0.2.25,<0.3"
31
+ httpx = ">=0.27.2,<0.28"
32
+ setuptools = ">=73.0.1,<74"
33
+ rdkit = ">=2024.03.1"
34
+
35
+ [tool.hatch.build.targets.wheel]
36
+ packages = ["rowan"]
37
+
@@ -0,0 +1,10 @@
1
+ # ruff: noqa
2
+
3
+ from . import utils
4
+ from .client import compute
5
+
6
+ from . import constants
7
+
8
+ from .folder import Folder
9
+ from .workflow import Workflow
10
+ from .calculation import Calculation
@@ -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()
@@ -0,0 +1,50 @@
1
+ import cctk
2
+ import stjames
3
+ import time
4
+ from typing import Optional
5
+
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
@@ -0,0 +1 @@
1
+ API_URL = "https://api.rowansci.com"
@@ -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()
@@ -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(stjames.Atom(atomic_number=atomic_numbers[i], position=geometry[i]))
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
@@ -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,30 +0,0 @@
1
- [project]
2
- name = "rowan-python"
3
- version = "0.0.5"
4
- description = "Rowan Python Library"
5
- readme = "README.md"
6
- requires-python = ">=3.8"
7
- authors = [
8
- { name = "Corin Wagen", email = "corin@rowansci.com" },
9
- ]
10
-
11
- dependencies = [
12
- "cctk>=0.2.18",
13
- "httpx>=0.25",
14
- "numpy>=1.24",
15
- "stjames>=0.0.23",
16
- ]
17
-
18
- [build-system]
19
- # maybe will want to move away from setuptools eventually
20
- requires = ["setuptools>=61.0"]
21
- build-backend = "setuptools.build_meta"
22
-
23
- [project.urls]
24
- "Homepage" = "https://github.com/rowansci/rowan-client"
25
- "Bug Tracker" = "https://github.com/rowansci/rowan-client/issues"
26
-
27
- [tool.ruff]
28
- line-length = 160
29
- select = ["E", "F"]
30
- ignore = ["E741"]
@@ -1,4 +0,0 @@
1
- # ruff: noqa
2
-
3
- from . import utils
4
- from .client import Client
@@ -1,155 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import cctk
4
- import httpx
5
- from typing import Optional
6
- import stjames
7
- from dataclasses import dataclass, field
8
- import time
9
-
10
- import rowan
11
-
12
- API_URL = "https://api.rowansci.com"
13
-
14
-
15
- @dataclass
16
- class Client:
17
- blocking: bool = True
18
- print: bool = True
19
- ping_interval: int = 5
20
- delete_when_finished: bool = False
21
-
22
- headers: dict = field(init=False)
23
-
24
- def __post_init__(self):
25
- self.headers = {"X-API-Key": rowan.utils.get_api_key()}
26
-
27
- if not self.blocking and self.delete_when_finished:
28
- print("Warning: ``delete_when_finished`` has no effect when ``blocking`` is False. To delete calculations, call ``Client.delete()`` manually.")
29
-
30
- def compute(
31
- self,
32
- type: Optional[str] = "calculation",
33
- input_mol: Optional[cctk.Molecule] = None,
34
- input_smiles: Optional[str] = None,
35
- name: Optional[str] = None,
36
- folder_uuid: Optional[str] = None,
37
- engine: str = "peregrine",
38
- **options,
39
- ) -> dict | str:
40
- if (input_mol is None) == (input_smiles is None):
41
- raise ValueError("Must specify exactly one of ``input_smiles`` and ``input_mol``!")
42
-
43
- if input_mol is None:
44
- input_mol = cctk.Molecule.new_from_smiles(input_smiles)
45
-
46
- molecule = rowan.utils.cctk_to_stjames(input_mol)
47
-
48
- with httpx.Client() as client:
49
- if type == "calculation":
50
- settings = stjames.Settings(**options)
51
- calc = stjames.Calculation(molecules=[molecule], name=name, engine=engine, settings=settings)
52
-
53
- response = client.post(
54
- f"{API_URL}/calculation",
55
- headers=self.headers,
56
- json={
57
- "json_data": calc.model_dump(mode="json"),
58
- "folder_uuid": folder_uuid,
59
- },
60
- )
61
-
62
- else:
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
- else:
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
- return status in [2, 3, 4]
107
-
108
- def get(self, calc_uuid: str, type: str = "calculation") -> dict:
109
- with httpx.Client() as client:
110
- if type == "calculation":
111
- stj_response = client.get(f"{API_URL}/calculation/{calc_uuid}/stjames", headers=self.headers)
112
- stj_response.raise_for_status()
113
- stj_dict = stj_response.json()
114
-
115
- response = client.get(f"{API_URL}/calculation/{calc_uuid}", headers=self.headers)
116
- response.raise_for_status()
117
- response_dict = response.json()
118
-
119
- # reformat
120
- del response_dict["settings"]
121
- response_dict["data"] = stj_dict
122
-
123
- return response_dict
124
-
125
- else:
126
- response = client.get(f"{API_URL}/workflow/{calc_uuid}", headers=self.headers)
127
- response.raise_for_status()
128
- response_dict = response.json()
129
-
130
- # reformat
131
- response_dict["data"] = response_dict["object_data"]
132
- del response_dict["object_data"]
133
- del response_dict["status"]
134
-
135
- return response_dict
136
-
137
- def stop(self, calc_uuid: str, type: str = "calculation") -> None:
138
- with httpx.Client() as client:
139
- if type == "calculation":
140
- response = client.post(f"{API_URL}/calculation/{calc_uuid}/stop", headers=self.headers)
141
- response.raise_for_status()
142
-
143
- else:
144
- response = client.post(f"{API_URL}/workflow/{calc_uuid}/stop", headers=self.headers)
145
- response.raise_for_status()
146
-
147
- def delete(self, calc_uuid: str, type: str = "calculation") -> None:
148
- with httpx.Client() as client:
149
- if type == "calculation":
150
- response = client.delete(f"{API_URL}/calculation/{calc_uuid}", headers=self.headers)
151
- response.raise_for_status()
152
-
153
- else:
154
- response = client.delete(f"{API_URL}/folder/{calc_uuid}", headers=self.headers)
155
- response.raise_for_status()
@@ -1,32 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: rowan-python
3
- Version: 0.0.5
4
- Summary: Rowan Python Library
5
- Author-email: Corin Wagen <corin@rowansci.com>
6
- Project-URL: Homepage, https://github.com/rowansci/rowan-client
7
- Project-URL: Bug Tracker, https://github.com/rowansci/rowan-client/issues
8
- Requires-Python: >=3.8
9
- 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
-
16
- # Rowan Python Library
17
-
18
- [![pypi](https://img.shields.io/pypi/v/rowan-python.svg)](https://pypi.python.org/pypi/rowan-python)
19
- [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json)](https://github.com/charliermarsh/ruff)
20
-
21
- The Rowan Python library provides convenient access to the Rowan API from applications written in the Python language.
22
-
23
- ## Documentation
24
-
25
- The documentation is available [here](https://docs.rowansci.com/python-api).
26
-
27
-
28
- ## Issues
29
-
30
- To report issues, please use the "Issues" tab above.
31
-
32
- *Corin Wagen, 2023*
@@ -1,11 +0,0 @@
1
- LICENSE
2
- README.md
3
- pyproject.toml
4
- rowan/__init__.py
5
- rowan/client.py
6
- rowan/utils.py
7
- rowan_python.egg-info/PKG-INFO
8
- rowan_python.egg-info/SOURCES.txt
9
- rowan_python.egg-info/dependency_links.txt
10
- rowan_python.egg-info/requires.txt
11
- rowan_python.egg-info/top_level.txt
@@ -1,4 +0,0 @@
1
- cctk>=0.2.18
2
- httpx>=0.25
3
- numpy>=1.24
4
- stjames>=0.0.23
@@ -1 +0,0 @@
1
- rowan
@@ -1,4 +0,0 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
File without changes