plexus-python-pulse-common 1.1.77__py3-none-any.whl → 1.1.79__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.
- plexus/pulse/common/utils/flowutils.py +161 -37
- plexus/pulse/common/utils/tagutils.py +36 -1
- {plexus_python_pulse_common-1.1.77.dist-info → plexus_python_pulse_common-1.1.79.dist-info}/METADATA +3 -1
- {plexus_python_pulse_common-1.1.77.dist-info → plexus_python_pulse_common-1.1.79.dist-info}/RECORD +6 -6
- {plexus_python_pulse_common-1.1.77.dist-info → plexus_python_pulse_common-1.1.79.dist-info}/WHEEL +0 -0
- {plexus_python_pulse_common-1.1.77.dist-info → plexus_python_pulse_common-1.1.79.dist-info}/top_level.txt +0 -0
|
@@ -9,28 +9,62 @@ from collections.abc import Generator
|
|
|
9
9
|
from typing import Self
|
|
10
10
|
|
|
11
11
|
import pydantic as pdt
|
|
12
|
+
import requests
|
|
12
13
|
import sqlalchemy as sa
|
|
13
14
|
import sqlalchemy.dialects.sqlite as sa_sqlite
|
|
14
15
|
import sqlalchemy.orm as sa_orm
|
|
15
16
|
from plexus.common.utils.dbutils import ConnectionMaker
|
|
16
17
|
from plexus.common.utils.funcutils import Chainable
|
|
17
18
|
from plexus.common.utils.funcutils import chainable, singleton
|
|
19
|
+
from plexus.common.utils.jsonutils import JsonObject
|
|
20
|
+
from plexus.common.utils.retry import retry
|
|
18
21
|
from sqlmodel import Field
|
|
19
22
|
|
|
20
23
|
from plexus.pulse.common.utils.ormutils import SQLiteUUID, SequenceModelMixinProtocol
|
|
21
24
|
from plexus.pulse.common.utils.ormutils import clone_sequence_model_instance, make_base_model, make_sequence_model_mixin
|
|
22
25
|
|
|
23
26
|
__all__ = [
|
|
27
|
+
"flow_workspace_root_path",
|
|
28
|
+
"current_flow_run_id",
|
|
29
|
+
"current_flow_workspace_root_path",
|
|
24
30
|
"FlowStageEnum",
|
|
25
31
|
"current_flow_stage",
|
|
26
|
-
"
|
|
32
|
+
"stage_can_resolve_dataset_ref",
|
|
33
|
+
"make_dataset_ref_model_mixin",
|
|
27
34
|
"DatasetRef",
|
|
28
35
|
"DatasetRefTable",
|
|
29
|
-
"
|
|
36
|
+
"current_flow_context_file_path",
|
|
30
37
|
"FlowContext",
|
|
31
|
-
"
|
|
38
|
+
"flow_context",
|
|
39
|
+
"flow_api_url",
|
|
40
|
+
"resolve_dataset_ref",
|
|
41
|
+
"resolve_dataset_storage_location",
|
|
42
|
+
"resolve",
|
|
32
43
|
]
|
|
33
44
|
|
|
45
|
+
flow_stage_env = "PULSE_FLOW_STAGE"
|
|
46
|
+
flow_run_id_env = "PULSE_FLOW_RUN_ID"
|
|
47
|
+
flow_workspace_root_dir_env = "PULSE_FLOW_WORKSPACE_ROOT_DIR"
|
|
48
|
+
flow_api_url_env = "PULSE_FLOW_API_URL"
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def flow_workspace_root_path() -> pathlib.Path:
|
|
52
|
+
value = os.environ.get(flow_workspace_root_dir_env)
|
|
53
|
+
if value is None:
|
|
54
|
+
raise ValueError(f"Missing required environment variable '{flow_workspace_root_dir_env}'")
|
|
55
|
+
return pathlib.Path(value).absolute()
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def current_flow_run_id() -> str:
|
|
59
|
+
value = os.environ.get(flow_run_id_env)
|
|
60
|
+
if value is None:
|
|
61
|
+
raise ValueError(f"Missing required environment variable '{flow_run_id_env}'")
|
|
62
|
+
return value
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def current_flow_workspace_root_path() -> pathlib.Path:
|
|
66
|
+
return flow_workspace_root_path() / current_flow_run_id()
|
|
67
|
+
|
|
34
68
|
|
|
35
69
|
class FlowStageEnum(enum.Enum):
|
|
36
70
|
Preprocessing = "preprocessing"
|
|
@@ -40,20 +74,19 @@ class FlowStageEnum(enum.Enum):
|
|
|
40
74
|
|
|
41
75
|
|
|
42
76
|
def current_flow_stage() -> FlowStageEnum:
|
|
43
|
-
|
|
44
|
-
if
|
|
45
|
-
raise ValueError("Missing required environment variable '
|
|
77
|
+
value = os.environ.get(flow_stage_env)
|
|
78
|
+
if value is None:
|
|
79
|
+
raise ValueError(f"Missing required environment variable '{flow_stage_env}'")
|
|
46
80
|
for stage in list(FlowStageEnum):
|
|
47
|
-
if
|
|
81
|
+
if value == stage.value:
|
|
48
82
|
return stage
|
|
49
|
-
raise ValueError(f"Illegal '
|
|
83
|
+
raise ValueError(f"Illegal '{flow_stage_env}' value '{value}'")
|
|
50
84
|
|
|
51
85
|
|
|
52
|
-
def
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
return run_id_str
|
|
86
|
+
def stage_can_resolve_dataset_ref(stage: FlowStageEnum | None = None) -> bool:
|
|
87
|
+
if stage is None:
|
|
88
|
+
stage = current_flow_stage()
|
|
89
|
+
return stage in {FlowStageEnum.Curation}
|
|
57
90
|
|
|
58
91
|
|
|
59
92
|
def make_dataset_ref_model_mixin() -> type[pdt.BaseModel]:
|
|
@@ -62,10 +95,16 @@ def make_dataset_ref_model_mixin() -> type[pdt.BaseModel]:
|
|
|
62
95
|
sa_column=sa.Column(SQLiteUUID(), nullable=False),
|
|
63
96
|
description="UUID of the dataset",
|
|
64
97
|
)
|
|
65
|
-
dataset_name: str
|
|
66
|
-
sa_column=sa.Column(sa_sqlite.VARCHAR(128), nullable=
|
|
98
|
+
dataset_name: str = Field(
|
|
99
|
+
sa_column=sa.Column(sa_sqlite.VARCHAR(128), nullable=False),
|
|
67
100
|
description="Name of the dataset",
|
|
68
101
|
)
|
|
102
|
+
dataset_props: JsonObject | None = Field(
|
|
103
|
+
sa_column=sa.Column(sa_sqlite.JSON),
|
|
104
|
+
default=None,
|
|
105
|
+
description="Additional properties stored as JSON",
|
|
106
|
+
schema_extra=dict(examples=[{"example_prop_key": "example_prop_value"}]),
|
|
107
|
+
)
|
|
69
108
|
|
|
70
109
|
return ModelMixin
|
|
71
110
|
|
|
@@ -84,30 +123,16 @@ class DatasetRefTable(DatasetRef, make_sequence_model_mixin("sqlite"), table=Tru
|
|
|
84
123
|
if typing.TYPE_CHECKING:
|
|
85
124
|
class DatasetRef(BaseModel):
|
|
86
125
|
dataset_uuid: sa_orm.Mapped[py_uuid.UUID] = ...
|
|
87
|
-
dataset_name: sa_orm.Mapped[str
|
|
126
|
+
dataset_name: sa_orm.Mapped[str] = ...
|
|
127
|
+
dataset_props: sa_orm.Mapped[JsonObject | None] = ...
|
|
88
128
|
|
|
89
129
|
|
|
90
130
|
class DatasetRefTable(DatasetRef, SequenceModelMixinProtocol):
|
|
91
131
|
pass
|
|
92
132
|
|
|
93
133
|
|
|
94
|
-
def
|
|
95
|
-
|
|
96
|
-
stage = current_flow_stage()
|
|
97
|
-
return stage in {FlowStageEnum.Curation}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def is_construct_dataset_ref_stage(stage: FlowStageEnum | None) -> bool:
|
|
101
|
-
if stage is None:
|
|
102
|
-
stage = current_flow_stage()
|
|
103
|
-
return stage in {FlowStageEnum.Training}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def flow_context_file_path() -> pathlib.Path:
|
|
107
|
-
root_dir = os.environ.get("PULSE_FLOW_CONTEXT_ROOT_DIR")
|
|
108
|
-
if root_dir is None:
|
|
109
|
-
raise ValueError("Missing required environment variable 'PULSE_FLOW_CONTEXT_ROOT_DIR'")
|
|
110
|
-
return pathlib.Path(root_dir) / current_flow_run_id() / "flow_context.db"
|
|
134
|
+
def current_flow_context_file_path() -> pathlib.Path:
|
|
135
|
+
return current_flow_workspace_root_path() / "flow_context.db"
|
|
111
136
|
|
|
112
137
|
|
|
113
138
|
class FlowContext(object):
|
|
@@ -117,7 +142,7 @@ class FlowContext(object):
|
|
|
117
142
|
file_path: str | os.PathLike[str] | None = None,
|
|
118
143
|
fail_if_exists: bool = False,
|
|
119
144
|
):
|
|
120
|
-
self.file_path = pathlib.Path(file_path or
|
|
145
|
+
self.file_path = pathlib.Path(file_path or current_flow_context_file_path())
|
|
121
146
|
if fail_if_exists and self.file_path.exists():
|
|
122
147
|
raise FileExistsError(f"flow context file '{self.file_path}' already exists")
|
|
123
148
|
self.file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
@@ -148,13 +173,32 @@ class FlowContext(object):
|
|
|
148
173
|
with self.make_session() as session:
|
|
149
174
|
return session.query(DatasetRefTable).all()
|
|
150
175
|
|
|
176
|
+
def query_dataset_ref(
|
|
177
|
+
self,
|
|
178
|
+
dataset_uuid: py_uuid.UUID | None = None,
|
|
179
|
+
dataset_name: str | None = None,
|
|
180
|
+
) -> Chainable[Self, DatasetRefTable | None]:
|
|
181
|
+
if dataset_uuid is None and dataset_name is None:
|
|
182
|
+
raise ValueError("either 'dataset_uuid' or 'dataset_name' is required")
|
|
183
|
+
|
|
184
|
+
with self.make_session() as session:
|
|
185
|
+
query_stmt = session.query(DatasetRefTable)
|
|
186
|
+
if dataset_uuid is not None:
|
|
187
|
+
query_stmt = query_stmt.filter(DatasetRefTable.dataset_uuid == dataset_uuid)
|
|
188
|
+
if dataset_name is not None:
|
|
189
|
+
query_stmt = query_stmt.filter(DatasetRefTable.dataset_name == dataset_name)
|
|
190
|
+
db_dataset_ref = query_stmt.one_or_none()
|
|
191
|
+
|
|
192
|
+
return chainable(self, db_dataset_ref)
|
|
193
|
+
|
|
151
194
|
def add_dataset_ref(
|
|
152
195
|
self,
|
|
153
196
|
dataset_uuid: py_uuid.UUID,
|
|
154
|
-
dataset_name: str
|
|
197
|
+
dataset_name: str,
|
|
198
|
+
dataset_props: JsonObject | None = None,
|
|
155
199
|
) -> Chainable[Self, DatasetRefTable]:
|
|
156
200
|
with self.make_session() as session:
|
|
157
|
-
dataset_ref = DatasetRef(dataset_uuid=dataset_uuid, dataset_name=dataset_name)
|
|
201
|
+
dataset_ref = DatasetRef(dataset_uuid=dataset_uuid, dataset_name=dataset_name, dataset_props=dataset_props)
|
|
158
202
|
db_dataset_ref = clone_sequence_model_instance(DatasetRefTable, dataset_ref)
|
|
159
203
|
session.add(db_dataset_ref)
|
|
160
204
|
session.commit()
|
|
@@ -163,5 +207,85 @@ class FlowContext(object):
|
|
|
163
207
|
|
|
164
208
|
|
|
165
209
|
@singleton
|
|
166
|
-
def
|
|
210
|
+
def flow_context() -> FlowContext:
|
|
167
211
|
return FlowContext()
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
def flow_api_url() -> str:
|
|
215
|
+
value = os.environ.get(flow_api_url_env)
|
|
216
|
+
if value is None:
|
|
217
|
+
raise ValueError(f"Missing required environment variable '{flow_api_url_env}'")
|
|
218
|
+
return value
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
@retry(wait=10, retrials=3)
|
|
222
|
+
def fetch_dataset_ref(
|
|
223
|
+
dataset_uuid: py_uuid.UUID | None = None,
|
|
224
|
+
dataset_name: str | None = None,
|
|
225
|
+
) -> DatasetRef | None:
|
|
226
|
+
response = requests.get(f"{flow_api_url()}/pulse_demeter/dataset_public/query_dataset",
|
|
227
|
+
headers={"accept": "application/json"},
|
|
228
|
+
params={
|
|
229
|
+
"dataset_uuid": str(dataset_uuid),
|
|
230
|
+
"dataset_name": dataset_name,
|
|
231
|
+
})
|
|
232
|
+
response.raise_for_status()
|
|
233
|
+
|
|
234
|
+
response_data = response.json()
|
|
235
|
+
|
|
236
|
+
try:
|
|
237
|
+
uuid = py_uuid.UUID(response_data["dataset"]["uuid"])
|
|
238
|
+
name = response_data["dataset"]["name"]
|
|
239
|
+
props = response_data["dataset"].get("props", None)
|
|
240
|
+
return DatasetRef(dataset_uuid=uuid, dataset_name=name, dataset_props=props)
|
|
241
|
+
except KeyError:
|
|
242
|
+
return None
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def resolve_dataset_ref(
|
|
246
|
+
dataset_uuid: py_uuid.UUID | None = None,
|
|
247
|
+
dataset_name: str | None = None,
|
|
248
|
+
*,
|
|
249
|
+
context: FlowContext | None = None,
|
|
250
|
+
) -> DatasetRefTable:
|
|
251
|
+
if context is None:
|
|
252
|
+
context = flow_context()
|
|
253
|
+
|
|
254
|
+
if dataset_uuid is None and dataset_name is None:
|
|
255
|
+
raise ValueError("either 'dataset_uuid' or 'dataset_name' is required")
|
|
256
|
+
|
|
257
|
+
_, db_dataset_ref = context.query_dataset_ref(dataset_uuid=dataset_uuid, dataset_name=dataset_name)
|
|
258
|
+
if db_dataset_ref is None:
|
|
259
|
+
if not stage_can_resolve_dataset_ref():
|
|
260
|
+
# In some stages, the dataset ref should have been resolved and stored in the flow context.
|
|
261
|
+
# If not found, it's an error.
|
|
262
|
+
raise ValueError(f"cannot resolve dataset ref at flow stage '{current_flow_stage()}'")
|
|
263
|
+
|
|
264
|
+
dataset_ref = fetch_dataset_ref(dataset_uuid=dataset_uuid, dataset_name=dataset_name)
|
|
265
|
+
if dataset_ref is None:
|
|
266
|
+
raise ValueError(f"cannot found dataset with uuid '{str(dataset_uuid)}' or name '{dataset_name}'")
|
|
267
|
+
|
|
268
|
+
_, db_dataset_ref = context.add_dataset_ref(dataset_ref.dataset_uuid,
|
|
269
|
+
dataset_ref.dataset_name,
|
|
270
|
+
dataset_ref.dataset_props)
|
|
271
|
+
|
|
272
|
+
return db_dataset_ref
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
def resolve_dataset_storage_location(
|
|
276
|
+
dataset_uuid: str | py_uuid.UUID | None = None,
|
|
277
|
+
dataset_name: str | None = None,
|
|
278
|
+
*,
|
|
279
|
+
context: FlowContext | None = None,
|
|
280
|
+
) -> pathlib.Path:
|
|
281
|
+
if isinstance(dataset_uuid, str):
|
|
282
|
+
return resolve_dataset_storage_location(py_uuid.UUID(dataset_uuid), dataset_name, context=context)
|
|
283
|
+
|
|
284
|
+
db_dataset_ref = resolve_dataset_ref(dataset_uuid, dataset_name, context=context)
|
|
285
|
+
if "storage_location" in (db_dataset_ref.dataset_props or {}):
|
|
286
|
+
return pathlib.Path(db_dataset_ref.dataset_props["storage_location"]).absolute()
|
|
287
|
+
|
|
288
|
+
return current_flow_workspace_root_path() / "datasets" / str(db_dataset_ref.dataset_uuid)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
resolve = resolve_dataset_storage_location
|
|
@@ -26,7 +26,7 @@ from plexus.common.utils.iterutils import dicttree_add, dicttree_remove
|
|
|
26
26
|
from plexus.common.utils.iterutils import dicttree_children, dicttree_lineage, dicttree_subtree
|
|
27
27
|
from plexus.common.utils.jsonutils import JsonObject, JsonType
|
|
28
28
|
from plexus.common.utils.randutils import randomizer
|
|
29
|
-
from plexus.common.utils.strutils import is_blank
|
|
29
|
+
from plexus.common.utils.strutils import is_blank, parse_bool_or
|
|
30
30
|
from sqlmodel import Field
|
|
31
31
|
|
|
32
32
|
from plexus.pulse.common.resources.tags import predefined_tagset_specs
|
|
@@ -47,6 +47,7 @@ __all__ = [
|
|
|
47
47
|
"MutableTagset",
|
|
48
48
|
"populate_tagset",
|
|
49
49
|
"predefined_tagsets",
|
|
50
|
+
"seek_predefined_tagset_of",
|
|
50
51
|
"render_tagset_markdown_readme",
|
|
51
52
|
"make_tag_target_model_mixin",
|
|
52
53
|
"make_tag_record_model_mixin",
|
|
@@ -356,6 +357,23 @@ def predefined_tagsets() -> dict[str, Tagset]:
|
|
|
356
357
|
return tagsets
|
|
357
358
|
|
|
358
359
|
|
|
360
|
+
def seek_predefined_tagset_of(
|
|
361
|
+
tag: str | Tag | BoundTag,
|
|
362
|
+
*,
|
|
363
|
+
tagset_namespace: str | None = None,
|
|
364
|
+
tagset_version: str | None = None,
|
|
365
|
+
) -> Tagset | None:
|
|
366
|
+
if isinstance(tag, BoundTag):
|
|
367
|
+
versioned_namespace = versioned_identifier(tagset_namespace or tag.namespace, tagset_version or tag.version)
|
|
368
|
+
else:
|
|
369
|
+
versioned_namespace = versioned_identifier(tagset_namespace, tagset_version)
|
|
370
|
+
|
|
371
|
+
tagset = predefined_tagsets().get(versioned_namespace)
|
|
372
|
+
if tagset is None or tag not in tagset:
|
|
373
|
+
return None
|
|
374
|
+
return tagset
|
|
375
|
+
|
|
376
|
+
|
|
359
377
|
def render_tagset_markdown_readme(tagset: Tagset) -> str:
|
|
360
378
|
def render_desc(desc: str | RichDesc | None) -> str:
|
|
361
379
|
if desc is None:
|
|
@@ -628,6 +646,16 @@ def tag_cache_file_path() -> pathlib.Path:
|
|
|
628
646
|
return pathlib.Path.home() / ".local" / "plexus" / "tag_cache" / f"{randomizer().random_alphanumeric(7)}.db"
|
|
629
647
|
|
|
630
648
|
|
|
649
|
+
tag_cache_strict_mode_env = "PULSE_TAG_CACHE_STRICT_MODE"
|
|
650
|
+
|
|
651
|
+
|
|
652
|
+
def is_tag_cache_strict_mode() -> bool:
|
|
653
|
+
value = os.environ.get(tag_cache_strict_mode_env)
|
|
654
|
+
if value is None:
|
|
655
|
+
return False
|
|
656
|
+
return parse_bool_or(value) or False
|
|
657
|
+
|
|
658
|
+
|
|
631
659
|
class TagCache(object):
|
|
632
660
|
def __init__(
|
|
633
661
|
self,
|
|
@@ -1089,6 +1117,13 @@ class TagCache(object):
|
|
|
1089
1117
|
instance, this parameter will be ignored and the version from the instance will be used.
|
|
1090
1118
|
:return: Self instance for chaining along with the added ``TagRecordTable`` instance
|
|
1091
1119
|
"""
|
|
1120
|
+
if is_tag_cache_strict_mode():
|
|
1121
|
+
tagset = seek_predefined_tagset_of(tag, tagset_namespace=tagset_namespace, tagset_version=tagset_version)
|
|
1122
|
+
if tagset is None:
|
|
1123
|
+
raise ValueError(
|
|
1124
|
+
f"cannot find in the predefined tagset the specified tag '{tag}', with namespace '{tagset_namespace}' and version '{tagset_version}'"
|
|
1125
|
+
)
|
|
1126
|
+
|
|
1092
1127
|
with self.make_session() as session:
|
|
1093
1128
|
tag_record = TagRecord(
|
|
1094
1129
|
target_sqn=target_sqn,
|
{plexus_python_pulse_common-1.1.77.dist-info → plexus_python_pulse_common-1.1.79.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plexus-python-pulse-common
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.79
|
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.12
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.13
|
|
@@ -16,12 +16,14 @@ Requires-Dist: jsonschema>=4.0
|
|
|
16
16
|
Requires-Dist: lxml>=6.0
|
|
17
17
|
Requires-Dist: markdown-it-py>=4.0
|
|
18
18
|
Requires-Dist: numpy>=2.3
|
|
19
|
+
Requires-Dist: packaging>=25.0
|
|
19
20
|
Requires-Dist: pydantic>=2.8
|
|
20
21
|
Requires-Dist: pygeodesy>=24.10
|
|
21
22
|
Requires-Dist: pyparsing>=3.2
|
|
22
23
|
Requires-Dist: pyproj>=3.6
|
|
23
24
|
Requires-Dist: pyquaternion>=0.9
|
|
24
25
|
Requires-Dist: pyyaml>=6.0
|
|
26
|
+
Requires-Dist: requests>=2.0
|
|
25
27
|
Requires-Dist: sqlalchemy>=2.0
|
|
26
28
|
Requires-Dist: s3fs>=2025.10
|
|
27
29
|
Requires-Dist: rich>=13.9
|
{plexus_python_pulse_common-1.1.77.dist-info → plexus_python_pulse_common-1.1.79.dist-info}/RECORD
RENAMED
|
@@ -14,7 +14,7 @@ plexus/pulse/common/utils/bagutils.py,sha256=5JGnMgR8Q9OciW5dE7_2U7n1FGVEXMZXv1S
|
|
|
14
14
|
plexus/pulse/common/utils/config.py,sha256=YPtFK5QHTVsXwcFBGV0rlZad0GFtsgwysQNyKYjdzvk,2409
|
|
15
15
|
plexus/pulse/common/utils/datautils.py,sha256=OWlnyFSa6UaPbSSG3HzCJHxdiHyfHAE-FUVHaLfNZoM,9335
|
|
16
16
|
plexus/pulse/common/utils/dockerutils.py,sha256=7DF9yFGz8uHwpYk115xBWqOjs5etz0UE7yh66eDvBzs,5793
|
|
17
|
-
plexus/pulse/common/utils/flowutils.py,sha256=
|
|
17
|
+
plexus/pulse/common/utils/flowutils.py,sha256=MGu15KL9mw-LyGGLceVmY-c2FGer5PURnMZWFSJN--I,10182
|
|
18
18
|
plexus/pulse/common/utils/gisutils.py,sha256=UX_IHPeAx9mbA9p_SsbPFwdsdp7bGeaQhWaCTCzvrBM,11466
|
|
19
19
|
plexus/pulse/common/utils/jsonutils.py,sha256=zSbW94klN2jrkMdBECu4RNJX6zzNaSxauQ3FuihuB6E,3342
|
|
20
20
|
plexus/pulse/common/utils/ormutils.py,sha256=JD-hKLEGkFWy7ojc3dC_90qtexe2UnLEvD90tEOHtCg,61897
|
|
@@ -22,9 +22,9 @@ plexus/pulse/common/utils/pathutils.py,sha256=S5xk2WEmxP8MiuSKIU3cAEtk4Nk5Lz7IqC
|
|
|
22
22
|
plexus/pulse/common/utils/s3utils.py,sha256=RArl95rWoyBEFyWU9X0c8WgoQBjP_jOK3OkPoKxIMnA,36025
|
|
23
23
|
plexus/pulse/common/utils/sqlutils.py,sha256=D6kTBjhO5YlNRt3uFlPt6z3uH61m9ajEzPYmsI6NoFc,231
|
|
24
24
|
plexus/pulse/common/utils/strutils.py,sha256=PkmMHCcHN9vALCy_8fJTf00Dg7I2N4QTCXdBmB3t7rk,16440
|
|
25
|
-
plexus/pulse/common/utils/tagutils.py,sha256
|
|
25
|
+
plexus/pulse/common/utils/tagutils.py,sha256=-7cZWVpmtI7R8bB-SBtHPw4WyYJKp8AptH_Rfc-5sk4,62938
|
|
26
26
|
plexus/pulse/common/utils/testutils.py,sha256=hKPRvoN4mg8QGQJH121l59a0uo8jN5rntGQAVYplGBw,6166
|
|
27
|
-
plexus_python_pulse_common-1.1.
|
|
28
|
-
plexus_python_pulse_common-1.1.
|
|
29
|
-
plexus_python_pulse_common-1.1.
|
|
30
|
-
plexus_python_pulse_common-1.1.
|
|
27
|
+
plexus_python_pulse_common-1.1.79.dist-info/METADATA,sha256=yWNshrrquuxOYcZVF9KyXRMxqqTUZVOviSYLaapI_Co,1555
|
|
28
|
+
plexus_python_pulse_common-1.1.79.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
29
|
+
plexus_python_pulse_common-1.1.79.dist-info/top_level.txt,sha256=ug_g7CVwaMQuas5UzAXbHUrQvKGCn8ezc6ZNvvRlJOE,7
|
|
30
|
+
plexus_python_pulse_common-1.1.79.dist-info/RECORD,,
|
{plexus_python_pulse_common-1.1.77.dist-info → plexus_python_pulse_common-1.1.79.dist-info}/WHEEL
RENAMED
|
File without changes
|
|
File without changes
|