technologydata 0.2.1__tar.gz → 0.3.0__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 (165) hide show
  1. technologydata-0.3.0/.claude/settings.json +13 -0
  2. technologydata-0.3.0/.claude/settings.json.license +3 -0
  3. technologydata-0.3.0/.claude/skills/dataset-factsheet/SKILL.md +110 -0
  4. {technologydata-0.2.1 → technologydata-0.3.0}/.codespell.ignore +2 -0
  5. technologydata-0.3.0/.github/CODEOWNERS +23 -0
  6. technologydata-0.3.0/.github/PULL_REQUEST_TEMPLATE.md +18 -0
  7. technologydata-0.3.0/.github/dependabot.yml +18 -0
  8. technologydata-0.3.0/.github/release.yml +20 -0
  9. {technologydata-0.2.1 → technologydata-0.3.0}/.github/workflows/ci.yaml +5 -3
  10. technologydata-0.3.0/.github/workflows/codeql.yml +50 -0
  11. technologydata-0.3.0/.github/workflows/docs.yml +52 -0
  12. technologydata-0.3.0/.github/workflows/link-check.yml +29 -0
  13. {technologydata-0.2.1 → technologydata-0.3.0}/.github/workflows/release.yml +12 -13
  14. technologydata-0.3.0/.github/workflows/scorecard.yml +60 -0
  15. {technologydata-0.2.1 → technologydata-0.3.0}/.gitignore +6 -0
  16. technologydata-0.3.0/.lychee.toml +27 -0
  17. {technologydata-0.2.1 → technologydata-0.3.0}/.pre-commit-config.yaml +9 -9
  18. technologydata-0.3.0/AGENTS.md +114 -0
  19. {technologydata-0.2.1 → technologydata-0.3.0}/CITATIONS.cff +1 -1
  20. {technologydata-0.2.1 → technologydata-0.3.0}/MANIFEST.in +4 -2
  21. {technologydata-0.2.1 → technologydata-0.3.0}/PKG-INFO +8 -4
  22. {technologydata-0.2.1 → technologydata-0.3.0}/README.md +2 -2
  23. {technologydata-0.2.1 → technologydata-0.3.0}/REUSE.toml +3 -3
  24. technologydata-0.3.0/SECURITY.md +44 -0
  25. technologydata-0.3.0/docs/api/data_accessor.md +1 -0
  26. technologydata-0.3.0/docs/api/equations.md +3 -0
  27. technologydata-0.3.0/docs/assets/overrides/hooks/release_notes.py +71 -0
  28. {technologydata-0.2.1 → technologydata-0.3.0}/docs/contributing/CODE_OF_CONDUCT.md +1 -1
  29. technologydata-0.3.0/docs/contributing/adding_a_dataset.md +204 -0
  30. technologydata-0.3.0/docs/contributing/improvement_backlog.md +153 -0
  31. {technologydata-0.2.1 → technologydata-0.3.0}/docs/contributing/instructions.md +9 -8
  32. technologydata-0.3.0/docs/contributing/release_process.md +123 -0
  33. technologydata-0.3.0/docs/contributing/writing_a_parser.md +92 -0
  34. technologydata-0.3.0/docs/datasets/dea_energy_storage.md +202 -0
  35. technologydata-0.3.0/docs/datasets/index.md +22 -0
  36. technologydata-0.3.0/docs/datasets/legacy_input_data.md +334 -0
  37. technologydata-0.3.0/docs/home/faq.md +24 -0
  38. technologydata-0.3.0/docs/home/release-notes.md +9 -0
  39. technologydata-0.3.0/docs/index.md +160 -0
  40. technologydata-0.3.0/docs/overview.md +237 -0
  41. technologydata-0.3.0/docs/tutorial/index.md +303 -0
  42. {technologydata-0.2.1 → technologydata-0.3.0}/docs/user_guide/class-diagram.puml +1 -1
  43. technologydata-0.3.0/docs/user_guide/data_accessor.md +187 -0
  44. {technologydata-0.2.1 → technologydata-0.3.0}/docs/user_guide/datapackage.md +52 -6
  45. {technologydata-0.2.1 → technologydata-0.3.0}/docs/user_guide/design.md +21 -1
  46. technologydata-0.3.0/docs/user_guide/equations.md +428 -0
  47. {technologydata-0.2.1 → technologydata-0.3.0}/docs/user_guide/parameter.md +28 -13
  48. {technologydata-0.2.1 → technologydata-0.3.0}/docs/user_guide/source.md +4 -4
  49. {technologydata-0.2.1 → technologydata-0.3.0}/docs/user_guide/source_collection.md +5 -10
  50. technologydata-0.3.0/docs/user_guide/technology.md +211 -0
  51. {technologydata-0.2.1 → technologydata-0.3.0}/docs/user_guide/technology_collection.md +41 -14
  52. {technologydata-0.2.1 → technologydata-0.3.0}/mkdocs.yaml +19 -14
  53. {technologydata-0.2.1 → technologydata-0.3.0}/pyproject.toml +11 -13
  54. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/__init__.py +12 -1
  55. technologydata-0.3.0/src/technologydata/data_accessor.py +415 -0
  56. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/datapackage.py +35 -2
  57. technologydata-0.3.0/src/technologydata/default_equations.py +41 -0
  58. technologydata-0.3.0/src/technologydata/equations.py +741 -0
  59. technologydata-0.3.0/src/technologydata/equations_data/default_equations.schema.json +42 -0
  60. technologydata-0.3.0/src/technologydata/equations_data/default_equations.schema.json.license +3 -0
  61. technologydata-0.3.0/src/technologydata/equations_data/default_equations.yaml +49 -0
  62. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/parameter.py +230 -34
  63. technologydata-0.3.0/src/technologydata/parsers/__init__.py +5 -0
  64. technologydata-0.3.0/src/technologydata/parsers/commons.py +398 -0
  65. technologydata-0.3.0/src/technologydata/parsers/data_parser_base.py +41 -0
  66. technologydata-0.3.0/src/technologydata/parsers/dea_energy_storage/__init__.py +93 -0
  67. technologydata-0.3.0/src/technologydata/parsers/dea_energy_storage/parser_v10.py +683 -0
  68. {technologydata-0.2.1/src/technologydata/parsers/dea_energy_storage → technologydata-0.3.0/src/technologydata/parsers/dea_energy_storage/v10}/sources.json +2 -0
  69. {technologydata-0.2.1/src/technologydata/parsers/dea_energy_storage → technologydata-0.3.0/src/technologydata/parsers/dea_energy_storage/v10}/technologies.json +3257 -814
  70. technologydata-0.3.0/src/technologydata/parsers/legacy_input_data/__init__.py +94 -0
  71. technologydata-0.3.0/src/technologydata/parsers/legacy_input_data/parser_v0134.py +560 -0
  72. technologydata-0.3.0/src/technologydata/parsers/legacy_input_data/v0.13.4/sources.json +23 -0
  73. technologydata-0.3.0/src/technologydata/parsers/legacy_input_data/v0.13.4/technologies.json +19097 -0
  74. technologydata-0.3.0/src/technologydata/parsers/raw/legacy_input_data/other.csv +622 -0
  75. technologydata-0.3.0/src/technologydata/schema_version.py +48 -0
  76. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/source.py +3 -0
  77. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/source_collection.py +36 -10
  78. technologydata-0.3.0/src/technologydata/technology.py +387 -0
  79. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/technology_collection.py +233 -14
  80. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/utils/carriers.txt +15 -1
  81. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/utils/commons.py +1 -1
  82. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata.egg-info/PKG-INFO +8 -4
  83. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata.egg-info/SOURCES.txt +56 -16
  84. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata.egg-info/requires.txt +5 -1
  85. technologydata-0.3.0/src/technologydata.egg-info/scm_file_list.json +141 -0
  86. technologydata-0.3.0/src/technologydata.egg-info/scm_version.json +8 -0
  87. {technologydata-0.2.1 → technologydata-0.3.0}/test/conftest.py +26 -2
  88. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_data/solar_photovoltaics_example/sources.json +3 -0
  89. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_data/solar_photovoltaics_example/technologies.json +51 -10
  90. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_datapackage.py +4 -0
  91. technologydata-0.2.1/test/test_dea_energy_storage.py → technologydata-0.3.0/test/test_dea_energy_storage_v10.py +18 -21
  92. technologydata-0.3.0/test/test_docs.py +54 -0
  93. technologydata-0.3.0/test/test_equations.py +1175 -0
  94. technologydata-0.3.0/test/test_legacy_parser_v0134.py +103 -0
  95. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_parameter.py +252 -13
  96. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_parser_commons.py +16 -4
  97. technologydata-0.3.0/test/test_parser_data_accessor.py +171 -0
  98. technologydata-0.3.0/test/test_schema_version.py +122 -0
  99. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_source_collection.py +32 -0
  100. technologydata-0.3.0/test/test_technology.py +554 -0
  101. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_technology_collection.py +294 -0
  102. technologydata-0.3.0/uv.lock +3287 -0
  103. technologydata-0.2.1/.github/instructions/copilot-instructions.md +0 -44
  104. technologydata-0.2.1/docs/examples/dea_storage.md +0 -84
  105. technologydata-0.2.1/docs/examples/manual_input_usa.md +0 -78
  106. technologydata-0.2.1/docs/home/citing.md +0 -11
  107. technologydata-0.2.1/docs/home/contacts.md +0 -7
  108. technologydata-0.2.1/docs/home/faq.md +0 -26
  109. technologydata-0.2.1/docs/home/installation.md +0 -15
  110. technologydata-0.2.1/docs/home/release-notes.md +0 -16
  111. technologydata-0.2.1/docs/home/users.md +0 -25
  112. technologydata-0.2.1/docs/index.md +0 -16
  113. technologydata-0.2.1/docs/user_guide/technology.md +0 -136
  114. technologydata-0.2.1/src/technologydata/parsers/commons.py +0 -136
  115. technologydata-0.2.1/src/technologydata/parsers/dea_energy_storage/dea_energy_storage.py +0 -658
  116. technologydata-0.2.1/src/technologydata/parsers/manual_input_usa/manual_input_usa.py +0 -256
  117. technologydata-0.2.1/src/technologydata/parsers/manual_input_usa/sources.json +0 -12
  118. technologydata-0.2.1/src/technologydata/parsers/manual_input_usa/technologies.json +0 -4149
  119. technologydata-0.2.1/src/technologydata/technology.py +0 -191
  120. technologydata-0.2.1/test/test_technology.py +0 -271
  121. technologydata-0.2.1/uv.lock +0 -3453
  122. {technologydata-0.2.1 → technologydata-0.3.0}/.readthedocs.yaml +0 -0
  123. {technologydata-0.2.1 → technologydata-0.3.0}/CONTRIBUTING.md +0 -0
  124. {technologydata-0.2.1 → technologydata-0.3.0}/LICENSE +0 -0
  125. {technologydata-0.2.1 → technologydata-0.3.0}/LICENSES/CC-BY-4.0.txt +0 -0
  126. {technologydata-0.2.1 → technologydata-0.3.0}/LICENSES/MIT.txt +0 -0
  127. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/commons/commons.md +0 -0
  128. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/commons/dateformatenum.md +0 -0
  129. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/commons/fileextensionenum.md +0 -0
  130. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/datapackage.md +0 -0
  131. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/parameter.md +0 -0
  132. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/source.md +0 -0
  133. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/source_collection.md +0 -0
  134. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/technology.md +0 -0
  135. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/technology_collection.md +0 -0
  136. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/units/customundefineduniterror.md +0 -0
  137. {technologydata-0.2.1 → technologydata-0.3.0}/docs/api/units/specialunitregistry.md +0 -0
  138. {technologydata-0.2.1 → technologydata-0.3.0}/docs/assets/extensions/dynamic_inspect.py +0 -0
  139. {technologydata-0.2.1 → technologydata-0.3.0}/docs/assets/javascripts/matjax.js +0 -0
  140. {technologydata-0.2.1 → technologydata-0.3.0}/docs/assets/javascripts/readthedocs.js +0 -0
  141. {technologydata-0.2.1 → technologydata-0.3.0}/docs/assets/logo/technology_data_logo.png +0 -0
  142. {technologydata-0.2.1 → technologydata-0.3.0}/docs/assets/overrides/hooks/shortcodes.py +0 -0
  143. {technologydata-0.2.1 → technologydata-0.3.0}/docs/assets/stylesheets/extra.css +0 -0
  144. {technologydata-0.2.1 → technologydata-0.3.0}/docs/contributing/contributors.md +0 -0
  145. {technologydata-0.2.1 → technologydata-0.3.0}/docs/home/license.md +0 -0
  146. {technologydata-0.2.1 → technologydata-0.3.0}/docs/user_guide/models.md +0 -0
  147. {technologydata-0.2.1 → technologydata-0.3.0}/setup.cfg +0 -0
  148. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/constants/__init__.py +0 -0
  149. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/constants/energy_density.py +0 -0
  150. {technologydata-0.2.1/src/technologydata/parsers/raw → technologydata-0.3.0/src/technologydata/parsers/raw/dea_energy_storage}/Technology_datasheet_for_energy_storage.xlsx +0 -0
  151. /technologydata-0.2.1/src/technologydata/parsers/raw/manual_input_usa.csv → /technologydata-0.3.0/src/technologydata/parsers/raw/legacy_input_data/usa.csv +0 -0
  152. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/technologies/__init__.py +0 -0
  153. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/technologies/growth_models.py +0 -0
  154. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/utils/__init__.py +0 -0
  155. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/utils/heating_values.txt +0 -0
  156. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata/utils/units.py +0 -0
  157. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata.egg-info/dependency_links.txt +0 -0
  158. {technologydata-0.2.1 → technologydata-0.3.0}/src/technologydata.egg-info/top_level.txt +0 -0
  159. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_commons.py +0 -0
  160. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_data/currency_conversion/WB_CNY_2020/parameters.csv +0 -0
  161. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_data/currency_conversion/WB_EUR_2020/parameters.csv +0 -0
  162. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_data/currency_conversion/WB_USD_2020/parameters.csv +0 -0
  163. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_growth_models.py +0 -0
  164. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_source.py +0 -0
  165. {technologydata-0.2.1 → technologydata-0.3.0}/test/test_units.py +0 -0
