Rodando aplicações Flask no IRIS

Descrição
Este é um modelo para um aplicativo Flask que pode ser implantado no IRIS como um aplicativo Web nativo.
Instalação
- Clone o repositório
- Crie um ambiente virtual
- Instale os requisitos
- Rode o arquivo docker-compose
git clone
cd iris-flask-template
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
docker-compose up
Uso
A URL de base http://localhost:53795/flask/.
Endpoints
/iris- Retorna um objeto JSON com as 10 principais classes presentes no namespace IRISAPP./interop- Um endpoint de ping para testar o framework de interoperabilidade do IRIS/posts- Um simples enpoint CRUD para um objeto de Post/comments- Um enpoint simples de CRUD para o objeto de comentário
Como desenvolver deste template
Veja o artigo de introdução ao WSGI wsgi-introduction.
TL;DR: Você pode ativar ou desativar o sinalizador DEBUG no portal de segurança para que as alterações sejam refletidas no aplicativo à medida que você desenvolve.
Apresentação do código
app.py
Este é o arquivo principal do aplicativo. Ele contém o aplicativo Flask e os endpoints.
from flask import Flask, jsonify, request
from models import Comment, Post, init_db
from grongier.pex import Director
import iris
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'iris+emb://IRISAPP'
db = init_db(app)
from flask import Flask, jsonify, request: Importa a livraria Flaskfrom models import Comment, Post, init_db: Importa os modelos e a função de inicialização de base de dadosfrom grongier.pex import Director: Importa a classe Director para vincular o app flask à framework de interoperabilidade do IRISimport iris: Importa a livraria IRISapp = Flask(__name__): Cria uma aplicação Flaskapp.config['SQLALCHEMY_DATABASE_URI'] = 'iris+emb://IRISAPP': Define o URI da base de dados ao namespace IRISAPP- O esquema de URI
iris+embé usado para conectar ao IRIS como uma conexão embutida (sem necessidade de uma instância IRIS separada
- O esquema de URI
db = init_db(app): Inicialize a base de dados com aplicação Flask.
models.py
O arquivo contem os modelos SQLAlchemy para a aplicação.
from dataclasses import dataclass
from typing import List
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
@dataclass
class Comment(db.Model):
id:int = db.Column(db.Integer, primary_key=True)
content:str = db.Column(db.Text)
post_id:int = db.Column(db.Integer, db.ForeignKey('post.id'))
@dataclass
class Post(db.Model):
__allow_unmapped__ = True
id:int = db.Column(db.Integer, primary_key=True)
title:str = db.Column(db.String(100))
content:str = db.Column(db.Text)
comments:List[Comment] = db.relationship('Comment', backref='post')
Não há muito o que dizer aqui, os modelos são definidos como classes de dados e são subclasses da classe db.Model
O uso do atributo __allow_unmapped_ é necessário para permitir a criação do objeto Post sem o atributo comments
dataclasses são usadas para ajudar com a serialização de objetos ao JSON
A função init_db inicializa a base de dados com a aplicação Flask.
def init_db(app):
db.init_app(app)
with app.app_context():
db.drop_all()
db.create_all()
# Create fake data
post1 = Post(title='Post The First', content='Content for the first post')
...
db.session.add(post1)
...
db.session.commit()
return db
db.init_app(app): Inicializa a base de dados com a aplicação Flaskwith app.app_context(): Cria um contexto para a aplicaçãodb.drop_all(): Descarta todas as tabelas na base de dadosdb.create_all(): Cria todas as tabelas na base de dados- Cria dados falsos para a aplicação
- retorna o objeto de base de dados
/iris endpoint
######################
# IRIS Query exemplo#
######################
@app.route('/iris', methods=['GET'])
def iris_query():
query = "SELECT top 10 * FROM %Dictionary.ClassDefinition"
rs = iris.sql.exec(query)
# Converte o resultado em uma lista de dicionários
result = []
for row in rs:
result.append(row)
return jsonify(result)
Esse endpoint executa uma query na base de dados IRIS e retorna as top 10 classes presentes no namespace IRISAPP
/interop endpoint
########################
# IRIS interop exemplo #
########################
bs = Director.create_python_business_service('BS')
@app.route('/interop', methods=['GET', 'POST', 'PUT', 'DELETE'])
def interop():
rsp = bs.on_process_input(request)
return jsonify(rsp)
Este endpoint é usado para testar a estrutura de interoperabilidade do IRIS. Ele cria um objeto de Serviço de Negócio e o vincula ao aplicativo Flask.
Observação: O objeto bs deve estar fora do escopo da solicitação para mantê-lo ativo.
bs = Director.create_python_business_service('BS'): Cria um objeto Business Service chamado 'BS'rsp = bs.on_process_input(request): Chama o métodoon_process_inputdo objeto Business Service com o objeto de requisição como um argumento
/posts endpoint
############################
# operações CRUD para posts #
############################
@app.route('/posts', methods=['GET'])
def get_posts():
posts = Post.query.all()
return jsonify(posts)
@app.route('/posts', methods=['POST'])
def create_post():
data = request.get_json()
post = Post(title=data['title'], content=data['content'])
db.session.add(post)
db.session.commit()
return jsonify(post)
@app.route('/posts/<int:id>', methods=['GET'])
def get_post(id):
...
Este endpoint é usado para realizar operações CRUD no objeto Post
Graças ao módulo dataclasses, o objeto Post pode ser facilmente serializado para JSON.
Aqui, usamos o método query do sqlalchemy para obter todos os posts e os métodos add e commit para criar um novo post
/comments endpoint
############################
# operações CRUD para comentários #
############################
@app.route('/comments', methods=['GET'])
def get_comments():
comments = Comment.query.all()
return jsonify(comments)
@app.route('/comments', methods=['POST'])
def create_comment():
data = request.get_json()
comment = Comment(content=data['content'], post_id=data['post_id'])
db.session.add(comment)
db.session.commit()
return jsonify(comment)
@app.route('/comments/<int:id>', methods=['GET'])
def get_comment(id):
...
Este endpoint é usado para realizar operações CRUD no objeto Comment.
O objeto Comment está vinculado ao objeto Post por uma chave estrangeira.
Solução de Problemas
Como executar o aplicativo Flask em modo autônomo
Você sempre pode executar um aplicativo Flask autônomo com o seguinte comando:
python3 /irisdev/app/community/app.py
Nota: você deve estar dentro do container para rodar este comando
docker exec -it iris-flask-template-iris-1 bash
Reinicie a aplicação no IRIS
Esteja no modo DEBUG, faça várias chamadas para o aplicativo e as alterações serão refletidas no aplicativo.
Como acessar o Portal de Gerenciamento do IRIS
Você pode acessar o Portal de Gerenciamento do IRIS acessandohttp://localhost:53795/csp/sys/UtilHome.csp.
Rode este template localmente
Para isso, você precisa ter o IRIS instalado em sua máquina.
Em seguida, você precisa criar um namespace chamado IRISAPP.
Instale os requisitos.
Instale IoP :
#init iop
iop --init
# carregue a produção
iop -m /irisdev/app/community/interop/settings.py
# iniicie a produção
iop --start Python.Production
Configure a aplicação no portal de Segurança