hdx-python-api 6.2.7__tar.gz → 6.2.9__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.7 → hdx_python_api-6.2.9}/.config/pre-commit-config.yaml +2 -2
  2. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/PKG-INFO +3 -3
  3. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/documentation/main.md +4 -0
  4. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/pyproject.toml +2 -2
  5. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/requirements.txt +45 -40
  6. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/api/_version.py +2 -2
  7. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/dataset.py +4 -3
  8. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/filestore_helper.py +6 -4
  9. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/resource.py +11 -7
  10. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/vocabulary.py +5 -2
  11. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/__init__.py +10 -0
  12. hdx_python_api-6.2.9/tests/hdx/data/test_filestore_helper.py +49 -0
  13. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_resource.py +24 -34
  14. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_update_dataset_resources.py +4 -0
  15. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/.config/coveragerc +0 -0
  16. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/.config/pytest.ini +0 -0
  17. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/.config/ruff.toml +0 -0
  18. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/.github/workflows/publish.yaml +0 -0
  19. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/.github/workflows/run-python-tests.yaml +0 -0
  20. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/.gitignore +0 -0
  21. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/CONTRIBUTING.md +0 -0
  22. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/LICENSE +0 -0
  23. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/README.md +0 -0
  24. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/documentation/.readthedocs.yaml +0 -0
  25. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/documentation/pydoc-markdown.yaml +0 -0
  26. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/api/__init__.py +0 -0
  27. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/api/configuration.py +0 -0
  28. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/api/hdx_base_configuration.yaml +0 -0
  29. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/api/locations.py +0 -0
  30. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/api/remotehdx.py +0 -0
  31. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/__init__.py +0 -0
  32. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/dataset_title_helper.py +0 -0
  33. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/date_helper.py +0 -0
  34. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/hdx_datasource_topline.yaml +0 -0
  35. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/hdxobject.py +0 -0
  36. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/indicator_resource_view_template.yaml +0 -0
  37. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/organization.py +0 -0
  38. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/resource_matcher.py +0 -0
  39. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/resource_view.py +0 -0
  40. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/showcase.py +0 -0
  41. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/data/user.py +0 -0
  42. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/facades/__init__.py +0 -0
  43. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/facades/infer_arguments.py +0 -0
  44. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/facades/keyword_arguments.py +0 -0
  45. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/src/hdx/facades/simple.py +0 -0
  46. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/Accepted_Tags.csv +0 -0
  47. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/CKAN/hdx_dataset_static.yaml +0 -0
  48. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/Tag_Mapping.csv +0 -0
  49. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/Tag_Mapping_ChainRuleError.csv +0 -0
  50. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/empty.yaml +0 -0
  51. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_base_config.json +0 -0
  52. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_base_config.yaml +0 -0
  53. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_config.json +0 -0
  54. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_config.yaml +0 -0
  55. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_dataset_static.json +0 -0
  56. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_dataset_static.yaml +0 -0
  57. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_datasource_topline.json +0 -0
  58. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_datasource_topline.yaml +0 -0
  59. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_email_configuration.json +0 -0
  60. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_email_configuration.yaml +0 -0
  61. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_missing_site_config.json +0 -0
  62. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_organization_static.json +0 -0
  63. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_organization_static.yaml +0 -0
  64. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_resource_static.json +0 -0
  65. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_resource_static.yaml +0 -0
  66. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_resource_view_static.json +0 -0
  67. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_resource_view_static.yaml +0 -0
  68. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_showcase_static.json +0 -0
  69. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_showcase_static.yaml +0 -0
  70. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_user_static.json +0 -0
  71. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_user_static.yaml +0 -0
  72. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_vocabulary_static.json +0 -0
  73. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/hdx_vocabulary_static.yaml +0 -0
  74. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/project_configuration.json +0 -0
  75. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/project_configuration.yaml +0 -0
  76. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/user_agent_config.yaml +0 -0
  77. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/user_agent_config2.yaml +0 -0
  78. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/user_agent_config3.yaml +0 -0
  79. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/config/user_agent_config_wrong.yaml +0 -0
  80. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/dataset_search_results.yaml +0 -0
  81. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/datastore/ACLED-All-Africa-File_20170101-to-20170708.xlsx +0 -0
  82. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/empty.csv +0 -0
  83. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/gen_resource/conflict_data_alg.csv +0 -0
  84. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/gen_resource/min_qc_conflict_data_alg.csv +0 -0
  85. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/gen_resource/qc_conflict_data_alg.csv +0 -0
  86. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/gen_resource/test_data_no_data.csv +0 -0
  87. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/gen_resource/test_data_no_years.csv +0 -0
  88. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/organization_show_results.yaml +0 -0
  89. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/qc_from_rows/qc_conflict_data_alg.csv +0 -0
  90. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/qc_from_rows/qc_conflict_data_alg_one_col.csv +0 -0
  91. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/resource_formats.json +0 -0
  92. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/showcase_all_search_results.yaml +0 -0
  93. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/test_data.csv +0 -0
  94. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/test_data.zip +0 -0
  95. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/dem_data_zwe.csv +0 -0
  96. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/dem_indicatorlist_zwe.csv +0 -0
  97. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/expected_resources_to_update.json +0 -0
  98. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/opri_data_zwe.csv +0 -0
  99. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/opri_indicatorlist_zwe.csv +0 -0
  100. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/opri_metadata_zwe.csv +0 -0
  101. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/qc_sdg_data_zwe.csv +0 -0
  102. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/sdg_data_zwe.csv +0 -0
  103. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/sdg_indicatorlist_zwe.csv +0 -0
  104. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/sdg_metadata_zwe.csv +0 -0
  105. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/unesco_dataset.json +0 -0
  106. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_dataset_resources/unesco_update_dataset.json +0 -0
  107. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_logic/update_logic_resources.yaml +0 -0
  108. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/fixtures/update_logic/update_logic_resources_new.yaml +0 -0
  109. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/api/test_ckan.py +0 -0
  110. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/api/test_configuration.py +0 -0
  111. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/api/test_locations.py +0 -0
  112. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/conftest.py +0 -0
  113. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_dataset_core.py +0 -0
  114. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_dataset_noncore.py +0 -0
  115. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_dataset_title_helper.py +0 -0
  116. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_organization.py +0 -0
  117. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_resource_view.py +0 -0
  118. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_showcase.py +0 -0
  119. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_update_logic.py +0 -0
  120. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_user.py +0 -0
  121. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/data/test_vocabulary.py +0 -0
  122. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/facades/__init__.py +0 -0
  123. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/facades/test_infer_arguments.py +0 -0
  124. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/facades/test_keyword_arguments.py +0 -0
  125. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/tests/hdx/facades/test_simple.py +0 -0
  126. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/workingexample/my_code.py +0 -0
  127. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/workingexample/my_resource.csv +0 -0
  128. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/workingexample/my_resource.xlsx +0 -0
  129. {hdx_python_api-6.2.7 → hdx_python_api-6.2.9}/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
