Skip to content

2025-11-11 RDF 1.2 e ingestione DataCite

  • Ho provato a ricaricare la provenance su Figshare. Ho creato uno script per scaricarla da Figshare, (perché il link di download di Figshare non funziona con curl e wget, bisogna scaricare singolarmente tutti i file), ma si è ripresentato il problema degli archivi 7-zip corrotti. Questo mi fa pensare che la corruzione avvenga durante l’upload, perché gli stessi file 7-zip sono stati correttamente estratti in locale prima di essere caricati.

  • Ho capito qual è il problema ed è FOLLE (come tutte le API di Figshare). Avevo scaricato i file con le API di Figshare, che hanno un page size di default di 10. Questo vuol dire che se ci sono 18 file di default ne scaricano 10. Bisogna impostare a mano il parametro della paginazione. Non mi ero accorto che offline c’erano 10 file mentre online ce n’erano 18.

  • Ho anche migliorato lo script di caricamento su Zenodo. zenodopy non gestisce la ripresa dalle interruzioni in caso di stalled. Zenodo non supporta resume ma posso fare chunked streaming con retry e timeout aggressivi per gestire gli stall.

  • Conclusa ingestion di Datacite e verificato i risultati. Ho trovato tanti ID con più OMID che preesistevano a questa ingestion. Ho deciso di fonderli prima di proseguire con Crossref per essere sicuro di non starne introducendo di nuovi. Molto sono causati dalla presenza/assenza di datatype nei valori letterali degli identificatori.

  • Ho trovato un bug nel software che raggruppava le entità da fondere per consentire il multiprocessing. Il software raggruppava entità collegate nel grafo, ma non considerava entità prossime a livello numerico e che pertanto, anche se scollegate, si trovano nello stesso file RDF. File CSV 1 (worker 1):

    File CSV 2 (worker 2):

    Queste entità NON sono collegate nel grafo RDF, quindi group_entities.py le mette in file CSV separati.

    MA:

    Con dir_split_number=1000 e items_per_file=1000:

    • br/060100 → va in br/060/10000/1000.json
    • br/060105 → va in br/060/10000/1000.json
    • br/060150 → va in br/060/10000/1000.json ← STESSO FILE!
    • br/060180 → va in br/060/10000/1000.json ← STESSO FILE!

    Due worker scrivono contemporaneamente su br/060/10000/1000.json

    In realtà potrebbero anche esserci entità collegate nello stesso range numerico, che casino… Ah no, oc_ocdm fa lock sui file, a posto. Ho comunque aggiunto il grouping per range numerico, per migliorare le performance.

  • Problema

Terminal window
arcangelo@serverGrosso:/mnt/arcangelo/repositories/oc_meta$ poetry run python3 -m oc_meta.run.merge.group_entities /mnt/arcangelo/oc_meta_merge/duplicate_ids.csv /mnt/arcangelo/oc_meta_merge/duplicate_ids/ /mnt/arcangelo/oc_meta_merge/meta_config.yaml
Loaded CSV file with 1320223 rows
Configuration: dir_split=10000, items_per_file=1000, zip_output=True
Processing rows: 100%|█████████████████████████████████████████████████████████████████████| 1320223/1320223 [2:19:21<00:00, 157.89it/s]
Initially grouped entities into 10 groups
Optimized into 5 groups
Saving group with 1320211 rows to /mnt/arcangelo/oc_meta_merge/duplicate_ids/063101469758.csv
Saving group with 2 rows to /mnt/arcangelo/oc_meta_merge/duplicate_ids/062502642838.csv
Saving group with 2 rows to /mnt/arcangelo/oc_meta_merge/duplicate_ids/063301563999.csv
Saving group with 2 rows to /mnt/arcangelo/oc_meta_merge/duplicate_ids/06706496994.csv
Saving group with 6 rows to /mnt/arcangelo/oc_meta_merge/duplicate_ids/061402844404.csv
Finished saving grouped entities
  • Mentre provavo ad aggiornare OC Download con il link all’RDF ho incontrato un problema che avevo già previsto che sarebbe accaduto ma si è verificato soltanto adesso, ovvero un problema di gestione delle dipendenze. Infatti, OC Download e immagino anche tutti gli altri servizi, usano requirements.txt per gestire le dipendenze, che è il modo più fragile possibile. In particolare, quello che è successo è che WebPy 0.62 non è compatibile con Python 3.13 perché ha bisogno del modulo CGI che è stato rimosso da Python 3.13. Per evitare questi problemi in futuro, ho creato un nuovo branch nel quale ho fatto, per il momento solo per OC download, la migrazione a UV, che permette di gestire in maniera programmatica le versioni di Python ovvero tramite un file .pythonversion che informa UV di quale versione di python utilizzare. Dopodiché è UV a preoccuparsi di installarla e di mantenere la gestione tra multiple versioni di python installate sullo stesso dispositivo oltre a mantenere la gestione degli hash delle varie versioni, delle varie dipendenze e assicurarsi che siano tutti compatibili tra di loro.
  • Ho anche notato delle dipendenze inutilizzate:
  • ConjunctiveGraph (deprecato) -> Dataset
    • Ci sono differenze. Non esiste Dataset.subjects(unique=True), perché ambiguo sul contesto.
    • Non supporta confronto isomorfico, va convertito in Graph.
  • Modifiche a cascata necessarie su rdflib-ocdm, time-agnostic-library e oc_ocdm
    • OCDMConjunctiveGraph -> OCDMDataset
    • Mantenuta la retrocompatibilità con DeprecationWarning
    • Dataset(default_union=True) per fare in modo che le query siano sull’unione dei grafi
  • Francesca mi ha segnalato che i conteggi delle entità per ogni classe non si stanno più aggiornando. Questo accade perché avevo modificato la logica dei conteggi per farla funzionare su Meta: i conteggi venivano calcolati una volta sola all’inizio della via dell’applicazione. Tuttavia, mi ero scordato di inserire una logica per gestire il caso in cui vogliamo che questi conteggi vengano aggiornati in maniera dinamica. Ho implementato una logica automatica, ovvero lo stesso numero che ho impostato come numero massimo visualizzato, cioè 10.000, viene anche utilizzato per determinare se un dataset è piccolo o grande. Cioè, se il numero di entità pre-calcolate è superiore a 10.000 smettiamo di contare e viceversa.
  • https://www.w3.org/TR/rdf12-concepts/ (W3C Working Draft 30 October 2025)
  • Triple terms (https://www.w3.org/TR/rdf12-concepts/#section-triple-terms-reification)
    • A triple term is an RDF triple used as an RDF term within another triple.
    • È RDF-star
  • Supporto per la direzione del testo
    • datatype rdf:dirLangString ltr o rtl
  • Nuovi datatype rdf:JSON, rdf:HTML, e rdf:XMLLiteral (https://www.w3.org/TR/rdf12-concepts/#section-Datatypes)
    • permette di includere valori JSON, HTML e XML nativi nei literal RDF
  • Nuova classe e proprietà per la reificazione
    • È una risorsa associata a un triple term
    • Questa separazione permette di:
      • Avere multiple occorrenze dello stesso triple term con metadati diversi
      • Dare un’identità esplicita a un’occorrenza specifica di una tripla
      • Distinguere tra la tripla come concetto astratto (triple term) e sue realizzazioni concrete (reifier)
    VERSION "1.2"
    @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
    @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
    @prefix ex: <http://example.org/> .
    # Il reifier (una risorsa) che reifica un triple term
    ex:statement1 rdf:reifies << ex:Earth ex:shape "flat" >> ;
    a rdfs:Proposition ;
    ex:source ex:Arcangelo ;
    ex:timestamp "2025-11-01" .
    # Un altro reifier per lo stesso triple term, con metadati diversi
    ex:statement2 rdf:reifies << ex:Earth ex:shape "flat" >> ;
    a rdfs:Proposition ;
    ex:source ex:Mario ;
    ex:confidence 0.9 .
  • Direttive di versione (https://w3c.github.io/rdf-turtle/spec/#sec-version)
GET /document.ttl HTTP/1.1
Host: example.com
Accept: text/turtle; version=1.2
  • I language tag sono trattati in modo case insensitive
    • “chat”@it == “chat”@IT
  • Firma digitale: convenzioni unibo? Supporto Linux?
  • Io con la RAM e la memoria di massa a disposizione faccio veramente fatica a lavorare. Solo Redis e i database si prendono quasi 170GB su 200GB di RAM. Inoltre saturo i 4T avendo anche solo una copia di tutti i dati e un backup (RDF + db dati + db provenance + dump Redis). Mi rendo conto che sia assurdo ma questa è la situa. L’operazione di ricerca di id duplicati semplicemente non arrivava più in fondo neanche avendo 200G liberi. Ho dovuto renderla più efficiente, ma così facendo l’ho anche resa più lenta (lavora in chunk da 5000 file, salva i risultati temporanei su CSV e fonde in fondo).