commonmeta-py 0.124__py3-none-any.whl → 0.125__py3-none-any.whl

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.
commonmeta/__init__.py CHANGED
@@ -10,7 +10,7 @@ commonmeta-py is a Python library to convert scholarly metadata
10
10
  """
11
11
 
12
12
  __title__ = "commonmeta-py"
13
- __version__ = "0.124"
13
+ __version__ = "0.125"
14
14
  __author__ = "Martin Fenner"
15
15
  __license__ = "MIT"
16
16
 
commonmeta/metadata.py CHANGED
@@ -476,8 +476,9 @@ class MetadataList:
476
476
  elif to == "datacite":
477
477
  raise ValueError("Datacite not yet supported for metadata lists")
478
478
  elif to == "inveniordm":
479
+ kwargs = {"legacy_key": self.legacy_key}
479
480
  response = push_inveniordm_list(
480
- self, host=self.host, token=self.token, legacy_key=self.legacy_key
481
+ self, host=self.host, token=self.token, **kwargs
481
482
  )
482
483
  return response
483
484
  else:
@@ -8,7 +8,9 @@ import xmlschema
8
8
  from jsonschema import Draft202012Validator, ValidationError
9
9
 
10
10
 
11
- def json_schema_errors(instance: Dict[str, Any], schema: str = "commonmeta") -> Optional[str]:
11
+ def json_schema_errors(
12
+ instance: Dict[str, Any], schema: str = "commonmeta"
13
+ ) -> Optional[str]:
12
14
  """validate against JSON schema"""
13
15
  schema_map = {
14
16
  "commonmeta": "commonmeta_v0.16",
@@ -31,7 +33,9 @@ def json_schema_errors(instance: Dict[str, Any], schema: str = "commonmeta") ->
31
33
  return error.message
32
34
 
33
35
 
34
- def xml_schema_errors(instance: Union[str, bytes], schema: str = "crossref_xml") -> Optional[Union[bool, Exception]]:
36
+ def xml_schema_errors(
37
+ instance: Union[str, bytes], schema: str = "crossref_xml"
38
+ ) -> Optional[Union[bool, Exception]]:
35
39
  """validate against XML schema"""
36
40
  schema_map = {
37
41
  "crossref_xml": "crossref5.4.0",
@@ -385,7 +385,9 @@ def write_crossref_xml_list(metalist) -> Optional[str]:
385
385
  return unparse_xml_list(crossref_xml_list, dialect="crossref", head=head)
386
386
 
387
387
 
388
- def push_crossref_xml_list(metalist, login_id: str, login_passwd: str, legacy_key:str=None) -> bytes:
388
+ def push_crossref_xml_list(
389
+ metalist, login_id: str, login_passwd: str, legacy_key: str = None
390
+ ) -> bytes:
389
391
  """Push crossref_xml list to Crossref API, returns the API response."""
390
392
 
391
393
  input = write_crossref_xml_list(metalist)
@@ -426,28 +428,21 @@ def push_crossref_xml_list(metalist, login_id: str, login_passwd: str, legacy_ke
426
428
  items = []
427
429
  for item in metalist.items:
428
430
  record = {
429
- "doi": item.id,
430
- "updated": datetime.now().isoformat("T", "seconds"),
431
- "status": "submitted",
432
- }
431
+ "doi": item.id,
432
+ "updated": datetime.now().isoformat("T", "seconds"),
433
+ "status": "submitted",
434
+ }
433
435
 
434
436
  # update rogue-scholar legacy record if legacy_key is provided
435
437
  if is_rogue_scholar_doi(item.id, ra="crossref") and legacy_key is not None:
436
- record["uuid"] = py_.get(item, "identifiers.0.identifier")
437
- record = update_legacy_record(record, legacy_key=legacy_key, field="doi")
438
+ record["uuid"] = py_.get(item, "identifiers.0.identifier")
439
+ record = update_legacy_record(record, legacy_key=legacy_key, field="doi")
438
440
  items.append(record)
439
441
 
440
442
  # Return JSON response
441
443
  return json.dumps(items, option=json.OPT_INDENT_2)
442
444
 
443
445
 
444
-
445
-
446
-
447
-
448
-
449
-
450
-
451
446
  def get_attributes(obj, **kwargs) -> dict:
452
447
  """Get root attributes"""
453
448
  return compact(
@@ -4,7 +4,6 @@ import logging
4
4
  import re
5
5
  from time import time
6
6
  from typing import Dict, Optional
7
- from urllib.parse import urlparse
8
7
 
9
8
  import orjson as json
10
9
  import pydash as py_
@@ -32,6 +31,7 @@ from ..utils import (
32
31
 
33
32
  logger = logging.getLogger(__name__)
34
33
 
34
+
35
35
  def write_inveniordm(metadata):
36
36
  """Write inveniordm"""
37
37
  if metadata is None or metadata.write_errors is not None:
@@ -387,123 +387,161 @@ def write_inveniordm_list(metalist):
387
387
  return [write_inveniordm(item) for item in metalist.items]
388
388
 
389
389
 
390
- def push_inveniordm(
391
- metadata: Commonmeta,
392
- host: str,
393
- token: str,
394
- legacy_key: str
395
- ) -> Dict:
390
+ def push_inveniordm(metadata: Commonmeta, host: str, token: str, **kwargs) -> Dict:
396
391
  """Push record to InvenioRDM"""
397
392
 
398
- record = {}
399
- output = write_inveniordm(metadata)
400
-
401
393
  try:
402
- # Remove IsPartOf relation with InvenioRDM community identifier after storing it
403
- # community_index = None
404
- # if hasattr(metadata, "relations") and metadata.relations:
405
- # for i, relation in enumerate(metadata.relations):
406
- # if relation.get("type") == "IsPartOf" and relation.get(
407
- # "id", ""
408
- # ).startswith("https://rogue-scholar.org/api/communities/"):
409
- # slug = relation.get("id").split("/")[5]
410
- # community_id, _ = search_by_slug(slug, "blog", host, token)
411
- # if community_id:
412
- # record["community"] = slug
413
- # record["community_id"] = community_id
414
- # community_index = i
415
-
416
- # # Remove the relation if we found and processed it
417
- # if community_index is not None and hasattr(metadata, "relations"):
418
- # metadata.relations.pop(community_index)
419
-
420
- # Remove InvenioRDM rid after storing it
421
- # rid_index = None
422
- # if hasattr(metadata, "identifiers") and metadata.identifiers:
423
- # for i, identifier in enumerate(metadata.identifiers):
424
- # if identifier.get("identifierType") == "RID" and identifier.get("identifier"):
425
- # record["id"] = identifier.get("identifier")
426
- # rid_index = i
427
- # elif identifier.get("identifierType") == "UUID" and identifier.get("identifier"):
428
- # record["uuid"] = identifier.get("identifier")
429
-
430
- # # Remove the identifier if we found and processed it
431
- # if rid_index is not None and hasattr(metadata, "identifiers"):
432
- # metadata.identifiers.pop(rid_index)
433
-
434
- # Check if record already exists in InvenioRDM
435
- record["id"] = search_by_doi(doi_from_url(metadata.id), host, token)
436
-
437
- if record["id"] is not None:
438
- # Create draft record from published record
439
- record = edit_published_record(record, host, token)
440
-
441
- # Update draft record
442
- record = update_draft_record(record, host, token, output)
443
- else:
444
- # Create draft record
445
- record = create_draft_record(record, host, token, output)
446
-
447
- # Publish draft record
448
- record = publish_draft_record(record, host, token)
449
-
450
- # Add record to blog community if blog community is specified and exists
451
- if record.get("community_id", None) is not None:
452
- record = add_record_to_community(
453
- record, host, token, record["community_id"]
454
- )
455
-
456
- # Add record to subject area community if subject area community is specified and exists
457
- # Subject area communities should exist for all subjects in the FOSMappings
458
-
459
- if hasattr(metadata, "subjects"):
460
- for subject in metadata.subjects:
461
- subject_name = subject.get("subject", "")
462
- slug = string_to_slug(subject_name)
463
- if slug in COMMUNITY_TRANSLATIONS:
464
- slug = COMMUNITY_TRANSLATIONS[slug]
465
-
466
- community_id = search_by_slug(slug, "topic", host, token)
467
- if community_id:
468
- record = add_record_to_community(record, host, token, community_id)
469
-
470
- # Add record to communities defined as IsPartOf relation in inveniordm metadata's RelatedIdentifiers
471
- related_identifiers = py_.get(input, "metadata.related_identifiers")
394
+ doi = normalize_doi(metadata.id)
395
+ if doi is None:
396
+ raise ValueError("no doi provided")
472
397
 
473
- for identifier in wrap(related_identifiers):
474
- if py_.get(identifier, "relation_type.id") == "ispartof":
475
- parsed_url = urlparse(identifier.get("identifier", ""))
476
- path_parts = parsed_url.path.split("/")
398
+ record = {
399
+ "doi": doi,
400
+ }
477
401
 
478
- if (
479
- parsed_url.netloc == urlparse(host).netloc
480
- and len(path_parts) == 3
481
- and path_parts[1] == "communities"
402
+ # extract optional information needed but not upserted to the InvenioRDM API:
403
+ # rid is the InvenioRDM record id,
404
+ # uuid is the Rogue Scholar uuid,
405
+ # community_id is the id of the primary community of the record
406
+ if hasattr(metadata, "identifiers") and metadata.identifiers:
407
+ rid_index = None
408
+ uuid_index = None
409
+ for i, identifier in enumerate(metadata.identifiers):
410
+ if identifier.get("identifierType") == "RID" and identifier.get(
411
+ "identifier"
412
+ ):
413
+ record["id"] = identifier.get("identifier")
414
+ rid_index = i
415
+ elif identifier.get("identifierType") == "UUID" and identifier.get(
416
+ "identifier"
482
417
  ):
483
- record = add_record_to_community(record, host, token, path_parts[2])
418
+ record["uuid"] = identifier.get("identifier")
419
+ uuid_index = i
420
+ if rid_index is not None:
421
+ metadata.identifiers.pop(rid_index)
422
+ if uuid_index is not None:
423
+ metadata.identifiers.pop(rid_index)
424
+
425
+ if hasattr(metadata, "relations") and metadata.relations:
426
+ community_index = None
427
+ for i, relation in enumerate(metadata.relations):
428
+ if relation.get("type") == "IsPartOf" and relation.get(
429
+ "id", ""
430
+ ).startswith(f"https://{host}/api/communities/"):
431
+ slug = relation.get("id").split("/")[5]
432
+ community_id = search_by_slug(slug, "blog", host, token)
433
+ if community_id:
434
+ record["community"] = slug
435
+ record["community_id"] = community_id
436
+ community_index = i
437
+
438
+ if community_index is not None:
439
+ metadata.relations.pop(community_index)
440
+
441
+ # upsert record via the InvenioRDM API
442
+ record = upsert_record(metadata, host, token, record)
443
+
444
+ # optionally add record to InvenioRDM communities
445
+ record = add_record_to_communities(metadata, host, token, record)
446
+
447
+ # optionally update external services
448
+ record = update_external_services(metadata, host, token, record, **kwargs)
484
449
 
485
- # optionally update rogue-scholar legacy record
486
- if host == "rogue-scholar.org" and legacy_key is not None:
487
- record = update_legacy_record(record, legacy_key=legacy_key, field="rid")
488
450
  except Exception as e:
489
- logger.error(f"Unexpected error in push_inveniordm: {str(e)}", exc_info=True, extra={
490
- "host": host,
491
- "record_id": record.get("id")
492
- })
451
+ logger.error(
452
+ f"Unexpected error in push_inveniordm: {str(e)}",
453
+ exc_info=True,
454
+ extra={"host": host, "record_id": record.get("id")},
455
+ )
493
456
  record["status"] = "error"
494
457
 
495
458
  return record
496
459
 
497
460
 
498
- def push_inveniordm_list(metalist, host: str, token: str, legacy_key: str) -> list:
461
+ def push_inveniordm_list(metalist, host: str, token: str, **kwargs) -> list:
499
462
  """Push inveniordm list to InvenioRDM, returns list of push results."""
500
463
 
501
464
  if metalist is None:
502
465
  return None
503
- items = [push_inveniordm(item, host, token, legacy_key) for item in metalist.items]
466
+ items = [push_inveniordm(item, host, token, **kwargs) for item in metalist.items]
504
467
  return json.dumps(items, option=json.OPT_INDENT_2)
505
468
 
506
469
 
470
+ def upsert_record(metadata: Commonmeta, host: str, token: str, record: dict) -> dict:
471
+ """Upsert InvenioRDM record, based on DOI"""
472
+
473
+ output = write_inveniordm(metadata)
474
+
475
+ # Check if record already exists in InvenioRDM
476
+ record["id"] = search_by_doi(doi_from_url(record.get("doi")), host, token)
477
+
478
+ if record["id"] is not None:
479
+ # Create draft record from published record
480
+ record = edit_published_record(record, host, token)
481
+
482
+ # Update draft record
483
+ record = update_draft_record(record, host, token, output)
484
+ else:
485
+ # Create draft record
486
+ record = create_draft_record(record, host, token, output)
487
+
488
+ # Publish draft record
489
+ record = publish_draft_record(record, host, token)
490
+
491
+ return record
492
+
493
+
494
+ def add_record_to_communities(
495
+ metadata: Commonmeta, host: str, token: str, record: dict
496
+ ) -> dict:
497
+ """Add record to one or more InvenioRDM communities"""
498
+
499
+ # Add record to primary community if primary community is specified
500
+ if record.get("community_id", None) is not None:
501
+ record = add_record_to_community(record, host, token, record["community_id"])
502
+
503
+ # Add record to subject area community if subject area community is specified
504
+ # Subject area communities should exist for all OECD subject areas
505
+
506
+ if hasattr(metadata, "subjects"):
507
+ for subject in metadata.subjects:
508
+ subject_name = subject.get("subject", "")
509
+ slug = string_to_slug(subject_name)
510
+ if slug in COMMUNITY_TRANSLATIONS:
511
+ slug = COMMUNITY_TRANSLATIONS[slug]
512
+
513
+ community_id = search_by_slug(slug, "topic", host, token)
514
+ if community_id:
515
+ record = add_record_to_community(record, host, token, community_id)
516
+
517
+ # Add record to communities defined as IsPartOf relation in InvenioRDM RelatedIdentifiers
518
+ if hasattr(metadata, "related_identifiers") and metadata.related_identifiers:
519
+ for identifier in metadata.related_identifiers:
520
+ if py_.get(identifier, "relation_type.id") == "ispartof" and identifier.get(
521
+ "identifier", ""
522
+ ).startswith(f"https://{host}/api/communities/"):
523
+ slug = identifier.get("identifier").split("/")[5]
524
+ community_id = search_by_slug(slug, "topic", host, token)
525
+ if community_id:
526
+ record = add_record_to_community(record, host, token, community_id)
527
+
528
+ return record
529
+
530
+
531
+ def update_external_services(
532
+ metadata: Commonmeta, host: str, token: str, record: dict, **kwargs
533
+ ) -> dict:
534
+ """Update external services with changes in InvenioRDM"""
535
+
536
+ # optionally update rogue-scholar legacy record
537
+ if host == "rogue-scholar.org" and kwargs.get("legacy_key", None) is not None:
538
+ record = update_legacy_record(
539
+ record, legacy_key=kwargs.get("legacy_key"), field="rid"
540
+ )
541
+
542
+ return record
543
+
544
+
507
545
  def search_by_doi(doi, host, token) -> Optional[str]:
508
546
  """Search for a record by DOI in InvenioRDM"""
509
547
  headers = {
@@ -539,7 +577,9 @@ def create_draft_record(record, host, token, output):
539
577
  record["status"] = "failed_rate_limited"
540
578
  return record
541
579
  if response.status_code != 201:
542
- logger.error(f"Failed to create draft record: {response.status_code} - {response.json()}")
580
+ logger.error(
581
+ f"Failed to create draft record: {response.status_code} - {response.json()}"
582
+ )
543
583
  record["status"] = "failed_create_draft"
544
584
  return record
545
585
  data = response.json()
@@ -570,7 +610,9 @@ def edit_published_record(record, host, token):
570
610
  record["status"] = "edited"
571
611
  return record
572
612
  except requests.exceptions.RequestException as e:
573
- logger.error(f"Error creating draft from published record: {str(e)}", exc_info=True)
613
+ logger.error(
614
+ f"Error creating draft from published record: {str(e)}", exc_info=True
615
+ )
574
616
  record["status"] = "error_edit_published_record"
575
617
  return record
576
618
 
@@ -616,12 +658,14 @@ def publish_draft_record(record, host, token):
616
658
  record["status"] = "failed_rate_limited"
617
659
  return record
618
660
  if response.status_code != 202:
619
- logger.error(f"Failed to publish draft record: {response.status_code} - {response.json()}")
661
+ logger.error(
662
+ f"Failed to publish draft record: {response.status_code} - {response.json()}"
663
+ )
620
664
  record["status"] = "error_publish_draft_record"
621
665
  return record
622
666
  data = response.json()
623
667
  record["uuid"] = py_.get(data, "metadata.identifiers.0.identifier")
624
- record["doi"] = doi_as_url(py_.get(data, "pids.doi.identifier")),
668
+ record["doi"] = (doi_as_url(py_.get(data, "pids.doi.identifier")),)
625
669
  record["created"] = data.get("created", None)
626
670
  record["updated"] = data.get("updated", None)
627
671
  record["status"] = "published"
@@ -651,7 +695,7 @@ def add_record_to_community(record, host, token, community_id):
651
695
  return record
652
696
 
653
697
 
654
- def update_legacy_record(record, legacy_key: str, field:str=None) -> dict:
698
+ def update_legacy_record(record, legacy_key: str, field: str = None) -> dict:
655
699
  """Update corresponding record in Rogue Scholar legacy database."""
656
700
 
657
701
  legacy_host = "bosczcmeodcrajtcaddf.supabase.co"
@@ -678,7 +722,7 @@ def update_legacy_record(record, legacy_key: str, field:str=None) -> dict:
678
722
  }
679
723
  else:
680
724
  print(f"nothing to update for id {record.get('uuid')}")
681
- return record # nothing to update
725
+ return record # nothing to update
682
726
 
683
727
  request_url = f"https://{legacy_host}/rest/v1/posts?id=eq.{record['uuid']}"
684
728
  headers = {
@@ -700,7 +744,7 @@ def update_legacy_record(record, legacy_key: str, field:str=None) -> dict:
700
744
  return record
701
745
 
702
746
 
703
- def search_by_slug(slug, type_value, host, token) -> Optional[str]:
747
+ def search_by_slug(slug: str, type_value: str, host: str, token: str) -> Optional[str]:
704
748
  """Search for a community by slug in InvenioRDM"""
705
749
  headers = {
706
750
  "Authorization": f"Bearer {token}",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: commonmeta-py
3
- Version: 0.124
3
+ Version: 0.125
4
4
  Summary: Library for conversions to/from the Commonmeta scholarly metadata format
5
5
  Project-URL: Homepage, https://python.commonmeta.org
6
6
  Project-URL: Repository, https://github.com/front-matter/commonmeta-py
@@ -1,4 +1,4 @@
1
- commonmeta/__init__.py,sha256=pp3RcQ6mEgusaIHYnKMwYYMDh-6dGBRUhu2jP0ecdHw,2098
1
+ commonmeta/__init__.py,sha256=kDEzO2vW7BmMnXyZBc8T6XAN6gxwn0MRTRDOeTYdME8,2098
2
2
  commonmeta/api_utils.py,sha256=P8LMHHYiF4OTi97_5k4KstcBreooMkOAKZ4ebxsAv4o,2691
3
3
  commonmeta/author_utils.py,sha256=3lYW5s1rOUWNTKs1FP6XLfEUY3yCLOe_3L_VdJTDMp0,8585
4
4
  commonmeta/base_utils.py,sha256=-MGy9q2uTiJEkPWQUYOJMdq-3tRpNnvBwlLjvllQ5g8,11164
@@ -7,8 +7,8 @@ commonmeta/constants.py,sha256=wSTEUiHeRdXLwjXEQD9AU2hxFyEKi5OTX2iHOKO6nF0,19844
7
7
  commonmeta/date_utils.py,sha256=H2cCobX0JREIUOT_cCigGd3MG7prGiQpXk1m4ZNrFwU,6318
8
8
  commonmeta/doi_utils.py,sha256=cOogLatKg6qea2jgMd3yLALSTfaTNUgr-IkBXIK4xZw,11498
9
9
  commonmeta/file_utils.py,sha256=eFYDWyR8Gr722nvFmp542hCm-TGmO_q4ciZ85IPHpjA,2893
10
- commonmeta/metadata.py,sha256=_N9suKA10uiWU5-3a349x-H9VbhzEZ6rQ1PqXOCiinA,18408
11
- commonmeta/schema_utils.py,sha256=O6OxiySUrvnNJvslJLY86RFu2HldrZFi21OaLXnV3mA,1912
10
+ commonmeta/metadata.py,sha256=90aTe47d071wHxwcNsOqU5lSVPKP8wAPnPHhddj3Fuo,18443
11
+ commonmeta/schema_utils.py,sha256=zn3gqAHciUOQmrw9okR68weFs-yqPPyORFt-Zl1D3Lw,1924
12
12
  commonmeta/translators.py,sha256=CBMK4jrXRmGZiAhCh6wsJjhbDJWbcsda8UvXFXxccAw,1363
13
13
  commonmeta/utils.py,sha256=pJnh3EzOU1E2nutnAZsopY_NsUX6zYmxoj5bIYqqWvE,50574
14
14
  commonmeta/readers/__init__.py,sha256=vOf7UsOKNoh_ZCuyexxhAmPMt8wjB-pF_CfpWRaN8pk,45
@@ -77,14 +77,14 @@ commonmeta/writers/__init__.py,sha256=47-snms6xBHkoEXKYV1DBtH1npAtlVtvY29Z4Zr45q
77
77
  commonmeta/writers/bibtex_writer.py,sha256=doAdyl1NEp60mPkHPo3GMH8B-HA6MzLAdlyNsIecTzU,4972
78
78
  commonmeta/writers/citation_writer.py,sha256=qs_4X3BjrSqHexmJFPvPDTp0mRIqzb0F70_Wuc7S9x0,2343
79
79
  commonmeta/writers/commonmeta_writer.py,sha256=QpfyhG__7o_XpsOTCPWxGymO7YKwZi2LQh8Zic44bdc,1365
80
- commonmeta/writers/crossref_xml_writer.py,sha256=cGrX9vacNwDdK7TbH1RWig68SH8hg5VusuqkI9gU1DY,33931
80
+ commonmeta/writers/crossref_xml_writer.py,sha256=rcPOfrGxU4mX7_fFywYWDW2FFUoKW9wD-JzW8nX1ipI,33915
81
81
  commonmeta/writers/csl_writer.py,sha256=4gDYs1EzK4_L2UIRTfs25wgHmYRwdRP2zmfxF9387oU,2779
82
82
  commonmeta/writers/datacite_writer.py,sha256=bcinpwhq7XnVthKHH8-sdXA34dSlvFH4ImYH768iaQU,6428
83
- commonmeta/writers/inveniordm_writer.py,sha256=2CD2XYThHgZhUUeVVzZU6A_p6lOz7Xdt0Ij4Zy_E1PM,25772
83
+ commonmeta/writers/inveniordm_writer.py,sha256=ARNssMUhwckAGwzz2ugJoLjVSTezbyLrK2c-utdmins,26795
84
84
  commonmeta/writers/ris_writer.py,sha256=3SdyEvMRaPRP1SV1MB-MXBlunE7x6og7RF1zuWtetPc,2094
85
85
  commonmeta/writers/schema_org_writer.py,sha256=s18_x0ReXwAGBoEAwp2q-HCgFQ-h5qRg6JyAlqCoSFE,5871
86
- commonmeta_py-0.124.dist-info/METADATA,sha256=t0hoWqdbSD8HDjdOpJtoxhjb9_coYI_z9wBMgN5VZIU,7656
87
- commonmeta_py-0.124.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
88
- commonmeta_py-0.124.dist-info/entry_points.txt,sha256=U4w4BoRuS3rN5t5Y-uYSyOeU5Lh_VRVMS9OIDzIgw4w,50
89
- commonmeta_py-0.124.dist-info/licenses/LICENSE,sha256=wsIvxF9Q9GC9vA_s79zTWP3BkXJdfUNRmALlU8GbW1s,1074
90
- commonmeta_py-0.124.dist-info/RECORD,,
86
+ commonmeta_py-0.125.dist-info/METADATA,sha256=x7HcPVeiOM03np_p5URA_xH84RGt-8HO7tF3oV7xoB4,7656
87
+ commonmeta_py-0.125.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
88
+ commonmeta_py-0.125.dist-info/entry_points.txt,sha256=U4w4BoRuS3rN5t5Y-uYSyOeU5Lh_VRVMS9OIDzIgw4w,50
89
+ commonmeta_py-0.125.dist-info/licenses/LICENSE,sha256=wsIvxF9Q9GC9vA_s79zTWP3BkXJdfUNRmALlU8GbW1s,1074
90
+ commonmeta_py-0.125.dist-info/RECORD,,