@@ -18,7 +18,7 @@ repos:
18
18
  - id: ruff-format
19
19
  args: [--config, .config/ruff.toml]
20
20
  - repo: https://github.com/astral-sh/uv-pre-commit
21
- rev: v0.1.24
21
+ rev: 0.1.38
22
22
  hooks:
23
23
  # Run the pip compile
24
24
  - id: pip-compile
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: hdx-python-api
3
- Version: 6.2.7
3
+ Version: 6.2.9
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
6
  Author: Michael Rans
@@ -28,8 +28,8 @@ Requires-Python: >=3.8
28
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.7.0
32
- Requires-Dist: hdx-python-utilities>=3.6.7
31
+ Requires-Dist: hdx-python-country>=3.7.2
32
+ Requires-Dist: hdx-python-utilities>=3.6.9
33
33
  Requires-Dist: libhxl>=5.2.1
34
34
  Requires-Dist: makefun
35
35
  Requires-Dist: ndg-httpsclient
@@ -52,6 +52,10 @@ 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
+
55
59
  From 6.2.7, generate_resource_from_iterator renamed to
56
60
  generate_resource_from_iterable with requirement of iterable rather iterator
57
61
 
@@ -37,8 +37,8 @@ dependencies = [
37
37
  "ckanapi>=4.8",
38
38
  "defopt>=6.4.0",
39
39
  "email_validator",
40
- "hdx-python-country>=3.7.0",
41
- "hdx-python-utilities>=3.6.7",
40
+ "hdx-python-country>=3.7.2",
41
+ "hdx-python-utilities>=3.6.9",
42
42
  "libhxl>=5.2.1",
43
43
  "makefun",
44
44
  "ndg-httpsclient",
@@ -1,15 +1,16 @@
1
1
  # This file was autogenerated by uv via the following command:
2
2
  # uv pip compile pyproject.toml --resolver=backtracking --all-extras -o requirements.txt
3
- annotated-types==0.6.0
3
+ annotated-types==0.7.0
4
4
  # via pydantic
5
5
  attrs==23.2.0
6
6
  # via
7
7
  # frictionless
8
8
  # jsonlines
9
9
  # jsonschema
10
+ # referencing
10
11
  cachetools==5.3.3
11
12
  # via google-auth
12
- certifi==2024.2.2
13
+ certifi==2024.6.2
13
14
  # via requests
14
15
  cffi==1.16.0
15
16
  # via cryptography
@@ -22,9 +23,9 @@ charset-normalizer==3.3.2
22
23
  ckanapi==4.8
23
24
  click==8.1.7
24
25
  # via typer
25
- coverage==7.4.4
26
+ coverage==7.5.3
26
27
  # via pytest-cov
27
- cryptography==42.0.5
28
+ cryptography==42.0.8
28
29
  # via pyopenssl
29
30
  defopt==6.4.0
30
31
  distlib==0.3.8
@@ -35,14 +36,14 @@ docopt==0.6.2
35
36
  # via
36
37
  # ckanapi
37
38
  # num2words
38
- docutils==0.21.post1
39
+ docutils==0.21.2
39
40
  # via defopt
40
41
  email-validator==2.1.1
41
42
  et-xmlfile==1.1.0
42
43
  # via openpyxl
43
- filelock==3.13.4
44
+ filelock==3.14.0
44
45
  # via virtualenv
45
- frictionless==5.16.1
46
+ frictionless==5.17.0
46
47
  # via hdx-python-utilities
47
48
  google-auth==2.29.0
48
49
  # via
@@ -50,36 +51,38 @@ google-auth==2.29.0
50
51
  # gspread
51
52
  google-auth-oauthlib==1.2.0
52
53
  # via gspread
53
- gspread==6.1.0
54
- hdx-python-country==3.7.0
55
- hdx-python-utilities==3.6.7
54
+ gspread==6.1.2
55
+ hdx-python-country==3.7.2
56
+ hdx-python-utilities==3.6.9
56
57
  # via hdx-python-country
57
58
  humanize==4.9.0
58
59
  # via frictionless
59
- identify==2.5.35
60
+ identify==2.5.36
60
61
  # via pre-commit
61
- idna==3.6
62
+ idna==3.7
62
63
  # via
63
64
  # email-validator
64
65
  # requests
65
66
  ijson==3.2.3
66
67
  # via hdx-python-utilities
67
- inflect==7.2.0
68
+ inflect==7.2.1
68
69
  # via quantulum3
69
70
  iniconfig==2.0.0
70
71
  # via pytest
71
72
  isodate==0.6.1
72
73
  # via frictionless
73
- jinja2==3.1.3
74
+ jinja2==3.1.4
74
75
  # via frictionless
75
76
  jsonlines==4.0.0
76
77
  # via hdx-python-utilities
77
78
  jsonpath-ng==1.6.1
78
79
  # via libhxl
79
- jsonschema==4.17.3
80
+ jsonschema==4.22.0
80
81
  # via
81
82
  # frictionless
82
83
  # tableschema-to-template
84
+ jsonschema-specifications==2023.12.1
85
+ # via jsonschema
83
86
  libhxl==5.2.1
84
87
  # via hdx-python-country
85
88
  loguru==0.7.2
@@ -96,21 +99,21 @@ mdurl==0.1.2
96
99
  more-itertools==10.2.0
97
100
  # via inflect
98
101
  ndg-httpsclient==0.5.1
99
- nodeenv==1.8.0
102
+ nodeenv==1.9.1
100
103
  # via pre-commit
101
104
  num2words==0.5.13
102
105
  # via quantulum3
103
106
  oauthlib==3.2.2
104
107
  # via requests-oauthlib
105
- openpyxl==3.1.2
108
+ openpyxl==3.1.3
106
109
  # via hdx-python-utilities
107
110
  packaging==24.0
108
111
  # via pytest
109
112
  petl==1.7.15
110
113
  # via frictionless
111
- platformdirs==4.2.0
114
+ platformdirs==4.2.2
112
115
  # via virtualenv
113
- pluggy==1.4.0
116
+ pluggy==1.5.0
114
117
  # via pytest
115
118
  ply==3.11
116
119
  # via
@@ -118,7 +121,7 @@ ply==3.11
118
121
  # libhxl
119
122
  pockets==0.9.1
120
123
  # via sphinxcontrib-napoleon
121
- pre-commit==3.7.0
124
+ pre-commit==3.7.1
122
125
  pyasn1==0.6.0
123
126
  # via
124
127
  # ndg-httpsclient
@@ -128,19 +131,17 @@ pyasn1-modules==0.4.0
128
131
  # via google-auth
129
132
  pycparser==2.22
130
133
  # via cffi
131
- pydantic==2.6.4
134
+ pydantic==2.7.3
132
135
  # via frictionless
133
- pydantic-core==2.16.3
136
+ pydantic-core==2.18.4
134
137
  # via pydantic
135
- pygments==2.17.2
138
+ pygments==2.18.0
136
139
  # via rich
137
140
  pyopenssl==24.1.0
138
141
  # via ndg-httpsclient
139
142
  pyphonetics==0.5.3
140
143
  # via hdx-python-country
141
- pyrsistent==0.20.0
142
- # via jsonschema
143
- pytest==8.1.1
144
+ pytest==8.2.2
144
145
  # via pytest-cov
145
146
  pytest-cov==5.0.0
146
147
  python-dateutil==2.8.2
@@ -159,17 +160,21 @@ pyyaml==6.0.1
159
160
  # frictionless
160
161
  # pre-commit
161
162
  # tableschema-to-template
162
- quantulum3==0.9.0
163
+ quantulum3==0.9.1
163
164
  ratelimit==2.2.1
164
165
  # via hdx-python-utilities
165
- requests==2.31.0
166
+ referencing==0.35.1
167
+ # via
168
+ # jsonschema
169
+ # jsonschema-specifications
170
+ requests==2.32.3
166
171
  # via
167
172
  # ckanapi
168
173
  # frictionless
169
174
  # libhxl
170
175
  # requests-file
171
176
  # requests-oauthlib
172
- requests-file==2.0.0
177
+ requests-file==2.1.0
173
178
  # via hdx-python-utilities
174
179
  requests-oauthlib==2.0.0
175
180
  # via google-auth-oauthlib
@@ -177,16 +182,18 @@ rfc3986==2.0.0
177
182
  # via frictionless
178
183
  rich==13.7.1
179
184
  # via typer
185
+ rpds-py==0.18.1
186
+ # via
187
+ # jsonschema
188
+ # referencing
180
189
  rsa==4.9
181
190
  # via google-auth
182
191
  ruamel-yaml==0.18.6
183
192
  # via hdx-python-utilities
184
193
  ruamel-yaml-clib==0.2.8
185
194
  # via ruamel-yaml
186
- setuptools==69.2.0
187
- # via
188
- # ckanapi
189
- # nodeenv
195
+ setuptools==70.0.0
196
+ # via ckanapi
190
197
  shellingham==1.5.4
191
198
  # via typer
192
199
  simpleeval==0.9.13
@@ -202,11 +209,9 @@ six==1.16.0
202
209
  # sphinxcontrib-napoleon
203
210
  sphinxcontrib-napoleon==0.7
204
211
  # via defopt
205
- strenum==0.4.15
206
- # via gspread
207
212
  stringcase==1.2.0
208
213
  # via frictionless
209
- structlog==24.1.0
214
+ structlog==24.2.0
210
215
  # via libhxl
211
216
  tableschema-to-template==0.0.13
212
217
  # via hdx-python-utilities
@@ -214,11 +219,11 @@ tabulate==0.9.0
214
219
  # via frictionless
215
220
  text-unidecode==1.3
216
221
  # via python-slugify
217
- typeguard==4.2.1
222
+ typeguard==4.3.0
218
223
  # via inflect
219
224
  typer==0.12.3
220
225
  # via frictionless
221
- typing-extensions==4.11.0
226
+ typing-extensions==4.12.1
222
227
  # via
223
228
  # frictionless
224
229
  # inflect
@@ -234,9 +239,9 @@ urllib3==2.2.1
234
239
  # via
235
240
  # libhxl
236
241
  # requests
237
- validators==0.28.0
242
+ validators==0.28.3
238
243
  # via frictionless
239
- virtualenv==20.25.1
244
+ virtualenv==20.26.2
240
245
  # via pre-commit
241
246
  wheel==0.43.0
242
247
  # via libhxl
@@ -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.7'
16
- __version_tuple__ = version_tuple = (6, 2, 7)
15
+ __version__ = version = '6.2.9'
16
+ __version_tuple__ = version_tuple = (6, 2, 9)
@@ -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:
@@ -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
@@ -172,7 +172,8 @@ class Resource(HDXObject):
172
172
  if configuration is None:
173
173
  configuration = Configuration.read()
174
174
  with Download(
175
- full_agent=configuration.get_user_agent()
175
+ full_agent=configuration.get_user_agent(),
176
+ use_env=False,
176
177
  ) as downloader:
177
178
  if url is None:
178
179
  url = configuration["formats_mapping_url"]
@@ -393,9 +394,10 @@ class Resource(HDXObject):
393
394
  """
394
395
  data_updated = kwargs.pop("data_updated", self.data_updated)
395
396
  if data_updated and not self.file_to_upload:
396
- self.old_data["last_modified"] = datetime.now(
397
- timezone.utc
398
- ).isoformat(timespec="microseconds")
397
+ # Should not output timezone info here
398
+ self.old_data["last_modified"] = now_utc_notz().isoformat(
399
+ timespec="microseconds"
400
+ )
399
401
  self.data_updated = False
400
402
  # old_data will be merged into data in the next step
401
403
  self._merge_hdx_update(
@@ -533,7 +535,9 @@ class Resource(HDXObject):
533
535
  else:
534
536
  headers = None
535
537
  with Download(
536
- full_agent=self.configuration.get_user_agent(), headers=headers
538
+ full_agent=self.configuration.get_user_agent(),
539
+ use_env=False,
540
+ headers=headers,
537
541
  ) as downloader:
538
542
  path = downloader.download_file(
539
543
  url, folder=folder, filename=filename
@@ -258,7 +258,9 @@ class Vocabulary(HDXObject):
258
258
  Returns:
259
259
  List[str]: List of approved tags
260
260
  """
261
- with Download(full_agent=configuration.get_user_agent()) as downloader:
261
+ with Download(
262
+ full_agent=configuration.get_user_agent(), use_env=False
263
+ ) as downloader:
262
264
  if url is None:
263
265
  url = configuration["tags_list_url"]
264
266
  return list(
@@ -402,7 +404,8 @@ class Vocabulary(HDXObject):
402
404
  if configuration is None:
403
405
  configuration = Configuration.read()
404
406
  with Download(
405
- full_agent=configuration.get_user_agent()
407
+ full_agent=configuration.get_user_agent(),
408
+ use_env=False,
406
409
  ) as downloader:
407
410
  if url is None:
408
411
  url = configuration["tags_mapping_url"]
@@ -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"}
@@ -9,7 +9,7 @@ from os.path import basename, join
9
9
 
10
10
  import pytest
11
11
 
12
- from . import MockResponse, dataset_resultdict
12
+ from . import MockResponse, dataset_resultdict, resource_data
13
13
  from .test_resource_view import resource_view_list, resource_view_mocklist
14
14
  from hdx.api.configuration import Configuration
15
15
  from hdx.data.hdxobject import HDXError
@@ -318,16 +318,6 @@ def mockresourceview(url, decodedata):
318
318
 
319
319
 
320
320
  class TestResource:
321
- resource_data = {
322
- "name": "MyResource1",
323
- "package_id": "6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d",
324
- "format": "xlsx",
325
- "url": "http://test/spreadsheet.xlsx",
326
- "description": "My Resource",
327
- "api_type": "api",
328
- "resource_type": "api",
329
- }
330
-
331
321
  datastore = None
332
322
 
333
323
  @pytest.fixture(scope="class")
@@ -685,15 +675,15 @@ class TestResource:
685
675
  Resource.read_from_hdx("ABC")
686
676
 
687
677
  def test_check_url_filetoupload(self, configuration):
688
- resource_data = copy.deepcopy(TestResource.resource_data)
689
- resource = Resource(resource_data)
678
+ resource_data_copy = copy.deepcopy(resource_data)
679
+ resource = Resource(resource_data_copy)
690
680
  resource.check_url_filetoupload()
691
681
  resource.set_file_to_upload("abc")
692
682
  resource.check_url_filetoupload()
693
683
  resource["url"] = "lala"
694
684
  with pytest.raises(HDXError):
695
685
  resource.check_url_filetoupload()
696
- resource = Resource(resource_data)
686
+ resource = Resource(resource_data_copy)
697
687
  resource["format"] = "NOTEXIST"
698
688
  with pytest.raises(HDXError):
699
689
  resource.check_url_filetoupload()
@@ -726,8 +716,8 @@ class TestResource:
726
716
  }
727
717
 
728
718
  def test_check_required_fields(self, configuration):
729
- resource_data = copy.deepcopy(TestResource.resource_data)
730
- resource = Resource(resource_data)
719
+ resource_data_copy = copy.deepcopy(resource_data)
720
+ resource = Resource(resource_data_copy)
731
721
  resource.check_url_filetoupload()
732
722
  resource.check_required_fields()
733
723
 
@@ -740,8 +730,8 @@ class TestResource:
740
730
  with pytest.raises(HDXError):
741
731
  resource.create_in_hdx()
742
732
 
743
- resource_data = copy.deepcopy(TestResource.resource_data)
744
- resource = Resource(resource_data)
733
+ resource_data_copy = copy.deepcopy(resource_data)
734
+ resource = Resource(resource_data_copy)
745
735
  resource.create_in_hdx()
746
736
  assert resource["id"] == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5"
747
737
  assert resource["url_type"] == "api"
@@ -751,8 +741,8 @@ class TestResource:
751
741
  == "https://raw.githubusercontent.com/OCHA-DAP/hdx-python-api/main/tests/fixtures/test_data.csv"
752
742
  )
