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
2. Tabela de Conteúdos
- 1. iris-python-template
- 2. Tabela de Conteúdos
- 3. Instalação
- 4. Como começar a programar
- 5. O que tem dentro do repositório
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:
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.
Em seguida, configure seu interpretador python para /usr/irissys/bin/irispython
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
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.
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:
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:
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
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.