Artigo
· Ago. 15 11min de leitura

Exemplos de InterSystems IRIS 2021.2+ Python (Embedded, Native APIs e Notebooks)

Iris-python-template

Projeto template com vários códigos Python para ser usado com InterSystems IRIS Community Edition com container.

Apresentando:

  • Notebooks
    • Kernel de Python Embutido
    • ObjectScript Kernel
    • Vanilla Python Kernel
  • Python Embutido
    • Exemplo de código
    • Flask demo
  • IRIS Python Native APIs
    • Exemplo de código

Diagrama

2. Tabela de Conteúdos

3. Instalação

3.1. Docker

Esse repositório é dockerizado então você pode usar clone/git pull no repositório em qualquer diretório local.

git clone https://github.com/grongierisc/iris-python-template.git

Abre o terminal neste mesmo diretório e rode:

docker-compose up -d

então abra http://localhost:8888/tree para Notebooks

Ou, abra a pasta clonada no VSCode, inicie o docker-compose e abra a URL pelo menu VSCode:
VsCodeNotebooks

4. Como começar a programar

4.1. Pré-requisitos

Assegure-se de que você tem git eDocker desktop instalados.

Este repositório está pronto para começar a programar no VSCode com plugin ObjectScript.
Instale VSCode, Docker e o ObjectScript plugin e abra a pasta no VSCode.

4.1.1. Comece a desenvolver em ObjectScript

Abra a classe /src/ObjectScript/Embedded/Python.cls e tente fazer algumas mudanças - será compilado no container docker IRIS que está rodando.

4.1.2. Comece a desenvolver em Python Embutido

A maneira mais fácil é rodar o VSCode no container.

Para anexar a um container Docker, ou selecione Remote-Containers: Attach to Running Container... da paleta de comandos (kbstyle(F1)) ou use o Remote Explorer na barra de atividades, e da visualização Containers , selecione a ação em linha Attach to Container no container que você quer se conectar.

Print de tela do Containers Explorer

Em seguida, configure seu interpretador python para /usr/irissys/bin/irispython

PythonInterpreter

4.1.3. Comece a desenvolver com Notebooks

Abra essa url: http://localhost:8888/tree

Assim você deve ter acesso a três diferentes notebooks com três diferentes kernels.

  • kernel de Python Embutido
  • ObjectScript kernel
  • Vanilla python3 kernel

Notebooks

5. O que tem dentro do repositório

5.1. Dockerfile

Um dockerfile que instala algumas dependências do Python (pip, venv) e sudo no container para conveniências.
Então ele cria o diretório de desenvolvimento e copia nesse repositório git.

Ele inicia o IRIS e importa arquivos Titanics csv, e ativa %Service_CallIn para o Python Shell.
Use o docker-compose.yml relacionado para facilmente definir parâmetros adicionais como o número da porta e onde você pode mapear chaves e pastas hospedeiras.

Esse dockerfile finaliza com a instalação de requerimentos para módulos python.

A última parte é sobre instalação de notebook jupyter e seus kernels.

Use .env/ file para ajustar o dockerfile utilizado em docker-compose.

5.2. .vscode/settings.json

Arquivo de definições para permitir que você programe imediatamente em VSCode com o VSCode ObjectScript plugin

5.3. .vscode/launch.json

Arquivo ded configuração se você quiser debugar com VSCode ObjectScript

Leia tudo sobre os arquivos neste artigo

5.4. .vscode/extensions.json

Arquivo de recomendações para adicionar extensões se quiser rodar o VSCode no container.

Mais informações aqui

Arquitetura

Isso é muito útil para trabalhar com python embutido.

5.5. src folder

Essa pasta é dividida em duas partes, uma para exemplos de ObjectScript, outra para códigos Python.

5.5.1. src/ObjectScript

Pedaço de código diferente que mostra como usar Python em IRIS.

5.5.1.1. src/ObjectScript/Embedded/Python.cls

Todos os comentários estão em francês para você desenvolver suas habilidades em francês também.