753
743
 
754
- resource_data = copy.deepcopy(TestResource.resource_data)
755
- resource = Resource(resource_data)
744
+ resource_data_copy = copy.deepcopy(resource_data)
745
+ resource = Resource(resource_data_copy)
756
746
  filetoupload = join("tests", "fixtures", "test_data.csv")
757
747
  resource.set_file_to_upload(filetoupload)
758
748
  assert resource.get_file_to_upload() == filetoupload
@@ -770,13 +760,13 @@ class TestResource:
770
760
  resource["url"]
771
761
  == "http://test-data.humdata.org/dataset/6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d/resource/de6549d8-268b-4dfe-adaf-a4ae5c8510d5/download/test_data.csv"
772
762
  )
773
- resource_data["name"] = "MyResource2"
774
- resource = Resource(resource_data)
763
+ resource_data_copy["name"] = "MyResource2"
764
+ resource = Resource(resource_data_copy)
775
765
  with pytest.raises(HDXError):
776
766
  resource.create_in_hdx()
777
767
 
778
- resource_data["name"] = "MyResource3"
779
- resource = Resource(resource_data)
768
+ resource_data_copy["name"] = "MyResource3"
769
+ resource = Resource(resource_data_copy)
780
770
  with pytest.raises(HDXError):
781
771
  resource.create_in_hdx()
