lamindb 1.11.1__tar.gz → 1.11.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lamindb-1.11.3/PKG-INFO +180 -0
- lamindb-1.11.3/README.md +126 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/query-search.md +1 -1
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/registries.ipynb +4 -23
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/__init__.py +1 -1
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/query_set.py +24 -16
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/save.py +12 -2
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/schema.py +17 -5
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/sqlrecord.py +1 -1
- {lamindb-1.11.1 → lamindb-1.11.3}/pyproject.toml +2 -2
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_artifact.py +1 -5
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_queryset.py +34 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_schema.py +6 -3
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/curators/test_curators_examples.py +5 -5
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/permissions/test_permissions.py +14 -1
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/storage/test_artifact_storage.py +11 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/storage/test_streaming.py +2 -1
- lamindb-1.11.1/PKG-INFO +0 -139
- lamindb-1.11.1/README.md +0 -85
- {lamindb-1.11.1 → lamindb-1.11.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/.github/ISSUE_TEMPLATE/usage_question.yml +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/.github/workflows/build.yml +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/.github/workflows/doc-changes.yml +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/.gitignore +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/.gitmodules +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/.pre-commit-config.yaml +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/CONTRIBUTING.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/LICENSE +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/api.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/arrays.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/bio-registries.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/bionty.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/changelog.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/clinicore.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/curate.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/acid.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/curate-any.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/delete.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/idempotency.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/import-modules.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/keep-artifacts-local.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/pydantic-pandera.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/reference-field.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/search.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/setup.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/symbol-mapping.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/test_notebooks.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/track-run-inputs.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/validate-fields.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq/visibility.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/faq.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/guide.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/includes/installation.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/index.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/lamindb.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/curate_anndata_flexible.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/curate_anndata_uns.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/curate_dataframe_attrs.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/curate_dataframe_external_features.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/curate_dataframe_flexible.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/curate_dataframe_minimal_errors.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/curate_mudata.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/curate_soma_experiment.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/curate_spatialdata.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/define_mini_immuno_features_labels.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/define_mini_immuno_schema_flexible.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/define_schema_anndata_ensembl_gene_ids_and_valid_features_in_obs.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/define_schema_anndata_uns.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/define_schema_df_metadata.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/define_schema_spatialdata.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/define_valid_features.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/run_track_and_finish.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/run_track_with_params.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/run_workflow.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/save_mini_immuno_datasets.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/scripts/synced_with_git.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage/add-replace-cache.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage/anndata-accessor.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage/prepare-transfer-local-to-cloud.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage/test-files/iris.csv +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage/test-files/iris.data +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage/test-files/new_iris.csv +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage/test_notebooks.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage/transfer-local-to-cloud.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage/upload.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage/vitessce.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/storage.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/test_notebooks.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/track.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/transfer.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/docs/wetlab.md +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/_finish.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/_tracked.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/_view.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/base/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/base/dtypes.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/base/fields.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/base/ids.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/base/types.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/base/uids.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/base/users.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/_compat.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/_context.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/_mapped_collection.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/_settings.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/_sync_git.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/_track_environment.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/exceptions.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/loaders.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/_anndata_accessor.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/_backed_access.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/_polars_lazy_df.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/_pyarrow_dataset.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/_spatialdata_accessor.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/_tiledbsoma.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/_valid_suffixes.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/_zarr.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/objects.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/storage/paths.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/subsettings/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/subsettings/_annotation_settings.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/subsettings/_creation_settings.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/core/types.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/curators/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/curators/_legacy.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/curators/core.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/errors.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/cellxgene/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/cellxgene/_cellxgene.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/cellxgene/cellxgene_schema_versions.csv +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/croissant/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/croissant/mini_immuno.anndata.zarr_metadata.json +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/datasets/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/datasets/_core.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/datasets/_fake.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/datasets/_small.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/datasets/mini_immuno.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/fixtures/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/fixtures/sheets.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/schemas/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/schemas/_anndata.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/examples/schemas/_simple.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/integrations/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/integrations/_croissant.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/integrations/_vitessce.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0069_squashed.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0070_lamindbv1_migrate_data.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0071_lamindbv1_migrate_schema.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0072_remove_user__branch_code_remove_user_aux_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0073_merge_ourprojects.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0074_lamindbv1_part4.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0075_lamindbv1_part5.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0076_lamindbv1_part6.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0077_lamindbv1_part6b.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0078_lamindbv1_part6c.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0079_alter_rundata_value_json_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0080_polish_lamindbv1.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0081_revert_textfield_collection.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0082_alter_feature_dtype.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0083_alter_feature_is_type_alter_flextable_is_type_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0084_alter_schemafeature_feature_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0085_alter_feature_is_type_alter_flextable_is_type_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0086_various.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0087_rename__schemas_m2m_artifact_feature_sets_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0088_schema_components.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0089_subsequent_runs.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0090_runproject_project_runs.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0091_alter_featurevalue_options_alter_space_options_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0092_alter_artifactfeaturevalue_artifact_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0093_alter_schemacomponent_unique_together.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0094_writeloglock_writelogmigrationstate_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0095_remove_rundata_flextable.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0096_remove_artifact__param_values_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0097_remove_schemaparam_param_remove_paramvalue_param_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0098_alter_feature_type_alter_project_type_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0099_alter_writelog_seqno.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0100_branch_alter_artifact__branch_code_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0101_alter_artifact_hash_alter_feature_name_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0102_remove_writelog_branch_code_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0103_remove_writelog_migration_state_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0104_alter_branch_uid.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0105_record_unique_name.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0106_transfer_data_migration.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0107_add_schema_to_record.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0108_remove_record_sheet_remove_sheetproject_sheet_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0109_record_input_of_runs_alter_record_run_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0110_rename_values_artifacts_record_linked_artifacts.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0111_remove_record__sort_order.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0112_alter_recordartifact_feature_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0113_lower_case_branch_and_space_names.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0114_alter_run__status_code.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0115_alter_space_uid.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0116_remove_artifact_unique_artifact_storage_key_hash_and_more.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0117_fix_artifact_storage_hash_unique_constraints.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0118_alter_recordproject_value_projectrecord.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0119_rename_records_project_linked_in_records.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0119_squashed.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0120_add_record_fk_constraint.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/0121_recorduser.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/migrations/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/_describe.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/_django.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/_feature_manager.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/_from_values.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/_is_versioned.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/_label_manager.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/_relations.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/artifact.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/artifact_set.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/can_curate.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/collection.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/feature.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/has_parents.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/project.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/query_manager.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/record.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/run.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/storage.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/transform.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/models/ulabel.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/py.typed +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/setup/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/setup/_switch.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/setup/core/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/setup/errors/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/lamindb/setup/types/__init__.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/noxfile.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/conftest.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/_dataset_fixtures.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/conftest.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/notebooks/basic-r-notebook.Rmd.cleaned.html +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/notebooks/basic-r-notebook.Rmd.html +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/notebooks/duplicate/with-title-initialized-consecutive-finish.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/notebooks/no-title.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/notebooks/with-title-initialized-consecutive-finish-not-last-cell.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/notebooks/with-title-initialized-consecutive-finish.ipynb +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/scripts/duplicate1/script-to-test-versioning.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/scripts/duplicate2/script-to-test-versioning.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/scripts/duplicate3/script-to-test-versioning.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/scripts/duplicate4/script-to-test-versioning.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/scripts/duplicate5/script-to-test-versioning.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/scripts/script-to-test-filename-change.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/scripts/script-to-test-versioning.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_artifact_folders.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_can_curate.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_collection.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_data.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_db.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_delete.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_describe_and_df_calls.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_dtype.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_feature.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_feature_label_manager.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_from_values.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_has_parents.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_integrity.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_load.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_manager.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_models.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_notebooks.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_run.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_save.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_search.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_settings.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_sqlrecord.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_storage.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_track.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_tracked.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_transform.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_ulabel.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_versioning.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_view.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/core/test_visibility.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/curators/conftest.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/curators/test_cat_managers.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/curators/test_curate_from_croissant.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/curators/test_curators_general.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/curators/test_curators_multivalue.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/curators/test_cxg_curator.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/curators/test_dataframe_curators_accounting_example.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/curators/test_records.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/permissions/conftest.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/permissions/jwt_utils.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/permissions/scripts/check_lamin_dev.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/permissions/scripts/clean_lamin_dev.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/permissions/scripts/setup_access.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/permissions/scripts/setup_instance.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/storage/conftest.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/storage/test_artifact_zarr.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/storage/test_cache.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/storage/test_connect_reconnect.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/storage/test_storage_lifecycle.py +0 -0
- {lamindb-1.11.1 → lamindb-1.11.3}/tests/storage/test_transfer.py +0 -0
lamindb-1.11.3/PKG-INFO
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
Metadata-Version: 2.3
|
2
|
+
Name: lamindb
|
3
|
+
Version: 1.11.3
|
4
|
+
Summary: A data framework for biology.
|
5
|
+
Author-email: Lamin Labs <open-source@lamin.ai>
|
6
|
+
Requires-Python: >=3.10,<3.14
|
7
|
+
Description-Content-Type: text/markdown
|
8
|
+
Classifier: Programming Language :: Python :: 3.10
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
12
|
+
Requires-Dist: lamin_utils==0.15.0
|
13
|
+
Requires-Dist: lamin_cli==1.7.2
|
14
|
+
Requires-Dist: lamindb_setup[aws]==1.10.2
|
15
|
+
Requires-Dist: bionty>=1.7a1
|
16
|
+
Requires-Dist: wetlab>=1.5a1
|
17
|
+
Requires-Dist: nbproject==0.11.1
|
18
|
+
Requires-Dist: jupytext
|
19
|
+
Requires-Dist: nbconvert>=7.2.1
|
20
|
+
Requires-Dist: mistune!=3.1.0
|
21
|
+
Requires-Dist: pyyaml
|
22
|
+
Requires-Dist: pyarrow
|
23
|
+
Requires-Dist: pandera>=0.24.0
|
24
|
+
Requires-Dist: typing_extensions!=4.6.0
|
25
|
+
Requires-Dist: python-dateutil
|
26
|
+
Requires-Dist: pandas>=2.0.0
|
27
|
+
Requires-Dist: scipy<1.15.0
|
28
|
+
Requires-Dist: anndata>=0.8.0,<=0.12.1
|
29
|
+
Requires-Dist: fsspec
|
30
|
+
Requires-Dist: graphviz
|
31
|
+
Requires-Dist: psycopg2-binary
|
32
|
+
Requires-Dist: tomlkit ; extra == "dev"
|
33
|
+
Requires-Dist: line_profiler ; extra == "dev"
|
34
|
+
Requires-Dist: pre-commit ; extra == "dev"
|
35
|
+
Requires-Dist: nox ; extra == "dev"
|
36
|
+
Requires-Dist: laminci>=0.3 ; extra == "dev"
|
37
|
+
Requires-Dist: pytest>=6.0 ; extra == "dev"
|
38
|
+
Requires-Dist: coverage ; extra == "dev"
|
39
|
+
Requires-Dist: pytest-cov<7.0.0 ; extra == "dev"
|
40
|
+
Requires-Dist: mudata ; extra == "dev"
|
41
|
+
Requires-Dist: nbproject_test>=0.6.0 ; extra == "dev"
|
42
|
+
Requires-Dist: faker-biology ; extra == "dev"
|
43
|
+
Requires-Dist: pronto ; extra == "dev"
|
44
|
+
Requires-Dist: readfcs>=2.0.1 ; extra == "fcs"
|
45
|
+
Requires-Dist: lamindb_setup[gcp] ; extra == "gcp"
|
46
|
+
Requires-Dist: numcodecs<0.16.0 ; extra == "zarr"
|
47
|
+
Requires-Dist: zarr>=2.16.0,<3.0.0a0 ; extra == "zarr"
|
48
|
+
Project-URL: Home, https://github.com/laminlabs/lamindb
|
49
|
+
Provides-Extra: dev
|
50
|
+
Provides-Extra: fcs
|
51
|
+
Provides-Extra: gcp
|
52
|
+
Provides-Extra: zarr
|
53
|
+
|
54
|
+
[](https://github.com/laminlabs/lamindb)
|
55
|
+
[](https://codecov.io/gh/laminlabs/lamindb)
|
56
|
+
[](https://docs.lamin.ai)
|
57
|
+
[](https://docs.lamin.ai/summary.md)
|
58
|
+
[](https://pypi.org/project/lamindb)
|
59
|
+
[](https://pepy.tech/project/lamindb)
|
60
|
+
|
61
|
+
# LaminDB - A data lakehouse for biology
|
62
|
+
|
63
|
+
LaminDB is an open-source data lakehouse to enable learning at scale in biology.
|
64
|
+
It organizes datasets through validation & annotation and provides data lineage, queryability, and reproducibility on top of [FAIR](https://en.wikipedia.org/wiki/FAIR_data) data.
|
65
|
+
|
66
|
+
<details>
|
67
|
+
<summary>Why?</summary>
|
68
|
+
|
69
|
+
Reproducing analytical results or understanding how a dataset or model was created can be a pain.
|
70
|
+
Let alone training models on historical data, LIMS & ELN systems, orthogonal assays, or datasets generated by other teams.
|
71
|
+
Even maintaining a mere overview of a project's or team's datasets & analyses is harder than it sounds.
|
72
|
+
|
73
|
+
Biological datasets are typically managed with versioned storage systems, GUI-focused community or SaaS platforms, structureless data lakes, rigid data warehouses (SQL, monolithic arrays), and data lakehouses for tabular data.
|
74
|
+
|
75
|
+
LaminDB extends the lakehouse architecture to biological registries & datasets beyond tables (`DataFrame`, `AnnData`, `.zarr`, `.tiledbsoma`, ...) with enough structure to enable queries and enough freedom to keep the pace of R&D high.
|
76
|
+
Moreover, it provides context through data lineage -- tracing data and code, scientists and models -- and abstractions for biological domain knowledge and experimental metadata.
|
77
|
+
|
78
|
+
</details>
|
79
|
+
|
80
|
+
**Highlights.**
|
81
|
+
|
82
|
+
- **data lineage:** track inputs & outputs of notebooks, scripts, functions & pipelines with a single line of code
|
83
|
+
- **unified infrastructure:** access diverse storage locations (local, S3, GCP, ...), SQL databases (Postgres, SQLite) & ontologies
|
84
|
+
- **lakehouse capabilities**: manage, monitor & validate features, labels & dataset schemas; perform distributed queries and batch loading
|
85
|
+
- **biological data formats:** validate & annotate formats like `DataFrame`, `AnnData`, `MuData`, ... backed by `parquet`, `zarr`, HDF5, LanceDB, DuckDB, ...
|
86
|
+
- **biological entities**: organize experimental metadata & extensible ontologies in registries based on the Django ORM
|
87
|
+
- **reproducible & auditable:** auto-version & timestamp execution reports, source code & compute environments, attribute records to users
|
88
|
+
- **zero lock-in & scalable:** runs in your infrastructure; is _not_ a client for a rate-limited REST API
|
89
|
+
- **extendable:** create custom plug-ins for your own applications based on the Django ecosystem
|
90
|
+
- **integrations:** visualization tools like [vitessce](https://docs.lamin.ai/vitessce), workflow managers like [nextflow](https://docs.lamin.ai/nextflow) & [redun](https://docs.lamin.ai/redun), and [other tools](https://docs.lamin.ai/integrations)
|
91
|
+
- **production-ready:** used in BigPharma, BioTech, hospitals & top labs
|
92
|
+
|
93
|
+
LaminDB can be connected to LaminHub to serve as a [LIMS](https://en.wikipedia.org/wiki/Laboratory_information_management_system) for wetlab scientists, closing the drylab-wetlab feedback loop: [lamin.ai](https://lamin.ai)
|
94
|
+
|
95
|
+
## Docs
|
96
|
+
|
97
|
+
Copy [summary.md](https://docs.lamin.ai/summary.md) into an LLM chat and let AI explain or read the [docs](https://docs.lamin.ai).
|
98
|
+
|
99
|
+
## Setup
|
100
|
+
|
101
|
+
<!-- copied from quick-setup-lamindb.md -->
|
102
|
+
|
103
|
+
Install the `lamindb` Python package:
|
104
|
+
|
105
|
+
```shell
|
106
|
+
pip install lamindb
|
107
|
+
```
|
108
|
+
|
109
|
+
Create a LaminDB instance:
|
110
|
+
|
111
|
+
```shell
|
112
|
+
lamin init --storage ./quickstart-data # or s3://my-bucket, gs://my-bucket
|
113
|
+
```
|
114
|
+
|
115
|
+
Or if you have write access to an instance, connect to it:
|
116
|
+
|
117
|
+
```shell
|
118
|
+
lamin connect account/name
|
119
|
+
```
|
120
|
+
|
121
|
+
## Quickstart
|
122
|
+
|
123
|
+
<!-- copied from preface.md -->
|
124
|
+
|
125
|
+
Track a script or notebook run with source code, inputs, outputs, logs, and environment.
|
126
|
+
|
127
|
+
<!-- copied from py-quickstart.py -->
|
128
|
+
|
129
|
+
```python
|
130
|
+
import lamindb as ln
|
131
|
+
|
132
|
+
ln.track() # track a run
|
133
|
+
open("sample.fasta", "w").write(">seq1\nACGT\n")
|
134
|
+
ln.Artifact("sample.fasta", key="sample.fasta").save() # create an artifact
|
135
|
+
ln.finish() # finish the run
|
136
|
+
```
|
137
|
+
|
138
|
+
<!-- from here on, slight deviation from preface.md, where all this is treated in the walk through in more depth -->
|
139
|
+
|
140
|
+
This code snippet creates an artifact, which can store a dataset or model as a file or folder in various formats.
|
141
|
+
Running the snippet as a script (`python create-fasta.py`) produces the following data lineage.
|
142
|
+
|
143
|
+
```python
|
144
|
+
artifact = ln.Artifact.get(key="sample.fasta") # query artifact by key
|
145
|
+
artifact.view_lineage()
|
146
|
+
```
|
147
|
+
|
148
|
+
<img src="https://lamin-site-assets.s3.amazonaws.com/.lamindb/EkQATsQL5wqC95Wj0005.png" width="250">
|
149
|
+
|
150
|
+
You'll know how that artifact was created and what it's used for ([interactive visualization](https://lamin.ai/laminlabs/lamindata/artifact/8incOOgjn6F0K1TS)) in addition to capturing basic metadata:
|
151
|
+
|
152
|
+
```python
|
153
|
+
artifact.describe()
|
154
|
+
```
|
155
|
+
|
156
|
+
<img src="https://lamin-site-assets.s3.amazonaws.com/.lamindb/BOTCBgHDAvwglN3U0002.png" width="550">
|
157
|
+
|
158
|
+
You can organize datasets with validation & annotation of any kind of metadata to then access them via queries & search. Here is a more [comprehensive example](https://lamin.ai/laminlabs/lamindata/artifact/9K1dteZ6Qx0EXK8g).
|
159
|
+
|
160
|
+
<img src="https://lamin-site-assets.s3.amazonaws.com/.lamindb/6sofuDVvTANB0f480002.png" width="850">
|
161
|
+
|
162
|
+
To annotate an artifact with a label, use:
|
163
|
+
|
164
|
+
```python
|
165
|
+
my_experiment = ln.ULabel(name="My experiment").save() # create a label in the universal label ontology
|
166
|
+
artifact.ulabels.add(my_experiment) # annotate the artifact with the label
|
167
|
+
```
|
168
|
+
|
169
|
+
To query for a set of artifacts, use the `filter()` statement.
|
170
|
+
|
171
|
+
```python
|
172
|
+
ln.Artifact.filter(ulabels=my_experiment, suffix=".fasta").to_dataframe() # query by suffix and the ulabel we just created
|
173
|
+
ln.Artifact.filter(transform__key="create-fasta.py").to_dataframe() # query by the name of the script we just ran
|
174
|
+
```
|
175
|
+
|
176
|
+
If you have a structured dataset like a `DataFrame`, an `AnnData`, or another array, you can validate the content of the dataset (and parse annotations).
|
177
|
+
Here is an example for a dataframe: [docs.lamin.ai/introduction#validate-an-artifact](https://docs.lamin.ai/introduction#validate-an-artifact).
|
178
|
+
|
179
|
+
With a large body of validated datasets, you can then access data through distributed queries & batch streaming, see here: [docs.lamin.ai/arrays](https://docs.lamin.ai/arrays).
|
180
|
+
|
lamindb-1.11.3/README.md
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
[](https://github.com/laminlabs/lamindb)
|
2
|
+
[](https://codecov.io/gh/laminlabs/lamindb)
|
3
|
+
[](https://docs.lamin.ai)
|
4
|
+
[](https://docs.lamin.ai/summary.md)
|
5
|
+
[](https://pypi.org/project/lamindb)
|
6
|
+
[](https://pepy.tech/project/lamindb)
|
7
|
+
|
8
|
+
# LaminDB - A data lakehouse for biology
|
9
|
+
|
10
|
+
LaminDB is an open-source data lakehouse to enable learning at scale in biology.
|
11
|
+
It organizes datasets through validation & annotation and provides data lineage, queryability, and reproducibility on top of [FAIR](https://en.wikipedia.org/wiki/FAIR_data) data.
|
12
|
+
|
13
|
+
<details>
|
14
|
+
<summary>Why?</summary>
|
15
|
+
|
16
|
+
Reproducing analytical results or understanding how a dataset or model was created can be a pain.
|
17
|
+
Let alone training models on historical data, LIMS & ELN systems, orthogonal assays, or datasets generated by other teams.
|
18
|
+
Even maintaining a mere overview of a project's or team's datasets & analyses is harder than it sounds.
|
19
|
+
|
20
|
+
Biological datasets are typically managed with versioned storage systems, GUI-focused community or SaaS platforms, structureless data lakes, rigid data warehouses (SQL, monolithic arrays), and data lakehouses for tabular data.
|
21
|
+
|
22
|
+
LaminDB extends the lakehouse architecture to biological registries & datasets beyond tables (`DataFrame`, `AnnData`, `.zarr`, `.tiledbsoma`, ...) with enough structure to enable queries and enough freedom to keep the pace of R&D high.
|
23
|
+
Moreover, it provides context through data lineage -- tracing data and code, scientists and models -- and abstractions for biological domain knowledge and experimental metadata.
|
24
|
+
|
25
|
+
</details>
|
26
|
+
|
27
|
+
**Highlights.**
|
28
|
+
|
29
|
+
- **data lineage:** track inputs & outputs of notebooks, scripts, functions & pipelines with a single line of code
|
30
|
+
- **unified infrastructure:** access diverse storage locations (local, S3, GCP, ...), SQL databases (Postgres, SQLite) & ontologies
|
31
|
+
- **lakehouse capabilities**: manage, monitor & validate features, labels & dataset schemas; perform distributed queries and batch loading
|
32
|
+
- **biological data formats:** validate & annotate formats like `DataFrame`, `AnnData`, `MuData`, ... backed by `parquet`, `zarr`, HDF5, LanceDB, DuckDB, ...
|
33
|
+
- **biological entities**: organize experimental metadata & extensible ontologies in registries based on the Django ORM
|
34
|
+
- **reproducible & auditable:** auto-version & timestamp execution reports, source code & compute environments, attribute records to users
|
35
|
+
- **zero lock-in & scalable:** runs in your infrastructure; is _not_ a client for a rate-limited REST API
|
36
|
+
- **extendable:** create custom plug-ins for your own applications based on the Django ecosystem
|
37
|
+
- **integrations:** visualization tools like [vitessce](https://docs.lamin.ai/vitessce), workflow managers like [nextflow](https://docs.lamin.ai/nextflow) & [redun](https://docs.lamin.ai/redun), and [other tools](https://docs.lamin.ai/integrations)
|
38
|
+
- **production-ready:** used in BigPharma, BioTech, hospitals & top labs
|
39
|
+
|
40
|
+
LaminDB can be connected to LaminHub to serve as a [LIMS](https://en.wikipedia.org/wiki/Laboratory_information_management_system) for wetlab scientists, closing the drylab-wetlab feedback loop: [lamin.ai](https://lamin.ai)
|
41
|
+
|
42
|
+
## Docs
|
43
|
+
|
44
|
+
Copy [summary.md](https://docs.lamin.ai/summary.md) into an LLM chat and let AI explain or read the [docs](https://docs.lamin.ai).
|
45
|
+
|
46
|
+
## Setup
|
47
|
+
|
48
|
+
<!-- copied from quick-setup-lamindb.md -->
|
49
|
+
|
50
|
+
Install the `lamindb` Python package:
|
51
|
+
|
52
|
+
```shell
|
53
|
+
pip install lamindb
|
54
|
+
```
|
55
|
+
|
56
|
+
Create a LaminDB instance:
|
57
|
+
|
58
|
+
```shell
|
59
|
+
lamin init --storage ./quickstart-data # or s3://my-bucket, gs://my-bucket
|
60
|
+
```
|
61
|
+
|
62
|
+
Or if you have write access to an instance, connect to it:
|
63
|
+
|
64
|
+
```shell
|
65
|
+
lamin connect account/name
|
66
|
+
```
|
67
|
+
|
68
|
+
## Quickstart
|
69
|
+
|
70
|
+
<!-- copied from preface.md -->
|
71
|
+
|
72
|
+
Track a script or notebook run with source code, inputs, outputs, logs, and environment.
|
73
|
+
|
74
|
+
<!-- copied from py-quickstart.py -->
|
75
|
+
|
76
|
+
```python
|
77
|
+
import lamindb as ln
|
78
|
+
|
79
|
+
ln.track() # track a run
|
80
|
+
open("sample.fasta", "w").write(">seq1\nACGT\n")
|
81
|
+
ln.Artifact("sample.fasta", key="sample.fasta").save() # create an artifact
|
82
|
+
ln.finish() # finish the run
|
83
|
+
```
|
84
|
+
|
85
|
+
<!-- from here on, slight deviation from preface.md, where all this is treated in the walk through in more depth -->
|
86
|
+
|
87
|
+
This code snippet creates an artifact, which can store a dataset or model as a file or folder in various formats.
|
88
|
+
Running the snippet as a script (`python create-fasta.py`) produces the following data lineage.
|
89
|
+
|
90
|
+
```python
|
91
|
+
artifact = ln.Artifact.get(key="sample.fasta") # query artifact by key
|
92
|
+
artifact.view_lineage()
|
93
|
+
```
|
94
|
+
|
95
|
+
<img src="https://lamin-site-assets.s3.amazonaws.com/.lamindb/EkQATsQL5wqC95Wj0005.png" width="250">
|
96
|
+
|
97
|
+
You'll know how that artifact was created and what it's used for ([interactive visualization](https://lamin.ai/laminlabs/lamindata/artifact/8incOOgjn6F0K1TS)) in addition to capturing basic metadata:
|
98
|
+
|
99
|
+
```python
|
100
|
+
artifact.describe()
|
101
|
+
```
|
102
|
+
|
103
|
+
<img src="https://lamin-site-assets.s3.amazonaws.com/.lamindb/BOTCBgHDAvwglN3U0002.png" width="550">
|
104
|
+
|
105
|
+
You can organize datasets with validation & annotation of any kind of metadata to then access them via queries & search. Here is a more [comprehensive example](https://lamin.ai/laminlabs/lamindata/artifact/9K1dteZ6Qx0EXK8g).
|
106
|
+
|
107
|
+
<img src="https://lamin-site-assets.s3.amazonaws.com/.lamindb/6sofuDVvTANB0f480002.png" width="850">
|
108
|
+
|
109
|
+
To annotate an artifact with a label, use:
|
110
|
+
|
111
|
+
```python
|
112
|
+
my_experiment = ln.ULabel(name="My experiment").save() # create a label in the universal label ontology
|
113
|
+
artifact.ulabels.add(my_experiment) # annotate the artifact with the label
|
114
|
+
```
|
115
|
+
|
116
|
+
To query for a set of artifacts, use the `filter()` statement.
|
117
|
+
|
118
|
+
```python
|
119
|
+
ln.Artifact.filter(ulabels=my_experiment, suffix=".fasta").to_dataframe() # query by suffix and the ulabel we just created
|
120
|
+
ln.Artifact.filter(transform__key="create-fasta.py").to_dataframe() # query by the name of the script we just ran
|
121
|
+
```
|
122
|
+
|
123
|
+
If you have a structured dataset like a `DataFrame`, an `AnnData`, or another array, you can validate the content of the dataset (and parse annotations).
|
124
|
+
Here is an example for a dataframe: [docs.lamin.ai/introduction#validate-an-artifact](https://docs.lamin.ai/introduction#validate-an-artifact).
|
125
|
+
|
126
|
+
With a large body of validated datasets, you can then access data through distributed queries & batch streaming, see here: [docs.lamin.ai/arrays](https://docs.lamin.ai/arrays).
|
@@ -9,7 +9,6 @@
|
|
9
9
|
]
|
10
10
|
},
|
11
11
|
{
|
12
|
-
"attachments": {},
|
13
12
|
"cell_type": "markdown",
|
14
13
|
"id": "1",
|
15
14
|
"metadata": {},
|
@@ -175,7 +174,6 @@
|
|
175
174
|
]
|
176
175
|
},
|
177
176
|
{
|
178
|
-
"attachments": {},
|
179
177
|
"cell_type": "markdown",
|
180
178
|
"id": "15",
|
181
179
|
"metadata": {},
|
@@ -184,7 +182,6 @@
|
|
184
182
|
]
|
185
183
|
},
|
186
184
|
{
|
187
|
-
"attachments": {},
|
188
185
|
"cell_type": "markdown",
|
189
186
|
"id": "16",
|
190
187
|
"metadata": {},
|
@@ -223,7 +220,6 @@
|
|
223
220
|
]
|
224
221
|
},
|
225
222
|
{
|
226
|
-
"attachments": {},
|
227
223
|
"cell_type": "markdown",
|
228
224
|
"id": "19",
|
229
225
|
"metadata": {},
|
@@ -259,7 +255,7 @@
|
|
259
255
|
"id": "22",
|
260
256
|
"metadata": {},
|
261
257
|
"source": [
|
262
|
-
"{
|
258
|
+
"{meth}`~lamindb.models.SQLRecord.get` errors if more than one matching records are found."
|
263
259
|
]
|
264
260
|
},
|
265
261
|
{
|
@@ -283,7 +279,6 @@
|
|
283
279
|
]
|
284
280
|
},
|
285
281
|
{
|
286
|
-
"attachments": {},
|
287
282
|
"cell_type": "markdown",
|
288
283
|
"id": "24",
|
289
284
|
"metadata": {},
|
@@ -292,7 +287,6 @@
|
|
292
287
|
]
|
293
288
|
},
|
294
289
|
{
|
295
|
-
"attachments": {},
|
296
290
|
"cell_type": "markdown",
|
297
291
|
"id": "25",
|
298
292
|
"metadata": {},
|
@@ -315,14 +309,13 @@
|
|
315
309
|
]
|
316
310
|
},
|
317
311
|
{
|
318
|
-
"attachments": {},
|
319
312
|
"cell_type": "markdown",
|
320
313
|
"id": "27",
|
321
314
|
"metadata": {},
|
322
315
|
"source": [
|
323
316
|
"To access the results encoded in a filter statement, execute its return value with one of:\n",
|
324
317
|
"\n",
|
325
|
-
"- {meth}`~lamindb.models.QuerySet.
|
318
|
+
"- {meth}`~lamindb.models.QuerySet.to_dataframe`: A pandas `DataFrame` with each record in a row.\n",
|
326
319
|
"- {meth}`~lamindb.models.QuerySet.all`: A {class}`~lamindb.models.QuerySet`.\n",
|
327
320
|
"- {meth}`~lamindb.models.QuerySet.one`: Exactly one record. Will raise an error if there is none. Is equivalent to the `.get()` method shown above.\n",
|
328
321
|
"- {meth}`~lamindb.models.QuerySet.one_or_none`: Either one record or `None` if there is no query result."
|
@@ -453,7 +446,6 @@
|
|
453
446
|
]
|
454
447
|
},
|
455
448
|
{
|
456
|
-
"attachments": {},
|
457
449
|
"cell_type": "markdown",
|
458
450
|
"id": "40",
|
459
451
|
"metadata": {},
|
@@ -492,7 +484,6 @@
|
|
492
484
|
]
|
493
485
|
},
|
494
486
|
{
|
495
|
-
"attachments": {},
|
496
487
|
"cell_type": "markdown",
|
497
488
|
"id": "44",
|
498
489
|
"metadata": {},
|
@@ -501,7 +492,6 @@
|
|
501
492
|
]
|
502
493
|
},
|
503
494
|
{
|
504
|
-
"attachments": {},
|
505
495
|
"cell_type": "markdown",
|
506
496
|
"id": "45",
|
507
497
|
"metadata": {},
|
@@ -526,7 +516,6 @@
|
|
526
516
|
]
|
527
517
|
},
|
528
518
|
{
|
529
|
-
"attachments": {},
|
530
519
|
"cell_type": "markdown",
|
531
520
|
"id": "47",
|
532
521
|
"metadata": {},
|
@@ -585,7 +574,6 @@
|
|
585
574
|
]
|
586
575
|
},
|
587
576
|
{
|
588
|
-
"attachments": {},
|
589
577
|
"cell_type": "markdown",
|
590
578
|
"id": "52",
|
591
579
|
"metadata": {},
|
@@ -596,7 +584,6 @@
|
|
596
584
|
]
|
597
585
|
},
|
598
586
|
{
|
599
|
-
"attachments": {},
|
600
587
|
"cell_type": "markdown",
|
601
588
|
"id": "53",
|
602
589
|
"metadata": {},
|
@@ -619,7 +606,6 @@
|
|
619
606
|
]
|
620
607
|
},
|
621
608
|
{
|
622
|
-
"attachments": {},
|
623
609
|
"cell_type": "markdown",
|
624
610
|
"id": "55",
|
625
611
|
"metadata": {},
|
@@ -628,7 +614,6 @@
|
|
628
614
|
]
|
629
615
|
},
|
630
616
|
{
|
631
|
-
"attachments": {},
|
632
617
|
"cell_type": "markdown",
|
633
618
|
"id": "56",
|
634
619
|
"metadata": {},
|
@@ -651,7 +636,6 @@
|
|
651
636
|
]
|
652
637
|
},
|
653
638
|
{
|
654
|
-
"attachments": {},
|
655
639
|
"cell_type": "markdown",
|
656
640
|
"id": "58",
|
657
641
|
"metadata": {},
|
@@ -674,7 +658,6 @@
|
|
674
658
|
]
|
675
659
|
},
|
676
660
|
{
|
677
|
-
"attachments": {},
|
678
661
|
"cell_type": "markdown",
|
679
662
|
"id": "60",
|
680
663
|
"metadata": {},
|
@@ -737,7 +720,6 @@
|
|
737
720
|
]
|
738
721
|
},
|
739
722
|
{
|
740
|
-
"attachments": {},
|
741
723
|
"cell_type": "markdown",
|
742
724
|
"id": "65",
|
743
725
|
"metadata": {},
|
@@ -782,7 +764,6 @@
|
|
782
764
|
]
|
783
765
|
},
|
784
766
|
{
|
785
|
-
"attachments": {},
|
786
767
|
"cell_type": "markdown",
|
787
768
|
"id": "69",
|
788
769
|
"metadata": {},
|
@@ -851,7 +832,7 @@
|
|
851
832
|
],
|
852
833
|
"metadata": {
|
853
834
|
"kernelspec": {
|
854
|
-
"display_name": "
|
835
|
+
"display_name": "Python 3 (ipykernel)",
|
855
836
|
"language": "python",
|
856
837
|
"name": "python3"
|
857
838
|
},
|
@@ -865,7 +846,7 @@
|
|
865
846
|
"name": "python",
|
866
847
|
"nbconvert_exporter": "python",
|
867
848
|
"pygments_lexer": "ipython3",
|
868
|
-
"version": "3.
|
849
|
+
"version": "3.10.16"
|
869
850
|
}
|
870
851
|
},
|
871
852
|
"nbformat": 4,
|
@@ -155,19 +155,29 @@ def process_expressions(queryset: QuerySet, expressions: dict) -> dict:
|
|
155
155
|
expressions,
|
156
156
|
)
|
157
157
|
if issubclass(queryset.model, SQLRecord):
|
158
|
-
# branch_id is set to 1 unless expressions contains id or
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
158
|
+
# branch_id is set to 1 unless expressions contains id, uid or hash
|
159
|
+
id_uid_hash = {"id", "uid", "hash", "id__in", "uid__in", "hash__in"}
|
160
|
+
if not any(expression in id_uid_hash for expression in expressions):
|
161
|
+
expressions_have_branch = False
|
162
|
+
branch_branch_id = {"branch", "branch_id"}
|
163
|
+
branch_branch_id__ = ("branch__", "branch_id__")
|
164
|
+
for expression in expressions:
|
165
|
+
if expression in branch_branch_id or expression.startswith(
|
166
|
+
branch_branch_id__
|
167
|
+
):
|
168
|
+
expressions_have_branch = True
|
169
|
+
break
|
170
|
+
if not expressions_have_branch:
|
171
|
+
# TODO: should be set to the current default branch
|
172
|
+
expressions["branch_id"] = 1
|
173
|
+
else:
|
174
|
+
# if branch_id is None, do not apply a filter
|
175
|
+
# otherwise, it would mean filtering for NULL values, which doesn't make
|
176
|
+
# sense for a non-NULLABLE column
|
177
|
+
if "branch_id" in expressions and expressions["branch_id"] is None:
|
178
|
+
expressions.pop("branch_id")
|
179
|
+
if "branch" in expressions and expressions["branch"] is None:
|
180
|
+
expressions.pop("branch")
|
171
181
|
if queryset._db is not None:
|
172
182
|
# only check for database mismatch if there is a defined database on the
|
173
183
|
# queryset
|
@@ -226,8 +236,6 @@ def get(
|
|
226
236
|
else:
|
227
237
|
assert idlike is None # noqa: S101
|
228
238
|
expressions = process_expressions(qs, expressions)
|
229
|
-
# don't want branch_id here in .get(), only in .filter()
|
230
|
-
expressions.pop("branch_id", None)
|
231
239
|
# inject is_latest for consistency with idlike
|
232
240
|
is_latest_was_not_in_expressions = "is_latest" not in expressions
|
233
241
|
if issubclass(registry, IsVersioned) and is_latest_was_not_in_expressions:
|
@@ -241,7 +249,7 @@ def get(
|
|
241
249
|
result = qs.filter(**expressions).order_by("-created_at").first()
|
242
250
|
if result is not None:
|
243
251
|
return result
|
244
|
-
raise
|
252
|
+
raise e
|
245
253
|
|
246
254
|
|
247
255
|
class SQLRecordList(UserList, Generic[T]):
|
@@ -234,7 +234,15 @@ def check_and_attempt_upload(
|
|
234
234
|
try:
|
235
235
|
copy_or_move_to_cache(artifact, storage_path, cache_path)
|
236
236
|
except Exception as e:
|
237
|
-
|
237
|
+
if not str(e).startswith(
|
238
|
+
"[WinError 32] The process cannot access the file "
|
239
|
+
"because it is being used by another process"
|
240
|
+
):
|
241
|
+
# ignore WinError 32 error, this just means that the file is still open on save
|
242
|
+
# it is saved at this point, so not a big deal if copy or move to cache fails
|
243
|
+
# this mostly happens for run logs
|
244
|
+
# just ignore without a warning
|
245
|
+
logger.warning(f"A problem with cache on saving: {e}")
|
238
246
|
# after successful upload, we should remove the attribute so that another call
|
239
247
|
# call to save won't upload again, the user should call replace() then
|
240
248
|
del artifact._local_filepath
|
@@ -269,7 +277,9 @@ def copy_or_move_to_cache(
|
|
269
277
|
# non-local storage_path further
|
270
278
|
if local_path != cache_path:
|
271
279
|
if cache_path.exists():
|
272
|
-
logger.
|
280
|
+
logger.important_hint(
|
281
|
+
f"replacing the existing cache path {cache_path.as_posix()}"
|
282
|
+
)
|
273
283
|
if cache_path.is_dir():
|
274
284
|
shutil.rmtree(cache_path)
|
275
285
|
else:
|
@@ -258,6 +258,12 @@ class Schema(SQLRecord, CanCurate, TracksRun):
|
|
258
258
|
|
259
259
|
Composite schemas can have multiple slots, e.g., for an `AnnData`, one schema for slot `obs` and another one for `var`.
|
260
260
|
|
261
|
+
To create a schema, one of the following must be passed:
|
262
|
+
- `features`: A list of :class:`~lamindb.Feature` records, e.g., `[Feature(...), Feature(...)]`.
|
263
|
+
- `itype`: A registry field, e.g., `Feature` or `bionty.Gene.ensembl_gene_id`, to constrain feature identifiers to be valid identifiers of the registry.
|
264
|
+
- `slots`: A dictionary mapping slot names to :class:`~lamindb.Schema` objects, e.g., `{"obs": Schema(...), "var": Schema(...), "obsm": Schema(...)}`.
|
265
|
+
- `is_type=True`: To create a schema type, e.g., `ln.Schema(name="ProteinPanel", is_type=True)`.
|
266
|
+
|
261
267
|
Args:
|
262
268
|
features: `list[SQLRecord] | list[tuple[Feature, dict]] | None = None` Feature
|
263
269
|
records, e.g., `[Feature(...), Feature(...)]` or Features with their config, e.g., `[Feature(...).with_config(optional=True)]`.
|
@@ -565,6 +571,10 @@ class Schema(SQLRecord, CanCurate, TracksRun):
|
|
565
571
|
coerce_dtype=coerce_dtype,
|
566
572
|
n_features=n_features,
|
567
573
|
)
|
574
|
+
if not features and not slots and not is_type and not itype:
|
575
|
+
raise InvalidArgument(
|
576
|
+
"Please pass features or slots or itype or set is_type=True"
|
577
|
+
)
|
568
578
|
if not is_type:
|
569
579
|
schema = (
|
570
580
|
Schema.objects.using(using)
|
@@ -1211,12 +1221,14 @@ def get_type_str(dtype: str | None) -> str | None:
|
|
1211
1221
|
return type_str
|
1212
1222
|
|
1213
1223
|
|
1214
|
-
def _get_related_name(self: Schema) -> str:
|
1224
|
+
def _get_related_name(self: Schema) -> str | None:
|
1215
1225
|
related_models = dict_related_model_to_related_name(self, instance=self._state.db)
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1226
|
+
if self.itype:
|
1227
|
+
related_name = related_models.get(
|
1228
|
+
parse_cat_dtype(self.itype, is_itype=True)["registry_str"]
|
1229
|
+
)
|
1230
|
+
return related_name
|
1231
|
+
return None
|
1220
1232
|
|
1221
1233
|
|
1222
1234
|
class SchemaFeature(BaseSQLRecord, IsLink):
|
@@ -350,7 +350,7 @@ def delete_record(record: BaseSQLRecord, is_soft: bool = True):
|
|
350
350
|
with transaction.atomic():
|
351
351
|
new_latest.save()
|
352
352
|
delete()
|
353
|
-
logger.
|
353
|
+
logger.important_hint(f"new latest version is: {new_latest}")
|
354
354
|
return None
|
355
355
|
# deal with all other cases of the nested if condition now
|
356
356
|
delete()
|
@@ -17,8 +17,8 @@ classifiers = [
|
|
17
17
|
dependencies = [
|
18
18
|
# Lamin PINNED packages
|
19
19
|
"lamin_utils==0.15.0",
|
20
|
-
"lamin_cli==1.7.
|
21
|
-
"lamindb_setup[aws]==1.10.
|
20
|
+
"lamin_cli==1.7.2",
|
21
|
+
"lamindb_setup[aws]==1.10.2",
|
22
22
|
# Lamin OPTIONAL packages, included to avoid users forgetting about passing extras,
|
23
23
|
# which has happened very often these past years
|
24
24
|
# these are small packages with few dependencies
|