Nouvelle publication

検索

Article
· Juin 5 18m de lecture

Uso de Python en InterSystems Iris

Uso de Python en InterSystems Iris

Hola

En este artículo veremos el uso de python como lenguaje de programación en InterSystems Iris. Para ello, utilizaremos como referencia la versión de Community 2025.1 que está disponible para ser descargada en https:// download.intersystems.com iniciando sesión en el entorno. Para obtener más información sobre cómo descargar e instalar Iris, consulte el enlace de la comunidad https://community.intersystems.com/post/how-download-and-install-intersystems-iris

Una vez instalado el iris, ahora necesitamos tener python disponible en nuestro entorno. Tenemos varios tutoriales que explican la instalación y configuración de python en Iris. Una buena fuente de referencia es el enlace a la documentación oficial de InterSystems en https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_epython

Una vez que hemos instalado y configurado python en Iris, podemos hacer una primera prueba: abrir el shell de python a través del terminal Iris. Para ello, abriremos una ventana de terminal Iris y ejecutaremos el comando Do $SYSTEM. Python.Shell():

Fig. 1 – Pantalla de concha de Python en Iris

Si tienes tu entorno configurado correctamente, verás la pantalla de arriba. A partir de ahí podemos ejecutar comandos, como ver la versión de python. Para ello utilizaremos el módulo sys:

Fig. 2 – Pantalla de concha de Python en Iris

Listo. Tenemos a Iris y python listas para trabajar. Ahora podemos crear, por ejemplo, una clase Iris y programar algunos métodos usando python en ella. Veamos un ejemplo:

Class Demo.Pessoa Extends %Persistent
{

Property nome As %String;

Method MeuNome() [ Language = objectscript ]
{
              write ..nome
}

Method MeuNomePython() [ Language = python ]
{
              print(self.nome)
}
}

 La clase anterior tiene una propiedad (nombre) y dos métodos, uno en objectscript y otro en python, solo para comparar. Llamando a estos métodos, tenemos el resultado en la siguiente pantalla:

 

Fig. 3 – Llamada al método en Iris

 

 

Vea entonces que podemos tener en la misma clase métodos codificados en objectscript y en python. Y de uno de ellos podemos llamar al otro. Vea el siguiente ejemplo. Vamos a crear un nuevo método GetKey y desde el método MyPythonName vamos a hacer una llamada y recuperar la información:

Method MeuNomePython() [ Language = python ]
{
              chave=self.GetChave()
              print(self.nome)
              print(chave)
}

Method GetChave() As %Integer [ Language = objectscript ]
{
              Return $Get(^Chave)
}

Vamos a crear uno global con el valor que queremos que se recupere:

Fig. 4 – Creación de global en Iris

Listo. Con el global created, llamemos ahora a nuestro método:

Fig. 5 – Llamada al método en Iris

 

Observe que ahora nuestro método python hace una llamada a otro método, este codificado en objectscript. Lo contrario también es cierto.

Python tiene una serie de bibliotecas útiles, como:

  • iris: permite la interacción con la base de datos y el entorno de Iris
  • matplot – Visualización de datos y gráficos
  • numpy: proporciona soporte para matrices y estructuras de datos
  • scikit-learn: le permite crear e implementar modelos de aprendizaje automático
  • pandas: se utiliza para la manipulación y el análisis de datos

Otra característica presente en Iris con python es la posibilidad de acceder a los datos vía SQL, es decir, podemos tener los datos almacenados en tablas en Iris y código python consumiendo estos datos. Veamos un ejemplo de código que lee una tabla Iris y genera un archivo XLS utilizando la biblioteca Iris y Pandas:

ClassMethod tabela() As %Status [ Language = python ]
{

              import iris
              import pandas as pd
             
              rs = iris.sql.exec("select * from demo.alunos")
              df = rs.dataframe()   
              caminho_arquivo = 'c:\\temp\\dados.xlsx'
              df.to_excel(caminho_arquivo, index=False)
             
              return True
}

