index
La Novitade
Section titled “La Novitade”TripleLite
Section titled “TripleLite”perf: intern strings and terms as integer IDs in internal indices
Store subjects, predicates, and objects as integer IDs internally, mapping back to strings/RDFTerms only at the public API boundary. Reduces memory for repeated URIs and speeds up set operations (int hashing/comparison vs full string).
Add add_many() for batch insertion with cached lookups, avoiding per-call method overhead. Update rdflib bridge and subgraph to use it.
Stesse triple in 4 posti:
- finder.graph, cache grande condivisa
- subgraph temporaneo, vive durante
__init__, poi GC’d - GraphEntity.g, TripleLite per-entità in oc_ocdm
GraphEntity._preexisting_triples, frozenset per calcolo diff
No buono.
feat: replace subgraph copy with zero-copy SubgraphView [release]
subgraph() now returns a read-only SubgraphView that references the parent graph's internal data directly. The view reflects subsequent changes to the parent and supports iteration, length, predicate_objects(), and set operations.
#TODO Questa libreria va chiaramente riscritta in C. È piccola, semplice, già scritta col C in mente.
Total Duration: 28733.617s (7.9 ore)Total Records: 2_504_478Total Entities: 14_136_038Peak Memory (RSS): 30283.4 MBOUTCITE
Section titled “OUTCITE”Total Duration: 138883.274s (38,7 ore)Total Records: 2_306_758Total Entities: 15_707_992Peak Memory (RSS): 53809.9 MB
OC_OCDM
Section titled “OC_OCDM”refactor!: replace rdflib Graph/URIRef with lightweight LightGraph/str
BREAKING CHANGE: entity.res is now str (was URIRef), entity.g is now LightGraph (was rdflib.Graph), all factory methods accept str instead of URIRef, all getters return str instead of URIRef
Rilascio un’autorizzazione a buongiorno principessarmi: ho capito solo ora a cosa serva il context nei file json-ld e mi piace molto.
feat: extend context with new types, identifiers, and restructured properties
Add type mappings for document parts (abstract, introduction, discussion, methods, results, conclusion, related_work, materials), document types (archival_document, audio_document, computer_program, editorial, journal_editorial, newspaper, newspaper_article, newspaper_editorial, newspaper_issue, presentation, data_management_plan, retraction_notice), and has_annotation property.
Add identifier schemes: intrepid, jid, openalex, ror, wikidata, wikipedia.
refactor(context): add meta namespace prefixes and prune redundant aliases
Introduce short prefixes (br, ar, ra, id, re, pa) for the https://w3id.org/oc/meta/ namespace.
Since id now points to the identifier namespace, the former id term for literal:hasLiteralValue is renamed to literal_value.
Drop three redundant aliases: proceedings_series duplicated series (both fabio:Series), and xpath / xmlid duplicated localresource (all three datacite:local-resource-identifier-scheme).
Trovato questo in JaLC
"journal_title_name_list":[ {"journal_title_name":"金大考古\nen: The Archaeological Journal of Kanazawa University"}]fix(jalc): split packed multilang entries to keep CSV cells single-line
JaLC records occasionally collapse multiple languages into a single untagged title/journal entry separated by '\n' with an inline "en:" prefix (observed on 10.24517/0002000619). The extractor previously passed the raw string through, producing CSV rows with embedded newlines. Detect the packed-lang pattern, split it into per-language entries, and collapse residual whitespace on the chosen value so single-line cells are preserved.
fix(jalc): decode html entities before flattening whitespace
JaLC records occasionally encode control characters as numeric HTML
entities ( ) inside author, title, venue and publisher
fields. The previous collapse step ran before entity resolution, so the
decoded CR/LF survived into the CSV and broke downstream parsers.
Ingestione fatta.
OUTCITE
Section titled “OUTCITE”2,306,758 righe, 650,682 fanno capo a br esistenti, 1,656,076 (il 71.8%) sono nuove.
Facciamo che le processo tutte come nuove, sia perché ora si può fare velocemente sia per ricompensare il philippahsannico sforzo.
fix(check_results): verify output CSVs instead of input CSVs
Input CSVs may contain only temporary identifiers with no OMID
The new logic distinguishes three identifier categories per entity group: the OMID token (used as ground truth for file and provenance checks), recognized external identifiers (doi, orcid, etc.) looked up in the triplestore to detect mismatches with the expected OMID, and unverifiable schemas that are simply counted and skipped.
In fase di verifica ho trovato un bug nel creator, il quale non era allineato alla logica del curator per quanto riguarda il collegare un editor al contenitore e non al contenuto per specifici tipi di entità come ad esempio i capitoli dei libri. Di conseguenza, nonostante il curator creasse le nuove entità da collegare al contenitore, il creator le marcava come già esistenti per entità per le quali l’editor era già stato collegato al contenuto e l’OMID, per quanto tracciato all’interno del CSV di output, non compariva nei dati finali.
fix(creator): query editor roles on the correct BR entity
When a row's editors belong to a container (venue/book) rather than the row's own BR, skip_editor was evaluated against the row's BR roles. Now resolves the actual edited BR via get_edited_br_metaid and queries its existing roles separately when they differ.
Adds fix_misplaced_editor_ars patch script with tests to migrate existing RDF data where editor ARs were misplaced on content entities instead of their containers.
Mentre lanciavo la dry run per individuare l’entità del problema, mi sono accorto che c’è un problema preliminare, ovvero entità che hanno più di un part of. Fortunatamente nessuna di queste entità ha anche un problema di editor mal collocato.
fix(patch): detect duplicate editors during AR migration and fix duplicate partOf
The editor AR patch now resolves duplicate responsible agents by RA URI, shared identifier, or name match before moving ARs to containers. Skipped duplicates are removed from the content entity without being re-added.
New fix_duplicate_part_of script scans for BRs with multiple frbr:partOf values, follows container chains to top-level venues, and auto-fixes when chains converge to the same or equivalent venues. Divergent venues are flagged for manual review with enriched identifier and candidate info.
Found 82,794 misplaced editor ARs across 39,569 content entities. 61,931 to move, 62 skip (same RA), 3 skip (same identifier), 20,798 skip (same name)
fix(patch): handle content entities with multiple frbr:partOf containers
When a content entity belongs to multiple containers, the original AR is moved to the first and a new AR (same RA) is created for each additional one.
Ho deciso di non applicare la patch per ora. L’applicherò quando avrò un dataset di partenza più pulito con problemi preliminari risolti, a cominciare dalla rimozione dei duplicati, degli orfani, delle entità vuote, dei predicari doppi.
RAMOSE
Section titled “RAMOSE”refactor(openapi): remove x-ramose vendor extensions from spec output
Implementation details like endpoint, addon, sparql method, preprocess, and postprocess are not meaningful to API consumers.
raise ValueError(f"Expected key=value option, got {token!r}")Quel !r chiama repr sul valore. Produce la rappresentazione con le virgolette.
token = "left"
f"{token}" # leftf"{token!r}" # 'left'Rende visibili anche caratteri che altrimenti sarebbero invisibili (spazi iniziali/finali, tab, newline).
Ho capito a cosa serviva l’alias in @@foreach, per evitare questo
@@foreach ?br wait=0.1PREFIX cito: <http://purl.org/spar/cito/>
SELECT ?br (COUNT(?citing) AS ?oc_citation_count) WHERE { BIND(<[[?br]]> AS ?br) ?cit a cito:Citation ; cito:hasCitedEntity ?br ; cito:hasCitingEntity ?citing .}GROUP BY ?brSi può aggiungere un parametro obbligatorio posizionale, quindi non chiave-valore, così
@@foreach ?br item wait=0.1PREFIX cito: <http://purl.org/spar/cito/>
SELECT ?br (COUNT(?citing) AS ?oc_citation_count) WHERE { BIND(<[[item]]> AS ?br) ?cit a cito:Citation ; cito:hasCitedEntity ?br ; cito:hasCitingEntity ?citing .}GROUP BY ?brrefactor: standardize directive syntax with key=value options and merged @@foreach
Directive optional parameters now use unambiguous key=value syntax (e.g. type=left, wait=0.5) while required arguments stay positional. This resolves parsing ambiguity when extending directives with new options.
@@foreach absorbs the old @@values ?var:alias setup into a single directive: @@foreach ?variable placeholder [wait=N].
Però così @@foreach ?br item wait=0.1 è poco leggibile, non si capisce cosa sia item. Inoltre non si capisce perché i parametri obbligatori debbano essere solo posizionali e non anche per keyword. Si potrebbe fare come in Python
@@name <arg>... [param=value]...
@@foreach ?br item wait=0.5@@foreach ?br placeholder=item wait=0.5@@foreach variable=?br placeholder=item wait=0.5@@foreach wait=0.5 variable=?br placeholder=itemrefactor: replace key-value-only parser with Python-style argument parser
_parse_kv_options only handled key=value tokens after positional args were manually extracted by each handler. The new _parse_directive_args supports positional, keyword, and mixed styles in the same call, with free ordering when all arguments are keyword. A token containing = is only treated as keyword if the key part matches a known parameter name, so URLs with query strings work as positional values.
All directive handlers now delegate to _parse_directive_args with their parameter schema.
Documentation now includes parameter tables for each directive.
feat(skgif): add products/{local_identifier} endpoint with JSON-LD output
Implement the SKG-IF converter that transforms SPARQL results from OpenCitations Meta and Index into JSON-LD conforming to the Scholarly Knowledge Graph Interoperability Framework specification (v1.1.0).
The endpoint uses multi-source SPARQL with left joins across Meta (bibliographic metadata, contributors, venue) and Index (citations), producing a complete product representation including identifiers, ordered contributions with linked-list rank preservation, manifestation details, and citation references.
test(skgif): validate converter output against upstream OpenAPI schema
Fetch the SKG-IF OpenAPI spec from skg-if/api at test time, resolve $ref pointers, and validate JSON-LD responses against the extracted Product response schema using jsonschema.
docs(extractor): add /cex prefix to api endpoint examples
The Flask app mounts the API blueprint at /cex/api (main.py sets PREFIX="/cex"), but the README endpoint and curl examples referenced the bare /api path. Align the examples with the actual routing and include the per-request UUID segment in the download URL example.
feat(grobid): release 1.1.0 with configurable crossref mailto
Add oc_cec_grobid wrapper image over opencitations/grobid-cec:1.0.0 that injects the crossref consolidation mailto at container startup via the CROSSREF_MAILTO env var.
Register a dedicated build workflow and document the required variable in the compose example.
Drop pull_request triggers and remove the master branch so builds only fire on merges to main.
https://github.com/opencitations/cec/issues/13
feat: add bulk extraction script with configurable grobid concurrency
docs(extractor): document the consolidate form field
Add the new opt-in consolidate toggle to the API form-field table and to the curl upload example.
This is your daily dose of rdflib antidote
Section titled “This is your daily dose of rdflib antidote”Ultimo commit di due mesi fa, vorrei segnalare, e il repository è pieno zeppo di errori di tipizzazione e warning di deprecazione interni al repository stesso, oltre a 299 issue aperte e 61 PR: https://github.com/rdflib/rdflib. Secondo me possiamo considerarlo archiviato, per il momento
Duplicati nei CSV
Section titled “Duplicati nei CSV”fix(generate_csv): always rebuild Redis OMID set at startup
The previous logic skipped reloading processed OMIDs from output CSVs if Redis already had entries. This caused incomplete deduplication on restart: OMIDs written to output files during a prior run were absent from Redis (workers never write to it), so a restarted run would re-process already-output entities and produce duplicates.
Replace the early-return short-circuit with an unconditional delete + reload to guarantee Redis always reflects all existing output CSVs at startup.
In pratica il sistema era fatto per permettere un solo riavvio, perché la lettura del Redis per caricare gli OMID già processati veniva fatta soltanto se il Redis era vuoto e il Redis non veniva aggiornato file per file, ma soltanto all’avvio. Il senso era evitare che degli OMID venissero marcati come già processati quando in realtà erano assenti dai CSV perché i CSV vengono scritti in batch. La soluzione è caricare gli OMID in Redis a ogni riavvio a partire dai CSV già processati.
Produzione
Section titled “Produzione”Indicizzare Qlever per i dati di Meta (no provenance) ha impiegato su produzione 7.3 h vs 5.8 h su ServerGrosso. Io dico che è usabilissimo.
Domande
Section titled “Domande”GRAPHIA
Section titled “GRAPHIA”Documento di domande aperte per la stesura del rulebook della federazione GRAPHIA, organizzato per WP. Bisogna farne la review, commentandolo.
RAMOSE
Section titled “RAMOSE”Scapolottina numero 1
GET /skgif/v1/products/omid:br/0612058700
{ "local_identifier": "products/omid:br/0612058700", "contributions": [{"by": {"local_identifier": "persons/omid:ra/069012996"}}], "manifestations": [{"biblio": {"in": {"local_identifier": "venues/omid:br/0626055628"}}}], "related_products": {"cites": ["products/omid:br/0612058701"]}}Scapolottina numero 2
GET /skgif/v1/products/br/0612058700
{ "local_identifier": "products/br/0612058700", "contributions": [{"by": {"local_identifier": "persons/ra/069012996"}}], "manifestations": [{"biblio": {"in": {"local_identifier": "venues/br/0626055628"}}}], "related_products": {"cites": ["products/br/0612058701"]}}- Al momento la conversione al formato di skg-if si può triggerare con la query format
/skgif/v1/products/{omid}?format=skgifDovrebbe funzionare così? Al momento non c’è un modo per definire un formato di default, il formato di default è sempre CSV - Per la lingua metto none, giusto?
- Per il publisher lo metto il rank?
- Al momento l’operazione products è nei test del repo di ramose. Devo metto gli hf di skg-if? Quale sarà l’endpoint in produzione?
- Abbiamo un jsonschema per validare gli output di SKG-IF? La validazione fatta su skg-id/api è overkill https://github.com/skg-if/api/blob/main/.github/scripts/validate_files.py
Pubblicazioni
Section titled “Pubblicazioni”- Se io cito un software utilizzando software Heritage, in teoria dovrei utilizzare l’SHA preciso della versione da cui è dipendente il mio software nel momento in cui scrivo l’articolo. Giusto? Inoltre, mi chiedo, che anno devo specificare? L’anno di creazione del software o l’anno in cui è stata rilasciata quella versione?
- Email Francesca
- Email licenza speciale
- https://w3id.org/oc/ontology/context.jsonld questo è rotto. Come si aggiusta?
- Per evitare confusione a noi stessi e anche agli altri, io comincerei a marcare come archiviati/deprecati i repository che non stiamo più mantenendo. Tra questi c’è il corpus e aggiungerei anche le virtuoso_utilities che non servono più. https://github.com/opencitations/corpus. Che ne pensate?
Aldrovandi
- Ai related works c’è da aggiungere l’articolo su chad kg
- Mail con marcatura istituto
- Articolo del Twin
Vizioso
- https://en.wikipedia.org/wiki/Compilers:_Principles,_Techniques,_and_Tools
- https://en.wikipedia.org/wiki/GNU_Bison
- https://en.wikipedia.org/wiki/Yacc
HERITRACE
- C’è un bug che si verifica quando uno seleziona un’entità preesistente, poi clicca sulla X e inserisce i metadati a mano. Alcuni metadati vengono duplicati.
- Se uno ripristina una sotto entità a seguito di un merge, l’entità principale potrebbe rompersi.
- Per risolvere le performance del time-vault non usare la time-agnostic-library, ma guarda solo la query di update dello snapshot di cancellazione.
- Ordine dato all’indice dell’elemento
- date: formato
- anni: essere meno stretto sugli anni. Problema ISO per 999. 0999?
- Opzione per evitare counting
- Opzione per non aggiungere la lista delle risorse, che posso comunque essere cercate
- Configurabilità troppa fatica
- Timer massimo. Timer configurabile. Messaggio in caso si stia per toccare il timer massimo.
- Riflettere su @lang. SKOS come use case. skos:prefLabel, skos:altLabel
- Possibilità di specificare l’URI a mano in fase di creazione
- la base è non specificare la sorgente, perché non sarà mai quella iniziale.
- desvription con l’entità e stata modificata. Tipo commit
- display name è References Cited by VA bene
- Avvertire l’utente del disastro imminente nel caso in cui provi a cancellare un volume
Meta
- Matilda e OUTCITE nella prossima versione
- Da definire le sorgenti
- Va su Trello
- Bisogna produrre la tabella che associa temp a OMID per produrre le citazioni.
- Rilanciare processo eliminazione duplicati
- Fusione: chi ha più metadati compilati. A parità di metadato si tiene l’omid più basso
- frbr:partOf non deve aggiungere nel merge: https://opencitations.net/meta/api/v1/metadata/omid:br/06304322094
- API v2
- Usare il triplestore di provenance per fare 303 in caso di entità mergiate o mostrare la provenance in caso di cancellazione e basta.
oc_ocdm
- Automatizzare mark_as_restored di default. è possibile disabilitare e fare a mano mark_as_restored.
- https://opencitations.net/meta/api/v1/metadata/doi:10.1093/acprof:oso/9780199977628.001.0001
- DELETE con variabile
- Modificare Meta sulla base della tabella di Elia
- embodiment multipli devono essere purgati a monte
- Modificare documentazione API aggiungendo omid
RML
- Vedere come morh kgc rappresenta database internamente
- https://github.com/oeg-upm/gtfs-bench
- Chiedere Ionannisil diagramma che ha usato per auto rml.
Crowdsourcing
- Quando dobbiamo ingerire Crossref stoppo manualmente OJS. Si mette una nota nel repository per dire le cose. Ogni mese.
- Aggiornamenti al dump incrementali. Si usa un nuovo prefisso e si aggiungono dati solo a quel CSV.
- Bisogna usare il DOI di Zenodo come primary source. Un unico DOI per batch process.
- Bisogna fare l’aggiornamento sulla copia e poi bisogna automatizzare lo switch