hdx-python-api 6.7.1__tar.gz → 6.7.3__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 (151) hide show
  1. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/PKG-INFO +1 -1
  2. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/documentation/index.md +115 -5
  3. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/_version.py +2 -2
  4. hdx_python_api-6.7.3/src/hdx/api/utilities/hdx_stats.py +47 -0
  5. hdx_python_api-6.7.3/src/hdx/data/activity.py +247 -0
  6. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/dataset.py +41 -0
  7. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/hdxobject.py +28 -1
  8. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/location.py +17 -0
  9. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/organization.py +17 -0
  10. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/resource.py +163 -18
  11. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/user.py +39 -1
  12. hdx_python_api-6.7.3/tests/hdx/api/utilities/test_hdx_stats.py +59 -0
  13. hdx_python_api-6.7.3/tests/hdx/data/test_activity.py +201 -0
  14. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_dataset_noncore.py +38 -0
  15. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_resource.py +210 -1
  16. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_user.py +28 -0
  17. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/.github/workflows/publish.yaml +0 -0
  18. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/.github/workflows/run-python-tests.yaml +0 -0
  19. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/.gitignore +0 -0
  20. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/.pre-commit-config.yaml +0 -0
  21. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/CLAUDE.md +0 -0
  22. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/LICENSE +0 -0
  23. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/README.md +0 -0
  24. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/documentation/.readthedocs.yaml +0 -0
  25. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/documentation/mkdocs.yaml +0 -0
  26. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/pyproject.toml +0 -0
  27. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/__init__.py +0 -0
  28. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/configuration.py +0 -0
  29. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/hdx_base_configuration.yaml +0 -0
  30. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/locations.py +0 -0
  31. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/remotehdx.py +0 -0
  32. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/utilities/__init__.py +0 -0
  33. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/utilities/date_helper.py +0 -0
  34. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/utilities/filestore_helper.py +0 -0
  35. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/utilities/hdx_error_handler.py +0 -0
  36. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/utilities/hdx_state.py +0 -0
  37. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/api/utilities/url_utils.py +0 -0
  38. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/__init__.py +0 -0
  39. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/resource_matcher.py +0 -0
  40. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/resource_view.py +0 -0
  41. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/showcase.py +0 -0
  42. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/data/vocabulary.py +0 -0
  43. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/facades/__init__.py +0 -0
  44. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/facades/infer_arguments.py +0 -0
  45. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/facades/keyword_arguments.py +0 -0
  46. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/src/hdx/facades/simple.py +0 -0
  47. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/__init__.py +0 -0
  48. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/Accepted_Tags.csv +0 -0
  49. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/CKAN/hdx_dataset_static.yaml +0 -0
  50. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/Tag_Mapping.csv +0 -0
  51. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/Tag_Mapping_ChainRuleError.csv +0 -0
  52. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/empty.yaml +0 -0
  53. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_base_config.json +0 -0
  54. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_base_config.yaml +0 -0
  55. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_config.json +0 -0
  56. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_config.yaml +0 -0
  57. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_dataset_static.json +0 -0
  58. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_dataset_static.yaml +0 -0
  59. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_datasource_topline.json +0 -0
  60. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_datasource_topline.yaml +0 -0
  61. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_email_configuration.json +0 -0
  62. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_email_configuration.yaml +0 -0
  63. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_missing_site_config.json +0 -0
  64. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_organization_static.json +0 -0
  65. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_organization_static.yaml +0 -0
  66. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_resource_static.json +0 -0
  67. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_resource_static.yaml +0 -0
  68. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_resource_view_static.json +0 -0
  69. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_resource_view_static.yaml +0 -0
  70. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_showcase_static.json +0 -0
  71. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_showcase_static.yaml +0 -0
  72. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_user_static.json +0 -0
  73. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_user_static.yaml +0 -0
  74. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_vocabulary_static.json +0 -0
  75. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/hdx_vocabulary_static.yaml +0 -0
  76. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/project_configuration.json +0 -0
  77. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/project_configuration.yaml +0 -0
  78. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/user_agent_config.yaml +0 -0
  79. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/user_agent_config2.yaml +0 -0
  80. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/user_agent_config3.yaml +0 -0
  81. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/config/user_agent_config_wrong.yaml +0 -0
  82. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/dataset_search_results.yaml +0 -0
  83. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/download_gen_resource/conflict_data_alg.csv +0 -0
  84. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/download_gen_resource/min_qc_conflict_data_alg.csv +0 -0
  85. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/download_gen_resource/qc_conflict_data_alg.csv +0 -0
  86. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/download_gen_resource/test_data_no_data.csv +0 -0
  87. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/download_gen_resource/test_data_no_years.csv +0 -0
  88. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/empty.csv +0 -0
  89. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/gen_resource/conflict_data_alg.csv +0 -0
  90. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/gen_resource/min_qc_conflict_data_alg.csv +0 -0
  91. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/gen_resource/qc_conflict_data_alg.csv +0 -0
  92. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/gen_resource/test_data_no_data.csv +0 -0
  93. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/gen_resource/test_data_no_years.csv +0 -0
  94. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/location/location_list_all_fields.yaml +0 -0
  95. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/location/location_show_results.yaml +0 -0
  96. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/organization/organization_list_all_fields.yaml +0 -0
  97. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/organization/organization_show_results.yaml +0 -0
  98. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/qc_from_rows/qc_conflict_data_alg.csv +0 -0
  99. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/qc_from_rows/qc_conflict_data_alg_one_col.csv +0 -0
  100. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/resource_formats.json +0 -0
  101. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/showcase_all_search_results.yaml +0 -0
  102. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/size_hash/ACLED-All-Africa-File_20170101-to-20170708.xlsx +0 -0
  103. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/state/analysis_dates.txt +0 -0
  104. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/state/last_build_date.txt +0 -0
  105. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/test_data.csv +0 -0
  106. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/test_data.zip +0 -0
  107. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/dem_data_zwe.csv +0 -0
  108. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/dem_indicatorlist_zwe.csv +0 -0
  109. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/expected_resources_to_update.json +0 -0
  110. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/opri_data_zwe.csv +0 -0
  111. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/opri_indicatorlist_zwe.csv +0 -0
  112. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/opri_metadata_zwe.csv +0 -0
  113. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/qc_sdg_data_zwe.csv +0 -0
  114. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/sdg_data_zwe.csv +0 -0
  115. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/sdg_indicatorlist_zwe.csv +0 -0
  116. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/sdg_metadata_zwe.csv +0 -0
  117. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/unesco_dataset.json +0 -0
  118. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_dataset_resources/unesco_update_dataset.json +0 -0
  119. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_logic/update_logic_resources.yaml +0 -0
  120. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/fixtures/update_logic/update_logic_resources_new.yaml +0 -0
  121. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/__init__.py +0 -0
  122. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/api/__init__.py +0 -0
  123. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/api/test_ckan.py +0 -0
  124. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/api/test_configuration.py +0 -0
  125. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/api/test_locations.py +0 -0
  126. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/api/utilities/__init__.py +0 -0
  127. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/api/utilities/test_filestore_helper.py +0 -0
  128. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/api/utilities/test_hdx_error_handler.py +0 -0
  129. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/api/utilities/test_hdx_state.py +0 -0
  130. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/api/utilities/test_url_utils.py +0 -0
  131. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/conftest.py +0 -0
  132. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/__init__.py +0 -0
  133. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_dataset_add_hapi_error.py +0 -0
  134. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_dataset_core.py +0 -0
  135. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_dataset_resource_generation.py +0 -0
  136. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_location.py +0 -0
  137. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_organization.py +0 -0
  138. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_resource_view.py +0 -0
  139. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_showcase.py +0 -0
  140. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_update_dataset_resources.py +0 -0
  141. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_update_logic.py +0 -0
  142. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/data/test_vocabulary.py +0 -0
  143. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/facades/__init__.py +0 -0
  144. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/facades/test_infer_arguments.py +0 -0
  145. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/facades/test_keyword_arguments.py +0 -0
  146. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/tests/hdx/facades/test_simple.py +0 -0
  147. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/uv.lock +0 -0
  148. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/workingexample/my_code.py +0 -0
  149. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/workingexample/my_resource.csv +0 -0
  150. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/workingexample/my_resource.xlsx +0 -0
  151. {hdx_python_api-6.7.1 → hdx_python_api-6.7.3}/workingexample/run.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: hdx-python-api
