Proposal: attach open-access full-text PDFs from OpenAlex
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 45/100
Línea de trabajo
Comienza leyendo app/models/jobs.py y los puntos de entrada existentes para revisar, aplicar y revertir trabajos; después, compara la implementación hermana de doi_resolver. Empieza por el trabajo dry-run propuesto: estará terminado cuando informe de cada DOI, la URL candidata, la versión detectada, la licencia y la confianza, sin subir archivos.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Idea
OpenAlex already tells us, for most publications, where a free and legal full text lives — it carries Unpaywall's open-access data. BackToPure downloads that data today and ignores it: it writes the citation metadata into Pure and drops the PDF link.
Proposal: also fetch the PDF and attach it to the Pure record.
Depends on #2, #3 and #5 — build this as a job type in the new architecture, not on the legacy path.
We already have a working implementation to draw on
A sibling project, doi_resolver, already does this against Pure. It is proven code and should be the starting point rather than a fresh build.
- Upload endpoint:
PUT {base}/research-outputs/file-uploads,Content-Type: application/pdf, raw bytes as the body (not multipart). Returns JSON containing akey. - That key is then referenced back on the record as a
FileElectronicVersionentry inelectronicVersions. - It also has the safety work done: HTML-landing-page preflight,
%PDF-magic-byte and content-type validation, a size cap, adirect/likely/weakscorer for candidate links, and mappers to Pure's access-type and licence URIs.
Roughly 150 of the relevant ~250 lines are dependency-free pure functions that port almost verbatim. The remainder is httpx-async I/O to rewrite as synchronous requests.
Scope: existing records as well as new ones
An earlier draft of this issue framed BackToPure as only creating records that do not yet exist in Pure, and doi_resolver as only enriching ones that do. That split is not a reason to limit this work.
Attaching PDFs is worth doing in both directions, and they are close to the same code:
- New records — attach during the research-outputs import, after the record is created.
- Existing records — a separate job that walks publications already in Pure, finds those without a full text, and attaches one.
(2) is arguably the larger win: the back-catalogue of existing Pure records is far bigger than whatever a given import adds. It also needs no record creation at all, so it is the simpler of the two to build and to review.
Suggest these become two job types sharing one module, or one job type with a scope parameter. Decide during implementation.
Why port rather than depend on doi_resolver
doi_resolver is a FastAPI service. Depending on it would add fastapi, uvicorn, httpx, pydantic and pydantic-settings to BackToPure's four-line requirements.txt, plus a second .env config layer alongside config.ini. That is a real install and configuration cost for people who only want BackToPure. The two projects also do different halves of the job: doi_resolver attaches to records that already exist in Pure, BackToPure creates records that do not.
Accepted cost: the scorer and mappers will exist in both repositories. They are small and dependency-free; extracting a shared package can wait until it actually hurts.
The correctness issue to fix while porting
doi_resolver hardcodes versionType to publishersversion / "Final published version", because its candidate model has no version field.
This is wrong often enough to matter. Unpaywall's best OA location is frequently a repository copy — an accepted manuscript or a preprint. Labelling an accepted manuscript as the final published version is a metadata error that repository managers will rightly object to.
BackToPure can do better here with data it already downloads: OpenAlex's best_oa_location.version gives publishedVersion / acceptedVersion / submittedVersion, alongside pdf_url, license and is_oa. Map that to Pure's versionType instead of hardcoding it.
Fit with the job architecture
This maps onto the existing model cleanly:
- A new
JobTypeinapp/models/jobs.pywith its ownJobTypeDefinition(script_path,artifact_dir,identity_columns=("doi",)). - The
NEEDS_REVIEWstatus and/api/jobs/<id>/review-tablegive the human check on version and licence before anything is deposited. This should not be fully automatic on day one. /api/jobs/<id>/applyand/rollbackgive the apply hook and, importantly, a rollback path — which matters when the operation deposits files rather than metadata.- Job logs, artifacts and cancellation are already handled, which covers the resumability problem for what will be a long-running, network-flaky job.
Open questions — policy, not code
These need an answer from the Pure/repository side before implementation:
- Which versions may be auto-deposited? Publisher version only, or also accepted manuscripts?
- Who owns the licence check? Depositing a file is a different act from recording a citation.
- What about duplicates with the existing OA workflow — if UU already holds the file, should this skip?
- Storage growth in Pure at faculty scale.
Suggested first step
A dry-run job type that reports what would be attached — DOI, candidate URL, detected version, licence, confidence — without uploading anything. That gives the repository team something concrete to set policy against, and is useful on its own as a coverage report.
- Lenguaje dominante
- Python
- Estrellas
- 0
- Forks
- 0
- Merge medio
- 6 h 3 min
- PR fusionados (30 d)
- 9
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de UtrechtUniversity/BackToPure
-
Dificultad 4/5 3-5 días Aptitud para principiantes 55/100
UtrechtUniversity/BackToPure#19 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 30/100
UtrechtUniversity/BackToPure#7 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 5/5 Más de una semana Aptitud para principiantes 25/100
UtrechtUniversity/BackToPure#1 ·
Los mantenedores suelen responder en 1 día
Todos los issues de UtrechtUniversity/BackToPure
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 77/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 67/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
pgvector/pgvector-python#169 ·
-
ChaosEngine: backup-remote doctor row passes while consumer mode hides bot memory from gitPosiblemente ocupada @MohabMohie la tomó hoy. Abiertoagentic
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
ShaftHQ/SHAFT_ENGINE#7263 ·
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 87/100
huggingface/smolagents#3045 ·
Los mantenedores suelen responder en 1 día