commonmeta-py 0.116__py3-none-any.whl → 0.118__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.116"
13
+ __version__ = "0.118"
14
14
  __author__ = "Martin Fenner"
15
15
  __license__ = "MIT"
16
16
 
@@ -1,8 +1,9 @@
1
1
  """InvenioRDM writer for commonmeta-py"""
2
2
 
3
+ import logging
3
4
  import re
4
5
  from time import time
5
- from typing import Optional
6
+ from typing import Any, Dict, Optional, Tuple
6
7
  from urllib.parse import urlparse
7
8
 
8
9
  import orjson as json
@@ -15,6 +16,7 @@ from ..constants import (
15
16
  COMMUNITY_TRANSLATIONS,
16
17
  CROSSREF_FUNDER_ID_TO_ROR_TRANSLATIONS,
17
18
  INVENIORDM_IDENTIFIER_TYPES,
19
+ Commonmeta,
18
20
  )
19
21
  from ..date_utils import get_iso8601_date
20
22
  from ..doi_utils import doi_from_url, normalize_doi
@@ -28,6 +30,7 @@ from ..utils import (
28
30
  validate_ror,
29
31
  )
30
32
 
33
+ logger = logging.getLogger(__name__)
31
34
 
32
35
  def write_inveniordm(metadata):
33
36
  """Write inveniordm"""
@@ -384,7 +387,12 @@ def write_inveniordm_list(metalist):
384
387
  return [write_inveniordm(item) for item in metalist.items]
385
388
 
386
389
 
387
- def push_inveniordm(metadata, host: str, token: str, legacy_key: str):
390
+ def push_inveniordm(
391
+ metadata: Commonmeta,
392
+ host: str,
393
+ token: str,
394
+ legacy_key: str
395
+ ) -> Tuple[Dict[str, Any], Optional[Exception]]:
388
396
  """Push record to InvenioRDM"""
389
397
 
390
398
  record = {}
@@ -392,22 +400,22 @@ def push_inveniordm(metadata, host: str, token: str, legacy_key: str):
392
400
 
393
401
  try:
394
402
  # Remove IsPartOf relation with InvenioRDM community identifier after storing it
395
- community_index = None
396
- if hasattr(metadata, "relations") and metadata.relations:
397
- for i, relation in enumerate(metadata.relations):
398
- if relation.get("type") == "IsPartOf" and relation.get(
399
- "id", ""
400
- ).startswith("https://rogue-scholar.org/api/communities/"):
401
- slug = relation.get("id").split("/")[5]
402
- community_id, _ = search_by_slug(slug, "blog", host, token)
403
- if community_id:
404
- record["community"] = slug
405
- record["community_id"] = community_id
406
- community_index = i
407
-
408
- # Remove the relation if we found and processed it
409
- if community_index is not None and hasattr(metadata, "relations"):
410
- metadata.relations.pop(community_index)
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)
411
419
 
412
420
  # Remove InvenioRDM rid after storing it
413
421
  # rid_index = None
@@ -450,7 +458,8 @@ def push_inveniordm(metadata, host: str, token: str, legacy_key: str):
450
458
 
451
459
  if hasattr(metadata, "subjects"):
452
460
  for subject in metadata.subjects:
453
- slug = string_to_slug(subject.get("subject", ""))
461
+ subject_name = subject.get("subject", "")
462
+ slug = string_to_slug(subject_name)
454
463
  if slug in COMMUNITY_TRANSLATIONS:
455
464
  slug = COMMUNITY_TRANSLATIONS[slug]
456
465
 
@@ -477,7 +486,11 @@ def push_inveniordm(metadata, host: str, token: str, legacy_key: str):
477
486
  if host == "rogue-scholar.org" and legacy_key is not None:
478
487
  record = update_legacy_record(record, legacy_key)
479
488
  except Exception as e:
480
- raise InvenioRDMError(f"Unexpected error: {str(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
+ })
493
+ record["status"] = "error"
481
494
 
482
495
  return record
483
496
 
