rudi-node-write 1.2.0__tar.gz → 1.2.1__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 (45) hide show
  1. {rudi_node_write-1.2.0/src/rudi_node_write.egg-info → rudi_node_write-1.2.1}/PKG-INFO +1 -1
  2. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/pyproject.toml +2 -2
  3. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/connectors/io_rudi_manager_write.py +12 -8
  4. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/rudi_media.py +8 -1
  5. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/file_utils.py +38 -16
  6. rudi_node_write-1.2.1/src/rudi_node_write/wip/clean_node.py +50 -0
  7. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1/src/rudi_node_write.egg-info}/PKG-INFO +1 -1
  8. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write.egg-info/SOURCES.txt +1 -0
  9. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/LICENCE.md +0 -0
  10. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/README.md +0 -0
  11. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/requirements.txt +0 -0
  12. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/setup.cfg +0 -0
  13. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/__init__.py +0 -0
  14. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/conf/meta_defaults.py +0 -0
  15. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/connectors/io_connector.py +0 -0
  16. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/connectors/io_rudi_api_write.py +0 -0
  17. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/connectors/io_rudi_jwt_factory.py +0 -0
  18. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/connectors/io_rudi_media_write.py +0 -0
  19. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/connectors/rudi_node_auth.py +0 -0
  20. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_node_writer.py +0 -0
  21. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/rudi_const.py +0 -0
  22. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/rudi_contact.py +0 -0
  23. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/rudi_dates.py +0 -0
  24. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/rudi_dictionary_entry.py +0 -0
  25. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/rudi_geo.py +0 -0
  26. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/rudi_licence.py +0 -0
  27. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/rudi_meta.py +0 -0
  28. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/rudi_meta_misc.py +0 -0
  29. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/rudi_org.py +0 -0
  30. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/rudi_types/serializable.py +0 -0
  31. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/dict_utils.py +0 -0
  32. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/err.py +0 -0
  33. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/html_utils.py +0 -0
  34. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/jwt.py +0 -0
  35. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/list_utils.py +0 -0
  36. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/log.py +0 -0
  37. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/str_utils.py +0 -0
  38. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/type_date.py +0 -0
  39. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/typing_utils.py +0 -0
  40. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/utils/url_utils.py +0 -0
  41. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/wip/federation_backup.py +0 -0
  42. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write/wip/rudinode_federation.py +0 -0
  43. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write.egg-info/dependency_links.txt +0 -0
  44. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/src/rudi_node_write.egg-info/top_level.txt +0 -0
  45. {rudi_node_write-1.2.0 → rudi_node_write-1.2.1}/tests/test_rudi_node_write.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rudi-node-write
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: Use the internal API of a RUDI Producer node
5
5
  Author-email: Olivier Martineau <olivier.martineau@irisa.fr>
6
6
  Maintainer-email: Olivier Martineau <olivier.martineau@irisa.fr>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "rudi-node-write"
7
- version = "1.2.0"
7
+ version = "1.2.1"
8
8
  authors = [{ name = "Olivier Martineau", email = "olivier.martineau@irisa.fr" }]
9
9
  maintainers = [{ name = "Olivier Martineau", email = "olivier.martineau@irisa.fr" }]
10
10
  description = "Use the internal API of a RUDI Producer node"
@@ -34,7 +34,7 @@ target-version = ['py311']
34
34
  # ----- Tool: commitizen
35
35
  [tool.commitizen]
36
36
  name = "cz_conventional_commits"
37
- version = "1.2.0"
37
+ version = "1.2.1"
38
38
  version_files = ["pyproject.toml:version"]
39
39
 
40
40
  # ----- Tool: pytest
@@ -55,6 +55,8 @@ def ensure_url_startswith_api(url):
55
55
 
56
56
 
57
57
  def ensure_url_startswith_api_data(url):
58
+ if url.startswith("data"):
59
+ return ensure_url_startswith_api(url)
58
60
  return ensure_url_startswith(url, "api/data")
59
61
 
60
62
 
@@ -367,7 +369,7 @@ class RudiNodeManagerConnector(Connector):
367
369
  if url_bit in RUDI_OBJECT_TYPES:
368
370
  data: list[dict] = self._get_full_obj_list(url_bit)
369
371
  else:
370
- data = self._get_api(url=url_bit, headers=self._pm_headers) # type: ignore
372
+ data = self._get_api(url=url_bit, headers=self._pm_headers, should_log_request=True) # type: ignore
371
373
 
372
374
  self._data_cache[url_bit] = {"data": data, _REFRESH_KEY: time()}
373
375
  obj_data = self._data_cache[url_bit]["data"]
@@ -394,7 +396,7 @@ class RudiNodeManagerConnector(Connector):
394
396
  log_w(here, "Legacy node, request not available for 'media'")
395
397
  return {}
396
398
  else:
397
- return self._get_cache(slash_join("data", obj_type))
399
+ return self._get_cache(ensure_url_startswith(obj_type, "data"))
398
400
 
399
401
  # ----------[ Requesting data ]-------------------------------------------------------------------------------------
400
402
 
@@ -439,7 +441,7 @@ class RudiNodeManagerConnector(Connector):
439
441
 
440
442
  @property
441
443
  def last_metadata_update_date(self) -> Date | None:
442
- res = self.get_data("resources/?sort=-updatedAt&limit=1&fields=updatedAt")
444
+ res = self.get_data("resources?sort=-updatedAt&limit=1&fields=updatedAt")
443
445
  if not isinstance(res, list):
444
446
  raise TypeError(f"The server should have returned a list, got:\n{res}")
445
447
  if len(res) == 0:
@@ -449,7 +451,7 @@ class RudiNodeManagerConnector(Connector):
449
451
 
450
452
  @property
451
453
  def last_data_update_date(self) -> Date | None:
452
- res = self.get_data("resources/?sort=-dataset_dates.updated&limit=1&fields=dataset_dates.updated")
454
+ res = self.get_data("resources?sort=-dataset_dates.updated&limit=1&fields=dataset_dates.updated")
453
455
  print("last_data_update_date", res)
454
456
  if not isinstance(res, list):
455
457
  raise TypeError(f"The server should have returned a list, got:\n{res}")
@@ -1300,12 +1302,11 @@ class FileTooBigException(Exception):
1300
1302
  if __name__ == "__main__": # pragma: no cover
1301
1303
  begin = time()
1302
1304
  tests = "RudiNodeManagerConnector tests"
1303
- creds_file = "../creds/creds_bas.json"
1305
+ creds_file = "../creds/creds_release.json"
1304
1306
  rudi_node_creds = read_json_file(creds_file)
1305
- node_url = rudi_node_creds["url"]
1306
- log_d(tests, "node_url", node_url)
1307
+ pm_url = rudi_node_creds["pm_url"]
1308
+ log_d(tests, "node_url", pm_url)
1307
1309
  auth = RudiNodeAuth.from_json(rudi_node_creds)
1308
- pm_url = slash_join(node_url, "/prodmanager")
1309
1310
 
1310
1311
  pm_connector = RudiNodeManagerConnector(server_url=pm_url, auth=auth)
1311
1312
  pm_connector.test_connection()
@@ -1354,4 +1355,7 @@ if __name__ == "__main__": # pragma: no cover
1354
1355
  )
1355
1356
  except HttpError as e:
1356
1357
  log_w(tests, e)
1358
+
1359
+ log_d(tests, "last_metadata_update_date", pm_connector.last_metadata_update_date)
1360
+ log_d(tests, "last_data_update_date", pm_connector.last_data_update_date)
1357
1361
  log_d(tests, "exec. time", time() - begin)
@@ -52,6 +52,13 @@ def check_is_accepted_value(value, accepted_values: list | None = None):
52
52
  return value
53
53
 
54
54
 
55
+ def get_normalized_type_name(value):
56
+ if isinstance(value, str):
57
+ if value.lower() in ("true", "false"):
58
+ return "bool"
59
+ return get_type_name(value)
60
+
61
+
55
62
  def normalize_connector_values(value, value_type: str | None = None, accepted_values: list | None = None):
56
63
  if value_type is None:
57
64
  type_name = get_type_name(value)
