#Compatibilité

0 Abonnés · 5 Publications

La compatibilité est la capacité de deux systèmes à fonctionner ensemble sans devoir être modifiés pour y parvenir.

InterSystems officiel Adeline Icard · Avr 8, 2025

Résumé des alertes

Alert ID Produit et versions concernés Exigences explicites
DP-439207 Plateforme de données InterSystems IRIS® 2024.3 (AIX) Installations AIX utilisant le traitement JSON et les caractères Unicode non-Latin-1
DP-439280 InterSystems IRIS 2024.3 (conteneurs avec IntegratedML) Conteneurs IntegratedML utilisant TensorFlow

Détail des alertes

DP-439207 - Problème d'analyse JSON Unicode AIX

Un bug a été identifié dans InterSystems IRIS 2024.3.0 sur les instances AIX. Il affecte l'analyse des chaînes JSON Unicode. Ce problème survient lorsque la méthode %FromJSON() ou %FromJSONFile() analyse des chaînes contenant des caractères dont la valeur est inférieure à $CHAR(256) suivis de caractères Unicode dont la valeur est supérieure à $CHAR(255). Le processus de conversion transforme incorrectement les premiers caractères en $CHAR(0), ce qui entraîne une corruption silencieuse des données. Ce problème concerne uniquement la version AIX 2024.3 des produits suivants :

  • InterSystems IRIS
  • InterSystems IRIS for Health
  • HealthShare® Health Connect
0
0 24
Article Iryna Mykhailova · Avr 3, 2025 3m read

Introduction

Dans InterSystems IRIS 2024.3 et les versions ultérieures d'IRIS, le composant AutoML est désormais fourni sous forme de package Python distinct, installé après l'installation. Malheureusement, certaines versions récentes des packages Python sur lesquels AutoML s'appuie ont introduit des incompatibilités et peuvent entraîner des échecs lors de l'entraînement des modèles (instruction TRAIN MODEL). Si vous rencontrez une erreur mentionnant « TypeError » et l'argument de mot-clé « fit_params » ou « sklearn_tags », lisez la suite pour une solution rapide.

Cause principale

0
0 28
Article Guillaume Rongier · Fév 12, 2025 5m read

Cela fait longtemps que je n'ai pas écrit de post de mise à jour sur l'IoP.

image

Quelles sont les nouveautés depuis la publication de l'interface en ligne de commande de l'IoP?

Deux nouvelles fonctionnalités importantes ont été ajoutées à l'IoP:

  • Rebranding: le module grongier.pex a été renommé en iop pour refléter le nouveau nom du projet.
  • Support des opérations asynchrones: L'interface de programmation prend désormais en charge les fonctions asynchrones et les coroutines.

Rebranding

Le module grongier.pex a été renommé en iop pour refléter le nouveau nom du projet.

Le module grongier.pex est encore disponible pour des raisons de rétrocompatibilité, mais il sera supprimé à l'avenir.

Support des opérations asynchrones

L'IoP supporte les appels asynchrones depuis longtemps, mais il n'était pas possible d'utiliser les fonctions asynchrones et les coroutines directement dans l'IoP..

Avant d'aborder cette nouvelle fonctionnalité, je vais expliquer le fonctionnement des appels asynchrones dans InterSystems IRIS et présenter deux exemples d'utilisation des appels asynchrones dans l'IoP.

Appels asynchrones hérités

Examinons le fonctionnement des appels asynchrones hérités du passé:

from iop import BusinessProcess
from msg import MyMessage


class MyBP(BusinessProcess):

    def on_message(self, request):
        msg_one = MyMessage(message="Message1")
        msg_two = MyMessage(message="Message2")

        self.send_request_async("Python.MyBO", msg_one,completion_key="1")
        self.send_request_async("Python.MyBO", msg_two,completion_key="2")

    def on_response(self, request, response, call_request, call_response, completion_key):
        if completion_key == "1":
            self.response_one = call_response
        elif completion_key == "2":
            self.response_two = call_response

    def on_complete(self, request, response):
        self.log_info(f"Received response one: {self.response_one.message}")
        self.log_info(f"Received response two: {self.response_two.message}")

En fait, ils fonctionnent de la même manière que les appels asynchrones dans IRIS. La méthode send_request_async envoie une requête à une opération métier (Business Operation) et la méthode on_response est appelée lorsque la réponse est reçue.

Vous pouvez distinguer les réponses par le paramètre completion_key.

Envoi de plusieurs requête de synchronisation

Il ne s'agit pas vraiment d'une nouvelle fonctionnalité, mais il convient de mentionner qu'il est possible d'envoyer plusieurs requêtes de synchronisation en parallèle:

from iop import BusinessProcess
from msg import MyMessage


class MyMultiBP(BusinessProcess):

    def on_message(self, request):
        msg_one = MyMessage(message="Message1")
        msg_two = MyMessage(message="Message2")

        tuple_responses = self.send_multi_request_sync([("Python.MyMultiBO", msg_one),
                                                        ("Python.MyMultiBO", msg_two)])

        self.log_info("All requests have been processed")
        for target,request,response,status in tuple_responses:
            self.log_info(f"Received response: {response.message}")

Ici, nous envoyons deux requêtes à la même opération métier (Business Operation) en parallèle.

La réponse est un tuple contenant la cible, la requête, la réponse et le statut de chaque appel.

C'est très utile lorsque vous devez envoyer plusieurs requêtes et que vous ne vous souciez pas de l'ordre des réponses.

Fonctions asynchrones et coroutines

Voyons maintenant comment utiliser les fonctions asynchrones et les coroutines dans l'IoP:

import asyncio

from iop import BusinessProcess
from msg import MyMessage


class MyAsyncNGBP(BusinessProcess):

    def on_message(self, request):

        results = asyncio.run(self.await_response(request))

        for result in results:
            print(f"Received response: {result.message}")

    async def await_response(self, request):
        msg_one = MyMessage(message="Message1")
        msg_two = MyMessage(message="Message2")

        # utilisation d'asyncio.gather pour envoyer plusieurs requêtes de manière asynchrone
        # utilisation de la méthode send_request_async_ng
        tasks = [self.send_request_async_ng("Python.MyAsyncNGBO", msg_one),
                 self.send_request_async_ng("Python.MyAsyncNGBO", msg_two)]

        return await asyncio.gather(*tasks)

Dans cet exemple, nous envoyons plusieurs demandes à la même opération métier (Business Operation) en parallèle à l'aide de la méthode send_request_async_ng.

Si vous avez lu attentivement ce post jusqu'à ce point, veuillez ajouter le commentaire "Boomerang". C'est peut-être peu de choses pour vous, mais pour moi c'est très important. Je vous remercie!

La méthode await_response est une coroutine qui envoie plusieurs requêtes et attend que toutes les réponses soient reçues. Grâce à la fonction asyncio.gather, nous pouvons attendre que toutes les réponses soient reçues en parallèle.

Les avantages de l'utilisation des fonctions asynchrones et des coroutines sont les suivants :

  • Meilleures performances: vous pouvez envoyer plusieurs requêtes en parallèle.
  • Simplicité de lecture et de maintenance: vous pouvez utiliser le mot-clé await pour attendre les réponses.
  • Plus de flexibilité: vous pouvez utiliser le module asyncio pour créer des flux de travail complexes.
  • Plus de contrôle: vous pouvez utiliser le module asyncio pour gérer les exceptions et les timeouts.

Conclusion

Quelle est la différence entre send_request_async, send_multi_request_sync et send_request_async_ng?

  • send_request_async: envoie une requête à une opération métier (Business Operation) et attend la réponse si la méthode on_response est implémentée et le paramètre completion_key est utilisé.
    • avantage: vous pouvez utiliser les appels asynchrones comme vous en avez l'habitude.
    • inconvénient: il peut être difficile à maintenir si vous avez besoin d'envoyer plusieurs requêtes en parallèle.
  • send_multi_request_sync : envoie plusieurs requêtes à la même opération métier (Business Operation) en parallèle et attend que toutes les réponses soient reçues.
    • avantage: facile à utiliser.
    • inconvénient: vous ne pouvez pas contrôler l'ordre des réponses (c'est-à-dire que la liste des réponses n'est pas ordonnée).
  • send_request_async_ng: envoie plusieurs requêtes à la même opération métier (Business Operation) en parallèle et attend que toutes les réponses soient reçues.
    • avantage: vous pouvez contrôler l'ordre des réponse.
    • inconvénient : vous devez utiliser des fonctions asynchrones et des coroutines.

Joyeux multitraitement!

0
0 46
InterSystems officiel Adeline Icard · Déc 12, 2024

Les premiers aperçus pour les développeurs de la plateforme de données InterSystems IRIS®, InterSystems IRIS® for Health et HealthShare® Health Connect 2025.1 ont été publiés sur le site d'aperçus pour les développeurs sur WRC. Les conteneurs sont disponibles dans notre registre de conteneurs et sont étiquetés latest-preview.

0
0 45
Article Sylvain Guilbaud · Mai 15, 2023 5m read

Aperçu général

En passant d'IRIS objectScript à Python, on s'aperçoit qu'il existe des différences syntaxiques fascinantes.

L'une d'entre elles concerne la manière dont Python renvoie des tuples à partir d'une méthode à décompression automatique.

En fait, il s'agit d'une méthode qui renvoie plusieurs valeurs. Quelle invention géniale :)

out1, out2 = some_function(in1, in2)

ObjectScript a une autre approche avec les paramètres ByRef et Output.

Do ##class(some_class).SomeMethod(.inAndOut1, in2, .out2)

Où:

  • inAndOut1 représente ByRef
  • out2 représente Output

Le point initiale (".") devant le nom de la variable passe ByRef et pour Output.

Le but de cet article est de décrire comment l'utilitaire communautaire PyHelper a été amélioré pour donner une façon pythonique de tirer parti des paramètres ByRef et Output. Il donne accès à %objlasterror et a une approche pour la gestion des types Python None.
 

Exemple ByRef

L'invocation normale pour python intégré serait :

oHL7=iris.cls("EnsLib.HL7.Message")._OpenId('er12345')

Lorsque cette méthode ne parvient pas à s'ouvrir, la variable "oHL7" est une chaîne vide.
Dans la signature de cette méthode, il y a un paramètre d'état qui est disponible pour le script de l'objet qui donne une explication du problème exact.
Par exemple :

  • L'enregistrement peut ne pas exister
  • L'enregistrement ne peut être ouvert dans le mode d'accès simultané exclusif par défaut ("1"), pendant un timeout.
ClassMethod %OpenId(id As %String = "", concurrency As %Integer = -1, ByRef sc As %Status = {$$$OK}) As %ObjectHandle

La méthode TupleOut peut aider à renvoyer la valeur de l'argument sc dans un contexte python.
 

> oHL7,tsc=iris.cls("alwo.PyHelper").TupleOut("EnsLib.HL7.Message","%OpenId",['sc'],1,'er145999', 0)
> oHL7
''
> iris.cls("%SYSTEM.Status").DisplayError(tsc)
ERROR #5809: Objet à charger introuvable, classe 'EnsLib.HL7.Message', ID 'er145999'1
```

La liste ['sc'] contient un seul élément dans ce cas. Elle peut retourner plusieurs valeurs ByRef, et dans l'ordre spécifié. Ce qui est utile pour décompresser automatiquement vers les variables python prévues.

La gestion des paramètres de sortie (Output) en cas d'exemple

Code Python :

> oHL7=iris.cls("EnsLib.HL7.Message")._OpenId('145')
> oHL7.GetValueAt('<%MSH:9.1')
''

La chaîne renvoyée est vide, mais est-ce parce que l'élément est effectivement vide OU parce que quelque chose s'est mal passé ?
Dans le script objet, il existe également un paramètre de sortie d'état (pStatus) auquel il est possible d'accéder pour déterminer cette condition.

Code script objet :

> write oHL7.GetValueAt("<%MSH:9.1",,.pStatus)
''
> Do $System.Status.DisplayError(pStatus)
ERROR <Ens>ErrGeneral: Aucun segment n'a été trouvé lors du trajet '<%MSH'

Avec TupleOut, la fonctionnalité équivalente peut être atteinte en renvoyant et en décompressant à la fois la valeur de retour de la méthode ET le paramètre de sortie d'état.

Code Python :

> hl7=iris.cls("EnsLib.HL7.Message")._OpenId(145,0)
> val, status = iris.cls("alwo.PyHelper").TupleOut(hl7,"GetValueAt",['pStatus'],1,"<&$BadMSH:9.1")
> val==''
True
> iris.cls("%SYSTEM.Status").IsError(status)
1
> iris.cls("%SYSTEM.Status").DisplayError(status)
ERROR <Ens>ErrGeneral: Aucun segment n'a été trouvé lors du trajet '<&$BadMSH'1

Variable spéciale %objlasterror

Dans ObjectScript, il est possible d'accéder à des variables de pourcentage dans le cadre d'une méthode.
Dans certains cas, il est utile de détecter la variable spéciale %objlasterror ou d'y accéder après avoir appelé une API CORE ou une API de tiers.
La méthode TupleOut permet d'accéder à %objlasterror, comme si elle avait été définie en tant que paramètre de sortie, lors de l'invocation de méthodes à partir de Python.

> del _objlasterror

> out,_objlasterror=iris.cls("alwo.PyHelper").TupleOut("EnsLib.HL7.Message","%OpenId",['%objlasterror'],1,'er145999', 0)

> iris.cls("%SYSTEM.Status").DisplayError(_objlasterror)
ERROR #5809: Objet à charger introuvable, classe 'EnsLib.HL7.Message', ID 'er145999'1

Quand "None" n'est pas une chaîne

TupleOut traite les références python "None" comme objectscript "undefined". Cela permet aux paramètres d'être définis par défaut et aux méthodes de se comporter de manière cohérente.
C'est important, par exemple, dans le cas de %Persistent::%OnNew, où la méthode %OnNew n'est pas déclenchée lorsque "None" est fourni comme valeur initiale "initvalue", alors qu'elle serait déclenchée si une chaîne vide était fournie.

En objectscript, l'implémentation pourrait être la suivante :

do oHL7.myMethod("val1",,,"val2")

Notez l'absence de variables entre les virgules.

TupleOut facilite le même comportement avec :

Python:

iris.cls("alwo.PyHelper").TupleOut(oHL7,"myMethod",[],0,"val1",None,None,"val2")

Une autre façon d'envisager la question est d'avoir une implémentation du code d'invocation en une seule ligne, qui se comporte de manière flexible en fonction de la configuration préalable des variables :

Object Script:

set arg1="val1"
kill arg2
kill arg3
set arg4="val2"
do oHL7.myMethod(.arg1, .arg2, .arg3, .arg4)

TupleOut facilite le même comportement avec :

Python:

arg1="val1"
arg2=None
arg3=None
arg4="val2"
iris.cls("alwo.PyHelper").TupleOut(oHL7,"myMethod",[],0,arg1,arg2,arg3,arg4)

Liste et dictionnaires

Lors de la gestion des paramètres d'entrée, de ByRef et Output, TupleOut utilise la correspondance automatique de PyHelper entre: l les listes IRIS et les listes Python
les tableaux IRIS et les tableaux Python
Il prend soin de toujours utiliser des chaînes pour représenter les clés du dictionnaire lorsqu'il passe des tableaux IRIS aux types Dict de Python.

Conclusion

J'espère que cet article contribuera à inspirer de nouvelles idées et discussions sur les idées et suggestions relatives à Python intégré.

J'espère aussi qu'il encouragera à explorer la flexibilité d'IRIS, qui peut facilement s'adapter à de nouveaux défis.

0
0 80