odsbox 1.0.16rc492.post1__tar.gz → 1.0.16rc494.post1__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.
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/PKG-INFO +1 -1
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/requirements.txt +1 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/__init__.py +1 -1
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/con_i.py +10 -5
- odsbox-1.0.16rc494.post1/tests/test_con_i_chunked_download.py +214 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_con_i_file_access.py +5 -5
- odsbox-1.0.16rc492.post1/SECURITY.md +0 -41
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.devcontainer/Dockerfile +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.devcontainer/devcontainer.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/ISSUE_TEMPLATE/custom.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/dependabot.yml +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/template-sync.yml +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/CI.yml +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/publish.yml +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/schedule-update-actions.yml +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/semantic-pr-check.yml +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/sphinx.yml +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/template-sync.yml +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.gitignore +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.pre-commit-config.yaml +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.pypirc +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.vscode/launch.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.vscode/settings.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/CODE_OF_CONDUCT.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/CONTRIBUTING.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/LICENSE +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/README.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/SUPPORT.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/Makefile +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/_templates/layout.html +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/compare_measurement.ipynb +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/conf.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/index.rst +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/jaquel.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/jaquel_examples.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/jaquel_examples_notebook.ipynb +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/make.bat +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/odsbox.rst +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/overview.rst +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/repository_rules.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/simple_ods_example.ipynb +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/pyproject.toml +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/README.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/asam_time.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/bulk_reader.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/datamatrices_to_pandas.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/jaquel.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/jaquel_conversion_result.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/model_cache.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/model_suggestions.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/README.md +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/__init__.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_external_data_pb2.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_external_data_pb2.pyi +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_external_data_pb2_grpc.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_notification_pb2.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_notification_pb2.pyi +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_pb2.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_pb2.pyi +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_security_pb2.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_security_pb2.pyi +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/py.typed +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/security.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/submatrix_to_pandas.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/transaction.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/unit_catalog.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/unit_utils.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/conftest.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_asam_time.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_bulk_reader.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_bulk_reader_integration.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_con_i.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_con_i_type_error.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_con_i_with_resource_logout.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/application_model.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/examples_from_jaquel_doc.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Add some of the related physical dimension.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Add some of the related physical dimension.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Do access only few attributes.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Do access only few attributes.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Lets query for units with base entity name.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Lets query for units with base entity name.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Lets query for units with entity name.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Lets query for units with entity name.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Retrieve all attributes using asterisk.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Retrieve all attributes using asterisk.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Simplify attribute definition.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 01 Basic access 00 Simplify attribute definition.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 02 Order results by an attribute 00 Order results by name .json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 02 Order results by an attribute 00 Order results by name .json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 03 Limit the amounts of results 00 Retrieve only 5 result rows.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 03 Limit the amounts of results 00 Retrieve only 5 result rows.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 04 Query Instance by id 00 Query the unit with the id 3 full.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 04 Query Instance by id 00 Query the unit with the id 3 full.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 04 Query Instance by id 00 Query the unit with the id 3 simplified.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 04 Query Instance by id 00 Query the unit with the id 3 simplified.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 04 Query Instance by id 00 Query the unit with the id 3 .json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 04 Query Instance by id 00 Query the unit with the id 3 .json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 04 Query Instance by id 00 Query the units with the ids in 1 , 2 and 3 .json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 04 Query Instance by id 00 Query the units with the ids in 1 , 2 and 3 .json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 05 Query Instance by name 00 Query the unit with the name equal s case insensitive full.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 05 Query Instance by name 00 Query the unit with the name equal s case insensitive full.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 05 Query Instance by name 00 Query the unit with the name equal s case insensitive.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 05 Query Instance by name 00 Query the unit with the name equal s case insensitive.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 05 Query Instance by name 00 Query the unit with the name equal s .json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 05 Query Instance by name 00 Query the unit with the name equal s .json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 05 Query Instance by name 00 Query the unit with the name like k case insensitive.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 05 Query Instance by name 00 Query the unit with the name like k case insensitive.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 05 Query Instance by name 00 Query the unit with the name like k .json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 05 Query Instance by name 00 Query the unit with the name like k .json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 06 And conjunctions $and and $or 00 Search speed based Units with explicit $and conjunction.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 06 And conjunctions $and and $or 00 Search speed based Units with explicit $and conjunction.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 06 And conjunctions $and and $or 00 Search speed based Units.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 06 And conjunctions $and and $or 00 Search speed based Units.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 06 And conjunctions $and and $or 00 Search speed or time based Units.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 06 And conjunctions $and and $or 00 Search speed or time based Units.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 06 And conjunctions $and and $or 00 Search time based Units.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 06 And conjunctions $and and $or 00 Search time based Units.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Query using an enumeration int value.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Query using an enumeration int value.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Query using an enumeration text value.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Query using an enumeration text value.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Use $between operator 00 Get measurements that started in a time interval, ODS time.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Use $between operator 00 Get measurements that started in a time interval, ODS time.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Use $between operator 00 Get measurements that started in a time interval.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Use $between operator 00 Get measurements that started in a time interval.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Use operator $lt and gt .json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Use operator $lt and gt .json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Use operator $lte and gte .json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 07 Use operator $lte and gte .json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 08 Use aggregates $min , $max , $dcount , and $distinct 00 Get the distincted count of Unit description.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 08 Use aggregates $min , $max , $dcount , and $distinct 00 Get the distincted count of Unit description.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 08 Use aggregates $min , $max , $dcount , and $distinct 00 Get the distincted values of Unit description.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 08 Use aggregates $min , $max , $dcount , and $distinct 00 Get the distincted values of Unit description.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 08 Use aggregates $min , $max , $dcount , and $distinct 00 Get the min and max of unit factor and offset.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 08 Use aggregates $min , $max , $dcount , and $distinct 00 Get the min and max of unit factor and offset.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 08 Use aggregates $min , $max , $dcount , and $distinct 00 Get the min and max of unit factor.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 08 Use aggregates $min , $max , $dcount , and $distinct 00 Get the min and max of unit factor.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 09 Inner and outer joins 00 Use inner join.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 09 Inner and outer joins 00 Use inner join.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 09 Inner and outer joins 00 Use outer join.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 09 Inner and outer joins 00 Use outer join.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 10 Use $groupby 00 Use a $groupby on two attributes.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/01 Access Instances 10 Use $groupby 00 Use a $groupby on two attributes.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get AoTest instances.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get AoTest instances.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get MeaQuantity instances.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get MeaQuantity instances.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get MeaResult instances.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get MeaResult instances.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get Project instances.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get Project instances.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get StructureLevel instances.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get StructureLevel instances.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get Test instances.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get Test instances.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get TestStep instances.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 01 Access hierarchy elements 00 Get TestStep instances.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 02 Browse ODS tree 00 Get MeaResult from TestStep with id equal 4.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 02 Browse ODS tree 00 Get MeaResult from TestStep with id equal 4.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 02 Browse ODS tree 00 Get MeaResult with test with id equal 4.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 02 Browse ODS tree 00 Get MeaResult with test with id equal 4.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 02 Browse ODS tree 00 Get StructureLevel from Project with id equal 3.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 02 Browse ODS tree 00 Get StructureLevel from Project with id equal 3.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 02 Browse ODS tree 00 Get StructureLevel with parent_test with id equal 3.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 02 Browse ODS tree 00 Get StructureLevel with parent_test with id equal 3.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 03 Access descriptive meta 00 Get some meta of related AoUnitUnderTestPart instances.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 03 Access descriptive meta 00 Get some meta of related AoUnitUnderTestPart instances.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 04 Access parameter sets 00 Get name value pairs attached to MeaResult .json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/02 Access OpenMDM content 04 Access parameter sets 00 Get name value pairs attached to MeaResult .json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/03 Access Bulk 01 Read data from Measurement 00 Get AoMeasurementQuantity from AoMeasurement with id equal 153.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/03 Access Bulk 01 Read data from Measurement 00 Get AoMeasurementQuantity from AoMeasurement with id equal 153.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/03 Access Bulk 01 Read data from Measurement 00 Get AoMeasurementQuantity with measurement with id equal 153.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/03 Access Bulk 01 Read data from Measurement 00 Get AoMeasurementQuantity with measurement with id equal 153.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/03 Access Bulk 01 Read data from Measurement 00 Get AoSubmatrix with measurement with id equal 153.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/03 Access Bulk 01 Read data from Measurement 00 Get AoSubmatrix with measurement with id equal 153.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/03 Access Bulk 01 Read data from Measurement 00 Get bulk of AoLocalColumn with submatrix.measurement with id equal 153.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/03 Access Bulk 01 Read data from Measurement 00 Get bulk of AoLocalColumn with submatrix.measurement with id equal 153.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/03 Access Bulk 01 Read data from Measurement 00 Get meta of AoLocalColumn with submatrix.measurement with id equal 153.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/03 Access Bulk 01 Read data from Measurement 00 Get meta of AoLocalColumn with submatrix.measurement with id equal 153.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/bugs/bug_127_$notnull.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/bugs/bug_127_$notnull.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/bugs/bug_127_$null.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/bugs/bug_127_$null.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/bugs/bug_93_outer_join_must_preserve_direction.json +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/bugs/bug_93_outer_join_must_preserve_direction.json.proto +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_datamatrices_to_pandas.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_datamatrices_to_pandas2.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_date_value_mapping.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_enum_value_mapping.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_exd_api.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_is_null_to_nan.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_jaquel_convert.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_jaquel_mocked.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_model_cache.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_model_suggestions.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_odsbox_init.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_proto_init.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_security.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_unit_catalog.py +0 -0
- {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_unit_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: odsbox
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.16rc494.post1
|
|
4
4
|
Summary: Toolbox for accessing ASAM ODS servers using the HTTP API
|
|
5
5
|
Keywords: asam,ods,measurement,data access,data science,data analysis
|
|
6
6
|
Author-email: Andreas Krantz <a.krantz@peak-solution.de>
|
|
@@ -272,10 +272,10 @@ class ConI:
|
|
|
272
272
|
This uses pandas native nullable data types for better type preservation.
|
|
273
273
|
Defaults to True.
|
|
274
274
|
:param str result_naming_mode: Controls how result column names are generated.
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
275
|
+
"query" (default): Uses column names from the JAQUEL query
|
|
276
|
+
(e.g., 'name', 'phys_dimension.name').
|
|
277
|
+
"model": Uses column names from the ods.Model schema
|
|
278
|
+
(e.g., 'Unit.Name', 'PhysDimension.Name').
|
|
279
279
|
:param kwargs: Additional arguments passed to `to_pandas`.
|
|
280
280
|
:raises requests.HTTPError: If query fails.
|
|
281
281
|
:return DataFrame: The DataMatrices as Pandas.DataFrame with columns named according to `result_naming_mode`.
|
|
@@ -691,6 +691,7 @@ class ConI:
|
|
|
691
691
|
target_file_or_folder: str,
|
|
692
692
|
overwrite_existing: bool = False,
|
|
693
693
|
default_filename: str = "download.bin",
|
|
694
|
+
chunk_size: int = 8192,
|
|
694
695
|
) -> str:
|
|
695
696
|
"""
|
|
696
697
|
Read file content from server.
|
|
@@ -701,6 +702,7 @@ class ConI:
|
|
|
701
702
|
:param bool overwrite_existing: If existing files should be overwritten. It defaults to False.
|
|
702
703
|
:param str default_filename: Default filename if no filename is provided by server.
|
|
703
704
|
It defaults to "download.bin".
|
|
705
|
+
:param int chunk_size: Size of chunks in bytes to stream. It defaults to 8192 (8KB).
|
|
704
706
|
:raises requests.HTTPError: If something went wrong.
|
|
705
707
|
:raises FileExistsError: If file already exists and 'overwrite_existing' is False.
|
|
706
708
|
:raises ValueError: If no open session.
|
|
@@ -721,6 +723,7 @@ class ConI:
|
|
|
721
723
|
},
|
|
722
724
|
timeout=self.__request_timeout,
|
|
723
725
|
allow_redirects=self.__allow_redirects,
|
|
726
|
+
stream=True,
|
|
724
727
|
)
|
|
725
728
|
self.check_requests_response(file_response)
|
|
726
729
|
|
|
@@ -740,7 +743,9 @@ class ConI:
|
|
|
740
743
|
raise FileExistsError(f"File '{target_file_path}' already exists and 'overwrite_existing' is False.")
|
|
741
744
|
|
|
742
745
|
with open(target_file_path, "wb") as file:
|
|
743
|
-
|
|
746
|
+
for chunk in file_response.iter_content(chunk_size=chunk_size):
|
|
747
|
+
if chunk: # filter out keep-alive new chunks
|
|
748
|
+
file.write(chunk)
|
|
744
749
|
|
|
745
750
|
return target_file_path
|
|
746
751
|
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"""Tests for chunked download functionality in file_access_download"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import tempfile
|
|
7
|
+
from unittest import mock
|
|
8
|
+
|
|
9
|
+
import pytest
|
|
10
|
+
|
|
11
|
+
from odsbox.con_i import ConI
|
|
12
|
+
from odsbox.proto.ods_pb2 import FileIdentifier
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@pytest.fixture
|
|
16
|
+
def con_i():
|
|
17
|
+
return ConI("https://docker.peak-solution.de:10032/api", ("Demo", "mdm"))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class TestChunkedDownload:
|
|
21
|
+
"""Test suite for chunked download functionality"""
|
|
22
|
+
|
|
23
|
+
def test_chunked_download_with_default_chunk_size(self, con_i):
|
|
24
|
+
"""Test that default chunk size (8192 bytes) is used when not specified"""
|
|
25
|
+
file_identifier = FileIdentifier(aid=4711, iid=1)
|
|
26
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
27
|
+
target_file = os.path.join(temp_dir, "test_file.bin")
|
|
28
|
+
|
|
29
|
+
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
30
|
+
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
31
|
+
mock_response = mock.Mock()
|
|
32
|
+
mock_response.iter_content = mock.Mock(return_value=[b"chunk1", b"chunk2"])
|
|
33
|
+
mock_response.headers = {}
|
|
34
|
+
mock_get.return_value = mock_response
|
|
35
|
+
|
|
36
|
+
con_i.file_access_download(file_identifier, target_file, overwrite_existing=True)
|
|
37
|
+
|
|
38
|
+
# Verify iter_content was called with default chunk size
|
|
39
|
+
mock_response.iter_content.assert_called_once_with(chunk_size=8192)
|
|
40
|
+
|
|
41
|
+
def test_chunked_download_with_custom_chunk_size(self, con_i):
|
|
42
|
+
"""Test that custom chunk size is used when specified"""
|
|
43
|
+
file_identifier = FileIdentifier(aid=4711, iid=1)
|
|
44
|
+
custom_chunk_size = 4096
|
|
45
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
46
|
+
target_file = os.path.join(temp_dir, "test_file.bin")
|
|
47
|
+
|
|
48
|
+
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
49
|
+
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
50
|
+
mock_response = mock.Mock()
|
|
51
|
+
mock_response.iter_content = mock.Mock(return_value=[b"chunk1", b"chunk2"])
|
|
52
|
+
mock_response.headers = {}
|
|
53
|
+
mock_get.return_value = mock_response
|
|
54
|
+
|
|
55
|
+
con_i.file_access_download(
|
|
56
|
+
file_identifier, target_file, overwrite_existing=True, chunk_size=custom_chunk_size
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
# Verify iter_content was called with custom chunk size
|
|
60
|
+
mock_response.iter_content.assert_called_once_with(chunk_size=custom_chunk_size)
|
|
61
|
+
|
|
62
|
+
def test_chunked_download_writes_all_chunks(self, con_i):
|
|
63
|
+
"""Test that all chunks are written to file"""
|
|
64
|
+
file_identifier = FileIdentifier(aid=4711, iid=1)
|
|
65
|
+
chunks = [b"chunk1_", b"chunk2_", b"chunk3_"]
|
|
66
|
+
expected_content = b"chunk1_chunk2_chunk3_"
|
|
67
|
+
|
|
68
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
69
|
+
target_file = os.path.join(temp_dir, "test_file.bin")
|
|
70
|
+
|
|
71
|
+
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
72
|
+
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
73
|
+
mock_response = mock.Mock()
|
|
74
|
+
mock_response.iter_content = mock.Mock(return_value=chunks)
|
|
75
|
+
mock_response.headers = {}
|
|
76
|
+
mock_get.return_value = mock_response
|
|
77
|
+
|
|
78
|
+
con_i.file_access_download(file_identifier, target_file, overwrite_existing=True)
|
|
79
|
+
|
|
80
|
+
# Verify file content matches all chunks
|
|
81
|
+
with open(target_file, "rb") as f:
|
|
82
|
+
assert f.read() == expected_content
|
|
83
|
+
|
|
84
|
+
def test_chunked_download_filters_empty_chunks(self, con_i):
|
|
85
|
+
"""Test that empty chunks (keep-alive chunks) are filtered out"""
|
|
86
|
+
file_identifier = FileIdentifier(aid=4711, iid=1)
|
|
87
|
+
# Include empty byte strings (keep-alive chunks)
|
|
88
|
+
chunks = [b"data1", b"", b"data2", b"", b"data3"]
|
|
89
|
+
expected_content = b"data1data2data3"
|
|
90
|
+
|
|
91
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
92
|
+
target_file = os.path.join(temp_dir, "test_file.bin")
|
|
93
|
+
|
|
94
|
+
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
95
|
+
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
96
|
+
mock_response = mock.Mock()
|
|
97
|
+
mock_response.iter_content = mock.Mock(return_value=chunks)
|
|
98
|
+
mock_response.headers = {}
|
|
99
|
+
mock_get.return_value = mock_response
|
|
100
|
+
|
|
101
|
+
con_i.file_access_download(file_identifier, target_file, overwrite_existing=True)
|
|
102
|
+
|
|
103
|
+
# Verify that only non-empty chunks were written
|
|
104
|
+
with open(target_file, "rb") as f:
|
|
105
|
+
assert f.read() == expected_content
|
|
106
|
+
|
|
107
|
+
def test_chunked_download_with_stream_true(self, con_i):
|
|
108
|
+
"""Test that stream=True is set in the HTTP request"""
|
|
109
|
+
file_identifier = FileIdentifier(aid=4711, iid=1)
|
|
110
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
111
|
+
target_file = os.path.join(temp_dir, "test_file.bin")
|
|
112
|
+
|
|
113
|
+
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
114
|
+
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
115
|
+
mock_response = mock.Mock()
|
|
116
|
+
mock_response.iter_content = mock.Mock(return_value=[b"data"])
|
|
117
|
+
mock_response.headers = {}
|
|
118
|
+
mock_get.return_value = mock_response
|
|
119
|
+
|
|
120
|
+
con_i.file_access_download(file_identifier, target_file, overwrite_existing=True)
|
|
121
|
+
|
|
122
|
+
# Verify stream=True is in the call
|
|
123
|
+
call_kwargs = mock_get.call_args[1]
|
|
124
|
+
assert call_kwargs["stream"] is True
|
|
125
|
+
|
|
126
|
+
def test_chunked_download_large_file(self, con_i):
|
|
127
|
+
"""Test downloading a large file with chunked streaming"""
|
|
128
|
+
file_identifier = FileIdentifier(aid=4711, iid=1)
|
|
129
|
+
# Simulate a 1MB file downloaded in 8KB chunks
|
|
130
|
+
chunk_size = 8192
|
|
131
|
+
num_chunks = 128
|
|
132
|
+
chunks = [b"x" * chunk_size for _ in range(num_chunks)]
|
|
133
|
+
|
|
134
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
135
|
+
target_file = os.path.join(temp_dir, "large_file.bin")
|
|
136
|
+
|
|
137
|
+
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
138
|
+
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
139
|
+
mock_response = mock.Mock()
|
|
140
|
+
mock_response.iter_content = mock.Mock(return_value=chunks)
|
|
141
|
+
mock_response.headers = {}
|
|
142
|
+
mock_get.return_value = mock_response
|
|
143
|
+
|
|
144
|
+
con_i.file_access_download(file_identifier, target_file, overwrite_existing=True)
|
|
145
|
+
|
|
146
|
+
# Verify file size is correct
|
|
147
|
+
file_size = os.path.getsize(target_file)
|
|
148
|
+
assert file_size == chunk_size * num_chunks
|
|
149
|
+
|
|
150
|
+
def test_chunked_download_with_content_disposition(self, con_i):
|
|
151
|
+
"""Test chunked download respects Content-Disposition header"""
|
|
152
|
+
file_identifier = FileIdentifier(aid=4711, iid=1)
|
|
153
|
+
expected_filename = "server_filename.bin"
|
|
154
|
+
|
|
155
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
156
|
+
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
157
|
+
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
158
|
+
mock_response = mock.Mock()
|
|
159
|
+
mock_response.iter_content = mock.Mock(return_value=[b"data"])
|
|
160
|
+
mock_response.headers = {"Content-Disposition": f'attachment; filename="{expected_filename}"'}
|
|
161
|
+
mock_get.return_value = mock_response
|
|
162
|
+
|
|
163
|
+
result_path = con_i.file_access_download(file_identifier, temp_dir, overwrite_existing=True)
|
|
164
|
+
|
|
165
|
+
# Verify filename matches Content-Disposition
|
|
166
|
+
assert os.path.basename(result_path) == expected_filename
|
|
167
|
+
with open(result_path, "rb") as f:
|
|
168
|
+
assert f.read() == b"data"
|
|
169
|
+
|
|
170
|
+
def test_chunked_download_preserves_binary_data(self, con_i):
|
|
171
|
+
"""Test that binary data integrity is preserved through chunked download"""
|
|
172
|
+
file_identifier = FileIdentifier(aid=4711, iid=1)
|
|
173
|
+
# Create binary data with all byte values
|
|
174
|
+
binary_data = bytes(range(256))
|
|
175
|
+
chunks = [binary_data[i : i + 16] for i in range(0, len(binary_data), 16)]
|
|
176
|
+
|
|
177
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
178
|
+
target_file = os.path.join(temp_dir, "binary_file.bin")
|
|
179
|
+
|
|
180
|
+
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
181
|
+
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
182
|
+
mock_response = mock.Mock()
|
|
183
|
+
mock_response.iter_content = mock.Mock(return_value=chunks)
|
|
184
|
+
mock_response.headers = {}
|
|
185
|
+
mock_get.return_value = mock_response
|
|
186
|
+
|
|
187
|
+
con_i.file_access_download(file_identifier, target_file, overwrite_existing=True)
|
|
188
|
+
|
|
189
|
+
# Verify binary data is intact
|
|
190
|
+
with open(target_file, "rb") as f:
|
|
191
|
+
assert f.read() == binary_data
|
|
192
|
+
|
|
193
|
+
def test_chunked_download_chunk_size_variations(self, con_i):
|
|
194
|
+
"""Test various chunk sizes"""
|
|
195
|
+
file_identifier = FileIdentifier(aid=4711, iid=1)
|
|
196
|
+
chunk_sizes = [1024, 4096, 8192, 16384, 65536]
|
|
197
|
+
|
|
198
|
+
for chunk_size in chunk_sizes:
|
|
199
|
+
with tempfile.TemporaryDirectory() as temp_dir:
|
|
200
|
+
target_file = os.path.join(temp_dir, "test_file.bin")
|
|
201
|
+
|
|
202
|
+
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
203
|
+
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
204
|
+
mock_response = mock.Mock()
|
|
205
|
+
mock_response.iter_content = mock.Mock(return_value=[b"x" * chunk_size])
|
|
206
|
+
mock_response.headers = {}
|
|
207
|
+
mock_get.return_value = mock_response
|
|
208
|
+
|
|
209
|
+
con_i.file_access_download(
|
|
210
|
+
file_identifier, target_file, overwrite_existing=True, chunk_size=chunk_size
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
# Verify correct chunk size was requested
|
|
214
|
+
mock_response.iter_content.assert_called_once_with(chunk_size=chunk_size)
|
|
@@ -25,7 +25,7 @@ def test_file_access_download_success(con_i):
|
|
|
25
25
|
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
26
26
|
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
27
27
|
mock_response = mock.Mock()
|
|
28
|
-
mock_response.
|
|
28
|
+
mock_response.iter_content = mock.Mock(return_value=[b"file content"])
|
|
29
29
|
mock_response.headers = {"Content-Disposition": "attachment; filename=test_download.bin"}
|
|
30
30
|
mock_get.return_value = mock_response
|
|
31
31
|
|
|
@@ -46,7 +46,7 @@ def test_file_access_download_success_2(con_i):
|
|
|
46
46
|
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
47
47
|
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
48
48
|
mock_response = mock.Mock()
|
|
49
|
-
mock_response.
|
|
49
|
+
mock_response.iter_content = mock.Mock(return_value=[b"file content"])
|
|
50
50
|
mock_response.headers = {"Content-Disposition": 'attachment; filename="test_download.bin"'}
|
|
51
51
|
mock_get.return_value = mock_response
|
|
52
52
|
|
|
@@ -68,7 +68,7 @@ def test_file_access_download_success_3(con_i):
|
|
|
68
68
|
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
69
69
|
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
70
70
|
mock_response = mock.Mock()
|
|
71
|
-
mock_response.
|
|
71
|
+
mock_response.iter_content = mock.Mock(return_value=[b"file content"])
|
|
72
72
|
mock_response.headers = {"Content-Disposition": 'attachment; filename="test_download.bin"'}
|
|
73
73
|
mock_get.return_value = mock_response
|
|
74
74
|
|
|
@@ -88,7 +88,7 @@ def test_file_access_download_success_4(con_i):
|
|
|
88
88
|
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
89
89
|
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
90
90
|
mock_response = mock.Mock()
|
|
91
|
-
mock_response.
|
|
91
|
+
mock_response.iter_content = mock.Mock(return_value=[b"file content"])
|
|
92
92
|
mock_response.headers = {}
|
|
93
93
|
mock_get.return_value = mock_response
|
|
94
94
|
|
|
@@ -110,7 +110,7 @@ def test_file_access_download_no_overwrite(con_i):
|
|
|
110
110
|
with mock.patch.object(con_i, "file_access", return_value="http://example.com/file"):
|
|
111
111
|
with mock.patch.object(con_i._ConI__session, "get") as mock_get:
|
|
112
112
|
mock_response = mock.Mock()
|
|
113
|
-
mock_response.
|
|
113
|
+
mock_response.iter_content = mock.Mock(return_value=[b"new file content"])
|
|
114
114
|
mock_response.headers = {"Content-Disposition": "attachment; filename=test_download_no_overwrite.bin"}
|
|
115
115
|
mock_get.return_value = mock_response
|
|
116
116
|
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.5 BLOCK -->
|
|
2
|
-
|
|
3
|
-
## Security
|
|
4
|
-
|
|
5
|
-
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
|
|
6
|
-
|
|
7
|
-
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)), please report it to us as described below.
|
|
8
|
-
|
|
9
|
-
## Reporting Security Issues
|
|
10
|
-
|
|
11
|
-
**Please do not report security vulnerabilities through public GitHub issues.**
|
|
12
|
-
|
|
13
|
-
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://msrc.microsoft.com/create-report).
|
|
14
|
-
|
|
15
|
-
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://www.microsoft.com/en-us/msrc/pgp-key-msrc).
|
|
16
|
-
|
|
17
|
-
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
|
|
18
|
-
|
|
19
|
-
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
|
|
20
|
-
|
|
21
|
-
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
|
22
|
-
* Full paths of source file(s) related to the manifestation of the issue
|
|
23
|
-
* The location of the affected source code (tag/branch/commit or direct URL)
|
|
24
|
-
* Any special configuration required to reproduce the issue
|
|
25
|
-
* Step-by-step instructions to reproduce the issue
|
|
26
|
-
* Proof-of-concept or exploit code (if possible)
|
|
27
|
-
* Impact of the issue, including how an attacker might exploit the issue
|
|
28
|
-
|
|
29
|
-
This information will help us triage your report more quickly.
|
|
30
|
-
|
|
31
|
-
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://microsoft.com/msrc/bounty) page for more details about our active programs.
|
|
32
|
-
|
|
33
|
-
## Preferred Languages
|
|
34
|
-
|
|
35
|
-
We prefer all communications to be in English.
|
|
36
|
-
|
|
37
|
-
## Policy
|
|
38
|
-
|
|
39
|
-
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd).
|
|
40
|
-
|
|
41
|
-
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/ISSUE_TEMPLATE/feature_request.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/schedule-update-actions.yml
RENAMED
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/semantic-pr-check.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/jaquel_conversion_result.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_external_data_pb2.py
RENAMED
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_external_data_pb2.pyi
RENAMED
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_external_data_pb2_grpc.py
RENAMED
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_notification_pb2.py
RENAMED
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_notification_pb2.pyi
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_con_i_with_resource_logout.py
RENAMED
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/application_model.json
RENAMED
|
File without changes
|
{odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/examples_from_jaquel_doc.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|