@@ -504,11 +517,12 @@ def search_by_doi(doi, host, token) -> Optional[str]:
504
517
  )
505
518
  response.raise_for_status()
506
519
  data = response.json()
507
- if py_.get(data, "hits.total") or 0 > 0:
520
+ if py_.get(data, "hits.total", 0) > 0:
508
521
  return py_.get(data, "hits.hits.0.id")
509
522
  return None
510
523
  except requests.exceptions.RequestException as e:
511
- raise InvenioRDMError(f"Error searching for DOI: {str(e)}")
524
+ logger.error(f"Error searching for DOI {doi}: {str(e)}", exc_info=True)
525
+ return None
512
526
 
513
527
 
514
528
  def create_draft_record(record, host, token, input):
@@ -525,17 +539,19 @@ def create_draft_record(record, host, token, input):
525
539
  record["status"] = "failed_rate_limited"
526
540
  return record
527
541
  if response.status_code != 201:
528
- print(response.json())
542
+ logger.error(f"Failed to create draft record: {response.status_code} - {response.json()}")
529
543
  record["status"] = "failed_create_draft"
530
544
  return record
531
545
  data = response.json()
532
- record["id"]: data.get("id", None)
546
+ record["id"] = data.get("id", None)
533
547
  record["created"] = data.get("created", None)
534
548
  record["updated"] = data.get("updated", None)
535
549
  record["status"] = "draft"
536
550
  return record
537
551
  except requests.exceptions.RequestException as e:
538
- raise InvenioRDMError(f"Error creating draft record: {str(e)}")
552
+ logger.error(f"Error creating draft record: {str(e)}", exc_info=True)
553
+ record["status"] = "error_draft"
554
+ return record
539
555
 
540
556
 
541
557
  def edit_published_record(record, host, token):
@@ -554,7 +570,9 @@ def edit_published_record(record, host, token):
554
570
  record["status"] = "edited"
555
571
  return record
556
572
  except requests.exceptions.RequestException as e:
557
- raise InvenioRDMError(f"Error creating draft from published record: {str(e)}")
573
+ logger.error(f"Error creating draft from published record: {str(e)}", exc_info=True)
574
+ record["status"] = "error_edit_published_record"
575
+ return record
558
576
 
559
577
 
560
578
  def update_draft_record(record, host, token, inveniordm_data):
@@ -576,7 +594,9 @@ def update_draft_record(record, host, token, inveniordm_data):
576
594
  record["status"] = "updated"
577
595
  return record
578
596
  except requests.exceptions.RequestException as e:
579
- raise InvenioRDMError(f"Error updating draft record: {str(e)}")
597
+ logger.error(f"Error updating draft record: {str(e)}", exc_info=True)
598
+ record["status"] = "error_update_draft_record"
599
+ return record
580
600
 
581
601
 
582
602
  def publish_draft_record(record, host, token):
@@ -585,9 +605,10 @@ def publish_draft_record(record, host, token):
585
605
  "Authorization": f"Bearer {token}",
586
606
  "Content-Type": "application/json",
587
607
  }
588
- if not record.get("id", None):
589
- raise InvenioRDMError("Error publishing draft record")
590
608
  try:
