0 Seguidores · 13 Postagens

Caché Server Pages (CSP) é tanto uma arquitetura como um conjunto de ferramentas usado para construir aplicações web interativas com a Plataforma de Dados InterSystems.

Artigo Heloisa Paiva · Out. 23, 2025 1m read

Olá a todos,

Esta é uma dica rápida sobre como usar URLs em serviços REST API sem distinção entre maiúsculas e minúsculas.

Se você tem uma classe que estende de %CSP.REST e Ens.BusinessService para criar um serviço REST API, e você definiu seu WebApplication em minúsculas:

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
    <Route Url="/user" Method="POST" Call="User"/>
    <Route Url="/login" Method="POST" Call="Login"/>
</Routes>
}

Ele só aceitará URLs em minúsculas, por exemplo: http://myserver/myproduction/user

0
0 19
Artigo Heloisa Paiva · Jul. 24, 2025 5m read

img

Claro, aqui está a tradução:

Módulos, que tópico! Não temos essa noção no ObjectScript, mas é um conceito fundamental em Python. Vamos descobri-lo juntos.

O que é um Módulo?

Eu vejo módulos como uma camada intermediária entre classes e pacotes. Vamos ver por exemplo.

Um exemplo ruim:

# MyClass.py
class MyClass:
    def my_method(self):
        print("Hello from MyClass!")

Quando você tentar usar essa classe em outro script, você faz:

# class_usage.py
from MyClass import MyClass # estranho, né?

my_instance = MyClass()
my_instance.my_method()

Por que este é um exemplo ruim?

Primeiro porque os nomes de arquivos devem estar em snake_case de acordo com a PEP 8, então deveria ser my_class.py. Segundo, porque você está importando uma classe de um arquivo que tem o mesmo nome da classe. Esta não é uma boa prática em Python.

Sei que isso pode ser confuso, especialmente se você vem do ObjectScript, onde as classes são definidas em arquivos com o mesmo nome da classe.

Noções Avançadas

Um Módulo é um Arquivo Python

Então, acabamos de ver que módulos podem ser um arquivo Python, mas sem a extensão .py.

Mas espere, isso significa que um script Python também é um módulo? Sim, é!

É por isso que você deve ter cuidado ao importar um script, pois ele executará o código contido nele. Consulte o artigo Introdução ao Python para mais detalhes.

Um Módulo é uma Pasta com um Arquivo __init__.py

Uau, uma pasta pode ser um módulo? Sim, pode!

Uma pasta pode ser um módulo se contiver um arquivo __init__.py file. Este arquivo pode estar vazio ou conter código de inicialização para o módulo.

Vamos ver um exemplo:

src/python/article/
└── my_folder_module/
    ├── __init__.py
    ├── my_sub_module.py
    └── another_sub_module.py
# my_folder_module/my_sub_module.py
class MySubModule:
    def my_method(self):
        print("Hello from MySubModule!")
# my_folder_module/another_sub_module.py
class AnotherSubModule:
    def another_method(self):
        print("Hello from AnotherSubModule!")
# my_folder_module/__init__.py
# Este arquivo pode estar vazio ou conter código de inicialização para o módulo.

Neste caso, my_folder_module e você pode importá-lo assim:

from my_folder_module import my_sub_module, another_sub_module

Ou se você definir um arquivo __init__.py com o seguinte conteúdo:

# my_folder_module/__init__.py
from .my_sub_module import MySubModule
from .another_sub_module import AnotherSubModule

Você pode importá-lo assim:

from my_folder_module import MySubModule, AnotherSubModule

Você percebe a sutileza? Você pode importar as classes diretamente do módulo sem especificar o submódulo, porque o arquivo __init__.py é executado quando você importa o módulo, e ele pode definir o que está disponível no namespace do módulo.

sys.path

Quando você importa um módulo, o Python o procura nos diretórios listados emsys.path. Esta é uma lista de strings que especifica o caminho de busca por módulos.

Você pode ver o sys.path atual executando o seguinte código:

import sys
print(sys.path)

Por padrão, ele inclui o diretório atual e outros vários diretórios, dependendo da sua instalação Python.

Você também pode adicionar diretórios ao sys.path em tempo de execução, o que é útil quando você deseja importar módulos de um local específico. Por exemplo:

import sys
sys.path.append('/path/to/your/module')
from your_module import YourClass

