Skip to content

Commit c32eff3

Browse files
committed
Remove unused generate_qc_resource_from_rows method, test and documentation
Use save_iterable in generate_resource_from_rows
1 parent a96c343 commit c32eff3

5 files changed

Lines changed: 46 additions & 161 deletions

File tree

documentation/index.md

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ The library has detailed API documentation which can be found in the menu at the
5454

5555

5656
## Breaking Changes
57+
From 6., remove unused `generate_qc_resource_from_rows` method.
58+
5759
From 6.5.0, files will not be uploaded to the HDX filestore if the hash and size have
5860
not changed, but if there are any resource metadata changes, except for last_modified,
5961
they will still take place.
@@ -824,16 +826,6 @@ treated as containing values:
824826
dataset.generate_resource_from_rows("FOLDER", "FILENAME", ROWS,
825827
RESOURCE DATA, HEADERS, "ENCODING")
826828

827-
A resource for the purpose of driving QuickCharts can be generated by taking
828-
ROWS, a list of dictionaries, and producing a cut down subset from it. HXLTAGS
829-
are added as the second row after the header. The reduction in rows is
830-
performed by only outputting the rows where COLUMN_NAME has a value in
831-
QC_IDENTIFIERS. Optionally the columns that are output can be limited by
832-
specifying them in HEADERS.
833-
834-
dataset.generate_qc_resource_from_rows("FOLDER", "FILENAME", ROWS,
835-
RESOURCE DATA, HXLTAGS, "COLUMN_NAME", QC_IDENTIFIERS, HEADERS, "ENCODING")
836-
837829
Building on these basic resource generation methods, there are more powerful
838830
ones `generate_resource_from_iterator` and `download_and_generate_resource`.
839831

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ dependencies = [
3737
"ckanapi>=4.8",
3838
"defopt>=7.0.0",
3939
"email_validator",
40-
"hdx-python-country>=3.9.6",
41-
"hdx-python-utilities>=3.9.1",
40+
"hdx-python-country>=3.9.8",
41+
"hdx-python-utilities>=3.9.4",
4242
"libhxl>=5.2.2",
4343
"makefun",
4444
"quantulum3",

requirements.txt

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ annotated-types==0.7.0
44
# via pydantic
55
astdoc==1.3.2
66
# via mkapi
7-
attrs==25.3.0
7+
attrs==25.4.0
88
# via
99
# frictionless
1010
# jsonlines
@@ -14,9 +14,9 @@ babel==2.17.0
1414
# via mkdocs-material
1515
backrefs==5.9
1616
# via mkdocs-material
17-
cachetools==5.5.2
17+
cachetools==6.2.0
1818
# via google-auth
19-
certifi==2025.8.3
19+
certifi==2025.10.5
2020
# via requests
2121
cfgv==3.4.0
2222
# via pre-commit
@@ -26,54 +26,53 @@ charset-normalizer==3.4.3
2626
# via requests
2727
ckanapi==4.8
2828
# via hdx-python-api (pyproject.toml)
29-
click==8.2.1
29+
click==8.3.0
3030
# via
3131
# mkdocs
32-
# mkdocs-material
3332
# typer
3433
colorama==0.4.6
3534
# via mkdocs-material
36-
coverage==7.10.6
35+
coverage==7.10.7
3736
# via pytest-cov
3837
defopt==7.0.0
3938
# via hdx-python-api (pyproject.toml)
4039
distlib==0.4.0
4140
# via virtualenv
42-
dnspython==2.7.0
41+
dnspython==2.8.0
4342
# via email-validator
4443
docopt==0.6.2
4544
# via
4645
# ckanapi
4746
# num2words
48-
docutils==0.22
47+
docutils==0.22.2
4948
# via defopt
5049
email-validator==2.3.0
5150
# via hdx-python-api (pyproject.toml)
5251
et-xmlfile==2.0.0
5352
# via openpyxl
54-
filelock==3.19.1
53+
filelock==3.20.0
5554
# via virtualenv
5655
frictionless==5.18.1
5756
# via hdx-python-utilities
5857
ghp-import==2.1.0
5958
# via mkdocs
60-
google-auth==2.40.3
59+
google-auth==2.41.1
6160
# via
6261
# google-auth-oauthlib
6362
# gspread
6463
google-auth-oauthlib==1.2.2
6564
# via gspread
6665
gspread==6.2.1
6766
# via hdx-python-api (pyproject.toml)
68-
hdx-python-country==3.9.6
67+
hdx-python-country==3.9.8
6968
# via hdx-python-api (pyproject.toml)
70-
hdx-python-utilities==3.9.1
69+
hdx-python-utilities==3.9.4
7170
# via
7271
# hdx-python-api (pyproject.toml)
7372
# hdx-python-country
7473
humanize==4.13.0
7574
# via frictionless
76-
identify==2.6.13
75+
identify==2.6.15
7776
# via pre-commit
7877
idna==3.10
7978
# via
@@ -101,7 +100,7 @@ jsonschema==4.25.1
101100
# via
102101
# frictionless
103102
# tableschema-to-template
104-
jsonschema-specifications==2025.4.1
103+
jsonschema-specifications==2025.9.1
105104
# via jsonschema
106105
libhxl==5.2.2
107106
# via
@@ -111,7 +110,7 @@ loguru==0.7.3
111110
# via hdx-python-utilities
112111
makefun==1.16.0
113112
# via hdx-python-api (pyproject.toml)
114-
markdown==3.8.2
113+
markdown==3.9
115114
# via
116115
# mkdocs
117116
# mkdocs-material
@@ -120,7 +119,7 @@ markdown-it-py==4.0.0
120119
# via rich
121120
marko==2.2.0
122121
# via frictionless
123-
markupsafe==3.0.2
122+
markupsafe==3.0.3
124123
# via
125124
# jinja2
126125
# mkdocs
@@ -138,7 +137,7 @@ mkdocs==1.6.1
138137
# mkdocs-material
139138
mkdocs-get-deps==0.2.0
140139
# via mkdocs
141-
mkdocs-material==9.6.18
140+
mkdocs-material==9.6.21
142141
# via mkapi
143142
mkdocs-material-extensions==1.3.1
144143
# via mkdocs-material
@@ -162,7 +161,7 @@ pathspec==0.12.1
162161
# via mkdocs
163162
petl==1.7.17
164163
# via frictionless
165-
platformdirs==4.4.0
164+
platformdirs==4.5.0
166165
# via
167166
# mkdocs-get-deps
168167
# virtualenv
@@ -184,9 +183,9 @@ pyasn1==0.6.1
184183
# rsa
185184
pyasn1-modules==0.4.2
186185
# via google-auth
187-
pydantic==2.11.7
186+
pydantic==2.12.0
188187
# via frictionless
189-
pydantic-core==2.33.2
188+
pydantic-core==2.41.1
190189
# via pydantic
191190
pygments==2.19.2
192191
# via
@@ -197,14 +196,14 @@ pymdown-extensions==10.16.1
197196
# via mkdocs-material
198197
pyphonetics==0.5.3
199198
# via hdx-python-utilities
200-
pytest==8.4.1
199+
pytest==8.4.2
201200
# via
202201
# hdx-python-api (pyproject.toml)
203202
# pytest-check
204203
# pytest-cov
205-
pytest-check==2.5.3
204+
pytest-check==2.6.0
206205
# via hdx-python-api (pyproject.toml)
207-
pytest-cov==6.2.1
206+
pytest-cov==7.0.0
208207
# via hdx-python-api (pyproject.toml)
209208
python-dateutil==2.9.0.post0
210209
# via
@@ -218,7 +217,7 @@ python-slugify==8.0.4
218217
# via
219218
# ckanapi
220219
# frictionless
221-
pyyaml==6.0.2
220+
pyyaml==6.0.3
222221
# via
223222
# frictionless
224223
# mkdocs
@@ -262,15 +261,15 @@ rsa==4.9.1
262261
# via google-auth
263262
ruamel-yaml==0.18.15
264263
# via hdx-python-utilities
265-
ruamel-yaml-clib==0.2.12
264+
ruamel-yaml-clib==0.2.14
266265
# via ruamel-yaml
267266
setuptools==80.9.0
268267
# via ckanapi
269268
shellingham==1.5.4
270269
# via typer
271270
simpleeval==1.0.3
272271
# via frictionless
273-
simplejson==3.20.1
272+
simplejson==3.20.2
274273
# via ckanapi
275274
six==1.17.0
276275
# via
@@ -292,7 +291,7 @@ text-unidecode==1.3
292291
# via python-slugify
293292
typeguard==4.4.4
294293
# via inflect
295-
typer==0.17.3
294+
typer==0.19.2
296295
# via frictionless
297296
typing-extensions==4.15.0
298297
# via
@@ -302,7 +301,7 @@ typing-extensions==4.15.0
302301
# typeguard
303302
# typer
304303
# typing-inspection
305-
typing-inspection==0.4.1
304+
typing-inspection==0.4.2
306305
# via pydantic
307306
unidecode==1.4.0
308307
# via
@@ -326,7 +325,7 @@ xlrd3==1.1.0
326325
# via libhxl
327326
xlsx2csv==0.8.4
328327
# via hdx-python-utilities
329-
xlsxwriter==3.2.5
328+
xlsxwriter==3.2.9
330329
# via tableschema-to-template
331330
xlwt==1.3.0
332331
# via hdx-python-utilities

src/hdx/data/dataset.py

Lines changed: 14 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@
4545
parse_date,
4646
parse_date_range,
4747
)
48-
from hdx.utilities.dictandlist import merge_two_dictionaries, write_list_to_csv
48+
from hdx.utilities.dictandlist import merge_two_dictionaries
4949
from hdx.utilities.downloader import Download
5050
from hdx.utilities.loader import load_json
5151
from hdx.utilities.path import script_dir_plus_file
52-
from hdx.utilities.saver import save_json
52+
from hdx.utilities.saver import save_iterable, save_json
5353
from hdx.utilities.typehint import ListTuple, ListTupleDict
5454
from hdx.utilities.uuid import is_valid_uuid
5555