Como se ve, usamos las bibliotecas iris y pandas en el código. A continuación, creamos un conjunto de registros (rs) con el comando SQL deseado y después de eso un marco de datos pandas (df) de este conjunto de registros. Desde el marco de datos, exportamos los datos de la tabla a un archivo de Excel en la ruta especificada (df.to_excel). Fíjate que con muy pocas líneas armamos un código extremadamente útil. Aquí el uso de las bibliotecas de python fue clave. Ya nos han proporcionado el soporte para el dataframe (pandas) y a partir de ahí su manipulación (to_excel). Ejecutando nuestro código, tenemos la tabla de Excel generada a partir de los datos de la tabla:

Fig. 6 – Llamada al método en Iris

 

Fig. 7 – Hoja de trabajo generada por el método

 

Python tiene varias bibliotecas listas para usar con varias características, así como una gran cantidad de código en comunidades que se puede usar en aplicaciones.

Uno de ellos, que mencionamos anteriormente, es scikit-learn, que permite el uso de varios mecanismos de regresión, permitiendo la creación de métodos de predicción basados en información, como una regresión lineal. Podemos ver un ejemplo de código de regresión a continuación:

ClassMethod CalcularRegressaoLinear() As %String [ Language = python ]
{
    import iris
    import json

    import pandas as pd
    from sklearn.linear_model import LinearRegression
    from sklearn.metrics import mean_absolute_error
    import numpy as np
    import matplotlib
    import matplotlib.pyplot as plt
    matplotlib.use("Agg")
    
    rs = iris.sql.exec("select venda as x, temperatura as y from estat.fabrica")
    df = rs.dataframe()
    
    print(df)
    
    # Reformatando x1 para uma matriz 2D exigida pelo scikit-learn
    X = df[['x']]
    y = df['y']     # Inicializa e ajusta o modelo de regressão linear
    model = LinearRegression()
    model.fit(X, y)     # Extrai os coeficientes da regressão
    coeficiente_angular = model.coef_[0]
    intercepto = model.intercept_
    r_quadrado = model.score(X, y)
    
    # Calcula Y_pred baseado no X
    Y_pred = model.predict(X)
            
    # Calcula MAE
    MAE = mean_absolute_error(y, Y_pred)     # Previsão para a linha de regressão
    x_pred = np.linspace(df['x'].min(), df['x'].max(), 100).reshape(-1, 1)
    y_pred = model.predict(x_pred)     # Geração do gráfico de regressão
    plt.figure(figsize=(8, 6))
    plt.scatter(df['x'], df['y'], color='blue', label='Dados Originais')
    plt.plot(df['x'], df['y'], color='black', label='Linha dos Dados Originais')
    plt.scatter(df['x'], Y_pred, color='green', label='Dados Previstos')
    plt.plot(x_pred, y_pred, color='red', label='Linha da Regressão')
    plt.scatter(0, intercepto, color="purple", zorder=5, label="Ponto do intercepto")
    plt.title('Regressão Linear')
    plt.xlabel('X')
    plt.ylabel('Y')
    plt.legend()
    plt.grid(True)     # Salvando o gráfico como imagem
    caminho_arquivo = 'c:\\temp\\RegressaoLinear.png'
    plt.savefig(caminho_arquivo, dpi=300, bbox_inches='tight')
    plt.close()
        
    # Formata os resultados em JSON
    resultado = {
        'coeficiente_angular': coeficiente_angular,
        'intercepto': intercepto,
        'r_quadrado': r_quadrado,
        'MAE': MAE
    }     return json.dumps(resultado)
}

El código lee una tabla en Iris a través de SQL, crea un dataframe pandas basado en los datos de la tabla y calcula una regresión lineal, generando un gráfico con la línea de regresión, además de traer indicadores de regresión. Todo esto desde la biblioteca scikit-learn.

El artículo https://pt.community.intersystems.com/post/usando-o-python-no-intersystems-iris-%E2%80%93-calculando-uma-regress%C3%A3o-linear-simples  proporciona más información sobre el uso de scikit-learn para calcular la regresión lineal.

