liminal-orm 4.7.0__tar.gz → 5.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.
Files changed (310) hide show
  1. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/PKG-INFO +1 -6
  2. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/base/base_operation.py +15 -14
  3. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/base/name_template_parts.py +1 -1
  4. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/base/properties/base_field_properties.py +17 -0
  5. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/cli/cli.py +26 -11
  6. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/cli/controller.py +1 -1
  7. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/cli/live_test_entity_schema_migration.py +16 -0
  8. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/cli/utils.py +2 -2
  9. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/connection/benchling_connection.py +29 -8
  10. liminal_orm-5.0.0/liminal/connection/benchling_service.py +245 -0
  11. liminal_orm-5.0.0/liminal/dropdowns/api.py +149 -0
  12. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/dropdowns/compare.py +4 -2
  13. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/dropdowns/operations.py +101 -71
  14. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/dropdowns/utils.py +55 -51
  15. liminal_orm-5.0.0/liminal/entity_schemas/api.py +244 -0
  16. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/entity_schemas/compare.py +13 -30
  17. liminal_orm-5.0.0/liminal/entity_schemas/entity_schema_models.py +822 -0
  18. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/entity_schemas/generate_files.py +8 -19
  19. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/entity_schemas/operations.py +185 -141
  20. liminal_orm-5.0.0/liminal/entity_schemas/utils.py +186 -0
  21. liminal_orm-5.0.0/liminal/enums/__init__.py +15 -0
  22. liminal_orm-5.0.0/liminal/enums/benchling_entity_schema_endpoint_type.py +15 -0
  23. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/enums/benchling_entity_type.py +1 -1
  24. liminal_orm-5.0.0/liminal/enums/benchling_entity_type_name.py +15 -0
  25. liminal_orm-5.0.0/liminal/enums/benchling_field_definition_input_type.py +94 -0
  26. liminal_orm-5.0.0/liminal/enums/benchling_field_definition_type.py +85 -0
  27. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/enums/benchling_field_type.py +3 -1
  28. liminal_orm-5.0.0/liminal/enums/benchling_link_definition_type.py +31 -0
  29. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/enums/benchling_naming_strategy.py +2 -0
  30. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/enums/name_template_part_type.py +2 -0
  31. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/external/__init__.py +1 -3
  32. liminal_orm-5.0.0/liminal/mappers.py +343 -0
  33. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/migrate/revisions_timeline.py +20 -0
  34. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/base_model.py +5 -5
  35. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/column.py +8 -3
  36. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/relationship.py +2 -2
  37. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/schema_properties.py +29 -4
  38. liminal_orm-5.0.0/liminal/results_schemas/api.py +53 -0
  39. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/results_schemas/generate_files.py +13 -16
  40. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/results_schemas/models/results_schema_model.py +54 -36
  41. liminal_orm-5.0.0/liminal/results_schemas/utils.py +105 -0
  42. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/tests/conftest.py +0 -21
  43. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/tests/test_entity_schema_compare.py +6 -11
  44. liminal_orm-5.0.0/liminal/utils.py +237 -0
  45. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/pyproject.toml +2 -8
  46. liminal_orm-4.7.0/liminal/connection/benchling_service.py +0 -411
  47. liminal_orm-4.7.0/liminal/dropdowns/api.py +0 -175
  48. liminal_orm-4.7.0/liminal/entity_schemas/api.py +0 -95
  49. liminal_orm-4.7.0/liminal/entity_schemas/entity_schema_models.py +0 -209
  50. liminal_orm-4.7.0/liminal/entity_schemas/entity_schema_models_v3.py +0 -100
  51. liminal_orm-4.7.0/liminal/entity_schemas/tag_schema_models.py +0 -613
  52. liminal_orm-4.7.0/liminal/entity_schemas/utils.py +0 -149
  53. liminal_orm-4.7.0/liminal/enums/__init__.py +0 -8
  54. liminal_orm-4.7.0/liminal/enums/benchling_api_field_type.py +0 -23
  55. liminal_orm-4.7.0/liminal/enums/benchling_folder_item_type.py +0 -10
  56. liminal_orm-4.7.0/liminal/enums/benchling_sequence_type.py +0 -8
  57. liminal_orm-4.7.0/liminal/mappers.py +0 -272
  58. liminal_orm-4.7.0/liminal/results_schemas/utils.py +0 -48
  59. liminal_orm-4.7.0/liminal/utils.py +0 -96
  60. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.gitignore +0 -0
  61. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/__init__.py +0 -0
  62. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_dropdown.py +0 -0
  63. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_operation.py +0 -0
  64. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_validation_filters.py +0 -0
  65. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/compare_operation.py +0 -0
  66. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/name_template_parts.py +0 -0
  67. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_field_properties.py +0 -0
  68. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_name_template.py +0 -0
  69. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_schema_properties.py +0 -0
  70. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/str_enum.py +0 -0
  71. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/cli.py +0 -0
  72. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/controller.py +0 -0
  73. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/live_test_dropdown_migration.py +0 -0
  74. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/live_test_entity_schema_migration.py +0 -0
  75. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/utils.py +0 -0
  76. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/__init__.py +0 -0
  77. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/benchling_connection.py +0 -0
  78. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/benchling_service.py +0 -0
  79. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/api.py +0 -0
  80. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/compare.py +0 -0
  81. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/generate_files.py +0 -0
  82. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/operations.py +0 -0
  83. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/utils.py +0 -0
  84. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/api.py +0 -0
  85. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/compare.py +0 -0
  86. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/entity_schema_models.py +0 -0
  87. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/generate_files.py +0 -0
  88. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/operations.py +0 -0
  89. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/tag_schema_models.py +0 -0
  90. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/utils.py +0 -0
  91. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/__init__.py +0 -0
  92. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_api_field_type.py +0 -0
  93. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_entity_type.py +0 -0
  94. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_field_type.py +0 -0
  95. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_folder_item_type.py +0 -0
  96. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_naming_strategy.py +0 -0
  97. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_sequence_type.py +0 -0
  98. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/name_template_part_type.py +0 -0
  99. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/sequence_constraint.py +0 -0
  100. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/external/__init__.py +0 -0
  101. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/mappers.py +0 -0
  102. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/components.py +0 -0
  103. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/revision.py +0 -0
  104. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/revisions_timeline.py +0 -0
  105. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base.py +0 -0
  106. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_model.py +0 -0
  107. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_results_model.py +0 -0
  108. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/registry_entity.py +0 -0
  109. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/schema.py +0 -0
  110. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/user.py +0 -0
  111. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/column.py +0 -0
  112. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/mixins.py +0 -0
  113. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/name_template.py +0 -0
  114. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/name_template_parts.py +0 -0
  115. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/relationship.py +0 -0
  116. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/results_schema_properties.py +0 -0
  117. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/schema_properties.py +0 -0
  118. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/py.typed +0 -0
  119. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/generate_files.py +0 -0
  120. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/models/results_schema_model.py +0 -0
  121. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/utils.py +0 -0
  122. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/__init__.py +0 -0
  123. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/conftest.py +0 -0
  124. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/from benchling_sdk.py +0 -0
  125. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_benchling_service.py +0 -0
  126. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_dataframe_compatibility.py +0 -0
  127. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_dropdown_compare.py +0 -0
  128. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_entity_schema_compare.py +0 -0
  129. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/unit_dictionary/utils.py +0 -0
  130. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/utils.py +0 -0
  131. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/validation/__init__.py +0 -0
  132. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/validation/validation_severity.py +0 -0
  133. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/__init__.py +0 -0
  134. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/base_dropdown.py +0 -0
  135. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/base_operation.py +0 -0
  136. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/base_validation_filters.py +0 -0
  137. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/compare_operation.py +0 -0
  138. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/name_template_parts.py +0 -0
  139. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/properties/base_field_properties.py +0 -0
  140. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/properties/base_name_template.py +0 -0
  141. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/properties/base_schema_properties.py +0 -0
  142. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/base/str_enum.py +0 -0
  143. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/cli/cli.py +0 -0
  144. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/cli/controller.py +0 -0
  145. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/cli/live_test_dropdown_migration.py +0 -0
  146. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/cli/live_test_entity_schema_migration.py +0 -0
  147. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/cli/utils.py +0 -0
  148. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/connection/__init__.py +0 -0
  149. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/connection/benchling_connection.py +0 -0
  150. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/connection/benchling_service.py +0 -0
  151. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/dropdowns/api.py +0 -0
  152. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/dropdowns/compare.py +0 -0
  153. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/dropdowns/generate_files.py +0 -0
  154. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/dropdowns/operations.py +0 -0
  155. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/dropdowns/utils.py +0 -0
  156. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/api.py +0 -0
  157. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/compare.py +0 -0
  158. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/entity_schema_models.py +0 -0
  159. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/generate_files.py +0 -0
  160. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/operations.py +0 -0
  161. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/tag_schema_models.py +0 -0
  162. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/entity_schemas/utils.py +0 -0
  163. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/__init__.py +0 -0
  164. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_api_field_type.py +0 -0
  165. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_entity_type.py +0 -0
  166. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_field_type.py +0 -0
  167. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_folder_item_type.py +0 -0
  168. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_naming_strategy.py +0 -0
  169. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/benchling_sequence_type.py +0 -0
  170. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/name_template_part_type.py +0 -0
  171. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/enums/sequence_constraint.py +0 -0
  172. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/external/__init__.py +0 -0
  173. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/mappers.py +0 -0
  174. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/migrate/components.py +0 -0
  175. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/migrate/revision.py +0 -0
  176. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/migrate/revisions_timeline.py +0 -0
  177. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base.py +0 -0
  178. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base_model.py +0 -0
  179. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base_results_model.py +0 -0
  180. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base_tables/registry_entity.py +0 -0
  181. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base_tables/schema.py +0 -0
  182. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/base_tables/user.py +0 -0
  183. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/column.py +0 -0
  184. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/mixins.py +0 -0
  185. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/name_template.py +0 -0
  186. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/name_template_parts.py +0 -0
  187. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/relationship.py +0 -0
  188. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/results_schema_properties.py +0 -0
  189. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/orm/schema_properties.py +0 -0
  190. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/py.typed +0 -0
  191. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/results_schemas/generate_files.py +0 -0
  192. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/results_schemas/models/results_schema_model.py +0 -0
  193. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/results_schemas/utils.py +0 -0
  194. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/__init__.py +0 -0
  195. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/conftest.py +0 -0
  196. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/from benchling_sdk.py +0 -0
  197. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/test_benchling_service.py +0 -0
  198. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/test_dataframe_compatibility.py +0 -0
  199. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/test_dropdown_compare.py +0 -0
  200. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/tests/test_entity_schema_compare.py +0 -0
  201. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/unit_dictionary/utils.py +0 -0
  202. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/utils.py +0 -0
  203. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/validation/__init__.py +0 -0
  204. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/arvZabAJhner6mVH/liminal/validation/validation_severity.py +0 -0
  205. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/__init__.py +0 -0
  206. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_dropdown.py +0 -0
  207. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_operation.py +0 -0
  208. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/base_validation_filters.py +0 -0
  209. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/compare_operation.py +0 -0
  210. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/name_template_parts.py +0 -0
  211. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_field_properties.py +0 -0
  212. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_name_template.py +0 -0
  213. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/properties/base_schema_properties.py +0 -0
  214. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/base/str_enum.py +0 -0
  215. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/cli.py +0 -0
  216. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/controller.py +0 -0
  217. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/live_test_dropdown_migration.py +0 -0
  218. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/live_test_entity_schema_migration.py +0 -0
  219. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/cli/utils.py +0 -0
  220. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/__init__.py +0 -0
  221. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/benchling_connection.py +0 -0
  222. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/connection/benchling_service.py +0 -0
  223. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/api.py +0 -0
  224. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/compare.py +0 -0
  225. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/generate_files.py +0 -0
  226. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/operations.py +0 -0
  227. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/dropdowns/utils.py +0 -0
  228. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/api.py +0 -0
  229. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/compare.py +0 -0
  230. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/entity_schema_models.py +0 -0
  231. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/generate_files.py +0 -0
  232. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/operations.py +0 -0
  233. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/tag_schema_models.py +0 -0
  234. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/entity_schemas/utils.py +0 -0
  235. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/__init__.py +0 -0
  236. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_api_field_type.py +0 -0
  237. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_entity_type.py +0 -0
  238. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_field_type.py +0 -0
  239. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_folder_item_type.py +0 -0
  240. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_naming_strategy.py +0 -0
  241. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/benchling_sequence_type.py +0 -0
  242. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/name_template_part_type.py +0 -0
  243. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/enums/sequence_constraint.py +0 -0
  244. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/external/__init__.py +0 -0
  245. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/mappers.py +0 -0
  246. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/components.py +0 -0
  247. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/revision.py +0 -0
  248. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/migrate/revisions_timeline.py +0 -0
  249. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base.py +0 -0
  250. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_model.py +0 -0
  251. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_results_model.py +0 -0
  252. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/registry_entity.py +0 -0
  253. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/schema.py +0 -0
  254. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/base_tables/user.py +0 -0
  255. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/column.py +0 -0
  256. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/mixins.py +0 -0
  257. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/name_template.py +0 -0
  258. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/name_template_parts.py +0 -0
  259. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/relationship.py +0 -0
  260. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/results_schema_properties.py +0 -0
  261. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/orm/schema_properties.py +0 -0
  262. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/py.typed +0 -0
  263. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/generate_files.py +0 -0
  264. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/models/results_schema_model.py +0 -0
  265. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/results_schemas/utils.py +0 -0
  266. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/__init__.py +0 -0
  267. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/conftest.py +0 -0
  268. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/from benchling_sdk.py +0 -0
  269. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_benchling_service.py +0 -0
  270. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_dataframe_compatibility.py +0 -0
  271. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_dropdown_compare.py +0 -0
  272. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/tests/test_entity_schema_compare.py +0 -0
  273. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/unit_dictionary/utils.py +0 -0
  274. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/utils.py +0 -0
  275. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/validation/__init__.py +0 -0
  276. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/.uv-cache/archive-v0/eXa8KUkHhZHOAuoK/liminal/validation/validation_severity.py +0 -0
  277. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/LICENSE.md +0 -0
  278. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/README.md +0 -0
  279. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/__init__.py +0 -0
  280. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/base/base_dropdown.py +0 -0
  281. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/base/base_validation_filters.py +0 -0
  282. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/base/compare_operation.py +0 -0
  283. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/base/properties/base_name_template.py +0 -0
  284. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/base/properties/base_schema_properties.py +0 -0
  285. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/base/str_enum.py +0 -0
  286. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/cli/live_test_dropdown_migration.py +0 -0
  287. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/connection/__init__.py +0 -0
  288. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/dropdowns/generate_files.py +0 -0
  289. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/entity_schemas/test_entity_dataframe_compatibility.py +0 -0
  290. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/enums/sequence_constraint.py +0 -0
  291. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/migrate/components.py +0 -0
  292. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/migrate/revision.py +0 -0
  293. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/base.py +0 -0
  294. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/base_results_model.py +0 -0
  295. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/base_tables/registry_entity.py +0 -0
  296. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/base_tables/schema.py +0 -0
  297. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/base_tables/user.py +0 -0
  298. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/mixins.py +0 -0
  299. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/name_template.py +0 -0
  300. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/name_template_parts.py +0 -0
  301. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/orm/results_schema_properties.py +0 -0
  302. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/py.typed +0 -0
  303. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/results_schemas/test_results_dataframe_compatibility.py +0 -0
  304. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/tests/__init__.py +0 -0
  305. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/tests/from benchling_sdk.py +0 -0
  306. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/tests/test_benchling_service.py +0 -0
  307. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/tests/test_dropdown_compare.py +0 -0
  308. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/unit_dictionary/utils.py +0 -0
  309. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/validation/__init__.py +0 -0
  310. {liminal_orm-4.7.0 → liminal_orm-5.0.0}/liminal/validation/validation_severity.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: liminal-orm
3
- Version: 4.7.0
3
+ Version: 5.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
  Project-URL: Homepage, https://github.com/dynotx/liminal-orm
6
6
  Project-URL: Repository, https://github.com/dynotx/liminal-orm
@@ -15,9 +15,7 @@ Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: Programming Language :: Python :: 3.13
16
16
  Requires-Python: <3.14,>=3.10
17
17
  Requires-Dist: benchling-sdk<2,>=1.21.2
18
- Requires-Dist: bs4<0.0.3,>=0.0.2
19
18
  Requires-Dist: click<8.2.0,>=8.0.0
20
- Requires-Dist: lxml<6,>=5.3.0
21
19
  Requires-Dist: numpy<2,>=1.23.5; python_version < '3.12'
22
20
  Requires-Dist: numpy<2,>=1.26; python_version == '3.12'
23
21
  Requires-Dist: numpy<3,>=2.1; python_version == '3.13'
@@ -25,14 +23,11 @@ Requires-Dist: pandas<3,>=1.5.3; python_version == '3.10'
25
23
  Requires-Dist: pandas<4,>=1.5.3; python_version == '3.11'
26
24
  Requires-Dist: pandas<4,>=2.2.3; python_version == '3.13'
27
25
  Requires-Dist: pandas<4,>=2.2; python_version == '3.12'
