albert 1.12.0__tar.gz → 1.13.0b1__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.
- {albert-1.12.0 → albert-1.13.0b1}/PKG-INFO +1 -1
- {albert-1.12.0 → albert-1.13.0b1}/scripts/validate_version_bump.py +3 -11
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/__init__.py +1 -1
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/attachments.py +11 -17
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/auth/_listener.py +2 -4
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/inventory.py +6 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/lists.py +12 -9
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/utils/inventory.py +71 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/utils/property_data.py +1 -61
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_property_data.py +1 -152
- {albert-1.12.0 → albert-1.13.0b1}/tests/resources/test_inventory.py +1 -0
- {albert-1.12.0 → albert-1.13.0b1}/.circleci/config.yml +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/.gitignore +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/.pre-commit-config.yaml +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/.vscode/settings.json +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/CHANGELOG.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/CONTRIBUTING.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/LICENSE +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/README.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/CONTRIBUTING.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/albert.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/assets/Vector_Favicon_Blue.svg +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/assets/Wordmark_Black.png +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/assets/Wordmark_White.png +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/authentication.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/activities.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/attachments.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/base.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/batch_data.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/btdataset.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/btinsight.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/btmodel.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/cas.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/companies.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/custom_fields.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/custom_templates.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/data_columns.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/data_templates.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/entity_types.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/files.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/hazards.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/inventory.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/links.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/lists.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/locations.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/lots.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/notebooks.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/notes.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/parameter_groups.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/parameters.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/pricings.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/product_design.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/projects.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/property_data.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/reports.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/roles.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/storage_classes.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/storage_locations.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/substances.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/synthesis.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/tags.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/tasks.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/un_numbers.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/units.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/users.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/workflows.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/collections/worksheets.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/concepts.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/configuration.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/credentials.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/examples/notebook.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/examples/property_data.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/examples/tasks.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/index.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/installation.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/migration.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/activities.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/attachments.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/batch_data.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/btdataset.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/btinsight.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/btmodel.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/cas.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/companies.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/custom_fields.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/custom_templates.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/data_columns.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/data_templates.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/entity_types.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/files.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/hazards.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/identifiers.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/inventory.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/links.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/lists.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/locations.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/lots.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/notebooks.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/notes.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/parameter_groups.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/parameters.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/pricings.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/product_design.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/projects.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/property_data.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/reports.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/roles.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/sheets.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/storage_classes.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/storage_locations.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/substances.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/synthesis.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/tags.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/tasks.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/un_numbers.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/units.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/users.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/workflows.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/resources/worksheets.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/sso.md +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/docs/styles/extra.css +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/mkdocs.yml +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/pyproject.toml +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/scripts/validate_release_tag.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/setup.sh +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/client.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/__init__.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/activities.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/base.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/batch_data.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/btdataset.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/btinsight.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/btmodel.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/cas.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/companies.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/custom_fields.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/custom_templates.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/data_columns.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/data_templates.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/entity_types.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/files.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/hazards.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/inventory.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/links.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/lists.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/locations.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/lots.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/notebooks.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/notes.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/parameter_groups.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/parameters.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/pricings.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/product_design.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/projects.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/property_data.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/report_templates.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/reports.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/roles.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/storage_classes.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/storage_locations.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/substance.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/synthesis.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/tags.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/tasks.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/un_numbers.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/units.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/users.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/workflows.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/collections/worksheets.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/__init__.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/auth/__init__.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/auth/_manager.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/auth/credentials.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/auth/sso.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/base.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/logging.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/pagination.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/session.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/shared/__init__.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/shared/enums.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/shared/identifiers.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/shared/models/base.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/shared/models/patch.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/core/shared/types.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/exceptions.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/__init__.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/_mixins.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/acls.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/activities.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/attachments.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/batch_data.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/btdataset.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/btinsight.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/btmodel.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/cas.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/companies.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/custom_fields.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/custom_templates.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/data_columns.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/data_templates.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/entity_types.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/facet.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/files.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/hazards.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/links.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/locations.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/lots.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/notebooks.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/notes.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/parameter_groups.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/parameters.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/pricings.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/product_design.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/projects.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/property_data.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/report_templates.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/reports.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/roles.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/sheets.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/storage_classes.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/storage_locations.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/substance.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/synthesis.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/tagged_base.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/tags.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/tasks.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/un_numbers.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/units.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/users.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/worker_jobs.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/workflows.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/resources/worksheets.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/utils/__init__.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/utils/_auth.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/utils/_patch.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/utils/data_template.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/src/albert/utils/tasks.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/__init__.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/__init__.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_activities.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_attachments.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_batch_data.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_btdataset.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_btinsight.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_btmodel.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_cas.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_company.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_custom_fields.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_custom_templates.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_data_columns.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_data_templates.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_entity_types.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_files.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_hazards.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_inventory.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_links.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_lists.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_locations.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_lots.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_notebooks.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_notes.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_parameter_groups.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_parameters.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_pricings.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_product_design.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_projects.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_report_templates.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_reports.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_roles.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_storage_classes.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_storage_locations.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_substance.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_tags.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_tasks.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_un_number.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_units.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_users.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_workflows.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/collections/test_worksheet.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/conftest.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/core/shared/__init__.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/core/shared/test_identifiers.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/core/shared/test_types.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/core/test_auth.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/data/SDS_HCL.pdf +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/data/dontpanic.jpg +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/resources/test_lots.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/resources/test_notebooks.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/resources/test_sheets.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/seeding.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/utils/fake_session.py +0 -0
- {albert-1.12.0 → albert-1.13.0b1}/tests/utils/test_patches.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: albert
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.13.0b1
|
|
4
4
|
Summary: The official Python SDK for the Albert Invent platform.
|
|
5
5
|
Project-URL: Homepage, https://www.albertinvent.com/
|
|
6
6
|
Project-URL: Documentation, https://docs.developer.albertinvent.com/albert-python
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import argparse
|
|
2
|
-
import re
|
|
3
|
-
import subprocess
|
|
4
2
|
import sys
|
|
3
|
+
from os import popen
|
|
5
4
|
from pathlib import Path
|
|
6
5
|
|
|
7
6
|
from packaging import version
|
|
@@ -20,15 +19,8 @@ def main(base_branch: str):
|
|
|
20
19
|
local_path = Path(__file__).parents[1] / version_file
|
|
21
20
|
local_version = extract_version(local_path.read_text())
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
subprocess.run(["git", "fetch", "origin"], check=True)
|
|
27
|
-
base_contents = subprocess.check_output(
|
|
28
|
-
["git", "show", f"{base_branch}:{version_file}"],
|
|
29
|
-
text=True,
|
|
30
|
-
)
|
|
31
|
-
base_version = extract_version(base_contents)
|
|
22
|
+
with popen(f"git fetch origin && git show {base_branch}:{version_file}") as fh:
|
|
23
|
+
base_version = extract_version(fh.read())
|
|
32
24
|
|
|
33
25
|
if is_version_bump(local_version, base_version):
|
|
34
26
|
print(f"Version bump detected: {base_version} -> {local_version}")
|
|
@@ -152,30 +152,20 @@ class AttachmentCollection(BaseCollection):
|
|
|
152
152
|
The name of the file, by default ""
|
|
153
153
|
upload_key : str | None, optional
|
|
154
154
|
Override the storage key used when signing and uploading the file.
|
|
155
|
-
Defaults to ``
|
|
155
|
+
Defaults to the provided ``file_name``.
|
|
156
156
|
|
|
157
157
|
Returns
|
|
158
158
|
-------
|
|
159
159
|
Note
|
|
160
160
|
The created note.
|
|
161
161
|
"""
|
|
162
|
-
|
|
162
|
+
upload_name = upload_key or file_name
|
|
163
|
+
if not upload_name:
|
|
163
164
|
raise ValueError("A file name or upload key must be provided for attachment upload.")
|
|
164
165
|
|
|
165
|
-
|
|
166
|
-
note = Note(
|
|
167
|
-
parent_id=parent_id,
|
|
168
|
-
note=note_text,
|
|
169
|
-
)
|
|
170
|
-
registered_note = note_collection.create(note=note)
|
|
171
|
-
if upload_key:
|
|
172
|
-
attachment_name = file_name or Path(upload_key).name
|
|
173
|
-
upload_name = upload_key
|
|
174
|
-
else:
|
|
175
|
-
attachment_name = file_name
|
|
176
|
-
upload_name = f"{parent_id}/{registered_note.id}/{file_name}"
|
|
177
|
-
file_type = mimetypes.guess_type(attachment_name or upload_name)[0]
|
|
166
|
+
file_type = mimetypes.guess_type(file_name or upload_name)[0]
|
|
178
167
|
file_collection = self._get_file_collection()
|
|
168
|
+
note_collection = self._get_note_collection()
|
|
179
169
|
|
|
180
170
|
file_collection.sign_and_upload_file(
|
|
181
171
|
data=file_data,
|
|
@@ -186,12 +176,16 @@ class AttachmentCollection(BaseCollection):
|
|
|
186
176
|
file_info = file_collection.get_by_name(
|
|
187
177
|
name=upload_name, namespace=FileNamespace.RESULT.value
|
|
188
178
|
)
|
|
179
|
+
note = Note(
|
|
180
|
+
parent_id=parent_id,
|
|
181
|
+
note=note_text,
|
|
182
|
+
)
|
|
183
|
+
registered_note = note_collection.create(note=note)
|
|
189
184
|
self.attach_file_to_note(
|
|
190
185
|
note_id=registered_note.id,
|
|
191
|
-
file_name=
|
|
186
|
+
file_name=file_name or Path(upload_name).name,
|
|
192
187
|
file_key=file_info.name,
|
|
193
188
|
)
|
|
194
|
-
|
|
195
189
|
return note_collection.get_by_id(id=registered_note.id)
|
|
196
190
|
|
|
197
191
|
@validate_call
|
|
@@ -31,10 +31,6 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|
|
31
31
|
status = "successful" if self.server.token else "failed (no token found)"
|
|
32
32
|
self.send_response(200)
|
|
33
33
|
self.send_header("Content-Type", "text/html")
|
|
34
|
-
self.send_header(
|
|
35
|
-
"Content-Security-Policy",
|
|
36
|
-
"default-src 'none'; frame-ancestors 'none'; base-uri 'none';",
|
|
37
|
-
)
|
|
38
34
|
self.end_headers()
|
|
39
35
|
self.wfile.write(
|
|
40
36
|
f"""
|
|
@@ -42,6 +38,8 @@ class RequestHandler(BaseHTTPRequestHandler):
|
|
|
42
38
|
<body>
|
|
43
39
|
<h1>Authentication {status}</h1>
|
|
44
40
|
<p>You can close this window now.</p>
|
|
41
|
+
<script>window.close()</script>
|
|
42
|
+
<button onclick="window.close()">Close Window</button>
|
|
45
43
|
</body>
|
|
46
44
|
</html>
|
|
47
45
|
""".encode()
|
|
@@ -14,6 +14,7 @@ from albert.resources._mixins import HydrationMixin
|
|
|
14
14
|
from albert.resources.acls import ACL
|
|
15
15
|
from albert.resources.cas import Cas
|
|
16
16
|
from albert.resources.companies import Company
|
|
17
|
+
from albert.resources.lists import ListItem
|
|
17
18
|
from albert.resources.locations import Location
|
|
18
19
|
from albert.resources.tagged_base import BaseTaggedResource
|
|
19
20
|
from albert.resources.tags import Tag
|
|
@@ -75,6 +76,8 @@ class CasAmount(BaseAlbertModel):
|
|
|
75
76
|
The SMILES string of the CAS Number resource. Obtained from the Cas object when provided.
|
|
76
77
|
number: str | None
|
|
77
78
|
The CAS number. Obtained from the Cas object when provided.
|
|
79
|
+
inventory_function: list[ListItem | EntityLink | str] | None
|
|
80
|
+
Business-controlled functions associated with the CAS in this inventory context.
|
|
78
81
|
|
|
79
82
|
!!! tip
|
|
80
83
|
---
|
|
@@ -87,6 +90,9 @@ class CasAmount(BaseAlbertModel):
|
|
|
87
90
|
target: float | None = Field(default=None, alias="inventoryValue")
|
|
88
91
|
id: str | None = Field(default=None)
|
|
89
92
|
cas_category: str | None = Field(default=None, alias="casCategory")
|
|
93
|
+
inventory_function: list[SerializeAsEntityLink[ListItem] | str] | None = Field(
|
|
94
|
+
default=None, alias="inventoryFunction"
|
|
95
|
+
)
|
|
90
96
|
type: str | None = Field(default=None)
|
|
91
97
|
classification_type: str | None = Field(default=None, alias="classificationType")
|
|
92
98
|
|
|
@@ -25,9 +25,11 @@ class ListItem(BaseResource):
|
|
|
25
25
|
id : str | None
|
|
26
26
|
The Albert ID of the list item. Set when the list item is retrieved from Albert.
|
|
27
27
|
category : ListItemCategory | None
|
|
28
|
-
The category of the list item. Allowed values are `businessDefined`, `userDefined`, `projects`,
|
|
28
|
+
The category of the list item. Allowed values are `businessDefined`, `userDefined`, `projects`, `extensions`,
|
|
29
|
+
and `inventory`.
|
|
29
30
|
list_type : str | None
|
|
30
|
-
The type of the list item. Allowed values are `projectState` for `projects
|
|
31
|
+
The type of the list item. Allowed values are `projectState` for `projects`, `extensions` for `extensions`,
|
|
32
|
+
and `casCategory` or `inventoryFunction` for `inventory`.
|
|
31
33
|
"""
|
|
32
34
|
|
|
33
35
|
name: str
|
|
@@ -37,14 +39,15 @@ class ListItem(BaseResource):
|
|
|
37
39
|
|
|
38
40
|
@model_validator(mode="after")
|
|
39
41
|
def validate_list_type(self) -> ListItem:
|
|
42
|
+
allowed_by_category = {
|
|
43
|
+
ListItemCategory.PROJECTS: {"projectState"},
|
|
44
|
+
ListItemCategory.EXTENSIONS: {"extensions"},
|
|
45
|
+
ListItemCategory.INVENTORY: {"casCategory", "inventoryFunction"},
|
|
46
|
+
}
|
|
40
47
|
if (
|
|
41
|
-
self.
|
|
42
|
-
and self.
|
|
43
|
-
and self.list_type
|
|
44
|
-
) or (
|
|
45
|
-
self.category == ListItemCategory.EXTENSIONS
|
|
46
|
-
and self.list_type is not None
|
|
47
|
-
and self.list_type != "extensions"
|
|
48
|
+
self.list_type is not None
|
|
49
|
+
and self.category in allowed_by_category
|
|
50
|
+
and self.list_type not in allowed_by_category[self.category]
|
|
48
51
|
):
|
|
49
52
|
raise ValueError(
|
|
50
53
|
f"List type {self.list_type} is not allowed for category {self.category}"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from collections.abc import Iterable
|
|
2
2
|
from typing import Any
|
|
3
3
|
|
|
4
|
+
from albert.core.shared.models.base import BaseResource, EntityLink
|
|
4
5
|
from albert.resources.inventory import CasAmount
|
|
5
6
|
|
|
6
7
|
|
|
@@ -56,6 +57,61 @@ def _build_cas_delete_operation(identifier: str) -> dict[str, Any]:
|
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
|
|
60
|
+
def _normalize_inventory_function_ids(
|
|
61
|
+
value: list[BaseResource | EntityLink | str] | None,
|
|
62
|
+
) -> list[str]:
|
|
63
|
+
if not value:
|
|
64
|
+
return []
|
|
65
|
+
ids: list[str] = []
|
|
66
|
+
for item in value:
|
|
67
|
+
if isinstance(item, str):
|
|
68
|
+
if item:
|
|
69
|
+
ids.append(item)
|
|
70
|
+
continue
|
|
71
|
+
if isinstance(item, BaseResource):
|
|
72
|
+
if item.id:
|
|
73
|
+
ids.append(item.id)
|
|
74
|
+
continue
|
|
75
|
+
if isinstance(item, EntityLink):
|
|
76
|
+
if item.id:
|
|
77
|
+
ids.append(item.id)
|
|
78
|
+
continue
|
|
79
|
+
return ids
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _build_inventory_function_operations(
|
|
83
|
+
*,
|
|
84
|
+
entity_id: str,
|
|
85
|
+
existing: list[BaseResource | EntityLink | str] | None,
|
|
86
|
+
updated: list[BaseResource | EntityLink | str] | None,
|
|
87
|
+
) -> list[dict[str, Any]]:
|
|
88
|
+
existing_ids = set(_normalize_inventory_function_ids(existing))
|
|
89
|
+
updated_ids = set(_normalize_inventory_function_ids(updated))
|
|
90
|
+
to_add = sorted(updated_ids - existing_ids)
|
|
91
|
+
to_delete = sorted(existing_ids - updated_ids)
|
|
92
|
+
|
|
93
|
+
operations: list[dict[str, Any]] = []
|
|
94
|
+
if to_add:
|
|
95
|
+
operations.append(
|
|
96
|
+
{
|
|
97
|
+
"attribute": "inventoryFunction",
|
|
98
|
+
"entityId": entity_id,
|
|
99
|
+
"operation": "add",
|
|
100
|
+
"newValue": to_add,
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
if to_delete:
|
|
104
|
+
operations.append(
|
|
105
|
+
{
|
|
106
|
+
"attribute": "inventoryFunction",
|
|
107
|
+
"entityId": entity_id,
|
|
108
|
+
"operation": "delete",
|
|
109
|
+
"oldValue": to_delete,
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
return operations
|
|
113
|
+
|
|
114
|
+
|
|
59
115
|
def _build_cas_scalar_operation(
|
|
60
116
|
*,
|
|
61
117
|
attribute: str,
|
|
@@ -117,6 +173,14 @@ def _build_cas_update_operations(existing: CasAmount, updated: CasAmount) -> lis
|
|
|
117
173
|
if operation is not None:
|
|
118
174
|
operations.append(operation)
|
|
119
175
|
|
|
176
|
+
operations.extend(
|
|
177
|
+
_build_inventory_function_operations(
|
|
178
|
+
entity_id=identifier,
|
|
179
|
+
existing=existing.inventory_function,
|
|
180
|
+
updated=updated.inventory_function,
|
|
181
|
+
)
|
|
182
|
+
)
|
|
183
|
+
|
|
120
184
|
return operations
|
|
121
185
|
|
|
122
186
|
|
|
@@ -159,6 +223,13 @@ def _build_cas_patch_operations(
|
|
|
159
223
|
)
|
|
160
224
|
if target_operation is not None:
|
|
161
225
|
operations.append(target_operation)
|
|
226
|
+
operations.extend(
|
|
227
|
+
_build_inventory_function_operations(
|
|
228
|
+
entity_id=identifier,
|
|
229
|
+
existing=None,
|
|
230
|
+
updated=cas_amount.inventory_function,
|
|
231
|
+
)
|
|
232
|
+
)
|
|
162
233
|
|
|
163
234
|
removals = [existing_lookup[key] for key in existing_lookup.keys() - updated_lookup.keys()]
|
|
164
235
|
for cas_amount in removals:
|
|
@@ -2,10 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import ast
|
|
6
|
-
import math
|
|
7
5
|
import mimetypes
|
|
8
|
-
import operator
|
|
9
6
|
import re
|
|
10
7
|
import uuid
|
|
11
8
|
from collections.abc import Callable
|
|
@@ -576,63 +573,6 @@ def get_all_columns_used_in_calculations(*, first_row_data_column: list):
|
|
|
576
573
|
return used_columns
|
|
577
574
|
|
|
578
575
|
|
|
579
|
-
_ALLOWED_BINOPS = {
|
|
580
|
-
ast.Add: operator.add,
|
|
581
|
-
ast.Sub: operator.sub,
|
|
582
|
-
ast.Mult: operator.mul,
|
|
583
|
-
ast.Div: operator.truediv,
|
|
584
|
-
ast.Mod: operator.mod,
|
|
585
|
-
ast.Pow: operator.pow,
|
|
586
|
-
}
|
|
587
|
-
_ALLOWED_UNARYOPS = {
|
|
588
|
-
ast.UAdd: operator.pos,
|
|
589
|
-
ast.USub: operator.neg,
|
|
590
|
-
}
|
|
591
|
-
_ALLOWED_FUNCS: dict[str, tuple[Callable[..., float], int]] = {
|
|
592
|
-
"log10": (math.log10, 1),
|
|
593
|
-
"ln": (math.log, 1),
|
|
594
|
-
"sqrt": (math.sqrt, 1),
|
|
595
|
-
"pi": (lambda: math.pi, 0),
|
|
596
|
-
}
|
|
597
|
-
_ALLOWED_NAMES = {"pi": math.pi}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
def _safe_eval_math(*, expression: str) -> float:
|
|
601
|
-
"""Safely evaluate supported math expressions."""
|
|
602
|
-
parsed = ast.parse(expression, mode="eval")
|
|
603
|
-
|
|
604
|
-
def _eval(node: ast.AST) -> float:
|
|
605
|
-
if isinstance(node, ast.Expression):
|
|
606
|
-
return _eval(node.body)
|
|
607
|
-
if isinstance(node, ast.Constant) and isinstance(node.value, (int | float)):
|
|
608
|
-
return node.value
|
|
609
|
-
if isinstance(node, ast.BinOp) and type(node.op) in _ALLOWED_BINOPS:
|
|
610
|
-
return _ALLOWED_BINOPS[type(node.op)](_eval(node.left), _eval(node.right))
|
|
611
|
-
if isinstance(node, ast.UnaryOp) and type(node.op) in _ALLOWED_UNARYOPS:
|
|
612
|
-
return _ALLOWED_UNARYOPS[type(node.op)](_eval(node.operand))
|
|
613
|
-
if isinstance(node, ast.Call):
|
|
614
|
-
if not isinstance(node.func, ast.Name):
|
|
615
|
-
raise ValueError("Unsupported function call.")
|
|
616
|
-
func_name = node.func.id
|
|
617
|
-
if func_name not in _ALLOWED_FUNCS:
|
|
618
|
-
raise ValueError("Unsupported function.")
|
|
619
|
-
if node.keywords:
|
|
620
|
-
raise ValueError("Keyword arguments are not supported.")
|
|
621
|
-
func, arity = _ALLOWED_FUNCS[func_name]
|
|
622
|
-
if len(node.args) != arity:
|
|
623
|
-
raise ValueError("Unsupported function arity.")
|
|
624
|
-
if arity == 0:
|
|
625
|
-
return func()
|
|
626
|
-
return func(_eval(node.args[0]))
|
|
627
|
-
if isinstance(node, ast.Name):
|
|
628
|
-
if node.id in _ALLOWED_NAMES:
|
|
629
|
-
return _ALLOWED_NAMES[node.id]
|
|
630
|
-
raise ValueError("Unsupported name.")
|
|
631
|
-
raise ValueError("Unsupported expression.")
|
|
632
|
-
|
|
633
|
-
return _eval(parsed)
|
|
634
|
-
|
|
635
|
-
|
|
636
576
|
def evaluate_calculation(*, calculation: str, column_values: dict) -> float | None:
|
|
637
577
|
"""Evaluate a calculation expression against column values."""
|
|
638
578
|
calculation = calculation.lstrip("=")
|
|
@@ -649,7 +589,7 @@ def evaluate_calculation(*, calculation: str, column_values: dict) -> float | No
|
|
|
649
589
|
calculation = pattern.sub(repl, calculation)
|
|
650
590
|
|
|
651
591
|
calculation = calculation.replace("^", "**")
|
|
652
|
-
return
|
|
592
|
+
return eval(calculation)
|
|
653
593
|
except Exception as e:
|
|
654
594
|
logger.info(
|
|
655
595
|
"Error evaluating calculation '%s': %s. Likely do not have all values needed.",
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
from contextlib import suppress
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
1
|
from albert import Albert
|
|
6
|
-
from albert.exceptions import NotFoundError
|
|
7
|
-
from albert.resources.data_columns import DataColumn
|
|
8
|
-
from albert.resources.data_templates import DataColumnValue, DataTemplate
|
|
9
2
|
from albert.resources.property_data import (
|
|
10
3
|
BulkPropertyData,
|
|
11
4
|
BulkPropertyDataColumn,
|
|
@@ -17,13 +10,7 @@ from albert.resources.property_data import (
|
|
|
17
10
|
TaskPropertyCreate,
|
|
18
11
|
TaskPropertyData,
|
|
19
12
|
)
|
|
20
|
-
from albert.resources.tasks import
|
|
21
|
-
BaseTask,
|
|
22
|
-
Block,
|
|
23
|
-
PropertyTask,
|
|
24
|
-
TaskCategory,
|
|
25
|
-
TaskInventoryInformation,
|
|
26
|
-
)
|
|
13
|
+
from albert.resources.tasks import BaseTask, PropertyTask
|
|
27
14
|
|
|
28
15
|
|
|
29
16
|
def _get_latest_row(task_properties: TaskPropertyData) -> int:
|
|
@@ -234,141 +221,3 @@ def test_add_and_update_property_data_on_inventory(
|
|
|
234
221
|
assert r[0].inventory_id == inv.id
|
|
235
222
|
assert r[0].data_columns[0].data_column_id == seeded_data_columns[0].id
|
|
236
223
|
assert r[0].data_columns[0].value == "55.5"
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
def test_task_property_calculation_evaluation(
|
|
240
|
-
client: Albert,
|
|
241
|
-
seed_prefix: str,
|
|
242
|
-
seeded_inventory,
|
|
243
|
-
seeded_lots,
|
|
244
|
-
seeded_locations,
|
|
245
|
-
seeded_projects,
|
|
246
|
-
seeded_workflows,
|
|
247
|
-
):
|
|
248
|
-
calc_task_id = None
|
|
249
|
-
calc_dt_id = None
|
|
250
|
-
calc_dc_ids = []
|
|
251
|
-
|
|
252
|
-
try:
|
|
253
|
-
dc_one = client.data_columns.create(
|
|
254
|
-
data_column=DataColumn(name=f"{seed_prefix} - calc col one")
|
|
255
|
-
)
|
|
256
|
-
dc_two = client.data_columns.create(
|
|
257
|
-
data_column=DataColumn(name=f"{seed_prefix} - calc col two")
|
|
258
|
-
)
|
|
259
|
-
dc_calc = client.data_columns.create(
|
|
260
|
-
data_column=DataColumn(name=f"{seed_prefix} - calc col result")
|
|
261
|
-
)
|
|
262
|
-
calc_dc_ids = [dc_one.id, dc_two.id, dc_calc.id]
|
|
263
|
-
|
|
264
|
-
calc_dt = client.data_templates.create(
|
|
265
|
-
data_template=DataTemplate(
|
|
266
|
-
name=f"{seed_prefix} - calc dt",
|
|
267
|
-
description="Integration test template for calculated columns.",
|
|
268
|
-
data_column_values=[
|
|
269
|
-
DataColumnValue(
|
|
270
|
-
data_column=dc_one,
|
|
271
|
-
),
|
|
272
|
-
DataColumnValue(
|
|
273
|
-
data_column=dc_two,
|
|
274
|
-
),
|
|
275
|
-
],
|
|
276
|
-
)
|
|
277
|
-
)
|
|
278
|
-
calc_dt_id = calc_dt.id
|
|
279
|
-
sequence_by_id = {col.data_column_id: col.sequence for col in calc_dt.data_column_values}
|
|
280
|
-
seq_one = sequence_by_id[dc_one.id]
|
|
281
|
-
seq_two = sequence_by_id[dc_two.id]
|
|
282
|
-
calc_dt = client.data_templates.add_data_columns(
|
|
283
|
-
data_template_id=calc_dt.id,
|
|
284
|
-
data_columns=[
|
|
285
|
-
DataColumnValue(
|
|
286
|
-
data_column=dc_calc,
|
|
287
|
-
calculation=f"={seq_one}+sqrt({seq_two})",
|
|
288
|
-
)
|
|
289
|
-
],
|
|
290
|
-
)
|
|
291
|
-
sequence_by_id = {col.data_column_id: col.sequence for col in calc_dt.data_column_values}
|
|
292
|
-
seq_calc = sequence_by_id[dc_calc.id]
|
|
293
|
-
|
|
294
|
-
lot = next(
|
|
295
|
-
(l for l in seeded_lots if l.inventory_id == seeded_inventory[0].id),
|
|
296
|
-
None,
|
|
297
|
-
)
|
|
298
|
-
workflow = seeded_workflows[0]
|
|
299
|
-
interval_id = (
|
|
300
|
-
workflow.interval_combinations[0].interval_id
|
|
301
|
-
if workflow.interval_combinations
|
|
302
|
-
else "default"
|
|
303
|
-
)
|
|
304
|
-
|
|
305
|
-
calc_task = client.tasks.create(
|
|
306
|
-
task=PropertyTask(
|
|
307
|
-
name=f"{seed_prefix} - calc task",
|
|
308
|
-
category=TaskCategory.PROPERTY,
|
|
309
|
-
inventory_information=[
|
|
310
|
-
TaskInventoryInformation(
|
|
311
|
-
inventory_id=seeded_inventory[0].id,
|
|
312
|
-
lot_id=lot.id if lot else None,
|
|
313
|
-
)
|
|
314
|
-
],
|
|
315
|
-
parent_id=seeded_inventory[0].id,
|
|
316
|
-
location=seeded_locations[0],
|
|
317
|
-
project=seeded_projects[0],
|
|
318
|
-
blocks=[
|
|
319
|
-
Block(
|
|
320
|
-
workflow=[workflow],
|
|
321
|
-
data_template=[calc_dt],
|
|
322
|
-
)
|
|
323
|
-
],
|
|
324
|
-
)
|
|
325
|
-
)
|
|
326
|
-
calc_task_id = calc_task.id
|
|
327
|
-
calc_task = client.tasks.get_by_id(id=calc_task_id)
|
|
328
|
-
block_id = calc_task.blocks[0].id
|
|
329
|
-
|
|
330
|
-
result = client.property_data.add_properties_to_task(
|
|
331
|
-
task_id=calc_task_id,
|
|
332
|
-
inventory_id=seeded_inventory[0].id,
|
|
333
|
-
block_id=block_id,
|
|
334
|
-
lot_id=lot.id if lot else None,
|
|
335
|
-
properties=[
|
|
336
|
-
TaskPropertyCreate(
|
|
337
|
-
interval_combination=interval_id,
|
|
338
|
-
data_template=calc_dt,
|
|
339
|
-
data_column=TaskDataColumn(
|
|
340
|
-
data_column_id=dc_one.id,
|
|
341
|
-
column_sequence=seq_one,
|
|
342
|
-
),
|
|
343
|
-
value="5",
|
|
344
|
-
),
|
|
345
|
-
TaskPropertyCreate(
|
|
346
|
-
interval_combination=interval_id,
|
|
347
|
-
data_template=calc_dt,
|
|
348
|
-
data_column=TaskDataColumn(
|
|
349
|
-
data_column_id=dc_two.id,
|
|
350
|
-
column_sequence=seq_two,
|
|
351
|
-
),
|
|
352
|
-
value="16",
|
|
353
|
-
),
|
|
354
|
-
],
|
|
355
|
-
return_scope="block",
|
|
356
|
-
)
|
|
357
|
-
|
|
358
|
-
trial = max(
|
|
359
|
-
(t for t in result[0].data[0].trials if t.data_columns[0].property_data is not None),
|
|
360
|
-
key=lambda t: t.trial_number,
|
|
361
|
-
)
|
|
362
|
-
calc_column = next(c for c in trial.data_columns if c.sequence == seq_calc)
|
|
363
|
-
assert calc_column.property_data is not None
|
|
364
|
-
assert float(calc_column.property_data.value) == pytest.approx(9.0)
|
|
365
|
-
finally:
|
|
366
|
-
if calc_task_id:
|
|
367
|
-
with suppress(NotFoundError):
|
|
368
|
-
client.tasks.delete(id=calc_task_id)
|
|
369
|
-
if calc_dt_id:
|
|
370
|
-
with suppress(NotFoundError):
|
|
371
|
-
client.data_templates.delete(id=calc_dt_id)
|
|
372
|
-
for dc_id in calc_dc_ids:
|
|
373
|
-
with suppress(NotFoundError):
|
|
374
|
-
client.data_columns.delete(id=dc_id)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|