#Open Exchange

0 Seguidores · 139 Postagens

As soluções para a Plataforma de Dados InterSystems, o Open Exchange, é uma galeria de soluções de software, ferramentas, e frameworks que foram desenvolvidos com a Plataforma de Dados InterSystems (Caché, Ensemble, HealthShare, InterSystems IRIS, InterSystems IRIS for Health) ou destinam-se a ajudar no desenvolvimento, implantação e suporte as soluções construídas com a Plataforma de Dados InterSystems.

Você pode usar qualquer um dos recursos ou pode publicar sua própria ferramenta, exemplo de tecnologia ou solução.

Descubra o Open Exchange.

Artigo Davi Massaru Teixeira Muta · Out. 11, 2025 10m read

Documentação Técnica — Quarkus IRIS Monitor System

1. Objetivo e Escopo

Este módulo permite a integração entre aplicações Java baseadas em Quarkus e as capacidades nativas de monitoramento de performance do InterSystems IRIS.
Ele possibilita que o desenvolvedor anote métodos com @PerfmonReport, acionando automaticamente as rotinas ^PERFMON do IRIS durante a execução do método e gerando relatórios de performance sem intervenção manual.


2. Componentes do Sistema

2.1 Anotação: @PerfmonReport

  • Definida como InterceptorBinding do CDI.
  • Pode ser aplicada a métodos ou classes.
  • Instrui o framework a envolver a execução do método com a lógica de monitoramento do IRIS.

2.2 Interceptor: PerfmonReportInterceptor

  • Intercepta chamadas a métodos anotados.

  • Fluxo de execução:

    1. Registrar evento de início (LOG.infof("INIT: …"))
    2. Chamar monitorSystem.startPerfmon()
    3. Prosseguir com context.proceed()
    4. No bloco finally:
      • Chamar monitorSystem.generateReportPerfmon(...)
      • Chamar monitorSystem.stopPerfmon()
      • Registrar evento de fim com tempo de execução
  • Garante que o monitoramento sempre será encerrado, mesmo se ocorrer uma exceção.

2.3 Bean DAO: MonitorSystem

  • Bean CDI anotado com @ApplicationScoped.

  • Mantém uma única instância de IRIS inicializada na inicialização.

  • Configuração injetada via @ConfigProperty (URL JDBC, usuário, senha).

  • Utiliza DriverManager.getConnection(...) para obter uma IRISConnection nativa.

  • Contém os métodos:

    • startPerfmon()
    • generateReportPerfmon(String reportName)
    • stopPerfmon()
  • Cada método chama as correspondentes rotinas ObjectScript em iris.src.dc.AdapterPerfmonProc via iris.classMethodVoid(...).

2.4 Adapter ObjectScript: iris.src.dc.AdapterPerfmonProc

  • Define as rotinas que encapsulam a lógica do ^PERFMON:

      Class iris.src.dc.AdapterPerfmonProc Extends %RegisteredObject
      {
          ClassMethod start() As %Status
          {
              Set namespace = $NAMESPACE
              zn "%SYS"
              set status = $$Stop^PERFMON()
              set status = $$Start^PERFMON()
              zn namespace
              return status
          }
    
          ClassMethod generateReport(nameReport As %String = "report.txt") As %Status
          {
              Set namespace = $NAMESPACE
              zn "%SYS"
              Set tempDirectory = ##class(%SYS.System).TempDirectory()
              set status = $$Report^PERFMON("R","R","P", tempDirectory_"/"_nameReport)
              zn namespace
    
              return status
          }
    
          ClassMethod stop() As %Status
          {
              Set namespace = $NAMESPACE
              zn "%SYS"
              Set status = $$Stop^PERFMON()
              zn namespace
    
              return status
          }
      }
    

    Opera no namespace %SYS para acessar as rotinas ^PERFMON e, em seguida, retorna para o namespace original.

  • Opera no namespace %SYS para acessar as rotinas ^PERFMON, retornando ao namespace original.


3. Fluxo de Execução

  1. Uma requisição entra na aplicação Quarkus.

  2. O interceptor CDI detecta a anotação @PerfmonReport e intercepta a chamada do método.

  3. monitorSystem.startPerfmon() é invocado, acionando o monitoramento ^PERFMON do IRIS.

  4. O método de negócio é executado normalmente (acesso a dados, transformações, lógica, etc.).

  5. Após o método retornar ou lançar uma exceção, o interceptor garante que:

    • monitorSystem.generateReportPerfmon(...) seja chamado para criar um relatório de performance .txt.
    • monitorSystem.stopPerfmon() seja executado para encerrar a sessão de monitoramento.
    • O tempo total de execução do lado Java seja registrado usando Logger.infof(...).
  6. O arquivo de relatório gerado é armazenado no diretório temporário do IRIS, normalmente: /usr/irissys/mgr/Temp/

    • O nome do arquivo segue o padrão: <ClassName><MethodName><timestamp>.txt

4. Desafios Técnicos e Soluções

DesafioSolução
ClassCastException ao usar conexões JDBC pooladasUse DriverManager.getConnection(...) para obter uma IRISConnection nativa, em vez do ConnectionWrapper poolado.
Sobrecarga por abrir conexões repetidamenteMantenha uma única instância de IRIS dentro de um bean @ApplicationScoped, inicializada via @PostConstruct.
Garantir que ^PERFMON seja sempre encerrado, mesmo em exceçõesUse try-finally no interceptor para chamar stopPerfmon() e generateReportPerfmon().
Portabilidade de configuraçãoInjete as configurações de conexão (jdbc.url, username, password) usando @ConfigProperty e application.properties.
Gerenciamento de sessões de monitoramento concorrentesEvite anotar endpoints com alta concorrência. Versões futuras podem implementar isolamento por sessão.

5. Casos de Uso e Benefícios

  • Permite visibilidade em tempo real da atividade do IRIS a partir do código Java.
  • Simplifica a análise de performance e otimização de consultas para desenvolvedores.
  • Útil para benchmarking, profiling e testes de regressão do sistema.
  • Pode servir como um registro leve de auditoria de performance para operações críticas.

6. Exemplo Prático de Uso

O código-fonte completo e o setup de deployment estão disponíveis em:


6.1 Visão Geral

A aplicação roda um servidor Quarkus conectado a uma instância InterSystems IRIS configurada com o namespace FHIRSERVER.
A camada ORM é implementada usando Hibernate ORM com PanacheRepository, permitindo mapeamento direto entre entidades Java e classes do banco IRIS.

Quando a aplicação é iniciada (via docker-compose up), são iniciados:

  • O container IRIS, hospedando o modelo de dados FHIR e rotinas ObjectScript (incluindo AdapterPerfmonProc);
  • O container Quarkus, expondo endpoints REST e conectando-se ao IRIS via driver JDBC nativo.

6.2 Endpoint REST

Um recurso REST expõe um endpoint simples para recuperar informações de pacientes:

@Path("/patient")
public class PatientResource {

    @Inject
    PatientService patientService;

    @GET
    @Path("/info")
    @Produces(MediaType.APPLICATION_JSON)
    public PatientInfoDTO searchPatientInfo(@QueryParam("key") String key) {
        return patientService.patientGetInfo(key);
    }
}

Este endpoint aceita um parâmetro de consulta (key) que identifica o recurso do paciente dentro do repositório de dados FHIR.


6.3 Camada de Serviço com @PerfmonReport

A classe PatientService contém a lógica de negócio para recuperar e compor informações do paciente.
Ela é anotada com @PerfmonReport, o que significa que cada requisição para /patient/info aciona o monitoramento de performance do IRIS:

@ApplicationScoped
public class PatientService {

    @Inject
    PatientRepository patientRepository;

    @PerfmonReport
    public PatientInfoDTO patientGetInfo(String patientKey) {

        Optional<Patient> patientOpt = patientRepository.find("key", patientKey).firstResultOptional();
        Patient patient = patientOpt.orElseThrow(() -> new IllegalArgumentException("Patient not found"));

        PatientInfoDTO dto = new PatientInfoDTO();
        dto.setKey(patient.key);
        dto.setName(patient.name);
        dto.setAddress(patient.address);
        dto.setBirthDate(patient.birthDate != null ? patient.birthDate.toString() : null);
        dto.setGender(patient.gender);
        dto.setMedications(patientRepository.findMedicationTextByPatient(patientKey));
        dto.setConditions(patientRepository.findConditionsByPatient(patientKey));
        dto.setAllergies(patientRepository.findAllergyByPatient(patientKey));

        return dto;
    }
}

6.4 Fluxo de Execução

Uma requisição é feita para: GET /patient/info?key=Patient/4

O Quarkus encaminha a requisição para PatientResource.searchPatientInfo().

O interceptor CDI detecta a anotação @PerfmonReport em PatientService.patientGetInfo().

Antes de executar a lógica de serviço:

  • O interceptor invoca MonitorSystem.startPerfmon(), que chama a classe IRIS iris.src.dc.AdapterPerfmonProc.start().

  • O método executa a lógica de negócio, consultando dados do paciente usando os mapeamentos Hibernate PanacheRepository.

Após a conclusão do método:

  • MonitorSystem.generateReportPerfmon() é chamado para criar o relatório de performance.

  • MonitorSystem.stopPerfmon() interrompe o monitoramento de performance do IRIS.

Um relatório .txt é gerado em: usr/irissys/mgr/Temp/

Exemplo de nome de arquivo: PatientService_patientGetInfo_20251005_161906.txt

6.5 Resultado

O relatório gerado contém estatísticas detalhadas de execução do IRIS, por exemplo:

                         Routine Activity by Routine

Started: 10/11/2025 05:07:30PM                    Collected: 10/11/2025 05:07:31PM

Routine Name                        RtnLines  % Lines   RtnLoads  RtnFetch  Line/Load Directory
----------------------------------- --------- --------- --------- --------- --------- ---------
Other                                     0.0       0.0       0.0       0.0         0
PERFMON                                  44.0       0.0       0.0       0.0         0 /usr/irissys/mgr/
%occLibrary                         3415047.0      34.1   48278.0       0.0      70.7 /usr/irissys/mgr/irislib/
iris.src.dc.AdapterPerfmonProc.1          7.0       0.0       2.0       0.0       3.5 /usr/irissys/mgr/FHIRSERVER/
%occName                            5079994.0      50.7       0.0       0.0         0 /usr/irissys/mgr/irislib/
%apiDDL2                            1078497.0      10.8   63358.0       0.0      17.0 /usr/irissys/mgr/irislib/
%SQL.FeatureGetter.1                 446710.0       4.5   66939.0       0.0       6.7 /usr/irissys/mgr/irislib/
%SYS.WorkQueueMgr                       365.0       0.0       1.0       0.0     365.0 /usr/irissys/mgr/
%CSP.Daemon.1                            16.0       0.0       1.0       0.0      16.0 /usr/irissys/mgr/irislib/
%SYS.TokenAuth.1                         14.0       0.0       5.0       0.0       2.8 /usr/irissys/mgr/
%Library.PosixTime.1                      2.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislib/
%SYS.sqlcq.uEXTg3QR7a7I7Osf9e8Bz...      52.0       0.0       1.0       0.0      52.0 /usr/irissys/mgr/
%SYS.SQLSRV                              16.0       0.0       0.0       0.0         0 /usr/irissys/mgr/
%apiOBJ                                 756.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislib/
FT.Collector.1                            0.0       0.0       0.0       0.0         0 /usr/irissys/mgr/
SYS.Monitor.FeatureTrackerSensor.1        0.0       0.0       0.0       0.0         0 /usr/irissys/mgr/
%SYS.Monitor.Control.1                    0.0       0.0       0.0       0.0         0 /usr/irissys/mgr/
%SYS.DBSRV.1                            252.0       0.0       4.0       0.0      63.0 /usr/irissys/mgr/
%sqlcq.FHIRSERVER.cls12.1                19.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislocaldata/
%sqlcq.FHIRSERVER.cls13.1                74.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislocaldata/
%sqlcq.FHIRSERVER.cls14.1                74.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislocaldata/
%sqlcq.FHIRSERVER.cls15.1                52.0       0.0       0.0       0.0         0 /usr/irissys/mgr/irislocaldata/
%SYS.System.1                             1.0       0.0       0.0       0.0         0 /usr/irissys/mgr/

Esses dados fornecem uma visão precisa sobre quais rotinas foram executadas internamente pelo IRIS durante aquela chamada REST — incluindo compilação de SQL, execução e acesso a dados FHIR.

Observação: As rotinas %sqlcq.FHIRSERVER.* registram todas as consultas SQL cache executadas pelo Quarkus dentro do método. Monitorar essas rotinas permite aos desenvolvedores analisar a execução das queries, compreender o comportamento do código e identificar possíveis gargalos de performance. Isso as torna uma ferramenta poderosa para desenvolvimento e depuração de operações relacionadas ao FHIR.

image

6.6 Resumo

Este exemplo demonstra como um serviço padrão Quarkus pode utilizar de forma transparente as ferramentas nativas de monitoramento do IRIS usando a anotação @PerfmonReport.
Ele combina:

  • Interceptadores CDI (Quarkus)
  • Hibernate PanacheRepositories (ORM)
  • Rotinas ObjectScript nativas do IRIS (^PERFMON)

O resultado é um mecanismo de profiling de performance totalmente automatizado e reproduzível, que pode ser aplicado a qualquer método de serviço na aplicação.

0
0 17
Artigo Larissa Prussak · Set. 18, 2025 1m read

Se um dos seus pacotes no OEX recebe uma avaliação, você é notificado pelo OEX apenas sobre o seu próprio pacote.
A classificação reflete a experiência do avaliador com o status encontrado no momento da avaliação.
É como uma fotografia instantânea e pode já ter mudado desde então.
As avaliações feitas por outros membros da comunidade são marcadas com * na última coluna.

1
0 15
Anúncio Rochael Ribeiro · Jul. 28, 2025

🚀 NOVO EPISÓDIO NO AR! Eu no Café Debug com a Comunidade InterSystems! 🎧

Galera! Tenho uma novidade super bacana para compartilhar com vocês! Eu tive o prazer de participar de um bate-papo incrível no Café Debug, e o episódio #168 já está disponível!

https://open.spotify.com/episode/0xDm4JDXHZzpHLSBd8VXPW?si=4hTTUBwnS7u8M7ncyjrCMQ&nd=1&dlsi=8d6d058a13464fa6

1
0 23
Artigo Larissa Prussak · Jul. 3, 2025 2m read

Fazendo Profiling de Documentos CCD com o CCD Data Profiler da LEAD North

