#Python

0 Seguidores · 111 Postagens

Python é uma linguagem de programação interpretada de alto nível para programação de uso geral. Criado por Guido van Rossum e lançado pela primeira vez em 1991, o Python tem uma filosofia de design que enfatiza a legibilidade do código, principalmente usando significativos espaços em branco

Site oficial.

InterSystems Python BindingDocumentação.

Anúncio Danusa Calixto · Out. 30, 2025

Olá Comunidade,

Você é um desenvolvedor Python? Se sim, você já pode começar a criar aplicativos com o InterSystems IRIS sem precisar aprender uma nova linguagem de programação! 

Use Python with InterSystems IRIS. Try the exercise. 

👨‍💻Experimente este exercício para começar rapidamente a usar a interface familiar DB-API do Python para se conectar a um banco de dados InterSystems IRIS e executar consultas SQL.

💬 Qual foi a sua experiência com o exercício? Conte-me nos comentários!

0
0 13
Artigo Heloisa Paiva · Set. 30, 2025 3m read

Oi pessoal!  Esse artigo é para quem está começando com InterSystems IRIS. Espero que ajude!

O InterSystems IRIS é uma plataforma de dados unificada: uma base de dados de alta performance com ferramentas de interoperabilidade e análise integradas em um só produto. Você tem SQL e NoSQL na mesma máquina, além de jeitos nativos de rodar Python com seus dados. Em resumo: menos peças móveis, mais capacidade de processamento.

Por que engenheiros escolhem IRIS

0
0 28
Artigo Larissa Prussak · Ago. 5, 2025 1m read

Revisando meus pacotes publicados, identifiquei um bug sério na IRIS Native API.

Existe um método em %Net.DB.Iris chamado function().
Ele é equivalente ao comando ObjectScript $$label^routine(param).
Isso funcionava bem há 2 anos, quando publiquei meus pacotes de extensões para linha de comando.
Agora, está quebrado há pelo menos 1 ano e gera o erro <PROTECT>.

Identifiquei o problema em ObjectScript, Java, Python e Node.js.
Foi registrado como WRC# 1002589.

1
0 31
Artigo Heloisa Paiva · Jul. 24, 2025 5m read

img

Claro, aqui está a tradução:

Módulos, que tópico! Não temos essa noção no ObjectScript, mas é um conceito fundamental em Python. Vamos descobri-lo juntos.

O que é um Módulo?

Eu vejo módulos como uma camada intermediária entre classes e pacotes. Vamos ver por exemplo.

Um exemplo ruim:

# MyClass.py
class MyClass:
    def my_method(self):
        print("Hello from MyClass!")

Quando você tentar usar essa classe em outro script, você faz:

# class_usage.py
from MyClass import MyClass # estranho, né?

my_instance = MyClass()
my_instance.my_method()

Por que este é um exemplo ruim?

Primeiro porque os nomes de arquivos devem estar em snake_case de acordo com a PEP 8, então deveria ser my_class.py. Segundo, porque você está importando uma classe de um arquivo que tem o mesmo nome da classe. Esta não é uma boa prática em Python.

Sei que isso pode ser confuso, especialmente se você vem do ObjectScript, onde as classes são definidas em arquivos com o mesmo nome da classe.

Noções Avançadas

Um Módulo é um Arquivo Python

Então, acabamos de ver que módulos podem ser um arquivo Python, mas sem a extensão .py.

Mas espere, isso significa que um script Python também é um módulo? Sim, é!

É por isso que você deve ter cuidado ao importar um script, pois ele executará o código contido nele. Consulte o artigo Introdução ao Python para mais detalhes.

Um Módulo é uma Pasta com um Arquivo __init__.py

Uau, uma pasta pode ser um módulo? Sim, pode!

Uma pasta pode ser um módulo se contiver um arquivo __init__.py file. Este arquivo pode estar vazio ou conter código de inicialização para o módulo.

Vamos ver um exemplo:

src/python/article/
└── my_folder_module/
    ├── __init__.py
    ├── my_sub_module.py
    └── another_sub_module.py
# my_folder_module/my_sub_module.py
class MySubModule:
    def my_method(self):
        print("Hello from MySubModule!")
# my_folder_module/another_sub_module.py
class AnotherSubModule:
    def another_method(self):
        print("Hello from AnotherSubModule!")
# my_folder_module/__init__.py
# Este arquivo pode estar vazio ou conter código de inicialização para o módulo.

Neste caso, my_folder_module e você pode importá-lo assim:

from my_folder_module import my_sub_module, another_sub_module

Ou se você definir um arquivo __init__.py com o seguinte conteúdo:

# my_folder_module/__init__.py
from .my_sub_module import MySubModule
from .another_sub_module import AnotherSubModule

Você pode importá-lo assim:

from my_folder_module import MySubModule, AnotherSubModule

Você percebe a sutileza? Você pode importar as classes diretamente do módulo sem especificar o submódulo, porque o arquivo __init__.py é executado quando você importa o módulo, e ele pode definir o que está disponível no namespace do módulo.

sys.path

Quando você importa um módulo, o Python o procura nos diretórios listados emsys.path. Esta é uma lista de strings que especifica o caminho de busca por módulos.

Você pode ver o sys.path atual executando o seguinte código:

import sys
print(sys.path)

Por padrão, ele inclui o diretório atual e outros vários diretórios, dependendo da sua instalação Python.

Você também pode adicionar diretórios ao sys.path em tempo de execução, o que é útil quando você deseja importar módulos de um local específico. Por exemplo:

import sys
sys.path.append('/path/to/your/module')
from your_module import YourClass

É por isso que no artigo anterior, adicionamos o caminho para o módulo antes de importá-lo:

Set sys = ##class(%SYS.Python).Import("sys")
do sys.path.append("/irisdev/app/src/python/article")
set my_module = ##class(%SYS.Python).Import("my_module")

sys.path e os outros diretórios

Quais são os outros diretórios em sys.path? Eles geralmente são:

  • O diretório contendo o script de entrada (ou o diretório atual se nenhum script for especificado).
  • Os diretórios da biblioteca padrão, que contêm os módulos built-in que vêm com o Python.
  • site-packages diretórios onde pacotes de terceiros são instalados.d.

site-packages

Como site-packages funciona? Quando você instala um pacote usando pip, ele é instalado no diretório site-packages que é automaticamente incluído em sys.path. Isso permite que você importe o pacote sem ter que especificar sua localização.This allows you to import the package without having to specify its location.

🤨🔍 Mas como e onde o diretório site-packages é definido e por quem?

O diretório site-packages é criado durante a instalação do Python e geralmente está localizado no diretório lib da sua instalação Python. O local exato depende do seu sistema operacional e de como o Python foi instalado.

Por exemplo, em uma instalação Linux típica, o diretório site-packages pode estar localizado em:

/usr/local/lib/python3.x/site-packages

No Windows, pode estar localizado em:

C:\Python3x\Lib\site-packages

Quando você instala um pacote usando pip, ele é instalado no diretório site-packages que é automaticamente incluído em sys.path. Isso permite que você importe o pacote sem ter que especificar sua localização.

import site
print(site.getsitepackages())

🤨🔍 Quando e onde o interpretador Python lê o arquivo site.py?

O arquivo site.py (que está localizado no diretório da biblioteca padrão) é executado automaticamente quando o interpretador Python é iniciado. Ele é responsável por configurar o diretório site-packages e adicioná-lo ao sys.path. Este arquivo está localizado no diretório da biblioteca padrão da sua instalação Python.

sys.path no IRIS

No IRIS, também temos um arquivo site.pyque está localizado em <installation_directory>/lib/python/iris_site.py. Este arquivo é executado quando você inicia ou importa um script/módulo no IRIS, e ele configura o sys.path para você.

e forma geral, o arquivo iris_site.pyfaz o seguinte:

  • Mantém o diretório site-packages padrão
  • Adiciona o diretório<installation_directory>/lib/python/ ao sys.path
    • É aqui que os módulos Python do IRIS estão localizados, por favor, não coloque seus módulos aqui.
  • Adiciona o diretório <installation_directory>/mgr/python/ ao sys.path -É aqui que você pode colocar seus módulos Python personalizados.
  • Adiciona a string de configuração PythonPath ao sys.path

Conclusão

Um módulo pode ser:

  • Um arquivo Python (com ou sem a extensão .py)
  • Uma pasta com um arquivo __init__.py.
  • Um script Python (que também é um módulo).
  • Se você não conseguir importar um módulo, verifique se ele está na lista sys.path.
0
0 26
Artigo Larissa Prussak · Jul. 24, 2025 1m read

Você está curioso para saber como executar scripts Python diretamente no terminal do InterSystems IRIS ou Caché? 🤔
Boa notícia: é fácil! 😆
O IRIS oferece suporte ao Embedded Python, permitindo que você use Python de forma interativa dentro do terminal do IRIS.

Como acessar o Shell do Python?

Para iniciar o shell do Python a partir do terminal do IRIS, basta executar o seguinte comando:

do##class(%SYS.Python).Shell()

Esse comando abre um shell interativo do Python dentro do terminal do IRIS. A partir daí, você pode escrever e executar código Python como faria em um ambiente Python normal.

0
0 25
Artigo Heloisa Paiva · Jul. 22, 2025 2m read

img

Este será um breve artigo sobre a PEP 8, o guia de estilo do Python.

O que é a PEP 8?

Em poucas palavras, a PEP 8 fornece diretrizes e boas práticas sobre como escrever código Python.

  • Nomes de variáveis devem ser em snake_case
  • Nomes de classes devem ser em CamelCase
  • Nomes de funções devem ser em snake_case
  • Constantes devem ser emUPPER_CASE
  • A indentação deve ser de 4 espaços (no tabs)
  • Variáveis/funções privadas devem começar com um sublinhado (_)
    • Isso porque no Python variáveis e funções privadas não existem de fato, é apenas uma convenção.
  • Seu script não deve ser executado quando importado.
  • ...

Não é necessário memorizá-las todas, mas tenha em mente que isso o ajudará a entender o código de outras pessoas e a ajudar outras pessoas a entender o seu código ^^.

Além disso, você pode ter ouvido falar da palavra pythonic. Seguir a PEP 8 é uma maneira de escrever código Python que é considerado "pythonic" (não é apenas isso, mas faz parte).

Por que a PEP 8 é importante e relevante para os desenvolvedores Python IRIS?

No IRIS, e especialmente em ObjectScript, também temos um guia de estilo, que é baseado principalmente em camelCase para nomes de variáveis e PascalCase para nomes de classes. Infelizmente, a PEP 8 recomenda o uso de snake_case para nomes de variáveis e funções.

E você já sabe, em ObjectScript o sublinhado (_) é usado para concatenação e, obviamente, isso não nos convém.

Como superar esse problema? Use aspas duplas para chamar nomes de variáveis/funções em Python no código ObjectScript.

Exemplo:

Class Article.PEP8Example Extends %RegisteredObject
{

ClassMethod Run()
{
    Set sys = ##class(%SYS.Python).Import("sys")
    do sys.path.append("/irisdev/app/src/python/article")
    set pep8Example = ##class(%SYS.Python).Import("pep8_example")
    do pep8Example."my_function"() // Note as aspas duplas ao redor do nome da função 
}

}

Esta instrução chamará a função my_function no arquivo pep8_example.py que é definida da seguinte forma:

# src/python/article/pep8_example.py
def my_function():
    print("Olá, Mundo")

Quando você executar o método Run da classe Article.PEP8Example a saída será:

iris session iris -U IRISAPP '##class(Article.PEP8Example).Run()'
Olá, Mundo!

É isso

0
0 21
Artigo Larissa Prussak · Jun. 17, 2025 3m read

Se você está migrando do Oracle para o InterSystems IRIS — como muitos dos meus clientes — pode se deparar com padrões específicos de SQL do Oracle que precisam ser adaptados.

Veja esse examplo:

SELECT (TO_DATE('2023-05-12','YYYY-MM-DD') - LEVEL + 1) AS gap_date
FROM dual
CONNECT BY LEVEL <= (TO_DATE('2023-05-12','YYYY-MM-DD') - TO_DATE('2023-05-02','YYYY-MM-DD') + 1);

No Oracle:

0
0 25
Artigo Henry Pereira · Maio 30, 2025 6m read

imagem

Sabe aquela sensação de receber o resultado do seu exame de sangue e parecer que está em grego? É exatamente esse problema que o FHIRInsight veio resolver. Surgiu da ideia de que dados médicos não deveriam ser assustadores ou confusos – deveriam ser algo que todos podemos utilizar. Exames de sangue são extremamente comuns para verificar nossa saúde, mas, sejamos sinceros, interpretá-los é difícil para a maioria das pessoas e, às vezes, até para profissionais da área que não trabalham em um laboratório. O FHIRInsight quer tornar todo esse processo mais simples e acessível.

Logo FHIRInsight

🤖 Por que criamos o FHIRInsight

Tudo começou com uma simples pergunta:

“Por que interpretar um exame de sangue ainda é tão difícil — até para médicos, às vezes?”

Se você já olhou para um resultado de laboratório, provavelmente viu um monte de números, abreviações enigmáticas e uma “faixa de referência” que pode ou não se aplicar à sua idade, sexo ou condição. É uma ferramenta de diagnóstico, com certeza — mas sem contexto, vira um jogo de adivinhação. Até profissionais de saúde experientes às vezes precisam recorrer a diretrizes, artigos científicos ou opiniões de especialistas para entender tudo direito.

É aí que o FHIRInsight entra em cena.

Não foi feito apenas para pacientes — fizemos para quem está na linha de frente do atendimento. Para médicos em plantões intermináveis, para enfermeiros que captam sutis padrões nos sinais vitais, para qualquer profissional de saúde que precise tomar decisões certas com tempo limitado e muita responsabilidade. Nosso objetivo é facilitar um pouco o trabalho deles — transformando dados clínicos FHIR em algo claro, útil e fundamentado em ciência médica real. Algo que fale a língua humana.

O FHIRInsight faz mais do que só explicar valores de exames. Ele também:

  • Fornece aconselhamento contextual sobre se um resultado é leve, moderado ou grave
  • Sugere causas potenciais e diagnósticos diferenciais com base em sinais clínicos
  • Recomenda próximos passos — sejam exames adicionais, encaminhamentos ou atendimento de urgência
  • Utiliza RAG (Retrieval-Augmented Generation) para incorporar artigos científicos relevantes que fundamentam a análise

Imagine um jovem médico revisando um hemograma de um paciente com anemia. Em vez de buscar cada valor no Google ou vasculhar revistas médicas, ele recebe um relatório que não só resume o problema, mas cita estudos recentes ou diretrizes da OMS que embasam o raciocínio. Esse é o poder de combinar IA e busca vetorial sobre pesquisas selecionadas.

E o paciente?

Ele não fica mais diante de um monte de números, sem saber o que significa “bilirrubina 2,3 mg/dL” ou se deve se preocupar. Em vez disso, recebe uma explicação simples e cuidadosa. Algo que se assemelha mais a uma conversa do que a um laudo clínico. Algo que ele realmente entende — e que pode levar ao consultório do médico mais preparado e menos ansioso.

Porque é disso que o FHIRInsight trata de verdade: transformar complexidade médica em clareza e ajudar profissionais e pacientes a tomarem decisões melhores e mais confiantes — juntos.

🔍 Por dentro da tecnologia

Claro que toda essa simplicidade na superfície é viabilizada por uma tecnologia poderosa atuando discretamente nos bastidores.

Veja do que o FHIRInsight é feito:

  • FHIR (Fast Healthcare Interoperability Resources) — padrão global de dados de saúde. É assim que recebemos informações estruturadas como resultados de exames, histórico do paciente, dados demográficos e atendimentos. O FHIR é a linguagem que os sistemas médicos falam — e nós traduzimos essa linguagem em algo que as pessoas possam usar.
  • Busca Vetorial RAG (Retrieval-Augmented Generation): o FHIRInsight aprimora seu raciocínio diagnóstico indexando artigos científicos em PDF e URLs confiáveis em um banco de dados usando a busca vetorial nativa do InterSystems IRIS. Quando um resultado de exame fica ambíguo ou complexo, o sistema recupera conteúdo relevante para embasar suas recomendações — não da memória do modelo, mas de pesquisas reais e atualizadas.
  • Engenharia de Prompts para Raciocínio Médico: refinamos nossos prompts para guiar o LLM na identificação de um amplo espectro de condições relacionadas ao sangue. Desde anemia por deficiência de ferro até coagulopatias, desequilíbrios hormonais ou gatilhos autoimunes — o prompt conduz o LLM pelas variações de sintomas, padrões laboratoriais e causas possíveis.
  • Integração com LiteLLM: um adaptador customizado direciona requisições para múltiplos provedores de LLM (OpenAI, Anthropic, Ollama etc.) através de uma interface unificada, permitindo fallback, streaming e troca de modelo com facilidade.

Tudo isso acontece em segundos — transformando valores brutos de laboratório em insights médicos explicáveis e acionáveis, seja para um médico revisando 30 prontuários ou um paciente tentando entender seus números.

🧩 o Adapter LiteLLM: Uma Interface para Todos os Modelos

Nos bastidores, os relatórios do FHIRInsight movidos a IA são impulsionados pelo LiteLLM — uma library python que nos permite chamar mais de 100 LLMs (OpenAI, Claude, Gemini, Ollama etc.) por meio de uma única interface estilo OpenAI.

Porém, integrar o LiteLLM ao InterSystems IRIS exigiu algo mais permanente e reutilizável do que scripts Python escondidos numa Business Operation. Então, criamos nosso próprio Adapter LiteLLM.

Conheça o LiteLLMAdapter

Esse adaptador lida com tudo o que você esperaria de uma integração robusta de LLM:

  • Recebe parâmetros como prompt, model e temperature
  • Carrega dinamicamente variáveis de ambiente (por exemplo, chaves de API)

Para encaixar isso em nossa produção de interoperabilidade em um simples Business Operation:

  • Gerencia configuração em produção por meio da configuração padrão LLMModel
  • Integra-se ao componente FHIRAnalyzer para geração de relatórios em tempo real
  • Atua como uma “ponte de IA” central para quaisquer componentes futuros que precisem de acesso a LLM

Eis o fluxo de forma simplificada:

set response = ##class(dc.LLM.LiteLLMAdapter).CallLLM("Me fale sobre hemoglobina.", "openai/gpt-4o", 0.7)
write response

🧪 Conclusão

Quando começamos a desenvolver o FHIRInsight, nossa missão era simples: tornar exames de sangue mais fáceis de entender — para todo mundo. Não apenas pacientes, mas médicos, enfermeiros, cuidadores... qualquer pessoa que já tenha encarado um resultado de laboratório e pensado: “Ok, mas o que isso realmente significa?”

Todos nós já passamos por isso.

Ao combinar a estrutura do FHIR, a velocidade do InterSystems IRIS, a inteligência dos LLMs e a profundidade de pesquisas médicas reais via busca vetorial, criamos uma ferramenta que transforma números confusos em histórias significativas. Histórias que ajudam pessoas a tomarem decisões mais inteligentes sobre sua saúde — e, quem sabe, detectar algo cedo que passaria despercebido.

Mas o FHIRInsight não é só sobre dados. É sobre como nos sentimos ao olhar para esses dados. Queremos que seja claro, acolhedor e empoderador. Que a experiência seja... como um verdadeiro “vibecoding” na saúde — aquele ponto perfeito onde código inteligente, bom design e empatia humana se encontram.

Esperamos que você experimente, teste, questione — e nos ajude a melhorar.

Diga o que gostaria de ver no próximo release. Mais condições? Mais explicações? Mais personalização?

Isso é só o começo — e adoraríamos que você ajudasse a moldar o que vem a seguir.

1
0 33
Artigo Julio Esquerdo · Jun. 7, 2025 18m read

Olá,

Neste artigo vamos ver o uso do python como linguagem de programação no InterSystems Iris. Para tal vamos usar como referência a versão Community 2025.1 que está disponível para ser baixada em https://download.intersystems.com mediante o login no ambiente. Para maiores informações sobre o download e instalação do Iris veja o link da comunidade https://community.intersystems.com/post/how-download-and-install-intersystems-iris

0
0 41
Artigo Larissa Prussak · Jun. 5, 2025 5m read

Por muito tempo, eu quis aprender o framework Django, mas sempre surgia algum projeto mais urgente que acabava tomando prioridade. Como muitos desenvolvedores, eu uso Python para projetos de machine learning, mas quando comecei a aprender programação para web, o PHP ainda dominava. Então, quando precisei escolher um framework mais robusto para criar aplicações web e publicar meu trabalho de machine learning, acabei voltando para o PHP. Durante um tempo, utilizei o framework Laravel para construir meus sites, e foi com ele que conheci o padrão Model-View-Controller (MVC) moderno de programação

0
0 32
Artigo Heloisa Paiva · Maio 20, 2025 7m read

Este artigo apresenta uma solução em potencial para a busca semântica de código no TrakCare usando o IRIS Vector Search.

Aqui está uma breve visão geral dos resultados da busca semântica de código do TrakCare para a consulta: "Validação antes de salvar o objeto no banco de dados".

 

  • Modelo de Embedding de Código

Existem diversos modelos de embedding desenvolvidos para frases e parágrafos, mas eles não são ideais para embeddings específicos de código.

0
0 30
Artigo Heloisa Paiva · Abr. 18, 2025 18m read

Image generated by OpenAI DALL·E

Sou um grande fã de ficção científica, mas embora eu esteja totalmente a bordo da nave Star Wars (desculpas aos meus colegas Trekkies!), sempre apreciei os episódios clássicos de Star Trek da minha infância. A tripulação diversificada da USS Enterprise, cada um dominando suas funções únicas, é uma metáfora perfeita para entender os agentes de IA e seu poder em projetos como o Facilis. Então, vamos embarcar em uma missão intergaláctica, utilizando a IA como a tripulação da nossa nave e  audaciosamente ir audaciosamente ir homem jamais esteve!  Esse conceito de trabalho em equipe é uma analogia maravilhosa para ilustrar como os agentes de IA funcionam e como os usamos em nosso projeto DC-Facilis. Então, vamos mergulhar e assumir o papel de um capitão de nave estelar, liderando uma tripulação de IA em territórios inexplorados!

Bem-vindo ao CrewAI!

Para gerenciar nossa tripulação de IA, usamos uma estrutura fantástica chamada CrewAI.É enxuta, extremamente rápida e opera como uma plataforma Python multiagente. Uma das razões pelas quais a amamos, além do fato de ter sido criada por outro brasileiro, é sua incrível flexibilidade e design baseado em funções.

from crewai import Agent, Task, Crew

the taken quote

Conheça os Planejadores

No Facilis, nossos agentes de IA são divididos em dois grupos. Vamos começar com o primeiro, que gosto de chamar de "Os Planejadores".

O Agente de Extração

O papel principal do Facilis é receber uma descrição em linguagem natural de um serviço REST e criar automaticamente toda a interoperabilidade necessária. Portanto, nosso primeiro membro da tripulação é o Agente de Extração. Este agente tem a tarefa de "extrair" as especificações da API a partir da descrição fornecida pelo usuário.

Aqui está o que o Agente de Extração procura:

  • Host (obrigatório)
  • Endpoint (obrigatório)
  • Params (opcional)
  • Port (se disponível)
  • modelo JSON (para POST/PUT/PATCH/DELETE)
  • Autenticação (se aplicável)
    def create_extraction_agent(self) -> Agent:
        return Agent(
            role='Extrator de Especificações de API',
            goal='Extrair especificações de API de descrições em linguagem natural',
            backstory=dedent("""
                        Você é especializado em interpretar descrições em linguagem natural
                        e extrair especificações de API estruturadas.
            """),
            allow_delegation=True,
            llm=self.llm
        )

    def extract_api_specs(self, descriptions: List[str]) -> Task:
        return Task(
            description=dedent(f"""
               Extraia as especificações de API das seguintes descrições:
                {json.dumps(descriptions, indent=2)}
                
               Para cada descrição, extraia:
                - Host (obrigatório)
                - Endpoint (obrigatório)
                - Params (opcional)
                - Port (se disponível)
                - modelo JSON (para POST/PUT/PATCH/DELETE)
                - Autenticação (se aplicável)
                
                Marque quaisquer campos obrigatórios ausentes como 'missing'.
                Retorne os resultados em formato JSON como um array de especificações.
            """),
            expected_output="""Um array JSON contendo as especificações de API extraídas com todos os campos obrigatórios e opcionais""",
            agent=self.extraction_agent
        )

O Agente de Validação

Próximo na fila, o Agente de Validação! Sua missão é garantir que as especificações de API coletadas pelo Agente de Extração estejam corretas e consistentes. Ele verifica:

  1. Formato de host válido
  2. Endpoint começando com '/'
  3. Métodos HTTP válidos (GET, POST, PUT, DELETE, PATCH)
  4. Número de porta válido (se fornecido)
  5. Presença de modelo JSON para métodos aplicáveis.

    def create_validation_agent(self) -> Agent:
        return Agent(
            role='API Validator',
            goal='Validar especificações de API quanto à correção e consistência.',
            backstory=dedent("""
                 Você é um especialista em validação de API, garantindo que todas as especificações
                 atendam aos padrões e formatos necessários.
            """),
            allow_delegation=False,
            llm=self.llm
        )

 def validate_api_spec(self, extracted_data: Dict) -> Task:
        return Task(
            description=dedent(f"""
                Valide a seguinte especificação de API:
                {json.dumps(extracted_data, indent=2)}
                
                Verifique:
                1. Formato de host válido
                2. Endpoint começando com '/'
                3. Métodos HTTP válidos  (GET, POST, PUT, DELETE, PATCH)
                4. Número de porta válido (se fornecido)
                5. Presença de modelo JSON para métodos aplicáveis.
                
               Retorne os resultados da validação em formato JSON.
            """),
            expected_output="""Um objeto JSON contendo os resultados da validação com quaisquer erros ou confirmação de validade""",
            agent=self.validation_agent
        )

O Agente de Interação

Avançando, conhecemos o Agente de Interação, nosso Especialista em Interação com o Usuário. Seu papel é obter quaisquer campos de especificação de API ausentes que foram marcados pelo Agente de Extração e validá-los com base nas descobertas do Agente de Validação. Eles interagem diretamente com os usuários para preencher quaisquer lacunas.

O Agente de Produção

Precisamos de duas informações cruciais para criar a interoperabilidade necessária: namespace e nome da produção. O Agente de Produção interage com os usuários para coletar essas informações, de forma muito semelhante ao Agente de Interação.

O Agente de Transformação de Documentação

Assim que as especificações estiverem prontas, é hora de convertê-las em documentação OpenAPI. O Agente de Transformação de Documentação, um especialista em OpenAPI, cuida disso.

    def create_transformation_agent(self) -> Agent:
        return Agent(
            role='Especialista em Transformação OpenAPI',
            goal='Converter especificações de API em documentação OpenAPI',
            backstory=dedent("""
                Você é um especialista em especificações e documentação OpenAPI.
                Seu papel é transformar detalhes de API validados em documentação
                OpenAPI 3.0 precisa e abrangente.
            """),
            allow_delegation=False,
            llm=self.llm
        )

    def transform_to_openapi(self, validated_endpoints: List[Dict], production_info: Dict) -> Task:
        return Task(
            description=dedent(f"""
                Transforme as seguintes especificações de API validadas em documentação OpenAPI 3.0:
                
                Informações de Produção:
                {json.dumps(production_info, indent=2)}
                
               Endpoints Validados:
                {json.dumps(validated_endpoints, indent=2)}
                
               Requisitos:
               1. Gerar especificação OpenAPI 3.0 completa
               2. Incluir schemas de requisição/resposta apropriados
               3. Documentar todos os parâmetros e corpos de requisição
               4. Incluir autenticação se especificado
               5. Garantir formatação de caminho apropriada
                
                Retorne a especificação OpenAPI nos formatos JSON e YAML.
            """),
            expected_output="""Um objeto JSON contendo a especificação OpenAPI 3.0 completa com todos os endpoints e schemas.""",
            agent=self.transformation_agent
        )

The Review Agent

Após a transformação, a documentação OpenAPI passa por uma revisão meticulosa para garantir conformidade e qualidade. O Agente de Revisão segue esta lista de verificação:

1.Conformidade OpenAPI 3.0

  • Especificação de versão correta
  • Elementos raiz obrigatórios
  • Validação da estrutura do schema
  1. Completude
  • Todos os endpoints documentados
  • Parâmetros totalmente especificados
  • Schemas de requisição/resposta definidos
  • Esquemas de segurança configurados corretamente
  1. Verificações de Qualidade
  • Convenções de nomenclatura consistentes
  • Descrições claras
  • Uso adequado de tipos de dados
  • Códigos de resposta significativos
  1. Melhores Práticas
  • Uso adequado de tags
  • Nomenclatura de parâmetros consistente
  • Definições de segurança apropriadas

Finalmente, se tudo parecer bom, o Agente de Revisão reporta um objeto JSON saudável com a seguinte estrutura:

{
 "is_valid": boolean,
 "approved_spec": object (a especificação OpenAPI revisada e possivelmente corrigida),
 "issues": [array de strings descrevendo quaisquer problemas encontrados],
 "recommendations": [array de sugestões de melhoria]
}

    def create_reviewer_agent(self) -> Agent:
        return Agent(
            role='Revisor de Documentação OpenAPI',
            goal='Garantir a conformidade e qualidade da documentação OpenAPI',
            backstory=dedent("""
                Você é a autoridade final em qualidade e conformidade de documentação OpenAPI.
               Com vasta experiência em especificações OpenAPI 3.0, você revisa meticulosamente
               a documentação para precisão, completude e adesão aos padrões.
            """),
            allow_delegation=True,
            llm=self.llm
        )


    def review_openapi_spec(self, openapi_spec: Dict) -> Task:
        return Task(
            description=dedent(f"""
                Revise a seguinte especificação OpenAPI para conformidade e qualidade:
                
                {json.dumps(openapi_spec, indent=2)}
                
                Lista de Verificação da Revisão::
                1. Conformidade OpenAPI 3.0
                - Verificar a especificação de versão correta
                - Verificar os elementos raiz obrigatórios
                - Validar a estrutura do schema
                
                2. Completude
                - Todos os endpoints devidamente documentados
                - Parâmetros totalmente especificados
                - Schemas de requisição/resposta definidos
                - Esquemas de segurança configurados corretamente
                
                3. Quality Checks
                - Consistent naming conventions
                - Clear descriptions
                - Proper use of data types
                - Meaningful response codes
                
                4. Best Practices
                - Proper tag usage
                - Consistent parameter naming
                - Appropriate security definitions
                
                Você deve retornar um objeto JSON com a seguinte estrutura:
                {{
                    "is_valid": boolean,
                    "approved_spec": object (a especificação OpenAPI revisada e possivelmente corrigida),
                    "issues": [array de strings descrevendo quaisquer problemas encontrados],
                    "recommendations": [array de sugestões de melhoria]
                }}
            """),
            expected_output=""" Um objeto JSON contendo: is_valid (boolean), approved_spec (object), issues (array), e recommendations (array)""",
            agent=self.reviewer_agent
        )

O Agente Iris

O último agente no grupo do planejador é o Agente Iris, que envia a documentação OpenAPI finalizada para o Iris.


    def create_iris_i14y_agent(self) -> Agent:
        return Agent(
            role='Especialista em Integração Iris I14y',
            goal='Integrar especificações de API com o serviço Iris I14y',
            backstory=dedent("""
                  Você é responsável por garantir uma integração suave entre o sistema de
                 documentação da API e o serviço Iris I14y. Você lida com a
                 comunicação com o Iris, valida as respostas e garante a integração
                 bem-sucedida das especificações da API.
            """),
            allow_delegation=False,
            llm=self.llm
        )

    def send_to_iris(self, openapi_spec: Dict, production_info: Dict, review_result: Dict) -> Task:
        return Task(
            description=dedent(f"""
               Enviar a especificação OpenAPI aprovada para o serviço Iris I14y:

                Informações de Produção:
                - Nome: {production_info['production_name']}
                - Namespace: {production_info['namespace']}
                - É Novo: {production_info.get('create_new', False)}

               Status da Revisão:
                - Aprovado: {review_result['is_valid']}
                
                Retornar o resultado da integração em formato JSON.
            """),
            expected_output="""Um objeto JSON contendo o resultado da integração com o serviço Iris I14y, incluindo o status de sucesso e os detalhes da resposta.""",
            agent=self.iris_i14y_agent
        )

class IrisI14yService:
    def __init__(self):
        self.logger = logging.getLogger('facilis.IrisI14yService')
        self.base_url = os.getenv("FACILIS_URL", "http://dc-facilis-iris-1:52773") 
        self.headers = {
            "Content-Type": "application/json"
        }
        self.timeout = int(os.getenv("IRIS_TIMEOUT", "504"))  # in milliseconds
        self.max_retries = int(os.getenv("IRIS_MAX_RETRIES", "3"))
        self.logger.info("IrisI14yService initialized")

    async def send_to_iris_async(self, payload: Dict) -> Dict:
        """
        Enviar carga útil para o endpoint de geração do Iris de forma assíncrona.
        """
        self.logger.info("Enviando carga útil para o endpoint de geração do Iris.")
        if isinstance(payload, str):
            try:
                json.loads(payload)  
            except json.JSONDecodeError:
                raise ValueError("Invalid JSON string provided")
        
        retry_count = 0
        last_error = None

        # Cria timeout para o aiohttp
        timeout = aiohttp.ClientTimeout(total=self.timeout / 1000)  # Converte ms para seconds

        while retry_count < self.max_retries:
            try:
                self.logger.info(f"Attempt {retry_count + 1}/{self.max_retries}: Enviando requisição para {self.base_url}/facilis/api/generate")
                
                async with aiohttp.ClientSession(timeout=timeout) as session:
                    async with session.post(
                        f"{self.base_url}/facilis/api/generate",
                        json=payload,
                        headers=self.headers
                    ) as response:
                        if response.status == 200:
                            return await response.json()
                        response.raise_for_status()

            except asyncio.TimeoutError as e:
                retry_count += 1
                last_error = e
                error_msg = f"Timeout occurred (attempt {retry_count}/{self.max_retries})"
                self.logger.warning(error_msg)
                
                if retry_count < self.max_retries:
                    wait_time = 2 ** (retry_count - 1)
                    self.logger.info(f"Waiting {wait_time} seconds before retry...")
                    await asyncio.sleep(wait_time)
                continue

            except aiohttp.ClientError as e:
                error_msg = f"Failed to send to Iris: {str(e)}"
                self.logger.error(error_msg)
                raise IrisIntegrationError(error_msg)

        error_msg = f"Failed to send to Iris after {self.max_retries} attempts due to timeout"
        self.logger.error(error_msg)
        raise IrisIntegrationError(error_msg, last_error)

Conheça os Geradores

Nosso segundo conjunto de agentes são os Geradores. Eles estão aqui para transformar as especificações OpenAPI em interoperabilidade InterSystems IRIS. Há oito deles neste grupo.

O primeiro deles é o Agente Analisador. Ele é como o planejador, traçando a rota. Seu trabalho é mergulhar nas especificações OpenAPI e descobrir quais componentes de Interoperabilidade IRIS são necessários.


    def create_analyzer_agent():
        return Agent(
            role="Analisador de Especificações OpenAPI",
            goal="Analisar minuciosamente as especificações OpenAPI e planejar os componentes de Interoperabilidade IRIS",
            backstory="""Você é um especialista em especificações OpenAPI e em Interoperabilidade InterSystems IRIS.
                     Seu trabalho é analisar documentos OpenAPI e criar um plano detalhado de como eles devem ser implementados como componentes de Interoperabilidade IRIS.""",
            verbose=False,
            allow_delegation=False,
            tools=[analyze_openapi_tool],
            llm=get_facilis_llm()
        )

   analysis_task = Task(
        description="""Analisar a especificação OpenAPI e planejar os componentes de Interoperabilidade IRIS necessários.
Incluir uma lista de todos os componentes que devem estar na classe de Produção."",
        agent=analyzer,
        expected_output="Uma análise detalhada da especificação OpenAPI e um plano para os componentes IRIS, incluindo a lista de componentes de Produção",
        input={
            "openapi_spec": openApiSpec,
            "production_name": "${production_name}" 
        }
    )

Em seguida, os Agentes de Business Services (BS) e Business Operations (BO) assumem o controle. Eles geram os Business Services e as Business Operations com base nos endpoints OpenAPI. Eles usam uma ferramenta útil chamada MessageClassTool para gerar as classes de mensagens perfeitas, garantindo a comunicação.


    def create_bs_generator_agent():
        return Agent(
            role="Gerador de Produção e Business Service IRIS",
            goal="Gerar classes de Produção e Business Service IRIS formatadas corretamente a partir de especificações OpenAPI",
            backstory="""Você é um desenvolvedor InterSystems IRIS experiente, especializado em Produções de Interoperabilidade.
                 Sua expertise reside na criação de Business Services e Produções capazes de receber e processar requisições de entrada com base emespecificações de API."",
            verbose=False,
            allow_delegation=True,
            tools=[generate_production_class_tool, generate_business_service_tool],
            llm=get_facilis_llm()
        )

    def create_bo_generator_agent():
        return Agent(
            role="Gerador de Business Operation IRIS",
            goal="Gerar classes de Business Operation IRIS formatadas corretamente a partir de especificações OpenAPI",
            backstory="""Você é um desenvolvedor InterSystems IRIS experiente, especializado em Produções de Interoperabilidade.
                 Sua expertise reside na criação de Business Operations capazes de enviar requisições para sistemas externos com base em especificações de API.""",
            verbose=False,
            allow_delegation=True,
            tools=[generate_business_operation_tool, generate_message_class_tool],
            llm=get_facilis_llm()
        )

    bs_generation_task = Task(
        description="Gerar classes de Business Service com base nos endpoints OpenAPI",
        agent=bs_generator,
        expected_output="Definições de classes de Business Service do IRIS",
        context=[analysis_task]
    )

    bo_generation_task = Task(
        description="Gerar classes de Business Operation com base nos endpoints OpenAPI",
        agent=bo_generator,
        expected_output="Definições de classes de Business Operation do IRIS",
        context=[analysis_task]
    )

    class GenerateMessageClassTool(BaseTool):
        name: str = "generate_message_class"
        description: str = "Gerar uma classe de Mensagem IRIS"
        input_schema: Type[BaseModel] = GenerateMessageClassToolInput

        def _run(self, message_name: str, schema_info: Union[str, Dict[str, Any]]) -> str:
            writer = IRISClassWriter()
            try:
                if isinstance(schema_info, str):
                    try:
                        schema_dict = json.loads(schema_info)
                    except json.JSONDecodeError:
                        return "Error: Invalid JSON format for schema info"
                else:
                    schema_dict = schema_info

                class_content = writer.write_message_class(message_name, schema_dict)
                # Armazenar a classe gerada.
                writer.generated_classes[f"MSG.{message_name}"] = class_content
                return class_content
            except Exception as e:
                return f"Error generating message class: {str(e)}"

Depois que BS e BO fazem o que têm que fazer, é a hora do Agente de Produção brilhar! Este agente junta tudo para criar um ambiente de produção coeso.

Depois que tudo estiver configurado, o próximo na linha é o Agente de Validação. Este entra em cena para uma verificação final, garantindo que cada classe Iris esteja ok.

Em seguida, temos o Agente de Exportação e o Agente de Coleção. O Agente de Exportação gera os arquivos .cls, enquanto o Agente de Coleção reúne todos os nomes de arquivos. Tudo é passado para o importador, que compila tudo no InterSystems Iris.


    def create_exporter_agent():
        return Agent(
            role="Exportador de Classes IRIS",
            goal="Exportar e validar definições de classes IRIS para arquivos .cls adequados",
            backstory="""Você é um especialista em implantação InterSystems IRIS. Seu trabalho é garantir que as definições de classes IRIS geradas sejam devidamente exportadas como arquivos .cls válidos que
                possam ser importados diretamente para um ambiente IRIS.""",
            verbose=False,
            allow_delegation=False,
            tools=[export_iris_classes_tool, validate_iris_classes_tool],
            llm=get_facilis_llm()
        )
        
    def create_collector_agent():
        return Agent(
            role="Coletor de Classes IRIS",
            goal="Coletar todos os arquivos de classes IRIS gerados em uma coleção JSON",
            backstory="""Você é um especialista em sistema de arquivos responsável por reunir e
                organizar os arquivos de classes IRIS gerados em uma coleção estruturada.""",
            verbose=False,
            allow_delegation=False,
            tools=[CollectGeneratedFilesTool()],
            llm=get_facilis_llm()
        )

    export_task = Task(
        description="Exportar todas as classes IRIS geradas como arquivos .cls válidos",
        agent=exporter,
        expected_output="Arquivos .cls IRIS válidos salvos no diretório de saída",
        context=[bs_generation_task, bo_generation_task],
        input={
            "output_dir": "/home/irisowner/dev/output/iris_classes"  # Optional
        }
    )

    collection_task = Task(
        description="Coletar todos os arquivos de classes IRIS gerados em uma coleção JSON",
        agent=collector,
        expected_output="Coleção JSON de todos os arquivos .cls gerados",
        context=[export_task, validate_task],
        input={
            "directory": "./output/iris_classes"
        }
    )

Limitações e Desafios

Nosso projeto começou como um experimento empolgante, onde meus colegas mosqueteiros e eu almejávamos criar uma ferramenta totalmente automatizada usando agentes. Foi uma jornada selvagem! Nosso foco principal estava em integrações de API REST. É sempre uma alegria receber uma tarefa com uma especificação OpenAPI para integrar; no entanto, sistemas legados podem ser uma história completamente diferente. Pensamos que automatizar essas tarefas poderia ser incrivelmente útil. Mas toda aventura tem suas reviravoltas: Um dos maiores desafios foi instruir a IA a converter OpenAPI para Interoperabilidade Iris. Começamos com o modelo openAI GPT3.5-turbo, que em testes iniciais se mostrou difícil com depuração e prevenção de interrupções. A mudança para o Anthropic Claude 3.7 Sonnet mostrou melhores resultados para o grupo Gerador, mas não tanto para os Planejadores... Isso nos levou a dividir nossas configurações de ambiente, usando diferentes provedores de LLM para flexibilidade. Usamos GPT3.5-turbo para planejamento e Claude sonnet para geração, uma ótima combinação! Essa combinação funcionou bem, mas encontramos problemas com alucinações. A mudança para o GT4o melhorou os resultados, mas ainda enfrentamos alucinações na criação de classes Iris e, às vezes, especificações OpenAPI desnecessárias, como o renomado exemplo Pet Store OpenAPI. Nos divertimos muito aprendendo ao longo do caminho, e estou super animado com o futuro incrível nesta área, com inúmeras possibilidades!

1
0 42
Artigo Heloisa Paiva · Abr. 20, 2025 6m read

Sei que pessoas completamente novas no VS Code, Git, Docker, FHIR e outras ferramentas podem, às vezes, ter dificuldades com a configuração do ambiente. Por isso, decidi escrever um artigo que percorre todo o processo de configuração passo a passo para facilitar o início.

Eu realmente agradeceria se você pudesse deixar um comentário no final – me diga se as instruções foram claras, se algo ficou faltando ou se há mais alguma coisa que você acharia útil.

A configuração inclui:

✅ VS Code – Editor de código
✅ Git – Sistema de controle de versão
✅ Docker – Executa uma instância do IRIS for Health Community
Extensão REST Client do VS Code – Para executar consultas à API FHIR
✅ Python – Para escrever scripts baseados em FHIR
✅ Jupyter Notebooks –Para tarefas de IA e FHIR

Antes de começar: Certifique-se de ter privilégios de administrador no seu sistema.

Além de ler o guia, você também pode seguir os passos nos vídeos:

Para Windows

0
0 39
InterSystems Oficial Danusa Calixto · Abr. 3, 2025

Resumo de Alertas

Alerta ID Produto & Versões Afectadas Requisitos Explícitos
DP-439207  InterSystems IRIS® data platform 2024.3 (AIX) Instalações AIX Usando JSON e conjuntos de Caracteres Unicode non-Latin-1 
DP-439280  InterSystems IRIS 2024.3 (containers com IntegratedML)  IntegratedML Containers usando TensorFlow

Detalhes dos Alertas

DP-439207 - Problemas no Parser JSON Unicode em AIX

0
0 28
Artigo Heloisa Paiva · Fev. 27, 2025 6m read

A InterSystems está na vanguarda da tecnologia de bancos de dados desde sua criação, sendo pioneira em inovações que consistentemente superam concorrentes como Oracle, IBM e Microsoft. Ao se concentrar em um design de kernel eficiente e adotar uma abordagem intransigente em relação ao desempenho de dados, a InterSystems criou um nicho em aplicações de missão crítica, garantindo confiabilidade, velocidade e escalabilidade.

A História de Excelência Técnica

0
0 39
Artigo Julio Esquerdo · Fev. 12, 2025 5m read

Utilizando Flask, API REST e IAM com o InterSystems IRIS

Parte 3 – IAM

O InterSystems API Manager (IAM) é um componente que permite monitorar, controlar e gerir o tráfego de APIs baseadas em HTTP. Ele também atua como uma API gateway entre aplicações e servidores InterSystems IRIS. 

O documento publicado em https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=PAGE_apimgr traz as informações sobre o produto.

0
0 30
Artigo Julio Esquerdo · Fev. 12, 2025 6m read

Utilizando Flask, API REST e IAM com o InterSystems IRIS

Parte 2 – Aplicativo Flask

Flask é um microframework de desenvolvimento web escrito em Python. Ele é conhecido por ser simples, flexível e permitir o desenvolvimento rápido de aplicações. 

A instalação do Flask é muito simples. Depois de ter o python instalado corretamente no seu sistema operacional precisamos instalar a biblioteca flask com o comando pip. Para o consumo de API REST é aconselhado o uso da biblioteca requests. O link a seguir traz um guia para a instalação do flask: https://flask.palletsprojects.com/en/stable/installation/

0
0 25
Artigo Julio Esquerdo · Fev. 12, 2025 10m read

Utilizando Flask, API REST e IAM com o InterSystems IRIS

Parte 1 – API REST

Olá,

Neste artigo vamos ver a implementação de uma API REST para realizar a manutenção de um CRUD, utilizando o Flask e o IAM.

Nesta primeira parte do artigo vamos ver a construção e publicação da API REST no Iris.

Primeiro, vamos criar a nossa classe persistente para armazenar os dados. Para isso vamos para o Iris e criamos nossa classe:

Class ERP.Cliente Extends (%Persistent, %Populate, %XML.Adaptor)

{

Property nome As %String;

Property idade As %Integer;

}

0
0 33
Artigo Julio Esquerdo · Fev. 11, 2025 7m read

Utilizando o Gateway SQL com Python, Vector Search e Interoperabilidade no InterSystems Iris

Parte 2 – Python e Vector Search

Uma vez que temos acesso aos dados da nossa tabela externa podemos utilizar tudo que o Iris tem de excelente com estes dados. Vamos, por exemplo, ler os dados da nossa tabela externa e gerar uma regressão polinomial com eles.

Para mais informações sobre o uso do python com o Iris veja a documentação disponível em https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_epython

0
0 38
Artigo Julio Esquerdo · Fev. 11, 2025 4m read

Utilizando o Gateway SQL com Python, Vector Search e Interoperabilidade no InterSystems Iris

Parte 1 – Gateway SQL

Olá,

Neste artigo vamos ver o uso do Gateway SQL no Iris. O Gateway SQL permite que o Iris tenha acesso a tabelas de outros bancos (externos) via ODBC ou JDBC. Podemos acessar Tabelas ou Visões de diversos bancos, como Oracle, PostgreSQL, SQL Server, MySQL e outros.

Do ponto de vista de uso é como se a tabela estivesse local na nossa instância Iris, porém o armazenamento é realizado em um local externo.

0
0 57
Artigo Heloisa Paiva · jan 26, 2025 8m read

No artigo anterior. Práticas de membros de classe e sua execução dentro do Python embutido. Agora voltaremos nossa atenção para o processo de alternância de espaços de nomes, acesso a variáveis globais, travessia e execução de rotinas dentro do Python embutido.

Antes de prosseguir para as outras funções. vamos revisar brevemente a função executedentro do pacote iris. Esta função é excepcionalmente benéfica para executar funções ObjectScript arbitrárias e invocação de classe.

0
0 33
Artigo Heloisa Paiva · jan 23, 2025 7m read

Olá comunidade,

Neste artigo, vou descrever e ilustrar o processo de implementação do ObjectScript dentro do Python embutido. Esta discussão também fará referência a outros artigos relacionados ao Python embutido, bem como abordará questões que foram benéficas para a minha jornada de aprendizado.

Como você sabe, a integração de recursos Python dentro do IRIS tem sido possível há algum tempo. Este artigo se concentrará em como incorporar perfeitamente o ObjectScript com o Python embutido.

0
0 41
Artigo Heloisa Paiva · jan 16, 2025 5m read

Tenho o prazer de anunciar a nova versão do IoP, que aliás não é apenas uma linha de comando. Estou dizendo isso porque o novo mecanismo de pesquisa de IA ainda pensa que o IoP é apenas uma linha de comando. Mas não é. É uma estrutura completa para construir aplicativos sobre a estrutura de interoperabilidade do IRIS com uma abordagem priorizando Python.

A nova versão do IoP: 3.2.0 possui muitas novidades, mas a mais importante é o suporte a DTL (Data Type Language). 🥳

Tanto para mensagens IoP quanto para jsonschema. 🎉

image

Suporte DTL

A partir da versão 3.2.0, o IoP oferece suporte a transformações DTL.

DTL é a camada de transformação de dados na Interoperabilidade do IRIS.

As transformações DTL são usadas para transformar dados de um formato para outro usando um editor gráfico. Também oferece suporte a estruturas jsonschema.

Como usar DTL com Mensagens

Primeiramente, você precisa registrar sua classe de mensagem em um arquivo settings.py.

Para fazer isso, adicione a seguinte linha no arquivo settings.py :

settings.py

from msg import MyMessage

SCHEMAS = [MyMessage]

A seguir, você pode usar o comando de migração do IoP para gerar arquivos de esquema para suas classes de mensagem.

iop --migrate /path/to/your/project/settings.py

Exemplo

msg.py

from iop import Message
from dataclasses import dataclass

@dataclass
class MyMessage(Message):
    name: str = None
    age: int = None

settings.py

from msg import MyMessage

SCHEMAS = [MyMessage]

Migrar os arquivos do esquema.

iop --migrate /path/to/your/project/settings.py

Construindo uma Transformação DTL

Para construir uma transformação DTL, você precisa criar uma nova classe de transformação DTL.

Vá para o Portal de Gerenciamento de Interoperabilidade do IRIS e crie uma nova transformação DTL.

image

Em seguida, selecione as classes de mensagem de origem e destino.

image

E seu esquema.

image

Então você pode começar a construir sua transformação.

image

Você também pode testar sua transformação.

image

Exemplo de carga útil para testar como mensagem de origem:

<test>
  <Message>
    <json><![CDATA[
{
"list_str":["toto","titi"],
"post":{"Title":"foo","Selftext":"baz"},
"list_post":[{"Title":"bar","Selftext":"baz"},{"Title":"foo","Selftext":"foo"}]
}
]]></json>
  </Message>
</test>

Suporte JsonSchema

A partir da versão 3.2.0, o IoP suporta estruturas jsonschema para transformações DTL.

Assim como para classes de mensagens, você precisa registrar seu jsonschema.

Para fazer isso, você precisa invocar seu comando iris:

zw ##class(IOP.Message.JSONSchema).ImportFromFile("/irisdev/app/random_jsonschema.json","Demo","Demo")

Onde o primeiro argumento é o caminho para o arquivo jsonschema, o segundo argumento é o nome do pacote e o terceiro argumento é o nome do esquema.

Então você pode usá-lo em sua transformação DTL.

O esquema estará disponível com o nome de Demo.

Exemplo de arquivo jsonschema:

{
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "title": "PostMessage",
    "properties": {
        "post": {
            "allOf": [
                {
                    "$ref": "#/$defs/PostClass"
                }
            ]
        },
        "to_email_address": {
            "type": "string",
            "default": null
        },
        "my_list": {
            "type": "array",
            "items": {
                "type": "string"
            }
        },
        "found": {
            "type": "string",
            "default": null
        },
        "list_of_post": {
            "type": "array",
            "items": {
                "allOf": [
                    {
                        "$ref": "#/$defs/PostClass"
                    }
                ]
            }
        }
    },
    "$defs": {
        "PostClass": {
            "type": "object",
            "title": "PostClass",
            "properties": {
                "title": {
                    "type": "string"
                },
                "selftext": {
                    "type": "string"
                },
                "author": {
                    "type": "string"
                },
                "url": {
                    "type": "string"
                },
                "created_utc": {
                    "type": "number"
                },
                "original_json": {
                    "type": "string",
                    "default": null
                }
            },
            "required": [
                "title",
                "selftext",
                "author",
                "url",
                "created_utc"
            ]
        }
    }
}

Exemplo de Transformação DTL com JsonSchema ou Classe de Mensagem

Muitos podem ser encontrados no pacote UnitTest no diretório./src/tests/cls.

Class UnitTest.ComplexTransform Extends Ens.DataTransformDTL [ DependsOn = IOP.Message ]
{

Parameter IGNOREMISSINGSOURCE = 1;

Parameter REPORTERRORS = 1;

Parameter TREATEMPTYREPEATINGFIELDASNULL = 0;

XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
{
<transform sourceClass='IOP.Message' targetClass='IOP.Message' sourceDocType='registerFilesIop.message.ComplexMessage' targetDocType='registerFilesIop.message.ComplexMessage' create='new' language='objectscript' >
<assign value='source.{post}' property='target.{post}' action='set' />
<foreach property='source.{list_str()}' key='k1' >
<assign value='source.{list_str(k1)}_"foo"' property='target.{list_str()}' action='append' />
</foreach>
<foreach property='source.{list_post()}' key='k2' >
<assign value='source.{list_post().Title}' property='target.{list_post(k2).Title}' action='append' />
</foreach>
</transform>
}

}

Nova documentação

O IoP conta com uma nova documentação, disponível em https://grongierisc.github.io/interoperability-embedded-python/.

Você encontrará todas as informações necessárias para começar a usar o IoP.

image

Espero que você goste desta nova versão do IoP. 🎉

0
0 43
Artigo Julio Esquerdo · Nov. 28, 2024 20m read

Usando o Python no InterSystems IRIS – Montando o Relatório de Análise Exploratória de Dados

Olá,

Neste artigo vamos ver como usar o python para realizar a análise exploratória de dados (Exploratory Data Analysis - EDA) em um dataframe.

EDA é uma etapa importante no ciclo de análise de dados, É quando você examina os dados para entender suas características e padrões.

0
0 90