albert 1.14.1__tar.gz → 1.16.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.
- albert-1.16.0/.github/workflows/release-please.yml +19 -0
- albert-1.16.0/.release-please-manifest.json +1 -0
- {albert-1.14.1 → albert-1.16.0}/CHANGELOG.md +19 -0
- {albert-1.14.1 → albert-1.16.0}/PKG-INFO +1 -1
- albert-1.16.0/release-please-config.json +10 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/__init__.py +1 -1
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/attachments.py +45 -1
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/btinsight.py +9 -8
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/cas.py +1 -1
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/companies.py +3 -3
- albert-1.16.0/src/albert/collections/custom_templates.py +414 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/data_columns.py +4 -3
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/data_templates.py +1 -1
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/entity_types.py +2 -2
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/inventory.py +8 -8
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/lists.py +1 -1
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/locations.py +3 -3
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/lots.py +11 -28
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/notes.py +1 -1
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/parameter_groups.py +3 -2
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/parameters.py +4 -4
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/projects.py +44 -3
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/property_data.py +4 -7
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/storage_locations.py +3 -3
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/tags.py +3 -2
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/tasks.py +6 -3
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/units.py +4 -3
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/users.py +2 -2
- albert-1.16.0/src/albert/core/utils.py +20 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/custom_templates.py +32 -10
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/projects.py +16 -1
- albert-1.16.0/src/albert/resources/tags.py +61 -0
- albert-1.16.0/tests/collections/test_custom_templates.py +99 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_inventory.py +7 -25
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_projects.py +22 -1
- {albert-1.14.1 → albert-1.16.0}/tests/conftest.py +47 -0
- albert-1.14.1/src/albert/collections/custom_templates.py +0 -125
- albert-1.14.1/src/albert/resources/tags.py +0 -101
- albert-1.14.1/tests/collections/test_custom_templates.py +0 -60
- {albert-1.14.1 → albert-1.16.0}/.circleci/config.yml +0 -0
- {albert-1.14.1 → albert-1.16.0}/.gitignore +0 -0
- {albert-1.14.1 → albert-1.16.0}/.pre-commit-config.yaml +0 -0
- {albert-1.14.1 → albert-1.16.0}/.vscode/settings.json +0 -0
- {albert-1.14.1 → albert-1.16.0}/AGENTS.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/CONTRIBUTING.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/LICENSE +0 -0
- {albert-1.14.1 → albert-1.16.0}/README.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/CONTRIBUTING.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/albert.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/assets/Albert_Wordmark_Mono_RGB_White.svg +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/assets/Albert_Wordmark_RGB_Colour.svg +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/assets/favicon_bw.svg +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/authentication.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/activities.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/attachments.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/base.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/batch_data.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/btdataset.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/btinsight.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/btmodel.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/cas.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/companies.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/custom_fields.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/custom_templates.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/data_columns.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/data_templates.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/entity_types.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/files.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/hazards.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/inventory.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/links.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/lists.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/locations.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/lots.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/notebooks.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/notes.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/parameter_groups.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/parameters.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/pricings.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/product_design.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/projects.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/property_data.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/reports.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/roles.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/storage_classes.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/storage_locations.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/substances.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/synthesis.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/tags.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/tasks.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/un_numbers.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/units.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/users.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/workflows.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/collections/worksheets.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/concepts.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/configuration.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/credentials.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/examples/inventory.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/examples/notebook.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/examples/property_data.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/examples/tasks.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/index.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/installation.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/migration.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/acls.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/activities.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/attachments.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/batch_data.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/btdataset.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/btinsight.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/btmodel.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/cas.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/companies.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/custom_fields.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/custom_templates.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/data_columns.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/data_templates.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/entity_types.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/files.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/hazards.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/identifiers.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/inventory.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/links.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/lists.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/locations.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/lots.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/notebooks.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/notes.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/parameter_groups.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/parameters.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/pricings.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/product_design.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/projects.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/property_data.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/reports.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/roles.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/sheets.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/storage_classes.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/storage_locations.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/substances.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/synthesis.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/tags.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/tasks.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/un_numbers.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/units.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/users.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/workflows.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/resources/worksheets.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/sso.md +0 -0
- {albert-1.14.1 → albert-1.16.0}/docs/styles/extra.css +0 -0
- {albert-1.14.1 → albert-1.16.0}/mkdocs.yml +0 -0
- {albert-1.14.1 → albert-1.16.0}/pyproject.toml +0 -0
- {albert-1.14.1 → albert-1.16.0}/scripts/validate_release_tag.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/scripts/validate_version_bump.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/setup.sh +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/client.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/__init__.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/activities.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/base.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/batch_data.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/btdataset.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/btmodel.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/custom_fields.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/files.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/hazards.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/links.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/notebooks.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/pricings.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/product_design.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/report_templates.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/reports.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/roles.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/storage_classes.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/substance.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/synthesis.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/un_numbers.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/workflows.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/collections/worksheets.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/__init__.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/auth/__init__.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/auth/_listener.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/auth/_manager.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/auth/credentials.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/auth/sso.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/base.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/logging.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/pagination.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/session.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/shared/__init__.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/shared/enums.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/shared/identifiers.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/shared/models/base.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/shared/models/patch.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/core/shared/types.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/exceptions.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/__init__.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/_mixins.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/acls.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/activities.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/attachments.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/batch_data.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/btdataset.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/btinsight.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/btmodel.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/cas.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/companies.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/custom_fields.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/data_columns.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/data_templates.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/entity_types.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/facet.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/files.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/hazards.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/inventory.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/links.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/lists.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/locations.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/lots.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/notebooks.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/notes.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/parameter_groups.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/parameters.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/pricings.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/product_design.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/property_data.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/report_templates.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/reports.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/roles.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/sheets.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/storage_classes.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/storage_locations.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/substance.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/synthesis.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/tagged_base.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/tasks.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/un_numbers.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/units.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/users.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/worker_jobs.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/workflows.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/resources/worksheets.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/utils/__init__.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/utils/_auth.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/utils/_patch.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/utils/data_template.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/utils/inventory.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/utils/property_data.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/utils/tasks.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/src/albert/utils/worksheets.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/__init__.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/__init__.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_activities.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_attachments.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_batch_data.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_btdataset.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_btinsight.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_btmodel.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_cas.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_company.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_custom_fields.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_data_columns.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_data_templates.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_entity_types.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_files.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_hazards.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_links.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_lists.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_locations.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_lots.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_notebooks.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_notes.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_parameter_groups.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_parameters.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_pricings.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_product_design.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_property_data.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_report_templates.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_reports.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_roles.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_storage_classes.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_storage_locations.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_substance.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_tags.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_tasks.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_un_number.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_units.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_users.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_workflows.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/collections/test_worksheet.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/core/shared/__init__.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/core/shared/test_identifiers.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/core/shared/test_types.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/core/test_auth.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/data/SDS_HCL.pdf +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/data/dontpanic.jpg +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/resources/test_inventory.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/resources/test_lots.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/resources/test_notebooks.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/resources/test_sheets.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/seeding.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/utils/fake_session.py +0 -0
- {albert-1.14.1 → albert-1.16.0}/tests/utils/test_patches.py +0 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
name: release-please-poc
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch: {}
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: write
|
|
8
|
+
pull-requests: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
release-please:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: googleapis/release-please-action@v4
|
|
15
|
+
with:
|
|
16
|
+
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
|
|
17
|
+
release-type: python
|
|
18
|
+
package-name: albert
|
|
19
|
+
target-branch: main
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ ".": "1.14.1" }
|
|
@@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.15.0] - 2026-02-04
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added `CustomTemplatesCollection.create` to support creating custom templates.
|
|
13
|
+
- Added `CustomTemplatesCollection.update_acl` to support updating custom template ACLs.
|
|
14
|
+
- Added `CustomTemplatesCollection.delete` to support deleting custom templates.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Standardized list-parameter normalization across collection filters so scalars and
|
|
19
|
+
iterables are handled consistently.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- Resolved custom-template ACL handling and schema parsing issues.
|
|
24
|
+
- Defaulted missing custom-template workflow names to a sensible value.
|
|
25
|
+
- Fixed enum parameter resolution to use session-level enum definitions.
|
|
26
|
+
|
|
8
27
|
## [1.14.0] - 2025-01-29
|
|
9
28
|
|
|
10
29
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: albert
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.16.0
|
|
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
|
|
@@ -9,7 +9,7 @@ from pydantic import validate_call
|
|
|
9
9
|
from albert.collections.base import BaseCollection
|
|
10
10
|
from albert.collections.files import FileCollection
|
|
11
11
|
from albert.collections.notes import NotesCollection
|
|
12
|
-
from albert.core.shared.identifiers import AttachmentId, DataColumnId, InventoryId
|
|
12
|
+
from albert.core.shared.identifiers import AttachmentId, DataColumnId, InventoryId, ProjectId
|
|
13
13
|
from albert.core.shared.types import MetadataItem
|
|
14
14
|
from albert.resources.attachments import Attachment, AttachmentCategory
|
|
15
15
|
from albert.resources.files import FileCategory, FileNamespace
|
|
@@ -288,3 +288,47 @@ class AttachmentCollection(BaseCollection):
|
|
|
288
288
|
|
|
289
289
|
response = self.session.post(self.base_path, json=payload)
|
|
290
290
|
return Attachment(**response.json())
|
|
291
|
+
|
|
292
|
+
@validate_call
|
|
293
|
+
def upload_and_attach_document_to_project(
|
|
294
|
+
self,
|
|
295
|
+
*,
|
|
296
|
+
project_id: ProjectId,
|
|
297
|
+
file_path: Path,
|
|
298
|
+
) -> Attachment:
|
|
299
|
+
"""Upload a file and attach it as a document to a project.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
project_id: The Albert ID of the project (e.g. "PRO770").
|
|
303
|
+
file_path: Local path to the file to upload.
|
|
304
|
+
|
|
305
|
+
Returns:
|
|
306
|
+
The created Attachment record.
|
|
307
|
+
"""
|
|
308
|
+
resolved_path = file_path.expanduser()
|
|
309
|
+
if not resolved_path.is_file():
|
|
310
|
+
raise FileNotFoundError(f"File not found at '{resolved_path}'")
|
|
311
|
+
|
|
312
|
+
content_type = mimetypes.guess_type(resolved_path.name)[0] or "application/octet-stream"
|
|
313
|
+
encoded_file_name = quote(resolved_path.name)
|
|
314
|
+
file_key = f"{project_id}/documents/original/{encoded_file_name}"
|
|
315
|
+
|
|
316
|
+
file_collection = self._get_file_collection()
|
|
317
|
+
with resolved_path.open("rb") as file_handle:
|
|
318
|
+
file_collection.sign_and_upload_file(
|
|
319
|
+
data=file_handle,
|
|
320
|
+
name=file_key,
|
|
321
|
+
namespace=FileNamespace.RESULT,
|
|
322
|
+
content_type=content_type,
|
|
323
|
+
)
|
|
324
|
+
|
|
325
|
+
payload = {
|
|
326
|
+
"parentId": project_id,
|
|
327
|
+
"category": AttachmentCategory.OTHER.value,
|
|
328
|
+
"name": encoded_file_name,
|
|
329
|
+
"key": file_key,
|
|
330
|
+
"nameSpace": FileNamespace.RESULT.value,
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
response = self.session.post(self.base_path, json=payload)
|
|
334
|
+
return Attachment(**response.json())
|
|
@@ -7,6 +7,7 @@ from albert.core.pagination import AlbertPaginator
|
|
|
7
7
|
from albert.core.session import AlbertSession
|
|
8
8
|
from albert.core.shared.enums import OrderBy, PaginationMode
|
|
9
9
|
from albert.core.shared.identifiers import BTInsightId
|
|
10
|
+
from albert.core.utils import ensure_list
|
|
10
11
|
from albert.resources.btinsight import BTInsight, BTInsightCategory, BTInsightState
|
|
11
12
|
|
|
12
13
|
|
|
@@ -132,17 +133,17 @@ class BTInsightCollection(BaseCollection):
|
|
|
132
133
|
"""
|
|
133
134
|
params = {
|
|
134
135
|
"offset": offset,
|
|
135
|
-
"order":
|
|
136
|
+
"order": order_by,
|
|
136
137
|
"sortBy": sort_by,
|
|
137
138
|
"text": text,
|
|
138
|
-
"name": name,
|
|
139
|
+
"name": ensure_list(name),
|
|
139
140
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
|
|
142
|
+
state_values = ensure_list(state)
|
|
143
|
+
params["state"] = state_values if state_values else None
|
|
144
|
+
|
|
145
|
+
category_values = ensure_list(category)
|
|
146
|
+
params["category"] = category_values if category_values else None
|
|
146
147
|
|
|
147
148
|
return AlbertPaginator(
|
|
148
149
|
mode=PaginationMode.OFFSET,
|
|
@@ -106,7 +106,7 @@ class CasCollection(BaseCollection):
|
|
|
106
106
|
An iterator over Cas entities.
|
|
107
107
|
"""
|
|
108
108
|
|
|
109
|
-
params: dict[str, Any] = {"orderBy": order_by
|
|
109
|
+
params: dict[str, Any] = {"orderBy": order_by}
|
|
110
110
|
if id is not None:
|
|
111
111
|
yield self.get_by_id(id=id)
|
|
112
112
|
return
|
|
@@ -7,6 +7,7 @@ from albert.core.logging import logger
|
|
|
7
7
|
from albert.core.pagination import AlbertPaginator, PaginationMode
|
|
8
8
|
from albert.core.session import AlbertSession
|
|
9
9
|
from albert.core.shared.identifiers import CompanyId
|
|
10
|
+
from albert.core.utils import ensure_list
|
|
10
11
|
from albert.exceptions import AlbertException
|
|
11
12
|
from albert.resources.companies import Company
|
|
12
13
|
|
|
@@ -62,9 +63,8 @@ class CompanyCollection(BaseCollection):
|
|
|
62
63
|
"dupDetection": "false",
|
|
63
64
|
"startKey": start_key,
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
params["exactMatch"] = str(exact_match).lower()
|
|
66
|
+
params["name"] = ensure_list(name)
|
|
67
|
+
params["exactMatch"] = str(exact_match).lower()
|
|
68
68
|
|
|
69
69
|
return AlbertPaginator(
|
|
70
70
|
mode=PaginationMode.KEY,
|
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
from collections.abc import Iterator
|
|
2
|
+
|
|
3
|
+
from pydantic import validate_call
|
|
4
|
+
|
|
5
|
+
from albert.collections.base import BaseCollection
|
|
6
|
+
from albert.collections.tags import TagCollection
|
|
7
|
+
from albert.core.logging import logger
|
|
8
|
+
from albert.core.pagination import AlbertPaginator
|
|
9
|
+
from albert.core.session import AlbertSession
|
|
10
|
+
from albert.core.shared.enums import OrderBy, PaginationMode, Status
|
|
11
|
+
from albert.core.shared.identifiers import CustomTemplateId
|
|
12
|
+
from albert.core.shared.models.patch import PatchOperation
|
|
13
|
+
from albert.core.utils import ensure_list
|
|
14
|
+
from albert.resources.acls import ACL
|
|
15
|
+
from albert.resources.custom_templates import (
|
|
16
|
+
CustomTemplate,
|
|
17
|
+
CustomTemplateSearchItem,
|
|
18
|
+
TemplateCategory,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class CustomTemplatesCollection(BaseCollection):
|
|
23
|
+
"""CustomTemplatesCollection is a collection class for managing CustomTemplate entities in the Albert platform."""
|
|
24
|
+
|
|
25
|
+
# _updatable_attributes = {"symbol", "synonyms", "category"}
|
|
26
|
+
_api_version = "v3"
|
|
27
|
+
|
|
28
|
+
def __init__(self, *, session: AlbertSession):
|
|
29
|
+
"""
|
|
30
|
+
Initializes the CustomTemplatesCollection with the provided session.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
session : AlbertSession
|
|
35
|
+
The Albert session instance.
|
|
36
|
+
"""
|
|
37
|
+
super().__init__(session=session)
|
|
38
|
+
self.base_path = f"/api/{CustomTemplatesCollection._api_version}/customtemplates"
|
|
39
|
+
|
|
40
|
+
@validate_call
|
|
41
|
+
def create(
|
|
42
|
+
self,
|
|
43
|
+
*,
|
|
44
|
+
custom_template: CustomTemplate | list[CustomTemplate],
|
|
45
|
+
) -> list[CustomTemplate]:
|
|
46
|
+
"""
|
|
47
|
+
Creates one or more custom templates.
|
|
48
|
+
|
|
49
|
+
Parameters
|
|
50
|
+
----------
|
|
51
|
+
custom_template : CustomTemplate | list[CustomTemplate]
|
|
52
|
+
The template entities to create.
|
|
53
|
+
|
|
54
|
+
Returns
|
|
55
|
+
-------
|
|
56
|
+
list[CustomTemplate]
|
|
57
|
+
The created CustomTemplate entities.
|
|
58
|
+
"""
|
|
59
|
+
templates = ensure_list(custom_template) or []
|
|
60
|
+
if len(templates) == 0:
|
|
61
|
+
raise ValueError("At least one CustomTemplate must be provided.")
|
|
62
|
+
if len(templates) > 10:
|
|
63
|
+
raise ValueError("A maximum of 10 CustomTemplates can be created at once.")
|
|
64
|
+
|
|
65
|
+
payload = [
|
|
66
|
+
template.model_dump(
|
|
67
|
+
mode="json",
|
|
68
|
+
by_alias=True,
|
|
69
|
+
exclude_none=True,
|
|
70
|
+
exclude_unset=True,
|
|
71
|
+
)
|
|
72
|
+
for template in templates
|
|
73
|
+
]
|
|
74
|
+
response = self.session.post(url=self.base_path, json=payload)
|
|
75
|
+
response_data = response.json()
|
|
76
|
+
created_payloads = (
|
|
77
|
+
(response_data or {}).get("CreatedItems")
|
|
78
|
+
if response.status_code == 206
|
|
79
|
+
else response_data
|
|
80
|
+
) or []
|
|
81
|
+
|
|
82
|
+
tag_collection = TagCollection(session=self.session)
|
|
83
|
+
|
|
84
|
+
def resolve_tag(tag_id: str | None) -> dict[str, str] | None:
|
|
85
|
+
if not tag_id:
|
|
86
|
+
return None
|
|
87
|
+
tag = tag_collection.get_by_id(id=tag_id)
|
|
88
|
+
return {"albertId": tag.id or tag_id, "name": tag.tag}
|
|
89
|
+
|
|
90
|
+
def populate_tag_names(section: dict | None) -> None:
|
|
91
|
+
if not isinstance(section, dict):
|
|
92
|
+
return
|
|
93
|
+
tags = section.get("Tags")
|
|
94
|
+
if not tags:
|
|
95
|
+
return
|
|
96
|
+
resolved_tags = []
|
|
97
|
+
for tag in tags:
|
|
98
|
+
if isinstance(tag, dict):
|
|
99
|
+
tag_id = tag.get("id") or tag.get("albertId")
|
|
100
|
+
elif isinstance(tag, str):
|
|
101
|
+
tag_id = tag
|
|
102
|
+
else:
|
|
103
|
+
tag_id = None
|
|
104
|
+
|
|
105
|
+
resolved_tag = resolve_tag(tag_id)
|
|
106
|
+
if resolved_tag:
|
|
107
|
+
resolved_tags.append(resolved_tag)
|
|
108
|
+
section["Tags"] = resolved_tags
|
|
109
|
+
|
|
110
|
+
for payload in created_payloads:
|
|
111
|
+
if not isinstance(payload, dict):
|
|
112
|
+
continue
|
|
113
|
+
populate_tag_names(payload.get("Data"))
|
|
114
|
+
|
|
115
|
+
if response.status_code == 206:
|
|
116
|
+
failed_items = response_data.get("FailedItems") or []
|
|
117
|
+
if failed_items:
|
|
118
|
+
error_messages = []
|
|
119
|
+
for failed in failed_items:
|
|
120
|
+
errors = failed.get("errors") or []
|
|
121
|
+
if errors:
|
|
122
|
+
error_messages.extend(err.get("msg", "Unknown error") for err in errors)
|
|
123
|
+
joined = " | ".join(error_messages) if error_messages else "Unknown error"
|
|
124
|
+
logger.warning(
|
|
125
|
+
"Custom template creation partially succeeded. Errors: %s",
|
|
126
|
+
joined,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
hydrated_templates = []
|
|
130
|
+
for payload in created_payloads:
|
|
131
|
+
template = CustomTemplate(**payload)
|
|
132
|
+
hydrated = self.get_by_id(id=template.id)
|
|
133
|
+
hydrated_templates.append(hydrated)
|
|
134
|
+
|
|
135
|
+
return hydrated_templates
|
|
136
|
+
|
|
137
|
+
def get_by_id(self, *, id: CustomTemplateId) -> CustomTemplate:
|
|
138
|
+
"""Get a Custom Template by ID
|
|
139
|
+
|
|
140
|
+
Parameters
|
|
141
|
+
----------
|
|
142
|
+
id : str
|
|
143
|
+
id of the custom template
|
|
144
|
+
|
|
145
|
+
Returns
|
|
146
|
+
-------
|
|
147
|
+
CustomTemplate
|
|
148
|
+
The CutomTemplate with the provided ID
|
|
149
|
+
"""
|
|
150
|
+
url = f"{self.base_path}/{id}"
|
|
151
|
+
response = self.session.get(url)
|
|
152
|
+
return CustomTemplate(**response.json())
|
|
153
|
+
|
|
154
|
+
def search(
|
|
155
|
+
self,
|
|
156
|
+
*,
|
|
157
|
+
text: str | None = None,
|
|
158
|
+
offset: int | None = 0,
|
|
159
|
+
sort_by: str | None = None,
|
|
160
|
+
order_by: OrderBy | None = None,
|
|
161
|
+
status: Status | None = None,
|
|
162
|
+
created_by: str | None = None,
|
|
163
|
+
category: TemplateCategory | list[TemplateCategory] | None = None,
|
|
164
|
+
created_by_name: str | list[str] | None = None,
|
|
165
|
+
collaborator: str | list[str] | None = None,
|
|
166
|
+
facet_text: str | None = None,
|
|
167
|
+
facet_field: str | None = None,
|
|
168
|
+
contains_field: str | list[str] | None = None,
|
|
169
|
+
contains_text: str | list[str] | None = None,
|
|
170
|
+
my_role: str | list[str] | None = None,
|
|
171
|
+
max_items: int | None = None,
|
|
172
|
+
) -> Iterator[CustomTemplateSearchItem]:
|
|
173
|
+
"""
|
|
174
|
+
Search for CustomTemplate matching the provided criteria.
|
|
175
|
+
|
|
176
|
+
⚠️ This method returns partial (unhydrated) entities to optimize performance.
|
|
177
|
+
To retrieve fully detailed entities, use :meth:`get_all` instead.
|
|
178
|
+
|
|
179
|
+
Parameters
|
|
180
|
+
----------
|
|
181
|
+
text : str, optional
|
|
182
|
+
Free text search term.
|
|
183
|
+
offset : int, optional
|
|
184
|
+
Starting offset for pagination.
|
|
185
|
+
sort_by : str, optional
|
|
186
|
+
Field to sort on.
|
|
187
|
+
order_by : OrderBy, optional
|
|
188
|
+
Sort direction for `sort_by`.
|
|
189
|
+
status : Status | str, optional
|
|
190
|
+
Filter results by template status.
|
|
191
|
+
created_by : str, optional
|
|
192
|
+
Filter by creator id.
|
|
193
|
+
category : TemplateCategory | list[TemplateCategory], optional
|
|
194
|
+
Filter by template categories.
|
|
195
|
+
created_by_name : str | list[str], optional
|
|
196
|
+
Filter by creator display name(s).
|
|
197
|
+
collaborator : str | list[str], optional
|
|
198
|
+
Filter by collaborator ids.
|
|
199
|
+
facet_text : str, optional
|
|
200
|
+
Filter text within a facet.
|
|
201
|
+
facet_field : str, optional
|
|
202
|
+
Facet field to search inside.
|
|
203
|
+
contains_field : str | list[str], optional
|
|
204
|
+
Fields to apply contains search to.
|
|
205
|
+
contains_text : str | list[str], optional
|
|
206
|
+
Text values for contains search.
|
|
207
|
+
my_role : str | list[str], optional
|
|
208
|
+
Restrict templates to roles held by the calling user.
|
|
209
|
+
max_items : int, optional
|
|
210
|
+
Maximum number of items to yield client-side.
|
|
211
|
+
|
|
212
|
+
Returns
|
|
213
|
+
-------
|
|
214
|
+
Iterator[CustomTemplateSearchItem]
|
|
215
|
+
An iterator of CustomTemplateSearchItem items.
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
params = {
|
|
219
|
+
"text": text,
|
|
220
|
+
"offset": offset,
|
|
221
|
+
"sortBy": sort_by,
|
|
222
|
+
"order": order_by,
|
|
223
|
+
"status": status,
|
|
224
|
+
"createdBy": created_by,
|
|
225
|
+
"category": ensure_list(category),
|
|
226
|
+
"createdByName": ensure_list(created_by_name),
|
|
227
|
+
"collaborator": ensure_list(collaborator),
|
|
228
|
+
"facetText": facet_text,
|
|
229
|
+
"facetField": facet_field,
|
|
230
|
+
"containsField": ensure_list(contains_field),
|
|
231
|
+
"containsText": ensure_list(contains_text),
|
|
232
|
+
"myRole": ensure_list(my_role),
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return AlbertPaginator(
|
|
236
|
+
mode=PaginationMode.OFFSET,
|
|
237
|
+
path=f"{self.base_path}/search",
|
|
238
|
+
session=self.session,
|
|
239
|
+
params=params,
|
|
240
|
+
max_items=max_items,
|
|
241
|
+
deserialize=lambda items: [
|
|
242
|
+
CustomTemplateSearchItem.model_validate(x)._bind_collection(self) for x in items
|
|
243
|
+
],
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
def get_all(
|
|
247
|
+
self,
|
|
248
|
+
*,
|
|
249
|
+
name: str | list[str] | None = None,
|
|
250
|
+
created_by: str | None = None,
|
|
251
|
+
category: TemplateCategory | None = None,
|
|
252
|
+
start_key: str | None = None,
|
|
253
|
+
max_items: int | None = None,
|
|
254
|
+
) -> Iterator[CustomTemplate]:
|
|
255
|
+
"""Iterate over CustomTemplate entities with optional filters.
|
|
256
|
+
|
|
257
|
+
Parameters
|
|
258
|
+
----------
|
|
259
|
+
name : str | list[str], optional
|
|
260
|
+
Filter by template name(s).
|
|
261
|
+
created_by : str, optional
|
|
262
|
+
Filter by creator id.
|
|
263
|
+
category : TemplateCategory, optional
|
|
264
|
+
Filter by category.
|
|
265
|
+
start_key : str, optional
|
|
266
|
+
Provide the `lastKey` from a previous request to resume pagination.
|
|
267
|
+
max_items : int, optional
|
|
268
|
+
Maximum number of items to return.
|
|
269
|
+
|
|
270
|
+
Returns
|
|
271
|
+
-------
|
|
272
|
+
Iterator[CustomTemplate]
|
|
273
|
+
An iterator of CustomTemplates.
|
|
274
|
+
"""
|
|
275
|
+
params = {
|
|
276
|
+
"startKey": start_key,
|
|
277
|
+
"createdBy": created_by,
|
|
278
|
+
"category": category,
|
|
279
|
+
}
|
|
280
|
+
params["name"] = ensure_list(name)
|
|
281
|
+
|
|
282
|
+
return AlbertPaginator(
|
|
283
|
+
mode=PaginationMode.KEY,
|
|
284
|
+
path=self.base_path,
|
|
285
|
+
session=self.session,
|
|
286
|
+
params=params,
|
|
287
|
+
max_items=max_items,
|
|
288
|
+
deserialize=lambda items: [CustomTemplate(**item) for item in items],
|
|
289
|
+
)
|
|
290
|
+
|
|
291
|
+
@validate_call
|
|
292
|
+
def delete(self, *, id: CustomTemplateId) -> None:
|
|
293
|
+
"""
|
|
294
|
+
Delete a custom template by id.
|
|
295
|
+
|
|
296
|
+
Parameters
|
|
297
|
+
----------
|
|
298
|
+
id : CustomTemplateId
|
|
299
|
+
The id of the custom template to delete.
|
|
300
|
+
|
|
301
|
+
Returns
|
|
302
|
+
-------
|
|
303
|
+
None
|
|
304
|
+
"""
|
|
305
|
+
|
|
306
|
+
url = f"{self.base_path}/{id}"
|
|
307
|
+
self.session.delete(url)
|
|
308
|
+
|
|
309
|
+
@validate_call
|
|
310
|
+
def update_acl(
|
|
311
|
+
self,
|
|
312
|
+
*,
|
|
313
|
+
custom_template_id: CustomTemplateId,
|
|
314
|
+
acl_class: str | None = None,
|
|
315
|
+
acls: list[ACL] | None = None,
|
|
316
|
+
) -> CustomTemplate:
|
|
317
|
+
"""
|
|
318
|
+
Replace a template's ACL class and/or entries with the provided values.
|
|
319
|
+
|
|
320
|
+
Parameters
|
|
321
|
+
----------
|
|
322
|
+
custom_template_id : CustomTemplateId
|
|
323
|
+
The id of the custom template to update.
|
|
324
|
+
acl_class : str | None, optional
|
|
325
|
+
The ACL class to set (if provided).
|
|
326
|
+
acls : list[ACL] | None, optional
|
|
327
|
+
The ACL entries to replace on the template.
|
|
328
|
+
|
|
329
|
+
Returns
|
|
330
|
+
-------
|
|
331
|
+
CustomTemplate
|
|
332
|
+
The updated CustomTemplate.
|
|
333
|
+
"""
|
|
334
|
+
|
|
335
|
+
if acl_class is None and acls is None:
|
|
336
|
+
raise ValueError("Provide an ACL class and/or ACL entries to update.")
|
|
337
|
+
|
|
338
|
+
data = []
|
|
339
|
+
current_template: CustomTemplate | None = None
|
|
340
|
+
|
|
341
|
+
if acl_class is not None:
|
|
342
|
+
acl_class_value = getattr(acl_class, "value", acl_class)
|
|
343
|
+
data.append(
|
|
344
|
+
{
|
|
345
|
+
"operation": PatchOperation.UPDATE.value,
|
|
346
|
+
"attribute": "class",
|
|
347
|
+
"newValue": acl_class_value,
|
|
348
|
+
}
|
|
349
|
+
)
|
|
350
|
+
|
|
351
|
+
if acls is not None:
|
|
352
|
+
current_template = self.get_by_id(id=custom_template_id)
|
|
353
|
+
current_acl = (
|
|
354
|
+
current_template.acl.fgclist
|
|
355
|
+
if current_template.acl and current_template.acl.fgclist
|
|
356
|
+
else []
|
|
357
|
+
)
|
|
358
|
+
current_entries = {
|
|
359
|
+
entry.id: getattr(entry.fgc, "value", entry.fgc) for entry in current_acl
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
desired_entries = {entry.id: getattr(entry.fgc, "value", entry.fgc) for entry in acls}
|
|
363
|
+
|
|
364
|
+
to_add = []
|
|
365
|
+
to_delete = []
|
|
366
|
+
to_update = []
|
|
367
|
+
|
|
368
|
+
for entry_id, new_fgc in desired_entries.items():
|
|
369
|
+
if entry_id not in current_entries:
|
|
370
|
+
payload = {"id": entry_id}
|
|
371
|
+
if new_fgc is not None:
|
|
372
|
+
payload["fgc"] = new_fgc
|
|
373
|
+
to_add.append(payload)
|
|
374
|
+
else:
|
|
375
|
+
old_fgc = current_entries[entry_id]
|
|
376
|
+
if new_fgc is not None and old_fgc != new_fgc:
|
|
377
|
+
to_update.append(
|
|
378
|
+
{
|
|
379
|
+
"operation": PatchOperation.UPDATE.value,
|
|
380
|
+
"attribute": "fgc",
|
|
381
|
+
"id": entry_id,
|
|
382
|
+
"oldValue": old_fgc,
|
|
383
|
+
"newValue": new_fgc,
|
|
384
|
+
}
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
for entry_id in current_entries:
|
|
388
|
+
if entry_id not in desired_entries:
|
|
389
|
+
to_delete.append({"id": entry_id})
|
|
390
|
+
|
|
391
|
+
if to_add:
|
|
392
|
+
data.append(
|
|
393
|
+
{
|
|
394
|
+
"operation": PatchOperation.ADD.value,
|
|
395
|
+
"attribute": "ACL",
|
|
396
|
+
"newValue": to_add,
|
|
397
|
+
}
|
|
398
|
+
)
|
|
399
|
+
if to_delete:
|
|
400
|
+
data.append(
|
|
401
|
+
{
|
|
402
|
+
"operation": PatchOperation.DELETE.value,
|
|
403
|
+
"attribute": "ACL",
|
|
404
|
+
"oldValue": to_delete,
|
|
405
|
+
}
|
|
406
|
+
)
|
|
407
|
+
data.extend(to_update)
|
|
408
|
+
|
|
409
|
+
if not data:
|
|
410
|
+
return current_template or self.get_by_id(id=custom_template_id)
|
|
411
|
+
|
|
412
|
+
url = f"{self.base_path}/{custom_template_id}/acl"
|
|
413
|
+
self.session.patch(url, json={"data": data})
|
|
414
|
+
return self.get_by_id(id=custom_template_id)
|
|
@@ -7,6 +7,7 @@ from albert.core.pagination import AlbertPaginator
|
|
|
7
7
|
from albert.core.session import AlbertSession
|
|
8
8
|
from albert.core.shared.enums import OrderBy, PaginationMode
|
|
9
9
|
from albert.core.shared.identifiers import DataColumnId
|
|
10
|
+
from albert.core.utils import ensure_list
|
|
10
11
|
from albert.resources.data_columns import DataColumn
|
|
11
12
|
|
|
12
13
|
|
|
@@ -102,12 +103,12 @@ class DataColumnCollection(BaseCollection):
|
|
|
102
103
|
yield from (DataColumn(**item) for item in items)
|
|
103
104
|
|
|
104
105
|
params = {
|
|
105
|
-
"orderBy": order_by
|
|
106
|
+
"orderBy": order_by,
|
|
106
107
|
"startKey": start_key,
|
|
107
|
-
"name":
|
|
108
|
+
"name": ensure_list(name),
|
|
108
109
|
"exactMatch": exact_match,
|
|
109
110
|
"default": default,
|
|
110
|
-
"dataColumns":
|
|
111
|
+
"dataColumns": ensure_list(ids),
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
return AlbertPaginator(
|
|
@@ -282,10 +282,10 @@ class EntityTypeCollection(BaseCollection):
|
|
|
282
282
|
Returns an iterator of EntityType items matching the search criteria.
|
|
283
283
|
"""
|
|
284
284
|
params = {
|
|
285
|
-
"service": service
|
|
285
|
+
"service": service,
|
|
286
286
|
"limit": max_items,
|
|
287
287
|
"startKey": start_key,
|
|
288
|
-
"orderBy": order
|
|
288
|
+
"orderBy": order,
|
|
289
289
|
}
|
|
290
290
|
return AlbertPaginator(
|
|
291
291
|
mode=PaginationMode.KEY,
|