pymetadataeditor 0.1.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 World Bank
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,333 @@
1
+ Metadata-Version: 2.1
2
+ Name: pymetadataeditor
3
+ Version: 0.1.0
4
+ Summary: Metadata editor client for python
5
+ License: MIT
6
+ Author: Gordon Blackadder
7
+ Author-email: gblackadder@worldbank.org
8
+ Requires-Python: >=3.11,<4.0
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Requires-Dist: markitdown (>=0.0.1a3,<0.0.2)
14
+ Requires-Dist: metadataschemas (>=0.1.1,<0.2.0)
15
+ Requires-Dist: openai (>=1.59.4,<2.0.0)
16
+ Requires-Dist: pandas (>=2.2.2,<3.0.0)
17
+ Requires-Dist: pydantic (>=2.7.4,<3.0.0)
18
+ Requires-Dist: requests (>=2.32.3,<3.0.0)
19
+ Requires-Dist: tiktoken (>=0.8.0,<0.9.0)
20
+ Requires-Dist: urllib3 (>=2.2.2,<3.0.0)
21
+ Description-Content-Type: text/markdown
22
+
23
+ # pyMetadataEditor
24
+
25
+ A tool connected to Metadata Editor for creating, editing and managing metadata for microdata, indicators, geospatial data, documents, scripts, images and videos.
26
+
27
+ # How to use pyMetadataEditor
28
+
29
+
30
+ ```python
31
+ from pymetadataeditor import MetadataEditor
32
+ import os
33
+ ```
34
+
35
+
36
+
37
+ ```python
38
+ your_api_key = os.getenv("API_KEY")
39
+ api_url = os.getenv("API_URL")
40
+ me = MetadataEditor(api_url=api_url, api_key=your_api_key, verify_ssl=False)
41
+ ```
42
+
43
+ ## Listing your projects
44
+
45
+
46
+ ```python
47
+ me.list_projects(limit=8)
48
+ ```
49
+
50
+ <div>
51
+ <style scoped>
52
+ .dataframe tbody tr th:only-of-type {
53
+ vertical-align: middle;
54
+ }
55
+
56
+ .dataframe tbody tr th {
57
+ vertical-align: top;
58
+ }
59
+
60
+ .dataframe thead th {
61
+ text-align: right;
62
+ }
63
+ </style>
64
+ <table border="1" class="dataframe">
65
+ <thead>
66
+ <tr style="text-align: right;">
67
+ <th></th>
68
+ <th>type</th>
69
+ <th>idno</th>
70
+ <th>study_idno</th>
71
+ <th>title</th>
72
+ <th>abbreviation</th>
73
+ <th>nation</th>
74
+ <th>year_start</th>
75
+ <th>year_end</th>
76
+ </tr>
77
+ <tr>
78
+ <th>id</th>
79
+ <th></th>
80
+ <th></th>
81
+ <th></th>
82
+ <th></th>
83
+ <th></th>
84
+ <th></th>
85
+ <th></th>
86
+ <th></th>
87
+ </tr>
88
+ </thead>
89
+ <tbody>
90
+ <tr>
91
+ <th>1003</th>
92
+ <td>document</td>
93
+ <td>12345</td>
94
+ <td>DOC_001</td>
95
+ <td>Sample Document 1</td>
96
+ <td>SD1</td>
97
+ <td>Example Nation</td>
98
+ <td>2020</td>
99
+ <td>2025</td>
100
+ </tr>
101
+ <tr>
102
+ <th>1002</th>
103
+ <td>survey</td>
104
+ <td>67890</td>
105
+ <td>SURVEY_002</td>
106
+ <td>Sample Survey 2</td>
107
+ <td>SS2</td>
108
+ <td>Example Nation</td>
109
+ <td>2019</td>
110
+ <td>2024</td>
111
+ </tr>
112
+ <tr>
113
+ <th>1001</th>
114
+ <td>timeseries</td>
115
+ <td>54321</td>
116
+ <td>TS_003</td>
117
+ <td>Time Series 3</td>
118
+ <td>TS3</td>
119
+ <td>Another Nation</td>
120
+ <td>2021</td>
121
+ <td>2026</td>
122
+ </tr>
123
+ </tbody>
124
+ </table>
125
+ </div>
126
+
127
+
128
+
129
+
130
+ ## Creating a new indicator project
131
+
132
+
133
+ ```python
134
+ demo_name = "GB20241030_demo"
135
+ ```
136
+
137
+
138
+ ```python
139
+ series_description = {
140
+ "idno": demo_name,
141
+ "doi": "V1",
142
+ "name": "Version 1",
143
+ "display_name": "Version 1"
144
+ }
145
+
146
+ indicator_id = me.create_project_log({"idno": demo_name, "series_description": series_description}, "indicator")
147
+ ```
148
+
149
+
150
+ # Starting with outlines
151
+
152
+ The metadata can be both large and hierarchical. Starting with a skeleton outline makes things easier.
153
+
154
+ Outlines are available in three modes - dictionary, pydantic model and as an Excel file.
155
+
156
+ ## Dictionaries
157
+ Dictionaries are created like so:
158
+
159
+
160
+ ```python
161
+ indicator_dict = me.make_metadata_outline('indicator', output_mode='dict')
162
+ indicator_dict
163
+ ```
164
+
165
+
166
+
167
+
168
+ {'metadata_information': {'title': None,
169
+ 'idno': None,
170
+ 'producers': [{'name': '', 'abbr': None, 'affiliation': None, 'role': None}],
171
+ 'prod_date': None,
172
+ ...
173
+ 'email': None,
174
+ 'telephone': None,
175
+ 'uri': None}]},
176
+ 'tags': [{'tag': None, 'tag_group': None}]}
177
+
178
+
179
+ ## Pydantic
180
+
181
+ Pydantic is a nice python library for defining and validating data schemas. An outline for the indicator schema can be created like so:
182
+
183
+
184
+ ```python
185
+ indicator_pydantic = me.make_metadata_outline('indicator', 'pydantic')
186
+ indicator_pydantic
187
+ ```
188
+
189
+
190
+ giving
191
+
192
+ IHSN_INDICATOR_1-0_Template_v01_EN(metadata_information=metadata_information(title=None, idno=None, producers=[Producer(name='', abbr=None, affiliation=None, role=None)], prod_date=None, ...
193
+
194
+
195
+
196
+ It can be updated using dot notation, for example:
197
+
198
+
199
+ ```python
200
+ indicator_pydantic.metadata_information.producers[0].name = "example_producer"
201
+ indicator_pydantic
202
+ ```
203
+
204
+
205
+ giving
206
+
207
+ IHSN_INDICATOR_1-0_Template_v01_EN(metadata_information=metadata_information(title=None, idno=None, producers=[Producer(name='example_producer', abbr=None, affiliation=None, role=None)], prod_date=None, ...
208
+
209
+ ## Excel
210
+
211
+ Finally, a nicely formatted Excel file can be created into which the metadata can be written, with the name of the metadata type or of the default template used as the filename if no filename is explicitly given.
212
+
213
+
214
+ ```python
215
+ outline_filename = me.make_metadata_outline('indicator', 'excel')
216
+ ```
217
+
218
+ And then read back in from Excel like so:
219
+
220
+ ```python
221
+ indicator_excel = me.read_metadata_from_excel(outline_filename)
222
+ ```
223
+
224
+ ## Retreiving existing metadata
225
+
226
+ Likewise, existing projects can be downloaded as either dictionaries, pydantic models or as excel spreadsheets.
227
+
228
+ Asking for the metadata as a pydantic object
229
+
230
+ ```python
231
+ demo_pydantic = me.get_project_metadata_by_id(indicator_id, 'pydantic')
232
+ demo_pydantic
233
+ ```
234
+
235
+ which gives:
236
+
237
+ IHSN_INDICATOR_1-0_Template_v01_EN(metadata_information=metadata_information(title=None, idno=None, producers=[Producer(name='', abbr=None, affiliation=None, role=None)], prod_date=None, ...
238
+
239
+ # Automatic Metadata Creation and Augmentation from Sources
240
+
241
+ We can use a Large Language Model to make a first draft of metadata from a source document or documents.
242
+
243
+ We can create metadata from source files such as:
244
+ - pdfs
245
+ - word
246
+ - excel
247
+ - powerpoint
248
+ - text files
249
+ - csv
250
+ - XML
251
+ - ZIP files
252
+ - Images
253
+
254
+
255
+
256
+
257
+ ```python
258
+ docs = ["survey_records/cambodia/cambodia_lsms_basic_information_document.pdf", "survey_records/cambodia/cambodia_living_standards_measurement_study_plus_manual_english.pdf"]
259
+
260
+ example = me.draft_metadata_from_files(openai_api_key=openai_key,
261
+ files=docs,
262
+ metadata_type_or_template_uid='microdata',
263
+ output_mode='pydantic',
264
+ metadata_producer_organization="The World Bank Group, DEC - Development Data Group"
265
+ )
266
+ ```
267
+
268
+ The files are read in and sent to the LLM for processing.
269
+
270
+ Read in survey_records/cambodia/cambodia_lsms_basic_information_document.pdf, running token count is 6373
271
+ Read in survey_records/cambodia/cambodia_living_standards_measurement_study_plus_manual_english.pdf, running token count is 24901
272
+ Sending to OpenAI, this may take a few minutes...
273
+
274
+ We can then view the new metadata
275
+ ```python
276
+ example.pretty_print()
277
+ ```
278
+ which gives
279
+
280
+ <pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">IHSN_DDI_2-<span style="color: #800080; text-decoration-color: #800080; font-weight: bold">5_Template_v01_EN</span><span style="font-weight: bold">(</span>
281
+ <span style="color: #808000; text-decoration-color: #808000">doc_desc</span>=<span style="color: #800080; text-decoration-color: #800080; font-weight: bold">doc_desc</span><span style="font-weight: bold">(</span>
282
+ <span style="color: #808000; text-decoration-color: #808000">producers</span>=<span style="font-weight: bold">[</span>
283
+ <span style="color: #800080; text-decoration-color: #800080; font-weight: bold">Producer</span><span style="font-weight: bold">(</span>
284
+ <span style="color: #808000; text-decoration-color: #808000">name</span>=<span style="color: #008000; text-decoration-color: #008000">'The World Bank Group, DEC - Development Data Group'</span>,
285
+ <span style="color: #808000; text-decoration-color: #808000">abbr</span>=<span style="color: #008000; text-decoration-color: #008000">'WBG'</span>,
286
+ <span style="color: #808000; text-decoration-color: #808000">affiliation</span>=<span style="color: #008000; text-decoration-color: #008000">'World Bank'</span>,
287
+ <span style="color: #808000; text-decoration-color: #808000">role</span>=<span style="color: #008000; text-decoration-color: #008000">'Metadata producer'</span>
288
+ <span style="font-weight: bold">)</span>
289
+ <span style="font-weight: bold">]</span>,
290
+ <span style="color: #808000; text-decoration-color: #808000">prod_date</span>=<span style="color: #008000; text-decoration-color: #008000">'2025-01-28'</span>,
291
+ <span style="color: #808000; text-decoration-color: #808000">idno</span>=<span style="color: #008000; text-decoration-color: #008000">'CAMBODIA_LSMS_PLUS_2019_2020_v01_EN'</span>,
292
+ <span style="color: #808000; text-decoration-color: #808000">version_statement</span>=<span style="color: #800080; text-decoration-color: #800080; font-weight: bold">version_statement</span><span style="font-weight: bold">(</span>
293
+ <span style="color: #808000; text-decoration-color: #808000">version</span>=<span style="color: #008000; text-decoration-color: #008000">'1.0'</span>,
294
+ <span style="color: #808000; text-decoration-color: #808000">version_date</span>=<span style="color: #008000; text-decoration-color: #008000">'2025-01-28'</span>,
295
+ <span style="color: #808000; text-decoration-color: #808000">version_resp</span>=<span style="color: #008000; text-decoration-color: #008000">''</span>,
296
+ <span style="color: #808000; text-decoration-color: #808000">version_notes</span>=<span style="color: #008000; text-decoration-color: #008000">'First draft of the metadata for the Cambodia Living Standards Measurement Study - Plus </span>
297
+ <span style="color: #008000; text-decoration-color: #008000">(LSMS+) 2019-20.'</span>
298
+ <span style="font-weight: bold">)</span>
299
+ <span style="font-weight: bold">)</span>,
300
+ ...
301
+
302
+ <span style="font-weight: bold">)</span>
303
+ </pre>
304
+
305
+
306
+
307
+
308
+ # Contributing
309
+ ## Setting up the python environment
310
+
311
+ This library uses Poetry for dependency management (https://python-poetry.org/docs/basic-usage/).
312
+
313
+ In your python environment run `pip install poetry` then navigate to the pymetadataeditor folder and run `poetry install` or, if that doesn't work, try `python -m poetry install`.
314
+
315
+ ### Development python environment
316
+
317
+ If you want to make changes to this repo then you also need to install the tools used for development but which aren't used otherwise, for example pytest.
318
+
319
+ Run:
320
+
321
+ `poetry install --with dev`
322
+ `poetry run pre-commit install`
323
+
324
+ ### Poetry troubleshooting
325
+
326
+ If you are running on Windows and see errors about numpy installation errors then it could be an issue with Windows file paths. With default settings, file paths that exceed a few hundred characters can cause installation problems. To overcome this you can either
327
+
328
+ 1) enable long path support in Windows (https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=powershell#enable-long-paths-in-windows-10-version-1607-and-later)
329
+ 2) install python libraries in a folder in the current directory by running `poetry config virtualenvs.in-project true` and then running `poetry install`
330
+
331
+ ## Notes
332
+
333
+ In keeping with World Bank Group practice, it should be noted that parts of this code base were written with the assistance of ChatGPT.
@@ -0,0 +1,311 @@
1
+ # pyMetadataEditor
2
+
3
+ A tool connected to Metadata Editor for creating, editing and managing metadata for microdata, indicators, geospatial data, documents, scripts, images and videos.
4
+
5
+ # How to use pyMetadataEditor
6
+
7
+
8
+ ```python
9
+ from pymetadataeditor import MetadataEditor
10
+ import os
11
+ ```
12
+
13
+
14
+
15
+ ```python
16
+ your_api_key = os.getenv("API_KEY")
17
+ api_url = os.getenv("API_URL")
18
+ me = MetadataEditor(api_url=api_url, api_key=your_api_key, verify_ssl=False)
19
+ ```
20
+
21
+ ## Listing your projects
22
+
23
+
24
+ ```python
25
+ me.list_projects(limit=8)
26
+ ```
27
+
28
+ <div>
29
+ <style scoped>
30
+ .dataframe tbody tr th:only-of-type {
31
+ vertical-align: middle;
32
+ }
33
+
34
+ .dataframe tbody tr th {
35
+ vertical-align: top;
36
+ }
37
+
38
+ .dataframe thead th {
39
+ text-align: right;
40
+ }
41
+ </style>
42
+ <table border="1" class="dataframe">
43
+ <thead>
44
+ <tr style="text-align: right;">
45
+ <th></th>
46
+ <th>type</th>
47
+ <th>idno</th>
48
+ <th>study_idno</th>
49
+ <th>title</th>
50
+ <th>abbreviation</th>
51
+ <th>nation</th>
52
+ <th>year_start</th>
53
+ <th>year_end</th>
54
+ </tr>
55
+ <tr>
56
+ <th>id</th>
57
+ <th></th>
58
+ <th></th>
59
+ <th></th>
60
+ <th></th>
61
+ <th></th>
62
+ <th></th>
63
+ <th></th>
64
+ <th></th>
65
+ </tr>
66
+ </thead>
67
+ <tbody>
68
+ <tr>
69
+ <th>1003</th>
70
+ <td>document</td>
71
+ <td>12345</td>
72
+ <td>DOC_001</td>
73
+ <td>Sample Document 1</td>
74
+ <td>SD1</td>
75
+ <td>Example Nation</td>
76
+ <td>2020</td>
77
+ <td>2025</td>
78
+ </tr>
79
+ <tr>
80
+ <th>1002</th>
81
+ <td>survey</td>
82
+ <td>67890</td>
83
+ <td>SURVEY_002</td>
84
+ <td>Sample Survey 2</td>
85
+ <td>SS2</td>
86
+ <td>Example Nation</td>
87
+ <td>2019</td>
88
+ <td>2024</td>
89
+ </tr>
90
+ <tr>
91
+ <th>1001</th>
92
+ <td>timeseries</td>
93
+ <td>54321</td>
94
+ <td>TS_003</td>
95
+ <td>Time Series 3</td>
96
+ <td>TS3</td>
97
+ <td>Another Nation</td>
98
+ <td>2021</td>
99
+ <td>2026</td>
100
+ </tr>
101
+ </tbody>
102
+ </table>
103
+ </div>
104
+
105
+
106
+
107
+
108
+ ## Creating a new indicator project
109
+
110
+
111
+ ```python
112
+ demo_name = "GB20241030_demo"
113
+ ```
114
+
115
+
116
+ ```python
117
+ series_description = {
118
+ "idno": demo_name,
119
+ "doi": "V1",
120
+ "name": "Version 1",
121
+ "display_name": "Version 1"
122
+ }
123
+
124
+ indicator_id = me.create_project_log({"idno": demo_name, "series_description": series_description}, "indicator")
125
+ ```
126
+
127
+
128
+ # Starting with outlines
129
+
130
+ The metadata can be both large and hierarchical. Starting with a skeleton outline makes things easier.
131
+
132
+ Outlines are available in three modes - dictionary, pydantic model and as an Excel file.
133
+
134
+ ## Dictionaries
135
+ Dictionaries are created like so:
136
+
137
+
138
+ ```python
139
+ indicator_dict = me.make_metadata_outline('indicator', output_mode='dict')
140
+ indicator_dict
141
+ ```
142
+
143
+
144
+
145
+
146
+ {'metadata_information': {'title': None,
147
+ 'idno': None,
148
+ 'producers': [{'name': '', 'abbr': None, 'affiliation': None, 'role': None}],
149
+ 'prod_date': None,
150
+ ...
151
+ 'email': None,
152
+ 'telephone': None,
153
+ 'uri': None}]},
154
+ 'tags': [{'tag': None, 'tag_group': None}]}
155
+
156
+
157
+ ## Pydantic
158
+
159
+ Pydantic is a nice python library for defining and validating data schemas. An outline for the indicator schema can be created like so:
160
+
161
+
162
+ ```python
163
+ indicator_pydantic = me.make_metadata_outline('indicator', 'pydantic')
164
+ indicator_pydantic
165
+ ```
166
+
167
+
168
+ giving
169
+
170
+ IHSN_INDICATOR_1-0_Template_v01_EN(metadata_information=metadata_information(title=None, idno=None, producers=[Producer(name='', abbr=None, affiliation=None, role=None)], prod_date=None, ...
171
+
172
+
173
+
174
+ It can be updated using dot notation, for example:
175
+
176
+
177
+ ```python
178
+ indicator_pydantic.metadata_information.producers[0].name = "example_producer"
179
+ indicator_pydantic
180
+ ```
181
+
182
+
183
+ giving
184
+
185
+ IHSN_INDICATOR_1-0_Template_v01_EN(metadata_information=metadata_information(title=None, idno=None, producers=[Producer(name='example_producer', abbr=None, affiliation=None, role=None)], prod_date=None, ...
186
+
187
+ ## Excel
188
+
189
+ Finally, a nicely formatted Excel file can be created into which the metadata can be written, with the name of the metadata type or of the default template used as the filename if no filename is explicitly given.
190
+
191
+
192
+ ```python
193
+ outline_filename = me.make_metadata_outline('indicator', 'excel')
194
+ ```
195
+
196
+ And then read back in from Excel like so:
197
+
198
+ ```python
199
+ indicator_excel = me.read_metadata_from_excel(outline_filename)
200
+ ```
201
+
202
+ ## Retreiving existing metadata
203
+
204
+ Likewise, existing projects can be downloaded as either dictionaries, pydantic models or as excel spreadsheets.
205
+
206
+ Asking for the metadata as a pydantic object
207
+
208
+ ```python
209
+ demo_pydantic = me.get_project_metadata_by_id(indicator_id, 'pydantic')
210
+ demo_pydantic
211
+ ```
212
+
213
+ which gives:
214
+
215
+ IHSN_INDICATOR_1-0_Template_v01_EN(metadata_information=metadata_information(title=None, idno=None, producers=[Producer(name='', abbr=None, affiliation=None, role=None)], prod_date=None, ...
216
+
217
+ # Automatic Metadata Creation and Augmentation from Sources
218
+
219
+ We can use a Large Language Model to make a first draft of metadata from a source document or documents.
220
+
221
+ We can create metadata from source files such as:
222
+ - pdfs
223
+ - word
224
+ - excel
225
+ - powerpoint
226
+ - text files
227
+ - csv
228
+ - XML
229
+ - ZIP files
230
+ - Images
231
+
232
+
233
+
234
+
235
+ ```python
236
+ docs = ["survey_records/cambodia/cambodia_lsms_basic_information_document.pdf", "survey_records/cambodia/cambodia_living_standards_measurement_study_plus_manual_english.pdf"]
237
+
238
+ example = me.draft_metadata_from_files(openai_api_key=openai_key,
239
+ files=docs,
240
+ metadata_type_or_template_uid='microdata',
241
+ output_mode='pydantic',
242
+ metadata_producer_organization="The World Bank Group, DEC - Development Data Group"
243
+ )
244
+ ```
245
+
246
+ The files are read in and sent to the LLM for processing.
247
+
248
+ Read in survey_records/cambodia/cambodia_lsms_basic_information_document.pdf, running token count is 6373
249
+ Read in survey_records/cambodia/cambodia_living_standards_measurement_study_plus_manual_english.pdf, running token count is 24901
250
+ Sending to OpenAI, this may take a few minutes...
251
+
252
+ We can then view the new metadata
253
+ ```python
254
+ example.pretty_print()
255
+ ```
256
+ which gives
257
+
258
+ <pre style="white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace">IHSN_DDI_2-<span style="color: #800080; text-decoration-color: #800080; font-weight: bold">5_Template_v01_EN</span><span style="font-weight: bold">(</span>
259
+ <span style="color: #808000; text-decoration-color: #808000">doc_desc</span>=<span style="color: #800080; text-decoration-color: #800080; font-weight: bold">doc_desc</span><span style="font-weight: bold">(</span>
260
+ <span style="color: #808000; text-decoration-color: #808000">producers</span>=<span style="font-weight: bold">[</span>
261
+ <span style="color: #800080; text-decoration-color: #800080; font-weight: bold">Producer</span><span style="font-weight: bold">(</span>
262
+ <span style="color: #808000; text-decoration-color: #808000">name</span>=<span style="color: #008000; text-decoration-color: #008000">'The World Bank Group, DEC - Development Data Group'</span>,
263
+ <span style="color: #808000; text-decoration-color: #808000">abbr</span>=<span style="color: #008000; text-decoration-color: #008000">'WBG'</span>,
264
+ <span style="color: #808000; text-decoration-color: #808000">affiliation</span>=<span style="color: #008000; text-decoration-color: #008000">'World Bank'</span>,
265
+ <span style="color: #808000; text-decoration-color: #808000">role</span>=<span style="color: #008000; text-decoration-color: #008000">'Metadata producer'</span>
266
+ <span style="font-weight: bold">)</span>
267
+ <span style="font-weight: bold">]</span>,
268
+ <span style="color: #808000; text-decoration-color: #808000">prod_date</span>=<span style="color: #008000; text-decoration-color: #008000">'2025-01-28'</span>,
269
+ <span style="color: #808000; text-decoration-color: #808000">idno</span>=<span style="color: #008000; text-decoration-color: #008000">'CAMBODIA_LSMS_PLUS_2019_2020_v01_EN'</span>,
270
+ <span style="color: #808000; text-decoration-color: #808000">version_statement</span>=<span style="color: #800080; text-decoration-color: #800080; font-weight: bold">version_statement</span><span style="font-weight: bold">(</span>
271
+ <span style="color: #808000; text-decoration-color: #808000">version</span>=<span style="color: #008000; text-decoration-color: #008000">'1.0'</span>,
272
+ <span style="color: #808000; text-decoration-color: #808000">version_date</span>=<span style="color: #008000; text-decoration-color: #008000">'2025-01-28'</span>,
273
+ <span style="color: #808000; text-decoration-color: #808000">version_resp</span>=<span style="color: #008000; text-decoration-color: #008000">''</span>,
274
+ <span style="color: #808000; text-decoration-color: #808000">version_notes</span>=<span style="color: #008000; text-decoration-color: #008000">'First draft of the metadata for the Cambodia Living Standards Measurement Study - Plus </span>
275
+ <span style="color: #008000; text-decoration-color: #008000">(LSMS+) 2019-20.'</span>
276
+ <span style="font-weight: bold">)</span>
277
+ <span style="font-weight: bold">)</span>,
278
+ ...
279
+
280
+ <span style="font-weight: bold">)</span>
281
+ </pre>
282
+
283
+
284
+
285
+
286
+ # Contributing
287
+ ## Setting up the python environment
288
+
289
+ This library uses Poetry for dependency management (https://python-poetry.org/docs/basic-usage/).
290
+
291
+ In your python environment run `pip install poetry` then navigate to the pymetadataeditor folder and run `poetry install` or, if that doesn't work, try `python -m poetry install`.
292
+
293
+ ### Development python environment
294
+
295
+ If you want to make changes to this repo then you also need to install the tools used for development but which aren't used otherwise, for example pytest.
296
+
297
+ Run:
298
+
299
+ `poetry install --with dev`
300
+ `poetry run pre-commit install`
301
+
302
+ ### Poetry troubleshooting
303
+
304
+ If you are running on Windows and see errors about numpy installation errors then it could be an issue with Windows file paths. With default settings, file paths that exceed a few hundred characters can cause installation problems. To overcome this you can either
305
+
306
+ 1) enable long path support in Windows (https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=powershell#enable-long-paths-in-windows-10-version-1607-and-later)
307
+ 2) install python libraries in a folder in the current directory by running `poetry config virtualenvs.in-project true` and then running `poetry install`
308
+
309
+ ## Notes
310
+
311
+ In keeping with World Bank Group practice, it should be noted that parts of this code base were written with the assistance of ChatGPT.
@@ -0,0 +1 @@
1
+ from .interface import MetadataEditor # noqa