609
+ if not record.get("id", None):
610
+ raise InvenioRDMError("Missing record id")
611
+
591
612
  response = requests.post(
592
613
  f"https://{host}/api/records/{record['id']}/draft/actions/publish",
593
614
  headers=headers,
@@ -596,8 +617,8 @@ def publish_draft_record(record, host, token):
596
617
  record["status"] = "failed_rate_limited"
597
618
  return record
598
619
  if response.status_code != 202:
599
- print(response.json())
600
- record["status"] = "failed_publish_draft"
620
+ logger.error(f"Failed to publish draft record: {response.status_code} - {response.json()}")
621
+ record["status"] = "error_publish_draft_record"
601
622
  return record
602
623
  data = response.json()
603
624
  record["uuid"] = py_.get(data, "metadata.identifiers.0.identifier")
@@ -606,7 +627,9 @@ def publish_draft_record(record, host, token):
606
627
  record["status"] = "published"
607
628
  return record
608
629
  except requests.exceptions.RequestException as e:
609
- raise InvenioRDMError(f"Error publishing draft record: {str(e)}")
630
+ logger.error(f"Error publishing draft record: {str(e)}", exc_info=True)
631
+ record["status"] = "error_publish_draft_record"
632
+ return record
610
633
 
611
634
 
612
635
  def add_record_to_community(record, host, token, community_id):
@@ -624,49 +647,47 @@ def add_record_to_community(record, host, token, community_id):
624
647
  response.raise_for_status()
625
648
  return record
626
649
  except requests.exceptions.RequestException as e:
627
- raise InvenioRDMError(f"Error adding record to community: {str(e)}")
650
+ logger.error(f"Error adding record to community: {str(e)}", exc_info=True)
651
+ return record
628
652
 
629
653
 
630
654
  def update_legacy_record(record, legacy_key: str):
631
655
  """Update corresponding record in Rogue Scholar legacy database."""
632
656
 
633
657
  legacy_host = "bosczcmeodcrajtcaddf.supabase.co"
634
-
635
- if not legacy_key:
636
- raise ValueError("no legacy key provided")
637
- if not record.get("uuid", None):
638
- raise ValueError("no UUID provided")
639
-
640
- now = f"{int(time())}"
641
- if record.get("id", None) is not None:
642
- output = {
643
- "rid": record.get("id"),
644
- "indexed_at": now,
645
- "indexed": "true",
646
- "archived": "true",
647
- }
648
- elif record.get("doi", None) is not None:
649
- output = {
650
- "doi": record.get("doi"),
651
- "indexed_at": now,
652
- "indexed": "true",
653
- "archived": "true",
654
- }
655
- else:
656
- print(f"nothing to update for id {record.get("uuid")}")
657
- return record # nothing to update
658
-
659
- request_url = f"https://{legacy_host}/rest/v1/posts?id=eq.{record['uuid']}"
660
- headers = {
661
- "Content-Type": "application/json",
662
- "apikey": legacy_key,
663
- "Authorization": f"Bearer {legacy_key}",
664
- "Prefer": "return=minimal",
665
- }
666
-
667
658
  try:
659
+ if not legacy_key:
660
+ raise ValueError("no legacy key provided")
661
+ if not record.get("uuid", None):
662
+ raise ValueError("no UUID provided")
663
+
664
+ now = f"{int(time())}"
665
+ if record.get("id", None) is not None:
666
+ output = {
667
+ "rid": record.get("id"),
668
+ "indexed_at": now,
669
+ "indexed": "true",
670
+ "archived": "true",
671
+ }
672
+ elif record.get("doi", None) is not None:
673
+ output = {
674
+ "doi": record.get("doi"),
675
+ "indexed_at": now,
676
+ "indexed": "true",
677
+ "archived": "true",
678
+ }
679
+ else:
680
+ print(f"nothing to update for id {record.get("uuid")}")
681
+ return record # nothing to update
682
+
683
+ request_url = f"https://{legacy_host}/rest/v1/posts?id=eq.{record['uuid']}"
684
+ headers = {
685
+ "Content-Type": "application/json",
686
+ "apikey": legacy_key,
687
+ "Authorization": f"Bearer {legacy_key}",
688
+ "Prefer": "return=minimal",
689
+ }
668
690
  response = requests.patch(request_url, json=output, headers=headers, timeout=30)
669
- response.raise_for_status()
670
691
  if response.status_code != 204:
671
692
  return Exception(f"Unexpected status code: {response.status_code}")
672
693
 
@@ -674,7 +695,9 @@ def update_legacy_record(record, legacy_key: str):
674
695
  return record
675
696
 
676
697
  except requests.exceptions.RequestException as e:
677
- raise InvenioRDMError(f"Error updating legacy record: {str(e)}")
698
+ logger.error(f"Error updating legacy record: {str(e)}", exc_info=True)
699
+ record["status"] = "error_update_legacy_record"
700
+ return record
678
701
 
679
702
 
680
703
  def search_by_slug(slug, type_value, host, token) -> Optional[str]:
@@ -690,15 +713,16 @@ def search_by_slug(slug, type_value, host, token) -> Optional[str]:
690
713
  )
691
714
  response.raise_for_status()
692
715
  data = response.json()
693
- if py_.get(data, "hits.total") or 0 > 0:
716
+ if py_.get(data, "hits.total", 0) > 0:
694
717
  return py_.get(data, "hits.hits.0.id")
695
718
  return None
696
719
  except requests.exceptions.RequestException as e:
697
- raise InvenioRDMError(f"Error searching for community: {str(e)}")
720
+ logger.error(f"Error searching for community: {str(e)}", exc_info=True)
721
+ return None
698
722
 
699
723
 
700
724
  def string_to_slug(text):
701
- """Convert a string to a slug format"""
725
+ """makes a string lowercase and removes non-alphanumeric characters"""
702
726
  # Replace spaces with hyphens
703
727
  slug = re.sub(r"\s+", "-", text.lower())
704
728
  # Remove special characters
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: commonmeta-py
3
- Version: 0.116
3
+ Version: 0.118
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=BlEBVV1F2oGv-LZdRZvwqFf6_KmiMaahHV-G8Uq1Quk,2098
1
+ commonmeta/__init__.py,sha256=RbBIG26IxRjdvGzHH77sogy-rtAEHC51It7TQ6wPjS0,2098
2
2
  commonmeta/api_utils.py,sha256=y5KLfIOWOjde7LXZ36u-eneQJ-Q53yXUZg3hWpCBS2E,2685
3
3
  commonmeta/author_utils.py,sha256=3lYW5s1rOUWNTKs1FP6XLfEUY3yCLOe_3L_VdJTDMp0,8585
4
4
  commonmeta/base_utils.py,sha256=-MGy9q2uTiJEkPWQUYOJMdq-3tRpNnvBwlLjvllQ5g8,11164
@@ -80,11 +80,11 @@ commonmeta/writers/commonmeta_writer.py,sha256=QpfyhG__7o_XpsOTCPWxGymO7YKwZi2LQ
80
80
  commonmeta/writers/crossref_xml_writer.py,sha256=d-Rb2Vd_g3UW8GM4APIT7fivSQ5GMssZ6Ubi3OykHaw,33479
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=IxWEAQBzvPWQqROISJtEuTuWr7bZybhHAz_SqZTQtZY,24577
83
+ commonmeta/writers/inveniordm_writer.py,sha256=el4Eapa9HHg1ceddHb9rd4d1MAsM1ZBZ1F4jQUV8mbI,25717
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.116.dist-info/METADATA,sha256=aWZQLapM3o9hI0t4EgePoyAGCEj_X8HDDdMp-vbHVEc,7652
87
- commonmeta_py-0.116.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
88
- commonmeta_py-0.116.dist-info/entry_points.txt,sha256=U4w4BoRuS3rN5t5Y-uYSyOeU5Lh_VRVMS9OIDzIgw4w,50
89
- commonmeta_py-0.116.dist-info/licenses/LICENSE,sha256=wsIvxF9Q9GC9vA_s79zTWP3BkXJdfUNRmALlU8GbW1s,1074
90
- commonmeta_py-0.116.dist-info/RECORD,,
86
+ commonmeta_py-0.118.dist-info/METADATA,sha256=BD1a2ouuh4hYizCty5tBGQuQM3m6LWVf1zfmTQwnFPU,7652
87
+ commonmeta_py-0.118.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
88
+ commonmeta_py-0.118.dist-info/entry_points.txt,sha256=U4w4BoRuS3rN5t5Y-uYSyOeU5Lh_VRVMS9OIDzIgw4w,50
89
+ commonmeta_py-0.118.dist-info/licenses/LICENSE,sha256=wsIvxF9Q9GC9vA_s79zTWP3BkXJdfUNRmALlU8GbW1s,1074
90
+ commonmeta_py-0.118.dist-info/RECORD,,