/// Embedded python example
Class ObjectScript.Embbeded.Python Extends %SwizzleObject
{

/// HelloWorld with a parameter
ClassMethod HelloWorld(name As %String = "toto") As %Boolean [ Language = python ]
{
    print("Hello",name)
    return True
}

/// Description
Method compare(modèle, chaine) As %Status [ Language = python ]
{
    import re

    # compare la chaîne [chaîne] au modèle [modèle]
    # affichage résultats
    print(f"\nRésultats({chaine},{modèle})")
    match = re.match(modèle, chaine)
    if match:
        print(match.groups())
    else:
        print(f"La chaîne [{chaine}] ne correspond pas au modèle [{modèle}]")
}

/// Description
Method compareObjectScript(modèle, chaine) As %Status
{
    w !,"Résultats("_chaine_","_modèle_")",!
    set matcher=##class(%Regex.Matcher).%New(modèle)                             
    set matcher.Text=chaine
    if matcher.Locate() {
        write matcher.GroupGet(1)
    }
    else {
        w "La chaîne ["_chaine_"] ne correspond pas au modèle ["_modèle_"]"
    }
}

/// Description
Method DemoPyhtonToPython() As %Status [ Language = python ]
{
    # expression régulières en python
    # récupérer les différents champs d'une chaîne
    # le modèle : une suite de chiffres entourée de caractères quelconques
    # on ne veut récupérer que la suite de chiffres
    modèle = r"^.*?(\d+).*?$"

    # on confronte la chaîne au modèle
    self.compare(modèle, "xyz1234abcd")
    self.compare(modèle, "12 34")
    self.compare(modèle, "abcd")
}

Method DemoPyhtonToObjectScript() As %Status [ Language = python ]
{
    # expression régulières en python
    # récupérer les différents champs d'une chaîne
    # le modèle : une suite de chiffres entourée de caractères quelconques
    # on ne veut récupérer que la suite de chiffres
    modèle = r"^.*?(\d+).*?$"

    # on confronte la chaîne au modèle
    self.compareObjectScript(modèle, "xyz1234abcd")
    self.compareObjectScript(modèle, "12 34")
    self.compareObjectScript(modèle, "abcd")
}

/// Description
Method DemoObjectScriptToPython() As %Status
{
    // le modèle - une date au format jj/mm/aa
    set modèle = "^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$"
    do ..compare(modèle, "10/05/97")
    do ..compare(modèle, " 04/04/01 ")
    do ..compare(modèle, "5/1/01")
}

}
  • HelloWorld
    • Simples função para dizer "Hello" (Olá) em Python
    • Ela usa o envólucro ObjectScript com a tag [ Language = python ]
  • compare
    • Uma função python que compara uma string com uma regx, e se correspondem então imprime, se não, imprime que não foi encontrada correspondência
  • compareObjectScript
    • Mesma função que a do Python, mas em ObjectScript
  • DemoPyhtonToPython
    • Mostra como usar uma função Python com código Python envolto em ObjectScript
set demo = ##class(ObjectScript.Embbeded.Python).%New()

zw demo.DemoPyhtonToPython()
  • DemoPyhtonToObjectScript
    • Uma função Python que mostra como chamar uma função ObjectScript
  • DemoObjectScriptToPython
    • Uma função ObjectScript que mostra como chamar uma função Python

5.5.1.2. src/ObjectScript/Gateway/Python.cls

Uma classe ObjectScript que mostra como chamar código externo de Python com a funcionalidade de gateway.

Nesse exemplo o código Python não é executado no mesmo processo do IRIS.

/// Description
Class Gateway.Python
{

/// Demo de um Python gateway para executar código Python fora de um processo iris.
ClassMethod Demo() As %Status
{
    Set sc = $$$OK

    set pyGate = $system.external.getPythonGateway()

    d pyGate.addToPath("/irisdev/app/src/Python/gateway/Address.py")

    set objectBase = ##class(%Net.Remote.Object).%New(pyGate,"Address")

    set street = objectBase.street

    zw street

    Return sc
}

}

5.5.2. src/Python

Pedaço de código diferente de Python que mostra como usar Python embutido no IRIS.

5.5.2.1. src/Python/embedded/demo.cls

