Artigo
· Out. 20 6min de leitura

Rodando aplicações Flask no IRIS

Flask_logo

Descrição

Este é um modelo para um aplicativo Flask que pode ser implantado no IRIS como um aplicativo Web nativo.

Instalação

  1. Clone o repositório
  2. Crie um ambiente virtual
  3. Instale os requisitos
  4. 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 Flask
  • from models import Comment, Post, init_db: Importa os modelos e a função de inicialização de base de dados
  • from grongier.pex import Director: Importa a classe Director para vincular o app flask à framework de interoperabilidade do IRIS
  • import iris: Importa a livraria IRIS
  • app = Flask(__name__): Cria uma aplicação Flask
  • app.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
  • 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 Flask
  • with app.app_context(): Cria um contexto para a aplicação
  • db.drop_all(): Descarta todas as tabelas na base de dados
  • db.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étodo on_process_input do 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 modoDEBUG, 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

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