@@ -2619,11 +2619,12 @@ def generate_resource_from_rows(
26192619
self,
26202620
folder: str,
26212621
filename: str,
2622-
rows: List[ListTupleDict],
2622+
rows: Iterable[ListTupleDict],
26232623
resourcedata: Dict,
26242624
headers: Optional[ListTuple[str]] = None,
2625+
format: str = "csv",
26252626
encoding: Optional[str] = None,
2626-
) -> "Resource":
2627+
) -> Optional["Resource"]:
26272628
"""Write rows to csv and create resource, adding it to the dataset.
26282629
The headers argument is either a row number (rows start counting at
26292630
1), or the actual headers defined as a list of strings. If not set, all
@@ -2632,72 +2633,27 @@ def generate_resource_from_rows(
26322633
Args:
26332634
folder (str): Folder to which to write file containing rows
26342635
filename (str): Filename of file to write rows
2635-
rows (List[ListTupleDict]): List of rows in dict or list form
2636+
rows (Iterable[ListTupleDict]): List of rows in dict or list form
26362637
resourcedata (Dict): Resource data
26372638
headers (Optional[ListTuple[str]]): List of headers. Defaults to None.
2639+
format (str): Format to write. Defaults to csv.
26382640
encoding (Optional[str]): Encoding to use. Defaults to None (infer encoding).
26392641
26402642
Returns:
2641-
Resource: The created resource
2643+
Optional[Resource]: The created resource or None if not created
26422644
"""
26432645
filepath = join(folder, filename)
2644-
write_list_to_csv(filepath, rows, columns=headers, encoding=encoding)
2646+
res = save_iterable(
2647+
filepath, rows, columns=headers, format=format, encoding=encoding
2648+
)
2649+
if not res:
2650+
return None
26452651
resource = res_module.Resource(resourcedata)
2646-
resource.set_format("csv")
2652+
resource.set_format(format)
26472653
resource.set_file_to_upload(filepath)
26482654
self.add_update_resource(resource)
26492655
return resource
26502656