Todos os comentários estão em francês para você melhorar suas habilidades de francês também.

import iris

person = iris.cls('Titanic.Table.Passenger')._OpenId(1)

print(person.__dict__)

Primeiro, importe o módulo iris que habilita as capacidades do Python embutido.
Abra uma classe persistente com a função cls do módulo iris.
Note que todas as funções % são substituídas com _.

Para rodar esse exemplo, use o iris Python shell:

/usr/irissys/bin/irispython /opt/irisapp/src/Python/embedded/demo.py

5.5.2.2. src/Python/native/demo.cls

Mostra como usar a api nativa num código python.

import irisnative

# Cria a conexão da base de dados e instância IRIS
connection = irisnative.createConnection("localhost", 1972, "USER", "superuser", "SYS", sharedmemory = False)
myIris = irisnative.createIris(connection)

# classMethod
passenger = myIris.classMethodObject("Titanic.Table.Passenger","%OpenId",1)
print(passenger.get("name"))

# global
myIris.set("hello","myGlobal")
print(myIris.get("myGlobal"))

Para importar o irisnative, você deve instalar as native api wheels no seu ambiente python

pip3 install /usr/irissys/dev/python/intersystems_irispython-3.2.0-py3-none-any.whl

Então você pode rodar esse código python

/usr/bin/python3 /opt/irisapp/src/Python/native/demo.py

Note que nesse caso uma conexão é feita para a base de dados iris, o que significa que esse código é executado numa thread diferente que a de IRIS.

5.5.2.3. src/Python/flask

Uma demo completa da combinação entre python embutido e a micro framework flask.
Você pode testar esse endpoint:

GET http://localhost:4040/api/passengers?currPage=1&pageSize=1
5.5.2.3.1. Como funciona

Para usar o Python embutido, usamos irispython como interpretador python e fazemos:

import iris

Logo no início do arquivo.

Então, poderemos rodar métodos como:

flaskExample

Como você pode ver, para usar um GET em um passageiro com ID, executamos a query e usamos seu conjunto de resultados result set.

Também podemos diretamente usar os objetos IRIS:

flaskObjectExample

Aqui, usamos uma consulta SQL para pegar todos os IDs na tabela, então retornar cada passageiro da tabela com o método %OpenId() da classe Titanic.Table.Passenger (note que já que % é um caractere ilegal em Python, usamos _ no lugar).

Graças ao Flask, implementamos todas as nossas rotas e métodos dessa maneira.

5.5.2.3.2. Lançando o servidor flask

Para lançar o servidor, usamos gunicorn com irispython.

No arquivo docker-compose, adicionamos a linha a seguir:

iris:
  command: -a "sh /opt/irisapp/server_start.sh"

Isso deve lançar, depois do container ser iniciado (graças à bandeira -a), o script a seguir:

#!/bin/bash

cd ${SRC_PATH}/src/Python/flask

${PYTHON_PATH} -m gunicorn --bind "0.0.0.0:8080" wsgi:app &

exit 1

Com as variáveis de ambiente definidas no Dockerfile como se segue:

ENV PYTHON_PATH=/usr/irissys/bin/irispython
ENV SRC_PATH=/opt/irisapp/

5.5.3. src/Notebooks

Três notebooks com três diferentes kernels:

  • One Python3 kernel to run native APIs
  • One Embedded Python kernel
  • One ObjectScript kernel

Notebooks podem ser acessados aqui http://localhost:8888/tree

Notebooks

5.5.3.1. src/Notebooks/HelloWorldEmbedded.ipynb

Esse notebook usa o kernel de python embutido IRIS.

Ele mostra um exemplo de como abrir e salvar classes persistentes e como rodar consultas SQL.

5.5.3.2. src/Notebooks/IrisNative.ipynb

Esse notebook usa o kernel python tradicional.

Ele mostra um exemplo de como rodar apis nativas iris.

5.5.3.3. src/Notebooks/ObjectScript.ipynb

Esse notebook usa kernel ObjectScript.

Ele mostra como rodar código de ObjectScript e como usar python embutido no ObjectScript.

Discussão (0)1
Entre ou crie uma conta para continuar