@@ -66,7 +73,7 @@ def normalize_connector_values(value, value_type: str | None = None, accepted_va
66
73
  else:
67
74
  # log_d(here, "in", value, f"({value_type})")
68
75
  normalized_val_type = normalize_connector_parameter_type(value_type)
69
- if normalize_connector_parameter_type(get_type_name(value)) != normalized_val_type:
76
+ if normalize_connector_parameter_type(get_normalized_type_name(value)) != normalized_val_type:
70
77
  raise ValueError(f"incoherence in connector parameter type: input '{value}' is not of type '{value_type}'")
71
78
  return [check_is_accepted_value(value, accepted_values), normalized_val_type, accepted_values]
72
79
 
@@ -70,6 +70,8 @@ def get_file_mime(file_local_path: str) -> str:
70
70
  """
71
71
  file_info = magic_file(file_local_path)
72
72
  if not file_info: # pragma: no cover
73
+ if get_file_extension(file_local_path) == ".csv":
74
+ return "text/csv"
73
75
  return "application/octet-stream"
74
76
  mime_type = file_info[0].mime_type
75
77
  if mime_type == "application/x-gzip": # pragma: no cover
@@ -158,13 +160,17 @@ if __name__ == "__main__": # pragma: no cover
158
160
  tests = "FileUtils"
159
161
  begin = time()
160
162
 
161
- test_file_dir = "../../../tests/_test_files/"
163
+ test_file_dir = "../tests/_test_files/"
162
164
  yaml_file_path = test_file_dir + "RUDI producer internal API - 1.3.0.yml"
163
165
  right_path = test_file_dir + "unicorn.png"
164
166
  bin_file = test_file_dir + "WERTSTOFFE.m8s"
165
167
  tar_gz_file = test_file_dir + "rudi-node-read.tar.gz"
166
168
  txt_file = test_file_dir + "RUDI producer internal API - 1.3.0.yml"
169
+ csv_file = test_file_dir + "dummy.csv"
167
170
  wrong_path = test_file_dir + "toto"
171
+ unicode_file_path = test_file_dir + "unicode_chars.txt"
172
+ write_file(unicode_file_path, "tut0156êµîƒfiÌπÏ“{ëôøÇ¡¶{µœ≤é≤")
173
+
168
174
  log_d(tests, "exists file OK", exists_file(right_path))
169
175
  log_d(tests, "exists file KO", exists_file(wrong_path))
170
176
  log_d(tests, "is file OK", is_file(right_path))
@@ -172,22 +178,38 @@ if __name__ == "__main__": # pragma: no cover
172
178
  log_d(tests, "exists file (dir)", exists_file(test_file_dir))
173
179
  log_d(tests, "is dir a file", is_file(test_file_dir))
174
180
  # log_d(here, 'check_is_file', check_is_file(test_file_dir))
175
- log_d(tests, "file size", get_file_size(right_path))
176
- log_d(tests, "file extension", get_file_extension(right_path))
177
- log_d(tests, "file extension", get_file_extension("foobar.tar.gz"))
178
- log_d(tests, "file extension", get_file_extension("foo.bar.tar.gz"))
179
- log_d(tests, "file extension", get_file_extension(".bashrc"))
180
- log_d(tests, "file extension", get_file_extension(yaml_file_path))
181
- log_d(tests, "file mime", get_file_mime(right_path))
182
- log_d(tests, "file charset", get_file_charset(yaml_file_path))
183
- log_d(tests, "file info", FileDetails(right_path))
184
- log_d(tests, "file info", FileDetails(yaml_file_path))
185
- log_d(tests, "file info", FileDetails(bin_file))
186
- log_d(tests, "file info", FileDetails(tar_gz_file))
187
- log_d(tests, "file info", FileDetails(txt_file))
181
+ for file in [
182
+ right_path,
183
+ "foobar.tar.gz",
184
+ "foo.bar.tar.gz",
185
+ ".bashrc",
186
+ yaml_file_path,
187
+ csv_file,
188
+ bin_file,
189
+ tar_gz_file,
190
+ txt_file,
191
+ unicode_file_path,
192
+ ]:
193
+ if exists_file(file):
194
+ log_d(
195
+ tests,
196
+ f"file: '{file}' ",
197
+ f"\n- exists_file: {exists_file(file)}",
198
+ f"\n- extension: {get_file_extension(file)}",
199
+ f"\n- size: {get_file_size(file)}",
200
+ f"\n- MIME: {get_file_mime(file)}",
201
+ f"\n- charset: {get_file_charset(file)}",
202
+ f"\n- MD5: {get_file_hash(file)}",
203
+ f"\n- info: {FileDetails(file)}",
204
+ )
205
+ else:
206
+ log_d(
207
+ tests,
208
+ f"file: '{file}' ",
209
+ f"\n- exists_file: {exists_file(file)}",
210
+ f"\n- extension: {get_file_extension(file)}",
211
+ )
188
212
  # log_d(here, 'file info', get_file_info(wrong_path))
189
- unicode_file_path = test_file_dir + "unicode_chars.txt"
190
- write_file(unicode_file_path, "tut0156êµîƒfiÌπÏ“{ëôøÇ¡¶{µœ≤é≤")
191
213
 
192
214
  log_d(tests, "unicode file MD5 hash", get_file_hash(unicode_file_path))
193
215
  log_d(tests, "unicode file SHA-256 hash", get_file_hash(unicode_file_path, "sha256"))
@@ -0,0 +1,50 @@
1
+ from abc import ABC
2
+ from concurrent.futures import as_completed, ThreadPoolExecutor
3
+ from dataclasses import dataclass
4
+ from os import cpu_count
5
+ from time import sleep, time
6
+ from typing import Callable
7
+ from urllib.request import urlopen
8
+
9
+ from rudi_node_write.connectors.io_connector import HTTP_REQUEST_METHODS
10
+ from rudi_node_write.connectors.io_rudi_api_write import RudiNodeApiConnector
11
+ from rudi_node_write.connectors.io_rudi_jwt_factory import RudiNodeJwtFactory
12
+ from rudi_node_write.connectors.io_rudi_manager_write import RudiNodeManagerConnector
13
+ from rudi_node_write.connectors.rudi_node_auth import RudiNodeAuth
14
+ from rudi_node_write.rudi_node_writer import RudiNodeWriter
15
+ from rudi_node_write.utils.file_utils import check_is_dir, check_is_file, read_json_file, write_json_file
16
+ from rudi_node_write.utils.log import log_d, log_e, log_w
17
+ from rudi_node_write.utils.str_utils import slash_join
18
+ from rudi_node_write.utils.type_date import Date
19
+ from rudi_node_write.utils.url_utils import ensure_http, ensure_url_startswith
20
+
21
+ if __name__ == "__main__": # pragma: no cover
22
+ begin = time()
23
+ here = "RudiNodeClean"
24
+
25
+ test_dir = check_is_dir("../dwnld")
26
+ data_dir = check_is_dir("../data")
27
+ creds_file = read_json_file("../creds/creds_release.json")
28
+ auth = RudiNodeAuth(b64url_auth=creds_file["b64auth"])
29
+ node = RudiNodeWriter(creds_file["pm_url"], auth, keep_connection=True)
30
+
31
+ for meta in node.metadata_list:
32
+ changed = False
33
+ print(meta["global_id"], ":", meta["access_condition"]["confidentiality"]["gdpr_sensitive"])
34
+ if meta["access_condition"]["confidentiality"]["gdpr_sensitive"] == None:
35
+ meta["access_condition"]["confidentiality"]["gdpr_sensitive"] = False
36
+ changed = True
37
+ # try:
38
+ # if meta["geography"]["geographic_distribution"]["geometry"] == None:
39
+ # del meta["geography"]["geographic_distribution"]["geometry"]
40
+ # changed = True
41
+ # except:
42
+ # pass
43
+ # try:
44
+ # if meta["metadata_info"]["metadata_dates"]["published"] == None:
45
+ # del meta["metadata_info"]["metadata_dates"]["published"]
46
+ # changed = True
47
+ # except:
48
+ # pass
49
+ if changed:
50
+ node.put_metadata(meta)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rudi-node-write
3
- Version: 1.2.0
3
+ Version: 1.2.1
4
4
  Summary: Use the internal API of a RUDI Producer node
5
5
  Author-email: Olivier Martineau <olivier.martineau@irisa.fr>
6
6
  Maintainer-email: Olivier Martineau <olivier.martineau@irisa.fr>
@@ -37,6 +37,7 @@ src/rudi_node_write/utils/str_utils.py
37
37
  src/rudi_node_write/utils/type_date.py
38
38
  src/rudi_node_write/utils/typing_utils.py
39
39
  src/rudi_node_write/utils/url_utils.py
40
+ src/rudi_node_write/wip/clean_node.py
40
41
  src/rudi_node_write/wip/federation_backup.py
41
42
  src/rudi_node_write/wip/rudinode_federation.py
42
43
  tests/test_rudi_node_write.py