Ao começar a desenvolver com o IRIS, temos um kit de distribuição ou, no caso do Docker, extraímos a imagem do Docker e, geralmente, precisamos inicializá-lo e configurar o ambiente de desenvolvimento. Talvez seja necessário criar bancos de dados, namespaces, ativar/desativar serviços e criar recursos. Com frequência, precisamos importar código e dados na instância do IRIS e executar código personalizado para inicializar a solução.
Há vários modelos no Open Exchange onde sugerimos como inicializar o REST, Interoperability, Analytics, Fullstack e vários outros modelos com ObjectScript. E se só quisermos usar o Python para configurar o ambiente de desenvolvimento para o projeto do Embedded Python com o IRIS?
Então, a versão recente do modelo do Embedded Python é o boilerplate de python puro que pode ser um ponto de partida para os desenvolvedores que criam projetos em python, sem precisar usar e aprender o ObjectScript. Este artigo demonstra como esse modelo pode ser usado para inicializar o IRIS. Vamos lá!
Ok!
Criando o banco de dados e namespace
Geralmente, precisamos criar o banco de dados e namespace. Isso pode ser feito com a funcionalidade cpf merge do IRIS, e este é o arquivo merge que faz isso:
[Actions] CreateResource:Name=%DB_IRISAPP_DATA,Description="IRISAPP_DATA database" CreateDatabase:Name=IRISAPP_DATA,Directory=/usr/irissys/mgr/IRISAPP_DATA CreateResource:Name=%DB_IRISAPP_CODE,Description="IRISAPP_CODE database" CreateDatabase:Name=IRISAPP_CODE,Directory=/usr/irissys/mgr/IRISAPP_CODE CreateNamespace:Name=IRISAPP,Globals=IRISAPP_DATA,Routines=IRISAPP_CODE,Interop=1 ModifyService:Name=%Service_CallIn,Enabled=1,AutheEnabled=48 ModifyUser:Name=SuperUser,PasswordHash=a31d24aecc0bfe560a7e45bd913ad27c667dc25a75cbfd358c451bb595b6bd52bd25c82cafaa23ca1dd30b3b4947d12d3bb0ffb2a717df29912b743a281f97c1,0a4c463a2fa1e7542b61aa48800091ab688eb0a14bebf536638f411f5454c9343b9aa6402b4694f0a89b624407a5f43f0a38fc35216bb18aab7dc41ef9f056b1,10000,SHA512
O cpf Merge contém Ações que, nesse caso, criam os bancos de dados IRISAPP_DATA e IRISAPP_CODE para dados e código, respectivamente, o namespace IRISAPP relacionado para acessá-los e os recursos %IRISAPP_DATA e %IRISAPP_CODE" para gerenciar o acesso.
Esse cpf Merge também permite que o serviço Callin faça o Embedded Python funcionar através da ação ModifyService:
ModifyService:Name=%Service_CallIn,Enabled=1,AutheEnabled=48
A última ação é um exemplo de como você pode definir a senha do usuário com segurança, usando a ação ModifyUser:
ModifyUser:Name=SuperUser,PasswordHash=a31d24aecc0bfe560a7e45bd913ad27c667dc25a75cbfd358c451bb595b6bd52bd25c82cafaa23ca1dd30b3b4947d12d3bb0ffb2a717df29912b743a281f97c1,0a4c463a2fa1e7542b61aa48800091ab688eb0a14bebf536638f411f5454c9343b9aa6402b4694f0a89b624407a5f43f0a38fc35216bb18aab7dc41ef9f056b1,10000,SHA512
O hash da senha pode ser gerado por outra imagem do docker da InterSystems, por exemplo, com a seguinte linha chamada em um terminal (saiba mais sobre o passwordhash):
docker run --rm -it containers.intersystems.com/intersystems/passwordhash:1.1 -algorithm SHA512 -workfactor 10000
O comando merge pode ser chamado no Dockerfile desta maneira:
iris merge IRIS merge.cpf && \
Outros tipos de ações merge e diferentes configurações disponíveis para IRIS podem ser encontrados na documentação.
Executando um código de inicialização arbitrária
Outro caso de uso popular é executar um código personalizado arbitrário para carregar dados, inicializar variáveis e carregar código do repositório, por exemplo, em forma de pacote IPM. Geralmente, nos modelos IRIS, há um arquivo iris.script especial que contém esse código na forma de ObjectScript. Mantive o arquivo iris.script no repositório só para fazer a demonstração de como será usado com o ObjectScript.
Neste modelo do python, você pode encontrar o exemplo desse código de inicialização em um arquivo iris_script.py. Vamos ver o que ele contém:
import glob
import os
import iris
import pandas as pd
from sqlalchemy import create_engine
from iris import ipm
# switch namespace to the %SYS namespace
iris.system.Process.SetNamespace("%SYS")
# set credentials to not expire
iris.cls('Security.Users').UnExpireUserPasswords("*")
# switch namespace to IRISAPP built by merge.cpf
iris.system.Process.SetNamespace("IRISAPP")
# load ipm package listed in module.xml
#iris.cls('%ZPM.PackageManager').Shell("load /home/irisowner/dev -v")
assert ipm('load /home/irisowner/dev -v')
# load demo data
engine = create_engine('iris+emb:///')
# list all csv files in the demo data folder
for files in glob.glob('/home/irisowner/dev/data/*.csv'):
# get the file name without the extension
table_name = os.path.splitext(os.path.basename(files))[0]
# load the csv file into a pandas dataframe
df = pd.read_csv(files)
# write the dataframe to IRIS
df.to_sql(table_name, engine, if_exists='replace', index=False, schema='dc_demo')
PythonPython
O código é bastante autoexplicativo e demonstra como mudar namespaces, carregar código de respositório na forma de módulo IPM e importar arquivos csv contidos na pasta /data do repositório usando a biblioteca sqlalchemy.
O que o modelo faz?
Basicamente, esse modelo fornece exemplos de como o Embedded Python pode ser usado com o IRIS.
1. Chamar o Python a partir do ObjectScript
Para a demonstração, temos várias classes do ObjectScript no repositório.
Para testar a abordagem, abra o terminal IRIS e execute:
IRISAPP>d ##class(dc.python.test).Hello() World
Esse teste demonstra como você pode usar as funções no código sample.py no IRIS usando o Embedded Python.
2. Fazer referência ao IRIS no Python
Para testar isso, você pode executar irisapp.py, que realiza diferentes operações com o banco de dados IRIS. Para executar todo o teste, inicie a sessão do terminal no docker:
# attach to the running IRIS container docker-compose exec iris bash # run the script $ irispython ./python/irisapp.py
3. Criar uma API REST do Flask em Python que funcione com o IRIS
Também há um exemplo de API REST em Python criada com o Flask que você pode usar nos seus aplicativos encontrado em /python/flask/app.py.
Para iniciar a API REST do Flask, execute:
$ docker-compose exec iris bash # irispython /python/flask/app.py
Em seguida, você pode testar o servidor em http://localhost:55030/.
E aqui estão dois exemplos de como adicionar um novo registro no IRIS e ler um registro:
POST http://localhost:55030/persistentclass Content-Type: application/json Accept: application/json { "test": "toto" } Result: json { "id": 1, "test": "toto" } GET http://localhost:55030/persistentclass/1 Accept: application/json Result: json { "id": 1, "test": "toto" }
4. Implantação
A implantação da solução nos sistemas IRIS pode ser realizada por IPM. Para esse fim, temos um module.xml de IPM que entregará os arquivos ObjectScript e Python ao sistema IRIS de destino a partir de um registro de IPM em que você publicará o módulo.
Obrigado, @Guillaume Rongier e @Dmitry Maslennikov, que ajudaram muito a criar o modelo e possibilitar a abordagem "Python puro".
Há abordagens mais "radicais" na organização desses modelos — aqui está a amostra "no dockerfile" e "no objedctscript" de @Dmitry Maslennikov.
Aqui está o modelo "embedded python" de @Guillaume Rongier.