2651-
def generate_qc_resource_from_rows(
2652-
self,
2653-
folder: str,
2654-
filename: str,
2655-
rows: List[Dict],
2656-
resourcedata: Dict,
2657-
hxltags: Dict[str, str],
2658-
columnname: str,
2659-
qc_identifiers: ListTuple[str],
2660-
headers: Optional[ListTuple[str]] = None,
2661-
encoding: Optional[str] = None,
2662-
) -> Optional["Resource"]:
2663-
"""Generate QuickCharts rows by cutting down input rows by relevant
2664-
identifiers and optionally restricting to certain columns. Output to
2665-
csv and create resource, adding it to the dataset.
2666-
2667-
Args:
2668-
folder (str): Folder to which to write file containing rows
2669-
filename (str): Filename of file to write rows
2670-
rows (List[Dict]): List of rows in dict form
2671-
resourcedata (Dict): Resource data
2672-
hxltags (Dict[str,str]): Header to HXL hashtag mapping
2673-
columnname (str): Name of column containing identifier
2674-
qc_identifiers (ListTuple[str]): List of ids to match
2675-
headers (Optional[ListTuple[str]]): List of headers to output. Defaults to None (all headers).
2676-
encoding (Optional[str]): Encoding to use. Defaults to None (infer encoding).
2677-
2678-
Returns:
2679-
Optional[Resource]: The created resource or None
2680-
"""
2681-
qc_rows = []
2682-
for row in rows:
2683-
if row[columnname] in qc_identifiers:
2684-
if headers:
2685-
qcrow = {x: row[x] for x in headers}
2686-
else:
2687-
qcrow = row
2688-
qc_rows.append(qcrow)
2689-
if len(qc_rows) == 0:
2690-
return None
2691-
qc_rows.insert(0, hxltags)
2692-
return self.generate_resource_from_rows(
2693-
folder,
2694-
filename,
2695-
qc_rows,
2696-
resourcedata,
2697-
headers=headers,
2698-
encoding=encoding,
2699-
)
2700-
27012657
def generate_resource_from_iterable(
27022658
self,
27032659
headers: ListTuple[str],

0 commit comments

Comments
 (0)