3
- Version: 6.7.1
3
+ Version: 6.7.3
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
@@ -35,6 +35,8 @@ upload your datasets to HDX.
35
35
  - [Organization Management](#organization-management)
36
36
  - [Location Management](#location-management)
37
37
  - [Vocabulary Management](#vocabulary-management)
38
+ - [Activity Streams](#activity-streams)
39
+ - [HDX Statistics](#hdx-statistics)
38
40
  - [Pipeline State](#pipeline-state)
39
41
  - [Working Examples](#working-examples)
40
42
  - [Project Framework](#project-framework)
@@ -635,6 +637,16 @@ function, for example:
635
637
 
636
638
  dataset.remove_showcase(showcase)
637
639
 
640
+ HDX runs file structure checks on resources, recording schema changes (eg.
641
+ column names, order or types) and whether sheets have merged cells. You can get
642
+ these checks for all of a dataset's resources from HDX:
643
+
644
+ fs_check_info = dataset.get_fs_check_info()
645
+
646
+ This returns a list of dictionaries, each from a resource name to a list of
647
+ check events with keys such as `state`, `timestamp`, `sheet_changes` and
648
+ `hxl_proxy_response`.
649
+
638
650
  ### Time Period
639
651
 
640
652
  Time Period is a mandatory field in HDX. It is the earliest start date and
@@ -946,6 +958,12 @@ If the method **set_file_to_upload** is used to supply a file, the resource
946
958
  `last_modified` field is set to now automatically regardless of the value of
947
959
  `data_updated` or whether **mark_data_updated** has been called.
948
960
 
961
+ The file structure check events of a resource (see Dataset Specific
962
+ Operations) can be obtained from its `fs_check_info` field without a call to
963
+ HDX:
964
+
965
+ events = resource.get_fs_check_info()
966
+
949
967
  ### Data Dictionary
950
968
 
951
969
  A resource can have a data dictionary describing the columns in the data it
@@ -973,11 +991,36 @@ using the getter:
973
991
 
974
992
  data_dictionary = resource.get_hdx_data_dictionary()
975
993
 
994
+ To change the data dictionary of a resource already in HDX without sending
995
+ dataset update notifications, use **update_hdx_data_dictionary**. It patches
996
+ only the `hdx_data_dictionary` field (so `last_modified` is unchanged), then,
997
+ if the resource has a datastore, updates the datastore field labels and
998
+ descriptions without reloading the data. The given columns are merged by
999
+ `field` into the existing data dictionary in the resource metadata, so read
1000
+ the resource from HDX first. Pass `replace=True` to replace the data
1001
+ dictionary instead and `update_datastore=False` to leave the datastore alone:
1002
+
1003
+ resource = Resource.read_from_hdx(RESOURCE_ID)
1004
+ resource.update_hdx_data_dictionary([
1005
+ {
1006
+ "field": "col_name",
1007
+ "label": "Column Label",
1008
+ "description": "New description.",
1009
+ },
1010
+ ])
1011
+
1012
+ Columns are matched to datastore fields by `field`. A warning is logged for
1013
+ any column with no matching datastore field.
1014
+
976
1015
  ### Datastore
977
1016
 
978
- A resource's data can be loaded into the HDX datastore and queried. HDX
979
- requires an API key for all datastore actions and dumps, including reads of
980
- public resources. To create, update or delete the datastore for a resource:
1017
+ A resource's data can be loaded into the HDX datastore and queried. HDX calls this
1018
+ [Tabular Data Endpoints (TDE)](https://docs.humdata.org/build/hdx-apis/tabular-data-endpoints),
1019
+ and it is available only for resources with TDE enabled (their `datastore_active`
1020
+ field is true). Contact hdx@un.org to request TDE for your datasets. HDX requires an
1021
+ API key for all datastore actions and dumps, including reads of public resources,
1022
+ and limits each IP address to 60 requests per minute. To create, update or delete
1023
+ the datastore for a resource:
981
1024
 
982
1025
  resource.create_datastore(
983
1026
  [{"id": "code", "type": "text"}, {"id": "value", "type": "numeric"}],
@@ -987,6 +1030,17 @@ public resources. To create, update or delete the datastore for a resource:
987
1030
  has_datastore = resource.has_datastore()
988
1031
  resource.delete_datastore()
989
1032
 
1033
+ HDX loads uploaded files into the datastore using DataPusher+. To reload a
1034
+ resource's file into the datastore without uploading it again (so
1035
+ `last_modified` is unchanged), use **submit_to_datapusher**. It returns False
1036
+ if the job was not submitted, eg. because one is already pending. HDX's
1037
+ datastore allowlist and format checks, which apply to automatic submissions
1038
+ on upload, are not applied. **get_datapusher_status** returns the status of
1039
+ the latest job or None if there is none:
1040
+
1041
+ submitted = resource.submit_to_datapusher(ignore_hash=True)
1042
+ status = resource.get_datapusher_status() # eg. status["status"] == "complete"
1043
+
990
1044
  To download the whole datastore (rather than the resource's file) use
991
1045
  **download_datastore**, which returns the URL and path like **download**.
992
1046
  `file_format` can be `csv` (default), `tsv`, `json` or `xml`, and `filename`
@@ -1007,7 +1061,8 @@ and `include_total`, and passes any other keyword arguments to CKAN:
1007
1061
  records = result["records"]
1008
1062
 
1009
1063
  **get_datastore_records** takes the same query parameters but pages through
1010
- all matching rows, yielding each record (`page_size` defaults to 10000):
1064
+ all matching rows, yielding each record (`page_size` defaults to 10000).
1065
+ `records_format` csv and tsv are not supported; use `search_datastore` for those:
1011
1066
 
1012
1067
  for record in resource.get_datastore_records(filters={"code": "A"}):
1013
1068
  ...
@@ -1019,7 +1074,9 @@ internal `_id` field:
1019
1074
 
1020
1075
  **search_datastore_sql** wraps CKAN's `datastore_search_sql`, running a
1021
1076
  SELECT statement where tables are named by double quoted resource id and
1022
- returning the list of records:
1077
+ returning the list of records. HDX returns at most 32,000 rows per query and
1078
+ cuts off larger results, in which case a warning is logged (see
1079
+ [paging in the TDE docs](https://docs.humdata.org/build/hdx-apis/tabular-data-endpoints/troubleshooting-and-error-handling#pagination)):
1023
1080
 
1024
1081
  records = Resource.search_datastore_sql(
1025
1082
  'SELECT code, SUM(value) AS total FROM "RESOURCE_ID" GROUP BY code'
@@ -1066,6 +1123,11 @@ configuration):
1066
1123
 
1067
1124
  user = User.get_current_user()
1068
1125
 
1126
+ You can get the name of the API token in the configuration and the md5 hash
1127
+ of its owner's email:
1128
+
1129
+ token_info = User.get_current_token_info() # {"email_hash": ..., "token_name": ...}
1130
+
1069
1131
  You can check that the current user has a particular permission to a specific
1070
1132
  organization:
1071
1133
 
@@ -1188,6 +1250,54 @@ If you want to add a list of tags, you do it as follows:
1188
1250
 
1189
1251
  vocabulary.add_tags(["TAG","TAG","TAG"...])
1190
1252
 
1253
+ ## Activity Streams
1254
+
1255
+ The **Activity** class wraps CKAN activities, which record who changed what and when.
1256
+ Activities are read only. You can get the activity stream of a dataset, organization,
1257
+ location or user:
1258
+
1259
+ activities = dataset.get_activities(**kwargs)
1260
+ activities = organization.get_activities(**kwargs)
1261
+ activities = location.get_activities(**kwargs)
1262
+ activities = user.get_activities(**kwargs)
1263
+
1264
+ These return a list of **Activity** objects, each with fields like `timestamp`,
1265
+ `user_id`, `object_id` and `activity_type` (eg. "changed package"). One page of results
1266
+ is returned. Its size is set by `limit` (default 31, HDX maximum 100) and where it starts
1267
+ by `offset`. Passing `all_pages=True` gets every page. Other arguments (`**kwargs`) like
1268
+ `after`, `before` and `activity_types` depend on the object type and are detailed in the
1269
+ API documentation. Getting a user's activity stream requires authorisation to view the
1270
+ user's profile.
1271
+
1272
+ You can get the activity stream of all recently added or changed datasets:
1273
+
1274
+ activities = Activity.get_recently_changed_packages(limit=10)
1275
+
1276
+ With `all_pages=True`, this stream covers the whole history of HDX so it is capped by
1277
+ `max_activities` (default 1000). Pass `max_activities=None` to remove the cap.
1278
+
1279
+ You can read a single activity, get its data (including a snapshot of the object at the
1280
+ time of the activity) or get a diff against the object's previous version. HDX requires
1281
+ permission to edit the object the activity relates to for these:
1282
+
1283
+ activity = Activity.read_from_hdx("ACTIVITY_ID")
1284
+ data = activity.get_data()
1285
+ diff = activity.get_diff(diff_type="unified") # or "context" or "html"
1286
+
1287
+ ## HDX Statistics
1288
+
1289
+ General statistics about datasets, organizations and users on HDX can be
1290
+ obtained as follows:
1291
+
1292
+ from hdx.api.utilities.hdx_stats import get_general_statistics, push_general_stats
1293
+
1294
+ stats = get_general_statistics()
1295
+
1296
+ Users with permission to manage basic scheduled tasks can compute the statistics
1297
+ and push them to analytics:
1298
+
1299
+ pushed_stats = push_general_stats()
1300
+
1191
1301
  ## Pipeline State
1192
1302
 
1193
1303
  The HDXState class allows the reading and writing of state to a given dataset. Input
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '6.7.1'
22
- __version_tuple__ = version_tuple = (6, 7, 1)
21
+ __version__ = version = '6.7.3'
22
+ __version_tuple__ = version_tuple = (6, 7, 3)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -0,0 +1,47 @@
1
+ """HDX site-wide statistics"""
2
+
3
+ from hdx.api.configuration import Configuration
4
+ from hdx.data.hdxobject import HDXError
5
+
6
+
7
+ def _call_stats_action(action: str, configuration: Configuration | None) -> dict:
8
+ """Call an HDX statistics action
9
+
10
+ Args:
11
+ action: CKAN action name
12
+ configuration: HDX configuration. Defaults to global configuration.
13
+
14
+ Returns:
15
+ Statistics dictionary
16
+ """
17
+ if configuration is None:
18
+ configuration = Configuration.read()
19
+ try:
20
+ return configuration.call_remoteckan(action, {})
21
+ except Exception as e:
22
+ raise HDXError(f"Failed when trying to call {action}!") from e
23
+
24
+
25
+ def get_general_statistics(configuration: Configuration | None = None) -> dict:
26
+ """Get general statistics about datasets, organizations and users on HDX
27
+
28
+ Args:
29
+ configuration: HDX configuration. Defaults to global configuration.
30
+
31
+ Returns:
32
+ Dictionary with keys datasets, organizations and users
33
+ """
34
+ return _call_stats_action("hdx_general_statistics", configuration)
35
+
36
+
37
+ def push_general_stats(configuration: Configuration | None = None) -> dict:
38
+ """Compute general statistics on HDX and push them to analytics. Requires
39
+ permission to manage basic scheduled tasks.
40
+
41
+ Args:
42
+ configuration: HDX configuration. Defaults to global configuration.
43
+
44
+ Returns:
45
+ Statistics that were pushed
46
+ """
47
+ return _call_stats_action("hdx_push_general_stats", configuration)
@@ -0,0 +1,247 @@
1
+ """Activity class containing all logic for reading activity streams."""
2
+
3
+ import logging
4
+ from collections.abc import Sequence
5
+ from typing import Any, Optional
6
+
7
+ from hdx.api.configuration import Configuration
8
+ from hdx.data.hdxobject import HDXError, HDXObject
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+
13
+ class Activity(HDXObject):
14
+ """Activity class containing all logic for reading activity streams. Activities
15
+ are read only.
16
+
17
+ Args:
18
+ initial_data: Initial activity metadata dictionary. Defaults to None.
19
+ configuration: HDX configuration. Defaults to global configuration.
20
+ """
21
+
22
+ def __init__(
23
+ self,
24
+ initial_data: dict | None = None,
25
+ configuration: Configuration | None = None,
26
+ ) -> None:
27
+ if not initial_data:
28
+ initial_data = {}
29
+ super().__init__(initial_data, configuration=configuration)
30
+
31
+ @staticmethod
32
+ def actions() -> dict[str, str]:
33
+ """Dictionary of actions that can be performed on object
34
+
35
+ Returns:
36
+ Dictionary of actions that can be performed on object
37
+ """
38
+ return {
39
+ "show": "activity_show",
40
+ "data_show": "activity_data_show",
41
+ "diff": "activity_diff",
42
+ "package_list": "package_activity_list",
43
+ "organization_list": "organization_activity_list",
44
+ "group_list": "group_activity_list",
45
+ "user_list": "user_activity_list",
46
+ "recently_changed_packages": "recently_changed_packages_activity_list",
47
+ }
48
+
49
+ @classmethod
50
+ def read_from_hdx(
51
+ cls, identifier: str, configuration: Configuration | None = None
52
+ ) -> Optional["Activity"]:
53
+ """Reads the activity given by identifier from HDX and returns Activity object.
54
+ HDX requires permission to edit the object the activity relates to.
55
+
56
+ Args:
57
+ identifier: Identifier of activity
58
+ configuration: HDX configuration. Defaults to global configuration.
59
+
60
+ Returns:
61
+ Activity object if successful read, None if not
62
+ """
63
+ return cls._read_from_hdx_class("activity", identifier, configuration)
64
+
65
+ def get_object_type(self) -> str:
66
+ """Get the CKAN object type the activity relates to eg. package,
67
+ organization, group or user. This is the last word of the activity type
68
+ (eg. "changed package") with "dataset" (from "follow dataset") mapped to
69
+ "package".
70
+
71
+ Returns:
72
+ Object type
73
+ """
74
+ object_type = self.data["activity_type"].split(" ")[-1]
75
+ if object_type == "dataset":
76
+ return "package"
77
+ return object_type
78
+
79
+ def get_data(self) -> dict:
80
+ """Get the data of the activity which includes a snapshot of the object
81
+ at the time of the activity. HDX requires permission to edit the object
82
+ the activity relates to.
83
+
84
+ Returns:
85
+ Activity data
86
+ """
87
+ return self._write_to_hdx("data_show", {"id": self.data["id"]}, "id")
88
+
89
+ def get_diff(self, diff_type: str = "unified") -> dict:
90
+ """Get a diff of the object compared to its previous version. HDX requires
91
+ permission to edit the object the activity relates to.
92
+
93
+ Args:
94
+ diff_type: One of unified, context or html. Defaults to unified.
95
+
96
+ Returns:
97
+ Activity diff
98
+ """
99
+ data = {
100
+ "id": self.data["id"],
101
+ "object_type": self.get_object_type(),
102
+ "diff_type": diff_type,
103
+ }
104
+ return self._write_to_hdx("diff", data, "id")
105
+
106
+ @classmethod
107
+ def _get_list(
108
+ cls,
109
+ action: str,
110
+ data: dict,
111
+ configuration: Configuration | None = None,
112
+ all_pages: bool = False,
113
+ max_activities: int | None = None,
114
+ ) -> list["Activity"]:
115
+ """Helper method to get a list of activities from HDX
116
+
117
+ Args:
118
+ action: Action to perform
119
+ data: Data to pass to CKAN including any offset and limit
120
+ configuration: HDX configuration. Defaults to global configuration.
121
+ all_pages: Whether to get all pages of results. Defaults to False.
122
+ max_activities: Maximum number of activities if all_pages is True. Defaults to None (no maximum).
123
+
124
+ Returns:
125
+ List of Activity objects
126
+ """
127
+ activity = cls(configuration=configuration)
128
+ if not all_pages:
129
+ result = activity._write_to_hdx(action, data)
130
+ return [cls(x, configuration=configuration) for x in result]
131
+ data = dict(data)
132
+ # HDX silently caps limit at ckan.activity_list_limit_max
133
+ limit = min(data.get("limit", 100), 100)
134
+ data["limit"] = limit
135
+ offset = data.get("offset", 0)
136
+ activities = []
137
+ while True:
138
+ data["offset"] = offset
139
+ result = activity._write_to_hdx(action, data)
140
+ activities.extend(cls(x, configuration=configuration) for x in result)
141
+ if max_activities is not None and len(activities) >= max_activities:
142
+ return activities[:max_activities]
143
+ if len(result) < limit:
144
+ return activities
145
+ offset += limit
146
+
147
+ @classmethod
148
+ def get_activities(
149
+ cls,
150
+ object_type: str,
151
+ identifier: str,
152
+ configuration: Configuration | None = None,
153
+ all_pages: bool = False,
154
+ **kwargs: Any,
155
+ ) -> list["Activity"]:
156
+ """Get the activity stream of a CKAN object. One page of results (whose
157
+ size is given by limit) is returned unless all_pages is True.
158
+
159
+ Args:
160
+ object_type: One of package, organization, group or user
161
+ identifier: Id or name of object
162
+ configuration: HDX configuration. Defaults to global configuration.
163
+ all_pages: Whether to get all pages of results. Defaults to False.
164
+ **kwargs: See below
165
+ offset (int): Where to start getting activity items from. Defaults to 0.
166
+ limit (int): Maximum number of activities per page. Defaults to 31 (HDX maximum 100) or 100 if all_pages is True.
167
+ after (int | str): Only activities after this timestamp (package and user only)
168
+ before (int | str): Only activities before this timestamp (package and user only)
169
+ include_hidden_activity (bool): Include hidden activity, sysadmins only (package, organization and group only)
170
+ activity_types (list): Activity types to include (package only)
171
+ exclude_activity_types (list): Activity types to exclude (package only)
172
+
173
+ Returns:
174
+ List of Activity objects
175
+ """
176
+ if not identifier:
177
+ raise HDXError(f"No id or name for {object_type} to get activities!")
178
+ data = {"id": identifier}
179
+ data.update(kwargs)
180
+ return cls._get_list(f"{object_type}_list", data, configuration, all_pages)
181
+
182
+ @classmethod
183
+ def get_recently_changed_packages(
184
+ cls,
185
+ configuration: Configuration | None = None,
186
+ all_pages: bool = False,
187
+ max_activities: int | None = 1000,
188
+ **kwargs: Any,
189
+ ) -> list["Activity"]:
190
+ """Get the activity stream of all recently added or changed datasets.
191
+ One page of results (whose size is given by limit) is returned unless
192
+ all_pages is True. all_pages is capped by max_activities because the
193
+ stream covers the whole history of HDX.
194
+
195
+ Args:
196
+ configuration: HDX configuration. Defaults to global configuration.
197
+ all_pages: Whether to get all pages of results. Defaults to False.
198
+ max_activities: Maximum number of activities if all_pages is True. Defaults to 1000. None means no maximum (very slow).
199
+ **kwargs: See below
200
+ offset (int): Where to start getting activity items from. Defaults to 0.
201
+ limit (int): Maximum number of activities per page. Defaults to 31 (HDX maximum 100) or 100 if all_pages is True.
202
+
203
+ Returns:
204
+ List of Activity objects
205
+ """
206
+ return cls._get_list(
207
+ "recently_changed_packages",
208
+ kwargs,
209
+ configuration,
210
+ all_pages,
211
+ max_activities,
212
+ )
213
+
214
+ def check_required_fields(self, ignore_fields: Sequence[str] = ()) -> None:
215
+ """Activities are read only so this raises an exception
216
+
217
+ Args:
218
+ ignore_fields: Fields to ignore. Default is ().
219
+
220
+ Returns:
221
+ None
222
+ """
223
+ raise HDXError("Activities are read only!")
224
+
225
+ def update_in_hdx(self, **kwargs: Any) -> None:
226
+ """Activities are read only so this raises an exception
227
+
228
+ Returns:
229
+ None
230
+ """
231
+ raise HDXError("Activities are read only!")
232
+
233
+ def create_in_hdx(self, **kwargs: Any) -> None:
234
+ """Activities are read only so this raises an exception
235
+
236
+ Returns:
237
+ None
238
+ """
239
+ raise HDXError("Activities are read only!")
240
+
241
+ def delete_from_hdx(self) -> None:
242
+ """Activities are read only so this raises an exception
243
+
244
+ Returns:
245
+ None
246
+ """
247
+ raise HDXError("Activities are read only!")
@@ -40,6 +40,7 @@ from hdx.api.configuration import Configuration
40
40
  from hdx.api.locations import Locations
41
41
  from hdx.api.utilities.date_helper import DateHelper
42
42
  from hdx.api.utilities.filestore_helper import FilestoreHelper
43
+ from hdx.data.activity import Activity
43
44
  from hdx.data.hdxobject import HDXError, HDXObject
44
45
  from hdx.data.resource_matcher import ResourceMatcher
45
46
 
@@ -146,6 +147,7 @@ class Dataset(HDXObject):
146
147
  "list": "package_list",
147
148
  "autocomplete": "package_autocomplete",
148
149
  "create_default_views": "package_create_default_resource_views",
150
+ "fs_check_info": "fs_check_info_show",
149
151
  }
150
152
 
151
153
  def __setitem__(self, key: Any, value: Any) -> None:
@@ -1428,6 +1430,26 @@ class Dataset(HDXObject):
1428
1430
  resources.append(resource)
1429
1431
  return resources
1430
1432
 
1433
+ def get_activities(self, all_pages: bool = False, **kwargs: Any) -> list[Activity]:
1434
+ """Get the activity stream of this dataset. One page of results (whose size
1435
+ is given by limit) is returned unless all_pages is True.
1436
+
1437
+ Args:
1438
+ all_pages: Whether to get all pages of results. Defaults to False.
1439
+ **kwargs: See below
1440
+ offset (int): Where to start getting activity items from. Defaults to 0.
1441
+ limit (int): Maximum number of activities per page. Defaults to 31 (HDX maximum 100) or 100 if all_pages is True.
1442
+ after (int | str): Only activities after this timestamp
1443
+ before (int | str): Only activities before this timestamp
1444
+ include_hidden_activity (bool): Include hidden activity (sysadmins only)
1445
+ activity_types (list): Activity types to include
1446
+ exclude_activity_types (list): Activity types to exclude
1447
+
1448
+ Returns:
1449
+ List of Activity objects
1450
+ """
1451
+ return self._get_activities("package", all_pages, **kwargs)
1452
+
1431
1453
  @classmethod
1432
1454
  def autocomplete(
1433
1455
  cls,
@@ -2306,6 +2328,25 @@ class Dataset(HDXObject):
2306
2328
  return None
2307
2329
  return f"{self.configuration.get_hdx_site_url()}/api/3/action/package_show?id={name_or_id}"
2308
2330
 
2331
+ def get_fs_check_info(self) -> list[dict]:
2332
+ """Get file structure check information for the dataset's resources
2333
+ from HDX. Each list item is a dictionary from resource name to a list
2334
+ of check events, each of which can have keys such as state, timestamp,
2335
+ sheet_changes and hxl_proxy_response.
2336
+
2337
+ Returns:
2338
+ List of dictionaries from resource name to file structure checks
2339
+ """
2340
+ success, result = self._read_from_hdx(
2341
+ "dataset",
2342
+ self.get_name_or_id(prefer_name=False),
2343
+ "id",
2344
+ self.actions()["fs_check_info"],
2345
+ )
2346
+ if success:
2347
+ return result
2348
+ return []
2349
+
2309
2350
  def generate_resource(
2310
2351
  self,
2311
2352
  folder: Path | str,
@@ -9,7 +9,7 @@ from collections import UserDict
9
9
  from collections.abc import Sequence
10
10
  from os.path import isfile
11
11
  from pathlib import Path
12
- from typing import Any, Optional, Union
12
+ from typing import TYPE_CHECKING, Any, Optional, Union
13
13
 
14
14
  from ckanapi.errors import NotFound
15
15
  from hdx.utilities.dictandlist import merge_two_dictionaries
@@ -20,6 +20,9 @@ from hdx.utilities.loader import (
20
20
 
21
21
  from hdx.api.configuration import Configuration
22
22
 
23
+ if TYPE_CHECKING:
24
+ from hdx.data.activity import Activity
25
+
23
26
  logger = logging.getLogger(__name__)
24
27
 
25
28
 
@@ -376,6 +379,30 @@ class HDXObject(UserDict, ABC):
376
379
  **kwargs,
377
380
  )
378
381
 
382
+ def _get_activities(
383
+ self, object_type: str, all_pages: bool = False, **kwargs: Any
384
+ ) -> list["Activity"]:
385
+ """Helper method to get the activity stream of this object
386
+
387
+ Args:
388
+ object_type: One of package, organization, group or user
389
+ all_pages: Whether to get all pages of results. Defaults to False.
390
+ **kwargs: Parameters to pass to Activity.get_activities
391
+
392
+ Returns:
393
+ List of Activity objects
394
+ """
395
+ # Imported here as hdx.data.activity imports this module
396
+ from hdx.data.activity import Activity
397
+
398
+ return Activity.get_activities(
399
+ object_type,
400
+ self.data.get("id") or self.data.get("name"),
401
+ self.configuration,
402
+ all_pages,
403
+ **kwargs,
404
+ )
405
+
379
406
  def _write_to_hdx(
380
407
  self,
381
408
  action: str,
@@ -5,6 +5,7 @@ from collections.abc import Sequence
5
5
  from typing import Any, Optional
6
6
 
7
7
  from hdx.api.configuration import Configuration
8
+ from hdx.data.activity import Activity
8
9
  from hdx.data.hdxobject import HDXObject
9
10
 
10
11
  logger = logging.getLogger(__name__)
@@ -217,6 +218,22 @@ class Location(HDXObject):
217
218
  if len(group["name"]) == 3 and group.get("data_completeness") == "active"
218
219
  )
219
220
 
221
+ def get_activities(self, all_pages: bool = False, **kwargs: Any) -> list[Activity]:
222
+ """Get the activity stream of this location. One page of results (whose size
223
+ is given by limit) is returned unless all_pages is True.
224
+
225
+ Args:
226
+ all_pages: Whether to get all pages of results. Defaults to False.
227
+ **kwargs: See below
228
+ offset (int): Where to start getting activity items from. Defaults to 0.
229
+ limit (int): Maximum number of activities per page. Defaults to 31 (HDX maximum 100) or 100 if all_pages is True.
230
+ include_hidden_activity (bool): Include hidden activity (sysadmins only)
231
+
232
+ Returns:
233
+ List of Activity objects
234
+ """
235
+ return self._get_activities("group", all_pages, **kwargs)
236
+
220
237
  @classmethod
221
238
  def autocomplete(
222
239
  cls,
@@ -8,6 +8,7 @@ from typing import TYPE_CHECKING, Any, Optional, Union
8
8
  import hdx.data.dataset
9
9
  import hdx.data.user as user_module
10
10
  from hdx.api.configuration import Configuration
11
+ from hdx.data.activity import Activity
11
12
  from hdx.data.hdxobject import HDXError, HDXObject
12
13
 
13
14
  if TYPE_CHECKING:
@@ -311,6 +312,22 @@ class Organization(HDXObject):
311
312
 
312
313
  return final_orgs
313
314
 
315
+ def get_activities(self, all_pages: bool = False, **kwargs: Any) -> list[Activity]:
316
+ """Get the activity stream of this organization. One page of results (whose size
317
+ is given by limit) is returned unless all_pages is True.
318
+
319
+ Args:
320
+ all_pages: Whether to get all pages of results. Defaults to False.
321
+ **kwargs: See below
322
+ offset (int): Where to start getting activity items from. Defaults to 0.
323
+ limit (int): Maximum number of activities per page. Defaults to 31 (HDX maximum 100) or 100 if all_pages is True.
324
+ include_hidden_activity (bool): Include hidden activity (sysadmins only)
325
+
326
+ Returns:
327
+ List of Activity objects
328
+ """
329
+ return self._get_activities("organization", all_pages, **kwargs)
330
+
314
331
  @classmethod
315
332
  def autocomplete(
316
333
  cls,