datachain 0.6.11__tar.gz → 0.7.1__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.
Potentially problematic release.
This version of datachain might be problematic. Click here for more details.
- {datachain-0.6.11 → datachain-0.7.1}/.github/workflows/tests.yml +1 -1
- {datachain-0.6.11 → datachain-0.7.1}/.pre-commit-config.yaml +1 -1
- {datachain-0.6.11/src/datachain.egg-info → datachain-0.7.1}/PKG-INFO +2 -1
- {datachain-0.6.11 → datachain-0.7.1}/examples/computer_vision/openimage-detect.py +9 -15
- datachain-0.7.1/examples/computer_vision/ultralytics-bbox.py +22 -0
- datachain-0.7.1/examples/computer_vision/ultralytics-pose.py +22 -0
- datachain-0.7.1/examples/computer_vision/ultralytics-segment.py +22 -0
- {datachain-0.6.11 → datachain-0.7.1}/pyproject.toml +2 -1
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/__init__.py +1 -2
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/asyn.py +36 -4
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/data_storage/warehouse.py +4 -1
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/dc.py +6 -1
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/file.py +5 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/settings.py +11 -1
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/udf.py +45 -18
- datachain-0.7.1/src/datachain/model/__init__.py +6 -0
- datachain-0.7.1/src/datachain/model/bbox.py +102 -0
- datachain-0.7.1/src/datachain/model/pose.py +88 -0
- datachain-0.7.1/src/datachain/model/segment.py +47 -0
- datachain-0.7.1/src/datachain/model/ultralytics/__init__.py +27 -0
- datachain-0.7.1/src/datachain/model/ultralytics/bbox.py +147 -0
- datachain-0.7.1/src/datachain/model/ultralytics/pose.py +113 -0
- datachain-0.7.1/src/datachain/model/ultralytics/segment.py +91 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/node.py +1 -1
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/query/dataset.py +25 -27
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/toolkit/split.py +6 -2
- {datachain-0.6.11 → datachain-0.7.1/src/datachain.egg-info}/PKG-INFO +2 -1
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain.egg-info/SOURCES.txt +11 -4
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain.egg-info/requires.txt +1 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/conftest.py +20 -20
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_datachain.py +5 -2
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_pull.py +1 -1
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_toolkit.py +3 -3
- {datachain-0.6.11 → datachain-0.7.1}/tests/scripts/name_len_slow.py +1 -1
- datachain-0.7.1/tests/unit/lib/test_models.py +142 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_asyn.py +32 -0
- datachain-0.6.11/src/datachain/lib/models/__init__.py +0 -5
- datachain-0.6.11/src/datachain/lib/models/bbox.py +0 -45
- datachain-0.6.11/src/datachain/lib/models/pose.py +0 -37
- datachain-0.6.11/src/datachain/lib/models/yolo.py +0 -39
- datachain-0.6.11/tests/unit/lib/test_models.py +0 -50
- {datachain-0.6.11 → datachain-0.7.1}/.cruft.json +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.gitattributes +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.github/ISSUE_TEMPLATE/empty_issue.md +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.github/codecov.yaml +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.github/dependabot.yml +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.github/workflows/benchmarks.yml +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.github/workflows/release.yml +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.github/workflows/tests-studio.yml +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.github/workflows/update-template.yaml +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/.gitignore +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/CODE_OF_CONDUCT.rst +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/CONTRIBUTING.rst +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/LICENSE +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/README.rst +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/assets/captioned_cartoons.png +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/assets/datachain-white.svg +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/assets/datachain.svg +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/index.md +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/overrides/main.html +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/references/datachain.md +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/references/datatype.md +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/references/file.md +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/references/index.md +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/references/sql.md +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/references/torch.md +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/docs/references/udf.md +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/computer_vision/iptc_exif_xmp_lib.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/computer_vision/llava2_image_desc_lib.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/get_started/common_sql_functions.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/get_started/json-csv-reader.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/get_started/torch-loader.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/get_started/udfs/parallel.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/get_started/udfs/simple.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/get_started/udfs/stateful.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/llm_and_nlp/claude-query.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/llm_and_nlp/hf-dataset-llm-eval.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/llm_and_nlp/unstructured-embeddings-gen.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/llm_and_nlp/unstructured-summary-map.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/multimodal/clip_inference.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/multimodal/hf_pipeline.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/multimodal/openai_image_desc_lib.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/multimodal/wds.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/examples/multimodal/wds_filtered.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/mkdocs.yml +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/noxfile.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/setup.cfg +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/__main__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/cache.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/catalog/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/catalog/catalog.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/catalog/datasource.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/catalog/loader.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/cli.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/cli_utils.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/client/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/client/azure.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/client/fileslice.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/client/fsspec.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/client/gcs.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/client/hf.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/client/local.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/client/s3.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/config.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/data_storage/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/data_storage/db_engine.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/data_storage/id_generator.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/data_storage/job.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/data_storage/metastore.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/data_storage/schema.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/data_storage/serializer.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/data_storage/sqlite.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/dataset.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/error.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/job.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/arrow.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/clip.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/convert/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/convert/flatten.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/convert/python_to_sql.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/convert/sql_to_python.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/convert/unflatten.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/convert/values_to_tuples.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/data_model.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/dataset_info.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/func/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/func/aggregate.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/func/func.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/hf.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/image.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/listing.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/listing_info.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/meta_formats.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/model_store.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/pytorch.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/signal_schema.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/tar.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/text.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/udf_signature.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/utils.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/vfile.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/webdataset.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/lib/webdataset_laion.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/listing.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/nodes_fetcher.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/nodes_thread_pool.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/progress.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/py.typed +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/query/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/query/batch.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/query/dispatch.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/query/metrics.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/query/params.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/query/queue.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/query/schema.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/query/session.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/remote/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/remote/studio.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/default/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/default/base.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/functions/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/functions/aggregate.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/functions/array.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/functions/conditional.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/functions/path.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/functions/random.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/functions/string.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/selectable.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/sqlite/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/sqlite/base.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/sqlite/types.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/sqlite/vector.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/types.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/sql/utils.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/studio.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/telemetry.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/toolkit/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/torch/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain/utils.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain.egg-info/dependency_links.txt +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain.egg-info/entry_points.txt +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/src/datachain.egg-info/top_level.txt +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/benchmarks/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/benchmarks/conftest.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/benchmarks/datasets/.dvc/.gitignore +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/benchmarks/datasets/.dvc/config +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/benchmarks/datasets/.gitignore +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/benchmarks/datasets/laion-tiny.npz.dvc +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/benchmarks/test_datachain.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/benchmarks/test_ls.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/benchmarks/test_version.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/data.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/examples/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/examples/test_examples.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/examples/test_wds_e2e.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/examples/wds_data.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_catalog.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_client.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_dataset_query.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_datasets.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_feature_pickling.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_listing.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_ls.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_meta_formats.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_metrics.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_pytorch.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/func/test_query.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/scripts/feature_class.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/scripts/feature_class_exception.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/scripts/feature_class_parallel.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/scripts/feature_class_parallel_data_model.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/test_atomicity.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/test_cli_e2e.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/test_cli_studio.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/test_query_e2e.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/test_telemetry.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/conftest.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_arrow.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_clip.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_datachain.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_datachain_bootstrap.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_datachain_merge.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_feature.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_feature_utils.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_file.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_hf.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_image.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_listing_info.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_schema.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_signal_schema.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_sql_to_python.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_text.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_udf_signature.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_utils.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/lib/test_webdataset.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/sql/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/sql/sqlite/__init__.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/sql/sqlite/test_types.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/sql/sqlite/test_utils.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/sql/test_array.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/sql/test_conditional.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/sql/test_path.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/sql/test_random.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/sql/test_selectable.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/sql/test_string.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_cache.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_catalog.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_catalog_loader.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_cli_parsing.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_client.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_client_s3.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_config.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_data_storage.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_database_engine.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_dataset.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_dispatch.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_fileslice.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_id_generator.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_listing.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_metastore.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_module_exports.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_query.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_query_metrics.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_query_params.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_serializer.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_session.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_utils.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/unit/test_warehouse.py +0 -0
- {datachain-0.6.11 → datachain-0.7.1}/tests/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: datachain
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.1
|
|
4
4
|
Summary: Wrangle unstructured AI data at scale
|
|
5
5
|
Author-email: Dmitry Petrov <support@dvc.org>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -98,6 +98,7 @@ Requires-Dist: unstructured[embed-huggingface,pdf]<0.16.0; extra == "examples"
|
|
|
98
98
|
Requires-Dist: pdfplumber==0.11.4; extra == "examples"
|
|
99
99
|
Requires-Dist: huggingface_hub[hf_transfer]; extra == "examples"
|
|
100
100
|
Requires-Dist: onnx==1.16.1; extra == "examples"
|
|
101
|
+
Requires-Dist: ultralytics==8.3.29; extra == "examples"
|
|
101
102
|
|
|
102
103
|
================
|
|
103
104
|
|logo| DataChain
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
import json
|
|
2
2
|
|
|
3
3
|
from PIL import Image
|
|
4
|
-
from pydantic import BaseModel
|
|
5
4
|
|
|
6
|
-
from datachain import C, DataChain, File
|
|
5
|
+
from datachain import C, DataChain, File, model
|
|
7
6
|
from datachain.sql.functions import path
|
|
8
7
|
|
|
9
8
|
|
|
10
|
-
class BBox(BaseModel):
|
|
11
|
-
x_min: int
|
|
12
|
-
x_max: int
|
|
13
|
-
y_min: int
|
|
14
|
-
y_max: int
|
|
15
|
-
|
|
16
|
-
|
|
17
9
|
def openimage_detect(args):
|
|
18
10
|
if len(args) != 2:
|
|
19
11
|
raise ValueError("Group jpg-json mismatch")
|
|
@@ -30,11 +22,13 @@ def openimage_detect(args):
|
|
|
30
22
|
detections = json.load(stream_json).get("detections", [])
|
|
31
23
|
|
|
32
24
|
for i, detect in enumerate(detections):
|
|
33
|
-
bbox = BBox(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
25
|
+
bbox = model.BBox.from_list(
|
|
26
|
+
[
|
|
27
|
+
detect["XMin"] * img.width,
|
|
28
|
+
detect["XMax"] * img.width,
|
|
29
|
+
detect["YMin"] * img.height,
|
|
30
|
+
detect["YMax"] * img.height,
|
|
31
|
+
]
|
|
38
32
|
)
|
|
39
33
|
|
|
40
34
|
fstream = File(
|
|
@@ -56,7 +50,7 @@ source = "gs://datachain-demo/openimages-v6-test-jsonpairs/"
|
|
|
56
50
|
openimage_detect,
|
|
57
51
|
partition_by=path.file_stem(C("file.path")),
|
|
58
52
|
params=["file"],
|
|
59
|
-
output={"file": File, "bbox": BBox},
|
|
53
|
+
output={"file": File, "bbox": model.BBox},
|
|
60
54
|
)
|
|
61
55
|
.show()
|
|
62
56
|
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
3
|
+
from PIL import Image
|
|
4
|
+
from ultralytics import YOLO
|
|
5
|
+
|
|
6
|
+
from datachain import C, DataChain, File
|
|
7
|
+
from datachain.model.ultralytics import YoloBBoxes
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def process_bboxes(yolo: YOLO, file: File) -> YoloBBoxes:
|
|
11
|
+
results = yolo(Image.open(BytesIO(file.read())))
|
|
12
|
+
return YoloBBoxes.from_results(results)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
(
|
|
16
|
+
DataChain.from_storage("gs://datachain-demo/openimages-v6-test-jsonpairs/")
|
|
17
|
+
.filter(C("file.path").glob("*.jpg"))
|
|
18
|
+
.limit(20)
|
|
19
|
+
.setup(yolo=lambda: YOLO("yolo11n.pt"))
|
|
20
|
+
.map(boxes=process_bboxes)
|
|
21
|
+
.show()
|
|
22
|
+
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
3
|
+
from PIL import Image
|
|
4
|
+
from ultralytics import YOLO
|
|
5
|
+
|
|
6
|
+
from datachain import C, DataChain, File
|
|
7
|
+
from datachain.model.ultralytics import YoloPoses
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def process_poses(yolo: YOLO, file: File) -> YoloPoses:
|
|
11
|
+
results = yolo(Image.open(BytesIO(file.read())))
|
|
12
|
+
return YoloPoses.from_results(results)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
(
|
|
16
|
+
DataChain.from_storage("gs://datachain-demo/openimages-v6-test-jsonpairs/")
|
|
17
|
+
.filter(C("file.path").glob("*.jpg"))
|
|
18
|
+
.limit(20)
|
|
19
|
+
.setup(yolo=lambda: YOLO("yolo11n-pose.pt"))
|
|
20
|
+
.map(poses=process_poses)
|
|
21
|
+
.show()
|
|
22
|
+
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
3
|
+
from PIL import Image
|
|
4
|
+
from ultralytics import YOLO
|
|
5
|
+
|
|
6
|
+
from datachain import C, DataChain, File
|
|
7
|
+
from datachain.model.ultralytics import YoloSegments
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def process_segments(yolo: YOLO, file: File) -> YoloSegments:
|
|
11
|
+
results = yolo(Image.open(BytesIO(file.read())))
|
|
12
|
+
return YoloSegments.from_results(results)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
(
|
|
16
|
+
DataChain.from_storage("gs://datachain-demo/openimages-v6-test-jsonpairs/")
|
|
17
|
+
.filter(C("file.path").glob("*.jpg"))
|
|
18
|
+
.limit(20)
|
|
19
|
+
.setup(yolo=lambda: YOLO("yolo11n-seg.pt"))
|
|
20
|
+
.map(segments=process_segments)
|
|
21
|
+
.show()
|
|
22
|
+
)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from datachain.lib import func
|
|
1
|
+
from datachain.lib import func
|
|
2
2
|
from datachain.lib.data_model import DataModel, DataType, is_chain_type
|
|
3
3
|
from datachain.lib.dc import C, Column, DataChain, Sys
|
|
4
4
|
from datachain.lib.file import (
|
|
@@ -38,6 +38,5 @@ __all__ = [
|
|
|
38
38
|
"func",
|
|
39
39
|
"is_chain_type",
|
|
40
40
|
"metrics",
|
|
41
|
-
"models",
|
|
42
41
|
"param",
|
|
43
42
|
]
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
|
|
2
|
+
import threading
|
|
3
|
+
from collections.abc import (
|
|
4
|
+
AsyncIterable,
|
|
5
|
+
Awaitable,
|
|
6
|
+
Coroutine,
|
|
7
|
+
Generator,
|
|
8
|
+
Iterable,
|
|
9
|
+
Iterator,
|
|
10
|
+
)
|
|
3
11
|
from concurrent.futures import ThreadPoolExecutor
|
|
4
12
|
from heapq import heappop, heappush
|
|
5
13
|
from typing import Any, Callable, Generic, Optional, TypeVar
|
|
@@ -47,6 +55,7 @@ class AsyncMapper(Generic[InputT, ResultT]):
|
|
|
47
55
|
self.loop = get_loop() if loop is None else loop
|
|
48
56
|
self.pool = ThreadPoolExecutor(workers)
|
|
49
57
|
self._tasks: set[asyncio.Task] = set()
|
|
58
|
+
self._shutdown_producer = threading.Event()
|
|
50
59
|
|
|
51
60
|
def start_task(self, coro: Coroutine) -> asyncio.Task:
|
|
52
61
|
task = self.loop.create_task(coro)
|
|
@@ -54,9 +63,31 @@ class AsyncMapper(Generic[InputT, ResultT]):
|
|
|
54
63
|
task.add_done_callback(self._tasks.discard)
|
|
55
64
|
return task
|
|
56
65
|
|
|
57
|
-
|
|
66
|
+
def _produce(self) -> None:
|
|
58
67
|
for item in self.iterable:
|
|
59
|
-
|
|
68
|
+
if self._shutdown_producer.is_set():
|
|
69
|
+
return
|
|
70
|
+
fut = asyncio.run_coroutine_threadsafe(self.work_queue.put(item), self.loop)
|
|
71
|
+
fut.result() # wait until the item is in the queue
|
|
72
|
+
|
|
73
|
+
async def produce(self) -> None:
|
|
74
|
+
await self.to_thread(self._produce)
|
|
75
|
+
|
|
76
|
+
def shutdown_producer(self) -> None:
|
|
77
|
+
"""
|
|
78
|
+
Signal the producer to stop and drain any remaining items from the work_queue.
|
|
79
|
+
|
|
80
|
+
This method sets an internal event, `_shutdown_producer`, which tells the
|
|
81
|
+
producer that it should stop adding items to the queue. To ensure that the
|
|
82
|
+
producer notices this signal promptly, we also attempt to drain any items
|
|
83
|
+
currently in the queue, clearing it so that the event can be checked without
|
|
84
|
+
delay.
|
|
85
|
+
"""
|
|
86
|
+
self._shutdown_producer.set()
|
|
87
|
+
q = self.work_queue
|
|
88
|
+
while not q.empty():
|
|
89
|
+
q.get_nowait()
|
|
90
|
+
q.task_done()
|
|
60
91
|
|
|
61
92
|
async def worker(self) -> None:
|
|
62
93
|
while (item := await self.work_queue.get()) is not None:
|
|
@@ -132,7 +163,7 @@ class AsyncMapper(Generic[InputT, ResultT]):
|
|
|
132
163
|
self.result_queue.get_nowait()
|
|
133
164
|
await self.result_queue.put(None)
|
|
134
165
|
|
|
135
|
-
def iterate(self, timeout=None) ->
|
|
166
|
+
def iterate(self, timeout=None) -> Generator[ResultT, None, None]:
|
|
136
167
|
init = asyncio.run_coroutine_threadsafe(self.init(), self.loop)
|
|
137
168
|
init.result(timeout=1)
|
|
138
169
|
async_run = asyncio.run_coroutine_threadsafe(self.run(), self.loop)
|
|
@@ -145,6 +176,7 @@ class AsyncMapper(Generic[InputT, ResultT]):
|
|
|
145
176
|
if exc := async_run.exception():
|
|
146
177
|
raise exc
|
|
147
178
|
finally:
|
|
179
|
+
self.shutdown_producer()
|
|
148
180
|
if not async_run.done():
|
|
149
181
|
async_run.cancel()
|
|
150
182
|
|
|
@@ -232,7 +232,10 @@ class AbstractWarehouse(ABC, Serializable):
|
|
|
232
232
|
if limit < page_size:
|
|
233
233
|
paginated_query = paginated_query.limit(None).limit(limit)
|
|
234
234
|
|
|
235
|
-
|
|
235
|
+
# Ensure we're using a thread-local connection
|
|
236
|
+
with self.clone() as wh:
|
|
237
|
+
# Cursor results are not thread-safe, so we convert them to a list
|
|
238
|
+
results = list(wh.dataset_rows_select(paginated_query.offset(offset)))
|
|
236
239
|
|
|
237
240
|
processed = False
|
|
238
241
|
for row in results:
|
|
@@ -334,6 +334,7 @@ class DataChain:
|
|
|
334
334
|
parallel=None,
|
|
335
335
|
workers=None,
|
|
336
336
|
min_task_size=None,
|
|
337
|
+
prefetch: Optional[int] = None,
|
|
337
338
|
sys: Optional[bool] = None,
|
|
338
339
|
) -> "Self":
|
|
339
340
|
"""Change settings for chain.
|
|
@@ -360,7 +361,7 @@ class DataChain:
|
|
|
360
361
|
if sys is None:
|
|
361
362
|
sys = self._sys
|
|
362
363
|
settings = copy.copy(self._settings)
|
|
363
|
-
settings.add(Settings(cache, parallel, workers, min_task_size))
|
|
364
|
+
settings.add(Settings(cache, parallel, workers, min_task_size, prefetch))
|
|
364
365
|
return self._evolve(settings=settings, _sys=sys)
|
|
365
366
|
|
|
366
367
|
def reset_settings(self, settings: Optional[Settings] = None) -> "Self":
|
|
@@ -882,6 +883,8 @@ class DataChain:
|
|
|
882
883
|
```
|
|
883
884
|
"""
|
|
884
885
|
udf_obj = self._udf_to_obj(Mapper, func, params, output, signal_map)
|
|
886
|
+
if (prefetch := self._settings.prefetch) is not None:
|
|
887
|
+
udf_obj.prefetch = prefetch
|
|
885
888
|
|
|
886
889
|
return self._evolve(
|
|
887
890
|
query=self._query.add_signals(
|
|
@@ -919,6 +922,8 @@ class DataChain:
|
|
|
919
922
|
```
|
|
920
923
|
"""
|
|
921
924
|
udf_obj = self._udf_to_obj(Generator, func, params, output, signal_map)
|
|
925
|
+
if (prefetch := self._settings.prefetch) is not None:
|
|
926
|
+
udf_obj.prefetch = prefetch
|
|
922
927
|
return self._evolve(
|
|
923
928
|
query=self._query.generate(
|
|
924
929
|
udf_obj.to_udf_wrapper(),
|
|
@@ -268,6 +268,11 @@ class File(DataModel):
|
|
|
268
268
|
client = self._catalog.get_client(self.source)
|
|
269
269
|
client.download(self, callback=self._download_cb)
|
|
270
270
|
|
|
271
|
+
async def _prefetch(self) -> None:
|
|
272
|
+
if self._caching_enabled:
|
|
273
|
+
client = self._catalog.get_client(self.source)
|
|
274
|
+
await client._download(self, callback=self._download_cb)
|
|
275
|
+
|
|
271
276
|
def get_local_path(self) -> Optional[str]:
|
|
272
277
|
"""Return path to a file in a local cache.
|
|
273
278
|
|
|
@@ -7,11 +7,19 @@ class SettingsError(DataChainParamsError):
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class Settings:
|
|
10
|
-
def __init__(
|
|
10
|
+
def __init__(
|
|
11
|
+
self,
|
|
12
|
+
cache=None,
|
|
13
|
+
parallel=None,
|
|
14
|
+
workers=None,
|
|
15
|
+
min_task_size=None,
|
|
16
|
+
prefetch=None,
|
|
17
|
+
):
|
|
11
18
|
self._cache = cache
|
|
12
19
|
self.parallel = parallel
|
|
13
20
|
self._workers = workers
|
|
14
21
|
self.min_task_size = min_task_size
|
|
22
|
+
self.prefetch = prefetch
|
|
15
23
|
|
|
16
24
|
if not isinstance(cache, bool) and cache is not None:
|
|
17
25
|
raise SettingsError(
|
|
@@ -66,3 +74,5 @@ class Settings:
|
|
|
66
74
|
self.parallel = settings.parallel or self.parallel
|
|
67
75
|
self._workers = settings._workers or self._workers
|
|
68
76
|
self.min_task_size = settings.min_task_size or self.min_task_size
|
|
77
|
+
if settings.prefetch is not None:
|
|
78
|
+
self.prefetch = settings.prefetch
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import contextlib
|
|
1
2
|
import sys
|
|
2
3
|
import traceback
|
|
3
4
|
from collections.abc import Iterable, Iterator, Mapping, Sequence
|
|
@@ -7,6 +8,7 @@ import attrs
|
|
|
7
8
|
from fsspec.callbacks import DEFAULT_CALLBACK, Callback
|
|
8
9
|
from pydantic import BaseModel
|
|
9
10
|
|
|
11
|
+
from datachain.asyn import AsyncMapper
|
|
10
12
|
from datachain.dataset import RowDict
|
|
11
13
|
from datachain.lib.convert.flatten import flatten
|
|
12
14
|
from datachain.lib.data_model import DataValue
|
|
@@ -21,6 +23,8 @@ from datachain.query.batch import (
|
|
|
21
23
|
)
|
|
22
24
|
|
|
23
25
|
if TYPE_CHECKING:
|
|
26
|
+
from collections import abc
|
|
27
|
+
|
|
24
28
|
from typing_extensions import Self
|
|
25
29
|
|
|
26
30
|
from datachain.catalog import Catalog
|
|
@@ -276,9 +280,18 @@ class UDFBase(AbstractUDF):
|
|
|
276
280
|
return result_objs
|
|
277
281
|
|
|
278
282
|
|
|
283
|
+
async def _prefetch_input(row):
|
|
284
|
+
for obj in row:
|
|
285
|
+
if isinstance(obj, File):
|
|
286
|
+
await obj._prefetch()
|
|
287
|
+
return row
|
|
288
|
+
|
|
289
|
+
|
|
279
290
|
class Mapper(UDFBase):
|
|
280
291
|
"""Inherit from this class to pass to `DataChain.map()`."""
|
|
281
292
|
|
|
293
|
+
prefetch: int = 2
|
|
294
|
+
|
|
282
295
|
def run(
|
|
283
296
|
self,
|
|
284
297
|
udf_fields: "Sequence[str]",
|
|
@@ -290,16 +303,22 @@ class Mapper(UDFBase):
|
|
|
290
303
|
) -> Iterator[Iterable[UDFResult]]:
|
|
291
304
|
self.catalog = catalog
|
|
292
305
|
self.setup()
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
306
|
+
prepared_inputs: abc.Generator[Sequence[Any], None, None] = (
|
|
307
|
+
self._prepare_row_and_id(row, udf_fields, cache, download_cb)
|
|
308
|
+
for row in udf_inputs
|
|
309
|
+
)
|
|
310
|
+
if self.prefetch > 0:
|
|
311
|
+
prepared_inputs = AsyncMapper(
|
|
312
|
+
_prefetch_input, prepared_inputs, workers=self.prefetch
|
|
313
|
+
).iterate()
|
|
314
|
+
|
|
315
|
+
with contextlib.closing(prepared_inputs):
|
|
316
|
+
for id_, *udf_args in prepared_inputs:
|
|
317
|
+
result_objs = self.process_safe(udf_args)
|
|
318
|
+
udf_output = self._flatten_row(result_objs)
|
|
319
|
+
output = [{"sys__id": id_} | dict(zip(self.signal_names, udf_output))]
|
|
320
|
+
processed_cb.relative_update(1)
|
|
321
|
+
yield output
|
|
303
322
|
|
|
304
323
|
self.teardown()
|
|
305
324
|
|
|
@@ -349,6 +368,7 @@ class Generator(UDFBase):
|
|
|
349
368
|
"""Inherit from this class to pass to `DataChain.gen()`."""
|
|
350
369
|
|
|
351
370
|
is_output_batched = True
|
|
371
|
+
prefetch: int = 2
|
|
352
372
|
|
|
353
373
|
def run(
|
|
354
374
|
self,
|
|
@@ -361,14 +381,21 @@ class Generator(UDFBase):
|
|
|
361
381
|
) -> Iterator[Iterable[UDFResult]]:
|
|
362
382
|
self.catalog = catalog
|
|
363
383
|
self.setup()
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
384
|
+
prepared_inputs: abc.Generator[Sequence[Any], None, None] = (
|
|
385
|
+
self._prepare_row(row, udf_fields, cache, download_cb) for row in udf_inputs
|
|
386
|
+
)
|
|
387
|
+
if self.prefetch > 0:
|
|
388
|
+
prepared_inputs = AsyncMapper(
|
|
389
|
+
_prefetch_input, prepared_inputs, workers=self.prefetch
|
|
390
|
+
).iterate()
|
|
391
|
+
|
|
392
|
+
with contextlib.closing(prepared_inputs):
|
|
393
|
+
for row in prepared_inputs:
|
|
394
|
+
result_objs = self.process_safe(row)
|
|
395
|
+
udf_outputs = (self._flatten_row(row) for row in result_objs)
|
|
396
|
+
output = (dict(zip(self.signal_names, row)) for row in udf_outputs)
|
|
397
|
+
processed_cb.relative_update(1)
|
|
398
|
+
yield output
|
|
372
399
|
|
|
373
400
|
self.teardown()
|
|
374
401
|
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from pydantic import Field
|
|
2
|
+
|
|
3
|
+
from datachain.lib.data_model import DataModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class BBox(DataModel):
|
|
7
|
+
"""
|
|
8
|
+
A data model for representing bounding box.
|
|
9
|
+
|
|
10
|
+
Attributes:
|
|
11
|
+
title (str): The title of the bounding box.
|
|
12
|
+
coords (list[int]): The coordinates of the bounding box.
|
|
13
|
+
|
|
14
|
+
The bounding box is defined by two points:
|
|
15
|
+
- (x1, y1): The top-left corner of the box.
|
|
16
|
+
- (x2, y2): The bottom-right corner of the box.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
title: str = Field(default="")
|
|
20
|
+
coords: list[int] = Field(default=None)
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def from_list(coords: list[float], title: str = "") -> "BBox":
|
|
24
|
+
assert len(coords) == 4, "Bounding box must be a list of 4 coordinates."
|
|
25
|
+
assert all(
|
|
26
|
+
isinstance(value, (int, float)) for value in coords
|
|
27
|
+
), "Bounding box coordinates must be floats or integers."
|
|
28
|
+
return BBox(
|
|
29
|
+
title=title,
|
|
30
|
+
coords=[round(c) for c in coords],
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def from_dict(coords: dict[str, float], title: str = "") -> "BBox":
|
|
35
|
+
assert isinstance(coords, dict) and set(coords) == {
|
|
36
|
+
"x1",
|
|
37
|
+
"y1",
|
|
38
|
+
"x2",
|
|
39
|
+
"y2",
|
|
40
|
+
}, "Bounding box must be a dictionary with keys 'x1', 'y1', 'x2' and 'y2'."
|
|
41
|
+
return BBox.from_list(
|
|
42
|
+
[coords["x1"], coords["y1"], coords["x2"], coords["y2"]],
|
|
43
|
+
title=title,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class OBBox(DataModel):
|
|
48
|
+
"""
|
|
49
|
+
A data model for representing oriented bounding boxes.
|
|
50
|
+
|
|
51
|
+
Attributes:
|
|
52
|
+
title (str): The title of the oriented bounding box.
|
|
53
|
+
coords (list[int]): The coordinates of the oriented bounding box.
|
|
54
|
+
|
|
55
|
+
The oriented bounding box is defined by four points:
|
|
56
|
+
- (x1, y1): The first corner of the box.
|
|
57
|
+
- (x2, y2): The second corner of the box.
|
|
58
|
+
- (x3, y3): The third corner of the box.
|
|
59
|
+
- (x4, y4): The fourth corner of the box.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
title: str = Field(default="")
|
|
63
|
+
coords: list[int] = Field(default=None)
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def from_list(coords: list[float], title: str = "") -> "OBBox":
|
|
67
|
+
assert (
|
|
68
|
+
len(coords) == 8
|
|
69
|
+
), "Oriented bounding box must be a list of 8 coordinates."
|
|
70
|
+
assert all(
|
|
71
|
+
isinstance(value, (int, float)) for value in coords
|
|
72
|
+
), "Oriented bounding box coordinates must be floats or integers."
|
|
73
|
+
return OBBox(
|
|
74
|
+
title=title,
|
|
75
|
+
coords=[round(c) for c in coords],
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
@staticmethod
|
|
79
|
+
def from_dict(coords: dict[str, float], title: str = "") -> "OBBox":
|
|
80
|
+
assert isinstance(coords, dict) and set(coords) == {
|
|
81
|
+
"x1",
|
|
82
|
+
"y1",
|
|
83
|
+
"x2",
|
|
84
|
+
"y2",
|
|
85
|
+
"x3",
|
|
86
|
+
"y3",
|
|
87
|
+
"x4",
|
|
88
|
+
"y4",
|
|
89
|
+
}, "Oriented bounding box must be a dictionary with coordinates."
|
|
90
|
+
return OBBox.from_list(
|
|
91
|
+
[
|
|
92
|
+
coords["x1"],
|
|
93
|
+
coords["y1"],
|
|
94
|
+
coords["x2"],
|
|
95
|
+
coords["y2"],
|
|
96
|
+
coords["x3"],
|
|
97
|
+
coords["y3"],
|
|
98
|
+
coords["x4"],
|
|
99
|
+
coords["y4"],
|
|
100
|
+
],
|
|
101
|
+
title=title,
|
|
102
|
+
)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
from pydantic import Field
|
|
2
|
+
|
|
3
|
+
from datachain.lib.data_model import DataModel
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Pose(DataModel):
|
|
7
|
+
"""
|
|
8
|
+
A data model for representing pose keypoints.
|
|
9
|
+
|
|
10
|
+
Attributes:
|
|
11
|
+
x (list[int]): The x-coordinates of the keypoints.
|
|
12
|
+
y (list[int]): The y-coordinates of the keypoints.
|
|
13
|
+
|
|
14
|
+
The keypoints are represented as lists of x and y coordinates, where each index
|
|
15
|
+
corresponds to a specific body part.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
x: list[int] = Field(default=None)
|
|
19
|
+
y: list[int] = Field(default=None)
|
|
20
|
+
|
|
21
|
+
@staticmethod
|
|
22
|
+
def from_list(points: list[list[float]]) -> "Pose":
|
|
23
|
+
assert len(points) == 2, "Pose must be a list of 2 lists: x and y coordinates."
|
|
24
|
+
points_x, points_y = points
|
|
25
|
+
assert (
|
|
26
|
+
len(points_x) == len(points_y) == 17
|
|
27
|
+
), "Pose x and y coordinates must have the same length of 17."
|
|
28
|
+
assert all(
|
|
29
|
+
isinstance(value, (int, float)) for value in [*points_x, *points_y]
|
|
30
|
+
), "Pose coordinates must be floats or integers."
|
|
31
|
+
return Pose(
|
|
32
|
+
x=[round(coord) for coord in points_x],
|
|
33
|
+
y=[round(coord) for coord in points_y],
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def from_dict(points: dict[str, list[float]]) -> "Pose":
|
|
38
|
+
assert isinstance(points, dict) and set(points) == {
|
|
39
|
+
"x",
|
|
40
|
+
"y",
|
|
41
|
+
}, "Pose must be a dict with keys 'x' and 'y'."
|
|
42
|
+
return Pose.from_list([points["x"], points["y"]])
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class Pose3D(DataModel):
|
|
46
|
+
"""
|
|
47
|
+
A data model for representing 3D pose keypoints.
|
|
48
|
+
|
|
49
|
+
Attributes:
|
|
50
|
+
x (list[int]): The x-coordinates of the keypoints.
|
|
51
|
+
y (list[int]): The y-coordinates of the keypoints.
|
|
52
|
+
visible (list[float]): The visibility of the keypoints.
|
|
53
|
+
|
|
54
|
+
The keypoints are represented as lists of x, y, and visibility values,
|
|
55
|
+
where each index corresponds to a specific body part.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
x: list[int] = Field(default=None)
|
|
59
|
+
y: list[int] = Field(default=None)
|
|
60
|
+
visible: list[float] = Field(default=None)
|
|
61
|
+
|
|
62
|
+
@staticmethod
|
|
63
|
+
def from_list(points: list[list[float]]) -> "Pose3D":
|
|
64
|
+
assert (
|
|
65
|
+
len(points) == 3
|
|
66
|
+
), "Pose3D must be a list of 3 lists: x, y coordinates and visible."
|
|
67
|
+
points_x, points_y, points_v = points
|
|
68
|
+
assert (
|
|
69
|
+
len(points_x) == len(points_y) == len(points_v) == 17
|
|
70
|
+
), "Pose3D x, y coordinates and visible must have the same length of 17."
|
|
71
|
+
assert all(
|
|
72
|
+
isinstance(value, (int, float))
|
|
73
|
+
for value in [*points_x, *points_y, *points_v]
|
|
74
|
+
), "Pose3D coordinates must be floats or integers."
|
|
75
|
+
return Pose3D(
|
|
76
|
+
x=[round(coord) for coord in points_x],
|
|
77
|
+
y=[round(coord) for coord in points_y],
|
|
78
|
+
visible=points_v,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def from_dict(points: dict[str, list[float]]) -> "Pose3D":
|
|
83
|
+
assert isinstance(points, dict) and set(points) == {
|
|
84
|
+
"x",
|
|
85
|
+
"y",
|
|
86
|
+
"visible",
|
|
87
|
+
}, "Pose3D must be a dict with keys 'x', 'y' and 'visible'."
|
|
88
|
+
return Pose3D.from_list([points["x"], points["y"], points["visible"]])
|