Pular para conteúdo

API Python

O mapa-da-ciencia também funciona dentro de um notebook (Jupyter, Colab) ou de um script. A fachada mapa_da_ciencia.api reúne as mesmas etapas da CLI e devolve objetos Python, e o corpus pode ser consultado em SQL.

import mapa_da_ciencia.api as mapa

p = mapa.novo("op-2024", revistas=["op"], anos=2024)
resumo = mapa.coletar(p)
print(resumo)
# 25 documento(s) de 1 revista(s), 2024, em 7,2 s. De fora: 544 fora do período, ...

por_idioma = """
    SELECT idioma, count(*) AS n
    FROM textos WHERE campo = 'resumo'
    GROUP BY idioma ORDER BY n DESC
"""
mapa.consultar(p, por_idioma)
# [{'idioma': 'pt', 'n': 25}, {'idioma': 'en', 'n': 25}, ...]

Todas as funções que recebem projeto aceitam um Projeto já aberto ou o caminho da pasta (mapa.coletar("op-2024")).

No Jupyter e no Colab

  • A coleta roda dentro do notebook, com barras de progresso na própria célula. Para desligá-las, use progresso=False.
  • mapa.importar(p, "export.ris") só guarda o arquivo em importados/. Diferente de mapa importar na CLI, ela não roda a coleta: chame mapa.coletar(p) em seguida.
  • mapa.painel(p) abre o painel com o servidor numa thread: a célula termina e o painel fica no ar enquanto o notebook estiver aberto (.parar() o derruba). No Colab, ele abre numa janela nova, pelo proxy do Google (veja Oficina no Colab).
  • como="pandas" e como="polars" em consultar devolvem um DataFrame, mas precisam da biblioteca instalada (pip install pandas). O mapa-da-ciencia não depende de nenhuma das duas.

Tabelas para consulta

O corpus fica em dados/documentos.parquet. consultar e conectar abrem esse arquivo no DuckDB com as views abaixo (as de tópicos, geografia e classificação aparecem depois das etapas correspondentes):

View Uma linha por Colunas principais
documentos documento id, pid, doi, ano, tipo, revista_acronimo, revista_issn, idioma_original, citacoes, licenca, casamento, origens, possivel_duplicata_de; listas titulos, resumos, palavras_chave, autores, afiliacoes
textos título ou resumo em um idioma id, campo (titulo ou resumo), idioma, texto, origem (articlemeta ou openalex)
autores autor de um documento id, ordem, nome, sobrenome, orcid, afiliacoes (ids das afiliações)
afiliacoes afiliação de um documento id, afiliacao, instituicao, divisoes, cidade, uf, pais, fonte (v240, v70 ou openalex)
atribuicoes documento, depois de topicos() id, topico (−1 = sem tópico), atribuicao (cluster ou vizinho), x, y (posição no mapa), vizinhos (5 ids), idioma_analise, fonte_analise
vinculos autor × afiliação, depois de geografia() doc, autor, afiliacao, fonte, texto, instituicao (id; nula se não casou), nivel do casamento, semelhanca, pais, uf e o que a fonte escreveu (pais_fonte, uf_fonte, cidade_fonte)
pesos documento × (instituição, UF, país), depois de geografia() doc, instituicao (nula = sem afiliação; nao-identificada), uf, pais, peso (contagem fracionária: soma 1 por documento)
instituicoes instituição, depois de geografia() id, nome, sigla, pais, uf, tipo, ror, peso, documentos
classificacoes documento × variável × execução, depois de classificar() doc, variavel, valor (texto; lista JSON nas de múltipla escolha), evidencia, status (literal, aproximada, ausente, dispensada), campo, inicio, fim (offsets no texto), tentativas, execucao (modelo e hash do codebook)

A coluna id liga as cinco primeiras views; nas da geografia e na classificacoes, a coluna é doc. Os campos de documentos estão descritos em Fontes de dados. Para consultas longas, abra uma conexão:

with mapa.conectar(p) as con:
    por_ano = con.sql("SELECT ano, count(*) FROM documentos GROUP BY ano").fetchall()

O Parquet também pode ser lido direto pelo pandas ou pelo polars (pd.read_parquet("op-2024/dados/documentos.parquet")), inclusive em R com o pacote arrow.

Fachada mapa_da_ciencia.api

mapa_da_ciencia.api.abrir

abrir(caminho: str | Path = '.') -> Projeto

Abre o projeto na pasta indicada (ou na primeira pasta acima dela que tenha mapa.yaml).

mapa_da_ciencia.api.novo

novo(
    caminho: str | Path,
    *,
    modelo: str = "ciencia-politica",
    perfil: str | None = None,
    revistas: list[str] | None = None,
    anos: Anos | None = None,
) -> Projeto

Cria um projeto, como mapa novo.

Parameters:

Name Type Description Default
caminho str | Path

pasta a criar.

required
modelo str

ciencia-politica (as 10 revistas do piloto e um codebook de exemplo) ou vazio.

'ciencia-politica'
perfil str | None

leve, padrao ou forte. Sem ele, o perfil é sugerido pela memória da máquina.

None
revistas list[str] | None

ISSNs ou acrônimos que substituem as revistas do modelo.

None
anos Anos | None

2024, "2010-2025" ou (2010, 2025).

None

mapa_da_ciencia.api.coletar

coletar(
    projeto: Projeto | str | Path = ".",
    *,
    revistas: list[str] | None = None,
    anos: Anos | None = None,
    limite: int | None = None,
    atualizar: bool = False,
    offline: bool = False,
    sem_openalex: bool = False,
    consulta: str | None = None,
    progresso: bool = True,
) -> ResumoColeta

Coleta o corpus, como mapa coletar, e devolve o resumo da execução (print(resumo) mostra os números).

revistas e anos valem só para esta execução; o mapa.yaml não muda. Os demais argumentos correspondem às opções da CLI (--limite, --atualizar, --offline, --sem-openalex, --consulta).

mapa_da_ciencia.api.importar

importar(
    projeto: Projeto | str | Path, *arquivos: str | Path
) -> list[Importacao]

Guarda exportações do search.scielo.org (RIS, CSV, BibTeX) ou listas de DOIs em importados/.

Diferente de mapa importar, não roda a coleta: chame coletar(projeto) em seguida. Cada Importacao diz quantos registros foram reconhecidos (.resumo()) e quais foram ignorados.

mapa_da_ciencia.api.revistas

revistas(
    busca: str = "", *, area: str = ""
) -> list[Revista]

Revistas correntes do SciELO Brasil, como mapa revistas, filtradas por nome, acrônimo, ISSN ou área.

mapa_da_ciencia.api.documentos

documentos(
    projeto: Projeto | str | Path = ".",
) -> list[Documento]

Todos os documentos do corpus, com títulos, resumos, autores e afiliações.

mapa_da_ciencia.api.embeddings

embeddings(
    projeto: Projeto | str | Path = ".",
    *,
    refazer: bool = False,
    progresso: bool = True,
) -> Embeddings

Um vetor por documento (título e resumo no idioma de análise), calculado pelo Ollama e guardado em cache.

O resultado tem ids e matriz (numpy, uma linha por documento, normalizada), além da marca de cada texto (textos[i].fonte: resumo, reserva ou so_titulo). Na segunda vez, vem inteiro do cache.

mapa_da_ciencia.api.topicos

topicos(
    projeto: Projeto | str | Path = ".",
    *,
    sem_rotulos: bool = False,
    refazer_embeddings: bool = False,
    semente: int | None = None,
    refazer_macrotemas: bool = False,
    progresso: bool = True,
) -> ResumoTopicos

Descobre os tópicos, como mapa topicos, e devolve o resumo (print(resumo) mostra os números).

O resultado fica em dados/topicos/ e pode ser consultado pela view atribuicoes (tópico, coordenadas no mapa e vizinhos de cada documento), por exemplo: consultar(p, "SELECT topico, count(*) FROM atribuicoes GROUP BY topico").

mapa_da_ciencia.api.geografia

geografia(
    projeto: Projeto | str | Path = ".",
    *,
    progresso: bool = True,
) -> ResumoGeografia

Liga as afiliações às instituições, como mapa geografia, e devolve o resumo (print(resumo) mostra os números).

O resultado fica em dados/geografia/ e pode ser consultado pelas views vinculos (cada autor ligado a uma instituição, com o texto da fonte e o nível do casamento), pesos (a contagem fracionária) e instituicoes, por exemplo: consultar(p, "SELECT uf, sum(peso) FROM pesos GROUP BY uf ORDER BY 2 DESC").

mapa_da_ciencia.api.classificar

classificar(
    projeto: Projeto | str | Path = ".",
    *,
    estimar: bool = False,
    limite: int | None = None,
    modelo: str | None = None,
    somente_amostra: bool = False,
    progresso: bool = True,
) -> ResumoClassificacao

Classifica os resumos pelo codebook, como mapa classificar, e devolve o resumo.

O resultado fica em dados/classificacao/ e pode ser consultado pela view classificacoes (uma linha por documento × variável, com o valor, a evidência e o status da conferência; a coluna execucao diz o modelo e o codebook), por exemplo: consultar(p, "SELECT valor, count(*) FROM classificacoes WHERE variavel = 'abordagem' GROUP BY valor").

mapa_da_ciencia.api.amostra_de_validacao

amostra_de_validacao(
    projeto: Projeto | str | Path = ".",
    *,
    refazer: bool = False,
    n: int | None = None,
) -> Amostra

A amostra de validação, como mapa validar amostra: sorteada na primeira vez (ou com refazer=True) e exportada em validacao/amostra.jsonl. amostra.docs traz os ids na ordem da fila de codificação; n troca o tamanho de validacao.n só neste sorteio.

mapa_da_ciencia.api.importar_codificacoes

importar_codificacoes(
    projeto: Projeto | str | Path,
    arquivo: str | Path,
    codificador: str,
    *,
    tipo: Literal["humano", "referencia"] = "humano",
) -> ResumoImportacao

Importa um JSONL de codificações da amostra, como mapa validar importar. Linhas inválidas não são gravadas e aparecem em resumo.invalidas.

mapa_da_ciencia.api.codificacoes

codificacoes(
    projeto: Projeto | str | Path = ".",
    codificador: str | None = None,
) -> list[dict[str, Any]]

As codificações guardadas (de um codificador, ou de todos), uma por codificador × documento × variável.

mapa_da_ciencia.api.validacao

validacao(projeto: Projeto | str | Path = '.') -> Validacao

As métricas de concordância na amostra, como mapa validar metricas: por variável e por par de participantes (codificadores e modelos), com kappa e IC 95%, PABAK, alfa, matriz de confusão e P/R/F1 por classe; McNemar entre modelos e as divergências com o modelo principal.

mapa_da_ciencia.api.relatorio_de_validacao

relatorio_de_validacao(
    projeto: Projeto | str | Path = ".",
) -> dict[str, Path]

Grava o relatório da validação, como mapa validar relatorio, e devolve os caminhos: markdown (validacao/relatorio.md), latex (validacao/tabelas.tex) e json (validacao/metricas.json).

mapa_da_ciencia.api.publicar

publicar(
    projeto: Projeto | str | Path = ".",
    destino: str | Path | None = None,
    *,
    sem_resumos: bool = False,
) -> ResumoPublicacao

Gera o site estático do projeto, como mapa publicar: a interface e o contrato, com api: false, os resumos só com licença aberta e nenhum e-mail. Devolve o resumo (onde ficou, quantos resumos foram e quantos saíram).

mapa_da_ciencia.api.painel

painel(
    projeto: Projeto | str | Path = ".",
    *,
    porta: int = 8765,
    colab: bool | None = None,
) -> Painel

