hdx-python-api 6.2.6__tar.gz → 6.2.8__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 (129) hide show
  1. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/.config/pre-commit-config.yaml +5 -4
  2. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/PKG-INFO +5 -5
  3. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/documentation/.readthedocs.yaml +1 -0
  4. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/documentation/main.md +7 -0
  5. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/documentation/pydoc-markdown.yaml +1 -1
  6. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/pyproject.toml +4 -4
  7. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/requirements.txt +44 -64
  8. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/api/_version.py +2 -2
  9. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/dataset.py +42 -9
  10. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/filestore_helper.py +6 -4
  11. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/resource.py +6 -5
  12. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/api/test_ckan.py +9 -3
  13. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/__init__.py +10 -0
  14. hdx_python_api-6.2.8/tests/hdx/data/test_filestore_helper.py +49 -0
  15. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_resource.py +24 -34
  16. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_update_dataset_resources.py +4 -0
  17. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/.config/coveragerc +0 -0
  18. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/.config/pytest.ini +0 -0
  19. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/.config/ruff.toml +0 -0
  20. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/.github/workflows/publish.yaml +0 -0
  21. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/.github/workflows/run-python-tests.yaml +0 -0
  22. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/.gitignore +0 -0
  23. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/CONTRIBUTING.md +0 -0
  24. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/LICENSE +0 -0
  25. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/README.md +0 -0
  26. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/api/__init__.py +0 -0
  27. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/api/configuration.py +0 -0
  28. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/api/hdx_base_configuration.yaml +0 -0
  29. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/api/locations.py +0 -0
  30. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/api/remotehdx.py +0 -0
  31. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/__init__.py +0 -0
  32. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/dataset_title_helper.py +0 -0
  33. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/date_helper.py +0 -0
  34. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/hdx_datasource_topline.yaml +0 -0
  35. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/hdxobject.py +0 -0
  36. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/indicator_resource_view_template.yaml +0 -0
  37. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/organization.py +0 -0
  38. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/resource_matcher.py +0 -0
  39. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/resource_view.py +0 -0
  40. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/showcase.py +0 -0
  41. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/user.py +0 -0
  42. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/data/vocabulary.py +0 -0
  43. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/facades/__init__.py +0 -0
  44. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/facades/infer_arguments.py +0 -0
  45. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/facades/keyword_arguments.py +0 -0
  46. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/src/hdx/facades/simple.py +0 -0
  47. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/Accepted_Tags.csv +0 -0
  48. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/CKAN/hdx_dataset_static.yaml +0 -0
  49. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/Tag_Mapping.csv +0 -0
  50. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/Tag_Mapping_ChainRuleError.csv +0 -0
  51. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/empty.yaml +0 -0
  52. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_base_config.json +0 -0
  53. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_base_config.yaml +0 -0
  54. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_config.json +0 -0
  55. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_config.yaml +0 -0
  56. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_dataset_static.json +0 -0
  57. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_dataset_static.yaml +0 -0
  58. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_datasource_topline.json +0 -0
  59. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_datasource_topline.yaml +0 -0
  60. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_email_configuration.json +0 -0
  61. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_email_configuration.yaml +0 -0
  62. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_missing_site_config.json +0 -0
  63. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_organization_static.json +0 -0
  64. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_organization_static.yaml +0 -0
  65. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_resource_static.json +0 -0
  66. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_resource_static.yaml +0 -0
  67. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_resource_view_static.json +0 -0
  68. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_resource_view_static.yaml +0 -0
  69. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_showcase_static.json +0 -0
  70. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_showcase_static.yaml +0 -0
  71. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_user_static.json +0 -0
  72. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_user_static.yaml +0 -0
  73. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_vocabulary_static.json +0 -0
  74. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/hdx_vocabulary_static.yaml +0 -0
  75. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/project_configuration.json +0 -0
  76. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/project_configuration.yaml +0 -0
  77. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/user_agent_config.yaml +0 -0
  78. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/user_agent_config2.yaml +0 -0
  79. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/user_agent_config3.yaml +0 -0
  80. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/config/user_agent_config_wrong.yaml +0 -0
  81. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/dataset_search_results.yaml +0 -0
  82. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/datastore/ACLED-All-Africa-File_20170101-to-20170708.xlsx +0 -0
  83. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/empty.csv +0 -0
  84. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/gen_resource/conflict_data_alg.csv +0 -0
  85. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/gen_resource/min_qc_conflict_data_alg.csv +0 -0
  86. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/gen_resource/qc_conflict_data_alg.csv +0 -0
  87. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/gen_resource/test_data_no_data.csv +0 -0
  88. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/gen_resource/test_data_no_years.csv +0 -0
  89. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/organization_show_results.yaml +0 -0
  90. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/qc_from_rows/qc_conflict_data_alg.csv +0 -0
  91. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/qc_from_rows/qc_conflict_data_alg_one_col.csv +0 -0
  92. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/resource_formats.json +0 -0
  93. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/showcase_all_search_results.yaml +0 -0
  94. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/test_data.csv +0 -0
  95. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/test_data.zip +0 -0
  96. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/dem_data_zwe.csv +0 -0
  97. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/dem_indicatorlist_zwe.csv +0 -0
  98. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/expected_resources_to_update.json +0 -0
  99. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/opri_data_zwe.csv +0 -0
  100. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/opri_indicatorlist_zwe.csv +0 -0
  101. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/opri_metadata_zwe.csv +0 -0
  102. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/qc_sdg_data_zwe.csv +0 -0
  103. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/sdg_data_zwe.csv +0 -0
  104. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/sdg_indicatorlist_zwe.csv +0 -0
  105. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/sdg_metadata_zwe.csv +0 -0
  106. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/unesco_dataset.json +0 -0
  107. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_dataset_resources/unesco_update_dataset.json +0 -0
  108. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_logic/update_logic_resources.yaml +0 -0
  109. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/fixtures/update_logic/update_logic_resources_new.yaml +0 -0
  110. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/api/test_configuration.py +0 -0
  111. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/api/test_locations.py +0 -0
  112. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/conftest.py +0 -0
  113. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_dataset_core.py +0 -0
  114. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_dataset_noncore.py +0 -0
  115. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_dataset_title_helper.py +0 -0
  116. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_organization.py +0 -0
  117. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_resource_view.py +0 -0
  118. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_showcase.py +0 -0
  119. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_update_logic.py +0 -0
  120. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_user.py +0 -0
  121. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/data/test_vocabulary.py +0 -0
  122. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/facades/__init__.py +0 -0
  123. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/facades/test_infer_arguments.py +0 -0
  124. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/facades/test_keyword_arguments.py +0 -0
  125. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/tests/hdx/facades/test_simple.py +0 -0
  126. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/workingexample/my_code.py +0 -0
  127. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/workingexample/my_resource.csv +0 -0
  128. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/workingexample/my_resource.xlsx +0 -0
  129. {hdx_python_api-6.2.6 → hdx_python_api-6.2.8}/workingexample/run.py +0 -0