É por isso que no artigo anterior, adicionamos o caminho para o módulo antes de importá-lo:

Set sys = ##class(%SYS.Python).Import("sys")
do sys.path.append("/irisdev/app/src/python/article")
set my_module = ##class(%SYS.Python).Import("my_module")

sys.path e os outros diretórios

Quais são os outros diretórios em sys.path? Eles geralmente são:

  • O diretório contendo o script de entrada (ou o diretório atual se nenhum script for especificado).
  • Os diretórios da biblioteca padrão, que contêm os módulos built-in que vêm com o Python.
  • site-packages diretórios onde pacotes de terceiros são instalados.d.

site-packages

Como site-packages funciona? Quando você instala um pacote usando pip, ele é instalado no diretório site-packages que é automaticamente incluído em sys.path. Isso permite que você importe o pacote sem ter que especificar sua localização.This allows you to import the package without having to specify its location.

🤨🔍 Mas como e onde o diretório site-packages é definido e por quem?

O diretório site-packages é criado durante a instalação do Python e geralmente está localizado no diretório lib da sua instalação Python. O local exato depende do seu sistema operacional e de como o Python foi instalado.

Por exemplo, em uma instalação Linux típica, o diretório site-packages pode estar localizado em:

/usr/local/lib/python3.x/site-packages

No Windows, pode estar localizado em:

C:\Python3x\Lib\site-packages

Quando você instala um pacote usando pip, ele é instalado no diretório site-packages que é automaticamente incluído em sys.path. Isso permite que você importe o pacote sem ter que especificar sua localização.

import site
print(site.getsitepackages())

🤨🔍 Quando e onde o interpretador Python lê o arquivo site.py?

O arquivo site.py (que está localizado no diretório da biblioteca padrão) é executado automaticamente quando o interpretador Python é iniciado. Ele é responsável por configurar o diretório site-packages e adicioná-lo ao sys.path. Este arquivo está localizado no diretório da biblioteca padrão da sua instalação Python.

sys.path no IRIS

No IRIS, também temos um arquivo site.pyque está localizado em <installation_directory>/lib/python/iris_site.py. Este arquivo é executado quando você inicia ou importa um script/módulo no IRIS, e ele configura o sys.path para você.

e forma geral, o arquivo iris_site.pyfaz o seguinte:

  • Mantém o diretório site-packages padrão
  • Adiciona o diretório<installation_directory>/lib/python/ ao sys.path
    • É aqui que os módulos Python do IRIS estão localizados, por favor, não coloque seus módulos aqui.
  • Adiciona o diretório <installation_directory>/mgr/python/ ao sys.path -É aqui que você pode colocar seus módulos Python personalizados.
  • Adiciona a string de configuração PythonPath ao sys.path

Conclusão

Um módulo pode ser:

  • Um arquivo Python (com ou sem a extensão .py)
  • Uma pasta com um arquivo __init__.py.
  • Um script Python (que também é um módulo).
  • Se você não conseguir importar um módulo, verifique se ele está na lista sys.path.
0
0 26
Artigo Julio Esquerdo · Jun. 7, 2025 18m read

Olá,

Neste artigo vamos ver o uso do python como linguagem de programação no InterSystems Iris. Para tal vamos usar como referência a versão Community 2025.1 que está disponível para ser baixada em https://download.intersystems.com mediante o login no ambiente. Para maiores informações sobre o download e instalação do Iris veja o link da comunidade https://community.intersystems.com/post/how-download-and-install-intersystems-iris

0
0 41
Artigo Heloisa Paiva · Fev. 13, 2025 4m read

No WRC, frequentemente vemos clientes entrarem em contato conosco porque seus Web Gateways são incapazes de servir páginas web. Este artigo explicará um motivo frequente para a ocorrência desses erros e descreverá algumas ferramentas que podem ser usadas para depurar o problema. Esta explicação está focada no Web Gateway servindo instâncias do InterSystems IRIS, mas a mesma explicação deve se aplicar ao CSP Gateway servindo instâncias do Caché também.

O Problema:

0
1 35
Artigo Heloisa Paiva · Out. 24, 2024 7m read

fastapi_logo

Descrição

Este é um modelo para um aplicativo FastAPI 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. Execute o arquivo docker-compose
git clone
cd iris-fastapi-template
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
docker-compose up

Uso

A URL base é http://localhost:53795/fastapi/.