Iris también permite el almacenamiento de datos vectoriales, lo que abre numerosas posibilidades. La biblioteca langchain_iris trae mecanismos que ayudan en el almacenamiento y recuperación de información en bases de datos vectoriales.

El siguiente código toma un archivo PDF y genera una base de datos vectorial con las incrustaciones generadas para futuras recuperaciones de datos:

ClassMethod Ingest(collectionName As %String, filePath As %String) As %String [ Language = python ]
{     import json
    from langchain_iris import IRISVector
    from langchain_openai import OpenAIEmbeddings
    from langchain_community.document_loaders import PyPDFLoader     try:
        apiKey = <chatgpt_api_key>
        loader = PyPDFLoader(filePath)
        splits = loader.load_and_split()
        vectorstore = IRISVector.from_documents(
            documents=splits,
            embedding=OpenAIEmbeddings(openai_api_key=apiKey),
            dimension=1536,
            collection_name=collectionName,
        )
        return json.dumps({"status": True})
    except Exception as err:
        return json.dumps({"error": str(err)})
}

 

Al leer el archivo PDF, se "divide" en partes y estas piezas se almacenan en forma de incrustaciones en Iris. Las incrustaciones son vectores que representan esa división.

Fig. 8 – Tabla con columna vectorial en Iris

 

Una vez que se ha ingerido el archivo, ahora podemos recuperar información y pasarla al LLM para generar un texto de retorno basado en una pregunta formulada. La pregunta se convierte en vectores y se busca en la base de datos. A continuación, los datos recuperados se envían a LLM, que da formato a una respuesta. En el ejemplo usamos ChatGPT:

Fig.9 – Llamada al método en Iris

 

A continuación se muestra el código de la búsqueda realizada:

ClassMethod Retrieve(collectionName As %String, question As %String, sessionId As %String = "") [ Language = python ]
{
    import json
    import iris
    from langchain_iris import IRISVector
    from langchain_community.chat_message_histories import ChatMessageHistory
    from langchain_core.chat_history import BaseChatMessageHistory
    from langchain_core.runnables.history import RunnableWithMessageHistory
    from langchain_openai import ChatOpenAI, OpenAIEmbeddings    

    from langchain.chains import create_history_aware_retriever
    from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
    from langchain.chains import create_retrieval_chain
    from langchain.chains.combine_documents import create_stuff_documents_chain

    
    try:
        
        apiKey = <chatgpt_api_key>
        model = "gpt-3.5-turbo"
        llm = ChatOpenAI(model= model, temperature=0, api_key=apiKey)
        embeddings = OpenAIEmbeddings(openai_api_key=apiKey)         vectorstore = IRISVector(
            embedding_function=OpenAIEmbeddings(openai_api_key=apiKey),
            dimension=1536,
            collection_name=collectionName,
        )         retriever = vectorstore.as_retriever()         contextualize_q_system_prompt = """Dado um histórico de bate-papo e a última pergunta do usuário \
        que pode fazer referência ao contexto no histórico do bate-papo, formule uma pergunta independente \
        que pode ser entendido sem o histórico de bate-papo. NÃO responda à pergunta, \
        apenas reformule-o se necessário e devolva-o como está."""
        
        contextualize_q_prompt = ChatPromptTemplate.from_messages(
            [
                ("system", contextualize_q_system_prompt),
                MessagesPlaceholder("chat_history"),
                ("human", "{input}"),
            ]
        )
        history_aware_retriever = create_history_aware_retriever(
            llm, retriever, contextualize_q_prompt
        )         qa_system_prompt = """
                            Você é um assistente inteligente que responde perguntas com base em dados recuperados de uma base. Dependendo da natureza dos dados, você deve escolher o melhor formato de resposta:                             1. **Texto:** Se os dados contêm principalmente informações descritivas ou narrativas, responda em formato de texto.
                           
                            2. **Tabela:** Se os dados contêm informações estruturadas (ex: listas, valores, métricas, comparações diretas), responda em formato HTML com o seguinte estilo:
                               - Bordas de 1px sólidas e de cor #dddddd.
                               - O cabeçalho deve ter um fundo cinza escuro (#2C3E50) e texto em branco.
                               - As células devem ter padding de 8px.
                               - As linhas pares devem ter um fundo cinza claro (#f9f9f9).
                               - As linhas devem mudar de cor ao passar o mouse sobre elas, usando a cor #f1f1f1.
                               - O texto nas células deve estar centralizado.                             3. **Lista:** Se os dados contêm informações estruturadas (ex: listas, valores, métricas, comparações diretas), responda em formato HTML com o seguinte estilo:
                               - Bordas de 1px sólidas e de cor #dddddd.
                               - O cabeçalho deve ter um fundo cinza escuro (#2C3E50) e texto em branco.
                               - As células devem ter padding de 8px.
                               - As linhas pares devem ter um fundo cinza claro (#f9f9f9).
                               - As linhas devem mudar de cor ao passar o mouse sobre elas, usando a cor #f1f1f1.
                               - O texto nas células deve estar centralizado.
                                                        
                            4. **Gráfico:** Se os dados contêm informações que são mais bem visualizadas em um gráfico (ex: tendências, distribuições, comparações entre categorias), gere um gráfico apropriado. Inclua um título, rótulos de eixo e uma legenda quando necessário. Responda utilizando um link do quickchart.io.
                                                        
                            Contexto: {context}
                            Pergunta: {input}
                            """
        
        qa_prompt = ChatPromptTemplate.from_messages(
            [
                ("system", qa_system_prompt),
                MessagesPlaceholder("chat_history"),
                ("human", "{input}"),
            ]
        )         question_answer_chain = create_stuff_documents_chain(llm, qa_prompt)
        rag_chain = create_retrieval_chain(history_aware_retriever, question_answer_chain)         def get_session_history(sessionId: str) -> BaseChatMessageHistory:
            rs = iris.sql.exec("SELECT * FROM (SELECT TOP 5 pergunta, resposta, ID FROM Vector.ChatHistory WHERE sessionId = ? ORDER BY ID DESC) SUB ORDER BY ID ASC", sessionId)
            history = ChatMessageHistory()
            for row in rs:
                history.add_user_message(row[0])
                history.add_ai_message(row[1])
            return history         def save_session_history(sessionId: str, pergunta: str, resposta: str):
            iris.sql.exec("INSERT INTO Vector.ChatHistory (sessionId, pergunta, resposta) VALUES (?, ?, ?) ", sessionId, pergunta, resposta)         conversational_rag_chain = RunnableWithMessageHistory(
            rag_chain,
            get_session_history,
            input_messages_key="input",
            history_messages_key="chat_history",
            output_messages_key="answer",
        )         ai_msg_1 = conversational_rag_chain.invoke(
            {"input": question, "chat_history": get_session_history(sessionId).messages},
            config={
                "configurable": {"session_id": sessionId}
            },
        )
        
        save_session_history(sessionId, question, str(ai_msg_1['answer']))
        return str(ai_msg_1['answer'])
    except Exception as err:
        return str(err)
}

 

Aquí en este código entran varios aspectos que deben tenerse en cuenta en este tipo de código, como el contexto de la conversación, el prompt de LLM, las incrustaciones y la búsqueda vectorial.

E incluso podemos tener una interfaz para realizar las llamadas al método, lo que le da un aspecto más sofisticado a la consulta. En el ejemplo tenemos una página web accediendo a una api REST que llama al método de consulta:

 

Fig. 10 – Llamada a la API REST en la pantalla de la aplicación web en Iris

 

Estos son ejemplos del uso de python en Iris. Pero el universo de bibliotecas disponibles es mucho mayor. Podemos usar bibliotecas para reconocimiento de imágenes, OCR, biometría, estadísticas y más.

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Annonce
· Juin 5

Cambridge Developer Meetup - Building and Evaluating Agentic Generative Retrieval Systems