Abre o painel do projeto de dentro de um notebook (Jupyter ou Colab), com o servidor numa thread: a célula termina e o painel continua no ar enquanto o notebook estiver aberto (ou até .parar()).

No Colab (detectado sozinho, ou com colab=True), o painel abre numa janela nova pelo proxy do Colab, que chega ao servidor com o endereço do Google: só nesse modo a API aceita pedidos de outro endereço. A máquina do Colab é só sua, e o proxy exige o seu login.

mapa_da_ciencia.api.consultar

consultar(
    projeto: Projeto | str | Path,
    sql: str,
    *,
    como: Literal[
        "dicts", "tuplas", "pandas", "polars"
    ] = "dicts",
) -> Any

Roda uma consulta SQL sobre o corpus e devolve o resultado já materializado.

Parameters:

Name Type Description Default
sql str

consulta sobre as views documentos, textos, autores e afiliacoes.

required
como Literal['dicts', 'tuplas', 'pandas', 'polars']

dicts (lista de dicionários, o padrão), tuplas, pandas ou polars. Os dois últimos precisam da biblioteca instalada.

'dicts'

mapa_da_ciencia.api.conectar

conectar(
    projeto: Projeto | str | Path = ".",
) -> duckdb.DuckDBPyConnection

Conexão DuckDB com as views documentos, textos, autores, afiliacoes; depois de topicos(), atribuicoes; depois de geografia(), vinculos, pesos e instituicoes; depois de classificar(), classificacoes.

Use com with para fechar ao fim:

with mapa.conectar(p) as con:
    df = con.sql("SELECT * FROM textos WHERE campo = 'resumo'").df()  # .df() pede pandas; .pl(), polars

mapa_da_ciencia.api.cobertura

cobertura(
    projeto: Projeto | str | Path = ".",
) -> dict[str, Any]

Os números da seção Corpus do mapa status: por revista, tipo, idioma, DOI, afiliações, licenças...

mapa_da_ciencia.api.etapas

etapas(
    projeto: Projeto | str | Path = ".",
) -> dict[str, dict[str, Any] | None]

Manifesto da última execução de cada etapa (None para as pendentes), como na tabela do mapa status.

Objetos devolvidos

mapa_da_ciencia.api.Painel dataclass

O painel aberto por painel(): o endereço e como parar o servidor.

parar

parar() -> None

Derruba o servidor do painel.

mapa_da_ciencia.coleta.ResumoColeta dataclass

O que uma execução da coleta fez. print(resumo) mostra os números principais numa frase.

documentos e por_revista contam o que foi gravado no corpus. fora_do_periodo, excluidos_por_tipo e nao_encontrados contam o que ficou de fora, e casamento conta os documentos por passo da ligação com o OpenAlex. requisicoes, do_cache e creditos_openalex medem o acesso às APIs.

mapa_da_ciencia.topicos.pipeline.ResumoTopicos dataclass

O que a etapa de tópicos fez. print(resumo) mostra os números principais numa frase.

nucleo, reatribuidos e sem_topico somam documentos; casados conta os tópicos que mantiveram o número da execução anterior e mesma_cor, os que mantiveram também a cor (não mudaram de macrotema); rotulos diz quantos rótulos vieram do modelo, do cache ou do rotulos.yaml.

mapa_da_ciencia.classificacao.pipeline.ResumoClassificacao dataclass

O que a etapa fez. print(resumo) mostra os números principais numa frase.

mapa_da_ciencia.validacao.amostra.Amostra dataclass

por_estrato

por_estrato() -> Counter[str]

mapa_da_ciencia.validacao.amostra.ResumoImportacao dataclass

mapa_da_ciencia.validacao.metricas.Validacao dataclass

metrica

metrica(
    variavel: str, referencia: str, comparado: str
) -> Metrica | None

mapa_da_ciencia.validacao.metricas.Metrica dataclass

A concordância de um par de participantes numa variável.

mapa_da_ciencia.documento.Documento

Bases: _Base

Um documento do corpus, normalizado a partir de uma ou mais fontes.

