rowan-python 3.0.6__py3-none-any.whl → 3.0.8__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 +1 -0
- rowan/api_keys.py +144 -0
- rowan/workflows/__init__.py +5 -0
- rowan/workflows/electronic_properties.py +29 -1
- rowan/workflows/pka.py +10 -1
- rowan/workflows/pocket_detection.py +112 -0
- rowan/workflows/protein_cofolding.py +19 -2
- {rowan_python-3.0.6.dist-info → rowan_python-3.0.8.dist-info}/METADATA +2 -2
- {rowan_python-3.0.6.dist-info → rowan_python-3.0.8.dist-info}/RECORD +11 -9
- {rowan_python-3.0.6.dist-info → rowan_python-3.0.8.dist-info}/WHEEL +0 -0
- {rowan_python-3.0.6.dist-info → rowan_python-3.0.8.dist-info}/licenses/LICENSE +0 -0
rowan/__init__.py
CHANGED
rowan/api_keys.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import uuid
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import Literal, Self
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel
|
|
6
|
+
|
|
7
|
+
from .utils import api_client
|
|
8
|
+
|
|
9
|
+
APIKeyScope = Literal["read", "read_write", "read_write_delete"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class APIKey(BaseModel):
|
|
13
|
+
"""
|
|
14
|
+
Rowan API key.
|
|
15
|
+
|
|
16
|
+
:ivar uuid: UUID of the API key.
|
|
17
|
+
:ivar name: Human-readable name of the API key.
|
|
18
|
+
:ivar created_at: When the key was created.
|
|
19
|
+
:ivar expires_at: When the key expires.
|
|
20
|
+
:ivar is_expired: Whether the key has expired.
|
|
21
|
+
:ivar is_revoked: Whether the key has been revoked.
|
|
22
|
+
:ivar scope: Permission scope ("read", "read_write", or "read_write_delete").
|
|
23
|
+
:ivar can_manage_api_keys: Whether this key can create/list/revoke other API keys.
|
|
24
|
+
:ivar scoped_project_uuid: If set, the key can only access this project.
|
|
25
|
+
:ivar created_by_key_uuid: UUID of the API key used to create this one (if any).
|
|
26
|
+
:ivar revoked_at: When the key was revoked, if applicable.
|
|
27
|
+
:ivar last_used_at: When the key was last used, if known.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
uuid: str
|
|
31
|
+
name: str
|
|
32
|
+
created_at: datetime
|
|
33
|
+
expires_at: datetime
|
|
34
|
+
is_expired: bool
|
|
35
|
+
is_revoked: bool
|
|
36
|
+
scope: str
|
|
37
|
+
can_manage_api_keys: bool
|
|
38
|
+
scoped_project_uuid: str | None = None
|
|
39
|
+
created_by_key_uuid: str | None = None
|
|
40
|
+
revoked_at: datetime | None = None
|
|
41
|
+
last_used_at: datetime | None = None
|
|
42
|
+
|
|
43
|
+
def __repr__(self) -> str:
|
|
44
|
+
return (
|
|
45
|
+
f"<APIKey name='{self.name}' scope='{self.scope}' "
|
|
46
|
+
f"scoped_project_uuid={self.scoped_project_uuid!r} uuid='{self.uuid}'>"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
def revoke(self) -> Self:
|
|
50
|
+
"""
|
|
51
|
+
Revoke this API key.
|
|
52
|
+
|
|
53
|
+
:returns: Updated APIKey object.
|
|
54
|
+
"""
|
|
55
|
+
with api_client() as client:
|
|
56
|
+
response = client.post(f"/api_key/{self.uuid}/revoke")
|
|
57
|
+
response.raise_for_status()
|
|
58
|
+
return type(self)(**response.json())
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class CreatedAPIKey(BaseModel):
|
|
62
|
+
"""
|
|
63
|
+
Result of creating a new API key.
|
|
64
|
+
|
|
65
|
+
The plaintext ``key`` is only available at creation time — store it now,
|
|
66
|
+
it cannot be retrieved later.
|
|
67
|
+
|
|
68
|
+
:ivar key: Plaintext API key. Save this; it is only returned once.
|
|
69
|
+
:ivar api_key: Metadata for the newly-created key.
|
|
70
|
+
"""
|
|
71
|
+
|
|
72
|
+
key: str
|
|
73
|
+
api_key: APIKey
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def create_api_key(
|
|
77
|
+
name: str = "api-key",
|
|
78
|
+
scope: APIKeyScope = "read_write",
|
|
79
|
+
valid_days: int = 365,
|
|
80
|
+
scoped_project_uuid: str | None = None,
|
|
81
|
+
) -> CreatedAPIKey:
|
|
82
|
+
"""
|
|
83
|
+
Create a new API key.
|
|
84
|
+
|
|
85
|
+
The caller must currently authenticate with an unscoped key that has
|
|
86
|
+
``can_manage_api_keys`` permission.
|
|
87
|
+
|
|
88
|
+
:param name: Human-readable name for the key.
|
|
89
|
+
:param scope: Permission scope. One of "read", "read_write", "read_write_delete".
|
|
90
|
+
:param valid_days: Number of days until the key expires.
|
|
91
|
+
:param scoped_project_uuid: If provided, restrict the key to a single project.
|
|
92
|
+
:returns: plaintext key together with its metadata; the plaintext key is
|
|
93
|
+
only returned once — store it immediately.
|
|
94
|
+
"""
|
|
95
|
+
plaintext_key = f"rowan-sk{uuid.uuid4()}"
|
|
96
|
+
payload = {
|
|
97
|
+
"api_key": plaintext_key,
|
|
98
|
+
"name": name,
|
|
99
|
+
"scope": scope,
|
|
100
|
+
"valid_days": valid_days,
|
|
101
|
+
"scoped_project_uuid": scoped_project_uuid,
|
|
102
|
+
}
|
|
103
|
+
with api_client() as client:
|
|
104
|
+
response = client.post("/api_key", json=payload)
|
|
105
|
+
if response.status_code == 403:
|
|
106
|
+
raise PermissionError(
|
|
107
|
+
"API key creation rejected by the server (403). The key you are "
|
|
108
|
+
"authenticating with must be unscoped and have `can_manage_api_keys` "
|
|
109
|
+
"permission. Create a manager key from the Rowan web UI "
|
|
110
|
+
"(Account → API keys) and retry with that key."
|
|
111
|
+
)
|
|
112
|
+
response.raise_for_status()
|
|
113
|
+
return CreatedAPIKey(key=plaintext_key, api_key=APIKey(**response.json()))
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def list_api_keys(active: bool | None = True) -> list[APIKey]:
|
|
117
|
+
"""
|
|
118
|
+
List API keys belonging to the current user.
|
|
119
|
+
|
|
120
|
+
:param active: If True (default), only return non-revoked, non-expired keys.
|
|
121
|
+
If False, only return revoked or expired keys. If None, return all keys.
|
|
122
|
+
:returns: List of APIKey objects.
|
|
123
|
+
"""
|
|
124
|
+
params: dict[str, str] = {}
|
|
125
|
+
if active is not None:
|
|
126
|
+
params["active"] = "true" if active else "false"
|
|
127
|
+
|
|
128
|
+
with api_client() as client:
|
|
129
|
+
response = client.get("/api_key", params=params)
|
|
130
|
+
response.raise_for_status()
|
|
131
|
+
return [APIKey(**item) for item in response.json()]
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def revoke_api_key(uuid: str) -> APIKey:
|
|
135
|
+
"""
|
|
136
|
+
Revoke an API key by UUID.
|
|
137
|
+
|
|
138
|
+
:param uuid: UUID of the key to revoke.
|
|
139
|
+
:returns: Updated APIKey object.
|
|
140
|
+
"""
|
|
141
|
+
with api_client() as client:
|
|
142
|
+
response = client.post(f"/api_key/{uuid}/revoke")
|
|
143
|
+
response.raise_for_status()
|
|
144
|
+
return APIKey(**response.json())
|
rowan/workflows/__init__.py
CHANGED
|
@@ -84,6 +84,7 @@ from .multistage_optimization import (
|
|
|
84
84
|
)
|
|
85
85
|
from .nmr import NMRPeak, NMRResult, submit_nmr_workflow
|
|
86
86
|
from .pka import pKaMicrostate, pKaResult, submit_pka_workflow
|
|
87
|
+
from .pocket_detection import Pocket, PocketDetectionResult, submit_pocket_detection_workflow
|
|
87
88
|
from .pose_analysis_md import PoseAnalysisMDResult, submit_pose_analysis_md_workflow
|
|
88
89
|
from .protein_binder_design import (
|
|
89
90
|
ProteinBinder,
|
|
@@ -91,7 +92,11 @@ from .protein_binder_design import (
|
|
|
91
92
|
submit_protein_binder_design_workflow,
|
|
92
93
|
)
|
|
93
94
|
from .protein_cofolding import (
|
|
95
|
+
CofoldingModel,
|
|
94
96
|
CofoldingResult,
|
|
97
|
+
ConstraintTarget,
|
|
98
|
+
ContactConstraint,
|
|
99
|
+
PocketConstraint,
|
|
95
100
|
ProteinCofoldingResult,
|
|
96
101
|
submit_protein_cofolding_workflow,
|
|
97
102
|
)
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass
|
|
4
4
|
|
|
5
|
+
import httpx
|
|
5
6
|
import stjames
|
|
7
|
+
from pydantic import ValidationError
|
|
8
|
+
from stjames import ENGINE_METHODS, Engine, Method
|
|
6
9
|
|
|
7
10
|
from ..folder import Folder
|
|
8
11
|
from ..types import MoleculeInput
|
|
@@ -30,6 +33,22 @@ class ElectronicPropertiesResult(WorkflowResult):
|
|
|
30
33
|
|
|
31
34
|
_stjames_class = stjames.ElectronicPropertiesWorkflow
|
|
32
35
|
|
|
36
|
+
def __post_init__(self) -> None:
|
|
37
|
+
# Computed results (dipole, charges, cubes, orbitals, ...) live only in
|
|
38
|
+
# the gzipped S3 blob, not in the workflow's object_data row. Fetch and
|
|
39
|
+
# parse it once on construction so accessors below see populated data.
|
|
40
|
+
super().__post_init__()
|
|
41
|
+
if not self.complete:
|
|
42
|
+
return
|
|
43
|
+
try:
|
|
44
|
+
with api_client() as client:
|
|
45
|
+
response = client.get(f"/orbitals/{self.workflow_uuid}/compressed_json")
|
|
46
|
+
response.raise_for_status()
|
|
47
|
+
populated = stjames.ElectronicPropertiesWorkflow.model_validate(response.json())
|
|
48
|
+
object.__setattr__(self, "_workflow", populated)
|
|
49
|
+
except (httpx.HTTPError, ValidationError):
|
|
50
|
+
pass
|
|
51
|
+
|
|
33
52
|
def __repr__(self) -> str:
|
|
34
53
|
return f"<ElectronicPropertiesResult dipole={self.dipole} D>"
|
|
35
54
|
|
|
@@ -155,6 +174,7 @@ def submit_electronic_properties_workflow(
|
|
|
155
174
|
:param webhook_url: URL that Rowan will POST to when the workflow completes.
|
|
156
175
|
:param is_draft: If True, submit the workflow as a draft without starting execution.
|
|
157
176
|
:returns: Workflow object representing the submitted workflow.
|
|
177
|
+
:raises ValueError: If the method is not supported by the psi4 engine.
|
|
158
178
|
:raises requests.HTTPError: if the request to the API fails.
|
|
159
179
|
"""
|
|
160
180
|
if folder and folder_uuid:
|
|
@@ -164,7 +184,15 @@ def submit_electronic_properties_workflow(
|
|
|
164
184
|
initial_molecule = molecule_to_dict(initial_molecule)
|
|
165
185
|
|
|
166
186
|
if isinstance(method, str):
|
|
167
|
-
method =
|
|
187
|
+
method = Method(method)
|
|
188
|
+
|
|
189
|
+
supported_methods = ENGINE_METHODS[Engine.PSI4]
|
|
190
|
+
if method not in supported_methods:
|
|
191
|
+
supported_names = sorted(m.value for m in supported_methods)
|
|
192
|
+
raise ValueError(
|
|
193
|
+
f"Method '{method.value}' is not supported by the psi4 engine. "
|
|
194
|
+
f"Supported methods: {', '.join(supported_names)}"
|
|
195
|
+
)
|
|
168
196
|
|
|
169
197
|
settings = stjames.Settings(method=method, basis_set=basis_set)
|
|
170
198
|
|
rowan/workflows/pka.py
CHANGED
|
@@ -188,7 +188,16 @@ def submit_pka_workflow(
|
|
|
188
188
|
if method in _PKA_WATER_ONLY_METHODS and solvent != "water":
|
|
189
189
|
raise ValueError(f"{method} only supports water as solvent.")
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
if method == "chemprop_nevolianis2025" and protonate_elements:
|
|
192
|
+
raise ValueError(
|
|
193
|
+
"chemprop_nevolianis2025 was only trained on deprotonation data; "
|
|
194
|
+
"protonation is disabled. Leave `protonate_elements` unset or pass []."
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
if method == "chemprop_nevolianis2025":
|
|
198
|
+
protonate_elements = []
|
|
199
|
+
else:
|
|
200
|
+
protonate_elements = protonate_elements or [7]
|
|
192
201
|
deprotonate_elements = deprotonate_elements or [7, 8, 16]
|
|
193
202
|
|
|
194
203
|
workflow = stjames.pKaWorkflow(
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Pocket detection workflow - detect potential binding sites on a protein."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
import stjames
|
|
6
|
+
|
|
7
|
+
from ..folder import Folder
|
|
8
|
+
from ..protein import Protein
|
|
9
|
+
from ..utils import api_client
|
|
10
|
+
from .base import Workflow, WorkflowResult, register_result
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(frozen=True, slots=True)
|
|
14
|
+
class Pocket:
|
|
15
|
+
"""
|
|
16
|
+
A detected binding pocket.
|
|
17
|
+
|
|
18
|
+
:param sphere_centers: centers of detected spheres, in Å
|
|
19
|
+
:param sphere_radii: radii of detected spheres, in Å
|
|
20
|
+
:param volume: pocket volume, in ų
|
|
21
|
+
:param score: druggability/quality score; larger is better
|
|
22
|
+
:param pocket_center: center of axis-aligned bounding box, in Å
|
|
23
|
+
:param pocket_sides: side lengths of axis-aligned bounding box, in Å
|
|
24
|
+
:param residue_numbers: residue numbers lining the pocket
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
sphere_centers: tuple[tuple[float, float, float], ...]
|
|
28
|
+
sphere_radii: tuple[float, ...]
|
|
29
|
+
volume: float
|
|
30
|
+
score: float
|
|
31
|
+
pocket_center: tuple[float, float, float]
|
|
32
|
+
pocket_sides: tuple[float, float, float]
|
|
33
|
+
residue_numbers: tuple[int, ...]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@register_result("pocket_detection")
|
|
37
|
+
class PocketDetectionResult(WorkflowResult):
|
|
38
|
+
"""Result from a pocket-detection workflow."""
|
|
39
|
+
|
|
40
|
+
_stjames_class = stjames.PocketDetectionWorkflow
|
|
41
|
+
|
|
42
|
+
def __repr__(self) -> str:
|
|
43
|
+
return f"<PocketDetectionResult pockets={len(self.pockets)}>"
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def pockets(self) -> list[Pocket]:
|
|
47
|
+
"""Detected pockets, in the order returned by the backend."""
|
|
48
|
+
raw = getattr(self._workflow, "pockets", []) or []
|
|
49
|
+
return [
|
|
50
|
+
Pocket(
|
|
51
|
+
sphere_centers=tuple(tuple(c) for c in p.sphere_centers),
|
|
52
|
+
sphere_radii=tuple(p.sphere_radii),
|
|
53
|
+
volume=p.volume,
|
|
54
|
+
score=p.score,
|
|
55
|
+
pocket_center=tuple(p.pocket_center),
|
|
56
|
+
pocket_sides=tuple(p.pocket_sides),
|
|
57
|
+
residue_numbers=tuple(p.residue_numbers),
|
|
58
|
+
)
|
|
59
|
+
for p in raw
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def submit_pocket_detection_workflow(
|
|
64
|
+
protein: str | Protein,
|
|
65
|
+
merge_distance: float = 1.75,
|
|
66
|
+
name: str = "Pocket Detection Workflow",
|
|
67
|
+
folder_uuid: str | None = None,
|
|
68
|
+
folder: Folder | None = None,
|
|
69
|
+
max_credits: int | None = None,
|
|
70
|
+
webhook_url: str | None = None,
|
|
71
|
+
is_draft: bool = False,
|
|
72
|
+
) -> Workflow:
|
|
73
|
+
"""
|
|
74
|
+
Submits a pocket-detection workflow to the API.
|
|
75
|
+
|
|
76
|
+
:param protein: protein to analyze. Can be a UUID or a Protein object.
|
|
77
|
+
:param merge_distance: distance for merging pocket spheres, in Å
|
|
78
|
+
:param name: name of the workflow
|
|
79
|
+
:param folder_uuid: UUID of the folder to place the workflow in
|
|
80
|
+
:param folder: Folder object to store the workflow in
|
|
81
|
+
:param max_credits: maximum number of credits to use for the workflow
|
|
82
|
+
:param webhook_url: URL that Rowan will POST to when the workflow completes
|
|
83
|
+
:param is_draft: if True, submit the workflow as a draft without starting execution
|
|
84
|
+
:returns: Workflow object representing the submitted workflow
|
|
85
|
+
:raises requests.HTTPError: if the request to the API fails
|
|
86
|
+
"""
|
|
87
|
+
if folder and folder_uuid:
|
|
88
|
+
raise ValueError("Provide either `folder` or `folder_uuid`, not both.")
|
|
89
|
+
if folder:
|
|
90
|
+
folder_uuid = folder.uuid
|
|
91
|
+
if isinstance(protein, Protein):
|
|
92
|
+
protein = protein.uuid
|
|
93
|
+
|
|
94
|
+
workflow = stjames.PocketDetectionWorkflow(
|
|
95
|
+
protein=protein,
|
|
96
|
+
merge_distance=merge_distance,
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
data = {
|
|
100
|
+
"workflow_type": "pocket_detection",
|
|
101
|
+
"workflow_data": workflow.model_dump(mode="json"),
|
|
102
|
+
"name": name,
|
|
103
|
+
"folder_uuid": folder_uuid,
|
|
104
|
+
"max_credits": max_credits,
|
|
105
|
+
"webhook_url": webhook_url,
|
|
106
|
+
"is_draft": is_draft,
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
with api_client() as client:
|
|
110
|
+
response = client.post("/workflow", json=data)
|
|
111
|
+
response.raise_for_status()
|
|
112
|
+
return Workflow(**response.json())
|
|
@@ -9,8 +9,12 @@ from ..protein import Protein, retrieve_protein
|
|
|
9
9
|
from ..utils import api_client
|
|
10
10
|
from .base import Message, Workflow, WorkflowResult, parse_messages, register_result
|
|
11
11
|
|
|
12
|
-
# Re-export cofolding model enum from stjames
|
|
13
12
|
CofoldingModel = stjames.CofoldingModel
|
|
13
|
+
# `ConstraintTarget` aliases stjames's `Token` - one position in an input
|
|
14
|
+
# (a protein/nucleic-acid residue or a ligand atom) addressable by a constraint.
|
|
15
|
+
ConstraintTarget = stjames.workflows.protein_cofolding.Token
|
|
16
|
+
ContactConstraint = stjames.workflows.protein_cofolding.ContactConstraint
|
|
17
|
+
PocketConstraint = stjames.workflows.protein_cofolding.PocketConstraint
|
|
14
18
|
|
|
15
19
|
|
|
16
20
|
@dataclass(frozen=True, slots=True)
|
|
@@ -244,6 +248,9 @@ def submit_protein_cofolding_workflow(
|
|
|
244
248
|
ligand_binding_affinity_index: int | None = None,
|
|
245
249
|
use_msa_server: bool = True,
|
|
246
250
|
use_potentials: bool = False,
|
|
251
|
+
contact_constraints: list[ContactConstraint] | None = None,
|
|
252
|
+
pocket_constraints: list[PocketConstraint] | None = None,
|
|
253
|
+
num_samples: int | None = None,
|
|
247
254
|
compute_strain: bool = False,
|
|
248
255
|
do_pose_refinement: bool = False,
|
|
249
256
|
name: str = "Protein-Ligand Co-Folding",
|
|
@@ -260,6 +267,10 @@ def submit_protein_cofolding_workflow(
|
|
|
260
267
|
Predicts the 3D structure of protein-protein, protein-ligand, protein-DNA,
|
|
261
268
|
protein-RNA, or other biomolecular complexes.
|
|
262
269
|
|
|
270
|
+
See `examples/protein_cofolding_with_constraints.py` for a worked example
|
|
271
|
+
of using `ConstraintTarget`, `ContactConstraint`, and `PocketConstraint`
|
|
272
|
+
(Boltz-2 only).
|
|
273
|
+
|
|
263
274
|
:param initial_protein_sequences: Protein sequences to be cofolded.
|
|
264
275
|
:param initial_dna_sequences: DNA sequences to be cofolded.
|
|
265
276
|
:param initial_rna_sequences: RNA sequences to be cofolded.
|
|
@@ -267,7 +278,10 @@ def submit_protein_cofolding_workflow(
|
|
|
267
278
|
:param ligand_binding_affinity_index: Index of the ligand for which to compute
|
|
268
279
|
the binding affinity.
|
|
269
280
|
:param use_msa_server: Whether to use the MSA server for the computation.
|
|
270
|
-
:param use_potentials: Whether to use potentials
|
|
281
|
+
:param use_potentials: Whether to use potentials (inference-time steering) with Boltz.
|
|
282
|
+
:param contact_constraints: Boltz contact constraints between two tokens.
|
|
283
|
+
:param pocket_constraints: Boltz pocket constraints between a binder and contact tokens.
|
|
284
|
+
:param num_samples: Number of diffusion samples to generate. If None, uses the model default.
|
|
271
285
|
:param compute_strain: Whether to compute the strain of the pose
|
|
272
286
|
(if `pose_refinement` is enabled).
|
|
273
287
|
:param do_pose_refinement: Whether to optimize non-rotatable bonds in output poses.
|
|
@@ -302,6 +316,9 @@ def submit_protein_cofolding_workflow(
|
|
|
302
316
|
workflow = stjames.ProteinCofoldingWorkflow(
|
|
303
317
|
use_msa_server=use_msa_server,
|
|
304
318
|
use_potentials=use_potentials,
|
|
319
|
+
contact_constraints=contact_constraints or [],
|
|
320
|
+
pocket_constraints=pocket_constraints or [],
|
|
321
|
+
num_samples=num_samples,
|
|
305
322
|
model=model_str,
|
|
306
323
|
ligand_binding_affinity_index=ligand_binding_affinity_index,
|
|
307
324
|
initial_smiles_list=initial_smiles_list,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rowan-python
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.8
|
|
4
4
|
Summary: Rowan Python Library
|
|
5
5
|
Project-URL: Homepage, https://github.com/rowansci/rowan-client
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/rowansci/rowan-client/issues
|
|
@@ -11,7 +11,7 @@ Requires-Dist: httpx
|
|
|
11
11
|
Requires-Dist: nest-asyncio
|
|
12
12
|
Requires-Dist: rdkit
|
|
13
13
|
Requires-Dist: setuptools
|
|
14
|
-
Requires-Dist: stjames
|
|
14
|
+
Requires-Dist: stjames<=0.0.182
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
|
|
17
17
|
# Rowan Python Library
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
rowan/__init__.py,sha256=
|
|
1
|
+
rowan/__init__.py,sha256=wiEroKH5I6VQ-tiseUcrNGJaS_0soFnYMX0EtpwyLIs,859
|
|
2
|
+
rowan/api_keys.py,sha256=TvG5l5MmQ3Qt8Z3Y7jCA_lcrwEHuI7xHy-KLbIdQ8_A,4793
|
|
2
3
|
rowan/calculation.py,sha256=lZZ52DxPsuJWCTzFZXjhauHK6dV0KCUwzoxtmoxSY48,3442
|
|
3
4
|
rowan/config.py,sha256=3cVKHUNzkIPnN2bvx7l5sia7Zc5poXS8lKOJlowXyLA,21088
|
|
4
5
|
rowan/constants.py,sha256=emCH4m9OL2Hm5E-6mJGM_FgzrK_JrZT-FiKJ6pMNQ4Y,84
|
|
@@ -12,7 +13,7 @@ rowan/user.py,sha256=Tnwz1-u_92ACt1xATQegtMj3FcosFsAG4m-4YuAkiyg,5955
|
|
|
12
13
|
rowan/utils.py,sha256=c1s6Ze-OqLtfvrD23OV60otskejmj-CD88nNf8_nFcw,3636
|
|
13
14
|
rowan/rowan_rdkit/__init__.py,sha256=EATX2VRzywzKxqkpCUMTf7RNQLkWsfi5VcCNDW6EIiw,503
|
|
14
15
|
rowan/rowan_rdkit/chem_utils.py,sha256=ZWdLziT59Qr5JzjvV789CAyRq0m5JIawsOP4RxUbQQA,35529
|
|
15
|
-
rowan/workflows/__init__.py,sha256=
|
|
16
|
+
rowan/workflows/__init__.py,sha256=CM3GKDTafp6vl79dWqSOvkVfwH1Ty8zuc8yzi65ABxM,4438
|
|
16
17
|
rowan/workflows/admet.py,sha256=0_wIwXXLfHF-3kgGx_1EM1ljjaYHLeEijJ-GbMYxpL8,2904
|
|
17
18
|
rowan/workflows/analogue_docking.py,sha256=LJpbbaug0tZ9Cg-m0b7EgGH5hJ5894fHOC16Wefx7mE,9206
|
|
18
19
|
rowan/workflows/base.py,sha256=eLGyzTc9NpXBGC-FRjsaUwKP6RluWrz0ipDZ4jDY_jc,30103
|
|
@@ -24,7 +25,7 @@ rowan/workflows/constants.py,sha256=el8jWE9gnGTLNWn5_n_V0H362vIRneOqgy7BOQ8CScg,
|
|
|
24
25
|
rowan/workflows/descriptors.py,sha256=rGrNca6kA4SzX5BAOjP6rE91MOLTvCWSYKF_LW2Z0y4,2963
|
|
25
26
|
rowan/workflows/docking.py,sha256=wmE7QJu1uDHBDynTT1XesXXAZtpB6xLjZUKsHOQyCcU,7386
|
|
26
27
|
rowan/workflows/double_ended_ts_search.py,sha256=abBblMkshhbzq5UTwIf-ovNFxY8Ltp2O-bGu_plkI58,7806
|
|
27
|
-
rowan/workflows/electronic_properties.py,sha256=
|
|
28
|
+
rowan/workflows/electronic_properties.py,sha256=ia4mlmgnioEuLDrcgDuxAyyI6VqRkdxBqshjb9uiEI8,8385
|
|
28
29
|
rowan/workflows/fukui.py,sha256=wLimH3QmorSpvkovRPlI91VuxHG4J91F2EcLYqg3eP0,5112
|
|
29
30
|
rowan/workflows/hydrogen_bond_donor_acceptor_strength.py,sha256=WWiEK_GlumIEgTTOaqw-Y5gPDkRkaePWcIjTdIocrPc,4916
|
|
30
31
|
rowan/workflows/interaction_energy_decomposition.py,sha256=Kjwkb-pviFSFIIZNjMb9i8nAkdKrbjFftmG_lkYtE40,6120
|
|
@@ -35,10 +36,11 @@ rowan/workflows/membrane_permeability.py,sha256=oIDmB8qF_K_Kesv7o_FiljAk4dpptEeO
|
|
|
35
36
|
rowan/workflows/msa.py,sha256=V3B1SyWPR8MT306hh9W-T9JTpi_E-XgAIeF9yRQZ7tI,5075
|
|
36
37
|
rowan/workflows/multistage_optimization.py,sha256=HFVx8mnHxG97pDYyL6eOhNGmESqTxaKNgUdwrFpFUJ0,6456
|
|
37
38
|
rowan/workflows/nmr.py,sha256=hergJdsiawKj7iV-jHxDOS03n_EnZcaCIt_ZTl34-JY,5183
|
|
38
|
-
rowan/workflows/pka.py,sha256=
|
|
39
|
+
rowan/workflows/pka.py,sha256=TCFSE5HI5JLPslKdbUvJe4IxrVaLExrI_3PnDfXtxTw,8691
|
|
40
|
+
rowan/workflows/pocket_detection.py,sha256=aGHY0puxekp4c4nsNYHcvKCe1fsetygL04BcSvNFvE8,3864
|
|
39
41
|
rowan/workflows/pose_analysis_md.py,sha256=UvotLhWv0_VAkKteZboOutDry7l-Zt1K6_SBx3EXqgM,9530
|
|
40
42
|
rowan/workflows/protein_binder_design.py,sha256=J-9NSbRLdHb6JQRhY_vq43HlHCDCiQqrkOZUCAF-2dk,8604
|
|
41
|
-
rowan/workflows/protein_cofolding.py,sha256=
|
|
43
|
+
rowan/workflows/protein_cofolding.py,sha256=D2PVwL51H3traml1JDG-9jU3R0E29AdfR9Bk0tLX1Zw,14093
|
|
42
44
|
rowan/workflows/protein_md.py,sha256=_n0IdmTQsunbP1geF-wUjXNMKNYV-ngmAPEMJlj0dkI,7021
|
|
43
45
|
rowan/workflows/rbfe_graph.py,sha256=PLqzBRkxD7tPdBViYJZjgaCP8aA2UXKc9dD4odx5XUo,5788
|
|
44
46
|
rowan/workflows/redox_potential.py,sha256=lg2Djev58oOmBmI4l3eIaGKafkNXMhwo17K2G7kQvjY,5319
|
|
@@ -49,7 +51,7 @@ rowan/workflows/solvent_dependent_conformers.py,sha256=ovvnhCE4xlkpdhccLHEq7oBJR
|
|
|
49
51
|
rowan/workflows/spin_states.py,sha256=GZgBJPO6_ds9el4b7wbigIZ5213Z9DwXhokczJ5NDhs,7122
|
|
50
52
|
rowan/workflows/strain.py,sha256=r0tlZoUlAslAiF7dPTpa9WlQFUAKyVjZ19zASjSS8Hs,6339
|
|
51
53
|
rowan/workflows/tautomer_search.py,sha256=aqwXoj0ffWsb5gbvzfz_bpx5ifIfR_K07fbdWhU62Ko,5820
|
|
52
|
-
rowan_python-3.0.
|
|
53
|
-
rowan_python-3.0.
|
|
54
|
-
rowan_python-3.0.
|
|
55
|
-
rowan_python-3.0.
|
|
54
|
+
rowan_python-3.0.8.dist-info/METADATA,sha256=Fm1PlPUx4eLxJqD6QWIvxuhPvwAOnrLWbYw3Lu_IYhU,1600
|
|
55
|
+
rowan_python-3.0.8.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
56
|
+
rowan_python-3.0.8.dist-info/licenses/LICENSE,sha256=i05z7xEhyrg6f8j0lR3XYjShnF-MJGFQ-DnpsZ8yiVI,1084
|
|
57
|
+
rowan_python-3.0.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|