782
772
 
@@ -841,10 +831,10 @@ class TestResource:
841
831
  with pytest.raises(HDXError):
842
832
  resource.update_in_hdx()
843
833
 
844
- resource_data = copy.deepcopy(TestResource.resource_data)
845
- resource_data["name"] = "MyResource1"
846
- resource_data["id"] = "74b74ae1-df0c-4716-829f-4f939a046811"
847
- resource = Resource(resource_data)
834
+ resource_data_copy = copy.deepcopy(resource_data)
835
+ resource_data_copy["name"] = "MyResource1"
836
+ resource_data_copy["id"] = "74b74ae1-df0c-4716-829f-4f939a046811"
837
+ resource = Resource(resource_data_copy)
848
838
  resource.mark_data_updated()
849
839
  assert resource.data_updated is True
850
840
  assert resource.is_marked_data_updated() is True
@@ -872,8 +862,8 @@ class TestResource:
872
862
  resource.delete_from_hdx()
873
863
 
874
864
  def test_update_yaml(self, configuration, static_yaml):
875
- resource_data = copy.deepcopy(TestResource.resource_data)
876
- resource = Resource(resource_data)
865
+ resource_data_copy = copy.deepcopy(resource_data)
866
+ resource = Resource(resource_data_copy)
877
867
  assert resource["name"] == "MyResource1"
878
868
  assert resource.get_format() == "xlsx"
879
869
  resource.update_from_yaml(static_yaml)
@@ -881,8 +871,8 @@ class TestResource:
881
871
  assert resource.get_format() == "csv"
882
872
 
883
873
  def test_update_json(self, configuration, static_json):
884
- resource_data = copy.deepcopy(TestResource.resource_data)
885
- resource = Resource(resource_data)
874
+ resource_data_copy = copy.deepcopy(resource_data)
875
+ resource = Resource(resource_data_copy)
886
876
  assert resource["name"] == "MyResource1"
887
877
  assert resource.get_format() == "xlsx"
888
878
  resource.update_from_json(static_json)
@@ -898,8 +888,8 @@ class TestResource:
898
888
  assert resource["id"] == "de6549d8-268b-4dfe-adaf-a4ae5c8510d5"
899
889
 
900
890
  def test_get_dataset(self, configuration, post_dataset):
901
- resource_data = copy.deepcopy(TestResource.resource_data)
902
- resource = Resource(resource_data)
891
+ resource_data_copy = copy.deepcopy(resource_data)
892
+ resource = Resource(resource_data_copy)
903
893
  dataset = resource.get_dataset()
904
894
  assert dataset["id"] == "6f36a41c-f126-4b18-aaaf-6c2ddfbc5d4d"
905
895
  del resource["package_id"]
@@ -130,6 +130,10 @@ class TestUpdateDatasetResourcesLogic:
130
130
  ("QuickCharts-SDG 4 Global and Thematic data", "csv"),
131
131
  ]
132
132
  dataset._prepare_hdx_call(dataset.old_data, {})
133
+ assert (
134
+ dataset["updated_by_script"]
135
+ == "HDX Scraper: UNESCO (2022-12-19T12:51:30.579185)"
136
+ )
133
137
  results = dataset._revise_dataset(
134
138
  tuple(),
135
139
  resources_to_update,
File without changes
File without changes