@@ -9,7 +9,7 @@ repos:
9
9
  exclude: test_scraper_.*\.json
10
10
  - id: check-ast
11
11
  - repo: https://github.com/astral-sh/ruff-pre-commit
12
- rev: v0.3.2
12
+ rev: v0.4.2
13
13
  hooks:
14
14
  # Run the linter.
15
15
  - id: ruff
@@ -17,10 +17,11 @@ repos:
17
17
  # Run the formatter.
18
18
  - id: ruff-format
19
19
  args: [--config, .config/ruff.toml]
20
- - repo: https://github.com/jazzband/pip-tools
21
- rev: 7.4.1
20
+ - repo: https://github.com/astral-sh/uv-pre-commit
21
+ rev: 0.1.38
22
22
  hooks:
23
+ # Run the pip compile
23
24
  - id: pip-compile
24
25
  name: pip-compile requirements.txt
25
26
  files: pyproject.toml
26
- args: [pyproject.toml, --resolver=backtracking, --all-extras, --upgrade, -q, -o, requirements.txt]
27
+ args: [ pyproject.toml, --resolver=backtracking, --all-extras, --upgrade, -q, -o, requirements.txt ]
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hdx-python-api
3
- Version: 6.2.6
3
+ Version: 6.2.8
4
4
  Summary: HDX Python API for interacting with the Humanitarian Data Exchange
5
5
  Project-URL: Homepage, https://github.com/OCHA-DAP/hdx-python-api
6
- Author-email: Michael Rans <rans@email.com>
6
+ Author: Michael Rans
7
7
  License: MIT
8
8
  License-File: LICENSE
9
9
  Keywords: API,CKAN,HDX,humanitarian data exchange
@@ -25,11 +25,11 @@ Classifier: Programming Language :: Python :: 3.11
25
25
  Classifier: Programming Language :: Python :: 3.12
26
26
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
27
27
  Requires-Python: >=3.8
28
- Requires-Dist: ckanapi>=4.7
28
+ Requires-Dist: ckanapi>=4.8
29
29
  Requires-Dist: defopt>=6.4.0
30
30
  Requires-Dist: email-validator
31
- Requires-Dist: hdx-python-country>=3.6.9
32
- Requires-Dist: hdx-python-utilities>=3.6.7
31
+ Requires-Dist: hdx-python-country>=3.7.0
32
+ Requires-Dist: hdx-python-utilities>=3.6.8
33
33
  Requires-Dist: libhxl>=5.2.1
34
34
  Requires-Dist: makefun
35
35
  Requires-Dist: ndg-httpsclient
@@ -11,5 +11,6 @@ build:
11
11
  jobs:
12
12
  pre_build:
13
13
  - pip install --upgrade mkdocs
14
+ - pip install mkdocs-material
14
15
  - pip install pydoc-markdown
15
16
  - pydoc-markdown documentation/pydoc-markdown.yaml
@@ -52,6 +52,13 @@ The library has detailed API documentation which can be found in the menu at the
52
52
 
53
53
 
54
54
  ## Breaking Changes
55
+ From 6.2.8, fix mark_data_updated which was broken due to an error in
56
+ dataset_update_filestore_resource in which timezone information was
57
+ incorrectly added to the iso formatted string
58
+
59
+ From 6.2.7, generate_resource_from_iterator renamed to
60
+ generate_resource_from_iterable with requirement of iterable rather iterator
61
+
55
62
  From 6.2.6, kwargs take preference over environment variables which take
56
63
  preference over configuration files
57
64
 
@@ -11,7 +11,7 @@ renderer:
11
11
  output_directory: docs
12
12
  mkdocs_config:
13
13
  site_name: HDX Python API
14
- theme: mkdocs
14
+ theme: material
15
15
  repo_url: "https://github.com/OCHA-DAP/hdx-python-api"
16
16
  markdown:
17
17
  source_linker:
@@ -9,7 +9,7 @@ build-backend = "hatchling.build"
9
9
  [project]
10
10
  name = "hdx-python-api"
11
11
  description = "HDX Python API for interacting with the Humanitarian Data Exchange"
12
- authors = [{name = "Michael Rans", email = "rans@email.com"}]
12
+ authors = [{name = "Michael Rans"}]
13
13
  license = {text = "MIT"}
14
14
  keywords = ["HDX", "API", "CKAN", "humanitarian data exchange"]