Já abriu um CCD e foi recebido por uma parede de XML confuso? Você não está sozinho. Apesar de ser um formato essencial para a troca de dados clínicos, os CCDs são notoriamente densos, verbosos e pouco amigáveis à leitura humana. Para desenvolvedores e analistas que tentam validar sua estrutura ou extrair informações significativas, navegar por esses documentos pode parecer mais arqueologia do que engenharia.

Apresentando o CCD Data Profiler

0
0 22
Artigo Heloisa Paiva · Jun. 5, 2025 4m read

Duas Grandes Mudanças para a Ferramenta de Código Aberto TestCoverage: Suporte a Python Embutido e uma Nova Interface de Usuário

Python Embutido

Anteriormente, o TestCoverage conseguia rastrear a cobertura de testes unitários apenas para códigos escritos em ObjectScript. Ele ignorava o código escrito em outras linguagens, como Python, nas estatísticas de cobertura.

 

0
0 23
Artigo Heloisa Paiva · Abr. 30, 2025 17m read

Olá Comunidade,

Gostaria de apresentar meu último pacoteOpenAPI-Suite.Este é um conjunto de ferramentas para gerar código ObjectScript a partir deuma especificação OpenAPI versão 3.0..  IEm resumo, estes pacotes permitem:

  • Gerar classes de servidor. É bem parecido com o código gerado por ^%REST mas o valor adicionado é o suporte à versão 3.0.
  • Gerar classes de cliente HTTP.
  • Gerar classes de produção de cliente (business services, business operation, business process, Ens.Request, Ens.Response).
  • Uma interface web para gerar e baixar o código ou gerar e compilar diretamente no servidor.
  • Converter especificações das versões 1.x, 2.x para a versão 3.0.
0
0 43
Artigo Heloisa Paiva · Abr. 18, 2025 18m read

Image generated by OpenAI DALL·E

Sou um grande fã de ficção científica, mas embora eu esteja totalmente a bordo da nave Star Wars (desculpas aos meus colegas Trekkies!), sempre apreciei os episódios clássicos de Star Trek da minha infância. A tripulação diversificada da USS Enterprise, cada um dominando suas funções únicas, é uma metáfora perfeita para entender os agentes de IA e seu poder em projetos como o Facilis. Então, vamos embarcar em uma missão intergaláctica, utilizando a IA como a tripulação da nossa nave e  audaciosamente ir audaciosamente ir homem jamais esteve!  Esse conceito de trabalho em equipe é uma analogia maravilhosa para ilustrar como os agentes de IA funcionam e como os usamos em nosso projeto DC-Facilis. Então, vamos mergulhar e assumir o papel de um capitão de nave estelar, liderando uma tripulação de IA em territórios inexplorados!

Bem-vindo ao CrewAI!

Para gerenciar nossa tripulação de IA, usamos uma estrutura fantástica chamada CrewAI.É enxuta, extremamente rápida e opera como uma plataforma Python multiagente. Uma das razões pelas quais a amamos, além do fato de ter sido criada por outro brasileiro, é sua incrível flexibilidade e design baseado em funções.

from crewai import Agent, Task, Crew

the taken quote

Conheça os Planejadores

No Facilis, nossos agentes de IA são divididos em dois grupos. Vamos começar com o primeiro, que gosto de chamar de "Os Planejadores".

O Agente de Extração

O papel principal do Facilis é receber uma descrição em linguagem natural de um serviço REST e criar automaticamente toda a interoperabilidade necessária. Portanto, nosso primeiro membro da tripulação é o Agente de Extração. Este agente tem a tarefa de "extrair" as especificações da API a partir da descrição fornecida pelo usuário.

Aqui está o que o Agente de Extração procura:

  • Host (obrigatório)
  • Endpoint (obrigatório)
  • Params (opcional)
  • Port (se disponível)
  • modelo JSON (para POST/PUT/PATCH/DELETE)
  • Autenticação (se aplicável)
    def create_extraction_agent(self) -> Agent:
        return Agent(
            role='Extrator de Especificações de API',
            goal='Extrair especificações de API de descrições em linguagem natural',
            backstory=dedent("""
                        Você é especializado em interpretar descrições em linguagem natural
                        e extrair especificações de API estruturadas.
            """),
            allow_delegation=True,
            llm=self.llm
        )

    def extract_api_specs(self, descriptions: List[str]) -> Task:
        return Task(
            description=dedent(f"""
               Extraia as especificações de API das seguintes descrições:
                {json.dumps(descriptions, indent=2)}
                
               Para cada descrição, extraia:
                - Host (obrigatório)
                - Endpoint (obrigatório)
                - Params (opcional)
                - Port (se disponível)
                - modelo JSON (para POST/PUT/PATCH/DELETE)
                - Autenticação (se aplicável)
                
                Marque quaisquer campos obrigatórios ausentes como 'missing'.
                Retorne os resultados em formato JSON como um array de especificações.
            """),
            expected_output="""Um array JSON contendo as especificações de API extraídas com todos os campos obrigatórios e opcionais""",
            agent=self.extraction_agent
        )

O Agente de Validação

Próximo na fila, o Agente de Validação! Sua missão é garantir que as especificações de API coletadas pelo Agente de Extração estejam corretas e consistentes. Ele verifica:

  1. Formato de host válido
  2. Endpoint começando com '/'
  3. Métodos HTTP válidos (GET, POST, PUT, DELETE, PATCH)
  4. Número de porta válido (se fornecido)
  5. Presença de modelo JSON para métodos aplicáveis.

    def create_validation_agent(self) -> Agent:
        return Agent(
            role='API Validator',
            goal='Validar especificações de API quanto à correção e consistência.',
            backstory=dedent("""
                 Você é um especialista em validação de API, garantindo que todas as especificações
                 atendam aos padrões e formatos necessários.
            """),
            allow_delegation=False,
            llm=self.llm
        )

 def validate_api_spec(self, extracted_data: Dict) -> Task:
        return Task(
            description=dedent(f"""
                Valide a seguinte especificação de API:
                {json.dumps(extracted_data, indent=2)}
                
                Verifique:
                1. Formato de host válido
                2. Endpoint começando com '/'
                3. Métodos HTTP válidos  (GET, POST, PUT, DELETE, PATCH)
                4. Número de porta válido (se fornecido)
                5. Presença de modelo JSON para métodos aplicáveis.
                
               Retorne os resultados da validação em formato JSON.
            """),
            expected_output="""Um objeto JSON contendo os resultados da validação com quaisquer erros ou confirmação de validade""",
            agent=self.validation_agent
        )

O Agente de Interação

Avançando, conhecemos o Agente de Interação, nosso Especialista em Interação com o Usuário. Seu papel é obter quaisquer campos de especificação de API ausentes que foram marcados pelo Agente de Extração e validá-los com base nas descobertas do Agente de Validação. Eles interagem diretamente com os usuários para preencher quaisquer lacunas.

O Agente de Produção

Precisamos de duas informações cruciais para criar a interoperabilidade necessária: namespace e nome da produção. O Agente de Produção interage com os usuários para coletar essas informações, de forma muito semelhante ao Agente de Interação.

O Agente de Transformação de Documentação

Assim que as especificações estiverem prontas, é hora de convertê-las em documentação OpenAPI. O Agente de Transformação de Documentação, um especialista em OpenAPI, cuida disso.

    def create_transformation_agent(self) -> Agent:
        return Agent(
            role='Especialista em Transformação OpenAPI',
            goal='Converter especificações de API em documentação OpenAPI',
            backstory=dedent("""
                Você é um especialista em especificações e documentação OpenAPI.
                Seu papel é transformar detalhes de API validados em documentação
                OpenAPI 3.0 precisa e abrangente.
            """),
            allow_delegation=False,
            llm=self.llm
        )

    def transform_to_openapi(self, validated_endpoints: List[Dict], production_info: Dict) -> Task:
        return Task(
            description=dedent(f"""
                Transforme as seguintes especificações de API validadas em documentação OpenAPI 3.0:
                
                Informações de Produção:
                {json.dumps(production_info, indent=2)}
                
               Endpoints Validados:
                {json.dumps(validated_endpoints, indent=2)}
                
               Requisitos:
               1. Gerar especificação OpenAPI 3.0 completa
               2. Incluir schemas de requisição/resposta apropriados
               3. Documentar todos os parâmetros e corpos de requisição
               4. Incluir autenticação se especificado
               5. Garantir formatação de caminho apropriada
                
                Retorne a especificação OpenAPI nos formatos JSON e YAML.
            """),
            expected_output="""Um objeto JSON contendo a especificação OpenAPI 3.0 completa com todos os endpoints e schemas.""",
            agent=self.transformation_agent
        )

The Review Agent

Após a transformação, a documentação OpenAPI passa por uma revisão meticulosa para garantir conformidade e qualidade. O Agente de Revisão segue esta lista de verificação:

1.Conformidade OpenAPI 3.0

  • Especificação de versão correta
  • Elementos raiz obrigatórios
  • Validação da estrutura do schema
  1. Completude
  • Todos os endpoints documentados
  • Parâmetros totalmente especificados
  • Schemas de requisição/resposta definidos
  • Esquemas de segurança configurados corretamente
  1. Verificações de Qualidade
  • Convenções de nomenclatura consistentes
  • Descrições claras
  • Uso adequado de tipos de dados
  • Códigos de resposta significativos
  1. Melhores Práticas
  • Uso adequado de tags
  • Nomenclatura de parâmetros consistente
  • Definições de segurança apropriadas

Finalmente, se tudo parecer bom, o Agente de Revisão reporta um objeto JSON saudável com a seguinte estrutura:

{
 "is_valid": boolean,
 "approved_spec": object (a especificação OpenAPI revisada e possivelmente corrigida),
 "issues": [array de strings descrevendo quaisquer problemas encontrados],
 "recommendations": [array de sugestões de melhoria]
}

    def create_reviewer_agent(self) -> Agent:
        return Agent(
            role='Revisor de Documentação OpenAPI',
            goal='Garantir a conformidade e qualidade da documentação OpenAPI',
            backstory=dedent("""
                Você é a autoridade final em qualidade e conformidade de documentação OpenAPI.
               Com vasta experiência em especificações OpenAPI 3.0, você revisa meticulosamente
               a documentação para precisão, completude e adesão aos padrões.
            """),
            allow_delegation=True,
            llm=self.llm
        )


    def review_openapi_spec(self, openapi_spec: Dict) -> Task:
        return Task(
            description=dedent(f"""
                Revise a seguinte especificação OpenAPI para conformidade e qualidade:
                
                {json.dumps(openapi_spec, indent=2)}
                
                Lista de Verificação da Revisão::
                1. Conformidade OpenAPI 3.0
                - Verificar a especificação de versão correta
                - Verificar os elementos raiz obrigatórios
                - Validar a estrutura do schema
                
                2. Completude
                - Todos os endpoints devidamente documentados
                - Parâmetros totalmente especificados
                - Schemas de requisição/resposta definidos
                - Esquemas de segurança configurados corretamente
                
                3. Quality Checks
                - Consistent naming conventions
                - Clear descriptions
                - Proper use of data types
                - Meaningful response codes
                
                4. Best Practices
                - Proper tag usage
                - Consistent parameter naming
                - Appropriate security definitions
                
                Você deve retornar um objeto JSON com a seguinte estrutura:
                {{
                    "is_valid": boolean,
                    "approved_spec": object (a especificação OpenAPI revisada e possivelmente corrigida),
                    "issues": [array de strings descrevendo quaisquer problemas encontrados],
                    "recommendations": [array de sugestões de melhoria]
                }}
            """),
            expected_output=""" Um objeto JSON contendo: is_valid (boolean), approved_spec (object), issues (array), e recommendations (array)""",
            agent=self.reviewer_agent
        )

O Agente Iris

O último agente no grupo do planejador é o Agente Iris, que envia a documentação OpenAPI finalizada para o Iris.


    def create_iris_i14y_agent(self) -> Agent:
        return Agent(
            role='Especialista em Integração Iris I14y',
            goal='Integrar especificações de API com o serviço Iris I14y',
            backstory=dedent("""
                  Você é responsável por garantir uma integração suave entre o sistema de
                 documentação da API e o serviço Iris I14y. Você lida com a
                 comunicação com o Iris, valida as respostas e garante a integração
                 bem-sucedida das especificações da API.
            """),
            allow_delegation=False,
            llm=self.llm
        )

    def send_to_iris(self, openapi_spec: Dict, production_info: Dict, review_result: Dict) -> Task:
        return Task(
            description=dedent(f"""
               Enviar a especificação OpenAPI aprovada para o serviço Iris I14y:

                Informações de Produção:
                - Nome: {production_info['production_name']}
                - Namespace: {production_info['namespace']}
                - É Novo: {production_info.get('create_new', False)}

               Status da Revisão:
                - Aprovado: {review_result['is_valid']}
                
                Retornar o resultado da integração em formato JSON.
            """),
            expected_output="""Um objeto JSON contendo o resultado da integração com o serviço Iris I14y, incluindo o status de sucesso e os detalhes da resposta.""",
            agent=self.iris_i14y_agent
        )

class IrisI14yService:
    def __init__(self):
        self.logger = logging.getLogger('facilis.IrisI14yService')
        self.base_url = os.getenv("FACILIS_URL", "http://dc-facilis-iris-1:52773") 
        self.headers = {
            "Content-Type": "application/json"
        }
        self.timeout = int(os.getenv("IRIS_TIMEOUT", "504"))  # in milliseconds
        self.max_retries = int(os.getenv("IRIS_MAX_RETRIES", "3"))
        self.logger.info("IrisI14yService initialized")

    async def send_to_iris_async(self, payload: Dict) -> Dict:
        """
        Enviar carga útil para o endpoint de geração do Iris de forma assíncrona.
        """
        self.logger.info("Enviando carga útil para o endpoint de geração do Iris.")
        if isinstance(payload, str):
            try:
                json.loads(payload)  
            except json.JSONDecodeError:
                raise ValueError("Invalid JSON string provided")
        
        retry_count = 0
        last_error = None

        # Cria timeout para o aiohttp
        timeout = aiohttp.ClientTimeout(total=self.timeout / 1000)  # Converte ms para seconds

        while retry_count < self.max_retries:
            try:
                self.logger.info(f"Attempt {retry_count + 1}/{self.max_retries}: Enviando requisição para {self.base_url}/facilis/api/generate")
                
                async with aiohttp.ClientSession(timeout=timeout) as session:
                    async with session.post(
                        f"{self.base_url}/facilis/api/generate",
                        json=payload,
                        headers=self.headers
                    ) as response:
                        if response.status == 200:
                            return await response.json()
                        response.raise_for_status()

            except asyncio.TimeoutError as e:
                retry_count += 1
                last_error = e
                error_msg = f"Timeout occurred (attempt {retry_count}/{self.max_retries})"
                self.logger.warning(error_msg)
                
                if retry_count < self.max_retries:
                    wait_time = 2 ** (retry_count - 1)
                    self.logger.info(f"Waiting {wait_time} seconds before retry...")
                    await asyncio.sleep(wait_time)
                continue

            except aiohttp.ClientError as e:
                error_msg = f"Failed to send to Iris: {str(e)}"
                self.logger.error(error_msg)
                raise IrisIntegrationError(error_msg)

        error_msg = f"Failed to send to Iris after {self.max_retries} attempts due to timeout"
        self.logger.error(error_msg)
        raise IrisIntegrationError(error_msg, last_error)

Conheça os Geradores

Nosso segundo conjunto de agentes são os Geradores. Eles estão aqui para transformar as especificações OpenAPI em interoperabilidade InterSystems IRIS. Há oito deles neste grupo.

O primeiro deles é o Agente Analisador. Ele é como o planejador, traçando a rota. Seu trabalho é mergulhar nas especificações OpenAPI e descobrir quais componentes de Interoperabilidade IRIS são necessários.


    def create_analyzer_agent():
        return Agent(
            role="Analisador de Especificações OpenAPI",
            goal="Analisar minuciosamente as especificações OpenAPI e planejar os componentes de Interoperabilidade IRIS",
            backstory="""Você é um especialista em especificações OpenAPI e em Interoperabilidade InterSystems IRIS.
                     Seu trabalho é analisar documentos OpenAPI e criar um plano detalhado de como eles devem ser implementados como componentes de Interoperabilidade IRIS.""",
            verbose=False,
            allow_delegation=False,
            tools=[analyze_openapi_tool],
            llm=get_facilis_llm()
        )

   analysis_task = Task(
        description="""Analisar a especificação OpenAPI e planejar os componentes de Interoperabilidade IRIS necessários.
Incluir uma lista de todos os componentes que devem estar na classe de Produção."",
        agent=analyzer,
        expected_output="Uma análise detalhada da especificação OpenAPI e um plano para os componentes IRIS, incluindo a lista de componentes de Produção",
        input={
            "openapi_spec": openApiSpec,
            "production_name": "${production_name}" 
        }
    )

Em seguida, os Agentes de Business Services (BS) e Business Operations (BO) assumem o controle. Eles geram os Business Services e as Business Operations com base nos endpoints OpenAPI. Eles usam uma ferramenta útil chamada MessageClassTool para gerar as classes de mensagens perfeitas, garantindo a comunicação.


    def create_bs_generator_agent():
        return Agent(
            role="Gerador de Produção e Business Service IRIS",
            goal="Gerar classes de Produção e Business Service IRIS formatadas corretamente a partir de especificações OpenAPI",
            backstory="""Você é um desenvolvedor InterSystems IRIS experiente, especializado em Produções de Interoperabilidade.
                 Sua expertise reside na criação de Business Services e Produções capazes de receber e processar requisições de entrada com base emespecificações de API."",
            verbose=False,
            allow_delegation=True,
            tools=[generate_production_class_tool, generate_business_service_tool],
            llm=get_facilis_llm()
        )

    def create_bo_generator_agent():
        return Agent(
            role="Gerador de Business Operation IRIS",
            goal="Gerar classes de Business Operation IRIS formatadas corretamente a partir de especificações OpenAPI",
            backstory="""Você é um desenvolvedor InterSystems IRIS experiente, especializado em Produções de Interoperabilidade.
                 Sua expertise reside na criação de Business Operations capazes de enviar requisições para sistemas externos com base em especificações de API.""",
            verbose=False,
            allow_delegation=True,
            tools=[generate_business_operation_tool, generate_message_class_tool],
            llm=get_facilis_llm()
        )

    bs_generation_task = Task(
        description="Gerar classes de Business Service com base nos endpoints OpenAPI",
        agent=bs_generator,
        expected_output="Definições de classes de Business Service do IRIS",
        context=[analysis_task]
    )

    bo_generation_task = Task(
        description="Gerar classes de Business Operation com base nos endpoints OpenAPI",
        agent=bo_generator,
        expected_output="Definições de classes de Business Operation do IRIS",
        context=[analysis_task]
    )

    class GenerateMessageClassTool(BaseTool):
        name: str = "generate_message_class"
        description: str = "Gerar uma classe de Mensagem IRIS"
        input_schema: Type[BaseModel] = GenerateMessageClassToolInput

        def _run(self, message_name: str, schema_info: Union[str, Dict[str, Any]]) -> str:
            writer = IRISClassWriter()
            try:
                if isinstance(schema_info, str):
                    try:
                        schema_dict = json.loads(schema_info)
                    except json.JSONDecodeError:
                        return "Error: Invalid JSON format for schema info"
                else:
                    schema_dict = schema_info

                class_content = writer.write_message_class(message_name, schema_dict)
                # Armazenar a classe gerada.
                writer.generated_classes[f"MSG.{message_name}"] = class_content
                return class_content
            except Exception as e:
                return f"Error generating message class: {str(e)}"

Depois que BS e BO fazem o que têm que fazer, é a hora do Agente de Produção brilhar! Este agente junta tudo para criar um ambiente de produção coeso.

Depois que tudo estiver configurado, o próximo na linha é o Agente de Validação. Este entra em cena para uma verificação final, garantindo que cada classe Iris esteja ok.

Em seguida, temos o Agente de Exportação e o Agente de Coleção. O Agente de Exportação gera os arquivos .cls, enquanto o Agente de Coleção reúne todos os nomes de arquivos. Tudo é passado para o importador, que compila tudo no InterSystems Iris.


    def create_exporter_agent():
        return Agent(
            role="Exportador de Classes IRIS",
            goal="Exportar e validar definições de classes IRIS para arquivos .cls adequados",
            backstory="""Você é um especialista em implantação InterSystems IRIS. Seu trabalho é garantir que as definições de classes IRIS geradas sejam devidamente exportadas como arquivos .cls válidos que
                possam ser importados diretamente para um ambiente IRIS.""",
            verbose=False,
            allow_delegation=False,
            tools=[export_iris_classes_tool, validate_iris_classes_tool],
            llm=get_facilis_llm()
        )
        
    def create_collector_agent():
        return Agent(
            role="Coletor de Classes IRIS",
            goal="Coletar todos os arquivos de classes IRIS gerados em uma coleção JSON",
            backstory="""Você é um especialista em sistema de arquivos responsável por reunir e
                organizar os arquivos de classes IRIS gerados em uma coleção estruturada.""",
            verbose=False,
            allow_delegation=False,
            tools=[CollectGeneratedFilesTool()],
            llm=get_facilis_llm()
        )

    export_task = Task(
        description="Exportar todas as classes IRIS geradas como arquivos .cls válidos",
        agent=exporter,
        expected_output="Arquivos .cls IRIS válidos salvos no diretório de saída",
        context=[bs_generation_task, bo_generation_task],
        input={
            "output_dir": "/home/irisowner/dev/output/iris_classes"  # Optional
        }
    )

    collection_task = Task(
        description="Coletar todos os arquivos de classes IRIS gerados em uma coleção JSON",
        agent=collector,
        expected_output="Coleção JSON de todos os arquivos .cls gerados",
        context=[export_task, validate_task],
        input={
            "directory": "./output/iris_classes"
        }
    )

Limitações e Desafios

Nosso projeto começou como um experimento empolgante, onde meus colegas mosqueteiros e eu almejávamos criar uma ferramenta totalmente automatizada usando agentes. Foi uma jornada selvagem! Nosso foco principal estava em integrações de API REST. É sempre uma alegria receber uma tarefa com uma especificação OpenAPI para integrar; no entanto, sistemas legados podem ser uma história completamente diferente. Pensamos que automatizar essas tarefas poderia ser incrivelmente útil. Mas toda aventura tem suas reviravoltas: Um dos maiores desafios foi instruir a IA a converter OpenAPI para Interoperabilidade Iris. Começamos com o modelo openAI GPT3.5-turbo, que em testes iniciais se mostrou difícil com depuração e prevenção de interrupções. A mudança para o Anthropic Claude 3.7 Sonnet mostrou melhores resultados para o grupo Gerador, mas não tanto para os Planejadores... Isso nos levou a dividir nossas configurações de ambiente, usando diferentes provedores de LLM para flexibilidade. Usamos GPT3.5-turbo para planejamento e Claude sonnet para geração, uma ótima combinação! Essa combinação funcionou bem, mas encontramos problemas com alucinações. A mudança para o GT4o melhorou os resultados, mas ainda enfrentamos alucinações na criação de classes Iris e, às vezes, especificações OpenAPI desnecessárias, como o renomado exemplo Pet Store OpenAPI. Nos divertimos muito aprendendo ao longo do caminho, e estou super animado com o futuro incrível nesta área, com inúmeras possibilidades!

1
0 42
Artigo Heloisa Paiva · Fev. 19, 2025 7m read


Olá!

Este artigo é uma pequena visão geral de uma ferramenta que ajuda a entender classes e sua estrutura dentro dos produtos InterSystems: do IRIS ao Caché, Ensemble e HealthShare.

Em resumo, ela visualiza uma classe ou um pacote inteiro, mostra as relações entre as classes e fornece todas as informações possíveis para desenvolvedores e líderes de equipe sem fazê-los ir ao Studio e examinar o código lá.

Se você está aprendendo os produtos InterSystems, revisando muitos projetos ou apenas interessado em algo novo nas soluções de tecnologia InterSystems - você é mais do que bem-vindo para ler a visão geral do ObjectScript Class Explorer!

0
0 63
InterSystems Oficial Danusa Calixto · jan 28, 2025

Já faz um tempo que não posto sobre o Embedded Git na Comunidade de Desenvolvedores, e gostaria de fornecer uma atualização sobre a enorme quantidade de trabalho que fizemos este ano e para onde estamos indo a seguir.

Contexto

Se você estiver construindo soluções no IRIS e quiser usar o Git, isso é ótimo! Basta usar o VSCode com um repositório git local e enviar suas alterações para o servidor - é muito fácil.

Mas e se:

0
0 32
Artigo Lealdo Flaminio · Jul. 31, 2024 6m read

Coleta de dados

Esse é um guia de instruções passo a passo para criar uma tarefa que coleta dados sobre a base InterSystems e as globais que contem (como se vê no App Open Exchange associado - encontre todo o código relacionado ali)

Termo de responsabilidade: Este software é meramente para fins de TESTE/DEMO. Este código não é suportado pela InterSystems como parte de nenhum produto. InterSystems o fornece como ferramenta de demonstração/teste para um produto e versão específicos. O usuário ou cliente é totalmente responsável pelo mantimento e teste deste software depois da entrega, e a InterSystems não terá nenhuma responsabilidade por erros ou mal uso deste código.

  1. Em primeiro lugar, importe o arquivo «DataCollection.xml» através do portal de administração e assegure que não há erros. Se houver, pode se tratar de uma questão de versões. Entre em contato com Ari Glikman em ari.glikman@intersystems.com para que os ajude a obter uma versão adequada para você. Ademais, assegure que está importando os dados no namespace cujos dados internos deseja coletar para sua inspeção.

  2. Uma vez finalizada a importação, você deve ver o pacote Sample/Muestra com vários subpacotes também.

image

Se um pacote de Sample/Muestra já está presente no seu servidor, então você deve ver os novos subpacotes junto com qualquer outra pasta que estava ali previamente.

  1. Agora é o momento de executar os testes unitários para assegurar-se que tudo funciona corretamente.

a. Crie uma pasta chamada Unit Tests que possa ser lida pelo seu Terminal InterSystems. Por exemplo, como eu tenho uma instalação local, cria uma pasta em meu disco C.

FolderStructure

b. Nesta pasta exportaremos agora a classee Sample.DBExpansion.Test.CaptureTest como arquivo xml.

image

c. No terminal, defina a global ^UnitTestRoot = “<< pasta onde está Unit Tests>>”.. Segundo o exemplo anterior, seria (não se esqueça que você deve estar no mesmo namespace onde você importou o pacote) C:\ (note que não é “C:\Unit Tests” !)

set ^UnitTestRoot = "C:\"

d. Por último, executamos os testes unitários. Faça isso executando a seguinte linha de código no terminal:

do ##class(Sample.DBExpansion.Test.TestManager).RunTest("Unit Tests", "/noload/nodelete")

Essencialmente estamos dizendo ao programa que execute todos os testes que se encontram na pasta C:\Unit Tests. Por hora, só temos um arquivo ali, que é o criado no passo 3.b.

A saída deve ser a seguinte

UnitTestOutput

Se não passarem todas os testes unitários, então o programa não está pronto para ser executado. Não continue com os passos seguintes até que obtenha uma saída que diga que todos os testes passaram.

  1. Felicidades! Agora é o momento de construir a tarefa. Para isso

a. Abra o portal de administração e vá a Operação de Sistema > Gerenciador de Tarefas > Nova tarefa

*Assegure que seu usuário tenha acesso ao namespace %SYS, se não a tarefa se executará, mas não coletará nenhum dado.

NewTask

Agora, há vários campos para completar acerca da tarefa que quer criar. Você deve escolher o namespace em que importou o pacote e dar um nome para a tarefa. Deverá dar uma descrição para futuras referências. O ideal é deixar a opção de verificação rápida sem marcar, isso significa que a tarefa se executará mais lentamente, mas coletará dados mais completos. Se demorar demais para executar (depende do tamanho que seja a base de dados e suas globais) , então talvez seja melhor marcar aqui e optar por uma tarefa mais rápida. HowManyGlobals indica quantos dados globais devem ser coletados: -1 indica todos os dados globais, e é a opção recomendada. Selecione Avançar, escolha com que frequência a tarefa deve ser executada e aperte em Finalizar.

Recording 2023-05-10 at 7 10 32 PM

b. Aparecerá o Calendário de Tarefas, onde poderá ver quando estão programadas todas as tarefas, incluindo a recém criada. Se, além disso, desejar executá-la agora, selecione Executar no lado direito.

Selecione o histórico de tarefas para assegurar que foi criada corretamente. Depois de executar a tarefa, você deve ver que também foi executada corretamente. Caso contrário, aparecerá um erro.

Esta tarefa criará duas tabelas:

Sample_DBExpansion_Data.DBAnalysisInfo.

Essa tabela vai armazenar dados sobre a própria base de dados. Nos referimos a isso como «metadatos». A informação que armazena pode ser vista na imagem que se segue. A FastFlag indicará a seleção escolhida em 4.a.

DBTable

Sample_DBExpansion_Data.GlobalAnalysisInfo

Essa irá conter a informação relativa às globais na base de dados. Observe que se há um nome de classe associado à global, o veremos aqui junto com seu tamanho. Por último, observe que o campo MetaDataID corresponde ao campo ID da tabela Sample_DBExpansion_Data.DBAnalysisInfo. Isso quer dizer que no momento em que se capturou a informação da base de dados, se capturou seu correspondente de informação global e compartilham esse número de identificação (são as globais da base de dados nesse momento). É uma forma de ver como evoluem no tempo as globais de uma base de dados e a própria base de dados.

GLOBALTABLE

  1. Em continuação, a interface de usuário um pouco mais bonita.

Recording_2023-05-23_at_2_03_45_PM_AdobeExpress

Mostra informação sobre a global e a base de dados que aparecem na tabela de uma maneira mais amigável. Há 3 gráficos: um que mostra o histórico dos dados, o segundo que mostra o histórico de tamanhos de uma global escolhida, seja através do menu ou de uma busca, e por último há uma visão geral de todos os tamanhos de globais. Na parte inferior, há uma tabela onde se introduz quantas globais se quer mostrar e as apresenta ordenadas por tamanho. A coluna %Change está realçada em amarelo para uma mudança mínima de tamanho, em verde para uma diminuição de tamanho e em vermelho para um aumento significativo de tamanho.

Você pode encontrar instruções passo a passo sobre como configurá-los aqui.

Se não te interessam os gráficos, continue com a análise de dados aqui.

Docker

Pré-requisitos

Assegure-se que tenha git e Docker desktop instalados.

Instalação

Clone/git pull o repositório em qualquer diretório local

$ git clone https://github.com/rcemper/PR_DataCollection.git
$ docker compose up -d && docker compose logs -f

Inicio do container Crie o diretório apropriado «/home/irisowner/dev/Unit Tests»
Defina ^UnitTestRoot = «/home/irisowner/dev/»

Para abrir o Terminal IRIS:

$ docker-compose exec iris iris session iris
USER>

ou utilizando WebTerminal.
http://localhost:42773/terminal/

Para acessar ao portal de administração do sistema IRIS http://localhost:42773/csp/sys/UtilHome.csp

Para acessar a UnitTestPortal http://localhost:42773/csp/sys/%25UnitTest.Portal.Indices.cls?$NAMESPACE=USUARIO

0
0 47
Artigo Heloisa Paiva · Jul. 23, 2024 8m read

image

Olá Comunidade,

Nesse artigo, demonstrarei os seguintes passos para criar seu próprio chatbot utilizando spaCy (spaCy é uma biblioteca de software de código aberto para o processamento avançado de linguagem natural, escrita nas linguagens de programação Python e Cython):

  • Passo 1: Instalar as livrarias necessárias

  • Passo 2: Criar o arquivo de padrões e respostas

  • Passo 3: Treinar o modelo

  • Passo 4: Criar uma aplicação ChatBot baseada no modelo treinado

Comecemos

0
0 104
Artigo Heloisa Paiva · Jul. 10, 2024 1m read

Por que usá-la?

Esse app oferece uma interface fácil para analisar armazenamento:

  • Filtro por base de dado (namespace), nome da global, tamanho utilizado ou tamanho alocado;
  • Veja a soma dos tamanhos usado e alocado para os filtros aplicados;
  • Exporte a tabela para JSON, CSV, ou XML.

Como usar

Siga as instruções no arquivo README do repositório GitHub e configure as definições para conectar à sua instância.

Como adaptar às suas necessidades

0
0 45
Artigo Heloisa Paiva · Jun. 30, 2024 7m read

Por que conectar Flask com InterSystems IRIS?

A primeira coisa que vem à mente quando pensamos sobre a combinação de Flask com IRIS é um portal para interagir com seus clientes e parceiros. Um bom exemplo seria um website para pacientes acessarem seus exames clínicos. É claro, nesse caso seria necessário uma boa camada de segurança, que nós não cobrimos no último artigo. No enteando, podemos adicioná-la sem esforços com o Werkzeug, por exemplo.

0
0 64
Artigo Danusa Calixto · Abr. 4, 2024 12m read

Olá, Desenvolvedores!

Hoje quero falar sobre um assunto que já me deu trabalho. Tenho certeza de que isso deve ter acontecido com muitos de vocês (o chamado "gargalo"). Como esse é um tema amplo, este artigo focará apenas em identificar solicitações HTTP recebidas que podem estar causando problemas de lentidão. Também disponibilizarei uma pequena ferramenta que desenvolvi para ajudar a identificá-las.

Nosso software está cada vez mais complexo, processando um grande número de solicitações de diferentes origens, seja aplicativos de front-end ou back-end de terceiros. Para garantir um desempenho ideal, é fundamental ter um sistema de registro capaz de obter algumas medições importantes, como tempo de resposta, número de referências globais e número de linhas de código executadas para cada resposta HTTP. Como parte do meu trabalho, participo do desenvolvimento de software EMR e da análise de incidentes.  Como a carga do usuário vem principalmente de solicitações HTTP (API REST ou aplicativo CSP), a necessidade desse tipo de medição quando ocorrem problemas generalizados de lentidão se tornou óbvia.

Medição de tempo de resposta

Um dos elementos mais relevantes para avaliar o desempenho de um aplicativo é o tempo de resposta. Cada solicitação precisa ser respondida dentro de um prazo razoável para fornecer uma experiência satisfatória ao usuário. Por isso que, ao registrar o tempo de resposta de cada solicitação, um sistema de registro ajuda a identificar o desempenho ruim. Também podemos usar essas informações para identificar quais APIs ou CSPs são mais lentos a fim de otimizá-los e aumentar a execução geral do aplicativo​.

Número de referências globais

Embora o tempo de resposta seja uma característica essencial, também não devemos negligenciar o número de referências globais. Devemos lembrar que o acesso ao disco também costuma ser uma operação cara em termos de tempo de execução. No entanto, a eficiência do cache IRIS pode mascarar esse problema. Quero dizer com isso que, se muitas referências globais em cache forem acessadas simultaneamente, o tempo de resposta será excelente. Ainda assim, o desempenho cai consideravelmente assim que os dados acessados vêm de fora do cache. Em outras palavras, em um sistema onde são feitas várias solicitações ao mesmo tempo, o uso excessivo do acesso ao disco pode causar uma lentidão considerável. Um sistema de registro que mede referências de acesso global para cada solicitação também nos permite detectar solicitações HTTP que solicitam recursos em excesso. Ao identificar problemas desse tipo, os desenvolvedores podem fazer alterações para minimizar esse acesso (adicionando índices, otimizando consultas SQL, mudando a lógica etc.)

Número de linhas de código executadas

Contar o número de linhas de código executadas para cada solicitação nos oferece uma medida da complexidade e magnitude das operações realizadas. Essa medição nos ajuda a identificar consultas que executam muitas linhas de código, o que pode indicar partes do código que precisam de otimização. Na maioria dos casos, o problema está no número de referências globais. Porém, caso uma parte complexa do código seja apenas a manipulação de dados de memória com pouco acesso ao banco de dados, essa medição permitirá destacá-la (por exemplo, se houver um problema com loops).

Detecção de anomalias

Um registro do sistema também pode ser usado para detectar anomalias no desempenho da consulta de resposta. Ao registrar essas medições, é possível identificar solicitações fora do comum. Por exemplo, se uma consulta que costuma ser executada rapidamente de repente começa a demorar mais ou a acessar o disco em excesso, pode haver um problema que exige atenção imediata (como um maior tempo de resposta após a atualização de um aplicativo). Lembre-se de que a detecção precoce de anomalias nos ajuda a resolver problemas de desempenho rapidamente e garante uma boa experiência do usuário.

Pacote web-timing-logger

Recentemente, desenvolvi uma pequena ferramenta para a comunidade que nos permite registrar todas as solicitações HTTP recebidas. Se você tiver interesse, ela está disponível no Open Exchange. Essa ferramenta registra especialmente as principais métricas discutidas neste artigo: número de linhas de código executadas, número de referências globais e tempo de resposta. Ela também registra algumas informações sobre o autor da chamada que podem ser úteis para depuração:

  • Data e hora.
  • O usuário conectado.
  • Endereço IP do autor da chamada.
  • URL.
  • Namespace de execução.
  • Web app.
  • Nome da página (se aplicável).
  • URL sem parâmetros.

 

Além disso, também oferece a capacidade de integrar métricas personalizadas com SAM ("/api/monitor"), que permite incorporá-las no Prometheus e criar um painel de controle com o Grafana.
Há uma série de dados por web app, página ou rota (se for um aplicativo REST) ​​agregado por dia e quarto de hora:

  • Total de acessos: número de solicitações recebidas.
  • Tempo total: tempo de resposta cumulativa para todas as solicitações.
  • Tempo máximo: tempo de resposta mais lento.
  • Tempo média: tempo médio de resposta.

As mesmas métricas também estão disponíveis para referências globais e linhas de código executadas.

                                                                                                   Fichier:Prometheus software logo.svg — Wikipédia

Abaixo você pode ver um exemplo com as métricas ativadas nos web apps "/api/monitor/" e "/csp/sys/exp/":

webmeasure_average_gloref{id="/api/monitor/"} 903.5227272727272727
webmeasure_average_gloref{id="/api/monitor/metrics"} 903.5227272727272727
webmeasure_average_gloref{id="/csp/sys/exp/"} 1853.6875
webmeasure_average_gloref{id="/csp/sys/exp/%CSP.Broker.cls"} 1242.933333333333333
webmeasure_average_gloref{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 11015
webmeasure_average_gloref_current_quarter{id="/api/monitor/"} 903.5227272727272727
webmeasure_average_gloref_current_quarter{id="/api/monitor/metrics"} 903.5227272727272727
webmeasure_average_gloref_current_quarter{id="/csp/sys/exp/"} 1853.6875
webmeasure_average_gloref_current_quarter{id="/csp/sys/exp/%CSP.Broker.cls"} 1242.933333333333333
webmeasure_average_gloref_current_quarter{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 11015
webmeasure_average_lines{id="/api/monitor/"} 29365.5
webmeasure_average_lines{id="/api/monitor/metrics"} 29365.5
webmeasure_average_lines{id="/csp/sys/exp/"} 19415.5
webmeasure_average_lines{id="/csp/sys/exp/%CSP.Broker.cls"} 11570.73333333333333
webmeasure_average_lines{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 137087
webmeasure_average_lines_current_quarter{id="/api/monitor/"} 29365.5
webmeasure_average_lines_current_quarter{id="/api/monitor/metrics"} 29365.5
webmeasure_average_lines_current_quarter{id="/csp/sys/exp/"} 19415.5
webmeasure_average_lines_current_quarter{id="/csp/sys/exp/%CSP.Broker.cls"} 11570.73333333333333
webmeasure_average_lines_current_quarter{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 137087
webmeasure_average_timing_in_ms{id="/api/monitor/"} 27.27256818181818182
webmeasure_average_timing_in_ms{id="/api/monitor/metrics"} 27.27256818181818182
webmeasure_average_timing_in_ms{id="/csp/sys/exp/"} 16.6
webmeasure_average_timing_in_ms{id="/csp/sys/exp/%CSP.Broker.cls"} 9.94633333333333333
webmeasure_average_timing_in_ms{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 116.405
webmeasure_average_timing_in_ms_current_quarter{id="/api/monitor/"} 27.27256818181818182
webmeasure_average_timing_in_ms_current_quarter{id="/api/monitor/metrics"} 27.27256818181818182
webmeasure_average_timing_in_ms_current_quarter{id="/csp/sys/exp/"} 16.6
webmeasure_average_timing_in_ms_current_quarter{id="/csp/sys/exp/%CSP.Broker.cls"} 9.94633333333333333
webmeasure_average_timing_in_ms_current_quarter{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 116.405
webmeasure_max_lines{id="/api/monitor/"} 29498
webmeasure_max_lines{id="/api/monitor/metrics"} 29498
webmeasure_max_lines{id="/csp/sys/exp/"} 137087
webmeasure_max_lines{id="/csp/sys/exp/%CSP.Broker.cls"} 45208
webmeasure_max_lines{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 137087
webmeasure_max_lines_current_quarter{id="/api/monitor/"} 29498
webmeasure_max_lines_current_quarter{id="/api/monitor/metrics"} 29498
webmeasure_max_lines_current_quarter{id="/csp/sys/exp/"} 137087
webmeasure_max_lines_current_quarter{id="/csp/sys/exp/%CSP.Broker.cls"} 45208
webmeasure_max_lines_current_quarter{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 137087
webmeasure_max_timing{id="/api/monitor/"} 40.783
webmeasure_max_timing{id="/api/monitor/metrics"} 40.783
webmeasure_max_timing{id="/csp/sys/exp/"} 116.405
webmeasure_max_timing{id="/csp/sys/exp/%CSP.Broker.cls"} 66.458
webmeasure_max_timing{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 116.405
webmeasure_max_timing_current_quarter{id="/api/monitor/"} 40.783
webmeasure_max_timing_current_quarter{id="/api/monitor/metrics"} 40.783
webmeasure_max_timing_current_quarter{id="/csp/sys/exp/"} 116.405
webmeasure_max_timing_current_quarter{id="/csp/sys/exp/%CSP.Broker.cls"} 66.458
webmeasure_max_timing_current_quarter{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 116.405
webmeasure_total_gloref{id="/api/monitor/"} 39755
webmeasure_total_gloref{id="/api/monitor/metrics"} 39755
webmeasure_total_gloref{id="/csp/sys/exp/"} 29659
webmeasure_total_gloref{id="/csp/sys/exp/%CSP.Broker.cls"} 18644
webmeasure_total_gloref{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 11015
webmeasure_total_gloref_current_quarter{id="/api/monitor/"} 39755
webmeasure_total_gloref_current_quarter{id="/api/monitor/metrics"} 39755
webmeasure_total_gloref_current_quarter{id="/csp/sys/exp/"} 29659
webmeasure_total_gloref_current_quarter{id="/csp/sys/exp/%CSP.Broker.cls"} 18644
webmeasure_total_gloref_current_quarter{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 11015
webmeasure_total_hit{id="/api/monitor/"} 44
webmeasure_total_hit{id="/api/monitor/metrics"} 44
webmeasure_total_hit{id="/csp/sys/exp/"} 16
webmeasure_total_hit{id="/csp/sys/exp/%CSP.Broker.cls"} 15
webmeasure_total_hit{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 1
webmeasure_total_hit_current_quarter{id="/api/monitor/"} 44
webmeasure_total_hit_current_quarter{id="/api/monitor/metrics"} 44
webmeasure_total_hit_current_quarter{id="/csp/sys/exp/"} 16
webmeasure_total_hit_current_quarter{id="/csp/sys/exp/%CSP.Broker.cls"} 15
webmeasure_total_hit_current_quarter{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 1
webmeasure_total_lines{id="/api/monitor/"} 1292082
webmeasure_total_lines{id="/api/monitor/metrics"} 1292082
webmeasure_total_lines{id="/csp/sys/exp/"} 310648
webmeasure_total_lines{id="/csp/sys/exp/%CSP.Broker.cls"} 173561
webmeasure_total_lines{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 137087
webmeasure_total_lines_current_quarter{id="/api/monitor/"} 1292082
webmeasure_total_lines_current_quarter{id="/api/monitor/metrics"} 1292082
webmeasure_total_lines_current_quarter{id="/csp/sys/exp/"} 310648
webmeasure_total_lines_current_quarter{id="/csp/sys/exp/%CSP.Broker.cls"} 173561
webmeasure_total_lines_current_quarter{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 137087
webmeasure_total_timing_in_ms{id="/api/monitor/"} 1199.993
webmeasure_total_timing_in_ms{id="/api/monitor/metrics"} 1199.993
webmeasure_total_timing_in_ms{id="/csp/sys/exp/"} 265.6
webmeasure_total_timing_in_ms{id="/csp/sys/exp/%CSP.Broker.cls"} 149.195
webmeasure_total_timing_in_ms{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 116.405
webmeasure_total_timing_in_ms_current_quarter{id="/api/monitor/"} 1199.993
webmeasure_total_timing_in_ms_current_quarter{id="/api/monitor/metrics"} 1199.993
webmeasure_total_timing_in_ms_current_quarter{id="/csp/sys/exp/"} 265.6
webmeasure_total_timing_in_ms_current_quarter{id="/csp/sys/exp/%CSP.Broker.cls"} 149.195
webmeasure_total_timing_in_ms_current_quarter{id="/csp/sys/exp/%CSP.UI.Portal.SQL.Home.zen"} 116.405

Você deve ter notado que as métricas ilustradas acima são muito genéricas. Recomendo fortemente que você amplie e personalize suas métricas. É necessário para o monitoramento adequado dos aplicativos

Instalação usando ZPM

Se você deseja fazer uma instalação de teste e é usuário do Docker, recomendo que você revise esta seção para obter algumas informações práticas antes de passar para a próxima. O script de criação do contêiner configura o ambiente automaticamente.

A instalação é feita com o ZPM. Basta acessar o terminal IRIS e executar o seguinte:

zpm "install web-timing-logger”

Após a instalação, você precisa inicializar as configurações, então execute:

Do##class(dc.webtiming.Config).Initialize()

Por padrão, o log e as métricas de solicitações HTTP não estão ativos. Para ativá-los, siga as seguintes etapas:

Do##class(dc.webtiming.Config).SetLogEnabled(1)

Do##class(dc.webtiming.Config).SetMetricsEnabled(1)

Para SAM ("/api/monitor") expor métricas personalizadas, além de adicionar uma função ao web app /API/monitor, você deve registrar uma classe em SYS.Monitor.SAM.Config. Então, execute o seguinte comando:

Do##class(dc.webtiming.Config).ConfigureAPIMonitor()

Se você quiser usar esse utilitário em diversos web apps que são executados em diferentes namespaces, é fundamental mapear o pacote "dc.webtiming" e os globais "dc.webtiming*" em “%ALL”.  Para evitar fazer isso manualmente, use o método especificado abaixo:

Do##class(dc.webtiming.Config).AddToPercentAllNS()

Todas as ações mencionadas acima podem ser executadas em uma única linha com o próximo comando:

Do##class(dc.webtiming.Config).DefaultSetup()

Instalação usando Docker

O início com o Docker é clássico. Clone o repositório e inicie o contêiner:

git clone https://github.com/lscalese/iris-web-timing-logger.git
docker-compose up -d

Ativação em um web app

Agora que configuramos o sistema, ainda há um detalhe importante a ser configurado para que você possa registrar as medições. Para entender o que é preciso fazer, você deve saber como funciona o sistema.  Para acionar a medição e o registro, o web-timing-logger usa os eventos "OnStartRequest" e "OnEndRequest". Esses eventos são implementados na classe "dc.webtiming.CSPSessionEvents", que é uma subclasse de "%CSP.SessionEvents". Em seguida, cada web app precisa ser configurado com a classe de evento "dc.webtiming.CSPSessionEvents".

 

Se o seu web app já estiver usando outra classe de evento, não se preocupe! Basta adicionar as seguintes chamadas a essa classe:

No método OnStartRequest: 

Do##class(dc.webtiming.Events).OnStart()

e no método OnEndRequest:

Do##class(dc.webtiming.Events).OnEnd()

Isso adicionará a funcionalidade de medição e gravação às suas classes de evento existentes.

Faça essa configuração para todos os web apps que você deseja medir.

Se você tiver um sistema vazio e só quiser fazer alguns testes, use a configuração no web app /API/monitor. Como o acesso às métricas é estabelecido por uma chamada HTTP, elas também podem ser medidas para gerar logs.  Então, basta abrir seu navegador e acessar a página http://localhost:49165/api/monitor/metrics várias vezes (adapte com o número da sua porta). Você perceberá que as métricas "webmeasure" são alimentadas, e a tabela "dc_webtiming_log.Request" é preenchida com dados de solicitações HTTP:

SELECT *
FROM dc_webtiming_log.Request

Mesmo que Web-timing-logger facilite a identificação de pontos de entrada problemáticos em web apps, ele não oferece informações precisas sobre partes específicas do código que estão causando problemas.   Depois de identificar o ponto de entrada, você poderá usar outras ferramentas, como OEX ZProfile, desenvolvida por Dmitry Maslennikov. Ela pode realizar uma análise aprofundada do código que está sendo executado. Confira um artigo dedicado aqui.

Isso é tudo por hoje. É claro que poderíamos abordar outras coisas sobre o "web-timing-logger", como limpeza de logs, exemplo do painel de controle do Grafana ou até mesmo algumas consultas SQL interessantes. Espero que você tenha gostado do artigo e ele tenha dado ideias para o monitoramento dos seus aplicativos. Posso escrever uma continuação se você tiver interesse.

Até logo!

0
0 63
Artigo Danusa Calixto · jan 10, 2024 4m read

Alguns meses atrás, enfrentei um desafio importante: otimizar o tratamento da lógica de negócios em nosso aplicativo. Meu objetivo era extrair a lógica de negócios do código e passar para analistas. Lidar com várias regras pode resultar facilmente em um código desorganizado com uma infinidade de instruções "if", especialmente se o programador não entende a complexidade ciclomática. Esse código vira uma dor de cabeça para quem trabalha com ele — difícil de escrever, testar e desenvolver.

 
Spoiler
Para quem não tem interesse nos detalhes, observe a funcionalidade aqui e implante o aplicativo por conta própria.

https://openexchange.intersystems.com/package/iris-dmn

Depois de explorar várias opções, incluindo tentar ensinar Python a analistas 😀, me deparei com a técnica Decision Model Notation (DMN) para descrever a lógica de negócios. Ela se mostrou um sucesso — analistas poderiam agora articular a lógica de negócios sozinhos, reduzindo mais de mil linhas de código a apenas três + arquivo de descrição DMN.

Agora, vamos nos aprofundar na solução.

O DMN, concebido em 2015 pelos criadores do BPMN, interage bem com o último, mas também pode ser usado de maneira independente.

O principal conceito do DMN é a capacidade de gerenciar decisões semelhantes a outros aspectos dos seus aplicativos. Por exemplo, considere uma solução para calcular bônus — você pode modificá-la de maneira independente sem afetar outros elementos do aplicativo.

O DMN opera de duas formas:

  1. Analítica: compondo tabelas de solução em programas, programados por desenvolvedores.
  2. Automação: executando tabelas diretamente com o mecanismo do DMN, minimizando o risco de desenvolvedores interpretarem errado as especificações técnicas.

Portanto, nosso código é parecido com isto 

 

 Será uma tabela simples

Basicamente, é uma tabela em que os seguintes itens são definidos:

  1. Dados de entrada com seus tipos (strings, booleanos, inteiros, longos, duplos, datas).
  2. As linhas de regras aplicadas aos dados de entrada.
  3. A política de seleção de regras (política de hits) que determina a ordem e o número de regras acionadas (primeira bem-sucedida, única, todas as correspondentes etc.).
  4. A decisão final correspondente à linha de regras correspondente.

Em conclusão, o uso do Decision Model and Notation (DMN) oferece vários benefícios para a gestão da lógica de negócios:

  1. Clareza e transparência: o DMN oferece uma forma clara e transparente de expressar lógica de negócios complexa. Isso permite a representação visual das tabelas de decisão, facilitando para as partes interessas técnicas ou não entenderem e colaborarem nas regras de negócios.
  2. Separação de preocupações: ao extrair a lógica de negócios do código e representá-la no DMN, há uma clara separação de preocupações entre desenvolvedores e analistas de negócios. Os analistas podem articular e modificar as regras sem entrar nas complexidades do código, promovendo a colaboração e agilidade.
  3. Manutenção e flexibilidade: o DMN facilita a manutenção e atualização das regras de negócios. As mudanças na lógica de negócios podem ser implementadas ao ajustar as tabelas do DMN, sem precisar de grandes modificações de código. Isso otimiza a flexibilidade do sistema de se adaptar aos requisitos de negócios em constante mudança.
  4. Menor complexidade do código: utilizar o DMN ajuda a reduzir a complexidade do código. Em vez de incorporar uma lógica complicada de tomada de decisões na base de código, a lógica é encapsulada em um formato visual e estruturado, deixando a base de código mais administrável e compreensível.
  5. Mitigação de riscos: o uso do DMN, especialmente em cenários de tomada de decisão automatizados, mitiga o risco de má interpretação ou implementação das regras de negócios. O mecanismo do DMN garante que as decisões sejam executadas corretamente com base nas regras definidas, minimizando erros.
  6. Eficiência no desenvolvimento: os desenvolvedores podem focar em implementar a interação entre o aplicativo e o mecanismo do DMN, em vez de escrever e depurar lógica complexa de tomada de decisões. Isso pode levar a ciclos de desenvolvimento mais rápidos e menor tempo até o mercado para aplicativos.

E sim, depois de tudo isso, você pode usar seus esquemas do DMN com os dados armazenados no seu banco de dados do IRIS - https://openexchange.intersystems.com/package/iris-dmn

Se você tiver interesse em saber mais sobre o DMN, a linguagem FEEL e o motivo pelo qual a solução foi criada em JAVA, envie suas perguntas, vou responder nos comentários em mais detalhes

Informações adicionais sobre o DMN 

https://docs.drools.org/latest/drools-docs/drools/DMN/index.html  - a documentação mais detalhada

https://sandbox.kie.org/ - sandbox online onde você tentar desenhar seu próprio diagrama 

https://learn-dmn-in-15-minutes.com/ - tutorial interativo

0
0 101
Artigo Danusa Calixto · Dez. 26, 2023 8m read

 

A inteligência artificial não é limitada apenas a gerar imagens por texto com instruções ou criar narrativas com direções simples.

Você também pode criar variações de uma foto ou incluir um plano de fundo especial a um já existente.

Além disso, você pode obter a transcrição de áudio, não importando o idioma e a velocidade do falante.

Então, vamos analisar como o gerenciamento de arquivos funciona.

O problema

Ao analisar as informações da OpenAI sobre os métodos que exigem um arquivo como valor de entrada, os parâmetros precisam ser fornecidos usando um multipart/form-data.

No IRIS, sabemos como criar uma chamada para um método POST usando conteúdo JSON. No entanto, nesse caso, usar um parâmetro com o conteúdo do arquivo no formato Base64 não será prático.

Para incluir o conteúdo do arquivo em um multipart/form-data, você precisa usar a classe %Net.MIMEPart.

Para incluir um arquivo na nossa chamada, você deve criar um cabeçalho Content-Disposition com o objeto de classe %Net.MIMEPart

set content = ##class(%Net.MIMEPart).%New()
set contentDisposition = "form-data; name="_$CHAR(34)_"image"_$CHAR(34)
set contentDisposition = contentDisposition_"; filename="_$CHAR(34)_fileName_$CHAR(34)
do content.SetHeader("Content-Disposition",contentDisposition)

Como utilizamos uma classe de Solicitação para reter os valores do nosso processo, precisamos converter o conteúdo em Base64 em um stream que constituirá o Corpo do nosso conteúdo.

Podemos operar o utilitário StreamUtils para converter o Base64 em um Stream.

Observação: a variável "pImage" contém a string Base64 do conteúdo do arquivo.

Do##class(HS.Util.StreamUtils).Base64Encode(pImage, .tStream)
Set content.Body = tStream

Ainda assim, há um truque melhor que tive a sorte de aprender com um especialista da InterSystems no Global Summit 2023. Ele me ensinou que a execução é mais eficaz que StreamUtils, que, no final, tem um loop que lê a String e registra no Stream.

Essa solução é tão simples quanto usar um JSON e fazer o Get que o converte em um Stream.

set contentfile = {}
set contentfile.file = pImage
set content.Body = contentfile.%Get("file",,"stream<base64")

Depois de incluir todos os parâmetros necessários na chamada, podemos finalmente criar uma nova classe MIMEPart para envolver as partes.

Set rootMIME = ##class(%Net.MIMEPart).%New()
do rootMIME.Parts.Insert(content)
set writer = ##class(%Net.MIMEWriter).%New()
set tSC = writer.OutputToStream(tHttpRequest.EntityBody)
set tSC = writer.WriteMIMEBody(rootMIME)
Set tContentType = "multipart/form-data; boundary="_rootMIME.Boundary
set tSC = ..Adapter.SendFormDataArray(.tHttpResponse, "POST", tHttpRequest,,,url)

É assim que enviamos o conteúdo do arquivo para o método que precisamos na OpenAI.

Arquivos de imagem

O método de imagem permite enviar uma imagem e realizar uma variação. Como todas as ilustrações precisam estar no formato PNG, quando indicamos o conteúdo do arquivo no formato Base64, o nome do arquivo é gerado aleatoriamente com a extensão PNG.

Este é um exemplo de como isso altera uma foto.

OriginalVariação

Como você pode ver, o programa interpretou as instruções da sua própria maneira.

Ele decidiu que o logotipo da empresa era um círculo, então o substituiu por outro. Ele também reconheceu que o escritório tinha uma porta de vidro e a substituiu por outra, mas com uma parede de tijolos agora.

Além disso, ele modificou a cor da camisa e mudou a posição dos braços do homem.

Além disso, a OpenIA permite que você edite uma imagem ao fornecer uma máscara com a área em que deseja inserir o conteúdo indicado no prompt.

Utilizando a mesma imagem, apliquei uma máscara que removeu o plano de fundo da imagem.

OriginalMáscara

Quando pedi para me transportar para uma praia jamaicana, obtive o seguinte resultado:

Agora, você pode se gabar das suas férias na próxima vez que encontrar seus amigos e familiares 😊

Imagem

Endpoint: POST https://api.openai.com/v1/images/variations

Isso permite que você crie uma modificação de uma imagem existente. Como não é necessário um prompt indicando as alterações desejadas, temos que confiar no gosto da IA em como ela interpretaria essa imagem. Além disso, é possível definir o tamanho e a forma como queremos que o resultado seja retornado, por exemplo, através de um link ou conteúdo em Base64.

Os parâmetros de entrada seriam os mencionados abaixo:

  • image: obrigatório
  • Aqui, você menciona o arquivo de imagem que deseja transformar.
  • n: opcional. Padrão 1
  • Nessa área, você determina o número máximo de imagens geradas. (Use números entre 1 e 10).
  • size: opcional. Padrão 1024x1024
  • Esse parâmetro caracteriza o tamanho da imagem gerada. O valor precisa ser "256x256", "512x512" ou "1024x1024".
  • response_format: opcional. Por padrão, é "url"
  • Esse elemento se refere ao formato desejado para retornar as imagens geradas. Os valores devem ser "url" ou "b64_json".

Endpoint: POST https://api.openai.com/v1/images/edits

Ele deixa você modificar uma imagem existente que, com base no arquivo de máscara, criará uma imagem de acordo com o prompt. Além disso, podemos especificar as dimensões e a forma como o resultado deve ser retornado, por exemplo, através de um link ou conteúdo em Base64.

Os parâmetros de entrada devem ser os seguintes:

  • image: obrigatório
  • Aqui, você menciona o arquivo de imagem que deseja alterar.
  • mask: obrigatório
  • Essa parte é relacionada ao arquivo de imagem da máscara que deve ser aplicada.
  • n: opcional. Padrão 1
  • Nessa área, você determina o número máximo de imagens geradas. (Use números entre 1 e 10).
  • size: opcional. Padrão 1024x1024
  • Esse parâmetro caracteriza o tamanho da imagem gerada. O valor precisa ser "256x256", "512x512" ou "1024x1024".
  • response_format: opcional. Por padrão, é "url"
  • Esse elemento se refere ao formato desejado para retornar as imagens geradas. Os valores devem ser "url" ou "b64_json".

Arquivos de áudio

As imagens não são os únicos arquivos gerenciados pela OpenAI. Também podemos usar arquivos de áudio para obter uma transcrição ou tradução da gravação fornecida.

Esse método usa o modelo Whisper, que permite diferenciar nomes próprios, marcas e gírias para oferecer transcrição e tradução corretas. Por exemplo, falar sobre "micromachine" como uma marca não é o mesmo que traduzir "micromachines" como um substantivo comum para o espanhol.

O exemplo a seguir é a transcrição de um comercial bem conhecido dos anos 80:

<iframe allowfullscreen="" frameborder="0" height="360" src="https://www.youtube.com/embed/zLP6oT3uqV8" width="640"></iframe>

Portanto, ao instruir o Whisper a fazer uma transcrição do áudio, o resultado é o seguinte:

{
    "text": "This is the Micromachine Man presenting the most midget miniature motorcade of micromachines. 
Each one has dramatic details, terrific trim, precision paint jobs, plus incredible micromachine pocket playsets. 
There's a police station, fire station, restaurant, service station, and more. Perfect pocket portables to take anyplace. 
And there are many miniature playsets to play with and each one comes with its own special edition micromachine vehicle and 
fun fantastic features that miraculously move. Raise the boat lift at the airport, marina, man the gun turret at 
the army base, clean your car at the car wash, raise the toll bridge. And these playsets fit together to form a micromachine world.
Micromachine pocket playsets, so tremendously tiny, so perfectly precise, so dazzlingly detailed, you'll want to pocket them all.
Micromachines and micromachine pocket playsets sold separately from Galoob. The smaller they are, the better they are."
}

Incrível! Você não acha?

O resultado acima mencionado é possível devido ao treinamento que o modelo Whisper recebeu. Podemos ver algumas informações sobre isso no diagrama a seguir oferecido pela página da OpenAI.

 

Confira mais informações em https://openai.com/research/whisper

Lembre-se de que é fundamental informar ao programa o nome do arquivo, porque o serviço precisa saber o tipo de arquivo que está processando (por exemplo, WAV, MP3, OGG etc.).

Como só incluímos o conteúdo em Base64 na nossa chamada, também precisamos indicar a extensão do arquivo para criar o nome do arquivo com texto aleatório e a extensão sugerida.

Por exemplo, a mensagem St.OpenAi.Msg.Audio.AudioRequest tem a propriedade "type" para revelar o tipo de áudio: MP3, OGG, WAV, FLAC etc.

Endpoint: https://api.openai.com/v1/audio/transcriptions

Esse método deixa você transcrever o conteúdo de áudio no idioma do áudio.

Os parâmetros de entrada devem ser os seguintes:

  • file: obrigatório
  • Aqui, você especifica o arquivo de áudio que deseja transcrever (não o nome do arquivo). Os seguintes formatos são compatíveis: FLAC, MP3, MP4, MPEG, MPGA, M4A, OGG, WAV ou WEBM
  • model: obrigatório.
  • O modelo que será usado para fazer a transcrição. Por enquanto, somente "whisper-1" está disponível
  • language: opcional. Por padrão, é o idioma do áudio.
  • Se indicado, de acordo com o ISO-639-1, melhorará a precisão e latência.
  • prompt: opcional.
  • É um texto opcional para orientar o estilo do modelo ou continuar o segmento de áudio anterior. A mensagem aqui deve corresponder ao idioma do áudio.
  • response_format. Opcional. Por padrão, é "json".
  • Nesta parte, você indica o formato da saída da transcrição. Use uma das seguintes opções: "json", "text", "verbose_json".
  • temperature: opcional. Por padrão, o valor é 0.
  • A temperatura de amostragem deve estar entre 0 e 1. Valores mais altos, como 0,8, deixam a saída mais aleatória, enquanto valores mais baixos, como 0,2, a deixam mais focada e determinística. Se definido como 0, o modelo usará a probabilidade logarítmica para aumentar a temperatura automaticamente até que sejam atingidos limites específicos.

Veja a documentação para esse método em https://platform.openai.com/docs/api-reference/audio/createTranscription<.

Endpoint: https://api.openai.com/v1/audio/translations

Esse método deixa você traduzir o conteúdo de áudio para o inglês.

Os parâmetros de entrada devem ser os seguintes:

  • file: obrigatório
  • É o arquivo de áudio que você deseja traduzir (não o nome do arquivo). Os seguintes formatos são compatíveis: FLAC, MP3, MP4, MPEG, MPGA, M4A, OGG, WAV ou WEBM
  • model: obrigatório.
  • Nesse campo, você digita o modelo que será utilizado para fazer a transcrição. Por enquanto, somente "whisper-1" está disponível.
  • prompt: opcional.
  • É um texto opcional para orientar o estilo do modelo ou continuar o segmento de áudio anterior. A mensagem aqui deve estar em inglês.
  • response_format. Opcional. Por padrão, é "json".
  • Aqui você determina o formato da saída da transcrição como uma das seguintes opções: "json", "text", "verbose_json".
  • temperature: opcional. Por padrão, o valor é 0.
  • A temperatura de amostragem fica entre 0 e 1. Valores mais altos, como 0,8, deixam a saída mais aleatória, enquanto valores mais baixos, como 0,2, a deixam mais focada e determinística. Se definido como 0, o modelo usará a probabilidade logarítmica para aumentar a temperatura automaticamente até que sejam atingidos limites específicos.

Veja a documentação para esse método em https://platform.openai.com/docs/api-reference/audio/createTranscription.

O que vem a seguir?

Como a OpenAI está em evolução contínua, a próxima iteração será o método para converter texto em áudio e alguns outros novos recursos.

Lembre-se de marcar o artigo com uma "curtida" se você gostou.

0
0 105
Artigo Danusa Calixto · Nov. 28, 2023 8m read

Olá, Comunidade,
Neste artigo, vou apresentar meu aplicativo iris-mlm-explainer

Esse aplicativo da Web se conecta ao InterSystems Cloud SQL para criar, treinar, validar e prever modelos de ML, fazer previsões e mostrar um painel com todos os modelos treinados e uma explicação sobre o funcionamento de um modelo de machine learning ajustado. O painel fornece plotagens interativas de desempenho do modelo, importância do recurso, contribuições do recurso para previsões individuais, plotagens de dependência parcial, valores SHAP (interação), visualização de árvores de decisões individuais etc.

Pré-requisitos

  • Você precisa ter uma conta no InterSystems Cloud SQL.
  • Você precisa ter o <a book="" en="" getting-started-installing-git="" git-scm.com="" https:="" v2="">Git</a> instalado localmente.
  • Você precisa ter o <a downloads="" https:="" www.python.org="">Python3</a> instalado localmente.  

Primeiros Passos

Vamos seguir as etapas abaixo para criar e visualizar o painel explicativo de um modelo:

  • Etapa 1 : fazer o git pull/clone do repositório

  • Etapa 2 : fazer login no portal de serviços do InterSystems Cloud SQL

    • Etapa 2.1 : adicionar e gerenciar arquivos
    • Etapa 2.2 : importar DDL e arquivos de dados
    • Etapa 2.3 : criar modelo
    • Etapa 2.4 : treinar modelo
    • Etapa 2.5 : validar modelo
  • Etapa 3 : ativar o ambiente virtual do Python

  • Etapa 4 : executar o aplicativo da Web para previsão

  • Etapa 5 : explorar e o painel explicativo

Etapa 1 : fazer o git pull/clone do repositório

Então, vamos começar com a primeira etapa

Crie uma pasta e faça o git pull/clone do repositório em qualquer diretório local

git clone https://github.com/mwaseem75/iris-mlm-explainer.git

 

Etapa 2 : fazer login no portal de serviços do InterSystems Cloud SQL

Faça login no InterSystems Cloud Service Portal
image

 

 

Selecione a implantação executada

image

 

Etapa 2.1 : adicionar e gerenciar arquivos

Clique em "Add and Manage Files" (Adicionar e gerenciar arquivos)

image

O repositório contém os arquivos USA_Housing_tables_DDL.sql(DDL para criar tabelas), USA_Housing_train.csv(dados de treinamento) e USA_Housing_validate.csv(para validação) na pasta de conjuntos de dados. Selecione o botão de upload para adicionar esses arquivos.

Adicionar arquivos

Etapa 2.2 : importar DDL e arquivos de dados

Clique em "Import files" (Importar arquivos), no botão de opção das declarações DDL ou DML e no botão "Next" (Próximo)

Importar DDL

Clique no botão de opção do Intersystems IRIS e em "Next"

IsIRIS

Selecione o arquivo USA_Housing_tables_DDL.sql e pressione o botão para importar arquivos

Importar arquivo DDL

Clique em "Import" na caixa de diálogo de confirmação para criar a tabela

confirmar importação

importação concluída

Clique nas ferramentas da Query em SQL para verificar se as tabelas foram criadas

conferir se as tabelas foram criadas

Importar arquivos de dados

Clique em "Import files" (Importar arquivos), no botão de opção dos dados CSV e no botão "Next" (Próximo)

csv1

Selecione o arquivo USA_Housing_train.csv e clique no botão "Next"

csv2

 

Selecione o arquivo USA_Housing_train.csv na lista suspensa, marque para importar o arquivo como linha de cabeçalho, selecione "Field names in header row match column names in selected table" (Os nomes dos campos na linha de cabeçalho correspondem aos nomes das colunas na tabela selecionada) e clique em "Import files"

csv3

Clique em "Import" na caixa de diálogo de confirmação

csv4

Confira se 4000 linhas foram atualizadas

csv5

Repita as mesmas etapas para importar o arquivo USA_Housing_validate.csv, que contém 1500 registros

csv6

Etapa 2.3 : criar modelo

Clique em "IntegratedML tools" (ferramentas do IntegratedML) e selecione "Create Panel" (Criar painel).

Insira "USAHousingPriceModel" no campo de nome do modelo, selecione a tabela "usa_housing_train" e "Price" no menu suspenso "Field to predict" (Campo para prever). Clique no botão "Create model" para criar o modelo

criar modelo

 

Etapa 2.4 : treinar modelo

Selecione "Train Panel" (Treinar painel), escolha "USAHousingPriceModel" na lista suspensa "Model to train" (Modelo a treinar) e insira "USAHousingPriceModel_t1" no campo de nome do modelo a treinar

TREINAR1

O modelo será treinado após a conclusão do status de execução

TREINAR2

 

Etapa 2.5 : validar modelo

Selecione "Validate Panel" (Validar painel), escolha "USAHousingPriceModel_t1" na lista suspensa "Trained model to validate" (Modelo treinado a validar), selecione "usa_houseing_validate" na lista suspensa "Table to validate model from" (Tabela para validar o modelo) e clique no botão "Validate model" (Validar modelo)

image

Clique em "Show validation metrics" para ver as métricas

mostrar validação

Clique no ícone de gráfico para ver o gráfico "Prediction VS Actual" (Previsão x Real)

gráfico de validação

 

Etapa 3 : ativar o ambiente virtual do Python

O repositório já contém uma pasta de ambiente virtual do python (venv) com as bibliotecas necessárias.

Tudo o que precisamos fazer é ativar o ambiente
No Unix ou MacOS:

$source venv/bin/activate

No Windows:

venv\scripts\activate

###Etapa 4 : definir parâmetros de conexão do InterSystems Cloud SQL

O repositório contém o arquivo config.py. Basta abrir e definir os parâmetros
image
Coloque os mesmos valores usados no InterSystems Cloud SQL
image

 

Etapa 4 : executar o aplicativo da Web para previsão

Execute o comando abaixo no ambiente virtual para iniciar nosso aplicativo principal

python app.py

image

Acesse http://127.0.0.1:5000/ para executar o aplicativo

image

Insira "Age of house" (Idade da casa), "No of rooms" (Nº de cômodos), "No of bedroom" (Nº de quartos) e "Area population" (População da área) para obter a previsão

image

Etapa 5 : explorar e o painel explicativo

Por fim, execute o comando abaixo no ambiente virtual para iniciar nosso aplicativo principal

python expdash.py

imageimage
image

Acesse http://localhost:8050/ para executar o aplicativo
image

O aplicativo listará todos os modelos treinados com nosso "USAHousingPriceModel". Clique no hyperlink "Go to dashboard" (Acessar painel) para visualizar a explicação sobre o modelo

Importância dos recursos. Quais recursos tiveram o maior impacto?
image

Métricas quantitativas para o desempenho do modelo, Qual é a diferença entre o valor previsto e o observado?
image

Previsão e Como cada recurso contribuiu para a previsão?
image

Ajuste os valores dos recursos para mudar a previsão
image

Resumo Shap, Ordenamento dos recursos por valores shap
image

Resumo de interações, Ordenamento dos recursos por valor de interação shap
image

Árvores de decisões, Exibição de árvores de decisões individuais dentro do Random Forest
image

Obrigado

0
0 87
Artigo Danusa Calixto · Nov. 13, 2023 10m read

Olá, comunidade,

Neste artigo, vamos aprender sobre os tópicos listados abaixo:

  1. O que é o Docker?
  2. Alguns dos benefícios do Docker
  3. Como o Docker funciona?
  4. Imagem do Docker
  5. Contêiner Docker
  6. Repositório de imagens do Docker
  7. Repositório de imagens do Docker da InterSystems
  8. Instalação do Docker
  9. Comandos básicos do Docker
  10. Execução do IRIS Community Edition usando o docker
  11. GUI do Docker Desktop

Vamos começar.

##1. O que é o Docker?

Um guia do Docker para iniciantes — como criar seu primeiro aplicativo DockerO Docker é um software de virtualização que facilita muito o desenvolvimento e a implantação de aplicativos. O Docker faz isso ao empacotar o aplicativo em um contêiner que contém tudo o que o aplicativo precisa para ser executado, incluindo o código do aplicativo, as bibliotecas e dependências, o runtime e a configuração do ambiente.

O Docker é uma plataforma de conteinerização que permite aos desenvolvedores criar, implantar e executar aplicativos em um ambiente conteinerizado. O Docker fornece uma maneira de empacotar um aplicativo e as dependências dele em um único contêiner que pode ser executado em qualquer máquina compatível com o Docker. Isso faz com que seja fácil criar aplicativos leves e portáveis que podem ser implantados rapidamente e sem esforço.

##2. Alguns dos benefícios do Docker

Confira abaixo alguns dos benefícios de usar o Docker:

  • Portabilidade Os contêineres do Docker podem ser executados em qualquer máquina compatível com o Docker, facilitando a implantação de aplicativos em ambientes diferentes.
  • Consistência Ao empacotar um aplicativo e as dependências dele em um contêiner, o Docker garante a execução consistente do aplicativo, independentemente da infraestrutura subjacente.
  • Escalabilidade O Docker elimina as dificuldades de escalar aplicativos horizontalmente ao executar várias instâncias do mesmo contêiner.
  • Eficiência de recursos Os contêineres Docker são leves e exigem recursos mínimos, fazendo com que sejam ideais para a execução em infraestrutura na nuvem.
    • Segurança O Docker fornece um ambiente seguro e isolado para executar aplicativos, reduzindo o risco de conflitos com outros aplicativos ou com o sistema de host.

     

    3. Como o Docker funciona?

    O Docker cria um ambiente virtualizado para um aplicativo, chamado contêiner. Um contêiner é um pacote leve, independente e executável que incorpora tudo o que é necessário para executar o aplicativo, incluindo código, bibliotecas e dependências. Os contêineres são isolados do sistema de host. Portanto, eles podem ser executados em qualquer máquina compatível com o Docker, independentemente do hardware ou sistema operacional subjacente.

    Os contêineres são criados a partir de imagens que são modelos somente leitura que definem o aplicativo e as dependências dele. Essas imagens são armazenadas em um repositório central, chamado registro, como Docker Hub ou um registro privado. Os desenvolvedores podem criar imagens personalizadas por conta própria ou usar as pré-criadas do registro.

    Quando um contêiner é iniciado, ele é criado a partir de uma imagem e recebe o próprio sistema de arquivos isolado, rede e espaço de processo. Então, o contêiner consegue executar o aplicativo como se estivesse sendo executado em um servidor dedicado.

     

    4. Imagens do Docker

    Uma imagem do Docker é um pacote leve, independente e executável que retém o necessário para executar um aplicativo, incluindo o código, as bibliotecas e as dependências. As imagens do Docker são empregadas para criar e executar contêineres, que são ambientes isolados que podem ser utilizados para executar aplicativos.

    As imagens do Docker são criadas a partir de um Dockerfile, que é um arquivo de texto com um conjunto de instruções para criar a imagem. O Dockerfile especifica a imagem de base, o código e as dependências do aplicativo, as variáveis do ambiente e outras opções de configuração necessárias para criar a imagem.

    As imagens do Docker são armazenadas em um registro, como o Docker Hub ou um privado. Sempre que um contêiner é criado a partir de uma imagem, ele é executado como um processo separado na máquina host, isolado de outros processos e contêineres.

    As imagens do Docker podem ser usadas para implantar aplicativos de maneira consistente em várias plataformas diferentes. Elas facilitam empacotar, distribuir e implantar aplicativos, além de garantir que sejam executados da mesma maneira em todos os lugares.

    5. Contêineres Docker

    Uma instância em execução de uma imagem é um Contêiner, que, conforme mencionado acima, é um pacote leve, independente e executável que inclui tudo o que é necessário para executar um aplicativo, incluindo o código, as bibliotecas e as dependências.

    Um contêiner Docker fornece um ambiente isolado para executar um aplicativo, garantindo que tenha todos os recursos necessários para a execução adequada. Cada contêiner é executado como um processo separado na máquina host e tem seu próprio sistema de arquivos, rede e outros recursos.

    Os contêineres Docker são feitos para serem portáteis e fáceis de implantar. Eles podem ser executados em qualquer máquina que tenha o Docker instalado, independentemente do hardware ou sistema operacional subjacente. Os contêineres oferecem um ambiente consistente para executar aplicativos, tornando mais confortável mover aplicativos entre diferentes ambientes, como desenvolvimento, teste e produção.

    Os contêineres Docker podem ser gerenciados com a ajuda da CLI do Docker ou ferramentas do Docker como Docker Compose ou Kubernetes. Eles podem ser iniciados, parados, interrompidos e reinicializados conforme necessário. Eles também podem ser monitorados e gerenciados usando uma variedade de ferramentas e plataformas.

    Em geral, os contêineres Docker oferecem uma maneira flexível e escalável de empacotar e implantar aplicativos, deixando menos complicado gerenciar e escalar aplicativos complexos em diferentes ambientes e plataformas.

    6. Repositório de imagens do Docker

    O Docker hospeda um dos maiores Repositórios Docker, chamadoDocker Hub. É um sistema de armazenamento e distribuição para imagens do Docker. Ele fornece um repositório central para que desenvolvedores e organizações compartilhem e distribuam as imagens do Docker, tornando mais divertido criar, compartilhar e implantar aplicativos com o Docker.

    Com o Docker Hub, usuários e organizações podem armazenar e gerenciar as imagens do Docker, além de oferecer recursos como versionamento, inclusão de tags e colaboração. Os usuários podem pesquisar e baixar imagens do Docker Hub, assim como publicar as próprias imagens no registro.

    Além do registro público, o Docker Hub disponibiliza um registro privado para organizações que querem gerenciar as próprias imagens do Docker e garantir que sejam acessadas somente por usuários autorizados.

     

     

    7. Repositório de imagens do Docker da InterSystems

    Ao usar o recurso de pesquisa do Docker Hub, podemos encontrar imagens da InterSystems.

     

    8. Instalação do Docker

    Para usar o Docker, precisamos instalá-lo no nosso sistema. O Docker fornece pacotes de instalação para vários sistemas operacionais, incluindo Windows, macOS e Linux.Acesse osite do Docker.  Podemos baixar o pacote de instalação no site do Docker, executar o instalador e seguir os comandos para concluir a instalação.

    Depois de instalar o Docker Desktop, podemos usar a CLI (Interface de Linha de Comando) do Docker para gerenciar imagens, contêineres, redes e outros recursos do Docker.  

     

    9. Comandos básicos do Docker

    Vamos revisar alguns dos comandos básicos da CLI do docker. (Certifique-se de que está executando o Docker Desktop antes de usar os comandos indicados abaixo)

    9.1 Listar imagens (localmente)Podemos usar o comando docker image ls para listar todas as imagens do Docker disponíveis no nosso sistema. Veja como você pode usar esse comando:

    docker image ls


    Como você pode ver, atualmente, não temos nenhuma imagem localmente

    9.2 Extrair imagens do repositório do Docker

    Podemos usar o comandodocker pullpara baixar uma imagem do Docker a partir de um registro

    docker pull <image>

    Vamos extrair uma imagem da intersystemsdc/iris-community a partir do docker hub
    Nesse ponto, usamos o comando de lista para ver as imagens localmente
    Muito bem! A imagem da iris-community foi extraída com sucesso

    9.3 Remover imagem localmente
    Podemos usar o comando docker image rm  para excluir a imagem do nosso sistema

    docker image rm <image name>

    9.4 Listar todos os contêineres existentes (em execução ou não)
    Podemos utilizar o comando docker ps para listar os contêineres em execução

    docker ps 


    Conforme exibido na foto, nenhum contêiner está em execução no momento.

    9.5 Criar e iniciar o contêiner
    Podemos usar o comando docker run para criar e iniciar o contêiner

    docker run <image id/namge>

    Vamos criar e iniciar o contêiner da imagem da iris-community

    Aqui, -d ou --detach significa o seguinte: execute o comando em segundo plano e retorne o controle ao terminal.

    É hora de listar os contêineres em execução mais uma vez

    docker ps

    Podemos ver que nosso contêiner da imagem da iris-community está em execução agora.

    9.6 Parar um contêiner específico
    Podemos usar o comando docker stop para parar o contêiner em execução

    docker stop <container id/name>

    9.7 Iniciar um contêiner específicoPodemos usar o comandodocker start para iniciar um contêiner que foi interrompido antes no Docker. 

    docker start <container id/name>

    9.8 Reiniciar um contêiner específico

    Podemos usar o comando docker restart para parar e iniciar o contêiner em execução no Docker

    docker restart <container id/name>

    9.9 Remover um contêiner específico

    Podemos usar o comando docker rm para remover o contêiner interrompido

    docker rm <container id/name>

    9.10 Executar um comando dentro de um contêiner em execuçãoPodemos utilizar o comando docker exec para executar um comando dentro de um contêiner em execução. Isso pode ser útil ao realizar tarefas administrativas ou para fins de depuração.

    docker exec -it my-container sh

    Algumas das opções comuns para o comando docker exec são:

    • -i ou --interactive:  esse comando mantém o STDIN aberto mesmo se não estiver anexado, permitindo que você interaja com o contêiner.
    • -t ou --tty:  esse comando aloca um pseudo TTY ao comando, permitindo que você use os comandos do terminal dentro do contêiner.
    • -d ou --detach:  isso executa o comando em segundo plano e retorna o controle ao terminal.

    10. Execução do IRIS Community Edition usando o docker

    Utilize o comando listado abaixo para executar o contêiner ao implantar a imagem da iris-community

    docker run -d -p 52773:52773 intersystemsdc/iris-community

    Algumas opções comuns para o comandodocker execsão as seguintes:

    • -d: esse comando é usado para iniciar um novo contêiner Docker no modo detached, ou seja, o contêiner será executado em segundo plano e poderemos continuar usando o terminal para outras tarefas.
    • -p:  esse comando nos ajuda a publicar a porta de um contêiner na máquina host para possibilitar o acesso ao contêiner de fora da rede do Docker.

    Na ilustração abaixo, você pode ver a execução do IRIS no Docker.

     

    11. GUI do Docker Desktop

    O Docker desktop também tem uma GUI em que podemos utilizar todos os comandos mencionados acima de forma gráfica.

     

    Resumo

    O Docker é uma ferramenta poderosa que permite desenvolvedores e equipes de TI criar, implantar e executar aplicativos em um ambiente conteinerizado. Ao fornecer portabilidade, consistência, escalabilidade, eficiência de recursos e segurança, o Docker facilita a implantação de aplicativos em diferentes ambientes e infraestruturas. Com a crescente popularidade da conteinerização, o Docker está se tornando uma ferramenta essencial para o desenvolvimento e a implantação de software moderno.No próximo artigo, vamos aprender como usar um Docker file (usado para criar uma imagem do Docker), o Docker compose (um arquivo YAML que especifica as opções de configuração para cada contêiner no aplicativo) e o Docker volume (um mecanismo de armazenamento de dados persistente operado para compartilhar dados entre os contêineres Docker e a máquina host).

    Obrigado pela leitura!

    0
    0 179
    Artigo Danusa Calixto · Set. 16, 2023 9m read

    Olá, comunidade,

    No antigo anterior, aprendemos sobre os tópicos listados abaixo:

    1. O que é o Docker?
    2. Alguns dos benefícios do Docker
    3. Como o Docker funciona?
    4. Imagem do Docker
    5. Contêiner Docker
    6. Repositório de imagens do Docker
    7. Repositório de imagens do Docker da InterSystems
    8. Instalação do Docker
    9. Comandos básicos do Docker
    10. Execução do IRIS Community Edition usando o Docker
    11. GUI do Docker Desktop

    Neste artigo, vamos abordar os seguintes tópicos:

    1. Uso do arquivo do Docker Compose (um arquivo YAML)
    2. Uso do Docker file (usado para criar uma imagem do Docker)
    3. Uso do volume do Docker

    Vamos começar.

    1. Uso do arquivo do Docker Compose (

    um arquivo YAML)

    Docker Compose é uma ferramenta desenvolvida para ajudar a definir e compartilhar aplicativos de vários contêineres. Com o Compose, podemos criar um arquivo YAML para definir os serviços e, com um único comando, podemos mudar ou descartar tudo.

    Uma grande vantagem de usar o Compose é a capacidade de definir sua pilha de aplicativo em um arquivo e mantê-la na raiz do repositório do projeto. Você também pode permitir facilmente que outra pessoa contribua com seu projeto. Ela só precisaria clonar seu repositório e iniciar o app compose. 

    No artigo anterior, usamos o comando mencionado abaixo para criar e iniciar o contêiner com a imagem da comunidade da InterSystems:

    docker run -d -p 52773:52773 intersystemsdc/iris-community 

    Nesse ponto, vamos modificar esse comando e adicionar um nome de contêiner, mapear mais portas e definir a opção de reinicialização:

    docker run -d -p 52773:52773 -p 53773:53773 -p 1972:1972 --name iris --restart=always intersystemsdc/iris-community

    Deixe-me detalhar o comando mencionado acima para você:
    #docker run command to create and start the container
    docker run 
    #-d -an option used to start container in deattach mode
    -d 
    #-p -an option is used to map the ports
    -p 52773:52773 
    -p 53773:53773 
    -p 1972:1972 
    #name of the container
    --name iris 
    #set the restart option to always
    --restart=always 
    #base image
    intersystemsdc/iris-community
    

    Crie o arquivo Compose {#create-the-compose-file}

    Na pasta raiz, crie um arquivo chamado docker-compose.yml a e escreva os comandos mencionados acima conforme indicado abaixo:

    #specify docker-compose versionversion:'3.6'#services/container detailsservices:#Name of the container  iris:#Base Image    image:intersystemsdc/iris-community      
        #set restart option    restart:always#port mapping    ports:      -55036:1972      -55037:52773      -53773:53773

    O mapeamento do comando de execução do docker e um arquivo docker-compose são ilustrados abaixo:

    Um instantâneo do arquivo Docker-compose é demonstrado a seguir:

    Para executar o código do arquivo docker-compose, usaremos o comando docker-compose up:

    docker-compose up -d
    • -d ou --detach:  uma opção que executa o comando em segundo plano e retorna o controle ao terminal.  


    O contêiner é iniciado. Vamos executar o comando "docker ps" para listar os contêineres em execução

    Como você pode ver, obtemos o mesmo resultado com o arquivo docker-compose.

    Crie e inicie vários contêineres

    Com a ajuda do docker-compose, não só podemos executar vários contêineres, como também podemos organizar e adicionar mais comandos a ele.

    Por exemplo, no arquivo docker-compose a seguir, executamos o contêiner MongoDB junto com o contêiner iris:

    #specify docker-compose version
    version: '3.6'
    #services/container details
    services:
      #Name of the container
      iris:
        #Base Image
        image: intersystemsdc/iris-community      
        #set restart option
        restart: always
        #port mapping
        ports:
          - 55036:1972
          - 55037:52773
          - 53773:53773
      
      #start MongoDB container
      mongodb:
        image: mongo 
        ports:
        - 27017:27017 

    Vamos executar o comando docker-compose up


    Ambos os contêineres MongoDB e iris foram criados e iniciados agora.

    2. Docker file

    O Docker pode criar imagens automaticamente ao ler as instruções de um Dockerfile. Um Dockerfile é um documento de texto que contém todos os comandos que um usuário pode chamar na linha de comando para montar uma imagem. 

    Então, nossa primeira pergunta é simples. O que é um Dockerfile? É o que o Docker usa para criar a própria imagem. O Dockerfile é, basicamente, as instruções de como criar a imagem.

    A vantagem de um Dockerfile em comparação com apenas armazenar a imagem binária é que as criações automáticas garantem que você tenha a versão mais recente disponível. É algo bom em termos de segurança, porque você quer garantir que não está instalando software vulnerável.


    Comandos comuns do Dockerfile

    Confira abaixo alguns dos comandos do Docker mais usados. Observe que todos os comandos do docker precisam estar em letra maiúscula.

    ###FROM 

    O primeiro é o comando FROM, que informa no que a imagem foi baseada. É uma abordagem de várias camadas que deixa o Docker muito eficiente e poderoso. Nesse caso, foi usada a imagem do Docker da iris-community, que faz referência a um Dockerfile mais uma vez para automatizar o processo de criação.

    FROM intersystemsdc/iris-community

    WORKDIR

    Esse comando é usado para configurar um diretório de trabalho para copiar os arquivos.
    Por exemplo, o comando mencionado abaixo configurará /opt/irisbuild como o diretório de trabalho:  

    WORKDIR /opt/irisbuild

     

    COPY

    O comando COPY é tão simples quanto parece.  Ele copia arquivos para o contêiner.  
    Geralmente, copiamos arquivos de configuração personalizados, arquivos de código-fonte de aplicativos, arquivos de dados etc.

    #coping Installer.cls to a root of workdir. Don't miss the dot, here.COPY Installer.cls .
    #copy source files from src folder to src folder in workdir in the docker container.COPY src src
    #copy source files from data/fhir folder to fhirdata folder in the docker container.COPY data/fhir fhirdata

    ENV

    Isso define as variáveis de ambiente, que podem ser usadas no Dockerfile e em qualquer script que chamar.
    A instrução ENV define a &lt;key> da variável de ambiente para o valor &lt;value>

    ENV USER_ID "SYSTEM"ENV USER_PASSWORD "MANAGER"

    RUN

    O comando RUN é usado para executar comandos durante o processo de criação da imagem.

    #here we give the rights to irisowner user and group which are run IRIS.RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisapp   
    #start IRIS and run script in iris.script file RUN iris start IRIS \    
        && iris session IRIS < /tmp/iris.script

    USER 

    Por padrão, os contêineres são executados como raiz, o que dá a eles controle total do sistema host. Com a evolução da tecnologia de contêiner, mais opções padrão seguras podem ficar disponíveis. Por enquanto, exigir a raiz é perigoso para outras pessoas e pode não estar disponível em todos os ambientes. Sua imagem deve usar a instrução USER para especificar um usuário não raiz para os contêineres serem executados. Se o software não criar o próprio usuário, você pode criar um usuário e um grupo no Dockerfile.

    #here we switch user to a root to create a folder and copy files in docker.USER root 
    
    WORKDIR /opt/irisapp
    #switching user from root to irisowner, to copy filesUSER irisowner 
    
    COPY src src

    Para mais detalhes, leia a documentação oficial do Docker

    3. Volume do Docker

    Um volume do Docker é um sistema de arquivos independente totalmente gerenciado pelo Docker. Ele existe como um arquivo ou diretório padrão no host onde os dados persistem.

    O propósito de usar volumes do Docker é manter os dados fora do contêiner para disponibilizá-los para backup ou compartilhamento.

    Os volumes do Docker dependem do sistema de arquivos do Docker e são o método preferencial de dados persistentes para contêineres e serviços do Docker. Quando um contêiner é iniciado, o Docker carrega a camada da imagem somente leitura, adiciona uma camada leitura-escrita em cima da pilha de imagem e monta volumes no sistema de arquivos do contêiner.

    Usamos a sinalização -v ou --volume para que seja possível montar arquivos locais no contêiner.

    Os volumes são o mecanismo preferencial para dados persistentes gerados e usados por contêineres Docker. Enquanto as montagens bind dependem da estrutura do diretório e da SO da máquina host, os volumes são totalmente gerenciados pelo Docker. Os volumes têm vários benefícios em relação às montagens bind:

    • Os volumes são mais fáceis de fazer backup ou migrar do que as montagens bind.
    • Você pode gerenciar volumes usando os comandos da CLI do Docker ou a API Docker.
    • Os volumes funcionam tanto em contêineres do Linux quanto do Windows.
    • Os volumes podem ser compartilhados com segurança entre vários contêineres.
    • Os drivers dos volumes permite o armazenamento de volumes em hosts remotos ou provedores de nuvem, para criptografar o conteúdo dos volumes ou adicionar outra funcionalidade.
    • Novos volumes podem ter o conteúdo pré-preenchido por um contêiner.
    • Os volumes no Docker Desktop têm um desempenho muito superior em relação às montagens bind de hosts Mac e Windows.

    Além disso, os volumes geralmente são uma melhor opção do que os dados persistentes em uma camada de contêiner que pode ser escrita, porque um volume não aumenta o tamanho dos contêineres durante o uso. O conteúdo do volume também existe fora do ciclo de vida de um determinado contêiner.

    Volumes no host Docker

    Podemos mencionar volumes na seção de serviços do arquivo docker-compose.

    #specify docker-compose versionversion:'3.6'#services/container detailsservices:#Name of the container  iris:#Base Image    image:intersystemsdc/iris-community      
        #set restart option    restart:always#port mapping    ports:      -55036:1972      -55037:52773      -53773:53773#create a volume    volumes:      -./:/irisdev/app

    Criamos o volume irisdev/app.

     

    Resumo

    O Docker é uma ferramenta poderosa que permite desenvolvedores e equipes de TI criar, implantar e executar aplicativos em um ambiente conteinerizado. Ao fornecer portabilidade, consistência, escalabilidade, eficiência de recursos e segurança, o Docker facilita a implantação de aplicativos em diferentes ambientes e infraestruturas. Com a crescente popularidade da conteinerização, o Docker está se tornando uma ferramenta essencial para o desenvolvimento e a implantação de software moderno.Neste artigo, aprendemos a usar o Docker compose (um arquivo YAML que especifica as opções de configuração para cada contêiner no aplicativo), o Docker file (usado para criar uma imagem do Docker) e o Docker volume (um mecanismo de armazenamento de dados persistente operado para compartilhar dados entre os contêineres Docker e a máquina host).

    Obrigado pela leitura!

    0
    0 426
    Artigo Danusa Calixto · Ago. 18, 2023 2m read

    A InterSystems também lançou o IRIS como implantações em contêineres. Esta postagem demonstra como o InterSystems IRIS e os aplicativos que dependem do IRIS como um back-end podem ser empacotados em uma imagem e executados em outras máquinas em contêineres e como é simples fazer isso.

    Um contêiner executa imagens que possuem todos os executáveis, código binário, bibliotecas e arquivos de configuração necessários. E as imagens podem ser movidas de uma máquina para outra, e um repositório de imagens como o Docker Hub pode simplificar esse processo.

    Usei um aplicativo do Open Exchange para esta demonstração.

    **Vídeo da demonstração: **https://www.loom.com/share/93f9a760b5f54c0a8811b7a212387b9d

    A imagem para a Plataforma de Dados IRIS Community Edition pode ser encontrada no InterSystems Container Registry: https://containers.intersystems.com/contents

    Para usar uma instância em contêiner do IRIS em uma máquina host, ela precisa ser extraída durante o tempo de execução.

    Para isso, o Dockerfile precisa ter os seguintes comandos, conforme mostrado abaixo:

    Dockerfile

    ARG IMAGE=intersystemsdc/irishealth-community ARG IMAGE=intersystemsdc/iris-community ARG IMAGE=intersystemsdc/iris-community:preview FROM $IMAGE RUN iris start IRIS \  && iris merge IRIS /tmp/merge.cpf \  && iris stop IRIS quietly

    Esses são os comandos básicos que criam um Dockerfile escrito para construir uma imagem que possui instruções para o IRIS em contêiner.

    Também podem ser adicionados os comandos para executar a instalação de outras dependências necessárias para o aplicativo que está sendo executado com a instância em contêiner do IRIS.

    São fornecidos os comandos do Docker que marcam e enviam uma imagem que carrega a instância IRIS para o Docker Hub e, subsequentemente, extraem e executam essa imagem em outra máquina host.

    Comandos

    docker build -t image_name filepath docker tag image_name dockerhub_username/repository_name:tag_name docker push dockerhub_username/repository_name:tag_name

       

    Comandos

    docker pull dockerhub_username/repository_name:tag_name docker run --name test -p host_8080:52773 padhikar/irisincontainer:main

    Aplicativo usado na demonstração: https://openexchange.intersystems.com/package/iris-geo-map

    Criando imagens do InterSystems IRIS: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=ADOCK#ADOCK_iris_creating

    0
    0 65
    Artigo Claudio Devecchi · Jun. 20, 2023 4m read

    Neste artigo, vou compartilhar o tema que apresentamos no Global Summit 2023, na sessão Tech Exchange. Eu e @Rochael.Ribeiro.

    Nesta oportunidade, abordamos os seguintes tópicos, os quais iremos explorar neste artigo:

    • Ferramentas Open Exchange para o desenvolvimento rápido de APIs
    • Open Api Specification (OAS)
    • Maneira Tradicional versus Desenvolvimento Rápido
    • API Composta (Interoperabilidade)
    • Abordagens Spec-First ou Api-First
    • Governança e Monitoramento de Api's
    • Demonstração (vídeo)

    Ferramentas Open Exchange para o Desenvolvimento Rápido de APIs Rest

    4
    0 145
    Artigo Heloisa Paiva · Maio 29, 2023 10m read

    Programação e suas linguagens

    Ser um programador hoje em dia é basicamente uma versão nerd de ser um poliglota. Claro, a maioria de nós aqui na comunidade InterSystems "falamos ObjectScript". Entretando, eu acredito que essa não foi a primeira língua de muita gente. Por exemplo, eu nunca tinha ouvido falar nela antes de receber o treinamento apropriado na Innovatium.

    0
    0 140
    Artigo Heloisa Paiva · Maio 26, 2023 6m read

    Introdução

    Dentre as diversas soluções que desenvolvemos aqui na Innovatium,  um desafio comum é a necessidade de acesso ao tamanho das bases de dados. Entretanto, notei que isso não é algo tão trivial no IRIS. Esse tipo de informação é importante para manter um controle do fluxo de dados e do custo em GB's de um sistema a ser implementado. Contudo, o que realmente me chamou atenção é a necessidade dela para uma função muito importante: migrar para cloud. Afinal, quem não quer migrar seus sistemas para cloud hoje em dia, certo?

    0
    0 141
    Artigo Heloisa Paiva · Mar. 9, 2023 3m read

    Introdução

    Em alguns dos últimos artigos, eu falei sobre tipos entre IRIS e Python, e ficou claro que não é tão fácil acessar objetos de um lado pelo outro.

    Por sorte, o trabalho já foi feito para criar o SQLAlchemy-iris (clique no link para ver na Open Exchange), o que faz tudo muito mais fácil para o Python acessar os objetos do IRIS, e eu vou mostrar como começar.

    Obrigada @Dmitry Maslennikov !

    Instalando

    Para instalar, simplesmente abra seu terminal com acesso do administrador e digite

    pip install sqlalchemy-iris

     

    Isso também vai instalar os pré-requisitos, se necessário.

    Usando

    2
    0 1199