-
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"
}
EOFComo 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.toolcurl -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 acimaimport 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>": ["..."] } |