@@ -0,0 +1,13 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(uv sync:*)",
5
+ "Bash(uv run pytest:*)",
6
+ "Bash(uv run ruff:*)",
7
+ "Bash(uv run mypy:*)",
8
+ "Bash(uv run pre-commit:*)",
9
+ "Bash(uv run reuse:*)",
10
+ "Bash(uv run mkdocs build:*)"
11
+ ]
12
+ }
13
+ }
@@ -0,0 +1,3 @@
1
+ SPDX-FileCopyrightText: technologydata contributors
2
+
3
+ SPDX-License-Identifier: MIT
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: dataset-factsheet
3
+ description: Create or update the fact sheet in docs/datasets/<key>.md for a dataset shipped with technologydata, including its Parser API section, once its parser and parsed JSON exist. Use when a data source or a new version of one is added, when a parser changes, or when a fact sheet's doctests fail after the data changed.
4
+ ---
5
+
6
+ # Dataset fact sheet
7
+
8
+ <!--
9
+ SPDX-FileCopyrightText: technologydata contributors
10
+
11
+ SPDX-License-Identifier: MIT
12
+
13
+ -->
14
+
15
+ The template, section order and writing guidelines are in `docs/contributing/adding_a_dataset.md`; read it first and follow it exactly.
16
+ `docs/datasets/dea_energy_storage.md` and `docs/datasets/legacy_input_data.md` are finished examples.
17
+ How a parser is structured is described in `docs/contributing/writing_a_parser.md`.
18
+ This skill covers how to find each fact, how to check the parser docstrings and how to check the page.
19
+
20
+ Readers are experienced modellers and AI agents: tables and short bullets, no description of the parser code.
21
+ Only state what you verified in the code or the data; if something cannot be verified (e.g. the upstream license), write what is known and tell the user.
22
+
23
+ ## Inputs
24
+
25
+ Determine, or ask the user if unclear:
26
+
27
+ - `<key>`: the `DataSourceName` value in `src/technologydata/data_accessor.py`.
28
+ - `<version>`: the directory in `src/technologydata/parsers/<key>/`.
29
+ - The parser module `src/technologydata/parsers/<key>/`, the raw files in `src/technologydata/parsers/raw/<key>/`, and `sources.json` of the version.
30
+
31
+ For a new version of an existing dataset, update the existing pages instead (see the end of the checklist in `adding_a_dataset.md`), including a `:::` block for the new version parser in `Parser API`.
32
+
33
+ ## Where each fact comes from
34
+
35
+ | Section | Source |
36
+ |---|---|
37
+ | Front matter, At a glance | `sources.json` (title, authors, `url`, `url_archive`, `url_date`), the license in `REUSE.toml` and upstream, the parser (region, currency) |
38
+ | Years, cases, currency | the loaded data, see the snippet below |
39
+ | Available versions | `get_supported_versions()` of the parser, the parse options that reproduce the shipped JSON |
40
+ | Field mapping | the raw file's columns and the parser; trace one real row from raw value to parsed value |
41
+ | Naming conventions | the parser's cleaning functions (regexes, renames, case maps, unit replacements); one real example each |
42
+ | Assumptions and deviations | hard-coded values in the parser: fixed region, parameter filters, filled-in units, dropped rows, merged cases, row-level sources not kept |
43
+ | Known limitations | checks below |
44
+ | Parser API | the dispatcher class in `src/technologydata/parsers/<key>/__init__.py` and the version parser class of each entry in its `get_supported_versions()` |
45
+
46
+ ```python
47
+ from technologydata import DataAccessor
48
+
49
+ df = DataAccessor(data_source="<key>", version="<version>").load().technologies.to_dataframe()
50
+ print(df[["region", "case"]].value_counts(), df["year"].min(), df["year"].max())
51
+ ```
52
+
53
+ Run all Python from the repository root: `DataAccessor.load()` resolves the data relative to the working directory.
54
+
55
+ ## Generate the code block outputs
56
+
57
+ Copy the `Accessing the data` and `Contents` blocks from the template, change only `data_source` and `version`, and pick a representative technology and parameter for `Accessing the data`.
58
+ Put a placeholder line as the expected output, then run:
59
+
60
+ ```bash
61
+ uv run pytest test/test_docs.py --test-docs -k <key>
62
+ ```
63
+
64
+ The failure report shows `Got:` for each block; paste that output into the page and run the test again until it passes.
65
+ Do not edit the output by hand; the tests compare it with whitespace normalised only.
66
+
67
+ ## Checks for known limitations
68
+
69
+ Look for these and quantify them where cheap ("7 of about 76 parameters"):
70
+
71
+ - **Overwritten values**: parameters are stored in a dict per technology, so raw rows mapping to the same technology, case, year and parameter key overwrite each other.
72
+ Count duplicates in the raw data after applying the parser's name cleaning.
73
+ - **Dropped data**: raw columns not mapped, rows removed by filters or failed parsing (compare raw row count with parsed parameter count).
74
+ - **Heterogeneous units**: visible in the `Parameters` table when one parameter has several reference units.
75
+ - **Order of operations** that loses precision, such as rounding before unit scaling.
76
+ - **Provenance**: whether row-level sources are kept, whether an archived copy of the source exists.
77
+
78
+ ## Verify Reproduce
79
+
80
+ The documented `parse()` call must reproduce the shipped files.
81
+ It overwrites them, so check the working tree is clean for the output directory first:
82
+
83
+ ```bash
84
+ git status --short src/technologydata/parsers/<key>/<version>/
85
+ uv run python -c 'from technologydata import DataAccessor; DataAccessor(data_source="<key>", version="<version>").parse(input_file_names=["<file>"], num_digits=3)'
86
+ git diff --stat src/technologydata/parsers/<key>/<version>/
87
+ git checkout -- src/technologydata/parsers/<key>/<version>/
88
+ ```
89
+
90
+ Restore only the output directory `<key>/<version>/`: the parser code next to it may have uncommitted changes.
91
+
92
+ `input_file_names` lists every raw file of the version, as file names inside `src/technologydata/parsers/raw/<key>/`.
93
+ Only a trailing-newline difference is acceptable; otherwise adjust the documented options until the output matches.
94
+ Never use `archive_source=True` here: it calls the Wayback Machine and rewrites `sources.json`.
95
+ The test suite also re-parses the shipped files in place; restore them with `git checkout` after running it.
96
+
97
+ ## Parser API section
98
+
99
+ The `Parser API` section at the end of the fact sheet renders the docstrings of the parser classes with mkdocstrings, one `:::` block per class with `heading_level: 3`, as in the template: first the dispatcher, then one block per supported version.
100
+ It is the only per-parser documentation, so the docstrings must be complete and match the code: parameters and their types, what the parser writes where, raised errors, which options it ignores, and examples.
101
+ Fix wrong docstrings in the parser, or tell the user if the fix is not obvious.
102
+
103
+ ## Wire up and check
104
+
105
+ 1. Add the fact sheet to the `Datasets` nav in `mkdocs.yaml` and a row to the table in `docs/datasets/index.md`.
106
+ 2. Run `uv run pytest test/test_docs.py --test-docs` and `uv run pre-commit run --all-files`.
107
+ Codespell may flag domain abbreviations; add real terms to `.codespell.ignore`.
108
+ 3. Run `READTHEDOCS_CANONICAL_URL=http://localhost/ uv run mkdocs build --strict -d /tmp/site` to check links, anchors and the `:::` blocks.
109
+ Warnings `has no git logs` for new, uncommitted files can be ignored.
110
+ 4. Report to the user: anything not verified, and parser problems found (such as overwritten values or wrong docstrings) as candidates for issues.
@@ -2,3 +2,5 @@
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
4
  CAF