15
15
  classifiers = [
@@ -34,11 +34,11 @@ classifiers = [
34
34
  requires-python = ">=3.8"
35
35
 
36
36
  dependencies = [
37
- "ckanapi>=4.7",
37
+ "ckanapi>=4.8",
38
38
  "defopt>=6.4.0",
39
39
  "email_validator",
40
- "hdx-python-country>=3.6.9",
41
- "hdx-python-utilities>=3.6.7",
40
+ "hdx-python-country>=3.7.0",
41
+ "hdx-python-utilities>=3.6.8",
42
42
  "libhxl>=5.2.1",
43
43
  "makefun",
44
44
  "ndg-httpsclient",
@@ -1,9 +1,5 @@
1
- #
2
- # This file is autogenerated by pip-compile with Python 3.11
3
- # by the following command:
4
- #
5
- # pip-compile --all-extras --output-file=requirements.txt pyproject.toml
6
- #
1
+ # This file was autogenerated by uv via the following command:
2
+ # uv pip compile pyproject.toml --resolver=backtracking --all-extras -o requirements.txt
7
3
  annotated-types==0.6.0
8
4
  # via pydantic
9
5
  attrs==23.2.0
@@ -23,18 +19,14 @@ chardet==5.2.0
23
19
  # via frictionless
24
20
  charset-normalizer==3.3.2
25
21
  # via requests
26
- ckanapi==4.7
27
- # via hdx-python-api (pyproject.toml)
22
+ ckanapi==4.8
28
23
  click==8.1.7
29
24
  # via typer
30
- colorama==0.4.6
31
- # via typer
32
- coverage[toml]==7.4.4
25
+ coverage==7.5.0
33
26
  # via pytest-cov
34
27
  cryptography==42.0.5
35
28
  # via pyopenssl
36
29
  defopt==6.4.0
37
- # via hdx-python-api (pyproject.toml)
38
30
  distlib==0.3.8
39
31
  # via virtualenv
40
32
  dnspython==2.6.1
@@ -43,41 +35,36 @@ docopt==0.6.2
43
35
  # via
44
36
  # ckanapi
45
37
  # num2words
46
- docutils==0.20.1
38
+ docutils==0.21.2
47
39
  # via defopt
48
40
  email-validator==2.1.1
49
- # via hdx-python-api (pyproject.toml)
50
41
  et-xmlfile==1.1.0
51
42
  # via openpyxl
52
- filelock==3.13.1
43
+ filelock==3.13.4
53
44
  # via virtualenv
54
45
  frictionless==5.16.1
55
46
  # via hdx-python-utilities
56
- google-auth==2.28.2
47
+ google-auth==2.29.0
57
48
  # via
58
49
  # google-auth-oauthlib
59
50
  # gspread
60
51
  google-auth-oauthlib==1.2.0
61
52
  # via gspread
62
- gspread==6.0.2
63
- # via hdx-python-api (pyproject.toml)
64
- hdx-python-country==3.6.9
65
- # via hdx-python-api (pyproject.toml)
66
- hdx-python-utilities==3.6.7
67
- # via
68
- # hdx-python-api (pyproject.toml)
69
- # hdx-python-country
53
+ gspread==6.1.0
54
+ hdx-python-country==3.7.0
55
+ hdx-python-utilities==3.6.8
56
+ # via hdx-python-country
70
57
  humanize==4.9.0
71
58
  # via frictionless
72
- identify==2.5.35
59
+ identify==2.5.36
73
60
  # via pre-commit
74
- idna==3.6
61
+ idna==3.7
75
62
  # via
76
63
  # email-validator
77
64
  # requests
78
65
  ijson==3.2.3
79
66
  # via hdx-python-utilities
80
- inflect==7.0.0
67
+ inflect==7.2.1
81
68
  # via quantulum3
82
69
  iniconfig==2.0.0
83
70
  # via pytest
@@ -94,13 +81,10 @@ jsonschema==4.17.3
94
81
  # frictionless
95
82
  # tableschema-to-template
96
83
  libhxl==5.2.1
97
- # via
98
- # hdx-python-api (pyproject.toml)
99
- # hdx-python-country
84
+ # via hdx-python-country
100
85
  loguru==0.7.2
101
86
  # via hdx-python-utilities
102
87
  makefun==1.15.2
103
- # via hdx-python-api (pyproject.toml)
104
88
  markdown-it-py==3.0.0
105
89
  # via rich
106
90
  marko==2.0.3
@@ -109,8 +93,9 @@ markupsafe==2.1.5
109
93
  # via jinja2
110
94
  mdurl==0.1.2
111
95
  # via markdown-it-py
96
+ more-itertools==10.2.0
97
+ # via inflect
112
98
  ndg-httpsclient==0.5.1
113
- # via hdx-python-api (pyproject.toml)
114
99
  nodeenv==1.8.0
115
100
  # via pre-commit
116
101
  num2words==0.5.13
@@ -123,9 +108,9 @@ packaging==24.0
123
108
  # via pytest
124
109
  petl==1.7.15
125
110
  # via frictionless
126
- platformdirs==4.2.0
111
+ platformdirs==4.2.1
127
112
  # via virtualenv
128
- pluggy==1.4.0
113
+ pluggy==1.5.0
129
114
  # via pytest
130
115
  ply==3.11
131
116
  # via
@@ -133,40 +118,31 @@ ply==3.11
133
118
  # libhxl
134
119
  pockets==0.9.1
135
120
  # via sphinxcontrib-napoleon
136
- pre-commit==3.6.2
137
- # via hdx-python-api (pyproject.toml)
138
- pyasn1==0.5.1
121
+ pre-commit==3.7.0
122
+ pyasn1==0.6.0
139
123
  # via
140
- # hdx-python-api (pyproject.toml)
141
124
  # ndg-httpsclient
142
125
  # pyasn1-modules
143
126
  # rsa
144
- pyasn1-modules==0.3.0
127
+ pyasn1-modules==0.4.0
145
128
  # via google-auth
146
- pycparser==2.21
129
+ pycparser==2.22
147
130
  # via cffi
148
- pydantic==2.6.4
149
- # via
150
- # frictionless
151
- # inflect
152
- pydantic-core==2.16.3
131
+ pydantic==2.7.1
132
+ # via frictionless
133
+ pydantic-core==2.18.2
153
134
  # via pydantic
154
135
  pygments==2.17.2
155
136
  # via rich
156
137
  pyopenssl==24.1.0
157
- # via
158
- # hdx-python-api (pyproject.toml)
159
- # ndg-httpsclient
138
+ # via ndg-httpsclient
160
139
  pyphonetics==0.5.3
161
140
  # via hdx-python-country
162
141
  pyrsistent==0.20.0
163
142
  # via jsonschema
164
143
  pytest==8.1.1
165
- # via
166
- # hdx-python-api (pyproject.toml)
167
- # pytest-cov
168
- pytest-cov==4.1.0
169
- # via hdx-python-api (pyproject.toml)
144
+ # via pytest-cov
145
+ pytest-cov==5.0.0
170
146
  python-dateutil==2.8.2
171
147
  # via
172
148
  # frictionless
@@ -183,21 +159,19 @@ pyyaml==6.0.1
183
159
  # frictionless
184
160
  # pre-commit
185
161
  # tableschema-to-template
186
- quantulum3==0.9.0
187
- # via hdx-python-api (pyproject.toml)
162
+ quantulum3==0.9.1
188
163
  ratelimit==2.2.1
189
164
  # via hdx-python-utilities
190
165
  requests==2.31.0
191
166
  # via
192
167
  # ckanapi
193
168
  # frictionless
194
- # hdx-python-api (pyproject.toml)
195
169
  # libhxl
196
170
  # requests-file
197
171
  # requests-oauthlib
198
172
  requests-file==2.0.0
199
173
  # via hdx-python-utilities
200
- requests-oauthlib==1.4.0
174
+ requests-oauthlib==2.0.0
201
175
  # via google-auth-oauthlib
202
176
  rfc3986==2.0.0
203
177
  # via frictionless
@@ -209,10 +183,16 @@ ruamel-yaml==0.18.6
209
183
  # via hdx-python-utilities
210
184
  ruamel-yaml-clib==0.2.8
211
185
  # via ruamel-yaml
186
+ setuptools==69.5.1
187
+ # via
188
+ # ckanapi
189
+ # nodeenv
212
190
  shellingham==1.5.4
213
191
  # via typer
214
192
  simpleeval==0.9.13
215
193
  # via frictionless
194
+ simplejson==3.19.2
195
+ # via ckanapi
216
196
  six==1.16.0
217
197
  # via
218
198
  # ckanapi
@@ -234,14 +214,17 @@ tabulate==0.9.0
234
214
  # via frictionless
235
215
  text-unidecode==1.3
236
216
  # via python-slugify
237
- typer[all]==0.9.0
217
+ typeguard==4.2.1
218
+ # via inflect
219
+ typer==0.12.3
238
220
  # via frictionless
239
- typing-extensions==4.10.0
221
+ typing-extensions==4.11.0
240
222
  # via
241
223
  # frictionless
242
224
  # inflect
243
225
  # pydantic
244
226
  # pydantic-core
227
+ # typeguard
245
228
  # typer
246
229
  unidecode==1.3.8
247
230
  # via
@@ -251,9 +234,9 @@ urllib3==2.2.1
251
234
  # via
252
235
  # libhxl
253
236
  # requests
254
- validators==0.23.1
237
+ validators==0.28.1
255
238
  # via frictionless
256
- virtualenv==20.25.1
239
+ virtualenv==20.26.0
257
240
  # via pre-commit
258
241
  wheel==0.43.0
259
242
  # via libhxl
@@ -265,6 +248,3 @@ xlsxwriter==3.2.0
265
248
  # via tableschema-to-template
266
249
  xlwt==1.3.0
267
250
  # via hdx-python-utilities
268
-
269
- # The following packages are considered to be unsafe in a requirements file:
270
- # setuptools
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '6.2.6'
16
- __version_tuple__ = version_tuple = (6, 2, 6)
15
+ __version__ = version = '6.2.8'
16
+ __version_tuple__ = version_tuple = (6, 2, 8)
@@ -5,7 +5,7 @@ import logging
5
5
  import sys
6
6
  import warnings
7
7
  from copy import deepcopy
8
- from datetime import datetime, timezone
8
+ from datetime import datetime
9
9
  from os.path import isfile, join
10
10
  from typing import (
11
11
  TYPE_CHECKING,
@@ -41,6 +41,7 @@ from hdx.utilities.dateparse import (
41
41
  default_date,
42
42
  default_enddate,
43
43
  now_utc,
44
+ now_utc_notz,
44
45
  parse_date,
45
46
  parse_date_range,
46
47
  )
@@ -598,9 +599,9 @@ class Dataset(HDXObject):
598
599
  del kwargs["updated_by_script"]
599
600
  else:
600
601
  scriptinfo = self.configuration.get_user_agent()
601
- # No need to output timezone info here
602
+ # Should not output timezone info here
602
603
  data["updated_by_script"] = (
603
- f"{scriptinfo} ({datetime.now(timezone.utc).replace(tzinfo=None).isoformat(timespec='microseconds')})"
604
+ f"{scriptinfo} ({now_utc_notz().isoformat(timespec='microseconds')})"
604
605
  )
605
606
  batch = kwargs.get("batch")
606
607
  if batch:
@@ -2601,10 +2602,10 @@ class Dataset(HDXObject):
2601
2602
  encoding=encoding,
2602
2603
  )
2603
2604
 
2604
- def generate_resource_from_iterator(
2605
+ def generate_resource_from_iterable(
2605
2606
  self,
2606
2607
  headers: ListTuple[str],
2607
- iterator: Iterator[Union[ListTuple, Dict]],
2608
+ iterable: Iterable[Union[ListTuple, Dict]],
2608
2609
  hxltags: Dict[str, str],
2609
2610
  folder: str,
2610
2611
  filename: str,
@@ -2615,7 +2616,7 @@ class Dataset(HDXObject):
2615
2616
  quickcharts: Optional[Dict] = None,
2616
2617
  encoding: Optional[str] = None,
2617
2618
  ) -> Tuple[bool, Dict]:
2618
- """Given headers and an iterator, write rows to csv and create
2619
+ """Given headers and an iterable, write rows to csv and create
2619
2620
  resource, adding to it the dataset. The returned dictionary will
2620
2621
  contain the resource in the key resource, headers in the key headers
2621
2622
  and list of rows in the key rows.
@@ -2652,7 +2653,7 @@ class Dataset(HDXObject):
2652
2653
 
2653
2654
  Args:
2654
2655
  headers (ListTuple[str]): Headers
2655
- iterator (Iterator[Union[ListTuple,Dict]]): Iterator returning rows
2656
+ iterable (Iterable[Union[ListTuple,Dict]]): Iterable returning rows
2656
2657
  hxltags (Dict[str,str]): Header to HXL hashtag mapping
2657
2658
  folder (str): Folder to which to write file containing rows
2658
2659
  filename (str): Filename of file to write rows
@@ -2738,7 +2739,7 @@ class Dataset(HDXObject):
2738
2739
 
2739
2740
  date_function = datecol_function
2740
2741
 
2741
- for row in iterator:
2742
+ for row in iterable:
2742
2743
  if date_function is not None:
2743
2744
  result = date_function(row)
2744
2745
  if result is None:
@@ -2813,6 +2814,38 @@ class Dataset(HDXObject):
2813
2814
  retdict["qc_resource"] = resource
2814
2815
  return True, retdict
2815
2816
 
2817
+ def generate_resource_from_iterator(
2818
+ self,
2819
+ headers: ListTuple[str],
2820
+ iterator: Iterator[Union[ListTuple, Dict]],
2821
+ hxltags: Dict[str, str],
2822
+ folder: str,
2823
+ filename: str,
2824
+ resourcedata: Dict,
2825
+ datecol: Optional[Union[int, str]] = None,
2826
+ yearcol: Optional[Union[int, str]] = None,
2827
+ date_function: Optional[Callable[[Dict], Optional[Dict]]] = None,
2828
+ quickcharts: Optional[Dict] = None,
2829
+ encoding: Optional[str] = None,
2830
+ ) -> Tuple[bool, Dict]:
2831
+ warnings.warn(
2832
+ "generate_resource_from_iterator() is deprecated, use generate_resource_from_iterable() instead",
2833
+ DeprecationWarning,
2834
+ )
2835
+ return self.generate_resource_from_iterable(
2836
+ headers,
2837
+ iterator,
2838
+ hxltags,
2839
+ folder,
2840
+ filename,
2841
+ resourcedata,
2842
+ datecol,
2843
+ yearcol,
2844
+ date_function,
2845
+ quickcharts,
2846
+ encoding,
2847
+ )
2848
+
2816
2849
  def download_and_generate_resource(
2817
2850
  self,
2818
2851
  downloader: BaseDownload,
@@ -2898,7 +2931,7 @@ class Dataset(HDXObject):
2898
2931
  format="csv",
2899
2932
  **kwargs,
2900
2933
  )
2901
- return self.generate_resource_from_iterator(
2934
+ return self.generate_resource_from_iterable(
2902
2935
  headers,
2903
2936
  iterator,
2904
2937
  hxltags,
@@ -1,8 +1,9 @@
1
1
  """Helper to the Dataset class for handling resources with filestores."""
2
2
 
3
- from datetime import datetime, timezone
4
3
  from typing import TYPE_CHECKING, Any, Dict
5
4
 
5
+ from hdx.utilities.dateparse import now_utc_notz
6
+
6
7
  if TYPE_CHECKING:
7
8
  from hdx.data.resource import Resource
8
9
 
@@ -90,7 +91,8 @@ class FilestoreHelper:
90
91
 
91
92
  data_updated = resource_data_to_update.is_marked_data_updated()
92
93
  if data_updated:
93
- resource_data_to_update["last_modified"] = datetime.now(
94
- timezone.utc
95
- ).isoformat(timespec="microseconds")
94
+ # Should not output timezone info here
95
+ resource_data_to_update["last_modified"] = (
96
+ now_utc_notz().isoformat(timespec="microseconds")
97
+ )
96
98
  resource_data_to_update.data_updated = False
@@ -2,7 +2,7 @@
2
2
 
3
3
  import logging
4
4
  import warnings
5
- from datetime import datetime, timezone
5
+ from datetime import datetime
6
6
  from os.path import join
7
7
  from pathlib import Path
8
8
  from typing import Any, Dict, List, Optional, Tuple, Union
@@ -13,7 +13,7 @@ from hdx.api.configuration import Configuration
13
13
  from hdx.data.date_helper import DateHelper
14
14
  from hdx.data.hdxobject import HDXError, HDXObject
15
15
  from hdx.data.resource_view import ResourceView
16
- from hdx.utilities.dateparse import now_utc, parse_date
16
+ from hdx.utilities.dateparse import now_utc, now_utc_notz, parse_date
17
17
  from hdx.utilities.downloader import Download
18
18
  from hdx.utilities.typehint import ListTuple
19
19
  from hdx.utilities.uuid import is_valid_uuid
@@ -393,9 +393,10 @@ class Resource(HDXObject):
393
393
  """
394
394
  data_updated = kwargs.pop("data_updated", self.data_updated)
395
395
  if data_updated and not self.file_to_upload:
396
- self.old_data["last_modified"] = datetime.now(
397
- timezone.utc
398
- ).isoformat(timespec="microseconds")
396
+ # Should not output timezone info here
397
+ self.old_data["last_modified"] = now_utc_notz().isoformat(
398
+ timespec="microseconds"
399
+ )
399
400
  self.data_updated = False
400
401
  # old_data will be merged into data in the next step
401
402
  self._merge_hdx_update(
@@ -176,7 +176,9 @@ class TestCKAN:
176
176
  assert dataset["title"] == title
177
177
  assert dataset.get_tags() == tags
178
178
  assert dataset.get_maintainer()["id"] == maintainer_id
179
- assert dataset.get_organization()["display_name"] == "INNAGO"
179
+ assert (
180
+ dataset.get_organization()["display_name"] == "INNAGO (inactive)"
181
+ )
180
182
  resources = dataset.get_resources()
181
183
  for i, resource in enumerate(resources):
182
184
  assert resource["name"] == f"test_resource_{i}"
@@ -227,7 +229,9 @@ class TestCKAN:
227
229
  assert dataset["caveats"] == caveats
228
230
  assert dataset.get_tags() == tags
229
231
  assert dataset.get_maintainer()["id"] == maintainer_id
230
- assert dataset.get_organization()["display_name"] == "INNAGO"
232
+ assert (
233
+ dataset.get_organization()["display_name"] == "INNAGO (inactive)"
234
+ )
231
235
  updated_resources = dataset.get_resources()
232
236
  for i, updated_resource in enumerate(updated_resources):
233
237
  resource = resources[i]
@@ -269,7 +273,9 @@ class TestCKAN:
269
273
  assert "caveats" not in dataset
270
274
  assert dataset.get_tags() == tags
271
275
  assert dataset.get_maintainer()["id"] == maintainer_id
272
- assert dataset.get_organization()["display_name"] == "INNAGO"
276
+ assert (
277
+ dataset.get_organization()["display_name"] == "INNAGO (inactive)"
278
+ )
273
279
  updated_resources = dataset.get_resources()
274
280
  for i, updated_resource in enumerate(updated_resources):
275
281
  resource = resources[i]
@@ -96,6 +96,16 @@ resources_data = [
96
96
  },
97
97
  ]
98
98
 
99
+ resource_data = {
100
+ "name": "MyResource1",
101
+ "package_id": "6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d",
102
+ "format": "xlsx",
103
+ "url": "http://test/spreadsheet.xlsx",
104
+ "description": "My Resource",
105
+ "api_type": "api",
106
+ "resource_type": "api",
107
+ }
108
+
99
109
  organization_data = {
100
110
  "name": "MyOrganization1",
101
111
  "title": "Humanitarian Organization",
@@ -0,0 +1,49 @@
1
+ import copy
2
+ import re
3
+
4
+ from . import resource_data
5
+ from hdx.data.filestore_helper import FilestoreHelper
6
+ from hdx.data.resource import Resource
7
+
8
+
9
+ class TestFilestoreHelper:
10
+ def test_dataset_update_filestore_resource(self, configuration):
11
+ resource_data_copy = copy.deepcopy(resource_data)
12
+ resource = Resource(resource_data_copy)
13
+ filestore_resources = {}
14
+ FilestoreHelper.dataset_update_filestore_resource(
15
+ resource, filestore_resources, 0
16
+ )
17
+ assert resource == {
18
+ "api_type": "api",
19
+ "description": "My Resource",
20
+ "format": "xlsx",
21
+ "name": "MyResource1",
22
+ "package_id": "6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d",
23
+ "resource_type": "api",
24
+ "url": "http://test/spreadsheet.xlsx",
25
+ }
26
+ assert filestore_resources == {}
27
+
28
+ resource.set_file_to_upload("test")
29
+ FilestoreHelper.dataset_update_filestore_resource(
30
+ resource, filestore_resources, 0
31
+ )
32
+ assert resource == {
33
+ "api_type": "api",
34
+ "description": "My Resource",
35
+ "format": "xlsx",
36
+ "name": "MyResource1",
37
+ "package_id": "6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d",
38
+ "resource_type": "api",
39
+ "url": "updated_by_file_upload_step",
40
+ }
41
+ assert filestore_resources == {0: "test"}
42
+
43
+ resource.mark_data_updated()
44
+ FilestoreHelper.dataset_update_filestore_resource(
45
+ resource, filestore_resources, 0
46
+ )
47
+ regex = r"^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d\d\d\d\d\d$"
48
+ assert re.match(regex, resource["last_modified"])
49
+ assert filestore_resources == {0: "test"}