28
- Requires-Dist: playwright>=1.58.0
29
26
  Requires-Dist: psycopg2-binary<3,>=2.9.10
30
27
  Requires-Dist: pydantic<=2.13,>=2
31
- Requires-Dist: requests<3,>=2.32.3
32
28
  Requires-Dist: rich<14,>=13.9.2
33
29
  Requires-Dist: sqlalchemy<2,>=1.4.53
34
30
  Requires-Dist: tenacity<10,>=8
35
- Requires-Dist: tornado==6.5.0
36
31
  Requires-Dist: typer<0.13,>=0.12.5
37
32
  Description-Content-Type: text/markdown
38
33
 
@@ -9,20 +9,21 @@ Order of operations based on order class var:
9
9
  2. UpdateDropdownName
10
10
  3. UnarchiveDropdown
11
11
  4. CreateDropdownOption
12
- 5. UpdateDropdownOption
13
- 6. ArchiveDropdownOption
14
- 7. ReorderDropdownOptions
15
- 8. CreateSchema
16
- 9. UnarchiveSchema
17
- 10. CreateField
18
- 11. UpdateEntitySchemaNameTemplate
19
- 12. UpdateSchema
20
- 13. UnarchiveField
21
- 14. UpdateField
22
- 15. ArchiveField
23
- 16. ReorderFields
24
- 17. ArchiveSchema
25
- 18. ArchiveDropdown
12
+ 5. UnarchiveDropdownOption
13
+ 6. UpdateDropdownOption
14
+ 7. ArchiveDropdownOption
15
+ 8. ReorderDropdownOptions
16
+ 9. CreateEntitySchema
17
+ 10. UnarchiveEntitySchema
18
+ 11. CreateEntitySchemaField
19
+ 12. UpdateEntitySchemaNameTemplate
20
+ 13. UpdateEntitySchema
21
+ 14. UnarchiveEntitySchemaField
22
+ 15. UpdateEntitySchemaField
23
+ 16. ArchiveEntitySchemaField
24
+ 17. ReorderEntitySchemaFields
25
+ 18. ArchiveEntitySchema
26
+ 19. ArchiveDropdown
26
27
  """
27
28
 
28
29
 
@@ -3,6 +3,6 @@ import warnings
3
3
  from liminal.orm.name_template_parts import * # noqa: F403
4
4
 
5
5
  warnings.warn(
6
- "Importing from 'liminal.base.name_template_parts' is deprecated. Please import from 'liminal.orm.name_template_parts' instead. This will be removed in v5.",
6
+ "Importing from 'liminal.base.name_template_parts' is deprecated. Please import from 'liminal.orm.name_template_parts' instead. This will be removed in v6.",
7
7
  FutureWarning,
8
8
  )
@@ -56,6 +56,23 @@ class BaseFieldProperties(BaseModel):
56
56
  super().__init__(**data)
57
57
  self._archived = data.get("_archived", None)
58
58
 
59
+ @staticmethod
60
+ def unsupported_field_properties(
61
+ field_type: BenchlingFieldType, has_entity_link: bool
62
+ ) -> set[str]:
63
+ """Returns the properties that Benchling does not support for the given field type."""
64
+ unsupported: set[str] = set()
65
+ non_multi_types = BenchlingFieldType.get_non_multi_select_types()
66
+ if field_type in non_multi_types:
67
+ unsupported.add("is_multi")
68
+ if not (has_entity_link and field_type == BenchlingFieldType.ENTITY_LINK):
69
+ unsupported.add("parent_link")
70
+ if field_type not in BenchlingFieldType.get_number_field_types():
71
+ unsupported.add("unit_name")
72
+ if field_type != BenchlingFieldType.DECIMAL:
73
+ unsupported.add("decimal_places")
74
+ return unsupported
75
+
59
76
  def set_archived(self, value: bool) -> BaseFieldProperties:
60
77
  self._archived = value
61
78
  return self
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env python
2
2
  from pathlib import Path
3
3
  from typing import Any
4
+
4
5
  import typer
5
6
  from rich import print
6
7
  from typer.core import TyperGroup
@@ -67,8 +68,6 @@ connection = BenchlingConnection(
67
68
  api_client_id="my-secret-api-client-id",
68
69
  api_client_secret="my-secret-api-client-secret",
69
70
  warehouse_connection_string="...",
70
- internal_api_admin_email="my-secret-internal-api-admin-email",
71
- internal_api_admin_password="my-secret-internal-api-admin-password",
72
71
  config_flags=TenantConfigFlags(...)
73
72
  )
74
73
  """
