1 Synesis: API em Memória (synesis.load)

Versão 0.2.0


1.1 Introdução

A API synesis.load permite compilar projetos Synesis diretamente em memória, sem dependência de arquivos em disco. Esta funcionalidade é ideal para:

  • Jupyter Notebooks: Análise interativa de dados qualitativos
  • Scripts Python: Automação de pipelines de pesquisa
  • Integração com Pandas: Exportação direta para DataFrames
  • Testes e Prototipagem: Validação rápida de anotações

1.1.1 Diferença entre CLI e API

Aspecto CLI (synesis compile) API (synesis.load)
Entrada Arquivos em disco (.synp, .syn, .synt) Strings em memória
Saída Arquivos JSON/CSV/Excel Dicts, DataFrames
Uso Terminal, CI/CD Notebooks, Scripts
I/O Leitura/escrita em disco Zero I/O

1.2 Instalação

1.2.1 Requisitos

pip install synesis

1.2.2 Com suporte a Pandas (recomendado)

pip install synesis pandas

1.2.3 Verificar instalação

import synesis
print(synesis.__version__)  # 0.2.0

1.3 Quick Start

import synesis

# Conteúdos em memória
template = """
TEMPLATE Minimal
SOURCE FIELDS
    OPTIONAL date
END SOURCE FIELDS
ITEM FIELDS
    REQUIRED quote
END ITEM FIELDS
FIELD date TYPE DATE SCOPE SOURCE END FIELD
FIELD quote TYPE QUOTATION SCOPE ITEM END FIELD
END TEMPLATE
"""

project = """
PROJECT Demo
    TEMPLATE "template.synt"
END PROJECT
"""

annotations = {
    "sample.syn": """
SOURCE @ref2024
    date: 2024-06-15

    ITEM
        quote: A tecnologia mostra resultados promissores.
    END ITEM
END SOURCE
"""
}

bibliography = """
@article{ref2024,
    author = {Silva, Maria},
    title = {Estudo sobre Tecnologia},
    year = {2024}
}
"""

# Compilar
result = synesis.load(
    project_content=project,
    template_content=template,
    annotation_contents=annotations,
    bibliography_content=bibliography,
)

# Verificar resultado
if result.success:
    print(f"Compilado: {result.stats.item_count} items")
    df = result.to_dataframe("items")
    print(df)
else:
    print(result.get_diagnostics())

1.4 Função synesis.load()

1.4.1 Assinatura

def load(
    project_content: str,
    template_content: str,
    annotation_contents: Optional[Dict[str, str]] = None,
    ontology_contents: Optional[Dict[str, str]] = None,
    bibliography_content: Optional[str] = None,
    project_filename: str = "<project>",
    template_filename: str = "<template>",
) -> MemoryCompilationResult

1.4.2 Parâmetros

Parâmetro Tipo Obrigatório Descrição
project_content str Sim Conteúdo do arquivo .synp
template_content str Sim Conteúdo do arquivo .synt
annotation_contents Dict[str, str] Não Dicionário {filename: conteúdo} para arquivos .syn
ontology_contents Dict[str, str] Não Dicionário {filename: conteúdo} para arquivos .syno
bibliography_content str Não Conteúdo do arquivo .bib (BibTeX)
project_filename str Não Nome virtual para mensagens de erro
template_filename str Não Nome virtual para mensagens de erro

1.4.3 Retorno

Retorna um objeto MemoryCompilationResult com os dados compilados e métodos de exportação.

1.4.4 Exemplo Completo

import synesis

result = synesis.load(
    project_content="""
        PROJECT PesquisaQualitativa
            TEMPLATE "analysis.synt"
            INCLUDE BIBLIOGRAPHY "refs.bib"
            INCLUDE ANNOTATIONS "data.syn"
            INCLUDE ONTOLOGY "concepts.syno"
        END PROJECT
    """,
    template_content="""
        TEMPLATE QualitativeAnalysis

        SOURCE FIELDS
            REQUIRED date
            OPTIONAL country
        END SOURCE FIELDS

        ITEM FIELDS
            REQUIRED quote
            REQUIRED BUNDLE note, chain
            OPTIONAL code
        END ITEM FIELDS

        ONTOLOGY FIELDS
            REQUIRED description
            OPTIONAL topic
        END ONTOLOGY FIELDS

        FIELD date TYPE DATE SCOPE SOURCE END FIELD
        FIELD country TYPE TEXT SCOPE SOURCE END FIELD
        FIELD quote TYPE QUOTATION SCOPE ITEM END FIELD
        FIELD note TYPE MEMO SCOPE ITEM END FIELD
        FIELD code TYPE CODE SCOPE ITEM END FIELD
        FIELD chain TYPE CHAIN
            SCOPE ITEM
            ARITY >= 2
            RELATIONS
                INFLUENCES: Relação de influência
                ENABLES: Relação de habilitação
            END RELATIONS
        END FIELD
        FIELD description TYPE TEXT SCOPE ONTOLOGY END FIELD
        FIELD topic TYPE TOPIC SCOPE ONTOLOGY END FIELD

        END TEMPLATE
    """,
    annotation_contents={
        "interviews.syn": """
            SOURCE @silva2024
                date: 2024-03-15
                country: Brasil

                ITEM
                    quote: O custo é uma barreira significativa.
                    note: Entrevistado identifica fator econômico
                    chain: Cost -> INFLUENCES -> Adoption
                END ITEM

                ITEM
                    quote: A aceitação pública facilita a implementação.
                    note: Relação entre fatores sociais e técnicos
                    chain: Public Acceptance -> ENABLES -> Implementation
                END ITEM
            END SOURCE
        """
    },
    ontology_contents={
        "concepts.syno": """
            ONTOLOGY Cost
                description: Fator econômico de custo
                topic: Economics
            END ONTOLOGY

            ONTOLOGY Public Acceptance
                description: Aceitação da comunidade
                topic: Social Factors
            END ONTOLOGY

            ONTOLOGY Adoption
                description: Adoção de tecnologia
                topic: Technology
            END ONTOLOGY

            ONTOLOGY Implementation
                description: Implementação técnica
                topic: Technology
            END ONTOLOGY
        """
    },
    bibliography_content="""
        @article{silva2024,
            author = {Silva, João and Santos, Maria},
            title = {Fatores de Adoção Tecnológica},
            journal = {Revista Brasileira de Pesquisa},
            year = {2024}
        }
    """,
)

if result.success:
    print(f"Sources: {result.stats.source_count}")
    print(f"Items: {result.stats.item_count}")
    print(f"Ontologies: {result.stats.ontology_count}")
    print(f"Chains: {result.stats.chain_count}")

1.5 Classe MemoryCompilationResult

O objeto retornado por synesis.load() oferece métodos para acessar e exportar os dados compilados.

1.5.1 Atributos

Atributo Tipo Descrição
success bool True se compilação sem erros
linked_project LinkedProject Projeto vinculado (ou None se erros)
validation_result ValidationResult Erros, warnings e informações
template TemplateNode Template carregado
bibliography Dict[str, BibEntry] Bibliografia indexada
stats CompilationStats Estatísticas de compilação

1.5.2 Estatísticas (CompilationStats)

result.stats.source_count    # Número de SOURCEs
result.stats.item_count      # Número de ITEMs
result.stats.ontology_count  # Número de ONTOLOGYs
result.stats.code_count      # Códigos únicos
result.stats.chain_count     # Número de CHAINs
result.stats.triple_count    # Triplas extraídas (from, rel, to)

1.5.3 Métodos de Verificação

# Verificar sucesso
if result.success:
    # Processar dados
    ...

# Verificar erros específicos
if result.has_errors():
    print("Erros encontrados")

if result.has_warnings():
    print("Warnings encontrados")

# Obter diagnósticos formatados
print(result.get_diagnostics())

1.6 Métodos de Exportação

1.6.1 to_json_dict()

Retorna a estrutura JSON completa como dicionário Python.

data = result.to_json_dict()

# Acessar dados
project_name = data["project"]["name"]
sources = data["sources"]

for source in sources:
    print(f"Fonte: {source['bibref']}")
    for item in source["items"]:
        print(f"  Quote: {item['quote']}")

# Serializar para JSON
import json
json_str = json.dumps(data, indent=2, ensure_ascii=False)

1.6.2 to_csv_tables()

Retorna todas as tabelas como dicionário de tuplas (headers, rows).

tables = result.to_csv_tables()

# Listar tabelas disponíveis
print(tables.keys())  # dict_keys(['sources', 'items', 'ontologies', 'chains', 'codes'])

# Acessar tabela específica
headers, rows = tables["items"]
for row in rows:
    print(row)

1.6.3 to_dataframe(table_name)

Retorna uma tabela específica como pandas.DataFrame.

import pandas as pd

# Tabela de items
df_items = result.to_dataframe("items")
print(df_items.head())

# Tabela de chains
df_chains = result.to_dataframe("chains")
print(df_chains)

1.6.4 to_dataframes()

Retorna todas as tabelas como dicionário de DataFrames.

dfs = result.to_dataframes()

# Acessar qualquer tabela
dfs["sources"].info()
dfs["items"].describe()
dfs["chains"].head()
dfs["ontologies"].to_csv("ontologies.csv")

1.7 Tabelas Disponíveis

1.7.1 sources

Fontes bibliográficas com metadados.

Coluna Descrição
bibref Referência bibliográfica ((key?))
date Data (se definida)
country País (se definido)
source_file Arquivo de origem
source_line Linha no arquivo
source_column Coluna no arquivo

1.7.2 items

Unidades analíticas (excertos e anotações).

Coluna Descrição
bibref Referência da fonte
quote Excerto textual
notes Anotações analíticas (lista)
codes Códigos aplicados (lista)
source_file Arquivo de origem
source_line Linha no arquivo
source_column Coluna no arquivo

1.7.3 chains

Triplas relacionais extraídas das cadeias.

Coluna Descrição
bibref Referência da fonte
from_code Código de origem
relation Tipo de relação
to_code Código de destino
source_file Arquivo de origem
source_line Linha no arquivo
source_column Coluna no arquivo

1.7.4 ontologies

Definições de conceitos.

Coluna Descrição
concept Nome do conceito
description Descrição
topic Categoria superior
source_file Arquivo de origem
source_line Linha no arquivo
source_column Coluna no arquivo

1.7.5 codes

Frequência de códigos.

Coluna Descrição
code Nome do código
count Frequência de uso

1.8 Integração com Pandas

1.8.1 Análise Básica

import synesis
import pandas as pd

result = synesis.load(
    project_content=project,
    template_content=template,
    annotation_contents=annotations,
)

if result.success:
    # Carregar tabelas
    dfs = result.to_dataframes()

    # Análise de items
    df_items = dfs["items"]
    print(f"Total de items: {len(df_items)}")
    print(f"Items por fonte: {df_items['bibref'].value_counts()}")

    # Análise de chains
    df_chains = dfs["chains"]
    print(f"Relações mais frequentes: {df_chains['relation'].value_counts()}")

    # Códigos mais usados
    df_codes = dfs["codes"]
    print(df_codes.sort_values("count", ascending=False))

1.8.2 Filtragem e Agrupamento

# Filtrar items por fonte
items_silva = df_items[df_items["bibref"] == "silva2024"]

# Agrupar chains por relação
chains_by_rel = df_chains.groupby("relation").size()

# Ontologias por topic
ontologies_by_topic = dfs["ontologies"].groupby("topic").size()

1.8.3 Exportação

# Para CSV
df_items.to_csv("items_analysis.csv", index=False)

# Para Excel (múltiplas abas)
with pd.ExcelWriter("analysis.xlsx") as writer:
    for name, df in dfs.items():
        df.to_excel(writer, sheet_name=name, index=False)

1.9 Uso em Jupyter Notebook

1.9.1 Célula 1: Setup

import synesis
import pandas as pd
pd.set_option('display.max_colwidth', 100)

1.9.2 Célula 2: Definir Conteúdos

template = """
TEMPLATE JupyterDemo

SOURCE FIELDS
    REQUIRED date
END SOURCE FIELDS

ITEM FIELDS
    REQUIRED quote
    REQUIRED BUNDLE note, chain
END ITEM FIELDS

ONTOLOGY FIELDS
    REQUIRED description
END ONTOLOGY FIELDS

FIELD date TYPE DATE SCOPE SOURCE END FIELD
FIELD quote TYPE QUOTATION SCOPE ITEM END FIELD
FIELD note TYPE MEMO SCOPE ITEM END FIELD
FIELD chain TYPE CHAIN
    SCOPE ITEM
    ARITY >= 2
    RELATIONS
        INFLUENCES: Influência causal
        ENABLES: Habilitação
        INHIBITS: Inibição
    END RELATIONS
END FIELD
FIELD description TYPE TEXT SCOPE ONTOLOGY END FIELD

END TEMPLATE
"""

project = """
PROJECT NotebookAnalysis
    TEMPLATE "template.synt"
END PROJECT
"""

1.9.3 Célula 3: Adicionar Dados

annotations = {
    "data.syn": """
SOURCE @study2024
    date: 2024-01-10

    ITEM
        quote: O alto custo inicial dificulta a adoção.
        note: Barreira econômica identificada
        chain: Cost -> INHIBITS -> Adoption
    END ITEM

    ITEM
        quote: O suporte governamental acelera a implementação.
        note: Fator institucional positivo
        chain: Government Support -> ENABLES -> Implementation
    END ITEM

    ITEM
        quote: A falta de conhecimento técnico limita o uso.
        note: Barreira de capacitação
        chain: Technical Knowledge -> INFLUENCES -> Usage
    END ITEM
END SOURCE
"""
}

ontologies = {
    "concepts.syno": """
ONTOLOGY Cost
    description: Custos financeiros associados
END ONTOLOGY

ONTOLOGY Adoption
    description: Processo de adoção tecnológica
END ONTOLOGY

ONTOLOGY Government Support
    description: Apoio de políticas públicas
END ONTOLOGY

ONTOLOGY Implementation
    description: Execução técnica do projeto
END ONTOLOGY

ONTOLOGY Technical Knowledge
    description: Conhecimento técnico necessário
END ONTOLOGY

ONTOLOGY Usage
    description: Utilização efetiva da tecnologia
END ONTOLOGY
"""
}

bibliography = """
@article{study2024,
    author = {Oliveira, Ana},
    title = {Barreiras à Adoção Tecnológica},
    year = {2024}
}
"""

1.9.4 Célula 4: Compilar

result = synesis.load(
    project_content=project,
    template_content=template,
    annotation_contents=annotations,
    ontology_contents=ontologies,
    bibliography_content=bibliography,
)

print(f"Sucesso: {result.success}")
print(f"Sources: {result.stats.source_count}")
print(f"Items: {result.stats.item_count}")
print(f"Chains: {result.stats.chain_count}")

1.9.5 Célula 5: Visualizar Items

df_items = result.to_dataframe("items")
df_items[["bibref", "quote", "notes"]]

1.9.6 Célula 6: Analisar Chains

df_chains = result.to_dataframe("chains")
df_chains

1.9.7 Célula 7: Rede de Relações

# Frequência de relações
df_chains["relation"].value_counts().plot(kind="bar", title="Tipos de Relação")

1.9.8 Célula 8: Exportar JSON

import json

data = result.to_json_dict()
print(json.dumps(data, indent=2, ensure_ascii=False)[:500])

1.10 Função compile_string()

Para parsing de fragmentos individuais sem compilação completa.

1.10.1 Assinatura

def compile_string(
    content: str,
    filename: str = "<string>"
) -> List[Any]

1.10.2 Uso

import synesis

# Parsear fragmento de anotação
nodes = synesis.compile_string("""
SOURCE @ref2024
    date: 2024-05-20

    ITEM
        quote: Texto de exemplo.
    END ITEM
END SOURCE
""")

# Acessar nós AST
source = nodes[0]
print(f"Bibref: {source.bibref}")
print(f"Items: {len(source.items)}")

for item in source.items:
    print(f"  Quote: {item.quote}")

1.10.3 Tipos de Nós Retornados

Tipo Descrição
SourceNode Bloco SOURCE com ITEMs aninhados
ItemNode Bloco ITEM individual
OntologyNode Bloco ONTOLOGY
ProjectNode Bloco PROJECT

1.11 Tratamento de Erros

1.11.1 Erros de Sintaxe

Erros de sintaxe levantam exceção SynesisSyntaxError:

try:
    result = synesis.load(
        project_content="PROJECT Broken",  # Falta END PROJECT
        template_content=template,
    )
except Exception as e:
    print(f"Erro de sintaxe: {e}")

1.11.2 Erros de Validação

Erros semânticos são capturados no resultado:

result = synesis.load(
    project_content=project,
    template_content=template,
    annotation_contents={
        "bad.syn": """
SOURCE @inexistente
    ITEM
        quote: Referência não existe no .bib
    END ITEM
END SOURCE
"""
    },
)

if not result.success:
    print("Erros de validação:")
    print(result.get_diagnostics())

1.11.3 Formato de Diagnósticos

erro: bad.syn:1:8: Referência bibliográfica '@inexistente' não encontrada.
    SOURCE @inexistente
           ^~~~~~~~~~~

    Referências disponíveis: @silva2024, @oliveira2023

1.12 Referência Rápida

1.12.1 Importação

import synesis

# Funções principais
synesis.load(...)           # Compilação completa em memória
synesis.compile_string(...) # Parsing de fragmento

# Classes
synesis.MemoryCompilationResult  # Resultado da compilação
synesis.CompilationStats         # Estatísticas

1.12.2 Fluxo Típico

# 1. Preparar conteúdos
project = "..."
template = "..."
annotations = {"file.syn": "..."}

# 2. Compilar
result = synesis.load(project, template, annotations)

# 3. Verificar
if result.success:
    # 4. Exportar
    df = result.to_dataframe("items")
    data = result.to_json_dict()
else:
    print(result.get_diagnostics())

Documentação gerada para Synesis v0.2.0