Endpoints

  • /iris - Retorna um objeto JSON com as 10 principais classes presentes no namespace IRISAPP.
  • /interop - Um endpoint de ping para testar a estrutura de interoperabilidade do IRIS.
  • /posts - Um endpoint CRUD simples para um objeto Post.
  • /comments - Um endpoint CRUD simples para um objeto Comentário.

Como desenvolver a partir 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 FastAPI. Ele contém o aplicativo FastAPI e as rotas.

from fastapi import FastAPI, Request

import iris

from grongier.pex import Director

# import models
from models import Post, Comment, init_db
from sqlmodel import Session,select

app = FastAPI()

# create a database engine
url = "iris+emb://IRISAPP"
engine = init_db(url)
  • from fastapi import FastAPI, Request - Importe a classe FastAPI e a classe Request
  • import iris - Importe o módulo IRIS.
  • from grongier.pex import Director: Importe a classe Director para vincular o aplicativo Flask ao framework de interoperabilidade do IRIS.
  • from models import Post, Comment, init_db - Importe os modelos e a função init_db.
  • from sqlmodel import Session,select - Importe a classe Session e a função select do módulo sqlmodel.
  • app = FastAPI() - Crie um aplicativo FastAPI.
  • url = "iris+emb://IRISAPP" -Defina o URL do namespace IRIS.
  • engine = init_db(url) - Crie um mecanismo de banco de dados para o ORM sqlmodel..

models.py

Este arquivo contém os modelos para o aplicativo.

from sqlmodel import Field, SQLModel, Relationship, create_engine

class Comment(SQLModel, table=True):
    id: int = Field(default=None, primary_key=True)
    post_id: int = Field(foreign_key="post.id")
    content: str
    post: "Post" = Relationship(back_populates="comments")

class Post(SQLModel, table=True):
    id: int = Field(default=None, primary_key=True)
    title: str
    content: str
    comments: list["Comment"] = Relationship(back_populates="post")

Não há muito a dizer aqui, apenas a definição dos modelos com chaves estrangeiras e relacionamentos.

A função init_db é usada para criar o mecanismo de banco de dados.

def init_db(url):

    engine = create_engine(url)

    # create the tables
    SQLModel.metadata.drop_all(engine)
    SQLModel.metadata.create_all(engine)

    # initialize database with fake data
    from sqlmodel import Session

    with Session(engine) as session:
        # Create fake data
        post1 = Post(title='Post The First', content='Content for the first post')
        ...
        session.add(post1)
        ...
        session.commit()

    return engine
  • engine = create_engine(url) - Crie um mecanismo de banco de dados.
  • SQLModel.metadata.drop_all(engine) - Exclua todas as tabelas.
  • SQLModel.metadata.create_all(engine) - Crie todas as tabelas.
  • with Session(engine) as session: - Crie uma sessão para interagir com o banco de dados.
  • post1 = Post(title='Post The First', content='Content for the first post')- Crie um objeto Post..
  • session.add(post1) -Adicione o objeto Post à sessão.
  • session.commit() -Confirme as alterações no banco de dados.
  • return engine - Retorne o mecanismo de banco de dados.

/iris endpoint

######################
# IRIS Query exemplo #
######################

@app.get("/iris")
def iris_query():
    query = "SELECT top 10 * FROM %Dictionary.ClassDefinition"
    rs = iris.sql.exec(query)
    # Convert the result to a list of dictionaries
    result = []
    for row in rs:
        result.append(row)
    return result
  • @app.get("/iris") - Defina uma rota GET para o endpoint /iris .
  • query = "SELECT top 10 * FROM %Dictionary.ClassDefinition" -Defina a consulta para obter as 10 principais classes no namespace IRIS.
  • rs = iris.sql.exec(query) - Execute a consulta..
  • result = [] - Crie uma lista vazia para armazenar os resultados.
  • for row in rs: - Itere sobre o conjunto de resultados.
  • result.append(row) - Adicione a linha à lista de resultados.
  • return result - Retorne a lista de resultados.

/interop endpoint

########################
# IRIS interop exemplo #
########################
bs = Director.create_python_business_service('BS')

@app.get("/interop")
@app.post("/interop")
@app.put("/interop")
@app.delete("/interop")
def interop(request: Request):
    
    rsp = bs.on_process_input(request)

    return rsp

  • bs = Director.create_python_business_service('BS') - Crie um business service Python. -Deve ser criado fora da definição da rota para evitar múltiplas instâncias do serviço de negócios.
  • @app.get("/interop") - Define uma rota GET para o endpoint /interop.
  • @app.post("/interop") - Define uma rota POST para o endpoin /interop .
  • ...
  • def interop(request: Request): - Define o manipulador da rota.
  • rsp = bs.on_process_input(request) - Chame o método on_process_input do business service.
  • return rsp - Retorne a resposta.

/posts endpoint

############################
# operações CRUD de posts    #
############################

@app.get("/posts")
def get_posts():
    with Session(engine) as session:
        posts = session.exec(select(Post)).all()
        return posts
    
@app.get("/posts/{post_id}")
def get_post(post_id: int):
    with Session(engine) as session:
        post = session.get(Post, post_id)
        return post
    
@app.post("/posts")
def create_post(post: Post):
    with Session(engine) as session:
        session.add(post)
        session.commit()
        return post

Este endpoint é usado para realizar operações CRUD no objeto Post.

Não há muito a dizer aqui, apenas a definição das rotas para obter todos os posts, obter um post por ID e criar um post.

Tudo é feito usando o ORM sqlmodel.

/comments endpoint

############################
# operações  CRUD de comments #
############################


@app.get("/comments")
def get_comments():
    with Session(engine) as session:
        comments = session.exec(select(Comment)).all()
        return comments
    
@app.get("/comments/{comment_id}")
def get_comment(comment_id: int):
    with Session(engine) as session:
        comment = session.get(Comment, comment_id)
        return comment
    
@app.post("/comments")
def create_comment(comment: Comment):
    with Session(engine) as session:
        session.add(comment)
        session.commit()
        return comment

Este endpoint é usado para realizar operações CRUD no objeto Comment.

Não há muito a dizer aqui, apenas a definição das rotas para obter todos os comentários, obter um comentário por ID e criar um comentário.

Tudo é feito usando o ORM sqlmodel.

Solução de Problemas

Como executar o aplicativo FastAPI em modo autônomo

Você sempre pode executar um aplicativo Flask autônomo com o seguinte comando:

python3 /irisdev/app/community/app.py

Observação: você deve estar dentro do contêiner para executar este comando.

docker exec -it iris-fastapi-template-iris-1 bash

Reinicie o aplicativo no IRIS

Fique 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 acessando http://localhost:53795/csp/sys/UtilHome.csp.

Execute 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

# load production
iop -m /irisdev/app/community/interop/settings.py

# start production
iop --start Python.Production

Configure o aplicativo no portal de segurança.

0
0 43
Artigo Heloisa Paiva · Out. 22, 2024 9m read

django_logo

Descrição

Este é um modelo para um aplicativo Django 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-django-template
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
docker-compose up

Uso

A URL base é http://localhost:53795/django/.

Endpoints

  • /iris - Retorna um objeto JSON com as 10 principais classes presentes no namespace IRISAPP.
  • /interop - Um endpoint de ping para testar a estrutura de interoperabilidade do IRIS.
  • /api/posts -Um endpoint CRUD simples para um objeto Post.
  • /api/comments - Um endpoint CRUD simples para um objeto Comment.

Como desenvolver deste modelo

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

A aplicação Django é estruturada como se segue:

  • app - Pasta do projeto Django
    • app - Pasta da aplicação Django para configuração
      • settings.py - Arquivo de definições Django
      • urls.py - Arquivo de configuração de URL Django para conectar as visualizações às URLs
      • wsgi.py - Arquivo do Django WSGI
      • asgi.py - Arquivo do Django AGI
    • community - Pasta da aplicação Django para o aplicativo da comunidade, com CRUD nos objetos de Post e Comment
      • models.py - Arquivo de modelos do Djando para os objetos Post e Comment
      • views.py - Arquivo de visualizações Django para cessar os objetos Post e Comment
      • serializers.py - Arquivo Django de serializadores para os objetos Post e Comentário. * admin.py - Arquivo Django de administração para adicionar CRUD à interface administrativa.
      • migrations - Pasta Django de migrações para construir o banco de dados.
      • fixtures - Pasta Django de fixtures com dados de demonstração
    • sqloniris - Pasta do aplicativo Django para o aplicativo SQL no IRIS.
      • views.py - Arquivo Django de views para consultar o namespace IRISAPP.
      • apps.py - Arquivo de configuração do aplicativo Django.
    • interop - Pasta do aplicativo Django para o aplicativo de interoperabilidade.
      • views.py - Arquivo Django de views para testar a estrutura de interoperabilidade.
      • apps.py - Arquivo de configuração do aplicativo Django.
    • manage.py - Arquivo de gerenciamento Django.

app/settings.py

Este arquivo contém as configurações Django para o aplicativo.

...

# Definição de aplicação

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'community',
    'sqloniris',
    'interop',
    'rest_framework'
]

...

REST_FRAMEWORK = {
    # Use as permissões padrão do Django `django.contrib.auth` ,
    # ou permita acesso de apenas leitura para usuários não autenticados
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ],
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 20
}

...

DATABASES = {
    "default": {
        "ENGINE": "django_iris",
        "EMBEDDED": True,
        "NAMESPACE": "IRISAPP",
        "USER":"SuperUser",
        "PASSWORD":"SYS",
    }
}

Algumas definições importantes para notar:

  • INSTALLED_APPS - Contém a lista de aplicativos instalados no projeto Django.
  • community - O aplicativo Django para as operações CRUD nos objetos Post e Comentário.
  • sqloniris - TO aplicativo Django para as operações SQL no IRIS.
  • interop - O aplicativo Django para as operações de interoperabilidade.
  • rest_framework - O framework Django REST para a API REST.
  • REST_FRAMEWORK - Contém as configurações para o framework Django REST.
    • DEFAULT_PERMISSION_CLASSES - Somente usuários autenticados podem realizar operações CRUD.
    • DEFAULT_PAGINATION_CLASS - A classe de paginação para a API REST.
  • DATABASES - Contém as configurações para a conexão com o banco de dados IRIS.
    • Aqui estamos usando o mecanismo django_iris para conectar ao banco de dados IRIS.

app/urls.py

Este arquivo contém a configuração de URL para o aplicativo Django.

from django.contrib import admin
from django.urls import path,include
from rest_framework import routers
from community.views import PostViewSet, CommentViewSet
from sqloniris.views import index
from interop.views import index as interop_index

router = routers.DefaultRouter()
router.register(r'posts', PostViewSet)
router.register(r'comments', CommentViewSet)


urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),
    path('iris/', index),
    path('interop/', interop_index)
]
  • router - Contém o roteador padrão para a API REST.
  • routeer.register - Registra os viewsets Post e Comentário no roteador.
  • urlpatterns - Contém os padrões de URL para o aplicativo Django
    • /admin/ - A interface administrativa Django.
    • /api/ -A API REST para os objetos Post e Comentário.
    • /iris/ - O endpoint SQL no IRIS.
    • /interop/ - O endpoint de interoperabilidade.

app/wsgi.py

Este arquivo contém a configuração WSGI para o aplicativo Django.

Este é o arquivo que temos que fornecer ao IRIS para executar o aplicativo Django.

Na seção Security->Applications->Web Applications, temos que fornecer o caminho para este arquivo.

  • Application Name
    • app.wsgi
  • Callable Name
    • application
  • WSGI App directory
    • /irisdev/app/app

community/models.py

Este arquivo contém os modelos Django para os objetos Post e Comentário.

from django.db import models

# Create your models here.
class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

class Comment(models.Model):
    content = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
  • Post - O modelo para o objeto Post.
    • title - O título do post.
    • content - O conteúdo do post.
  • Comment - O modelo para o objeto Comentário.
    • content - O conteúdo do comentário.
    • post - A chave estrangeira para o objeto Post.
    • related_name - O nome relacionado para os comentários.

community/seializers.py

Este arquivo contém os serializadores Django para os objetos Post e Comentário.

Usando o framework Django REST, podemos serializar os modelos Django em objetos JSON.

from rest_framework import serializers
from community.models import Post, Comment

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ('id', 'title', 'content', 'comments')

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ('id', 'content', 'post')
  • PostSerializer -O serializador para o objeto Post.
  • CommentSerializer -O serializador para o objeto Comentário.
  • fields - Os campos a serem serializados.

community/views.py

Este arquivo contém as views Django para os objetos Post e Comentário.

Usando o framework Django REST, podemos criar operações CRUD para os modelos Django.

from django.shortcuts import render
from rest_framework import viewsets

# Import the Post and Comment models
from community.models import Post, Comment

# Import the Post and Comment serializers
from community.serializers import PostSerializer, CommentSerializer

# Create your views here.
class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

class CommentViewSet(viewsets.ModelViewSet):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer
  • PostViewSet - O viewset para o objeto Post.
  • CommentViewSet - O viewset para o objeto Comentário.
  • queryset - O queryset para o viewset.
  • serializer_class - A classe de serializador para o viewset.

sqloniris/views.py

Este arquivo contém as views Django para as operações SQL no IRIS.

from django.http import JsonResponse

import iris

def index(request):
    query = "SELECT top 10 * FROM %Dictionary.ClassDefinition"
    rs = iris.sql.exec(query)
    # Convert the result to a list of dictionaries
    result = []
    for row in rs:
        result.append(row)
    return JsonResponse(result, safe=False)
  • index - A view para a operação SQL no IRIS.
  • query - A consulta SQL a ser executada no banco de dados IRIS.
  • rs - O conjunto de resultados da consulta.
  • result - A lista de listas do conjunto de resultados.
  • JsonResponse - A resposta JSON para a view, safe é definido como False para permitir lista de listas.

interop/views.py

Este arquivo contém as views Django para as operações de interoperabilidade.

from django.http import HttpResponse

from grongier.pex import Director

bs = Director.create_python_business_service('BS')

def index(request):
    result = bs.on_process_input(request)
    return HttpResponse(result, safe=False)
  • bs - O objeto de serviço de negócios criado usando a classe Director .
  • index -A view para a operação de interoperabilidade.
  • result - A view para a operação de interoperabilidade.

Observação: não usamos JsonResponse para simplificar o código, podemos usá-lo se quisermos retornar um objeto JSON.

Solução de Problemas

Como executar o aplicativo Django em modo autônomo

Para executar o aplicativo Django em modo autônomo, podemos usar o seguinte comando:

cd /irisdev/app/app
python3 manage.py runserver 8001

Isso executará o aplicativo Django na porta padrão 8001.

Observação: você deve estar dentro do contêiner para executar este comando.

docker exec -it iris-django-template-iris-1 bash

Reiniciando o aplicativo 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 acessando http://localhost:53795/csp/sys/UtilHome.csp.

Executar 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.

# Move to the app directory
cd /irisdev/app/app

# python manage.py flush --no-input
python3 manage.py migrate
# create superuser
export DJANGO_SUPERUSER_PASSWORD=SYS
python3 manage.py createsuperuser --no-input --username SuperUser --email admin@admin.fr

# load demo data
python3 manage.py loaddata community/fixtures/demo.json

# collect static files
python3 manage.py collectstatic --no-input --clear

# init iop
iop --init

# load production
iop -m /irisdev/app/app/interop/settings.py

# start production
iop --start Python.Production

Como servir arquivos estáticos

Para servir os arquivos estáticos no aplicativo Django, podemos usar o seguinte comando:

cd /irisdev/app
python3 manage.py collectstatic

Isso coletará os arquivos estáticos do aplicativo Django e os servirá no diretório /irisdev/app/static.

Para publicar os arquivos estáticos no IRIS, configure a seçãoSecurity->Applications->Web Applications.

web_applications

0
0 35
Artigo Heloisa Paiva · Out. 20, 2024 6m read

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 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

0
0 48
Artigo Danusa Calixto · Abr. 5, 2024 6m read

Neste artigo, vou abordar o teste e a depuração dos aplicativos da Web Caché (principalmente REST) com ferramentas externas. A segunda parte abrange ferramentas de Caché.

Você escreveu um código do servidor e quer testar em um cliente ou já tem um aplicativo da Web e ele não funciona. É aqui que entra a depuração. Neste artigo, vou mostrar desde as ferramentas mais fáceis de usar (navegador) até as mais completas (analisador de pacotes). Porém, primeiro, vamos falar um pouco sobre os erros mais comuns e como eles podem ser resolvidos.

Erros

401 Não Autorizado

Acho que é o erro encontrado com mais frequência ao implantar para a produção. O servidor de desenvolvimento local geralmente tem uma configuração de segurança mínima ou normal, mas convencional. No entanto, o servidor de produção pode ter um esquema mais restritivo. Portanto:

  • Confira se você fez login
  • Confira se o usuário tem acesso ao banco de dados/tabela/procedimento/linha/coluna que você quer acessar
  • Confira se a solicitação OPTIONS pode ser realizada por um usuário não autorizado

404 Não Encontrado

Confira:

  • Se o url está correto
  • Caso seja um aplicativo novo e você esteja usando um servidor da Web externo, recarregar o servidor da Web pode ajudar

Erros do aplicativo

De certa forma, é o mais fácil de encontrar — o stack trace ajuda. A resolução é completamente específica ao aplicativo.

Ferramentas de depuração

Navegador da Web

A principal ferramenta de depuração sempre disponível é o navegador da Web, de preferência o Chrome, mas o Firefox também é suficiente. As solicitações GET podem ser testadas ao inserir o URL na barra de endereço, todas as outras solicitações exigem um aplicativo da Web ou a escrita de código js. A abordagem geral é:

  • Pressione F12 para abrir as ferramentas de desenvolvedor.
  • Acesse a guia Network (Rede).
  • Marque a caixa de seleção "Preserve Log" (Preservar registro), se não estiver selecionada.
  • Exiba apenas solicitações XHR.
  • Realize a ação com problemas no aplicativo da Web.

Depois, você pode examinar as solicitações e reenviá-las. O Firefox também pode editar as solicitações antes de repeti-las.

Vantagens:

  • Sempre disponível
  • Fácil de usar (os usuários finais podem enviar capturas de tela das guias Network e Console)
  • É um ambiente de usuário final

Desvantagens:

  • Não mostra respostas parcialmente enviadas/corrompidas/etc.
  • Lento para respostas grandes
  • Lento para um número grande de respostas
  • Tudo é feito manualmente

Cliente REST

O cliente REST é um aplicativo da Web independente ou um complemento do navegador da Web criado especificamente para testar aplicativos da Web. Eu uso Postman, mas há muitos outros. Veja como é a depuração no Postman:

O Postman trabalha com solicitações agrupadas em coleções. A solicitação pode ser enviada no ambiente. O ambiente é uma coleção de variáveis. Por exemplo, no meu ambiente CACHE@localhost, a variável do host está definida como localhost e o usuário como _SYSTEM. Quando a solicitação é enviada, as variáveis são substituídas pelos seus valores para o ambiente escolhido e a solicitação é enviada.

Confira um exemplo de coleção e ambiente para o projeto MDX2JSON.

Vantagens:

  • Escreva uma única vez e use em todos os lugares
  • Melhor controle sobre a solicitação
  • Embelezamento das respostas

Desvantagens:

  • <s>A depuração de solicitações em cadeia (a resposta à request1 pode forçar a request2 ou request 2B) ainda é manual</s> (Atualização de 22 de fevereiro: possível no Postman)
  • Às vezes, falha com respostas parcialmente enviadas/corrompidas/etc.

Proxy de depuração HTTP

Um aplicativo independente que registra tráfego HTTP(S). As solicitações registradas podem ser modificadas e reenviadas. Eu uso Charles e Fiddler.

Vantagens:

  • Processa respostas parcialmente enviadas/corrompidas/etc.
  • Embelezamento das respostas
  • Melhor suporte para tráfego HTTPS (do que no analisador de pacotes)
  • Consegue capturar sessões

Desvantagens:

  • Algo (aplicativo da Web/cliente REST/código JS) é necessário para enviar a solicitação

Analisador de pacotes

Um programa de computador consegue interceptar e registrar o tráfego transmitido por uma rede. Com os fluxos de dados fluindo em toda a rede, o sniffer captura cada pacote e, se necessário, decodifica os dados brutos do pacote. Essa é a opção mais completa, mas também exige um pouco de habilidade para a operação adequada. Eu uso o WireShark. Veja um breve guia sobre a instalação e o uso:

  1. Se você quiser capturar pacotes locais, leia sobre o loopback e instale o software de pré-requisito (npcap para windows)
  2. Instale o WireShark
  3. Configure filtros de captura (por exemplo, um filtro para só capturar tráfego na porta 57772: port 57772
  4. Inicie a captura
  5. Configure filtros de exibição (por exemplo, um filtro para só exibir tráfego http para um ip específico: ip.addr == 1.2.3.4 && http

Confira um exemplo de captura de tráfego http (filtro de exibição) na porta 57772 (filtro de captura):

 Vantagens:

  • Processa respostas parcialmente enviadas/corrompidas/etc.
  • Consegue capturar uma grande quantidade de tráfego
  • Consegue capturar qualquer coisa
  • Consegue capturar sessões

Desvantagens:

  • Algo (aplicativo da Web/cliente REST/código JS) é necessário para enviar a solicitação

O que usar

Bem, isso depende da finalidade. Primeiro, podemos ter como objetivo registrar (proxy de depuração, analisador de pacotes) ou gerar (navegador, cliente REST) solicitações.

Se você estiver desenvolvendo uma API Web REST, o cliente REST é a maneira mais rápida de testar o funcionamento.

No entanto, se as solicitações do cliente REST funcionarem, mas o aplicativo da Web cliente não, talvez seja necessário o proxy de depuração http e o analisador de pacotes.

Se você tiver clientes e precisar desenvolver uma API do lado do servidor para trabalhar com eles, precisará do proxy de depuração http ou do analisador de pacotes.

É melhor estar familiarizado com todos os 4 tipos de ferramentas e mudar rapidamente entre eles se o atual não der conta do trabalho.

Às vezes, a ferramenta ideal é óbvia.

Por exemplo, recentemente, desenvolvi uma API do lado do servidor para um protocolo de extensão http popular. Os requisitos eram:

  • Os clientes já estavam escritos e o código não podia ser alterado
  • Clientes diferentes têm comportamentos diferentes
  • O comportamento no http e https varia
  • O comportamento com diferentes tipos de autenticação varia
  • Até cem solicitações por segundo para cada cliente
  • Todos ignoram o RFC

Há só uma solução aqui: o analisador de pacotes.

Ou, se estou desenvolvendo uma API REST para consumo de JS, o cliente REST é uma ferramenta perfeita para testes.

Ao depurar o aplicativo da Web, comece com o navegador.

Na Parte 2, vamos discutir o que pode ser feito (muita coisa) para a depuração da Web no lado do Caché.

Quais são suas abordagens para depurar a comunicação no lado do cliente?

0
0 94
Artigo Danusa Calixto · Ago. 7, 2023 1m read

InterSystems FAQ 

Você pode definir páginas de erro individuais para as seguintes mensagens de erro/respostas de sistema do Web Gateway:   

  • erro de servidor 
  • servidor ocupado
  • servidor indisponível
  • tempo limite do servidor
  • conexão fechada

As configurações são feitas na tela de Gerenciamento do Web Gateway ([Management Portal] > [System Administration] > [Configuration] > [Web Gateway Management] > [Configuration] > [Default Parameters]).

Na seção Página de Erro do menu de Parâmetros Padrão, defina o nome do arquivo da página html a ser exibida ou o caminho (URL) para a qual redirecionar quando ocorrer um erro.  

  

0
0 58
Artigo Gilleady Alves da Silva · Fev. 17, 2023 2m read

O arquivo Messages.log contém muitas informações úteis sobre o IRIS. Às vezes, o arquivo fica grande e não é fácil encontrar os dados que estou interessado em revisar. Seria bom pular para uma data e hora específica em que suspeitamos que um problema possa ter começado.

Sempre que preciso de suporte da InterSystems, o WRC pedirá que envie o arquivo Messages.log. Dependendo de onde o IRIS está implantado, pode ser difícil obter o arquivo Messages.log para enviá-lo para a InterSystems.

0
0 69
Anúncio Angelo Bruno Braga · Mar. 23, 2022

É um prazer anunciar o lançamento da versão 1.4.4 da extensão para VS Code, que contém as seguintes melhorias e correções. Os links irão levá-los para o problema  no GitHub que está sendo endereçado. Como sempre, se você já possuir a extensão instalada, o VS Code deverá atualizar automaticamente sua extensão. Se você é um novo usuário, utilize estas instruções para iniciar. 

Log de Mudanças

0
1 119
Artigo Henrique Dias · Out. 26, 2020 3m read

Fala pessoal!


Quero dividir com vocês um projeto pessoal, que iniciou como um simples pedido no meu trabalho: 

É possível saber quantas licenças Caché estamos utilizando? 

Lendo outros artigos aqui na comunidade, eu encontrei este excelente artigo de David Loveluck 


APM - Utilizando Caché History Monitor
https://community.intersystems.com/post/apm-using-cach%C3%A9-history-monitor

Então, utilizando o artigo de David como base, eu comecei a utilizar o Caché History Monitor e a exibir todas as informações.
Quando me deparei com o seguinte dilema: Qual a melhor tecnologia de frontend que eu posso usar?

0
0 218