@@ -119,7 +118,7 @@ def generate_files(
119
118
  ),
120
119
  ) -> None:
121
120
  benchling_connection = read_local_liminal_dir(LIMINAL_DIR_PATH, benchling_tenant)
122
- benchling_service = BenchlingService(benchling_connection, use_internal_api=True)
121
+ benchling_service = BenchlingService(benchling_connection)
123
122
  if not write_path.exists():
124
123
  write_path.mkdir()
125
124
  print(f"[green]Created directory: {write_path}")
@@ -147,17 +146,33 @@ def current(
147
146
  ),
148
147
  ) -> None:
149
148
  benchling_connection = read_local_liminal_dir(LIMINAL_DIR_PATH, benchling_tenant)
150
- benchling_service = BenchlingService(benchling_connection, use_internal_api=True)
149
+ benchling_service = BenchlingService(benchling_connection)
151
150
  remote_revision_id = benchling_service.get_remote_revision_id()
152
151
  print(f"[blue]Current remote revision_id: {remote_revision_id}.")
153
152
 
154
153
 
155
154
  @app.command(
156
155
  name="head",
157
- help="Returns the local heads, or the latest revision_id, in your linear revision timeline.",
156
+ help="Returns the local heads, or the latest revision_id, in your linear revision timeline. Pass --reset to delete the local head revision file.",
158
157
  )
159
- def head() -> None:
158
+ def head(
159
+ reset: bool = typer.Option(
160
+ False,
161
+ "-r",
162
+ "--reset",
163
+ help="Deletes the local head revision file, making its down_revision the new head. Only use this for revisions that have not been applied to any tenant.",
164
+ ),
165
+ ) -> None:
160
166
  revision_timeline = RevisionsTimeline(VERSIONS_DIR_PATH)
167
+ if reset:
168
+ latest_revision = revision_timeline.get_latest_revision()
169
+ file_path = VERSIONS_DIR_PATH / latest_revision.revision_file_name
170
+ print(
171
+ f"[bold yellow]Delete local head revision file {latest_revision.id} ({file_path})?[/bold yellow]"
172
+ )
173
+ typer.confirm("Confirm", abort=True)
174
+ revision_timeline.delete_latest_revision()
175
+ print(f"[dim]Deleted revision file {file_path}.")
161
176
  print(f"[blue]{revision_timeline.get_latest_revision().id}: (head)[/blue]")
162
177
 
163
178
 
@@ -180,7 +195,7 @@ def revision(
180
195
  ),
181
196
  ) -> None:
182
197
  benchling_connection = read_local_liminal_dir(LIMINAL_DIR_PATH, benchling_tenant)
183
- benchling_service = BenchlingService(benchling_connection, use_internal_api=True)
198
+ benchling_service = BenchlingService(benchling_connection)
184
199
  revisions_timeline = RevisionsTimeline(VERSIONS_DIR_PATH)
185
200
  is_init_revision = revisions_timeline.is_only_init_revision()
186
201
  if is_init_revision:
@@ -214,7 +229,7 @@ def autogenerate(
214
229
  ),
215
230
  ) -> None:
216
231
  raise DeprecationWarning(
217
- "CLI command `liminal autogenerate ...` is deprecated and will be removed in v5. Please use `liminal revision ...` instead."
232
+ "CLI command `liminal autogenerate ...` is deprecated and will be removed in v6. Please use `liminal revision ...` instead."
218
233
  )
219
234
 
220
235
 
@@ -233,7 +248,7 @@ def upgrade(
233
248
  ),
234
249
  ) -> None:
235
250
  benchling_connection = read_local_liminal_dir(LIMINAL_DIR_PATH, benchling_tenant)
236
- benchling_service = BenchlingService(benchling_connection, use_internal_api=True)
251
+ benchling_service = BenchlingService(benchling_connection)
237
252
  current_revision_id = benchling_service.get_remote_revision_id()
238
253
  revisions_timeline = RevisionsTimeline(VERSIONS_DIR_PATH)
239
254
  upgrade_revision_id = upgrade_benchling_tenant(
@@ -261,7 +276,7 @@ def downgrade(
261
276
  ),
262
277
  ) -> None:
263
278
  benchling_connection = read_local_liminal_dir(LIMINAL_DIR_PATH, benchling_tenant)
264
- benchling_service = BenchlingService(benchling_connection, use_internal_api=True)
279
+ benchling_service = BenchlingService(benchling_connection)
265
280
  current_revision_id = benchling_service.get_remote_revision_id()
266
281
  revisions_timeline = RevisionsTimeline(VERSIONS_DIR_PATH)
