lamindb 1.10.0__tar.gz → 1.10.2__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.
- {lamindb-1.10.0 → lamindb-1.10.2}/.github/workflows/build.yml +1 -1
- {lamindb-1.10.0 → lamindb-1.10.2}/PKG-INFO +5 -4
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/arrays.ipynb +17 -60
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/pydantic-pandera.ipynb +248 -14
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/__init__.py +1 -1
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/_settings.py +45 -2
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/_anndata_accessor.py +96 -18
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/_backed_access.py +10 -7
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/_spatialdata_accessor.py +15 -4
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/_zarr.py +3 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/curators/core.py +7 -5
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/datasets/__init__.py +4 -1
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/datasets/_core.py +33 -1
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/schemas/_anndata.py +1 -1
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/schemas/_simple.py +1 -1
- lamindb-1.10.2/lamindb/migrations/0118_alter_recordproject_value_projectrecord.py +99 -0
- lamindb-1.10.2/lamindb/migrations/0119_rename_records_project_linked_in_records.py +26 -0
- lamindb-1.10.0/lamindb/migrations/0117_squashed.py → lamindb-1.10.2/lamindb/migrations/0119_squashed.py +87 -3
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/artifact.py +31 -20
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/project.py +24 -2
- {lamindb-1.10.0 → lamindb-1.10.2}/noxfile.py +4 -4
- {lamindb-1.10.0 → lamindb-1.10.2}/pyproject.toml +2 -2
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/curators/test_curators_general.py +19 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/permissions/scripts/setup_access.py +1 -1
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/storage/conftest.py +3 -4
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/storage/test_artifact_storage.py +6 -9
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/storage/test_storage_lifecycle.py +1 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/storage/test_streaming.py +55 -1
- {lamindb-1.10.0 → lamindb-1.10.2}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/.github/ISSUE_TEMPLATE/usage_question.yml +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/.github/workflows/doc-changes.yml +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/.gitignore +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/.gitmodules +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/.pre-commit-config.yaml +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/CONTRIBUTING.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/LICENSE +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/README.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/api.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/bio-registries.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/bionty.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/changelog.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/clinicore.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/curate.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/acid.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/curate-any.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/delete.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/idempotency.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/import-modules.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/keep-artifacts-local.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/reference-field.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/search.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/setup.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/symbol-mapping.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/test_notebooks.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/track-run-inputs.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/validate-fields.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq/visibility.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/faq.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/guide.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/includes/installation.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/index.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/lamindb.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/query-search.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/registries.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/curate_anndata_flexible.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/curate_dataframe_flexible.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/curate_dataframe_minimal_errors.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/curate_mudata.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/curate_soma_experiment.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/curate_spatialdata.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/define_mini_immuno_features_labels.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/define_mini_immuno_schema_flexible.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/define_schema_anndata_ensembl_gene_ids_and_valid_features_in_obs.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/define_schema_spatialdata.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/define_valid_features.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/run_track_and_finish.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/run_track_with_params.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/run_workflow.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/save_mini_immuno_datasets.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/scripts/synced_with_git.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage/add-replace-cache.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage/anndata-accessor.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage/prepare-transfer-local-to-cloud.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage/test-files/iris.csv +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage/test-files/iris.data +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage/test-files/new_iris.csv +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage/test_notebooks.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage/transfer-local-to-cloud.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage/upload.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage/vitessce.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/storage.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/test_notebooks.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/track.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/transfer.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/docs/wetlab.md +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/_finish.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/_tracked.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/_view.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/base/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/base/fields.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/base/ids.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/base/types.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/base/uids.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/base/users.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/_compat.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/_context.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/_mapped_collection.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/_sync_git.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/_track_environment.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/exceptions.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/loaders.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/_polars_lazy_df.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/_pyarrow_dataset.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/_tiledbsoma.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/_valid_suffixes.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/objects.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/storage/paths.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/subsettings/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/subsettings/_annotation_settings.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/subsettings/_creation_settings.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/core/types.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/curators/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/curators/_legacy.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/errors.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/cellxgene/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/cellxgene/_cellxgene.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/cellxgene/cxg_schema_versions.csv +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/croissant/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/croissant/mini_immuno.anndata.zarr_metadata.json +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/datasets/_fake.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/datasets/_small.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/datasets/mini_immuno.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/fixtures/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/fixtures/sheets.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/examples/schemas/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/integrations/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/integrations/_croissant.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/integrations/_vitessce.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0069_squashed.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0070_lamindbv1_migrate_data.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0071_lamindbv1_migrate_schema.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0072_remove_user__branch_code_remove_user_aux_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0073_merge_ourprojects.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0074_lamindbv1_part4.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0075_lamindbv1_part5.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0076_lamindbv1_part6.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0077_lamindbv1_part6b.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0078_lamindbv1_part6c.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0079_alter_rundata_value_json_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0080_polish_lamindbv1.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0081_revert_textfield_collection.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0082_alter_feature_dtype.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0083_alter_feature_is_type_alter_flextable_is_type_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0084_alter_schemafeature_feature_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0085_alter_feature_is_type_alter_flextable_is_type_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0086_various.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0087_rename__schemas_m2m_artifact_feature_sets_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0088_schema_components.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0089_subsequent_runs.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0090_runproject_project_runs.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0091_alter_featurevalue_options_alter_space_options_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0092_alter_artifactfeaturevalue_artifact_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0093_alter_schemacomponent_unique_together.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0094_writeloglock_writelogmigrationstate_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0095_remove_rundata_flextable.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0096_remove_artifact__param_values_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0097_remove_schemaparam_param_remove_paramvalue_param_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0098_alter_feature_type_alter_project_type_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0099_alter_writelog_seqno.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0100_branch_alter_artifact__branch_code_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0101_alter_artifact_hash_alter_feature_name_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0102_remove_writelog_branch_code_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0103_remove_writelog_migration_state_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0104_alter_branch_uid.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0105_record_unique_name.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0106_transfer_data_migration.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0107_add_schema_to_record.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0108_remove_record_sheet_remove_sheetproject_sheet_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0109_record_input_of_runs_alter_record_run_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0110_rename_values_artifacts_record_linked_artifacts.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0111_remove_record__sort_order.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0112_alter_recordartifact_feature_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0113_lower_case_branch_and_space_names.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0114_alter_run__status_code.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0115_alter_space_uid.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0116_remove_artifact_unique_artifact_storage_key_hash_and_more.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/0117_fix_artifact_storage_hash_unique_constraints.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/migrations/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/_describe.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/_django.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/_feature_manager.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/_from_values.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/_is_versioned.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/_label_manager.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/_relations.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/artifact_set.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/can_curate.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/collection.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/feature.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/has_parents.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/query_manager.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/query_set.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/record.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/run.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/save.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/schema.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/sqlrecord.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/storage.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/transform.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/models/ulabel.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/py.typed +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/setup/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/setup/_switch.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/setup/core/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/setup/errors/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/lamindb/setup/types/__init__.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/conftest.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/_dataset_fixtures.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/conftest.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/notebooks/basic-r-notebook.Rmd.cleaned.html +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/notebooks/basic-r-notebook.Rmd.html +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/notebooks/duplicate/with-title-initialized-consecutive-finish.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/notebooks/no-title.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/notebooks/with-title-initialized-consecutive-finish-not-last-cell.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/notebooks/with-title-initialized-consecutive-finish.ipynb +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/scripts/duplicate1/script-to-test-versioning.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/scripts/duplicate2/script-to-test-versioning.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/scripts/duplicate3/script-to-test-versioning.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/scripts/duplicate4/script-to-test-versioning.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/scripts/duplicate5/script-to-test-versioning.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/scripts/script-to-test-filename-change.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/scripts/script-to-test-versioning.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_artifact.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_artifact_folders.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_can_curate.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_collection.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_data.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_db.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_delete.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_describe_and_df_calls.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_dtype.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_feature.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_feature_label_manager.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_from_values.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_has_parents.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_integrity.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_load.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_manager.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_models.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_notebooks.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_queryset.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_record.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_run.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_save.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_schema.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_search.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_settings.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_storage.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_track.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_tracked.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_transform.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_ulabel.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_versioning.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_view.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/core/test_visibility.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/curators/conftest.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/curators/test_cat_managers.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/curators/test_curate_from_croissant.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/curators/test_curators_examples.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/curators/test_curators_multivalue.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/curators/test_cxg_curator.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/curators/test_dataframe_curators_accounting_example.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/curators/test_records.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/permissions/conftest.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/permissions/jwt_utils.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/permissions/scripts/check_lamin_dev.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/permissions/scripts/clean_lamin_dev.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/permissions/scripts/setup_instance.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/permissions/test_permissions.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/storage/test_artifact_zarr.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/storage/test_cache.py +0 -0
- {lamindb-1.10.0 → lamindb-1.10.2}/tests/storage/test_transfer.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: lamindb
|
3
|
-
Version: 1.10.
|
3
|
+
Version: 1.10.2
|
4
4
|
Summary: A data framework for biology.
|
5
5
|
Author-email: Lamin Labs <open-source@lamin.ai>
|
6
6
|
Requires-Python: >=3.10,<3.14
|
@@ -9,9 +9,10 @@ Classifier: Programming Language :: Python :: 3.10
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.11
|
10
10
|
Classifier: Programming Language :: Python :: 3.12
|
11
11
|
Classifier: Programming Language :: Python :: 3.13
|
12
|
+
License-File: LICENSE
|
12
13
|
Requires-Dist: lamin_utils==0.15.0
|
13
14
|
Requires-Dist: lamin_cli==1.6.1
|
14
|
-
Requires-Dist: lamindb_setup[aws]==1.9.
|
15
|
+
Requires-Dist: lamindb_setup[aws]==1.9.1
|
15
16
|
Requires-Dist: pyyaml
|
16
17
|
Requires-Dist: pyarrow
|
17
18
|
Requires-Dist: pandera>=0.24.0
|
@@ -19,7 +20,7 @@ Requires-Dist: typing_extensions!=4.6.0
|
|
19
20
|
Requires-Dist: python-dateutil
|
20
21
|
Requires-Dist: pandas>=2.0.0
|
21
22
|
Requires-Dist: scipy<1.15.0
|
22
|
-
Requires-Dist: anndata>=0.8.0,<=0.12.
|
23
|
+
Requires-Dist: anndata>=0.8.0,<=0.12.1
|
23
24
|
Requires-Dist: fsspec
|
24
25
|
Requires-Dist: graphviz
|
25
26
|
Requires-Dist: psycopg2-binary
|
@@ -102,62 +102,6 @@
|
|
102
102
|
"ln.Artifact(\"s3://lamindb-ci/test-arrays/testfile.hdf5\").save()"
|
103
103
|
]
|
104
104
|
},
|
105
|
-
{
|
106
|
-
"cell_type": "markdown",
|
107
|
-
"metadata": {},
|
108
|
-
"source": [
|
109
|
-
"Note that it is also possible to register Hugging Face paths. For this `huggingface_hub` package should be installed."
|
110
|
-
]
|
111
|
-
},
|
112
|
-
{
|
113
|
-
"cell_type": "markdown",
|
114
|
-
"metadata": {},
|
115
|
-
"source": [
|
116
|
-
"We register a folder of `parquet` files as a single artifact."
|
117
|
-
]
|
118
|
-
},
|
119
|
-
{
|
120
|
-
"cell_type": "code",
|
121
|
-
"execution_count": null,
|
122
|
-
"metadata": {
|
123
|
-
"tags": [
|
124
|
-
"hide-output"
|
125
|
-
]
|
126
|
-
},
|
127
|
-
"outputs": [],
|
128
|
-
"source": [
|
129
|
-
"ln.Artifact(\"hf://datasets/Koncopd/lamindb-test/sharded_parquet\").save()"
|
130
|
-
]
|
131
|
-
},
|
132
|
-
{
|
133
|
-
"cell_type": "markdown",
|
134
|
-
"metadata": {},
|
135
|
-
"source": [
|
136
|
-
"We also register a collection of individual `parquet` files."
|
137
|
-
]
|
138
|
-
},
|
139
|
-
{
|
140
|
-
"cell_type": "code",
|
141
|
-
"execution_count": null,
|
142
|
-
"metadata": {
|
143
|
-
"tags": [
|
144
|
-
"hide-output"
|
145
|
-
]
|
146
|
-
},
|
147
|
-
"outputs": [],
|
148
|
-
"source": [
|
149
|
-
"artifact_shard1 = ln.Artifact(\n",
|
150
|
-
" \"hf://datasets/Koncopd/lamindb-test/sharded_parquet/louvain=0/947eee0b064440c9b9910ca2eb89e608-0.parquet\"\n",
|
151
|
-
").save()\n",
|
152
|
-
"artifact_shard2 = ln.Artifact(\n",
|
153
|
-
" \"hf://datasets/Koncopd/lamindb-test/sharded_parquet/louvain=1/947eee0b064440c9b9910ca2eb89e608-0.parquet\"\n",
|
154
|
-
").save()\n",
|
155
|
-
"\n",
|
156
|
-
"ln.Collection(\n",
|
157
|
-
" [artifact_shard1, artifact_shard2], key=\"sharded_parquet_collection\"\n",
|
158
|
-
").save()"
|
159
|
-
]
|
160
|
-
},
|
161
105
|
{
|
162
106
|
"cell_type": "markdown",
|
163
107
|
"metadata": {},
|
@@ -495,13 +439,20 @@
|
|
495
439
|
"A dataframe stored as sharded `parquet`."
|
496
440
|
]
|
497
441
|
},
|
442
|
+
{
|
443
|
+
"cell_type": "markdown",
|
444
|
+
"metadata": {},
|
445
|
+
"source": [
|
446
|
+
"Note that it is also possible to register and access Hugging Face paths. For this `huggingface_hub` package should be installed."
|
447
|
+
]
|
448
|
+
},
|
498
449
|
{
|
499
450
|
"cell_type": "code",
|
500
451
|
"execution_count": null,
|
501
452
|
"metadata": {},
|
502
453
|
"outputs": [],
|
503
454
|
"source": [
|
504
|
-
"artifact = ln.Artifact.get(key=\"sharded_parquet\")"
|
455
|
+
"artifact = ln.Artifact.using(\"laminlabs/lamindata\").get(key=\"sharded_parquet\")"
|
505
456
|
]
|
506
457
|
},
|
507
458
|
{
|
@@ -572,13 +523,19 @@
|
|
572
523
|
"metadata": {},
|
573
524
|
"outputs": [],
|
574
525
|
"source": [
|
575
|
-
"collection = ln.Collection.
|
526
|
+
"collection = ln.Collection.using(\"laminlabs/lamindata\").get(\n",
|
527
|
+
" key=\"sharded_parquet_collection\"\n",
|
528
|
+
")"
|
576
529
|
]
|
577
530
|
},
|
578
531
|
{
|
579
532
|
"cell_type": "code",
|
580
533
|
"execution_count": null,
|
581
|
-
"metadata": {
|
534
|
+
"metadata": {
|
535
|
+
"tags": [
|
536
|
+
"hide-output"
|
537
|
+
]
|
538
|
+
},
|
582
539
|
"outputs": [],
|
583
540
|
"source": [
|
584
541
|
"backed = collection.open()"
|
@@ -663,7 +620,7 @@
|
|
663
620
|
"outputs": [],
|
664
621
|
"source": [
|
665
622
|
"# clean up test instance\n",
|
666
|
-
"
|
623
|
+
"ln.setup.delete(\"test-arrays\", force=True)"
|
667
624
|
]
|
668
625
|
}
|
669
626
|
],
|
@@ -11,7 +11,7 @@
|
|
11
11
|
"cell_type": "markdown",
|
12
12
|
"metadata": {},
|
13
13
|
"source": [
|
14
|
-
"This doc explains conceptual differences between data validation with `pydantic`, `pandera`, and `
|
14
|
+
"This doc explains conceptual differences between data validation with `pydantic`, `pandera`, and `LaminDB`."
|
15
15
|
]
|
16
16
|
},
|
17
17
|
{
|
@@ -42,10 +42,12 @@
|
|
42
42
|
"source": [
|
43
43
|
"import pandas as pd\n",
|
44
44
|
"import pydantic\n",
|
45
|
-
"from typing import Literal\n",
|
46
45
|
"import lamindb as ln\n",
|
47
46
|
"import bionty as bt\n",
|
48
|
-
"import pandera\n",
|
47
|
+
"import pandera.pandas as pandera\n",
|
48
|
+
"import pprint\n",
|
49
|
+
"\n",
|
50
|
+
"from typing import Literal, Any\n",
|
49
51
|
"\n",
|
50
52
|
"df = ln.core.datasets.small_dataset1()\n",
|
51
53
|
"df"
|
@@ -102,7 +104,6 @@
|
|
102
104
|
"metadata": {},
|
103
105
|
"outputs": [],
|
104
106
|
"source": [
|
105
|
-
"# Define the Pandera schema using DataFrameSchema\n",
|
106
107
|
"pandera_schema = pandera.DataFrameSchema(\n",
|
107
108
|
" {\n",
|
108
109
|
" \"perturbation\": pandera.Column(\n",
|
@@ -127,14 +128,15 @@
|
|
127
128
|
"cell_type": "markdown",
|
128
129
|
"metadata": {},
|
129
130
|
"source": [
|
130
|
-
"###
|
131
|
+
"### LaminDB"
|
131
132
|
]
|
132
133
|
},
|
133
134
|
{
|
134
135
|
"cell_type": "markdown",
|
135
136
|
"metadata": {},
|
136
137
|
"source": [
|
137
|
-
"Features & labels are defined on the level of the database instance
|
138
|
+
"Features & labels are defined on the level of the database instance.\n",
|
139
|
+
"You can either define a schema with required (and optional) columns."
|
138
140
|
]
|
139
141
|
},
|
140
142
|
{
|
@@ -147,8 +149,8 @@
|
|
147
149
|
},
|
148
150
|
"outputs": [],
|
149
151
|
"source": [
|
150
|
-
"ln.ULabel(name=\"DMSO\").save()
|
151
|
-
"ln.ULabel(name=\"IFNG\").save()
|
152
|
+
"ln.ULabel(name=\"DMSO\").save()\n",
|
153
|
+
"ln.ULabel(name=\"IFNG\").save()\n",
|
152
154
|
"\n",
|
153
155
|
"# leverage ontologies through types ln.ULabel, bt.CellType, bt.ExperimentalFactor\n",
|
154
156
|
"lamindb_schema = ln.Schema(\n",
|
@@ -308,7 +310,7 @@
|
|
308
310
|
"cell_type": "markdown",
|
309
311
|
"metadata": {},
|
310
312
|
"source": [
|
311
|
-
"###
|
313
|
+
"### LaminDB"
|
312
314
|
]
|
313
315
|
},
|
314
316
|
{
|
@@ -317,7 +319,8 @@
|
|
317
319
|
"source": [
|
318
320
|
"Because the term `\"CD8-positive, alpha-beta T cell\"` is part of the public `CellType` ontology, validation passes the first time.\n",
|
319
321
|
"\n",
|
320
|
-
"If validation
|
322
|
+
"If validation had not passed, we could have resolved the issue simply by adding a new term to the `CellType` registry rather than editing the code.\n",
|
323
|
+
"This also puts downstream data scientists into a position to update ontologies."
|
321
324
|
]
|
322
325
|
},
|
323
326
|
{
|
@@ -380,7 +383,7 @@
|
|
380
383
|
"source": [
|
381
384
|
"## Overview of validation properties\n",
|
382
385
|
"\n",
|
383
|
-
"Importantly, LaminDB offers not only a `DataFrameCurator`, but also a `AnnDataCurator`, `MuDataCurator`, `SpatialDataCurator`, `TiledbsomaCurator`.\n",
|
386
|
+
"Importantly, LaminDB offers not only a `DataFrameCurator`, but also a `AnnDataCurator`, `MuDataCurator`, `SpatialDataCurator`, and `TiledbsomaCurator`.\n",
|
384
387
|
"\n",
|
385
388
|
"The below overview only concerns validating dataframes."
|
386
389
|
]
|
@@ -464,7 +467,7 @@
|
|
464
467
|
"cell_type": "markdown",
|
465
468
|
"metadata": {},
|
466
469
|
"source": [
|
467
|
-
"If you don't expect a need for Curator functionality for updating ontologies and
|
470
|
+
"If you don't expect a need for Curator functionality for updating ontologies and standardization, you can also use the `Artifact` constructor."
|
468
471
|
]
|
469
472
|
},
|
470
473
|
{
|
@@ -561,11 +564,242 @@
|
|
561
564
|
"source": [
|
562
565
|
"artifact.schema.features.df()"
|
563
566
|
]
|
567
|
+
},
|
568
|
+
{
|
569
|
+
"cell_type": "markdown",
|
570
|
+
"metadata": {},
|
571
|
+
"source": [
|
572
|
+
"## Nested data with dynamic keys"
|
573
|
+
]
|
574
|
+
},
|
575
|
+
{
|
576
|
+
"cell_type": "markdown",
|
577
|
+
"metadata": {},
|
578
|
+
"source": [
|
579
|
+
"We will now examine another more complex example where data is nested with potentially arbitrary (dynamic) keys.\n",
|
580
|
+
"The example is inspired by the [CELLxGENE schema](https://github.com/chanzuckerberg/single-cell-curation/blob/main/schema/6.0.0/schema.md#uns-dataset-metadata) where annotations are stored as dictionaries in the AnnData `.uns` slot."
|
581
|
+
]
|
582
|
+
},
|
583
|
+
{
|
584
|
+
"cell_type": "code",
|
585
|
+
"execution_count": null,
|
586
|
+
"metadata": {},
|
587
|
+
"outputs": [],
|
588
|
+
"source": [
|
589
|
+
"uns_dict = ln.core.datasets.dict_cxg_uns()\n",
|
590
|
+
"pprint.pprint(uns_dict)"
|
591
|
+
]
|
592
|
+
},
|
593
|
+
{
|
594
|
+
"cell_type": "markdown",
|
595
|
+
"metadata": {},
|
596
|
+
"source": [
|
597
|
+
"### pydantic"
|
598
|
+
]
|
599
|
+
},
|
600
|
+
{
|
601
|
+
"cell_type": "markdown",
|
602
|
+
"metadata": {},
|
603
|
+
"source": [
|
604
|
+
"Pydantic is primed to deal with nested data."
|
605
|
+
]
|
606
|
+
},
|
607
|
+
{
|
608
|
+
"cell_type": "code",
|
609
|
+
"execution_count": null,
|
610
|
+
"metadata": {},
|
611
|
+
"outputs": [],
|
612
|
+
"source": [
|
613
|
+
"class Images(pydantic.BaseModel):\n",
|
614
|
+
" fullres: str\n",
|
615
|
+
" hires: str\n",
|
616
|
+
"\n",
|
617
|
+
"\n",
|
618
|
+
"class Scalefactors(pydantic.BaseModel):\n",
|
619
|
+
" spot_diameter_fullres: float\n",
|
620
|
+
" tissue_hires_scalef: float\n",
|
621
|
+
"\n",
|
622
|
+
"\n",
|
623
|
+
"class Library(pydantic.BaseModel):\n",
|
624
|
+
" images: Images\n",
|
625
|
+
" scalefactors: Scalefactors\n",
|
626
|
+
"\n",
|
627
|
+
"\n",
|
628
|
+
"class Spatial(pydantic.BaseModel):\n",
|
629
|
+
" is_single: bool\n",
|
630
|
+
" model_config = {\"extra\": \"allow\"}\n",
|
631
|
+
"\n",
|
632
|
+
" def __init__(self, **data):\n",
|
633
|
+
" libraries = {}\n",
|
634
|
+
" other_fields = {}\n",
|
635
|
+
"\n",
|
636
|
+
" # store all libraries under a single key for validation\n",
|
637
|
+
" for key, value in data.items():\n",
|
638
|
+
" if key.startswith(\"library_\"):\n",
|
639
|
+
" libraries[key] = Library(**value)\n",
|
640
|
+
" else:\n",
|
641
|
+
" other_fields[key] = value\n",
|
642
|
+
"\n",
|
643
|
+
" other_fields[\"libraries\"] = libraries\n",
|
644
|
+
" super().__init__(**other_fields)\n",
|
645
|
+
"\n",
|
646
|
+
"\n",
|
647
|
+
"class SpatialDataSchema(pydantic.BaseModel):\n",
|
648
|
+
" organism_ontology_term_id: str\n",
|
649
|
+
" spatial: Spatial\n",
|
650
|
+
"\n",
|
651
|
+
"\n",
|
652
|
+
"validated_data = SpatialDataSchema(**uns_dict)"
|
653
|
+
]
|
654
|
+
},
|
655
|
+
{
|
656
|
+
"cell_type": "markdown",
|
657
|
+
"metadata": {},
|
658
|
+
"source": [
|
659
|
+
"However, pydantic either requires all dictionary keys to be known beforehand to construct the Model classes or workarounds to collect all keys for a single model."
|
660
|
+
]
|
661
|
+
},
|
662
|
+
{
|
663
|
+
"cell_type": "markdown",
|
664
|
+
"metadata": {},
|
665
|
+
"source": [
|
666
|
+
"### pandera"
|
667
|
+
]
|
668
|
+
},
|
669
|
+
{
|
670
|
+
"cell_type": "markdown",
|
671
|
+
"metadata": {},
|
672
|
+
"source": [
|
673
|
+
"Pandera cannot validate dictionaries because it is designed for structured dataframe data.\n",
|
674
|
+
"Therefore, we need to flatten the dictionary to transform it into a DataFrame:"
|
675
|
+
]
|
676
|
+
},
|
677
|
+
{
|
678
|
+
"cell_type": "code",
|
679
|
+
"execution_count": null,
|
680
|
+
"metadata": {},
|
681
|
+
"outputs": [],
|
682
|
+
"source": [
|
683
|
+
"def _flatten_dict(d: dict[Any, Any], parent_key: str = \"\", sep: str = \"_\"):\n",
|
684
|
+
" items = []\n",
|
685
|
+
" for k, v in d.items():\n",
|
686
|
+
" new_key = f\"{parent_key}{sep}{k}\" if parent_key else k\n",
|
687
|
+
" if isinstance(v, dict):\n",
|
688
|
+
" items.extend(_flatten_dict(v, new_key, sep=sep).items())\n",
|
689
|
+
" else:\n",
|
690
|
+
" items.append((new_key, v))\n",
|
691
|
+
" return dict(items)"
|
692
|
+
]
|
693
|
+
},
|
694
|
+
{
|
695
|
+
"cell_type": "code",
|
696
|
+
"execution_count": null,
|
697
|
+
"metadata": {},
|
698
|
+
"outputs": [],
|
699
|
+
"source": [
|
700
|
+
"def create_dynamic_schema(flattened_data: dict[str, Any]):\n",
|
701
|
+
" schema_dict = {\n",
|
702
|
+
" \"organism_ontology_term_id\": pandera.Column(str),\n",
|
703
|
+
" \"spatial_is_single\": pandera.Column(bool),\n",
|
704
|
+
" }\n",
|
705
|
+
"\n",
|
706
|
+
" for key in flattened_data.keys():\n",
|
707
|
+
" if key.startswith(\"spatial_library_\") and key.endswith(\"_images_fullres\"):\n",
|
708
|
+
" lib_prefix = key.replace(\"_images_fullres\", \"\")\n",
|
709
|
+
" schema_dict.update(\n",
|
710
|
+
" {\n",
|
711
|
+
" f\"{lib_prefix}_images_fullres\": pandera.Column(str),\n",
|
712
|
+
" f\"{lib_prefix}_images_hires\": pandera.Column(str),\n",
|
713
|
+
" f\"{lib_prefix}_scalefactors_spot_diameter_fullres\": pandera.Column(\n",
|
714
|
+
" float\n",
|
715
|
+
" ),\n",
|
716
|
+
" f\"{lib_prefix}_scalefactors_tissue_hires_scalef\": pandera.Column(\n",
|
717
|
+
" float\n",
|
718
|
+
" ),\n",
|
719
|
+
" }\n",
|
720
|
+
" )\n",
|
721
|
+
"\n",
|
722
|
+
" return pandera.DataFrameSchema(schema_dict)\n",
|
723
|
+
"\n",
|
724
|
+
"\n",
|
725
|
+
"flattened = _flatten_dict(uns_dict)\n",
|
726
|
+
"df = pd.DataFrame([flattened])\n",
|
727
|
+
"spatial_schema = create_dynamic_schema(flattened)\n",
|
728
|
+
"validated_df = spatial_schema.validate(df)"
|
729
|
+
]
|
730
|
+
},
|
731
|
+
{
|
732
|
+
"cell_type": "markdown",
|
733
|
+
"metadata": {},
|
734
|
+
"source": [
|
735
|
+
"Analogously to pydantic, pandera does not have out of the box support for dynamically named keys.\n",
|
736
|
+
"Therefore, it is necessary to dynamically construct a pydantic schema."
|
737
|
+
]
|
738
|
+
},
|
739
|
+
{
|
740
|
+
"cell_type": "markdown",
|
741
|
+
"metadata": {},
|
742
|
+
"source": [
|
743
|
+
"### LaminDB"
|
744
|
+
]
|
745
|
+
},
|
746
|
+
{
|
747
|
+
"cell_type": "markdown",
|
748
|
+
"metadata": {},
|
749
|
+
"source": [
|
750
|
+
"Similarly, LaminDB currently requires constructing flattened dataframes to dynamically create features for the schema, which can then be used for validation with the DataFrameCurator.\n",
|
751
|
+
"Future improvements are expected, including support for a dictionary-specific curator."
|
752
|
+
]
|
753
|
+
},
|
754
|
+
{
|
755
|
+
"cell_type": "code",
|
756
|
+
"execution_count": null,
|
757
|
+
"metadata": {
|
758
|
+
"tags": [
|
759
|
+
"hide-output"
|
760
|
+
]
|
761
|
+
},
|
762
|
+
"outputs": [],
|
763
|
+
"source": [
|
764
|
+
"def create_dynamic_schema(flattened_data: dict[str, Any]) -> ln.Schema:\n",
|
765
|
+
" features = []\n",
|
766
|
+
"\n",
|
767
|
+
" for key, value in flattened_data.items():\n",
|
768
|
+
" if key == \"organism_ontology_term_id\":\n",
|
769
|
+
" features.append(ln.Feature(name=key, dtype=bt.Organism.ontology_id).save())\n",
|
770
|
+
" elif isinstance(value, bool):\n",
|
771
|
+
" features.append(ln.Feature(name=key, dtype=bool).save())\n",
|
772
|
+
" elif isinstance(value, (int, float)):\n",
|
773
|
+
" features.append(ln.Feature(name=key, dtype=float).save())\n",
|
774
|
+
" else:\n",
|
775
|
+
" features.append(ln.Feature(name=key, dtype=str).save())\n",
|
776
|
+
"\n",
|
777
|
+
" return ln.Schema(\n",
|
778
|
+
" name=\"Spatial data schema\", features=features, coerce_dtype=True\n",
|
779
|
+
" ).save()\n",
|
780
|
+
"\n",
|
781
|
+
"\n",
|
782
|
+
"flattened = _flatten_dict(uns_dict)\n",
|
783
|
+
"flattened_df = pd.DataFrame([flattened])\n",
|
784
|
+
"spatial_schema = create_dynamic_schema(flattened)\n",
|
785
|
+
"curator = ln.curators.DataFrameCurator(flattened_df, spatial_schema)\n",
|
786
|
+
"curator.validate()"
|
787
|
+
]
|
788
|
+
},
|
789
|
+
{
|
790
|
+
"cell_type": "markdown",
|
791
|
+
"metadata": {},
|
792
|
+
"source": [
|
793
|
+
"```{note}\n",
|
794
|
+
"Curators for scverse data structures allow for the specification of schema slots that access and validate dataframes in nested dictionary attributes like `.attrs` or `.uns`.\n",
|
795
|
+
"These schema slots use colon-separated paths like `'attrs:sample'` or `'uns:spatial:images'` to to target specific dataframes for validation.\n",
|
796
|
+
"```"
|
797
|
+
]
|
564
798
|
}
|
565
799
|
],
|
566
800
|
"metadata": {
|
567
801
|
"kernelspec": {
|
568
|
-
"display_name": "
|
802
|
+
"display_name": "lamindb",
|
569
803
|
"language": "python",
|
570
804
|
"name": "python3"
|
571
805
|
},
|
@@ -579,7 +813,7 @@
|
|
579
813
|
"name": "python",
|
580
814
|
"nbconvert_exporter": "python",
|
581
815
|
"pygments_lexer": "ipython3",
|
582
|
-
"version": "3.
|
816
|
+
"version": "3.12.8"
|
583
817
|
}
|
584
818
|
},
|
585
819
|
"nbformat": 4,
|
@@ -10,6 +10,7 @@ from lamindb_setup import settings as setup_settings
|
|
10
10
|
from lamindb_setup._set_managed_storage import set_managed_storage
|
11
11
|
from lamindb_setup.core import deprecated
|
12
12
|
from lamindb_setup.core._settings_instance import sanitize_git_repo_url
|
13
|
+
from lamindb_setup.core._settings_storage import StorageSettings
|
13
14
|
|
14
15
|
from .subsettings._annotation_settings import AnnotationSettings, annotation_settings
|
15
16
|
from .subsettings._creation_settings import CreationSettings, creation_settings
|
@@ -18,7 +19,6 @@ if TYPE_CHECKING:
|
|
18
19
|
from collections.abc import Mapping
|
19
20
|
from pathlib import Path
|
20
21
|
|
21
|
-
from lamindb_setup.core._settings_storage import StorageSettings
|
22
22
|
from upath import UPath
|
23
23
|
|
24
24
|
|
@@ -193,13 +193,39 @@ class Settings:
|
|
193
193
|
|
194
194
|
@storage.setter
|
195
195
|
def storage(self, path_kwargs: str | Path | UPath | tuple[str | UPath, Mapping]):
|
196
|
+
import lamindb as ln
|
197
|
+
|
196
198
|
if isinstance(path_kwargs, tuple):
|
197
199
|
path, kwargs = path_kwargs
|
200
|
+
# we should ultimately deprecate passing host here, I think
|
198
201
|
if isinstance(kwargs, str):
|
199
202
|
kwargs = {"host": kwargs}
|
200
203
|
else:
|
201
204
|
path, kwargs = path_kwargs, {}
|
202
|
-
|
205
|
+
ssettings = StorageSettings(root=path) # there is no need to pass kwargs here!
|
206
|
+
exists = ln.Storage.filter(root=ssettings.root_as_str).one_or_none()
|
207
|
+
if exists is None:
|
208
|
+
response = input(
|
209
|
+
f"Storage location {ssettings.root_as_str} does not yet exist. Do you want to continue with creating it? (y/n)"
|
210
|
+
)
|
211
|
+
# logger.warning(f"deprecated call because storage location does **not yet** exist; going forward, please create through ln.Storage(root={path}).save() going forward")
|
212
|
+
if response != "y":
|
213
|
+
return None
|
214
|
+
set_managed_storage(path, **kwargs)
|
215
|
+
else:
|
216
|
+
if exists.instance_uid != ln_setup.settings.instance.uid:
|
217
|
+
raise ValueError(
|
218
|
+
f"Storage {ssettings.root_as_str} exists in another instance ({exists.instance_uid}), cannot write to it from here."
|
219
|
+
)
|
220
|
+
ssettings = StorageSettings(
|
221
|
+
root=exists.root,
|
222
|
+
region=exists.region,
|
223
|
+
uid=exists.uid,
|
224
|
+
instance_id=ln_setup.settings.instance._id,
|
225
|
+
)
|
226
|
+
ln_setup.settings.instance._storage = ssettings
|
227
|
+
kwargs.pop("host", None) # host is not needed for existing storage
|
228
|
+
settings.storage._set_fs_kwargs(**kwargs)
|
203
229
|
|
204
230
|
@property
|
205
231
|
def instance_uid(self) -> str:
|
@@ -223,6 +249,23 @@ class Settings:
|
|
223
249
|
|
224
250
|
@local_storage.setter
|
225
251
|
def local_storage(self, local_root: Path):
|
252
|
+
import lamindb as ln
|
253
|
+
|
254
|
+
# note duplication with storage setter!
|
255
|
+
ssettings = StorageSettings(root=local_root)
|
256
|
+
exists = ln.Storage.filter(root=ssettings.root_as_str).one_or_none()
|
257
|
+
if exists is None:
|
258
|
+
response = input(
|
259
|
+
f"Storage location {ssettings.root_as_str} does not yet exist. Do you want to continue with creating it? (y/n)"
|
260
|
+
)
|
261
|
+
# logger.warning(f"deprecated call because storage location does **not yet** exist; going forward, please create through ln.Storage(root={path}).save() going forward")
|
262
|
+
if response != "y":
|
263
|
+
return None
|
264
|
+
else:
|
265
|
+
if exists.instance_uid != ln_setup.settings.instance.uid:
|
266
|
+
raise ValueError(
|
267
|
+
f"Storage {ssettings.root_as_str} exists in another instance ({exists.instance_uid}), cannot write to it from here."
|
268
|
+
)
|
226
269
|
ln_setup.settings.instance.local_storage = local_root
|
227
270
|
|
228
271
|
@property
|