5
+ FOM
6
+ ore
@@ -0,0 +1,23 @@
1
+ # CODEOWNERS file for technology-data
2
+ # These owners will be the default owners for everything in the repo
3
+ # and will be requested for review when someone opens a pull request.
4
+
5
+ # Default owners for the entire repository
6
+ * @euronion @finozzifa
7
+
8
+ # Documentation
9
+ /docs/ @euronion @finozzifa
10
+
11
+ # Source code
12
+ /src/ @euronion @finozzifa
13
+
14
+ # Tests
15
+ /tests/ @euronion @finozzifa
16
+
17
+ # CI/CD and workflows
18
+ /.github/ @euronion @finozzifa
19
+
20
+ # Configuration files
21
+ *.toml @euronion @finozzifa
22
+ *.yaml @euronion @finozzifa
23
+ *.yml @euronion @finozzifa
@@ -0,0 +1,18 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: technologydata contributors
3
+
4
+ SPDX-License-Identifier: MIT
5
+
6
+ -->
7
+
8
+ # Summary
9
+
10
+ <!-- What does this PR change, and why? Link related issues with "Closes #ISSUE_NUMBER". -->
11
+
12
+ ## Checklist
13
+
14
+ - [ ] Tests added/updated for the change and `uv run pytest` passes
15
+ - [ ] New files carry SPDX license info (checked by REUSE)
16
+ - [ ] `uv run pre-commit run --all-files` passes (lint, format, mypy, REUSE)
17
+ - [ ] Documentation/docstrings has been updated
18
+ - [ ] (If AI-assisted) Changes were reviewed by a human before opening this PR
@@ -0,0 +1,18 @@
1
+ # SPDX-FileCopyrightText: technologydata contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ # dependabot
6
+ # Ref: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
7
+ # ------------------------------------------------------------------------------
8
+ version: 2
9
+ updates:
10
+ - package-ecosystem: github-actions
11
+ directory: /
12
+ schedule:
13
+ interval: weekly
14
+ groups:
15
+ # open a single pull-request for all GitHub actions updates
16
+ github-actions:
17
+ patterns:
18
+ - '*'
@@ -0,0 +1,20 @@
1
+ changelog:
2
+ categories:
3
+ - title: Breaking Changes
4
+ labels:
5
+ - breaking change
6
+ - title: Features
7
+ labels:
8
+ - feature
9
+ - title: Bug Fixes
10
+ labels:
11
+ - bug
12
+ - title: Data
13
+ labels:
14
+ - data
15
+ - title: Documentation
16
+ labels:
17
+ - documentation
18
+ - title: Other Changes
19
+ labels:
20
+ - "*"
@@ -3,6 +3,8 @@
3
3
  # SPDX-License-Identifier: MIT
4
4
  name: Technologydata prototype CI
5
5
 
6
+ permissions: read-all
7
+
6
8
  on:
7
9
  push:
8
10
  branches: [prototype-2]
@@ -15,16 +17,16 @@ jobs:
15
17
 
16
18
  steps:
17
19
  - name: Checkout repository
18
- uses: actions/checkout@v4
20
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
19
21
 
20
22
 
21
23
  - name: Set up Python
22
- uses: actions/setup-python@v5
24
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
23
25
  with:
24
26
  python-version: "3.13"
25
27
 
26
28
  - name: Cache Python dependencies
27
- uses: actions/cache@v3
29
+ uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v 6.1.0
28
30
  with:
29
31
  path: ~/.cache/pip
30
32
  key: ${{ runner.os }}-pip-${{ hashFiles('**/uv.lock') }}
@@ -0,0 +1,50 @@
1
+ # SPDX-FileCopyrightText: technologydata contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ name: "CodeQL Advanced"
6
+
7
+ permissions: read-all
8
+
9
+ on:
10
+ push:
11
+ branches: ["prototype-2"]
12
+ pull_request:
13
+ branches: ["prototype-2"]
14
+ schedule:
15
+ - cron: '0 8 * * 1'
16
+
17
+ jobs:
18
+ analyze:
19
+ name: Analyze (${{ matrix.language }})
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ # required for all workflows
23
+ security-events: write
24
+
25
+ # required to fetch internal or private CodeQL packs
26
+ packages: read
27
+
28
+ strategy:
29
+ fail-fast: false
30
+ matrix:
31
+ include:
32
+ - language: actions
33
+ build-mode: none
34
+ - language: python
35
+ build-mode: none
36
+ steps:
37
+ - name: Checkout repository
38
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
39
+
40
+ # Initializes the CodeQL tools for scanning.
41
+ - name: Initialize CodeQL
42
+ uses: github/codeql-action/init@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
43
+ with:
44
+ languages: ${{ matrix.language }}
45
+ build-mode: ${{ matrix.build-mode }}
46
+
47
+ - name: Perform CodeQL Analysis
48
+ uses: github/codeql-action/analyze@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
49
+ with:
50
+ category: "/language:${{matrix.language}}"
@@ -0,0 +1,52 @@
1
+ # SPDX-FileCopyrightText: technologydata contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ name: Docs
5
+
6
+ permissions: read-all
7
+
8
+ on:
9
+ push:
10
+ branches: [master]
11
+ pull_request:
12
+ branches: [master]
13
+
14
+ jobs:
15
+ check-docs:
16
+ name: Check docs
17
+ runs-on: ubuntu-latest
18
+
19
+ steps:
20
+ - name: Checkout repository
21
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
25
+ with:
26
+ python-version: "3.13"
27
+
28
+ - name: Cache uv dependencies
29
+ uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v 6.1.0
30
+ with:
31
+ path: ~/.cache/uv
32
+ key: ${{ runner.os }}-uv-${{ hashFiles('**/uv.lock') }}
33
+ restore-keys: |
34
+ ${{ runner.os }}-uv-
35
+
36
+ # The tutorial's currency-conversion example downloads World Bank
37
+ # deflator data via pydeflate on first use. Caching it keeps reruns
38
+ # fast and avoids hitting the network every time.
39
+ - name: Cache pydeflate data
40
+ uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v 6.1.0
41
+ with:
42
+ path: pydeflate_data
43
+ key: pydeflate-worldbank-data
44
+
45
+ - name: Install package and dependencies
46
+ run: |
47
+ python -m pip install uv
48
+ uv sync --frozen --group dev
49
+
50
+ - name: Run documentation doctests
51
+ run: |
52
+ uv run pytest test/test_docs.py --test-docs
@@ -0,0 +1,29 @@
1
+ # SPDX-FileCopyrightText: technologydata contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ name: Check documentation links
6
+
7
+ permissions: read-all
8
+
9
+ on:
10
+ schedule:
11
+ - cron: "0 4 * * 1" # every Monday at 04:00 UTC
12
+ workflow_dispatch:
13
+
14
+ jobs:
15
+ link-check:
16
+ name: Check external links
17
+ runs-on: ubuntu-latest
18
+
19
+ steps:
20
+ - name: Checkout repository
21
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
22
+
23
+ - name: Check external links
24
+ uses: lycheeverse/lychee-action@e7477775783ea5526144ba13e8db5eec57747ce8 # v2.9.0
25
+ with:
26
+ args: "--config .lychee.toml --no-progress './docs/**/*.md' './README.md'"
27
+ fail: true
28
+ env:
29
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -4,6 +4,8 @@
4
4
 
5
5
  name: Release
6
6
 
7
+ permissions: read-all
8
+
7
9
  on:
8
10
  push:
9
11
  tags:
@@ -19,7 +21,7 @@ jobs:
19
21
  outputs:
20
22
  prepared: ${{ steps.validate.outputs.prepared }}
21
23
  steps:
22
- - uses: actions/checkout@v6
24
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
23
25
 
24
26
  - name: Validate commit message
25
27
  id: validate
@@ -48,7 +50,7 @@ jobs:
48
50
  echo "Branch found: $branch"
49
51
  echo "BRANCH_NAME=$branch" >> $GITHUB_ENV
50
52
 
51
- - uses: actions/checkout@v6
53
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
52
54
  with:
53
55
  fetch-depth: 0
54
56
  ref: ${{ env.BRANCH_NAME }}
@@ -56,7 +58,7 @@ jobs:
56
58
 
57
59
  # Start of preparation script
58
60
 
59
- - uses: actions/setup-python@v6
61
+ - uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
60
62
  with:
61
63
  python-version: 3.12
62
64
 
@@ -92,7 +94,7 @@ jobs:
92
94
  git push origin --delete ${{ github.ref_name }}
93
95
 
94
96
  - name: Commit changes
95
- uses: stefanzweifel/git-auto-commit-action@v7
97
+ uses: stefanzweifel/git-auto-commit-action@4a55954c782fc1ea30b9056cd3e7a2b40ca8887d #v7.2.0
96
98
  with:
97
99
  branch: ${{ env.BRANCH_NAME }}
98
100
  commit_message: '${{ env.PREPARATION_COMMIT }}'
@@ -106,8 +108,8 @@ jobs:
106
108
  if: ${{ needs.check-preparation.outputs.prepared == 'true' }}
107
109
  runs-on: ubuntu-latest
108
110
  steps:
109
- - uses: actions/checkout@v6
110
- - uses: hynek/build-and-inspect-python-package@v2
111
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
112
+ - uses: hynek/build-and-inspect-python-package@2abe76da66d0a6a4a227101f9348ee855797cfa5 #v3.0.1
111
113
 
112
114
  release:
113
115
  name: Create GitHub release
@@ -116,12 +118,9 @@ jobs:
116
118
  permissions:
117
119
  contents: write
118
120
  steps:
119
- - uses: actions/checkout@v6
120
- - uses: softprops/action-gh-release@v2
121
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7.0.1
122
+ - uses: softprops/action-gh-release@efb35369e0ad2afab669f228072c1b0d510eae64 #v3.0.3
121
123
  with:
122
- body: |
123
- Revised release notes are available in the documentation.
124
- append_body: true
125
124
  generate_release_notes: true
126
125
 
127
126
  publish:
@@ -134,8 +133,8 @@ jobs:
134
133
  permissions:
135
134
  id-token: write
136
135
  steps:
137
- - uses: actions/download-artifact@v6
136
+ - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
138
137
  with:
139
138
  name: Packages
140
139
  path: dist
141
- - uses: pypa/gh-action-pypi-publish@release/v1
140
+ - uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
@@ -0,0 +1,60 @@
1
+ # SPDX-FileCopyrightText: technologydata contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ name: Scorecard supply-chain security
6
+ on:
7
+ # For Branch-Protection check. Only the default branch is supported. See
8
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
9
+ branch_protection_rule:
10
+ # To guarantee Maintained check is occasionally updated. See
11
+ # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
12
+ schedule:
13
+ - cron: '0 8 * * 1'
14
+ push:
15
+ branches: ["prototype-2"]
16
+ workflow_dispatch:
17
+
18
+ # Declare default permissions as read only.
19
+ permissions: read-all
20
+
21
+ jobs:
22
+ analysis:
23
+ name: Scorecard analysis
24
+ runs-on: ubuntu-latest
25
+ # `publish_results: true` only works when run from the default branch. conditional can be removed if disabled.
26
+ if: github.event.repository.default_branch == github.ref_name || github.event_name == 'pull_request'
27
+ permissions:
28
+ # Needed to upload the results to code-scanning dashboard.
29
+ security-events: write
30
+ # Needed to publish results and get a badge (see publish_results below).
31
+ id-token: write
32
+
33
+ steps:
34
+ - name: "Checkout code"
35
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
36
+ with:
37
+ persist-credentials: false
38
+
39
+ - name: "Run analysis"
40
+ uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
41
+ with:
42
+ results_file: results.sarif
43
+ results_format: sarif
44
+ publish_results: true
45
+
46
+ # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
47
+ # format to the repository Actions tab.
48
+ - name: "Upload artifact"
49
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
50
+ with:
51
+ name: SARIF file
52
+ path: results.sarif
53
+ retention-days: 5
54
+
55
+ # Upload the results to GitHub's code scanning dashboard (optional).
56
+ # Commenting out will disable upload of results to your repo's Code Scanning dashboard
57
+ - name: "Upload to code-scanning"
58
+ uses: github/codeql-action/upload-sarif@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.1
59
+ with:
60
+ sarif_file: results.sarif
@@ -78,3 +78,9 @@ dev/
78
78
 
79
79
  # pydeflate cache
80
80
  pydeflate_data/
81
+
82
+ # site
83
+ site/
84
+
85
+ # Claude Code agent worktrees
86
+ .claude/worktrees/
@@ -0,0 +1,27 @@
1
+ # SPDX-FileCopyrightText: technologydata contributors
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ # lychee link checker config (https://lychee.cli.rs).
6
+ # Checks external links referenced from the documentation and README.
7
+ scheme = ["https", "http"]
8
+
9
+ # Accept every reachable response except definitive "not found" codes, so only
10
+ # 404 and 410 fail. Publishers routinely answer bots with 400/403/429, which is
11
+ # not link rot.
12
+ accept = ["100..=403", "405..=409", "411..=599"]
13
+
14
+ # Slow or rate-limiting hosts time out on a different random subset each run.
15
+ # Timeouts are not link rot, so tolerate them; genuine 404/410 and connection
16
+ # failures still fail the check.
17
+ accept_timeouts = true
18
+
19
+ # Placeholder URL used in code examples throughout the docs, not a real link.
20
+ exclude = [
21
+ "example.com",
22
+ ]
23
+
24
+ timeout = 30
25
+ max_retries = 5
26
+ max_redirects = 10
27
+ host_concurrency = 4
@@ -8,7 +8,7 @@ ci:
8
8
  repos:
9
9
  # Basic pre-commit hooks for whitespace, merge conflicts, etc.
10
10
  - repo: https://github.com/pre-commit/pre-commit-hooks
11
- rev: v5.0.0
11
+ rev: v6.0.0
12
12
  hooks:
13
13
  - id: check-merge-conflict
14
14
  - id: check-added-large-files
@@ -18,7 +18,7 @@ repos:
18
18
 
19
19
  # Ruff: Python linter and formatter
20
20
  - repo: https://github.com/astral-sh/ruff-pre-commit
21
- rev: v0.12.10
21
+ rev: v0.15.19
22
22
  hooks:
23
23
  - id: ruff
24
24
  args: [--fix]
@@ -26,7 +26,7 @@ repos:
26
26
 
27
27
  # Codespell: Checks for common misspellings
28
28
  - repo: https://github.com/codespell-project/codespell
29
- rev: v2.4.1
29
+ rev: v2.4.2
30
30
  hooks:
31
31
  - id: codespell
32
32
  args: ['--ignore-regex="(\b[A-Z]+\b)"', '--ignore-words=.codespell.ignore']
@@ -41,14 +41,14 @@ repos:
41
41
 
42
42
  # Pretty-format-yaml: YAML formatter
43
43
  - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks
44
- rev: v2.14.0
44
+ rev: v2.16.0
45
45
  hooks:
46
46
  - id: pretty-format-yaml
47
47
  args: [--autofix, --indent, '2', --preserve-quotes]
48
48
 
49
49
  # Mypy: Static type checker for Python
50
50
  - repo: https://github.com/pre-commit/mirrors-mypy
51
- rev: 'v1.15.0'
51
+ rev: 'v2.1.0'
52
52
  hooks:
53
53
  - id: mypy
54
54
  args: [--strict, --ignore-missing-imports, --config-file=pyproject.toml]
@@ -57,19 +57,19 @@ repos:
57
57
 
58
58
  # Pyupgrade: Automatically upgrades Python syntax
59
59
  - repo: https://github.com/asottile/pyupgrade
60
- rev: v3.16.0
60
+ rev: v3.21.2
61
61
  hooks:
62
62
  - id: pyupgrade
63
63
  args: ["--py311-plus"]
64
64
 
65
65
  # REUSE: Checks for REUSE license compliance
66
66
  - repo: https://github.com/fsfe/reuse-tool
67
- rev: v5.0.2
67
+ rev: v6.2.0
68
68
  hooks:
69
69
  - id: reuse
70
70
 
71
71
  - repo: https://github.com/rvben/rumdl-pre-commit
72
- rev: v0.0.99 # Use the latest release tag
72
+ rev: v0.2.22 # Use the latest release tag
73
73
  hooks:
74
74
  - id: rumdl
75
- args: ["--fix", "--disable=MD006, MD013, MD024, MD030, MD033, MD041"]
75
+ args: ["--fix", "--disable=MD013, MD024, MD030, MD033, MD041"]