267
282
  downgrade_revision_id = downgrade_benchling_tenant(
@@ -301,7 +316,7 @@ def live_test(
301
316
  "Only one of --entity-schema-migration or --dropdown-migration can be set."
302
317
  )
303
318
  benchling_connection = read_local_liminal_dir(LIMINAL_DIR_PATH, benchling_tenant)
304
- benchling_service = BenchlingService(benchling_connection, use_internal_api=True)
319
+ benchling_service = BenchlingService(benchling_connection)
305
320
  if test_entity_schema_migration:
306
321
  mock_entity_schema_full_migration(
307
322
  benchling_service, "test_dont_touch", dry_run=not execute
@@ -76,7 +76,7 @@ def autogenerate_revision_file(
76
76
  )
77
77
  if current_revision_id != revisions_timeline.get_latest_revision().id:
78
78
  raise Exception(
79
- f"Your target Benchling tenant is currently at revision_id {current_revision_id}, which is not up to date with the local head revision ({revisions_timeline.get_latest_revision().id}). Please upgrade your tenant to the latest revision before generating a new revision."
79
+ f"Your target Benchling tenant is currently at revision_id {current_revision_id}, which is not up to date with the local head revision ({revisions_timeline.get_latest_revision().id}). Please upgrade your tenant to the latest revision before generating a new revision. If the local head revision should not be applied, run `liminal head --reset` to delete it."
80
80
  )
81
81
  if compare:
82
82
  compare_ops = get_full_migration_operations(benchling_service)
@@ -1,5 +1,6 @@
1
1
  from liminal.base.base_operation import BaseOperation
2
2
  from liminal.base.properties.base_field_properties import BaseFieldProperties
3
+ from liminal.base.properties.base_name_template import BaseNameTemplate
3
4
  from liminal.base.properties.base_schema_properties import BaseSchemaProperties
4
5
  from liminal.connection.benchling_service import BenchlingService
5
6
  from liminal.entity_schemas.operations import (
@@ -12,6 +13,7 @@ from liminal.entity_schemas.operations import (
12
13
  UnarchiveEntitySchemaField,
13
14
  UpdateEntitySchema,
14
15
  UpdateEntitySchemaField,
16
+ UpdateEntitySchemaNameTemplate,
15
17
  )
16
18
  from liminal.enums import (
17
19
  BenchlingEntityType,
@@ -19,6 +21,7 @@ from liminal.enums import (
19
21
  BenchlingNamingStrategy,
20
22
  )
21
23
  from liminal.migrate.components import execute_operations, execute_operations_dry_run
24
+ from liminal.orm.name_template_parts import FieldPart, SeparatorPart, TextPart
22
25
  from liminal.orm.schema_properties import SchemaProperties
23
26
  from liminal.utils import generate_random_id
24
27
 
@@ -122,6 +125,18 @@ def mock_entity_schema_full_migration(
122
125
  ["test_column_1", "test_column_2", "test_column_3", "test_column_4"],
123
126
  )
124
127
 
128
+ update_name_template_op = UpdateEntitySchemaNameTemplate(
129
+ test_model_wh_name,
130
+ BaseNameTemplate(
131
+ parts=[
132
+ TextPart(value="TEST"),
133
+ SeparatorPart(value="-"),
134
+ FieldPart(wh_field_name="test_column_1"),
135
+ ],
136
+ order_name_parts_by_sequence=False,
137
+ ),
138
+ )
139
+
125
140
  archive_entity_schema_op = ArchiveEntitySchema(test_model_wh_name)
126
141
  unarchive_entity_schema_op = UnarchiveEntitySchema(test_model_wh_name)
127
142
  rearchive_entity_schema_op = ArchiveEntitySchema(test_model_wh_name)
@@ -134,6 +149,7 @@ def mock_entity_schema_full_migration(
134
149
  archive_entity_schema_field_op,
135
150
  unarchive_entity_schema_field_op,
136
151
  reorder_entity_schema_field_op,
152
+ update_name_template_op,
137
153
  archive_entity_schema_op,
138
154
  unarchive_entity_schema_op,
139
155
  rearchive_entity_schema_op,
@@ -25,7 +25,7 @@ def read_local_liminal_dir(
25
25
  liminal_dir_path: Path, benchling_tenant: str
26
26
  ) -> BenchlingConnection:
27
27
  """Imports the env.py file from /liminal/env.py and returns the BenchlingConnection object.
28
- The BenchlingConnection object is expected to be defined and have connection information for the Benchling API client and internal API.
28
+ The BenchlingConnection object is expected to be defined and have connection information for the Benchling API client.
29
29
  """
30
30
  _check_liminal_directory_initialized(liminal_dir_path)
31
31
  env_file_path = liminal_dir_path / "env.py"
@@ -36,7 +36,7 @@ def _read_local_env_file(
36
36
  env_file_path: Path, benchling_tenant: str
37
37
  ) -> BenchlingConnection:
38
38
  """Imports the env.py file from the current working directory and returns the BenchlingConnection object.
39
- The BenchlingConnection object is expected to be defined and have connection information for the Benchling API client and internal API.
39
+ The BenchlingConnection object is expected to be defined and have connection information for the Benchling API client.
40
40
  """
41
41
  module_path = Path.cwd() / env_file_path
42
42
  spec = importlib.util.spec_from_file_location(env_file_path.stem, module_path)
@@ -1,5 +1,6 @@
1
1
  import keyword
2
2
  import re
3
+ import warnings
3
4
 
4
5
  from pydantic import BaseModel, model_validator
5
6
 
@@ -37,14 +38,11 @@ class BenchlingConnection(BaseModel):
37
38
  warehouse_connection_string: str | None = None
38
39
  The connection string for the warehouse.
39
40
  internal_api_admin_email: str | None = None
40
- The email of the internal API admin. If SSO is not enabled or optional on your Benchling tenant, this email is used to log in to Benchling, and give Liminal the authenticated internal API session cookie.
41
+ DEPRECATED: Liminal no longer uses Benchling's internal API, so this is ignored. It will be removed in v6.
41
42
  internal_api_admin_password: str | None = None
42
- The password of the internal API admin. If SSO is not enabled or optional on your Benchling tenant, this password is used to log in to Benchling, and give Liminal the authenticated internal API session cookie.
43
- playwright_data_dir: str | None = "~/.liminal/chrome_data/"
44
- The directory to store the playwright browser user data. If SSO is enabled and required on your Benchling tenant,
45
- Liminal uses playwright so the user can log into Benchling in order to give Liminal the authenticated internal API session cookie.
46
- This directory is used to store playwright's persistent context, allowing the user to set up a persistent chrome profile.
47
- Set this to None in order to disable playwright's persistent context which enables automatic login.
43
+ DEPRECATED: Liminal no longer uses Benchling's internal API, so this is ignored. It will be removed in v6.
44
+ playwright_data_dir: str | None = None
45
+ DEPRECATED: Liminal no longer uses Playwright to log into Benchling's internal API, so this is ignored. It will be removed in v6.
48
46
  fieldsets: bool = False
49
47
  Whether your Benchling tenant has access to fieldsets.
50
48
  config_flags: TenantConfigFlags = TenantConfigFlags()
@@ -59,7 +57,7 @@ class BenchlingConnection(BaseModel):
59
57
  warehouse_connection_string: str | None = None
60
58
  internal_api_admin_email: str | None = None
61
59
  internal_api_admin_password: str | None = None
62
- playwright_data_dir: str | None = "~/.liminal/playwright_chrome_data/"
60
+ playwright_data_dir: str | None = None
63
61
  fieldsets: bool = False
64
62
  config_flags: TenantConfigFlags = TenantConfigFlags()
65
63
 
@@ -81,3 +79,26 @@ class BenchlingConnection(BaseModel):
81
79
 
82
80
  values["current_revision_id_var_name"] = var_name
83
81
  return values
82
+
83
+ @model_validator(mode="after")
84
+ def warn_deprecated_internal_api_credentials(self) -> "BenchlingConnection":
85
+ if (
86
+ self.internal_api_admin_email is not None
87
+ or self.internal_api_admin_password is not None
88
+ ):
89
+ warnings.warn(
90
+ "Deprecated BenchlingConnection properties set: internal_api_admin_email and internal_api_admin_password. Liminal no longer uses Benchling's internal API, so they are ignored. Remove them from your BenchlingConnection, since they will be removed in v6.",
91
+ FutureWarning,
92
+ stacklevel=3,
93
+ )
94
+ return self
95
+
96
+ @model_validator(mode="after")
97
+ def warn_deprecated_playwright_data_dir(self) -> "BenchlingConnection":
98
+ if self.playwright_data_dir is not None:
99
+ warnings.warn(
100
+ "Deprecated BenchlingConnection property set: playwright_data_dir. Liminal no longer uses Playwright to log into Benchling, so it is ignored. Remove it from your BenchlingConnection, since it will be removed in v6.",
101
+ FutureWarning,
102
+ stacklevel=3,
103
+ )
104
+ return self
@@ -0,0 +1,245 @@
1
+ import logging
2
+ import warnings
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from benchling_sdk.auth.client_credentials_oauth2 import ClientCredentialsOAuth2
6
+ from benchling_sdk.benchling import Benchling, BenchlingApiClientDecorator
7
+ from benchling_sdk.helpers.retry_helpers import RetryStrategy
8
+ from sqlalchemy import create_engine
9
+ from sqlalchemy.engine import Engine
10
+ from sqlalchemy.orm import Session, configure_mappers
11
+
12
+ from liminal.base.properties.base_field_properties import BaseFieldProperties
13
+ from liminal.base.properties.base_schema_properties import BaseSchemaProperties
14
+ from liminal.connection.benchling_connection import BenchlingConnection
15
+ from liminal.enums import (
16
+ BenchlingEntityType,
17
+ BenchlingFieldType,
18
+ BenchlingNamingStrategy,
19
+ )
20
+
21
+ if TYPE_CHECKING:
22
+ from liminal.entity_schemas.entity_schema_models import EntitySchemaModel
23
+
24
+ LOGGER = logging.getLogger(__name__)
25
+ logging.getLogger("httpx").setLevel(logging.WARNING)
26
+
27
+ REMOTE_LIMINAL_SCHEMA_NAME = "liminal_remote"
28
+ REMOTE_REVISION_ID_FIELD_WH_NAME = "revision_id"
29
+
30
+
31
+ class BenchlingService(Benchling):
32
+ """
33
+ Class that creates a connection object that can be used to connect to Benchling's API and/or Postgres warehouse.
34
+
35
+ Parameters
36
+ ----------
37
+ connection: BenchlingConnection
38
+ The connection object that contains the credentials for the Benchling tenant.
39
+ use_api: bool
40
+ Whether to connect to the Benchling SDK. Requires api_client_id and api_client_secret from the connection object.
41
+ use_db: bool = False
42
+ Whether to connect to the Benchling Postgres database. Requires warehouse_connection_string from the connection object.
43
+ use_internal_api: bool = False
44
+ DEPRECATED: Liminal no longer uses Benchling's internal API, so this is ignored. It will be removed in v6.
45
+ client_decorator: BenchlingApiClientDecorator | None = None
46
+ An optional function that receives the default BenchlingApiClient and returns a
47
+ customized one. Forwarded to the Benchling SDK. A common use is raising the HTTP
48
+ timeout, which otherwise defaults to 10 seconds: ``lambda c: c.with_timeout(60)``.
49
+ """
50
+
51
+ def __init__(
52
+ self,
53
+ connection: BenchlingConnection,
54
+ use_api: bool = True,
55
+ use_db: bool = False,
56
+ use_internal_api: bool = False,
57
+ client_decorator: BenchlingApiClientDecorator | None = None,
58
+ ) -> None:
59
+ if use_internal_api:
60
+ warnings.warn(
61
+ "Deprecated BenchlingService argument set: use_internal_api. Liminal no longer uses Benchling's internal API, so it is ignored. Remove it from your BenchlingService, since it will be removed in v6.",
62
+ FutureWarning,
63
+ stacklevel=2,
64
+ )
65
+ self.connection = connection
66
+ self._session: Session | None = None
67
+ self.use_api = use_api
68
+ self.benchling_tenant = connection.tenant_name
69
+ if use_api:
70
+ retry_strategy = RetryStrategy(max_tries=10)
71
+ auth_method = ClientCredentialsOAuth2(
72
+ client_id=connection.api_client_id,
73
+ client_secret=connection.api_client_secret,
74
+ token_url=f"https://{connection.tenant_name}.benchling.com/api/v2/token",
75
+ )
76
+ url = f"https://{connection.tenant_name}.benchling.com"
77
+ super().__init__(
78
+ url=url,
79
+ auth_method=auth_method,
80
+ retry_strategy=retry_strategy,
81
+ client_decorator=client_decorator,
82
+ )
83
+ LOGGER.info(f"Tenant {connection.tenant_name}: Connected to Benchling API.")
84
+ self.use_db = use_db
85
+ if use_db:
86
+ if connection.warehouse_connection_string:
87
+ self.engine: Engine = create_engine(
88
+ connection.warehouse_connection_string
89
+ )
90
+ configure_mappers()
91
+ LOGGER.info(
92
+ f"Tenant {connection.tenant_name}: Connected to Benchling read-only Postgres warehouse."
93
+ )
94
+ else:
95
+ raise ValueError(
96
+ "use_db is True but warehouse_connection_string not provided in BenchlingConnection."
97
+ )
98
+
99
+ @property
100
+ def session(self) -> Session:
101
+ """Returns a session made by the sessionmaker"""
102
+ return self.get_session()
103
+
104
+ @property
105
+ def registry_id(self) -> str:
106
+ # This assumes there is only one registry (which has always been the case at DynoTx)
107
+ registries = self.registry.registries()
108
+ assert len(registries) == 1
109
+ return registries[0].id
110
+
111
+ @property
112
+ def organization_id(self) -> str:
113
+ # This assumes there is only one registry (which has always been the case at DynoTx)
114
+ registries = self.registry.registries()
115
+ assert len(registries) == 1
116
+ return registries[0].owner.id
117
+
118
+ def __enter__(self) -> Session:
119
+ self._session = self.get_session()
120
+ return self._session
121
+
122
+ def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
123
+ if exc_val:
124
+ self._session.rollback()
125
+ self._session.close()
126
+ self._session = None
127
+
128
+ def get_session(self) -> Session:
129
+ """Provides a wrapper around getting sessions which enables batch inserts"""
130
+ if not self.use_db:
131
+ raise ValueError(
132
+ "Database connection not initialized! Initialize with 'use_db = True'"
133
+ )
134
+ session = Session(self.engine)
135
+ session.info["environment"] = self.connection.tenant_name
136
+ return session
137
+
138
+ def cleanup(self) -> None:
139
+ """Closes all sessions and cleans up engine"""
140
+ self.engine.dispose()
141
+
142
+ def _get_remote_liminal_schema(self) -> "EntitySchemaModel | None":
143
+ """Fetches the liminal_remote entity schema with its field definitions.
144
+ Returns None if the schema doesn't exist."""
145
+ from liminal.entity_schemas.entity_schema_models import EntitySchemaModel
146
+
147
+ try:
148
+ return EntitySchemaModel.get_one(self, REMOTE_LIMINAL_SCHEMA_NAME)
149
+ except ValueError:
150
+ return None
151
+
152
+ def get_remote_revision_id(self) -> str:
153
+ """
154
+ Searches for the liminal_remote schema, where the revision_id is stored.
155
+ This schema contains the remote revision_id in the name of the revision_id field.
156
+
157
+ Returns the remote revision_id stored on the entity.
158
+ """
159
+
160
+ liminal_schema = self._get_remote_liminal_schema()
161
+ if liminal_schema is None:
162
+ raise ValueError(
163
+ f"Did not find any schema name '{REMOTE_LIMINAL_SCHEMA_NAME}'. Run a liminal migration to populate your registry with the Liminal entity that stores the remote revision_id."
164
+ )
165
+ revision_id_fields = [
166
+ f
167
+ for f in liminal_schema.fields
168
+ if f.systemName == REMOTE_REVISION_ID_FIELD_WH_NAME and not f.archived
169
+ ]
170
+ if len(revision_id_fields) == 1:
171
+ revision_id = revision_id_fields[0].name
172
+ assert revision_id is not None, "No revision_id set in field name."
173
+ return revision_id
174
+ else:
175
+ raise ValueError(
176
+ f"Error finding field on {REMOTE_LIMINAL_SCHEMA_NAME} schema with warehouse_name {REMOTE_REVISION_ID_FIELD_WH_NAME}. Check schema fields to ensure this field exists and is defined according to documentation."
177
+ )
178
+
179
+ def upsert_remote_revision_id(self, revision_id: str) -> bool:
180
+ """Updates or inserts a remote Liminal schema into your tenant with the given revision_id stored in the name of a field.
181
+ If the 'liminal_remote' schema is found, check and make sure a field with warehouse_name 'revision_id' is present. If both are present, update the revision_id stored within the name.
182
+ If no schema is found, create the liminal_remote entity schema.
183
+
184
+ Parameters
185
+ ----------
186
+ revision_id : str
187
+ revision_id of migration file to set in Benchling on remote liminal entity.
188
+
189
+ Returns
190
+ -------
191
+ CustomEntity
192
+ remote liminal entity with updated revision_id field.
193
+ """
194
+ liminal_schema = self._get_remote_liminal_schema()
195
+ if liminal_schema is None:
196
+ # No liminal_remote schema found. Create schema.
197
+ from liminal.entity_schemas.operations import CreateEntitySchema
198
+
199
+ CreateEntitySchema(
200
+ schema_properties=BaseSchemaProperties(
201
+ name=REMOTE_LIMINAL_SCHEMA_NAME,
202
+ warehouse_name=REMOTE_LIMINAL_SCHEMA_NAME,
203
+ prefix=REMOTE_LIMINAL_SCHEMA_NAME,
204
+ entity_type=BenchlingEntityType.CUSTOM_ENTITY,
205
+ naming_strategies={BenchlingNamingStrategy.NEW_IDS},
206
+ ),
207
+ fields=[
208
+ BaseFieldProperties(
209
+ name=revision_id,
210
+ warehouse_name=REMOTE_REVISION_ID_FIELD_WH_NAME,
211
+ type=BenchlingFieldType.TEXT,
212
+ parent_link=False,
213
+ is_multi=False,
214
+ required=True,
215
+ )
216
+ ],
217
+ ).execute(self)
218
+ LOGGER.info(
219
+ f"Created {REMOTE_LIMINAL_SCHEMA_NAME} schema for tracking the remote revision id."
220
+ )
221
+ return True
222
+ # liminal_remote schema found. Check if revision_id field exists on it.
223
+ revision_id_fields = [
224
+ f
225
+ for f in liminal_schema.fields
226
+ if f.systemName == REMOTE_REVISION_ID_FIELD_WH_NAME and not f.archived
227
+ ]
228
+ if len(revision_id_fields) == 1:
229
+ revision_id_field = revision_id_fields[0]
230
+ if revision_id_field.name == revision_id:
231
+ return False
232
+ else:
233
+ # liminal_remote schema found, revision_id field found. Update revision_id field on it with given revision_id.
234
+ from liminal.entity_schemas.operations import UpdateEntitySchemaField
235
+
236
+ UpdateEntitySchemaField(
237
+ liminal_schema.systemName,
238
+ revision_id_field.systemName,
239
+ BaseFieldProperties(name=revision_id),
240
+ ).execute(self)
241
+ return True
242
+ else:
243
+ raise ValueError(
244
+ f"Error finding field on {REMOTE_LIMINAL_SCHEMA_NAME} schema with warehouse_name {REMOTE_REVISION_ID_FIELD_WH_NAME}. Check schema fields to ensure this field exists and is defined according to documentation."
245
+ )