liminal-orm 5.1.0__tar.gz → 5.1.3__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.
Files changed (298) hide show
  1. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.gitignore +2 -1
  2. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/PKG-INFO +4 -4
  3. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/README.md +1 -1
  4. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/base/base_operation.py +4 -4
  5. liminal_orm-5.1.3/liminal/base/compare_operation.py +19 -0
  6. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/base/properties/base_field_properties.py +5 -3
  7. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/base/properties/base_schema_properties.py +5 -0
  8. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/cli/cli.py +1 -1
  9. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/dropdowns/generate_files.py +5 -4
  10. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/dropdowns/operations.py +1 -8
  11. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/entity_schemas/compare.py +90 -36
  12. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/entity_schemas/entity_schema_models.py +26 -13
  13. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/entity_schemas/generate_files.py +11 -6
  14. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/entity_schemas/operations.py +14 -10
  15. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/entity_schemas/utils.py +1 -1
  16. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/column.py +2 -2
  17. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/schema_properties.py +33 -34
  18. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/results_schemas/generate_files.py +12 -7
  19. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/results_schemas/models/results_schema_model.py +2 -1
  20. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/results_schemas/utils.py +19 -17
  21. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/tests/conftest.py +106 -0
  22. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/tests/test_entity_schema_compare.py +236 -2
  23. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/utils.py +32 -7
  24. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/pyproject.toml +3 -3
  25. liminal_orm-5.1.0/liminal/base/compare_operation.py +0 -13
  26. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/__init__.py +0 -0
  27. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_dropdown.py +0 -0
  28. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_operation.py +0 -0
  29. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_validation_filters.py +0 -0
  30. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/compare_operation.py +0 -0
  31. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/name_template_parts.py +0 -0
  32. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_field_properties.py +0 -0
  33. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_name_template.py +0 -0
  34. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_schema_properties.py +0 -0
  35. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/str_enum.py +0 -0
  36. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/cli.py +0 -0
  37. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/controller.py +0 -0
  38. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/live_test_dropdown_migration.py +0 -0
  39. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/live_test_entity_schema_migration.py +0 -0
  40. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/utils.py +0 -0
  41. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/__init__.py +0 -0
  42. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/benchling_connection.py +0 -0
  43. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/benchling_service.py +0 -0
  44. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/api.py +0 -0
  45. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/compare.py +0 -0
  46. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/generate_files.py +0 -0
  47. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/operations.py +0 -0
  48. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/utils.py +0 -0
  49. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/api.py +0 -0
  50. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/compare.py +0 -0
  51. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/entity_schema_models.py +0 -0
  52. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/generate_files.py +0 -0
  53. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/operations.py +0 -0
  54. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/tag_schema_models.py +0 -0
  55. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/utils.py +0 -0
  56. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/__init__.py +0 -0
  57. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_api_field_type.py +0 -0
  58. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_entity_type.py +0 -0
  59. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_field_type.py +0 -0
  60. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_folder_item_type.py +0 -0
  61. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_naming_strategy.py +0 -0
  62. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_sequence_type.py +0 -0
  63. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/name_template_part_type.py +0 -0
  64. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/sequence_constraint.py +0 -0
  65. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/external/__init__.py +0 -0
  66. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/mappers.py +0 -0
  67. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/components.py +0 -0
  68. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/revision.py +0 -0
  69. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/revisions_timeline.py +0 -0
  70. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base.py +0 -0
  71. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_model.py +0 -0
  72. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_results_model.py +0 -0
  73. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/registry_entity.py +0 -0
  74. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/schema.py +0 -0
  75. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/user.py +0 -0
  76. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/column.py +0 -0
  77. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/mixins.py +0 -0
  78. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/name_template.py +0 -0
  79. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/name_template_parts.py +0 -0
  80. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/relationship.py +0 -0
  81. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/results_schema_properties.py +0 -0
  82. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/schema_properties.py +0 -0
  83. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/py.typed +0 -0
  84. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/generate_files.py +0 -0
  85. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/models/results_schema_model.py +0 -0
  86. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/utils.py +0 -0
  87. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/__init__.py +0 -0
  88. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/conftest.py +0 -0
  89. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/from benchling_sdk.py +0 -0
  90. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_benchling_service.py +0 -0
  91. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_dataframe_compatibility.py +0 -0
  92. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_dropdown_compare.py +0 -0
  93. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_entity_schema_compare.py +0 -0
  94. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/unit_dictionary/utils.py +0 -0
  95. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/utils.py +0 -0
  96. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/validation/__init__.py +0 -0
  97. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/validation/validation_severity.py +0 -0
  98. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/__init__.py +0 -0
  99. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/base_dropdown.py +0 -0
  100. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/base_operation.py +0 -0
  101. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/base_validation_filters.py +0 -0
  102. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/compare_operation.py +0 -0
  103. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/name_template_parts.py +0 -0
  104. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/properties/base_field_properties.py +0 -0
  105. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/properties/base_name_template.py +0 -0
  106. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/properties/base_schema_properties.py +0 -0
  107. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/str_enum.py +0 -0
  108. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/cli/cli.py +0 -0
  109. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/cli/controller.py +0 -0
  110. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/cli/live_test_dropdown_migration.py +0 -0
  111. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/cli/live_test_entity_schema_migration.py +0 -0
  112. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/cli/utils.py +0 -0
  113. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/connection/__init__.py +0 -0
  114. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/connection/benchling_connection.py +0 -0
  115. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/connection/benchling_service.py +0 -0
  116. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/dropdowns/api.py +0 -0
  117. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/dropdowns/compare.py +0 -0
  118. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/dropdowns/generate_files.py +0 -0
  119. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/dropdowns/operations.py +0 -0
  120. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/dropdowns/utils.py +0 -0
  121. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/api.py +0 -0
  122. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/compare.py +0 -0
  123. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/entity_schema_models.py +0 -0
  124. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/generate_files.py +0 -0
  125. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/operations.py +0 -0
  126. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/tag_schema_models.py +0 -0
  127. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/utils.py +0 -0
  128. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/__init__.py +0 -0
  129. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_api_field_type.py +0 -0
  130. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_entity_type.py +0 -0
  131. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_field_type.py +0 -0
  132. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_folder_item_type.py +0 -0
  133. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_naming_strategy.py +0 -0
  134. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_sequence_type.py +0 -0
  135. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/name_template_part_type.py +0 -0
  136. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/sequence_constraint.py +0 -0
  137. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/external/__init__.py +0 -0
  138. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/mappers.py +0 -0
  139. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/migrate/components.py +0 -0
  140. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/migrate/revision.py +0 -0
  141. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/migrate/revisions_timeline.py +0 -0
  142. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base.py +0 -0
  143. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base_model.py +0 -0
  144. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base_results_model.py +0 -0
  145. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base_tables/registry_entity.py +0 -0
  146. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base_tables/schema.py +0 -0
  147. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base_tables/user.py +0 -0
  148. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/column.py +0 -0
  149. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/mixins.py +0 -0
  150. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/name_template.py +0 -0
  151. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/name_template_parts.py +0 -0
  152. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/relationship.py +0 -0
  153. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/results_schema_properties.py +0 -0
  154. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/schema_properties.py +0 -0
  155. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/py.typed +0 -0
  156. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/results_schemas/generate_files.py +0 -0
  157. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/results_schemas/models/results_schema_model.py +0 -0
  158. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/results_schemas/utils.py +0 -0
  159. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/__init__.py +0 -0
  160. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/conftest.py +0 -0
  161. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/from benchling_sdk.py +0 -0
  162. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/test_benchling_service.py +0 -0
  163. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/test_dataframe_compatibility.py +0 -0
  164. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/test_dropdown_compare.py +0 -0
  165. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/test_entity_schema_compare.py +0 -0
  166. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/unit_dictionary/utils.py +0 -0
  167. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/utils.py +0 -0
  168. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/validation/__init__.py +0 -0
  169. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/validation/validation_severity.py +0 -0
  170. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/__init__.py +0 -0
  171. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_dropdown.py +0 -0
  172. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_operation.py +0 -0
  173. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_validation_filters.py +0 -0
  174. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/compare_operation.py +0 -0
  175. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/name_template_parts.py +0 -0
  176. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_field_properties.py +0 -0
  177. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_name_template.py +0 -0
  178. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_schema_properties.py +0 -0
  179. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/str_enum.py +0 -0
  180. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/cli.py +0 -0
  181. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/controller.py +0 -0
  182. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/live_test_dropdown_migration.py +0 -0
  183. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/live_test_entity_schema_migration.py +0 -0
  184. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/utils.py +0 -0
  185. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/__init__.py +0 -0
  186. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/benchling_connection.py +0 -0
  187. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/benchling_service.py +0 -0
  188. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/api.py +0 -0
  189. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/compare.py +0 -0
  190. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/generate_files.py +0 -0
  191. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/operations.py +0 -0
  192. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/utils.py +0 -0
  193. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/api.py +0 -0
  194. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/compare.py +0 -0
  195. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/entity_schema_models.py +0 -0
  196. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/generate_files.py +0 -0
  197. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/operations.py +0 -0
  198. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/tag_schema_models.py +0 -0
  199. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/utils.py +0 -0
  200. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/__init__.py +0 -0
  201. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_api_field_type.py +0 -0
  202. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_entity_type.py +0 -0
  203. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_field_type.py +0 -0
  204. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_folder_item_type.py +0 -0
  205. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_naming_strategy.py +0 -0
  206. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_sequence_type.py +0 -0
  207. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/name_template_part_type.py +0 -0
  208. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/sequence_constraint.py +0 -0
  209. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/external/__init__.py +0 -0
  210. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/mappers.py +0 -0
  211. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/components.py +0 -0
  212. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/revision.py +0 -0
  213. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/revisions_timeline.py +0 -0
  214. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base.py +0 -0
  215. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_model.py +0 -0
  216. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_results_model.py +0 -0
  217. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/registry_entity.py +0 -0
  218. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/schema.py +0 -0
  219. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/user.py +0 -0
  220. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/column.py +0 -0
  221. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/mixins.py +0 -0
  222. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/name_template.py +0 -0
  223. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/name_template_parts.py +0 -0
  224. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/relationship.py +0 -0
  225. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/results_schema_properties.py +0 -0
  226. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/schema_properties.py +0 -0
  227. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/py.typed +0 -0
  228. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/generate_files.py +0 -0
  229. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/models/results_schema_model.py +0 -0
  230. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/utils.py +0 -0
  231. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/__init__.py +0 -0
  232. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/conftest.py +0 -0
  233. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/from benchling_sdk.py +0 -0
  234. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_benchling_service.py +0 -0
  235. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_dataframe_compatibility.py +0 -0
  236. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_dropdown_compare.py +0 -0
  237. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_entity_schema_compare.py +0 -0
  238. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/unit_dictionary/utils.py +0 -0
  239. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/utils.py +0 -0
  240. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/validation/__init__.py +0 -0
  241. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/validation/validation_severity.py +0 -0
  242. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/LICENSE.md +0 -0
  243. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/__init__.py +0 -0
  244. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/base/base_dropdown.py +0 -0
  245. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/base/base_validation_filters.py +0 -0
  246. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/base/name_template_parts.py +0 -0
  247. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/base/properties/base_name_template.py +0 -0
  248. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/base/str_enum.py +0 -0
  249. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/cli/controller.py +0 -0
  250. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/cli/live_test_dropdown_migration.py +0 -0
  251. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/cli/live_test_entity_schema_migration.py +0 -0
  252. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/cli/utils.py +0 -0
  253. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/connection/__init__.py +0 -0
  254. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/connection/benchling_connection.py +0 -0
  255. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/connection/benchling_service.py +0 -0
  256. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/dropdowns/api.py +0 -0
  257. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/dropdowns/compare.py +0 -0
  258. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/dropdowns/utils.py +0 -0
  259. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/entity_schemas/api.py +0 -0
  260. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/entity_schemas/test_entity_dataframe_compatibility.py +0 -0
  261. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/__init__.py +0 -0
  262. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/benchling_entity_schema_endpoint_type.py +0 -0
  263. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/benchling_entity_type.py +0 -0
  264. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/benchling_entity_type_name.py +0 -0
  265. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/benchling_field_definition_input_type.py +0 -0
  266. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/benchling_field_definition_type.py +0 -0
  267. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/benchling_field_type.py +0 -0
  268. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/benchling_link_definition_type.py +0 -0
  269. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/benchling_naming_strategy.py +0 -0
  270. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/name_template_part_type.py +0 -0
  271. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/enums/sequence_constraint.py +0 -0
  272. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/external/__init__.py +0 -0
  273. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/mappers.py +0 -0
  274. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/migrate/components.py +0 -0
  275. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/migrate/revision.py +0 -0
  276. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/migrate/revisions_timeline.py +0 -0
  277. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/base.py +0 -0
  278. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/base_model.py +0 -0
  279. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/base_results_model.py +0 -0
  280. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/base_tables/registry_entity.py +0 -0
  281. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/base_tables/schema.py +0 -0
  282. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/base_tables/user.py +0 -0
  283. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/mixins.py +0 -0
  284. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/name_template.py +0 -0
  285. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/name_template_parts.py +0 -0
  286. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/relationship.py +0 -0
  287. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/orm/results_schema_properties.py +0 -0
  288. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/py.typed +0 -0
  289. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/results_schemas/api.py +0 -0
  290. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/results_schemas/test_results_dataframe_compatibility.py +0 -0
  291. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/tests/__init__.py +0 -0
  292. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/tests/from benchling_sdk.py +0 -0
  293. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/tests/test_benchling_service.py +0 -0
  294. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/tests/test_dropdown_compare.py +0 -0
  295. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/unit_dictionary/utils.py +0 -0
  296. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/validation/__init__.py +0 -0
  297. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/liminal/validation/validation_severity.py +0 -0
  298. {liminal_orm-5.1.0 → liminal_orm-5.1.3}/skills/liminal/SKILL.md +0 -0
@@ -20,4 +20,5 @@ site/
20
20
  test_liminal/
21
21
 
22
22
  .history/
23
- .cursor/
23
+ .cursor/
24
+ .envrc
@@ -1,12 +1,12 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: liminal-orm
3
- Version: 5.1.0
3
+ Version: 5.1.3
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
  Project-URL: Homepage, https://github.com/dynotx/liminal-orm
6
6
  Project-URL: Repository, https://github.com/dynotx/liminal-orm
7
7
  Project-URL: Documentation, https://dynotx.github.io/liminal-orm/
8
8
  Project-URL: Bug Tracker, https://github.com/dynotx/liminal-orm/issues
9
- Author-email: DynoTx Open Source <opensource@dynotx.com>
9
+ Author: DynoTx Open Source
10
10
  License-File: LICENSE.md
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.10
@@ -21,8 +21,8 @@ Requires-Dist: numpy<2,>=1.26; python_version == '3.12'
21
21
  Requires-Dist: numpy<3,>=2.1; python_version == '3.13'
22
22
  Requires-Dist: pandas<3,>=1.5.3; python_version == '3.10'
23
23
  Requires-Dist: pandas<4,>=1.5.3; python_version == '3.11'
24
+ Requires-Dist: pandas<4,>=2.1.1; python_version == '3.12'
24
25
  Requires-Dist: pandas<4,>=2.2.3; python_version == '3.13'
25
- Requires-Dist: pandas<4,>=2.2; python_version == '3.12'
26
26
  Requires-Dist: psycopg2-binary<3,>=2.9.10
27
27
  Requires-Dist: pydantic<=2.13,>=2
28
28
  Requires-Dist: rich<14,>=13.9.2
@@ -136,7 +136,7 @@ Liminal ORM is distributed under the [Apache License, Version 2.0](./LICENSE.md)
136
136
  ## [Direct Contact](#direct-contact)
137
137
 
138
138
  - Liminal Community Slack group: [Join here](https://join.slack.com/t/liminalorm/shared_invite/zt-3fu79tf06-oqL1000p8BAOG6B3yOOXNA)
139
- - Email: <opensource@dynotx.com>
139
+ - Email: <ndamania00@gmail.com>
140
140
  - LinkedIn: [Nirmit Damania](https://www.linkedin.com/in/nirmit-damania/)
141
141
 
142
142
  ## [Acknowledgements](#acknowledgements)
@@ -103,7 +103,7 @@ Liminal ORM is distributed under the [Apache License, Version 2.0](./LICENSE.md)
103
103
  ## [Direct Contact](#direct-contact)
104
104
 
105
105
  - Liminal Community Slack group: [Join here](https://join.slack.com/t/liminalorm/shared_invite/zt-3fu79tf06-oqL1000p8BAOG6B3yOOXNA)
106
- - Email: <opensource@dynotx.com>
106
+ - Email: <ndamania00@gmail.com>
107
107
  - LinkedIn: [Nirmit Damania](https://www.linkedin.com/in/nirmit-damania/)
108
108
 
109
109
  ## [Acknowledgements](#acknowledgements)
@@ -16,10 +16,10 @@ Order of operations based on order class var:
16
16
  9. CreateEntitySchema
17
17
  10. UnarchiveEntitySchema
18
18
  11. CreateEntitySchemaField
19
- 12. UpdateEntitySchemaNameTemplate
20
- 13. UpdateEntitySchema
21
- 14. UnarchiveEntitySchemaField
22
- 15. UpdateEntitySchemaField
19
+ 12. UpdateEntitySchema
20
+ 13. UnarchiveEntitySchemaField
21
+ 14. UpdateEntitySchemaField
22
+ 15. UpdateEntitySchemaNameTemplate
23
23
  16. ArchiveEntitySchemaField
24
24
  17. ReorderEntitySchemaFields
25
25
  18. ArchiveEntitySchema
@@ -0,0 +1,19 @@
1
+ from pydantic import BaseModel, ConfigDict
2
+
3
+ from liminal.base.base_operation import BaseOperation
4
+
5
+
6
+ class CompareOperation(BaseModel):
7
+ op: BaseOperation
8
+ reverse_op: BaseOperation
9
+ # Overrides op.order when this operation must run at a different point than its type's default.
10
+ order_override: int | None = None
11
+
12
+ model_config = ConfigDict(arbitrary_types_allowed=True)
13
+
14
+ @property
15
+ def sort_order(self) -> int:
16
+ return self.op.order if self.order_override is None else self.order_override
17
+
18
+ def __lt__(self, other: "CompareOperation") -> bool:
19
+ return self.sort_order < other.sort_order
@@ -65,8 +65,6 @@ class BaseFieldProperties(BaseModel):
65
65
  non_multi_types = BenchlingFieldType.get_non_multi_select_types()
66
66
  if field_type in non_multi_types:
67
67
  unsupported.add("is_multi")
68
- if not (has_entity_link and field_type == BenchlingFieldType.ENTITY_LINK):
69
- unsupported.add("parent_link")
70
68
  if field_type not in BenchlingFieldType.get_number_field_types():
71
69
  unsupported.add("unit_name")
72
70
  if field_type != BenchlingFieldType.DECIMAL:
@@ -77,7 +75,7 @@ class BaseFieldProperties(BaseModel):
77
75
  self._archived = value
78
76
  return self
79
77
 
80
- def set_warehouse_name(self, wh_name: str) -> BaseFieldProperties:
78
+ def set_warehouse_name(self, wh_name: str | None) -> BaseFieldProperties:
81
79
  self.warehouse_name = wh_name
82
80
  return self
83
81
 
@@ -96,6 +94,10 @@ class BaseFieldProperties(BaseModel):
96
94
  self.__pydantic_fields_set__.remove("unit_name")
97
95
  return self
98
96
 
97
+ def set_parent_link(self, value: bool) -> BaseFieldProperties:
98
+ self.parent_link = value
99
+ return self
100
+
99
101
  def set_type(self, new_type: BenchlingFieldType) -> BaseFieldProperties:
100
102
  self.type = new_type
101
103
  return self
@@ -105,6 +105,11 @@ class BaseSchemaProperties(BaseModel):
105
105
  self.naming_strategies = value
106
106
  return self
107
107
 
108
+ def unset_naming_strategies(self) -> BaseSchemaProperties:
109
+ if "naming_strategies" in self.__pydantic_fields_set__:
110
+ self.__pydantic_fields_set__.remove("naming_strategies")
111
+ return self
112
+
108
113
  def merge(self, new_props: BaseSchemaProperties) -> dict[str, Any]:
109
114
  """Creates a diff between the current schema properties and the new schema properties.
110
115
  Sets value to None if the values are equal, otherwise sets the value to the new value.
@@ -123,7 +123,7 @@ def generate_files(
123
123
  benchling_connection = read_local_liminal_dir(LIMINAL_DIR_PATH, benchling_tenant)
124
124
  benchling_service = BenchlingService(benchling_connection)
125
125
  if not write_path.exists():
126
- write_path.mkdir()
126
+ write_path.mkdir(parents=True)
127
127
  print(f"[green]Created directory: {write_path}")
128
128
  if not entity_schemas_flag and not dropdowns_flag and not results_schemas_flag:
129
129
  entity_schemas_flag = True
@@ -1,3 +1,4 @@
1
+ import json
1
2
  import shutil
2
3
  from pathlib import Path
3
4
 
@@ -5,7 +6,7 @@ from rich import print
5
6
 
6
7
  from liminal.connection import BenchlingService
7
8
  from liminal.dropdowns.utils import get_benchling_dropdowns_dict
8
- from liminal.utils import to_pascal_case, to_snake_case
9
+ from liminal.utils import to_module_name, to_pascal_case
9
10
 
10
11
 
11
12
  def generate_all_dropdown_files(
@@ -36,17 +37,17 @@ def generate_all_dropdown_files(
36
37
  num_files_written = 0
37
38
  for dropdown_name, dropdown_options in dropdowns.items():
38
39
  dropdown_values = [option.name for option in dropdown_options.options]
39
- options_list = str(dropdown_values).replace("'", '"')
40
+ options_list = json.dumps(dropdown_values, ensure_ascii=False)
40
41
  classname = to_pascal_case(dropdown_name)
41
42
  dropdown_content = f"""
42
43
  from liminal.base.base_dropdown import BaseDropdown
43
44
 
44
45
 
45
46
  class {classname}(BaseDropdown):
46
- __benchling_name__ = "{dropdown_name}"
47
+ __benchling_name__ = {json.dumps(dropdown_name, ensure_ascii=False)}
47
48
  __allowed_values__ = {options_list}
48
49
  """
49
- filename = to_snake_case(dropdown_name) + ".py"
50
+ filename = to_module_name(dropdown_name) + ".py"
50
51
  if overwrite or not (write_path / filename).exists():
51
52
  with open(write_path / filename, "w") as file:
52
53
  file.write(dropdown_content)
@@ -24,7 +24,6 @@ from liminal.dropdowns.utils import (
24
24
  dropdown_exists_in_benchling,
25
25
  get_benchling_dropdown_by_name,
26
26
  get_benchling_dropdown_summary_by_name,
27
- get_schemas_with_dropdown,
28
27
  )
29
28
 
30
29
  LOGGER = logging.getLogger(__name__)
@@ -74,7 +73,7 @@ class CreateDropdown(BaseOperation):
74
73
 
75
74
 
76
75
  class ArchiveDropdown(BaseOperation):
77
- order: ClassVar[int] = 180
76
+ order: ClassVar[int] = 190
78
77
 
79
78
  def __init__(self, dropdown_name: str) -> None:
80
79
  self.dropdown_name = dropdown_name
@@ -85,12 +84,6 @@ class ArchiveDropdown(BaseOperation):
85
84
  raise ValueError(f"Dropdown {self.dropdown_name} is already archived.")
86
85
  return archive_dropdown(benchling_service, dropdown.id)
87
86
 
88
- def validate(self, benchling_service: BenchlingService) -> None:
89
- if schemas_with_dropdown := get_schemas_with_dropdown(self.dropdown_name):
90
- raise ValueError(
91
- f"Dropdown {self.dropdown_name} is used in schemas {schemas_with_dropdown}. Cannot archive a dropdown that is in use in non-archived fields."
92
- )
93
-
94
87
  def describe_operation(self) -> str:
95
88
  return f"{self.dropdown_name}: Archiving dropdown."
96
89
 
@@ -26,6 +26,9 @@ from liminal.utils import to_snake_case
26
26
 
27
27
  LOGGER = logging.getLogger(__name__)
28
28
 
29
+ # Template based naming strategies need the name template, so the order is overridden to be set right after it.
30
+ NAME_TEMPLATE_NAMING_STRATEGY_ORDER = UpdateEntitySchemaNameTemplate.order + 1
31
+
29
32
 
30
33
  def compare_entity_schemas(
31
34
  benchling_service: BenchlingService, schema_names: set[str] | None = None
@@ -237,26 +240,50 @@ def compare_entity_schemas(
237
240
  )
238
241
  )
239
242
  if benchling_schema_props != model.__schema_properties__:
240
- ops.append(
241
- CompareOperation(
242
- op=UpdateEntitySchema(
243
- model.__schema_properties__.warehouse_name,
244
- BaseSchemaProperties(
245
- **benchling_schema_props.merge(
246
- model.__schema_properties__
247
- )
243
+ new_schema_props = BaseSchemaProperties(
244
+ **benchling_schema_props.merge(model.__schema_properties__)
245
+ )
246
+ rollback_schema_props = BaseSchemaProperties(
247
+ **model.__schema_properties__.merge(benchling_schema_props)
248
+ )
249
+ model_strategies = (
250
+ model.__schema_properties__.naming_strategies or set()
251
+ )
252
+ benchling_strategies = benchling_schema_props.naming_strategies or set()
253
+ # A template based naming strategy needs the name template, which runs after UpdateEntitySchema.
254
+ # So when one is being added, set all the naming strategies in their own operation after the template.
255
+ if any(
256
+ BenchlingNamingStrategy.is_template_based(s)
257
+ for s in model_strategies - benchling_strategies
258
+ ):
259
+ new_schema_props.unset_naming_strategies()
260
+ rollback_schema_props.unset_naming_strategies()
261
+ ops.append(
262
+ CompareOperation(
263
+ op=UpdateEntitySchema(
264
+ model_wh_name,
265
+ BaseSchemaProperties(
266
+ naming_strategies=model_strategies
267
+ ),
248
268
  ),
249
- ),
250
- reverse_op=UpdateEntitySchema(
251
- model.__schema_properties__.warehouse_name,
252
- BaseSchemaProperties(
253
- **model.__schema_properties__.merge(
254
- benchling_schema_props
255
- )
269
+ reverse_op=UpdateEntitySchema(
270
+ model_wh_name,
271
+ BaseSchemaProperties(
272
+ naming_strategies=benchling_strategies
273
+ ),
274
+ ),
275
+ order_override=NAME_TEMPLATE_NAMING_STRATEGY_ORDER,
276
+ )
277
+ )
278
+ if new_schema_props.model_dump(exclude_unset=True) != {}:
279
+ ops.append(
280
+ CompareOperation(
281
+ op=UpdateEntitySchema(model_wh_name, new_schema_props),
282
+ reverse_op=UpdateEntitySchema(
283
+ model_wh_name, rollback_schema_props
256
284
  ),
257
285
  ),
258
- ),
259
- )
286
+ )
260
287
  if benchling_name_template != model.__name_template__:
261
288
  ops.append(
262
289
  CompareOperation(
@@ -300,10 +327,23 @@ def compare_entity_schemas(
300
327
  for p in field_props
301
328
  if (p.unit_name and p.warehouse_name)
302
329
  }
330
+ # A link field is created without a target, and Benchling only accepts
331
+ # parent_link on a field that has one, so it is set with the target.
332
+ parent_links_to_update = {
333
+ p.warehouse_name
334
+ for p in field_props
335
+ if (p.parent_link and p.entity_link and p.warehouse_name)
336
+ }
303
337
  field_props = [
304
338
  f.unset_tooltip().unset_entity_link().unset_unit_name()
305
339
  for f in field_props
306
340
  ]
341
+ field_props = [
342
+ f.set_parent_link(False)
343
+ if f.warehouse_name in parent_links_to_update
344
+ else f
345
+ for f in field_props
346
+ ]
307
347
  field_props = [
308
348
  f.set_type(BenchlingFieldType.ENTITY_LINK) if f.entity_link else f
309
349
  for f in field_props
@@ -337,32 +377,20 @@ def compare_entity_schemas(
337
377
  )
338
378
  )
339
379
  # Benchling api does not allow for setting a custom warehouse_name.
340
- # Benchling api also does not allow for setting the name template.
341
380
  # Because of this, we need to run a separate UpdateEntitySchema to set the warehouse_name if it is different from the snakecase version of the model name.
342
- # We also need to set the template based naming_strategies separately, since the name template must first be set.
343
- new_schema_props = BaseSchemaProperties()
344
- rollback_schema_props = BaseSchemaProperties()
381
+ # Later operations on this schema use the model's warehouse_name.
345
382
  if model_wh_name != benchling_given_wh_name:
346
- new_schema_props.warehouse_name = model_wh_name
347
- rollback_schema_props.warehouse_name = benchling_given_wh_name
348
- if (
349
- model.__schema_properties__.naming_strategies
350
- - standard_naming_strategies
351
- ):
352
- new_schema_props.naming_strategies = (
353
- model.__schema_properties__.naming_strategies
354
- )
355
- rollback_schema_props.naming_strategies = standard_naming_strategies
356
- if new_schema_props.model_dump(exclude_unset=True) != {}:
357
383
  ops.append(
358
384
  CompareOperation(
359
385
  op=UpdateEntitySchema(
360
386
  benchling_given_wh_name,
361
- new_schema_props,
387
+ BaseSchemaProperties(warehouse_name=model_wh_name),
362
388
  ),
363
389
  reverse_op=UpdateEntitySchema(
364
390
  model_wh_name,
365
- rollback_schema_props,
391
+ BaseSchemaProperties(
392
+ warehouse_name=benchling_given_wh_name
393
+ ),
366
394
  ),
367
395
  )
368
396
  )
@@ -382,6 +410,9 @@ def compare_entity_schemas(
382
410
  )
383
411
  rollback_field_props.entity_link = None
384
412
  rollback_field_props.type = BenchlingFieldType.ENTITY_LINK
413
+ if wh_field_name in parent_links_to_update:
414
+ new_field_props.parent_link = True
415
+ rollback_field_props.parent_link = False
385
416
  if tooltip_value := tooltips_to_update.get(wh_field_name):
386
417
  new_field_props.tooltip = tooltip_value
387
418
  rollback_field_props.tooltip = None
@@ -403,11 +434,12 @@ def compare_entity_schemas(
403
434
  )
404
435
  # Benchling api also does not allow for setting the name template when Creating an Entity Schema, since it is a different endpoint.
405
436
  # Because of this, we need to run a separate UpdateEntitySchemaNameTemplate using the name template endpoint to set the name template on the newly created Entity Schema.
437
+ # The name template update runs after the field updates above, since a part can need a link target or parent link set there.
406
438
  if benchling_given_name_template != model.__name_template__:
407
439
  ops.append(
408
440
  CompareOperation(
409
441
  op=UpdateEntitySchemaNameTemplate(
410
- benchling_given_wh_name,
442
+ model_wh_name,
411
443
  BaseNameTemplate(
412
444
  **benchling_given_name_template.merge(
413
445
  model.__name_template__
@@ -415,7 +447,7 @@ def compare_entity_schemas(
415
447
  ),
416
448
  ),
417
449
  reverse_op=UpdateEntitySchemaNameTemplate(
418
- benchling_given_wh_name,
450
+ model_wh_name,
419
451
  BaseNameTemplate(
420
452
  **model.__name_template__.merge(
421
453
  benchling_given_name_template
@@ -424,6 +456,28 @@ def compare_entity_schemas(
424
456
  ),
425
457
  )
426
458
  )
459
+ # Template based naming_strategies need the name template, so they are set right after it.
460
+ if (
461
+ model.__schema_properties__.naming_strategies
462
+ - standard_naming_strategies
463
+ ):
464
+ ops.append(
465
+ CompareOperation(
466
+ op=UpdateEntitySchema(
467
+ model_wh_name,
468
+ BaseSchemaProperties(
469
+ naming_strategies=model.__schema_properties__.naming_strategies
470
+ ),
471
+ ),
472
+ reverse_op=UpdateEntitySchema(
473
+ model_wh_name,
474
+ BaseSchemaProperties(
475
+ naming_strategies=standard_naming_strategies
476
+ ),
477
+ ),
478
+ order_override=NAME_TEMPLATE_NAMING_STRATEGY_ORDER,
479
+ )
480
+ )
427
481
 
428
482
  model_operations[model.__schema_properties__.warehouse_name] = ops
429
483
  running_benchling_schema_names = [
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import warnings
3
4
  from functools import lru_cache
4
5
  from typing import Any
5
6
 
@@ -129,18 +130,26 @@ class EntitySchemaFieldModel(BaseModel):
129
130
  self.description = (
130
131
  update_props.tooltip if "tooltip" in update_diff_names else self.description
131
132
  )
132
- if "entity_link" in update_diff_names and update_props.entity_link:
133
- if benchling_service is None:
134
- raise ValueError(
135
- "Benchling SDK must be provided to update entity link field."
133
+ if "entity_link" in update_diff_names:
134
+ if update_props.entity_link is None:
135
+ self.linkDefinition = None
136
+ # Without a target schema the field is a generic entity link, not e.g. a CustomEntityLinkFieldDefinition.
137
+ if BenchlingFieldDefinitionType.is_entity_link(self.typename):
138
+ self.typename = (
139
+ BenchlingFieldDefinitionType.ANY_ENTITY_LINK_FIELD_DEFINITION
140
+ )
141
+ else:
142
+ if benchling_service is None:
143
+ raise ValueError(
144
+ "Benchling SDK must be provided to update entity link field."
145
+ )
146
+ linked_schema = EntitySchemaModel.get_one_cached(
147
+ benchling_service, update_props.entity_link
148
+ )
149
+ self.linkDefinition = FieldLinkDefinitionModel(
150
+ id=linked_schema.id,
151
+ typename=BenchlingLinkDefinitionType(linked_schema.typename.value),
136
152
  )
137
- linked_schema = EntitySchemaModel.get_one_cached(
138
- benchling_service, update_props.entity_link
139
- )
140
- self.linkDefinition = FieldLinkDefinitionModel(
141
- id=linked_schema.id,
142
- typename=BenchlingLinkDefinitionType(linked_schema.typename.value),
143
- )
144
153
  if "type" in update_diff_names and update_props.type:
145
154
  linked_schema_type = (
146
155
  BenchlingEntityTypeName(self.linkDefinition.typename.value)
@@ -484,7 +493,8 @@ class EntitySchemaModel(BaseModel):
484
493
  availableRegistrationNamingOptions: list[BenchlingNamingStrategy] | None = None
485
494
  constraint: EntitySchemaConstraintModel | None = None
486
495
  nameTemplate: NameTemplateModel | None = None
487
- containerNameTemplate: NameTemplateModel | None = None
496
+ # TODO(#263): Add coverage for containerNameTemplate.
497
+ containerNameTemplate: dict[str, Any] | None = None
488
498
  showResidues: bool | None = None
489
499
  typedIconId: str | None = None
490
500
  allowMeasuredIngredients: bool | None = None
@@ -519,7 +529,10 @@ class EntitySchemaModel(BaseModel):
519
529
  try:
520
530
  filtered_schemas.append(cls.model_validate(schema))
521
531
  except Exception as e:
522
- print(f"Error validating schema {schema['systemName']}: {e}")
532
+ warnings.warn(
533
+ f"Skipping schema {schema['systemName']}: failed validation: {e}",
534
+ stacklevel=2,
535
+ )
523
536
  return filtered_schemas
524
537
 
525
538
  @classmethod
@@ -9,7 +9,7 @@ from liminal.entity_schemas.utils import get_converted_entity_schemas
9
9
  from liminal.enums import BenchlingEntityType, BenchlingFieldType
10
10
  from liminal.mappers import map_benchling_type_to_python_type
11
11
  from liminal.orm.name_template import NameTemplate
12
- from liminal.utils import to_pascal_case, to_snake_case
12
+ from liminal.utils import to_module_name, to_python_identifier, to_pascal_case
13
13
 
14
14
 
15
15
  def get_entity_mixin(entity_type: BenchlingEntityType) -> str:
@@ -88,7 +88,7 @@ def generate_all_entity_schema_files(
88
88
 
89
89
  for schema_properties, name_template, columns in models:
90
90
  classname = to_pascal_case(schema_properties.name)
91
- filename = to_snake_case(schema_properties.name) + ".py"
91
+ filename = to_module_name(schema_properties.name) + ".py"
92
92
  columns = {key: columns[key] for key in columns}
93
93
  import_strings = [
94
94
  "from sqlalchemy import Column as SqlColumn",
@@ -109,8 +109,11 @@ def generate_all_entity_schema_files(
109
109
  column_strings = []
110
110
  dropdowns = []
111
111
  relationship_strings = []
112
- for col_name, col in columns.items():
112
+ for wh_col_name, col in columns.items():
113
+ col_name = to_python_identifier(wh_col_name)
113
114
  column_props = col.column_dump()
115
+ if col_name != wh_col_name:
116
+ column_props["_warehouse_name"] = wh_col_name
114
117
  dropdown_classname = None
115
118
  if col.dropdown_link:
116
119
  dropdown_classname = dropdown_name_to_classname_map[col.dropdown_link]
@@ -155,13 +158,14 @@ def generate_all_entity_schema_files(
155
158
  import_strings.append(
156
159
  "from liminal.orm.relationship import multi_relationship"
157
160
  )
158
- for col_name, col in columns.items():
161
+ for wh_col_name, col in columns.items():
162
+ col_name = to_python_identifier(wh_col_name)
159
163
  if not col.required and col.type:
160
164
  init_strings.append(
161
165
  f"""{TAB}{col_name}: {map_benchling_type_to_python_type(col.type).__name__} | None = None,"""
162
166
  )
163
167
  init_strings.append("):")
164
- for col_name in columns.keys():
168
+ for col_name in [to_python_identifier(n) for n in columns.keys()]:
165
169
  init_strings.append(f"{TAB}self.{col_name} = {col_name}")
166
170
  if len(dropdowns) > 0:
167
171
  import_strings.append(f"from ...dropdowns import {', '.join(dropdowns)}")
@@ -171,7 +175,8 @@ def generate_all_entity_schema_files(
171
175
  f"from liminal.orm.name_template_parts import {', '.join(sorted(set([part.__class__.__name__ for part in name_template.parts])))}"
172
176
  ]
173
177
  import_strings.extend(parts_imports)
174
- for col_name, col in columns.items():
178
+ for wh_col_name, col in columns.items():
179
+ col_name = to_python_identifier(wh_col_name)
175
180
  if col.dropdown_link:
176
181
  init_strings.append(
177
182
  TAB
@@ -41,7 +41,7 @@ LOGGER = logging.getLogger(__name__)
41
41
 
42
42
 
43
43
  class CreateEntitySchema(BaseOperation):
44
- order: ClassVar[int] = 80
44
+ order: ClassVar[int] = 90
45
45
 
46
46
  def __init__(
47
47
  self,
@@ -81,10 +81,10 @@ class CreateEntitySchema(BaseOperation):
81
81
  )
82
82
 
83
83
  def describe_operation(self) -> str:
84
- return f"{self._validated_schema_properties.name}: Creating new entity schema with fields: {', '.join([f.warehouse_name for f in self.fields if f.warehouse_name is not None])}."
84
+ return f"{self._validated_schema_properties.warehouse_name}: Creating new entity schema with fields: {', '.join([f.warehouse_name for f in self.fields if f.warehouse_name is not None])}."
85
85
 
86
86
  def describe(self) -> str:
87
- return f"{self._validated_schema_properties.name}: Schema is defined in code but not in Benchling."
87
+ return f"{self._validated_schema_properties.warehouse_name}: Schema is defined in code but not in Benchling."
88
88
 
89
89
  def validate(self, benchling_service: BenchlingService) -> None:
90
90
  if (
@@ -154,9 +154,13 @@ class CreateEntitySchema(BaseOperation):
154
154
  schema, entity_schema_id_to_name_map, dropdowns_map, unit_id_to_name_map
155
155
  )
156
156
  )
157
+ # Warehouse name exists in the Liminal operation definition but not in Benchling converted list.
158
+ # Set the warehouse name to None for operation fields to compare properly.
159
+ cleaned_op_fields = [f.set_warehouse_name(None) for f in self.fields]
160
+ benchling_fields = [f for _, f in benchling_fields_props.items()]
157
161
  if (
158
162
  self._validated_schema_properties != benchling_schema_props
159
- or self.fields != [f for _, f in benchling_fields_props.items()]
163
+ or cleaned_op_fields != benchling_fields
160
164
  ):
161
165
  raise ValueError(
162
166
  f"Entity schema {self._validated_schema_properties.warehouse_name} is different in code versus Benchling. Cannot unarchive."
@@ -165,7 +169,7 @@ class CreateEntitySchema(BaseOperation):
165
169
 
166
170
 
167
171
  class ArchiveEntitySchema(BaseOperation):
168
- order: ClassVar[int] = 170
172
+ order: ClassVar[int] = 180
169
173
 
170
174
  def __init__(self, wh_schema_name: str) -> None:
171
175
  self.wh_schema_name = wh_schema_name
@@ -193,7 +197,7 @@ class ArchiveEntitySchema(BaseOperation):
193
197
 
194
198
 
195
199
  class UnarchiveEntitySchema(BaseOperation):
196
- order: ClassVar[int] = 90
200
+ order: ClassVar[int] = 100
197
201
 
198
202
  def __init__(self, wh_schema_name: str) -> None:
199
203
  self.wh_schema_name = wh_schema_name
@@ -290,7 +294,7 @@ class UpdateEntitySchema(BaseOperation):
290
294
 
291
295
 
292
296
  class UpdateEntitySchemaNameTemplate(BaseOperation):
293
- order: ClassVar[int] = 110
297
+ order: ClassVar[int] = 150
294
298
 
295
299
  def __init__(
296
300
  self,
@@ -329,7 +333,7 @@ class UpdateEntitySchemaNameTemplate(BaseOperation):
329
333
 
330
334
 
331
335
  class CreateEntitySchemaField(BaseOperation):
332
- order: ClassVar[int] = 100
336
+ order: ClassVar[int] = 110
333
337
 
334
338
  def __init__(
335
339
  self,
@@ -442,7 +446,7 @@ class CreateEntitySchemaField(BaseOperation):
442
446
 
443
447
 
444
448
  class ArchiveEntitySchemaField(BaseOperation):
445
- order: ClassVar[int] = 150
449
+ order: ClassVar[int] = 160
446
450
 
447
451
  def __init__(
448
452
  self, wh_schema_name: str, wh_field_name: str, index: int | None = None
@@ -634,7 +638,7 @@ class UpdateEntitySchemaField(BaseOperation):
634
638
 
635
639
 
636
640
  class ReorderEntitySchemaFields(BaseOperation):
637
- order: ClassVar[int] = 160
641
+ order: ClassVar[int] = 170
638
642
 
639
643
  def __init__(self, wh_schema_name: str, new_order: list[str]) -> None:
640
644
  self.wh_schema_name = wh_schema_name
@@ -164,7 +164,7 @@ def convert_entity_schema_field_to_field_properties(
164
164
  if field.linkDefinition
165
165
  and field.linkDefinition.typename == BenchlingLinkDefinitionType.DROPDOWN
166
166
  else None,
167
- parent_link=field.isParent,
167
+ parent_link=field.isParent or False,
168
168
  entity_link=entity_schema_id_to_name_map.get(field.linkDefinition.id)
169
169
  if links_to_entity_schema
170
170
  else None,
@@ -104,9 +104,9 @@ class Column(SqlColumn):
104
104
  raise ValueError(
105
105
  f"Column {name}: Entity link can only be set if the field type is one of {BenchlingFieldType.get_entity_link_types()}."
106
106
  )
107
- if parent_link and type not in BenchlingFieldType.get_entity_link_types():
107
+ if parent_link and type != BenchlingFieldType.ENTITY_LINK:
108
108
  raise ValueError(
109
- f"Column {name}: Parent link can only be set if the field type is one of {BenchlingFieldType.get_entity_link_types()}."
109
+ f"Column {name}: Parent link can only be set if the field type is ENTITY_LINK."
110
110
  )
111
111
  if type in BenchlingFieldType.get_non_multi_select_types() and is_multi is True:
112
112
  raise ValueError(