texto_em

texto_em(
    campo: Literal["titulos", "resumos"],
    preferidos: list[str],
) -> Texto | None

O primeiro texto nos idiomas preferidos, ou qualquer um, ou None.

mapa_da_ciencia.fontes.importar.Importacao dataclass

resumo

resumo() -> str

mapa_da_ciencia.fontes.revistas.Revista dataclass

Uma revista corrente do SciELO Brasil, como aparece no retrato empacotado.

Módulos internos

As funções abaixo são usadas pela fachada, pela CLI e pelo servidor do painel. Elas podem mudar entre versões menores.

Projeto

mapa_da_ciencia.projeto.Projeto dataclass

config property
config: ConfigProjeto
codebook property
codebook: Codebook
abrir classmethod
abrir(caminho: Path | str = '.') -> Projeto

Abre o projeto na pasta indicada ou na primeira pasta acima que tenha mapa.yaml.

criar classmethod
criar(
    pasta: Path | str,
    *,
    modelo: str,
    perfil: Perfil,
    nome: str | None = None,
    revistas: list[str] | None = None,
    anos: tuple[int, int] | None = None,
) -> Projeto

Cria a pasta do projeto a partir de um modelo, com os modelos de LLM do perfil.

revistas (ISSNs ou acrônimos) e anos substituem o recorte do modelo, mantendo os comentários do YAML.

Configuração

mapa_da_ciencia.config.carregar_config

carregar_config(arquivo: Path) -> ConfigProjeto

mapa_da_ciencia.config.carregar_codebook

carregar_codebook(arquivo: Path) -> Codebook

mapa_da_ciencia.config.ErroConfig

Bases: ValueError

Arquivo de configuração ou codebook inválido. A mensagem já vem pronta para o usuário.

Manifesto de execução

mapa_da_ciencia.manifesto.registrar_execucao

registrar_execucao(
    projeto: Projeto,
    etapa: str,
    *,
    inicio: datetime,
    fim: datetime,
    contagens: dict[str, int] | None = None,
    modelos: dict[str, str] | None = None,
    parametros: dict[str, Any] | None = None,
) -> Path

Grava o manifesto de uma execução concluída e devolve o caminho do arquivo.

mapa_da_ciencia.manifesto.ultima_execucao

ultima_execucao(
    projeto: Projeto, etapa: str
) -> dict[str, Any] | None

O manifesto mais recente da etapa, ou None se ela nunca rodou.

Recursos da máquina

mapa_da_ciencia.recursos.cabe_na_memoria

cabe_na_memoria(
    tamanho_gb: float,
    *,
    margem_gb: float = MARGEM_PADRAO_GB,
    disponivel_gb: float | None = None,
) -> Folga

O modelo, mais uma margem para o contexto e o sistema, cabe na memória disponível agora?

mapa_da_ciencia.llm.perfis.sugerir_perfil

sugerir_perfil(ram_gb: float | None = None) -> Perfil

O perfil mais forte cuja memória mínima cabe na máquina (nunca menos que leve).

Diagnóstico

mapa_da_ciencia.diagnostico.diagnosticar

diagnosticar(
    projeto: Projeto | None = None,
    *,
    ollama: Ollama | None = None,
    checar_rede: bool = True,
) -> list[Checagem]

Contrato de dados

mapa_da_ciencia.contrato.modelos.fragmento_de

fragmento_de(doc_id: str) -> str

Nome do fragmento de detalhes ("00"…"3f") de um documento: FNV-1a 32 bits do id, módulo 64.

A mesma função existe no frontend (frontend/src/lib/dados/fragmentos.ts); os testes garantem que as duas dão o mesmo resultado.

mapa_da_ciencia.contrato.exemplo.gerar_exemplo

gerar_exemplo(
    n_docs: int = 1500, semente: int = 42
) -> tuple[dict[str, m.BaseModel], dict[str, m.Fragmento]]

Gera todos os arquivos do contrato. Devolve (arquivos por nome, fragmentos de detalhes).