Skip to content

Navigation Menu

Sign in
Sign up

API REST — referência

InnoLabs edited this page Aug 10, 2026 · 1 revision

Mapa de endpoints

Método Caminho Auth Descrição
POST /api/v1/auth/token/ Não Login → access + refresh
POST /api/v1/auth/token/refresh/ Não Novo access a partir do refresh
POST /api/v1/reference/ Sim Marcar referências a partir de texto / lista
GET /api/v1/reference/docx/ Sim Corpo vazio {} (form browsable)
POST /api/v1/reference/docx/ Sim Upload .docx, extrair secção e marcar
GET /api/v1/ Root do router somente se DEBUG (DefaultRouter)
GET /api/v1/reference/ Sim Rota "list" do router sem implementação → tipicamente 405

Convenções

Header de autenticação

Authorization: Bearer <access_token>

Formatos de saída (type)

Valor Significado Chave principal na resposta
json (default) Objeto marcado (dict) em data references ou message
xml String XML element-citation em data references ou message
jats Monta <ref-list>...</ref-list> ref_list

Entrada de referências (texto)

O campo references aceita:

  • string com uma referência por linha;
  • lista JSON ["Ref A", "Ref B"];
  • número (convertido para string) — uso raro.

Linhas vazias são ignoradas (parse_reference_list).

Cache

Referências já marcadas (mesmo texto normalizado → mesmo checksum SHA-256) são reutilizadas da base Reference / ElementCitation, sem nova chamada ao Llama.

Códigos HTTP frequentes

Código Quando
200 Sucesso
400 Validação / sem referências / DOCX inválido
401 / 403 Sem autenticação ou token inválido
405 Método não permitido (ex.: GET em /reference/ sem list)
503 Llama indisponível / desligado / mal configurado

Autenticação

POST /api/v1/auth/token/

Obtém o par JWT.

curl -s -X POST "${BASE_URL}/api/v1/auth/token/" \
 -H "Content-Type: application/json" \
 -d '{"username":"editor","password":"segredo"}'

Body

Campo Tipo Obrigatório
username string sim
password string sim

200

{
 "access": "<jwt>",
 "refresh": "<jwt>"
}

POST /api/v1/auth/token/refresh/

curl -s -X POST "${BASE_URL}/api/v1/auth/token/refresh/" \
 -H "Content-Type: application/json" \
 -d '{"refresh":"<refresh_jwt>"}'

200

{
 "access": "<novo_access_jwt>"
}

Mais exemplos: autenticacao.md.


Marcação por texto

POST /api/v1/reference/

ViewSet createapi_reference.
Permissão: IsAuthenticated.
Content-Type: application/json ou form.

Campos (ReferenceMarkRequestSerializer)

Campo Tipo Default Descrição
references string | lista | número Texto a marcar
type json | xml | jats json Formato de saída

Exemplo A — uma referência (string) → resposta message

Quando a entrada é string e resulta em uma referência marcada, a API responde com message (comportamento atual do ViewSet):

curl -s -X POST "${BASE_URL}/api/v1/reference/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -H "Content-Type: application/json" \
 -d '{
 "references": "Smith J. Example title. Nature. 2024;600:1-10.",
 "type": "json"
 }'

200 (forma típica)

{
 "message": "reference: {'reftype': 'journal', 'title': '...', ...}"
}

Exemplo B — várias referências (lista JSON) → references[]

curl -s -X POST "${BASE_URL}/api/v1/reference/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -H "Content-Type: application/json" \
 -d '{
 "references": [
 "Smith J. Example title. Nature. 2024;600:1-10.",
 "Doe A, Roe B. Another paper. Science. 2023;380:100-105. https://doi.org/10.1126/science.xxxx"
 ],
 "type": "json"
 }'

200

{
 "references": [
 {
 "mixed_citation": "Smith J. Example title. Nature. 2024;600:1-10.",
 "data": {
 "reftype": "journal",
 "title": "Example title",
 "authors": [ ... ],
 "source": "Nature",
 "year": "2024",
 "vol": 600,
 "doi": null
 }
 },
 {
 "mixed_citation": "Doe A, Roe B. Another paper. Science. 2023;380:100-105. https://doi.org/10.1126/science.xxxx",
 "data": { "...": "..." }
 }
 ]
}

Os campos dentro de data dependem do modelo e do enriquecimento; o exemplo acima ilustra a forma, não um schema rígido OpenAPI.

