liminal-orm 2.0.3a1__tar.gz → 3.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.
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/PKG-INFO +1 -1
- liminal_orm-3.0.0/liminal/.DS_Store +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/__init__.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/base.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/base_dropdown.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/base_operation.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/base_validation_filters.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/benchling_base_model.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/benchling_column.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/benchling_dropdown.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/benchling_field_properties.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/benchling_schema_properties.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/callable_operation.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/column.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/compare_operation.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/field_properties.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/name_template_components.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/name_template_parts.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/schema_properties.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/str_enum.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/unset.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/__pycache__/user.cpython-310.pyc +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/base/base_operation.py +7 -7
- liminal_orm-3.0.0/liminal/base/properties/__pycache__/NoDropdown.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/properties/__pycache__/__init__.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/properties/__pycache__/base_field_properties.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/properties/__pycache__/base_name_template.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/properties/__pycache__/base_schema_properties.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/properties/__pycache__/field_properties.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/base/properties/__pycache__/schema_properties.cpython-310.pyc +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/base/properties/base_field_properties.py +3 -1
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/base/properties/base_schema_properties.py +8 -2
- liminal_orm-3.0.0/liminal/cli/__pycache__/cli.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/cli/__pycache__/controller.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/cli/__pycache__/live_test_dropdown_migration.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/cli/__pycache__/live_test_entity_schema_migration.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/connection/__pycache__/__init__.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/connection/__pycache__/benchling_connection.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/connection/__pycache__/benchling_service.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/dropdowns/__pycache__/api.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/dropdowns/__pycache__/compare.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/dropdowns/__pycache__/generate_files.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/dropdowns/__pycache__/operations.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/dropdowns/__pycache__/utils.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/entity_schemas/__pycache__/api.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/entity_schemas/__pycache__/compare.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/entity_schemas/__pycache__/entity_schema_models.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/entity_schemas/__pycache__/generate_files.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/entity_schemas/__pycache__/operations.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/entity_schemas/__pycache__/schemas.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/entity_schemas/__pycache__/tag_schema_models.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/entity_schemas/__pycache__/utils.cpython-310.pyc +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/entity_schemas/compare.py +40 -21
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/entity_schemas/entity_schema_models.py +40 -13
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/entity_schemas/generate_files.py +2 -2
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/entity_schemas/operations.py +61 -11
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/entity_schemas/tag_schema_models.py +72 -25
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/entity_schemas/utils.py +36 -9
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/enums/__init__.py +1 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/__init__.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/benchling_api_field_type.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/benchling_dropdown.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/benchling_entity_type.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/benchling_enum.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/benchling_field_api_type.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/benchling_field_type.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/benchling_folder_item_type.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/benchling_naming_strategy.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/benchling_report_level.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/benchling_sequence_type.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/name_template_part_type.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/sequence_constraint.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/sequence_constraints.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/str_enum.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/enums/__pycache__/undefined.cpython-310.pyc +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/enums/benchling_entity_type.py +9 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/enums/benchling_field_type.py +8 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/enums/benchling_naming_strategy.py +1 -0
- liminal_orm-3.0.0/liminal/enums/sequence_constraint.py +13 -0
- liminal_orm-3.0.0/liminal/external/__pycache__/__init__.cpython-310.pyc +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/mappers.py +8 -11
- liminal_orm-3.0.0/liminal/migrate/__pycache__/components.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/migrate/__pycache__/revision.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/migrate/__pycache__/revisions_timeline.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/migrate/__pycache__/utils.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/__pycache__/__init__.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/__pycache__/base.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/__pycache__/base_model.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/__pycache__/column.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/__pycache__/mixins.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/__pycache__/name_template.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/__pycache__/name_template_parts.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/__pycache__/relationship.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/__pycache__/schema_properties.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/__pycache__/user.cpython-310.pyc +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/base_model.py +46 -11
- liminal_orm-3.0.0/liminal/orm/base_tables/__pycache__/__init__.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/base_tables/__pycache__/registry_entity.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/base_tables/__pycache__/schema.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/orm/base_tables/__pycache__/user.cpython-310.pyc +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/column.py +23 -5
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/schema_properties.py +14 -5
- liminal_orm-3.0.0/liminal/tests/.DS_Store +0 -0
- liminal_orm-3.0.0/liminal/tests/__pycache__/__init__.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/tests/__pycache__/conftest.cpython-310-pytest-8.3.3.pyc +0 -0
- liminal_orm-3.0.0/liminal/tests/__pycache__/test_dropdown_compare.cpython-310-pytest-8.3.3.pyc +0 -0
- liminal_orm-3.0.0/liminal/tests/__pycache__/test_entity_schema_compare.cpython-310-pytest-8.3.3.pyc +0 -0
- liminal_orm-3.0.0/liminal/unit_dictionary/__pycache__/utils.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/unit_dictionary/utils.py +48 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/validation/__init__.py +2 -9
- liminal_orm-3.0.0/liminal/validation/__pycache__/__init__.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/validation/__pycache__/validation_report_level.cpython-310.pyc +0 -0
- liminal_orm-3.0.0/liminal/validation/__pycache__/validation_severity.cpython-310.pyc +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/pyproject.toml +1 -1
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/LICENSE.md +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/README.md +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/__init__.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/base/base_dropdown.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/base/base_validation_filters.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/base/compare_operation.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/base/name_template_parts.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/base/properties/base_name_template.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/base/str_enum.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/cli/cli.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/cli/controller.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/cli/live_test_dropdown_migration.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/cli/live_test_entity_schema_migration.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/connection/__init__.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/connection/benchling_connection.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/connection/benchling_service.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/dropdowns/api.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/dropdowns/compare.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/dropdowns/generate_files.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/dropdowns/operations.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/dropdowns/utils.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/entity_schemas/api.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/enums/benchling_api_field_type.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/enums/benchling_folder_item_type.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/enums/benchling_sequence_type.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/enums/name_template_part_type.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/external/__init__.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/migrate/components.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/migrate/revision.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/migrate/revisions_timeline.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/migrate/utils.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/base.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/base_tables/registry_entity.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/base_tables/schema.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/base_tables/user.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/mixins.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/name_template.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/name_template_parts.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/orm/relationship.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/py.typed +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/tests/__init__.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/tests/conftest.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/tests/from benchling_sdk.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/tests/test_dropdown_compare.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/tests/test_entity_schema_compare.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/utils.py +0 -0
- {liminal_orm-2.0.3a1 → liminal_orm-3.0.0}/liminal/validation/validation_severity.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: liminal-orm
|
3
|
-
Version:
|
3
|
+
Version: 3.0.0
|
4
4
|
Summary: An ORM and toolkit that builds on top of Benchling's platform to keep your schemas and downstream code dependencies in sync.
|
5
5
|
Home-page: https://github.com/dynotx/liminal-orm
|
6
6
|
Author: DynoTx Open Source
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -13,13 +13,13 @@ Order of operations based on order class var:
|
|
13
13
|
6. ArchiveDropdownOption
|
14
14
|
7. ReorderDropdownOptions
|
15
15
|
8. CreateSchema
|
16
|
-
9.
|
17
|
-
10.
|
18
|
-
11.
|
19
|
-
12.
|
20
|
-
13.
|
21
|
-
14.
|
22
|
-
15.
|
16
|
+
9. UnarchiveSchema
|
17
|
+
10. CreateField
|
18
|
+
11. UpdateEntitySchemaNameTemplate
|
19
|
+
12. UpdateSchema
|
20
|
+
13. UnarchiveField
|
21
|
+
14. UpdateField
|
22
|
+
15. ArchiveField
|
23
23
|
16. ReorderFields
|
24
24
|
17. ArchiveSchema
|
25
25
|
18. ArchiveDropdown
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -49,6 +49,8 @@ class BaseFieldProperties(BaseModel):
|
|
49
49
|
dropdown_link: str | None = None
|
50
50
|
entity_link: str | None = None
|
51
51
|
tooltip: str | None = None
|
52
|
+
decimal_places: int | None = None
|
53
|
+
unit_name: str | None = None
|
52
54
|
_archived: bool | None = PrivateAttr(default=None)
|
53
55
|
|
54
56
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
@@ -122,4 +124,4 @@ class BaseFieldProperties(BaseModel):
|
|
122
124
|
|
123
125
|
def __repr__(self) -> str:
|
124
126
|
"""Generates a string representation of the class so that it can be executed."""
|
125
|
-
return f"{self.__class__.__name__}({', '.join([f'{k}={v.__repr__()}' for k, v in self.model_dump(exclude_unset=True
|
127
|
+
return f"{self.__class__.__name__}({', '.join([f'{k}={v.__repr__()}' for k, v in self.model_dump(exclude_unset=True).items()])})"
|
@@ -66,8 +66,13 @@ class BaseSchemaProperties(BaseModel):
|
|
66
66
|
include_registry_id_in_chips : bool | None = None
|
67
67
|
Flag for configuring the chip label for entities. Determines if the chip will include the Registry ID in the chip label.
|
68
68
|
constraint_fields : set[str] | None
|
69
|
-
Set of constraints for field values for the schema. Must be a set of column names
|
70
|
-
|
69
|
+
Set of constraints for field values for the schema. Must be a set of warehouse column names. This specifies that their entity field values must be a unique combination within an entity.
|
70
|
+
The following sequence constraints are also supported:
|
71
|
+
- bases: only supported for nucleotide sequence entity types. hasUniqueResidues=True
|
72
|
+
- amino_acids_ignore_case: only supported for amino acid sequence entity types. hasUniqueResidues=True
|
73
|
+
- amino_acids_exact_match: only supported for amino acid sequence entity types. hasUniqueResidues=True, areUniqueResiduesCaseSensitive=True
|
74
|
+
show_bases_in_expanded_view : bool | None
|
75
|
+
Whether the bases should be shown in the expanded view of the entity.
|
71
76
|
_archived : bool | None
|
72
77
|
Whether the schema is archived in Benchling.
|
73
78
|
"""
|
@@ -81,6 +86,7 @@ class BaseSchemaProperties(BaseModel):
|
|
81
86
|
use_registry_id_as_label: bool | None = None
|
82
87
|
include_registry_id_in_chips: bool | None = None
|
83
88
|
constraint_fields: set[str] | None = None
|
89
|
+
show_bases_in_expanded_view: bool | None = None
|
84
90
|
_archived: bool | None = None
|
85
91
|
|
86
92
|
def __init__(self, **data: Any):
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -18,6 +18,7 @@ from liminal.entity_schemas.operations import (
|
|
18
18
|
UpdateEntitySchemaNameTemplate,
|
19
19
|
)
|
20
20
|
from liminal.entity_schemas.utils import get_converted_tag_schemas
|
21
|
+
from liminal.enums.benchling_naming_strategy import BenchlingNamingStrategy
|
21
22
|
from liminal.orm.base_model import BaseModel
|
22
23
|
from liminal.orm.column import Column
|
23
24
|
from liminal.utils import to_snake_case
|
@@ -275,6 +276,16 @@ def compare_entity_schemas(
|
|
275
276
|
col.properties.set_warehouse_name(wh_name)
|
276
277
|
for wh_name, col in model_columns.items()
|
277
278
|
]
|
279
|
+
template_based_naming_strategies = {
|
280
|
+
s
|
281
|
+
for s in model.__schema_properties__.naming_strategies
|
282
|
+
if BenchlingNamingStrategy.is_template_based(s)
|
283
|
+
}
|
284
|
+
model.__schema_properties__.naming_strategies = {
|
285
|
+
s
|
286
|
+
for s in model.__schema_properties__.naming_strategies
|
287
|
+
if not BenchlingNamingStrategy.is_template_based(s)
|
288
|
+
}
|
278
289
|
ops.append(
|
279
290
|
CompareOperation(
|
280
291
|
op=CreateEntitySchema(
|
@@ -288,28 +299,10 @@ def compare_entity_schemas(
|
|
288
299
|
),
|
289
300
|
)
|
290
301
|
)
|
291
|
-
benchling_given_wh_name = to_snake_case(model.__schema_properties__.name)
|
292
|
-
if model.__schema_properties__.warehouse_name != benchling_given_wh_name:
|
293
|
-
ops.append(
|
294
|
-
CompareOperation(
|
295
|
-
op=UpdateEntitySchema(
|
296
|
-
benchling_given_wh_name,
|
297
|
-
BaseSchemaProperties(
|
298
|
-
warehouse_name=model.__schema_properties__.warehouse_name
|
299
|
-
),
|
300
|
-
),
|
301
|
-
reverse_op=UpdateEntitySchema(
|
302
|
-
model.__schema_properties__.warehouse_name,
|
303
|
-
BaseSchemaProperties(
|
304
|
-
warehouse_name=benchling_given_wh_name
|
305
|
-
),
|
306
|
-
),
|
307
|
-
)
|
308
|
-
)
|
309
302
|
benchling_given_name_template = BaseNameTemplate(
|
310
303
|
parts=[], order_name_parts_by_sequence=False
|
311
304
|
)
|
312
|
-
if
|
305
|
+
if benchling_given_name_template != model.__name_template__:
|
313
306
|
ops.append(
|
314
307
|
CompareOperation(
|
315
308
|
op=UpdateEntitySchemaNameTemplate(
|
@@ -323,13 +316,39 @@ def compare_entity_schemas(
|
|
323
316
|
reverse_op=UpdateEntitySchemaNameTemplate(
|
324
317
|
model.__schema_properties__.warehouse_name,
|
325
318
|
BaseNameTemplate(
|
326
|
-
**
|
327
|
-
|
319
|
+
**model.__name_template__.merge(
|
320
|
+
benchling_given_name_template
|
328
321
|
)
|
329
322
|
),
|
330
323
|
),
|
331
324
|
)
|
332
325
|
)
|
326
|
+
benchling_given_wh_name = to_snake_case(model.__schema_properties__.name)
|
327
|
+
new_schema_props = BaseSchemaProperties()
|
328
|
+
rollback_schema_props = BaseSchemaProperties()
|
329
|
+
if model.__schema_properties__.warehouse_name != benchling_given_wh_name:
|
330
|
+
new_schema_props.warehouse_name = (
|
331
|
+
model.__schema_properties__.warehouse_name
|
332
|
+
)
|
333
|
+
rollback_schema_props.warehouse_name = benchling_given_wh_name
|
334
|
+
if template_based_naming_strategies:
|
335
|
+
new_schema_props.naming_strategies = template_based_naming_strategies
|
336
|
+
rollback_schema_props.naming_strategies = (
|
337
|
+
model.__schema_properties__.naming_strategies
|
338
|
+
)
|
339
|
+
if new_schema_props.model_dump(exclude_unset=True) != {}:
|
340
|
+
ops.append(
|
341
|
+
CompareOperation(
|
342
|
+
op=UpdateEntitySchema(
|
343
|
+
benchling_given_wh_name,
|
344
|
+
new_schema_props,
|
345
|
+
),
|
346
|
+
reverse_op=UpdateEntitySchema(
|
347
|
+
model.__schema_properties__.warehouse_name,
|
348
|
+
rollback_schema_props,
|
349
|
+
),
|
350
|
+
)
|
351
|
+
)
|
333
352
|
|
334
353
|
model_operations[model.__schema_properties__.warehouse_name] = ops
|
335
354
|
running_benchling_schema_names = [
|
@@ -9,8 +9,10 @@ from liminal.connection import BenchlingService
|
|
9
9
|
from liminal.dropdowns.utils import get_benchling_dropdown_summary_by_name
|
10
10
|
from liminal.entity_schemas.tag_schema_models import TagSchemaModel
|
11
11
|
from liminal.enums import BenchlingEntityType
|
12
|
+
from liminal.enums.sequence_constraint import SequenceConstraint
|
12
13
|
from liminal.mappers import convert_field_type_to_api_field_type
|
13
14
|
from liminal.orm.schema_properties import MixtureSchemaConfig, SchemaProperties
|
15
|
+
from liminal.unit_dictionary.utils import get_unit_id_from_name
|
14
16
|
|
15
17
|
|
16
18
|
class FieldLinkShortModel(BaseModel):
|
@@ -26,28 +28,44 @@ class EntitySchemaConstraint(BaseModel):
|
|
26
28
|
"""
|
27
29
|
|
28
30
|
areUniqueResiduesCaseSensitive: bool | None = None
|
29
|
-
fields: dict[str, Any] | None = None
|
30
|
-
|
31
|
+
fields: list[dict[str, Any]] | None = None
|
32
|
+
hasUniqueCanonicalSmiles: bool | None = None
|
31
33
|
hasUniqueResidues: bool | None = None
|
32
34
|
|
33
35
|
@classmethod
|
34
36
|
def from_constraint_fields(
|
35
|
-
cls,
|
37
|
+
cls,
|
38
|
+
constraint_fields: set[str],
|
39
|
+
benchling_service: BenchlingService | None = None,
|
36
40
|
) -> EntitySchemaConstraint:
|
37
41
|
"""
|
38
42
|
Generates a Constraint object from a set of constraint fields to create a constraint on a schema.
|
39
43
|
"""
|
40
|
-
if constraint_fields is None:
|
41
|
-
return None
|
42
44
|
hasUniqueResidues = False
|
43
|
-
|
44
|
-
|
45
|
+
areUniqueResiduesCaseSensitive = False
|
46
|
+
if SequenceConstraint.BASES in constraint_fields:
|
47
|
+
constraint_fields.discard(SequenceConstraint.BASES)
|
48
|
+
hasUniqueResidues = True
|
49
|
+
elif SequenceConstraint.AMINO_ACIDS_IGNORE_CASE in constraint_fields:
|
50
|
+
constraint_fields.discard(SequenceConstraint.AMINO_ACIDS_IGNORE_CASE)
|
45
51
|
hasUniqueResidues = True
|
52
|
+
elif SequenceConstraint.AMINO_ACIDS_EXACT_MATCH in constraint_fields:
|
53
|
+
constraint_fields.discard(SequenceConstraint.AMINO_ACIDS_EXACT_MATCH)
|
54
|
+
hasUniqueResidues = True
|
55
|
+
areUniqueResiduesCaseSensitive = True
|
56
|
+
fields = []
|
57
|
+
for field_name in constraint_fields:
|
58
|
+
if benchling_service is None:
|
59
|
+
raise ValueError(
|
60
|
+
"Benchling SDK must be provided to update constraint fields."
|
61
|
+
)
|
62
|
+
field = TagSchemaModel.get_one(benchling_service, field_name)
|
63
|
+
fields.append({"name": field.name, "id": field.id})
|
46
64
|
return cls(
|
47
|
-
fields=
|
65
|
+
fields=fields,
|
48
66
|
hasUniqueResidues=hasUniqueResidues,
|
49
|
-
|
50
|
-
areUniqueResiduesCaseSensitive=
|
67
|
+
hasUniqueCanonicalSmiles=False,
|
68
|
+
areUniqueResiduesCaseSensitive=areUniqueResiduesCaseSensitive,
|
51
69
|
)
|
52
70
|
|
53
71
|
|
@@ -63,6 +81,8 @@ class CreateEntitySchemaFieldModel(BaseModel):
|
|
63
81
|
isParentLink: bool = False
|
64
82
|
dropdownId: str | None = None
|
65
83
|
link: FieldLinkShortModel | None = None
|
84
|
+
unitId: str | None = None
|
85
|
+
decimalPrecision: int | None = None
|
66
86
|
|
67
87
|
@classmethod
|
68
88
|
def from_benchling_props(
|
@@ -107,6 +127,11 @@ class CreateEntitySchemaFieldModel(BaseModel):
|
|
107
127
|
dropdown_summary_id = get_benchling_dropdown_summary_by_name(
|
108
128
|
benchling_service, field_props.dropdown_link
|
109
129
|
).id
|
130
|
+
unit_id = None
|
131
|
+
if field_props.unit_name is not None:
|
132
|
+
if benchling_service is None:
|
133
|
+
raise ValueError("Benchling SDK must be provided to update unit field.")
|
134
|
+
unit_id = get_unit_id_from_name(benchling_service, field_props.unit_name)
|
110
135
|
return CreateEntitySchemaFieldModel(
|
111
136
|
name=field_props.name,
|
112
137
|
systemName=field_props.warehouse_name,
|
@@ -118,6 +143,8 @@ class CreateEntitySchemaFieldModel(BaseModel):
|
|
118
143
|
link=FieldLinkShortModel(
|
119
144
|
tagSchema=tag_schema, folderItemType=folder_item_type
|
120
145
|
),
|
146
|
+
unitId=unit_id,
|
147
|
+
decimalPrecision=field_props.decimal_places,
|
121
148
|
)
|
122
149
|
|
123
150
|
|
@@ -135,6 +162,7 @@ class CreateEntitySchemaModel(BaseModel):
|
|
135
162
|
useOrganizationCollectionAliasForDisplayLabel: bool | None = None
|
136
163
|
labelingStrategies: list[str] | None = None
|
137
164
|
constraint: EntitySchemaConstraint | None = None
|
165
|
+
showResidues: bool | None = None
|
138
166
|
|
139
167
|
@classmethod
|
140
168
|
def from_benchling_props(
|
@@ -168,11 +196,10 @@ class CreateEntitySchemaModel(BaseModel):
|
|
168
196
|
includeRegistryIdInChips=benchling_props.include_registry_id_in_chips,
|
169
197
|
useOrganizationCollectionAliasForDisplayLabel=benchling_props.use_registry_id_as_label,
|
170
198
|
labelingStrategies=[s.value for s in benchling_props.naming_strategies],
|
199
|
+
showResidues=benchling_props.show_bases_in_expanded_view,
|
171
200
|
constraint=EntitySchemaConstraint.from_constraint_fields(
|
172
201
|
benchling_props.constraint_fields
|
173
|
-
)
|
174
|
-
if benchling_props.constraint_fields
|
175
|
-
else None,
|
202
|
+
),
|
176
203
|
fields=[
|
177
204
|
CreateEntitySchemaFieldModel.from_benchling_props(
|
178
205
|
field_props, benchling_service
|
@@ -91,7 +91,7 @@ def generate_all_entity_schema_files(
|
|
91
91
|
dropdown_classname = dropdown_name_to_classname_map[col.dropdown_link]
|
92
92
|
dropdowns.append(dropdown_classname)
|
93
93
|
column_strings.append(
|
94
|
-
f"""{tab}{col_name}: SqlColumn = Column(name="{col.name}", type={str(col.type)}, required={col.required}{', is_multi=True' if col.is_multi else ''}{', parent_link=True' if col.parent_link else ''}{f', entity_link="{col.entity_link}"' if col.entity_link else ''}{f', dropdown={dropdown_classname}' if dropdown_classname else ''}{f', tooltip="{col.tooltip}"' if col.tooltip else ''})"""
|
94
|
+
f"""{tab}{col_name}: SqlColumn = Column(name="{col.name}", type={str(col.type)}, required={col.required}{', is_multi=True' if col.is_multi else ''}{', parent_link=True' if col.parent_link else ''}{f', entity_link="{col.entity_link}"' if col.entity_link else ''}{f', dropdown={dropdown_classname}' if dropdown_classname else ''}{f', tooltip="{col.tooltip}"' if col.tooltip else ''}{f', unit_name="{col.unit_name}"' if col.unit_name else ''}{f', decimal_places={col.decimal_places}' if col.decimal_places is not None else ''})"""
|
95
95
|
)
|
96
96
|
if col.required and col.type:
|
97
97
|
init_strings.append(
|
@@ -105,7 +105,7 @@ def generate_all_entity_schema_files(
|
|
105
105
|
if not has_date:
|
106
106
|
import_strings.append("from datetime import datetime")
|
107
107
|
if (
|
108
|
-
col.type
|
108
|
+
col.type in BenchlingFieldType.get_entity_link_types()
|
109
109
|
and col.entity_link is not None
|
110
110
|
):
|
111
111
|
if not col.is_multi:
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import logging
|
1
2
|
from typing import Any, ClassVar
|
2
3
|
|
3
4
|
from liminal.base.base_operation import BaseOperation
|
@@ -25,8 +26,14 @@ from liminal.entity_schemas.utils import (
|
|
25
26
|
)
|
26
27
|
from liminal.enums import BenchlingNamingStrategy
|
27
28
|
from liminal.orm.schema_properties import SchemaProperties
|
29
|
+
from liminal.unit_dictionary.utils import (
|
30
|
+
get_unit_id_to_name_map,
|
31
|
+
get_unit_name_to_id_map,
|
32
|
+
)
|
28
33
|
from liminal.utils import to_snake_case
|
29
34
|
|
35
|
+
LOGGER = logging.getLogger(__name__)
|
36
|
+
|
30
37
|
|
31
38
|
class CreateEntitySchema(BaseOperation):
|
32
39
|
order: ClassVar[int] = 80
|
@@ -39,7 +46,7 @@ class CreateEntitySchema(BaseOperation):
|
|
39
46
|
self.schema_properties = schema_properties
|
40
47
|
self.fields = fields
|
41
48
|
self._validated_schema_properties = SchemaProperties(
|
42
|
-
**schema_properties.model_dump()
|
49
|
+
**schema_properties.model_dump(exclude_unset=True)
|
43
50
|
)
|
44
51
|
|
45
52
|
def execute(self, benchling_service: BenchlingService) -> dict[str, Any]:
|
@@ -83,6 +90,15 @@ class CreateEntitySchema(BaseOperation):
|
|
83
90
|
Either set warehouse_access to True in BenchlingConnection or set the schema warehouse_name to the given Benchling warehouse name: {to_snake_case(self._validated_schema_properties.name)}. \
|
84
91
|
Reach out to Benchling support if you need help setting up warehouse access."
|
85
92
|
)
|
93
|
+
for field in self.fields:
|
94
|
+
if (
|
95
|
+
field.unit_name
|
96
|
+
and field.unit_name
|
97
|
+
not in get_unit_name_to_id_map(benchling_service).keys()
|
98
|
+
):
|
99
|
+
raise ValueError(
|
100
|
+
f"{self._validated_schema_properties.warehouse_name}: On field {field.warehouse_name}, unit {field.unit_name} not found in Benchling Unit Dictionary as a valid unit. Please check the field definition or your Unit Dictionary."
|
101
|
+
)
|
86
102
|
|
87
103
|
def _validate_create(self, benchling_service: BenchlingService) -> None:
|
88
104
|
all_schemas = TagSchemaModel.get_all_json(benchling_service)
|
@@ -123,8 +139,11 @@ class CreateEntitySchema(BaseOperation):
|
|
123
139
|
f"Entity schema {self._validated_schema_properties.warehouse_name} is already active in Benchling."
|
124
140
|
)
|
125
141
|
dropdowns_map = get_benchling_dropdown_id_name_map(benchling_service)
|
142
|
+
unit_id_to_name_map = get_unit_id_to_name_map(benchling_service)
|
126
143
|
benchling_schema_props, _, benchling_fields_props = (
|
127
|
-
convert_tag_schema_to_internal_schema(
|
144
|
+
convert_tag_schema_to_internal_schema(
|
145
|
+
schema, dropdowns_map, unit_id_to_name_map
|
146
|
+
)
|
128
147
|
)
|
129
148
|
if (
|
130
149
|
self._validated_schema_properties != benchling_schema_props
|
@@ -162,7 +181,7 @@ class ArchiveEntitySchema(BaseOperation):
|
|
162
181
|
|
163
182
|
|
164
183
|
class UnarchiveEntitySchema(BaseOperation):
|
165
|
-
order: ClassVar[int] =
|
184
|
+
order: ClassVar[int] = 90
|
166
185
|
|
167
186
|
def __init__(self, wh_schema_name: str) -> None:
|
168
187
|
self.wh_schema_name = wh_schema_name
|
@@ -187,7 +206,7 @@ class UnarchiveEntitySchema(BaseOperation):
|
|
187
206
|
|
188
207
|
|
189
208
|
class UpdateEntitySchema(BaseOperation):
|
190
|
-
order: ClassVar[int] =
|
209
|
+
order: ClassVar[int] = 120
|
191
210
|
|
192
211
|
def __init__(
|
193
212
|
self,
|
@@ -251,7 +270,7 @@ class UpdateEntitySchema(BaseOperation):
|
|
251
270
|
|
252
271
|
|
253
272
|
class UpdateEntitySchemaNameTemplate(BaseOperation):
|
254
|
-
order: ClassVar[int] =
|
273
|
+
order: ClassVar[int] = 110
|
255
274
|
|
256
275
|
def __init__(
|
257
276
|
self,
|
@@ -283,7 +302,7 @@ class UpdateEntitySchemaNameTemplate(BaseOperation):
|
|
283
302
|
|
284
303
|
|
285
304
|
class CreateEntitySchemaField(BaseOperation):
|
286
|
-
order: ClassVar[int] =
|
305
|
+
order: ClassVar[int] = 100
|
287
306
|
|
288
307
|
def __init__(
|
289
308
|
self,
|
@@ -316,13 +335,20 @@ class CreateEntitySchemaField(BaseOperation):
|
|
316
335
|
f"Field {self._wh_field_name} is already active on entity schema {self.wh_schema_name}."
|
317
336
|
)
|
318
337
|
dropdowns_map = get_benchling_dropdown_id_name_map(benchling_service)
|
338
|
+
unit_id_to_name_map = get_unit_id_to_name_map(benchling_service)
|
319
339
|
if self.field_props == convert_tag_schema_field_to_field_properties(
|
320
|
-
field, dropdowns_map
|
321
|
-
):
|
340
|
+
field, dropdowns_map, unit_id_to_name_map
|
341
|
+
).set_warehouse_name(self._wh_field_name):
|
322
342
|
return UnarchiveEntitySchemaField(
|
323
343
|
self.wh_schema_name, self._wh_field_name, self.index
|
324
344
|
).execute(benchling_service)
|
325
345
|
else:
|
346
|
+
print(self.field_props)
|
347
|
+
print(
|
348
|
+
convert_tag_schema_field_to_field_properties(
|
349
|
+
field, dropdowns_map, unit_id_to_name_map
|
350
|
+
)
|
351
|
+
)
|
326
352
|
raise ValueError(
|
327
353
|
f"Field {self._wh_field_name} on entity schema {self.wh_schema_name} is different in code versus Benchling."
|
328
354
|
)
|
@@ -367,10 +393,18 @@ class CreateEntitySchemaField(BaseOperation):
|
|
367
393
|
Either set warehouse_access to True in BenchlingConnection or set the column variable name to the given Benchling field warehouse name: {to_snake_case(self.field_props.name)}. \
|
368
394
|
Reach out to Benchling support if you need help setting up warehouse access."
|
369
395
|
)
|
396
|
+
if (
|
397
|
+
self.field_props.unit_name
|
398
|
+
and self.field_props.unit_name
|
399
|
+
not in get_unit_name_to_id_map(benchling_service).keys()
|
400
|
+
):
|
401
|
+
raise ValueError(
|
402
|
+
f"{self.wh_schema_name}: On field {self._wh_field_name}, unit {self.field_props.unit_name} not found in Benchling Unit Dictionary as a valid unit. Please check the field definition or your Unit Dictionary."
|
403
|
+
)
|
370
404
|
|
371
405
|
|
372
406
|
class ArchiveEntitySchemaField(BaseOperation):
|
373
|
-
order: ClassVar[int] =
|
407
|
+
order: ClassVar[int] = 150
|
374
408
|
|
375
409
|
def __init__(
|
376
410
|
self, wh_schema_name: str, wh_field_name: str, index: int | None = None
|
@@ -421,7 +455,7 @@ class ArchiveEntitySchemaField(BaseOperation):
|
|
421
455
|
|
422
456
|
|
423
457
|
class UnarchiveEntitySchemaField(BaseOperation):
|
424
|
-
order: ClassVar[int] =
|
458
|
+
order: ClassVar[int] = 130
|
425
459
|
|
426
460
|
def __init__(
|
427
461
|
self, wh_schema_name: str, wh_field_name: str, index: int | None = None
|
@@ -468,7 +502,7 @@ class UnarchiveEntitySchemaField(BaseOperation):
|
|
468
502
|
|
469
503
|
|
470
504
|
class UpdateEntitySchemaField(BaseOperation):
|
471
|
-
order: ClassVar[int] =
|
505
|
+
order: ClassVar[int] = 140
|
472
506
|
|
473
507
|
def __init__(
|
474
508
|
self,
|
@@ -500,6 +534,9 @@ class UpdateEntitySchemaField(BaseOperation):
|
|
500
534
|
return f"{self.wh_schema_name}: Entity schema field '{self.wh_field_name}' in Benchling is different than in code: {str(self.update_props)}."
|
501
535
|
|
502
536
|
def validate(self, benchling_service: BenchlingService) -> None:
|
537
|
+
tag_schema = TagSchemaModel.get_one_cached(
|
538
|
+
benchling_service, self.wh_schema_name
|
539
|
+
)
|
503
540
|
if (
|
504
541
|
not benchling_service.connection.warehouse_access
|
505
542
|
and self.update_props.warehouse_name is not None
|
@@ -509,6 +546,19 @@ class UpdateEntitySchemaField(BaseOperation):
|
|
509
546
|
Either set warehouse_access to True in BenchlingConnection or do not change the warehouse name. \
|
510
547
|
Reach out to Benchling support if you need help setting up warehouse access."
|
511
548
|
)
|
549
|
+
if "unit_name" in self.update_props.model_dump(exclude_unset=True):
|
550
|
+
no_change_message = f"{self.wh_schema_name}: On field {self.wh_field_name}, updating unit name to {self.update_props.unit_name}. The unit of this field CANNOT be changed once it's been set."
|
551
|
+
if tag_schema.get_field(self.wh_field_name).unitApiIdentifier:
|
552
|
+
raise ValueError(no_change_message)
|
553
|
+
else:
|
554
|
+
LOGGER.warning(no_change_message)
|
555
|
+
if (
|
556
|
+
self.update_props.unit_name
|
557
|
+
not in get_unit_name_to_id_map(benchling_service).keys()
|
558
|
+
):
|
559
|
+
raise ValueError(
|
560
|
+
f"{self.wh_schema_name}: On field {self.wh_field_name}, unit {self.update_props.unit_name} not found in Benchling Unit Dictionary as a valid unit. Please check the field definition or your Unit Dictionary."
|
561
|
+
)
|
512
562
|
|
513
563
|
def _validate(self, benchling_service: BenchlingService) -> TagSchemaModel:
|
514
564
|
tag_schema = TagSchemaModel.get_one(benchling_service, self.wh_schema_name)
|