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 emimportados/. Diferente demapa importarna CLI, ela não roda a coleta: chamemapa.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"ecomo="polars"emconsultardevolvem um DataFrame, mas precisam da biblioteca instalada (pip install pandas). Omapa-da-ciencianã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'
|
perfil
|
str | None
|
|
None
|
revistas
|
list[str] | None
|
ISSNs ou acrônimos que substituem as revistas do modelo. |
None
|
anos
|
Anos | None
|
|
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 |
required |
como
|
Literal['dicts', 'tuplas', 'pandas', 'polars']
|
|
'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.
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.ResumoImportacao
dataclass
¶
mapa_da_ciencia.validacao.metricas.Validacao
dataclass
¶
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.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
¶
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.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).