Exemplo C — várias linhas numa única string

curl -s -X POST "${BASE_URL}/api/v1/reference/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -H "Content-Type: application/json" \
 --data-binary @- <<'EOF'
{
 "references": "Smith J. Nature. 2024;600:1-10.\nDoe A. Science. 2023;380:100-105.",
 "type": "json"
}
EOF

Como a entrada é string mas há duas linhas → resposta com chave references (array).

Exemplo D — saída XML (element-citation)

curl -s -X POST "${BASE_URL}/api/v1/reference/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -H "Content-Type: application/json" \
 -d '{
 "references": [
 "Smith J. Example title. Nature. 2024;600:1-10."
 ],
 "type": "xml"
 }'

200 (trecho)

{
 "references": [
 {
 "mixed_citation": "Smith J. Example title. Nature. 2024;600:1-10.",
 "data": "<element-citation publication-type=\"journal\">...</element-citation>"
 }
 ]
}

Exemplo E — saída JATS (ref-list)

Usado pelos scripts de acurácia e por integrações que precisam do bloco SPS pronto.

curl -s -X POST "${BASE_URL}/api/v1/reference/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -H "Content-Type: application/json" \
 -d '{
 "references": [
 "Smith J. Example title. Nature. 2024;600:1-10.",
 "Doe A. Another paper. Science. 2023;380:100-105."
 ],
 "type": "jats"
 }'

200

{
 "ref_list": "<ref-list><title>References</title><ref id=\"B1\">...</ref><ref id=\"B2\">...</ref></ref-list>"
}

Internamente a view marca como xml e chama build_ref_list.

Exemplo F — form-urlencoded (Browsable / curl)

curl -s -X POST "${BASE_URL}/api/v1/reference/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -H "Content-Type: application/x-www-form-urlencoded" \
 --data-urlencode "references=Smith J. Nature. 2024." \
 --data-urlencode "type=json"

Erros — texto

Sem referências úteis

curl -s -X POST "${BASE_URL}/api/v1/reference/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -H "Content-Type: application/json" \
 -d '{"references":"","type":"json"}'
{"error": "No references provided"}

Body inválido / serializer

{"references": ["Este campo é obrigatório."]}

(ou mensagens equivalentes do DRF)

Llama indisponível

{"error": "Llama model is not available: ..."}

HTTP 503.

Não autenticado

curl -s -o /dev/null -w "%{http_code}\n" \
 -X POST "${BASE_URL}/api/v1/reference/" \
 -H "Content-Type: application/json" \
 -d '{"references":["Ref A"],"type":"json"}'

Marcação a partir de DOCX

GET /api/v1/reference/docx/

Devolve {} (200) para o formulário da Browsable API.

curl -s -X GET "${BASE_URL}/api/v1/reference/docx/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -H "Accept: application/json"
{}

Útil também como probe de token (como em scripts/reference_accuracy.py): se HTTP ≠ 401, o token ainda é aceite.


POST /api/v1/reference/docx/

Parsers: MultiPartParser, FormParser.
Extrai texto do .docx, isola a secção de referências e reutiliza o mesmo pipeline de marcação.

Campos (ReferenceDocxRequestSerializer)

Campo Tipo Default Descrição
file ficheiro .docx Obrigatório; rejeita outros extensões e ficheiro vazio
type json | xml | jats json Formato de saída

Headings reconhecidos

Regex (case-insensitive), linha isolada, com número opcional:

  • References / Reference
  • Referências / Referência / Referencias / Referencia
  • Bibliography / Bibliografia

Exemplos válidos: References, 5. Referências, Bibliografia.

Cada parágrafo após o heading vira uma referência.

Exemplo G — DOCX → JSON

curl -s -X POST "${BASE_URL}/api/v1/reference/docx/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -F "file=@/caminho/para/artigo.docx" \
 -F "type=json"

200

{
 "references": [
 {
 "mixed_citation": "Smith J. Nature. 2024.",
 "data": { "reftype": "journal", "title": "..." }
 }
 ]
}

Exemplo H — DOCX → JATS (homologação / accuracy)

curl -s -X POST "${BASE_URL}/api/v1/reference/docx/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -F "file=@fixtures/bn-2025-1828/bn-2025-1828.docx" \
 -F "type=jats" \
 -o /tmp/ref_list_response.json
python3 -c 'import json; print(json.load(open("/tmp/ref_list_response.json"))["ref_list"][:500])'

Exemplo I — DOCX → XML

curl -s -X POST "${BASE_URL}/api/v1/reference/docx/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -F "file=@artigo.docx" \
 -F "type=xml" | python3 -m json.tool

Exemplo J — Content-Type explícito no ficheiro

curl -s -X POST "${BASE_URL}/api/v1/reference/docx/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -F "file=@artigo.docx;type=application/vnd.openxmlformats-officedocument.wordprocessingml.document" \
 -F "type=jats"

Erros — DOCX

Extensão inválida

curl -s -X POST "${BASE_URL}/api/v1/reference/docx/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -F "file=@notas.txt" \
 -F "type=json"
{"file": ["Only .docx files are accepted."]}

Sem secção de referências

{"error": "No references section found in DOCX"}

Ficheiro ilegível

{"error": "Could not read DOCX file"}

Sem autenticação

HTTP 401 ou 403.


Fluxos curl ponta a ponta

Homologação: login → marcar texto → refrescar → DOCX

#!/usr/bin/env bash
set -euo pipefail
BASE_URL="https://tools-hml.scielo.org"
USER="${JWT_USERNAME}"
PASS="${JWT_PASSWORD}"
DOCX_PATH="${1:-artigo.docx}"
TOKENS=$(curl -s -X POST "${BASE_URL}/api/v1/auth/token/" \
 -H "Content-Type: application/json" \
 -d "{\"username\":\"${USER}\",\"password\":\"${PASS}\"}")
ACCESS=$(echo "$TOKENS" | python3 -c 'import sys,json; print(json.load(sys.stdin)["access"])')
REFRESH=$(echo "$TOKENS" | python3 -c 'import sys,json; print(json.load(sys.stdin)["refresh"])')
echo "== texto / json =="
curl -s -X POST "${BASE_URL}/api/v1/reference/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -H "Content-Type: application/json" \
 -d '{"references":["Smith J. Nature. 2024;600:1-10."],"type":"json"}' \
 | python3 -m json.tool
echo "== refresh =="
ACCESS=$(curl -s -X POST "${BASE_URL}/api/v1/auth/token/refresh/" \
 -H "Content-Type: application/json" \
 -d "{\"refresh\":\"${REFRESH}\"}" \
 | python3 -c 'import sys,json; print(json.load(sys.stdin)["access"])')
echo "== docx / jats =="
curl -s -X POST "${BASE_URL}/api/v1/reference/docx/" \
 -H "Authorization: Bearer ${ACCESS}" \
 -F "file=@${DOCX_PATH}" \
 -F "type=jats" \
 | python3 -c 'import sys,json; d=json.load(sys.stdin); print(d.get("ref_list","")[:800] or d)'

Local: criar utilizador e testar

# num terminal com Compose já no ar
docker compose -f local.yml run --rm django python manage.py createsuperuser
export BASE_URL="http://localhost:8000"
# ... mesmo fluxo de token + POST acima

Python (requests) — espelho do cliente HML

import requests
BASE = "https://tools-hml.scielo.org"
r = requests.post(
 f"{BASE}/api/v1/auth/token/",
 json={"username": "editor", "password": "segredo"},
 timeout=60,
)
r.raise_for_status()
access = r.json()["access"]
headers = {"Authorization": f"Bearer {access}"}
# texto
resp = requests.post(
 f"{BASE}/api/v1/reference/",
 headers=headers,
 json={
 "references": ["Smith J. Nature. 2024;600:1-10."],
 "type": "json",
 },
 timeout=600,
)
print(resp.status_code, resp.json())
# docx
with open("artigo.docx", "rb") as fh:
 resp = requests.post(
 f"{BASE}/api/v1/reference/docx/",
 headers=headers,
 files={
 "file": (
 "artigo.docx",
 fh,
 "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
 )
 },
 data={"type": "jats"},
 timeout=600,
 )
print(resp.status_code, list(resp.json().keys()))

Resumo das formas de resposta

Condição Corpo
type=jats { "ref_list": "<ref-list>...</ref-list>" }
Entrada string + 1 resultado + type ≠ jats { "message": "reference: ..." }
Lista / multilinha / vários resultados { "references": [ { "mixed_citation", "data" }, ... ] }
Erro de negócio { "error": "..." }
Erro de serializer { "<campo>": ["..."] }

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /