-
Notifications
You must be signed in to change notification settings - Fork 4
API REST — referência
| 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 |
Authorization: Bearer <access_token>| 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 |
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).
Referências já marcadas (mesmo texto normalizado → mesmo checksum SHA-256) são reutilizadas da base Reference / ElementCitation, sem nova chamada ao Llama.
| 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 |
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>"
}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.
ViewSet create → api_reference.
Permissão: IsAuthenticated.
Content-Type: application/json ou form.
| Campo | Tipo | Default | Descrição |
|---|---|---|---|
references |
string | lista | número | — | Texto a marcar |
type |
json | xml | jats
|
json |
Formato de saída |
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': '...', ...}"
}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
datadependem do modelo e do enriquecimento; o exemplo acima ilustra a forma, não um schema rígido OpenAPI.
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).
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>"
}
]
}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.
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"
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"}'
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.
Parsers: MultiPartParser, FormParser.
Extrai texto do .docx, isola a secção de referências e reutiliza o mesmo pipeline de marcação.
| 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 |
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.
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": "..." }
}
]
}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])'
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
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"
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.
#!/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)'
# 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
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()))
| 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>": ["..."] } |