plexus-python-common 1.0.71__tar.gz → 1.0.73__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.
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/PKG-INFO +1 -1
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/tagutils.py +69 -76
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus_python_common.egg-info/PKG-INFO +1 -1
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/tagutils_test.py +10 -8
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/.editorconfig +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/.github/workflows/pr.yml +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/.github/workflows/push.yml +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/.gitignore +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/MANIFEST.in +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/README.md +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/VERSION +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/pyproject.toml +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/jsonutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/jsonutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/jsonutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/0-dummy +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/1-dummy +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/2-dummy +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.0.0.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.0.0.vol-0.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.0.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.1.1.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.1.1.vol-1.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.1.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.2.2.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.2.2.vol-2.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.2.jsonl +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.csv.part0 +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.csv.part1 +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.csv.part2 +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.txt +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils/dir.baz/file.bar.baz +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils/dir.baz/file.foo.bar +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils/dir.baz/file.foo.baz +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils/dir.foo/file.bar +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils/dir.foo/file.baz +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils/dir.foo/file.foo +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils_archive/archive.compressed.zip +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/s3utils_archive/archive.uncompressed.zip +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/setup.cfg +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/setup.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/__init__.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/carto/OSMFile.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/carto/OSMNode.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/carto/OSMTags.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/carto/OSMWay.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/carto/__init__.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/resources/__init__.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/resources/tags/__init__.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/resources/tags/unittest-1.0.0.tagset.yaml +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/resources/tags/universal-1.0.0.tagset.yaml +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/__init__.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/apiutils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/bagutils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/config.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/datautils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/dockerutils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/gisutils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/jsonutils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/ormutils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/pathutils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/s3utils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/sqlutils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/strutils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/testutils.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus_python_common.egg-info/SOURCES.txt +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus_python_common.egg-info/dependency_links.txt +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus_python_common.egg-info/not-zip-safe +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus_python_common.egg-info/requires.txt +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus_python_common.egg-info/top_level.txt +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/__init__.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/__init__.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/carto/__init__.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/carto/osm_file_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/carto/osm_tags_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/__init__.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/bagutils_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/datautils_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/dockerutils_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/gisutils_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/jsonutils_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/ormutils_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/pathutils_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/s3utils_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/strutils_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/utils/testutils_test.py +0 -0
- {plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/testenv.py +0 -0
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/tagutils.py
RENAMED
|
@@ -84,11 +84,11 @@ class Tag(object):
|
|
|
84
84
|
def unbind(self) -> Self:
|
|
85
85
|
return self
|
|
86
86
|
|
|
87
|
-
def validate(self,
|
|
88
|
-
if self.schema is None or
|
|
87
|
+
def validate(self, features: JsonType | None, *, raise_on_error: bool = False) -> bool:
|
|
88
|
+
if self.schema is None or features is None:
|
|
89
89
|
return True
|
|
90
90
|
try:
|
|
91
|
-
jsonschema.Draft7Validator(self.schema).validate(
|
|
91
|
+
jsonschema.Draft7Validator(self.schema).validate(features)
|
|
92
92
|
return True
|
|
93
93
|
except (jsonschema.ValidationError, jsonschema.SchemaError):
|
|
94
94
|
if raise_on_error:
|
|
@@ -178,9 +178,9 @@ class Tagset(Sequence[Tag], Mapping[str, Tag]):
|
|
|
178
178
|
return []
|
|
179
179
|
return list(dicttree_lineage(self.tags_tree, child.tag_parts[:-1]))
|
|
180
180
|
|
|
181
|
-
def validate(self, tag_name: str,
|
|
181
|
+
def validate(self, tag_name: str, features: JsonType | None, *, raise_on_error: bool = False) -> bool:
|
|
182
182
|
tag = self.get(tag_name)
|
|
183
|
-
return False if tag is None else tag.validate(
|
|
183
|
+
return False if tag is None else tag.validate(features, raise_on_error=raise_on_error)
|
|
184
184
|
|
|
185
185
|
|
|
186
186
|
class MutableTagset(Tagset):
|
|
@@ -491,6 +491,11 @@ def make_tag_record_model_mixin() -> type[pdt.BaseModel]:
|
|
|
491
491
|
sa_column=sa.Column(sa_sqlite.VARCHAR(256), nullable=False),
|
|
492
492
|
description="Tag name",
|
|
493
493
|
)
|
|
494
|
+
features: JsonType | None = Field(
|
|
495
|
+
sa_column=sa.Column(sa_sqlite.JSON, nullable=True),
|
|
496
|
+
default=None,
|
|
497
|
+
description="Tag features in JSON format, which can be used for storing preprocessed information of the tag record to facilitate querying and filtering",
|
|
498
|
+
)
|
|
494
499
|
props: JsonType | None = Field(
|
|
495
500
|
sa_column=sa.Column(sa_sqlite.JSON, nullable=True),
|
|
496
501
|
default=None,
|
|
@@ -592,6 +597,7 @@ if typing.TYPE_CHECKING:
|
|
|
592
597
|
tagset_namespace: sa_orm.Mapped[str | None] = ...
|
|
593
598
|
tagset_version: sa_orm.Mapped[str | None] = ...
|
|
594
599
|
tag: sa_orm.Mapped[str] = ...
|
|
600
|
+
features: sa_orm.Mapped[JsonType | None] = ...
|
|
595
601
|
props: sa_orm.Mapped[JsonType | None] = ...
|
|
596
602
|
flags: sa_orm.Mapped[int] = ...
|
|
597
603
|
|
|
@@ -676,7 +682,21 @@ class TagCache(object):
|
|
|
676
682
|
begin_dt: datetime.datetime,
|
|
677
683
|
end_dt: datetime.datetime,
|
|
678
684
|
props: JsonType | None = None,
|
|
679
|
-
) -> TagTargetTable:
|
|
685
|
+
) -> Chainable[Self, TagTargetTable]:
|
|
686
|
+
"""
|
|
687
|
+
Create a new tag target and add it to the cache.
|
|
688
|
+
|
|
689
|
+
:param identifier: Identifier of the tag target, which should be unique across the cache. It is recommended
|
|
690
|
+
to use a slash tag (e.g. "dummy_name/dummy_name") to ensure uniqueness and facilitate
|
|
691
|
+
organization, but other formats are also allowed as long as they are valid slash tags.
|
|
692
|
+
:param tagger_name: Name of the tagger creating the tag target.
|
|
693
|
+
:param tagger_version: Version of the tagger creating the tag target.
|
|
694
|
+
:param vehicle_name: Name of the vehicle associated with the tag target.
|
|
695
|
+
:param begin_dt: Start datetime for the tag target's validity period.
|
|
696
|
+
:param end_dt: End datetime for the tag target's validity period.
|
|
697
|
+
:param props: Additional properties for the tag target.
|
|
698
|
+
:return: Self instance for chaining along with the added ``TagTargetTable`` instance
|
|
699
|
+
"""
|
|
680
700
|
with self.make_session() as session:
|
|
681
701
|
tag_target = TagTarget(
|
|
682
702
|
identifier=identifier,
|
|
@@ -691,7 +711,7 @@ class TagCache(object):
|
|
|
691
711
|
session.add(db_tag_target)
|
|
692
712
|
session.commit()
|
|
693
713
|
|
|
694
|
-
return self
|
|
714
|
+
return chainable(self, db_tag_target)
|
|
695
715
|
|
|
696
716
|
def remove_targets(
|
|
697
717
|
self,
|
|
@@ -701,7 +721,23 @@ class TagCache(object):
|
|
|
701
721
|
vehicle_name: str | None = None,
|
|
702
722
|
begin_dt: datetime.datetime | None = None,
|
|
703
723
|
end_dt: datetime.datetime | None = None,
|
|
724
|
+
*,
|
|
725
|
+
cascade_records: bool = True,
|
|
704
726
|
):
|
|
727
|
+
"""
|
|
728
|
+
Remove tag targets from the cache that match the specified filters.
|
|
729
|
+
|
|
730
|
+
:param identifier: Filter by target identifier (exact match)
|
|
731
|
+
:param tagger_name: Filter by tagger name (exact match)
|
|
732
|
+
:param tagger_version: Filter by tagger version (exact match)
|
|
733
|
+
:param vehicle_name: Filter by vehicle name (exact match)
|
|
734
|
+
:param begin_dt: Filter by begin time (inclusive)
|
|
735
|
+
:param end_dt: Filter by end time (inclusive)
|
|
736
|
+
:param cascade_records: Whether to also remove tag records that are associated with the removed targets.
|
|
737
|
+
If False, the tag records will be kept but become orphaned (i.e. their ``target_sqn``
|
|
738
|
+
will not have a corresponding target in the cache).
|
|
739
|
+
:return: Self for chaining
|
|
740
|
+
"""
|
|
705
741
|
with self.make_session() as session:
|
|
706
742
|
query_stmt = session.query(TagTargetTable)
|
|
707
743
|
if identifier:
|
|
@@ -720,13 +756,16 @@ class TagCache(object):
|
|
|
720
756
|
query_stmt.delete()
|
|
721
757
|
session.commit()
|
|
722
758
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
759
|
+
if cascade_records:
|
|
760
|
+
(
|
|
761
|
+
session
|
|
762
|
+
.query(TagRecordTable)
|
|
763
|
+
.filter(TagRecordTable.target_sqn.notin_(session.query(TagTargetTable.sqn)))
|
|
764
|
+
.delete()
|
|
765
|
+
)
|
|
766
|
+
session.commit()
|
|
767
|
+
|
|
768
|
+
return self
|
|
730
769
|
|
|
731
770
|
def with_target(self, target: int | str) -> "TargetedTagCache":
|
|
732
771
|
db_tag_target = self.get_target(target)
|
|
@@ -1010,6 +1049,7 @@ class TagCache(object):
|
|
|
1010
1049
|
begin_dt: datetime.datetime,
|
|
1011
1050
|
end_dt: datetime.datetime,
|
|
1012
1051
|
tag: str | Tag | BoundTag,
|
|
1052
|
+
features: JsonType | None = None,
|
|
1013
1053
|
props: JsonType | None = None,
|
|
1014
1054
|
tagset_namespace: str | None = None,
|
|
1015
1055
|
tagset_version: str | None = None,
|
|
@@ -1022,6 +1062,8 @@ class TagCache(object):
|
|
|
1022
1062
|
:param end_dt: End datetime of the tag record
|
|
1023
1063
|
:param tag: Tag name or ``Tag``/``BoundTag`` instance to be added. If ``Tag``/``BoundTag`` instance is provided,
|
|
1024
1064
|
its name will be used.
|
|
1065
|
+
:param features: Additional tag features of the tag record in JSON format (optional), which can be used for
|
|
1066
|
+
storing preprocessed information of the tag record to facilitate querying and filtering.
|
|
1025
1067
|
:param props: Additional properties of the tag record in JSON format (optional)
|
|
1026
1068
|
:param tagset_namespace: Namespace of the tagset that the tag belongs to. If the ``tag`` parameter is a
|
|
1027
1069
|
``BoundTag`` instance, this parameter will be ignored and the namespace from the
|
|
@@ -1038,6 +1080,7 @@ class TagCache(object):
|
|
|
1038
1080
|
tagset_namespace=tag.namespace if isinstance(tag, BoundTag) else tagset_namespace,
|
|
1039
1081
|
tagset_version=tag.version if isinstance(tag, BoundTag) else tagset_version,
|
|
1040
1082
|
tag=tag.name if isinstance(tag, Tag) else tag,
|
|
1083
|
+
features=features,
|
|
1041
1084
|
props=props,
|
|
1042
1085
|
)
|
|
1043
1086
|
db_tag_record = clone_sequence_model_instance(TagRecordTable, tag_record)
|
|
@@ -1054,6 +1097,7 @@ class TagCache(object):
|
|
|
1054
1097
|
begin_dt: datetime.datetime | None = None,
|
|
1055
1098
|
end_dt: datetime.datetime | None = None,
|
|
1056
1099
|
tag: str | Tag | BoundTag | None = None,
|
|
1100
|
+
features: JsonType | None = None,
|
|
1057
1101
|
props: JsonType | None = None,
|
|
1058
1102
|
tagset_namespace: str | None = None,
|
|
1059
1103
|
tagset_version: str | None = None,
|
|
@@ -1068,6 +1112,8 @@ class TagCache(object):
|
|
|
1068
1112
|
:param end_dt: New end datetime of the tag record (optional)
|
|
1069
1113
|
:param tag: New tag name or ``Tag``/``BoundTag`` instance to be updated (optional). If ``Tag``/``BoundTag``
|
|
1070
1114
|
instance is provided, its name will be used.
|
|
1115
|
+
:param features: Additional tag features of the tag record in JSON format (optional), which can be used for
|
|
1116
|
+
storing preprocessed information of the tag record to facilitate querying and filtering.
|
|
1071
1117
|
:param props: New additional properties of the tag record in JSON format (optional)
|
|
1072
1118
|
:param tagset_namespace: New namespace of the tagset that the tag belongs to (optional). If the ``tag``
|
|
1073
1119
|
parameter is a ``BoundTag`` instance, this parameter will be ignored and the namespace
|
|
@@ -1082,7 +1128,7 @@ class TagCache(object):
|
|
|
1082
1128
|
db_tag_record = (
|
|
1083
1129
|
session
|
|
1084
1130
|
.query(TagRecordTable)
|
|
1085
|
-
.filter(
|
|
1131
|
+
.filter(TagRecordTable.target_sqn == target_sqn, TagRecordTable.sqn == sqn)
|
|
1086
1132
|
.one_or_none()
|
|
1087
1133
|
)
|
|
1088
1134
|
if not db_tag_record:
|
|
@@ -1098,6 +1144,8 @@ class TagCache(object):
|
|
|
1098
1144
|
db_tag_record.tagset_version = tag.version if isinstance(tag, BoundTag) else tagset_version
|
|
1099
1145
|
if tag is not None:
|
|
1100
1146
|
db_tag_record.tag = tag.name if isinstance(tag, Tag) else tag
|
|
1147
|
+
if features is not None:
|
|
1148
|
+
db_tag_record.features = features
|
|
1101
1149
|
if props is not None:
|
|
1102
1150
|
db_tag_record.props = props
|
|
1103
1151
|
if flags is not None:
|
|
@@ -1251,31 +1299,17 @@ class TargetedTagCache(object):
|
|
|
1251
1299
|
begin_dt: datetime.datetime | None,
|
|
1252
1300
|
end_dt: datetime.datetime | None,
|
|
1253
1301
|
tag: str | Tag | BoundTag,
|
|
1302
|
+
features: JsonType | None = None,
|
|
1254
1303
|
props: JsonType | None = None,
|
|
1255
1304
|
tagset_namespace: str | None = None,
|
|
1256
1305
|
tagset_version: str | None = None,
|
|
1257
1306
|
) -> Chainable[Self, TagRecordTable]:
|
|
1258
|
-
"""
|
|
1259
|
-
Add a tag record to the cache for the specified time range. If ``begin_dt`` or ``end_dt`` is None, it will
|
|
1260
|
-
default to the target's ``begin_dt`` or ``end_dt`` respectively.
|
|
1261
|
-
|
|
1262
|
-
:param begin_dt: Begin datetime of the tag record
|
|
1263
|
-
:param end_dt: End datetime of the tag record
|
|
1264
|
-
:param tag: Tag name or ``Tag``/``BoundTag`` instance to be added. If ``Tag``/``BoundTag`` instance is provided,
|
|
1265
|
-
its name will be used.
|
|
1266
|
-
:param props: Additional properties of the tag record in JSON format (optional)
|
|
1267
|
-
:param tagset_namespace: Namespace of the tagset that the tag belongs to. If the ``tag`` parameter is a
|
|
1268
|
-
``BoundTag`` instance, this parameter will be ignored and the namespace from the
|
|
1269
|
-
instance will be used.
|
|
1270
|
-
:param tagset_version: Version of the tagset that the tag belongs to. If the ``tag`` parameter is a ``BoundTag``
|
|
1271
|
-
instance, this parameter will be ignored and the version from the instance will be used.
|
|
1272
|
-
:return: Self instance for chaining along with the added ``TagRecordTable`` instance
|
|
1273
|
-
"""
|
|
1274
1307
|
result = self.cache.target_add_record(
|
|
1275
1308
|
target_sqn=self.tag_target.sqn,
|
|
1276
1309
|
begin_dt=begin_dt or self.tag_target.begin_dt,
|
|
1277
1310
|
end_dt=end_dt or self.tag_target.end_dt,
|
|
1278
1311
|
tag=tag,
|
|
1312
|
+
features=features,
|
|
1279
1313
|
props=props,
|
|
1280
1314
|
tagset_namespace=tagset_namespace,
|
|
1281
1315
|
tagset_version=tagset_version,
|
|
@@ -1285,28 +1319,16 @@ class TargetedTagCache(object):
|
|
|
1285
1319
|
def add_record(
|
|
1286
1320
|
self,
|
|
1287
1321
|
tag: str | Tag | BoundTag,
|
|
1322
|
+
features: JsonType | None = None,
|
|
1288
1323
|
props: JsonType | None = None,
|
|
1289
1324
|
tagset_namespace: str | None = None,
|
|
1290
1325
|
tagset_version: str | None = None,
|
|
1291
1326
|
) -> Chainable[Self, TagRecordTable]:
|
|
1292
|
-
"""
|
|
1293
|
-
Add a tag record to the cache for the entire target range.
|
|
1294
|
-
|
|
1295
|
-
:param tag: Tag name or ``Tag``/``BoundTag`` instance to be added. If ``Tag``/``BoundTag`` instance is provided,
|
|
1296
|
-
its name will be used.
|
|
1297
|
-
:param props: Additional properties of the tag record in JSON format (optional)
|
|
1298
|
-
:param tagset_namespace: Namespace of the tagset that the tag belongs to. If the ``tag`` parameter is a
|
|
1299
|
-
``BoundTag`` instance, this parameter will be ignored and the namespace from the
|
|
1300
|
-
instance will be used.
|
|
1301
|
-
:param tagset_version: Version of the tagset that the tag belongs to. If the ``tag`` parameter is a
|
|
1302
|
-
``BoundTag`` instance, this parameter will be ignored and the version from the instance
|
|
1303
|
-
will be used.
|
|
1304
|
-
:return: Self instance for chaining along with the added ``TagRecordTable`` instance
|
|
1305
|
-
"""
|
|
1306
1327
|
result = self.add_ranged_record(
|
|
1307
1328
|
begin_dt=self.tag_target.begin_dt,
|
|
1308
1329
|
end_dt=self.tag_target.end_dt,
|
|
1309
1330
|
tag=tag,
|
|
1331
|
+
features=features,
|
|
1310
1332
|
tagset_namespace=tagset_namespace,
|
|
1311
1333
|
tagset_version=tagset_version,
|
|
1312
1334
|
props=props,
|
|
@@ -1320,35 +1342,19 @@ class TargetedTagCache(object):
|
|
|
1320
1342
|
begin_dt: datetime.datetime | None = None,
|
|
1321
1343
|
end_dt: datetime.datetime | None = None,
|
|
1322
1344
|
tag: str | Tag | BoundTag | None = None,
|
|
1345
|
+
features: JsonType | None = None,
|
|
1323
1346
|
props: JsonType | None = None,
|
|
1324
1347
|
tagset_namespace: str | None = None,
|
|
1325
1348
|
tagset_version: str | None = None,
|
|
1326
1349
|
flags: int | None = None,
|
|
1327
1350
|
) -> Chainable[Self, TagRecordTable]:
|
|
1328
|
-
"""
|
|
1329
|
-
Update a tag record in the cache by its sequence number.
|
|
1330
|
-
|
|
1331
|
-
:param sqn: Sequence number of the tag record to be updated
|
|
1332
|
-
:param begin_dt: New begin datetime of the tag record (optional)
|
|
1333
|
-
:param end_dt: New end datetime of the tag record (optional)
|
|
1334
|
-
:param tag: New tag name or ``Tag``/``BoundTag`` instance to be updated (optional). If ``Tag``/``BoundTag``
|
|
1335
|
-
instance is provided, its name will be used.
|
|
1336
|
-
:param props: New additional properties of the tag record in JSON format (optional)
|
|
1337
|
-
:param tagset_namespace: New namespace of the tagset that the tag belongs to (optional). If the ``tag``
|
|
1338
|
-
parameter is a ``BoundTag`` instance, this parameter will be ignored and the namespace
|
|
1339
|
-
from the instance will be used.
|
|
1340
|
-
:param tagset_version: New version of the tagset that the tag belongs to (optional). If the ``tag`` parameter
|
|
1341
|
-
is a ``BoundTag`` instance, this parameter will be ignored and the version from the
|
|
1342
|
-
instance will be used.
|
|
1343
|
-
:param flags: New integer bitmask storing status or metadata flags for this tag record (optional)
|
|
1344
|
-
:return: Self instance for chaining along with the updated ``TagRecordTable`` instance
|
|
1345
|
-
"""
|
|
1346
1351
|
result = self.cache.target_update_record(
|
|
1347
1352
|
self.tag_target.sqn,
|
|
1348
1353
|
sqn,
|
|
1349
1354
|
begin_dt=begin_dt,
|
|
1350
1355
|
end_dt=end_dt,
|
|
1351
1356
|
tag=tag,
|
|
1357
|
+
features=features,
|
|
1352
1358
|
props=props,
|
|
1353
1359
|
tagset_namespace=tagset_namespace,
|
|
1354
1360
|
tagset_version=tagset_version,
|
|
@@ -1367,19 +1373,6 @@ class TargetedTagCache(object):
|
|
|
1367
1373
|
tagsets: Sequence[Tagset] | None = None,
|
|
1368
1374
|
tagset_inverted: bool = False,
|
|
1369
1375
|
) -> Self:
|
|
1370
|
-
"""
|
|
1371
|
-
Remove tag records from the cache that match the specified filters.
|
|
1372
|
-
|
|
1373
|
-
:param begin_dt: Filter by begin time (inclusive)
|
|
1374
|
-
:param end_dt: Filter by end time (inclusive)
|
|
1375
|
-
:param tagset_namespace: Filter by tagset namespace (exact match)
|
|
1376
|
-
:param tagset_version: Filter by tagset version (exact match)
|
|
1377
|
-
:param tag_prefix: Filter by tag name prefix, e.g. "dummy_tag:" to match all tags starting with "dummy_tag:"
|
|
1378
|
-
:param tagsets: Filter by tagsets (match tags that are in any of the specified tagsets)
|
|
1379
|
-
:param tagset_inverted: Whether to invert the tagset filter (match tags that are NOT in any of the specified
|
|
1380
|
-
tagsets)
|
|
1381
|
-
:return: Self instance for chaining
|
|
1382
|
-
"""
|
|
1383
1376
|
self.cache.target_remove_records(
|
|
1384
1377
|
self.tag_target.sqn,
|
|
1385
1378
|
begin_dt=begin_dt,
|
|
@@ -86,15 +86,15 @@ class TagUtilsTest(unittest.TestCase):
|
|
|
86
86
|
|
|
87
87
|
@ddt.idata(data_tag_validate)
|
|
88
88
|
@ddt.unpack
|
|
89
|
-
def test_tagset_validate(self, tag: str,
|
|
89
|
+
def test_tagset_validate(self, tag: str, features: JsonObject, should_pass: bool):
|
|
90
90
|
tagset = predefined_tagsets().get("unittest")
|
|
91
91
|
|
|
92
92
|
if should_pass:
|
|
93
|
-
self.assertTrue(tagset.validate(tag,
|
|
93
|
+
self.assertTrue(tagset.validate(tag, features))
|
|
94
94
|
else:
|
|
95
|
-
self.assertFalse(tagset.validate(tag,
|
|
95
|
+
self.assertFalse(tagset.validate(tag, features))
|
|
96
96
|
with self.assertRaises(Exception):
|
|
97
|
-
tagset.validate(tag,
|
|
97
|
+
tagset.validate(tag, features, raise_on_error=True)
|
|
98
98
|
|
|
99
99
|
def test_tag_cache(self):
|
|
100
100
|
tag_names = [
|
|
@@ -122,7 +122,7 @@ class TagUtilsTest(unittest.TestCase):
|
|
|
122
122
|
"dummy_vehicle",
|
|
123
123
|
dt_parse_iso("2020-01-01T00:00:00+00:00"),
|
|
124
124
|
dt_parse_iso("2020-01-01T01:00:00+00:00"),
|
|
125
|
-
{"dummy_target_prop": "dummy_value"})
|
|
125
|
+
props={"dummy_target_prop": "dummy_value"})
|
|
126
126
|
|
|
127
127
|
target_cache = cache.with_target("awesome_tagger/20200101_000000/dummy_vehicle/0")
|
|
128
128
|
|
|
@@ -135,7 +135,7 @@ class TagUtilsTest(unittest.TestCase):
|
|
|
135
135
|
dt_parse_iso("2020-01-01T00:00:00+00:00") + datetime.timedelta(seconds=i),
|
|
136
136
|
dt_parse_iso("2020-01-02T00:00:00+00:00") + datetime.timedelta(seconds=i + 1),
|
|
137
137
|
tag,
|
|
138
|
-
|
|
138
|
+
features={
|
|
139
139
|
"dummy_int": 1,
|
|
140
140
|
"dummy_float": 1.0e-1,
|
|
141
141
|
"dummy_bool": True,
|
|
@@ -148,6 +148,7 @@ class TagUtilsTest(unittest.TestCase):
|
|
|
148
148
|
"dummy_str": "dummy_string",
|
|
149
149
|
},
|
|
150
150
|
},
|
|
151
|
+
props={"dummy_record_prop": "dummy_value"},
|
|
151
152
|
)
|
|
152
153
|
|
|
153
154
|
self.assertEqual(target_cache.count_records(), tag_records_count)
|
|
@@ -277,7 +278,7 @@ class TagUtilsTest(unittest.TestCase):
|
|
|
277
278
|
"dummy_vehicle",
|
|
278
279
|
dt_parse_iso("2020-01-01T00:00:00+00:00"),
|
|
279
280
|
dt_parse_iso("2020-01-01T01:00:00+00:00"),
|
|
280
|
-
{"dummy_target_prop": "dummy_value"})
|
|
281
|
+
props={"dummy_target_prop": "dummy_value"})
|
|
281
282
|
|
|
282
283
|
target_caches = [cache.with_target(f"concurrent_tagger/20200101_000000/dummy_vehicle/{i}")
|
|
283
284
|
for i in range(target_caches_count)]
|
|
@@ -301,7 +302,7 @@ class TagUtilsTest(unittest.TestCase):
|
|
|
301
302
|
dt_parse_iso("2020-01-01T00:00:00+00:00") + datetime.timedelta(seconds=i),
|
|
302
303
|
dt_parse_iso("2020-01-02T00:00:00+00:00") + datetime.timedelta(seconds=i + 1),
|
|
303
304
|
tag,
|
|
304
|
-
|
|
305
|
+
features={
|
|
305
306
|
"dummy_int": 1,
|
|
306
307
|
"dummy_float": 1.0e-1,
|
|
307
308
|
"dummy_bool": True,
|
|
@@ -314,6 +315,7 @@ class TagUtilsTest(unittest.TestCase):
|
|
|
314
315
|
"dummy_str": "dummy_string",
|
|
315
316
|
},
|
|
316
317
|
},
|
|
318
|
+
props={"dummy_record_prop": "dummy_value"},
|
|
317
319
|
)
|
|
318
320
|
|
|
319
321
|
threads = [threading.Thread(target=worker, args=(tid,)) for tid in range(total_threads_count)]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/0-dummy
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/1-dummy
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/2-dummy
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/resources/unittest/pathutils/dummy.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/carto/OSMFile.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/carto/OSMNode.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/carto/OSMTags.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/carto/OSMWay.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/carto/__init__.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/resources/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/__init__.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/apiutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/bagutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/config.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/datautils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/dockerutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/gisutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/jsonutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/ormutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/pathutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/s3utils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/sqlutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/strutils.py
RENAMED
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/src/plexus/common/utils/testutils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{plexus_python_common-1.0.71 → plexus_python_common-1.0.73}/test/plexus_tests/common/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|