Join our next in-person Developer Meetup in Cambridge to explore the latest trends, tools, and features for innovating on data. This time we will dive into Building and Evaluating Agentic Generative Retrieval Systems.

Talk 1
Agentic Retrieval: Techniques beyond Vector Search
Speaker: Suprateem Banerjee, Sales Engineer - AI Specialist

Talk 2
Setting up testing frameworks to quantitatively measure improvements in agentic systems
This talk with cover how open source libraries such as langfuse and deepeval can be leveraged to see how improvements to prompts, llm models and tools change an agent / RAG system's performance. We will briefly cover how these systems work before delving into how they can be combined together.
Speaker: @Jayesh Gupta, Solutions Developer, InterSystems

>> Register here

 

⏱ Day and Time: July 9, 5:30 p.m. to 7:30 p.m.
NEW VENUE ALERT:
📍Amazon Boston Office, 55 Pier 4 Blvd, Boston, MA 02210

Save your seat now!

Food, beverages, and networking opportunities will be provided as always.
Join our Discord channel to connect with developers from the InterSystems developer ecosystem.

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Annonce
· Juin 5

[Video] Role of Data and Interoperability in Effective AI in Healthcare

Hey Community!

We're happy to share the next video in the "Code to Care" series on our InterSystems Developers YouTube:

⏯  Role of Data and Interoperability in Effective AI in Healthcare

This video is focused on the role of data and interoperability in enabling effective AI in healthcare. The discussion covers the importance of data normalization, patient matching, and adherence to national standards in both traditional machine learning and generative AI applications. Insights are shared on how healthcare organizations can better prepare their data strategies to support accurate and trustworthy AI outcomes.

Presenters:
🗣 @Don Woodlock, Head of Global Healthcare Solutions, InterSystems
🗣 Jay Nakashima, President, eHealth Exchange, Board Member

Enjoy watching, and subscribe for more videos! 👍

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Question
· Juin 5

SQL Procedure - Equivalent to "IN LIKE"

How would you go about creating an SQL Stored Procedure that would result in the same output as "IN LIKE"?
For example...


CustomersTable

RecordId CustomerName
123 Mark Stevens
456 Betty Johnson
789 John Stevens
321 Brian Smith
654 John Markson
987 Tom Obrian
select *
from CustomersTable
where inLike('%Mark%', '%John%')

Would return:

123 Mark Stevens
456 Betty Johnson
789 John Stevens
654 John Markson
3 nouveaux commentaires
Discussion (3)2
Connectez-vous ou inscrivez-vous pour continuer
Article
· Juin 5 5m de lecture

Usando Django e Vue.js para criar uma aplicação web no IRIS: Explorando o framework Django

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 web. Para deixar as coisas ainda mais complexas, gosto de desenvolver o front-end usando um framework moderno de JavaScript. O que eu mais domino é o Vue.js, então mantive essa escolha nesse projeto — embora seja mais comum ver as pessoas usando React.

Por que usar um framework complexo afinal? Quais os maiores desafios de aprender um framework como Django, Laravel, React ou Vue?

Cada um tem sua resposta para isso, mas eu passei a gostar de frameworks MVC porque eles oferecem uma estrutura clara para organizar o projeto. Isso me evita ter que reinventar a roda toda vez. No começo, esses frameworks podem parecer restritivos e confusos, mas, depois que você se familiariza com a estrutura, fica mais fácil adicionar novas funcionalidades.

O desafio é que as coisas podem até ficar “simples demais”. Frameworks como o Django usam muitas convenções e atalhos, baseados em conceitos comuns, mas com nomes e estruturas específicas. No meu projeto, por exemplo, o Django gerencia as APIs e todo o roteamento web. Se quero adicionar um novo endpoint de API, preciso criar uma função no arquivo views.py, depois ir até o urls.py e adicionar uma instrução para importar essa função e outra para definir a URL onde esse endpoint estará disponível. Depois disso, preciso editar meu componente Vue para, via JavaScript, consultar esse endpoint, exibir os dados ou manipulá-los para o usuário.

Depois que o projeto está configurado, adicionar novas funcionalidades é rápido. Basta incluir umas quatro linhas de código e posso focar na lógica da função nova no views.py para processar a requisição HTTP e devolver os dados em JSON. O mais desafiador é entender como esses arquivos funcionam juntos para formar a aplicação como um todo.

Eu encontrei a melhor maneira de aprender um frameowork com Django, basicamente, é encontrar um projeto funcionando e começar a fazer pequenas alterações para entender o fluxo dos dados. Consultar a documentação conforme os conceitos vão ficando mais claros e pedir para modelos de IA explicarem trechos de código e a função dos arquivos padrão de um framework ajuda muito. Logo fica evidente que essas ferramentas surgiram justamente para poupar tempo no longo prazo e facilitar a manutenção e atualização das aplicações. Como Django e Vue seguem estruturas padronizadas, quando você volta a trabalhar neles depois de um tempo, fica mais fácil entender o que foi feito e retomar o ritmo. E também é mais simples pegar um projeto de outra pessoa e entender as funções principais, já que a estrutura básica é familiar. 

Conceitos fundamentais de Django

Para quem está começando, a primeira coisa importante é saber que os projetos Django são criados rodando um comando que gera os arquivos e pastas base para iniciar o desenvolvimento. Essa estrutura inicial inclui alguns arquivos de configuração que se aplicam ao projeto inteiro. Os dois mais importantes e que você vai visitar com frequência são:

  • settings.py — onde ficam as configurações do projeto (se você perguntar “onde o Django configura o diretório de arquivos estáticos?”, a resposta está aqui)
  • urls.py — onde você registra as rotas de URL da aplicação.

Além desses arquivos no nível do projeto, você cria apps dentro dele, que são pastas onde fica o código de cada funcionalidade específica. Esses apps precisam ser registrados no settings.py. No meu projeto, o app principal se chama documents. Dentro dele, tenho:

  • models.py — onde defino meu objeto Document e seus campos. O Django se encarrega de criar a tabela correspondente no banco IRIS.
  • serializer.py — onde defino como converter o objeto para JSON e vice-versa. Para casos simples, isso é bem direto.
  • views.py — onde ficam as funções que recebem requisições HTTP e devolvem dados (pode ser uma resposta completa ou JSON, se for uma API).

O views.py é onde está a “graça” do Django: ele permite entregar páginas inteiras ou apenas JSON, de modo que você pode usar o Django tanto como front-end quanto apenas como back-end para um front separado.

No começo, seguir essas convenções pode parecer trabalhoso, mas logo você percebe que a aplicação simplesmente funciona, recebe as requisições e devolve os dados certos. Isso torna muito prazeroso continuar adicionando recursos. Depois que você cria um objeto, uma rota web e uma função para lidar com uma requisição, percebe como é fácil adicionar outra, e outra…

Meu projeto de exemplo

Eu fiz um fork do projeto Iris Django Template criado pelo @Guillaume Rongier no GitHub:
https://github.com/grongierisc/iris-django-template

Esse template contém apenas o Django e foi extremamente útil para eu aprender. A principal melhoria que adicionei foi integrar o Vue.js com Tailwind CSS, mostrando que dá para usar um framework moderno de JavaScript junto com Django e rodar uma Single Page Application (SPA) no IRIS. Uma SPA é uma aplicação JavaScript que faz requisições XHR para obter JSON e atualiza a página sem recarregar tudo — algo comum no desenvolvimento web moderno.

Convido você a olhar meu projeto não só como um exemplo de RAG e Vector Stores no IRIS, mas também como um template para usar Django, Vue.js e Tailwind CSS para criar aplicações web modernas, rápidas e flexíveis sobre o IRIS.
https://github.com/mindfulcoder49/iris-django-template

Fico à disposição para responder dúvidas ou compartilhar insights com quem quiser adaptar esse projeto para seu próprio uso.

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer