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.
Files changed (203) hide show
  1. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/PKG-INFO +1 -1
  2. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/requirements.txt +1 -0
  3. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/__init__.py +1 -1
  4. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/con_i.py +10 -5
  5. odsbox-1.0.16rc494.post1/tests/test_con_i_chunked_download.py +214 -0
  6. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_con_i_file_access.py +5 -5
  7. odsbox-1.0.16rc492.post1/SECURITY.md +0 -41
  8. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.devcontainer/Dockerfile +0 -0
  9. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.devcontainer/devcontainer.json +0 -0
  10. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  11. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/ISSUE_TEMPLATE/custom.md +0 -0
  12. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  13. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/dependabot.yml +0 -0
  14. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/template-sync.yml +0 -0
  15. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/CI.yml +0 -0
  16. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/publish.yml +0 -0
  17. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/schedule-update-actions.yml +0 -0
  18. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/semantic-pr-check.yml +0 -0
  19. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/sphinx.yml +0 -0
  20. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.github/workflows/template-sync.yml +0 -0
  21. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.gitignore +0 -0
  22. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.pre-commit-config.yaml +0 -0
  23. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.pypirc +0 -0
  24. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.vscode/launch.json +0 -0
  25. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/.vscode/settings.json +0 -0
  26. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/CODE_OF_CONDUCT.md +0 -0
  27. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/CONTRIBUTING.md +0 -0
  28. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/LICENSE +0 -0
  29. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/README.md +0 -0
  30. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/SUPPORT.md +0 -0
  31. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/Makefile +0 -0
  32. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/_templates/layout.html +0 -0
  33. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/compare_measurement.ipynb +0 -0
  34. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/conf.py +0 -0
  35. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/index.rst +0 -0
  36. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/jaquel.md +0 -0
  37. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/jaquel_examples.md +0 -0
  38. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/jaquel_examples_notebook.ipynb +0 -0
  39. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/make.bat +0 -0
  40. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/odsbox.rst +0 -0
  41. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/overview.rst +0 -0
  42. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/repository_rules.md +0 -0
  43. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/docs/simple_ods_example.ipynb +0 -0
  44. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/pyproject.toml +0 -0
  45. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/README.md +0 -0
  46. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/asam_time.py +0 -0
  47. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/bulk_reader.py +0 -0
  48. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/datamatrices_to_pandas.py +0 -0
  49. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/jaquel.py +0 -0
  50. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/jaquel_conversion_result.py +0 -0
  51. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/model_cache.py +0 -0
  52. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/model_suggestions.py +0 -0
  53. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/README.md +0 -0
  54. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/__init__.py +0 -0
  55. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_external_data_pb2.py +0 -0
  56. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_external_data_pb2.pyi +0 -0
  57. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_external_data_pb2_grpc.py +0 -0
  58. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_notification_pb2.py +0 -0
  59. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_notification_pb2.pyi +0 -0
  60. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_pb2.py +0 -0
  61. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_pb2.pyi +0 -0
  62. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_security_pb2.py +0 -0
  63. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/proto/ods_security_pb2.pyi +0 -0
  64. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/py.typed +0 -0
  65. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/security.py +0 -0
  66. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/submatrix_to_pandas.py +0 -0
  67. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/transaction.py +0 -0
  68. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/unit_catalog.py +0 -0
  69. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/src/odsbox/unit_utils.py +0 -0
  70. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/conftest.py +0 -0
  71. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_asam_time.py +0 -0
  72. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_bulk_reader.py +0 -0
  73. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_bulk_reader_integration.py +0 -0
  74. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_con_i.py +0 -0
  75. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_con_i_type_error.py +0 -0
  76. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_con_i_with_resource_logout.py +0 -0
  77. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/application_model.json +0 -0
  78. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/examples_from_jaquel_doc.json +0 -0
  79. {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
  80. {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
  81. {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
  82. {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
  83. {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
  84. {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
  85. {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
  86. {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
  87. {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
  88. {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
  89. {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
  90. {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
  91. {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
  92. {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
  93. {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
  94. {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
  95. {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
  96. {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
  97. {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
  98. {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
  99. {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
  100. {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
  101. {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
  102. {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
  103. {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
  104. {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
  105. {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
  106. {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
  107. {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
  108. {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
  109. {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
  110. {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
  111. {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
  112. {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
  113. {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
  114. {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
  115. {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
  116. {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
  117. {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
  118. {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
  119. {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
  120. {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
  121. {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
  122. {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
  123. {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
  124. {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
  125. {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
  126. {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
  127. {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
  128. {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
  129. {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
  130. {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
  131. {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
  132. {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
  133. {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
  134. {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
  135. {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
  136. {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
  137. {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
  138. {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
  139. {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
  140. {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
  141. {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
  142. {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
  143. {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
  144. {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
  145. {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
  146. {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
  147. {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
  148. {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
  149. {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
  150. {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
  151. {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
  152. {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
  153. {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
  154. {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
  155. {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
  156. {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
  157. {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
  158. {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
  159. {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
  160. {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
  161. {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
  162. {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
  163. {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
  164. {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
  165. {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
  166. {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
  167. {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
  168. {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
  169. {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
  170. {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
  171. {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
  172. {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
  173. {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
  174. {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
  175. {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
  176. {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
  177. {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
  178. {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
  179. {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
  180. {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
  181. {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
  182. {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
  183. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/bugs/bug_127_$notnull.json +0 -0
  184. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/bugs/bug_127_$notnull.json.proto +0 -0
  185. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/bugs/bug_127_$null.json +0 -0
  186. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_data/jaquel/bugs/bug_127_$null.json.proto +0 -0
  187. {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
  188. {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
  189. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_datamatrices_to_pandas.py +0 -0
  190. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_datamatrices_to_pandas2.py +0 -0
  191. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_date_value_mapping.py +0 -0
  192. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_enum_value_mapping.py +0 -0
  193. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_exd_api.py +0 -0
  194. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_is_null_to_nan.py +0 -0
  195. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_jaquel_convert.py +0 -0
  196. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_jaquel_mocked.py +0 -0
  197. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_model_cache.py +0 -0
  198. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_model_suggestions.py +0 -0
  199. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_odsbox_init.py +0 -0
  200. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_proto_init.py +0 -0
  201. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_security.py +0 -0
  202. {odsbox-1.0.16rc492.post1 → odsbox-1.0.16rc494.post1}/tests/test_unit_catalog.py +0 -0
  203. {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.16rc492.post1
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>
@@ -5,3 +5,4 @@ sphinx-copybutton
5
5
  sphinx-design
6
6
  sphinx-rtd-theme
7
7
  sphinx-sitemap
8
+ ipython
@@ -16,7 +16,7 @@ from __future__ import annotations
16
16
 
17
17
  from typing import TYPE_CHECKING
18
18
 
19
- __version__ = "1.0.16""-rc492-post1"
19
+ __version__ = "1.0.16""-rc494-post1"
20
20
 
21
21
  if TYPE_CHECKING:
22
22
  from .con_i import ConI
@@ -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
- "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').
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
- file.write(file_response.content)
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.content = b"file content"
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.content = b"file content"
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.content = b"file content"
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.content = b"file content"
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.content = b"new file content"
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 -->