Recherche

Effacer le filtre
Article
Irène Mykhailova · Mars 28, 2022

Les classes, les tables et les globales - comment tout cela fonctionne?

Lorsque je décris InterSystems IRIS à des personnes plus orientées vers la technique, je commence toujours par dire qu'il s'agit d'un DBMS (système de gestion de base de données) multi-modèle. À mon avis, c'est son principal avantage (du côté du DBMS). Et les données ne sont stockées qu'une seule fois. Vous choisissez simplement l'API d'accès que vous voulez utiliser. * Voulez-vous une sorte de résumé pour vos données ? Utilisez SQL ! * Souhaitez-vous travailler en profondeur avec un seul enregistrement ? Utilisez des objets ! * Voulez-vous accéder ou définir une valeur et vous connaissez la clé ? Utilisez les globales ! À première vue, c'est une belle histoire - courte et concrète, elle fait passer le message, mais lorsque les gens commencent vraiment à travailler avec InterSystems IRIS, les questions apparaissent. Comment les classes, les tables et les globales sont-ils liés ? Que sont-ils les uns pour les autres ? Comment les données sont-elles réellement stockées ? Dans cet article, je vais essayer de répondre à ces questions et d'expliquer ce qui se passe réellement. **Première partie. Le biais des modèles.** Les personnes qui travaillent avec des données ont souvent un biais en faveur du modèle avec lequel elles travaillent. Les développeurs pensent en objets. Pour eux, les bases de données et les tableaux sont des boîtes avec lesquelles vous interagissez via CRUD (Créer-Lire-Mettre à jour-Supprimer, de préférence via ORM), mais le modèle conceptuel sous-jacent est constitué d'objets (bien sûr, c'est surtout vrai pour les développeurs utilisant des langages orientés objet - donc la plupart d'entre nous). D'autre part, pour avoir passé beaucoup de temps dans des DBMS relationnels, les DBA considèrent souvent les données comme des tables. Dans ce cas, les objets ne sont que des enveloppes sur les lignes. Et avec InterSystems IRIS, une classe persistante est aussi un table, qui stocke les données en globale, donc une clarification est nécessaire. **Deuxième partie. Un exemple.** Disons que vous avez créé une classe Point : ```objectscript Class try.Point Extends %Persistent [DDLAllowed] { Property X; Property Y; } ``` Vous pouvez également créer la même classe avec DDL/SQL : ``` CREATE Table try.Point ( X VARCHAR(50), Y VARCHAR(50)) ``` Après la compilation, notre nouvelle classe aurait généré automatiquement une structure de stockage qui fait correspondre les données qui sont nativement stockées dans les globaux aux colonnes (ou aux propriétés si vous êtes un penseur orienté objet) : ``` Storage Default { %%CLASSNAME X Y ^try.PointD PointDefaultData ^try.PointD ^try.PointI ^try.PointS %Library.CacheStorage } ``` Qu'est-ce qui se passe ici ? De bas en haut (les mots en **gras** sont importants, ignorez le reste) : - Type : le type de stockage généré, dans notre cas le stockage par défaut pour les objets persistants - StreamLocation - l'endroit où nous stockons les flux de données séquencé - IndexLocation - la globale pour les indices - IdLocation - la globale où nous stockons l'ID compteur autoincrémental - **DefaultData** - l'élément XML de stockage qui fait correspondre la valeur globale aux colonnes/propriétés - **DataLocation** - la globale dans lequel les données sont stockées Maintenant notre "DefaultData" est `PointDefaultData` alors regardons de plus près sa structure. Essentiellement, cela dit que le noeud global a cette structure : - 1 - %%CLASSNAME - 2 - X - 3 - Y On peut donc s'attendre à ce que notre globale ressemble à ceci : ``` ^try.PointD(id) = %%CLASSNAME, X, Y ``` Mais si nous imprimons notre globale, il sera vide car nous n'avons pas ajouté de données : ``` zw ^try.PointD ``` Ajoutons un objet : ``` set p = ##class(try.Point).%New() set p.X = 1 set p.Y = 2 write p.%Save() ``` Et voici notre globale ``` zw ^try.PointD ^try.PointD=1 ^try.PointD(1)=$lb("",1,2) ``` Comme vous le voyez, notre structure attendue %%CLASSNAME, X, Y est définie avec `$lb("",1,2)` qui correspond aux propriétés X et Y de notre objet (%%CLASSNAME est une propriété du système, ignorez-la). Nous pouvons également ajouter une ligne via SQL : ``` INSERT INTO try.Point (X, Y) VALUES (3,4) ``` Maintenant, notre globale ressemble à ceci : ``` zw ^try.PointD ^try.PointD=2 ^try.PointD(1)=$lb("",1,2) ^try.PointD(2)=$lb("",3,4) ``` Ainsi, les données que nous ajoutons par le biais d'objets ou de SQL sont stockées dans des globales en fonction des définitions de stockage (remarque : vous pouvez modifier manuellement la définition de stockage en remplaçant X et Y dans PointDefaultData - vérifiez ce qu'il arrive aux nouvelles données !) Maintenant, que se passe-t-il lorsque nous voulons exécuter une requête SQL ? ``` SELECT * FROM try.Point ``` Elle est traduite en code ObjectScript qui itère sur la globale `^try.PointD` et remplit les colonnes en fonction de la définition du stockage - la partie `PointDefaultData` précisément. Maintenant pour les modifications. Supprimons toutes les données du table : ``` DELETE FROM try.Point ``` Et voyons notre globale à ce stade : ``` zw ^try.PointD ^try.PointD=2 ``` Notez que seul le compteur d'ID est laissé, donc le nouvel objet/ligne aura un ID=3. De même, notre classe et notre table continuent d'exister. Mais que se passe-t-il quand on lance : ``` DROP TABLE try.Point ``` Il détruirait le table, la classe et supprimerait la globale. ``` zw ^try.PointD ``` Si vous avez suivi cet exemple, j'espère que vous comprenez maintenant mieux comment les globales, les classes et les tables s'intègrent et se complètent. L'utilisation de la bonne API pour le travail à effectuer permet un développement plus rapide, plus agile et moins bogué.
Article
Irène Mykhailova · Oct 7, 2022

Invitation du service FHIR Accelerator à votre fête de microservices Kubernetes

![image](/sites/default/files/inline/images/microserviceparty2.png) Est-ce que vous souhaitez inclure une implémentation FHIR® de qualité commerciale dans votre écosystème de micro-services et vous avez à peine le temps de remplir les formulaires de sélection de votre régime d'assurance maladie ? Voici un moyen rapide d'inviter le service InterSystems® FHIR®Accelerator à votre groupe de microservices Kubernetes pour une utilisation immédiate. La solution fait appel à des mouvements de proxy ninja de [Nginx](https://nginx.org/en/) pour faire le travail. Bien qu'il s'agisse d'une solution rustique qui ne manquera pas de susciter des débats techniques, je suis plutôt satisfait des résultats obtenus, et ce jusqu'à ce que la communauté me dise le contraire, alors, comme on dit, " FHIR® ", mais ce serait formidable si vous m'écoutiez d'abord. ### Clause de non-responsabilité Vous verrez des secrets dans les manifestes, l'utilisation des port de nœuds nodePort et un nœud maître corrompu pour faire passer le message, la discrétion parentale est conseillée. ## Préalables Vous aurez besoin de quelques éléments si vous souhaitez le déployer vous-même. Il s'agit principalement d'un point de départ ou d'une approche pour ceux qui souhaitent intégrer rapidement la fonctionnalité FHIR® à des fins de développement. > 🔥 Environnement > > Pour cette démonstration, nous sommes parqués directement sur un nœud maître de Kubernetes corrompu pour mettre en œuvre le travail. ![image](/sites/default/files/inline/images/shell_env.png) ## FHIR up le service FHIR® Accelerator - [X ] [Créez un compte dans l'InterSystems® Cloud ](https://portal.live.isccloud.io/account/signup) - [ X] [Créez un déploiement de service InterSystems FHIR® Accelerator](https://portal.live.isccloud.io/deployments/create) ![image](/sites/default/files/inline/images/deploymentcreate.png) - [ ] [Créez une clé Api](https://portal.live.isccloud.io/deployments/create) ![image](/sites/default/files/inline/images/api-key.png) > 🖇 Enregistrez le point de terminaison et la clé API > > C'est tout ce que nous avons besoin de l'accélérateur FHIR®, nous interagirons avec le service à notre manière à l'intérieur du cluster Kubernetes. ## Clonage de ce Repo Pour le "reste du README", placez-vous sur un nœud maître Kubernetes corrompu. ``` git clone https://gitlab.com/isc_cloud/fhiraas-microservice-kubernetes.git cd fhir-microservice-kubernetes ``` ![image](/sites/default/files/inline/images/repo_clone.png) ## Déploiement vers le cluster Kubernetes - [X ] [Créez un espace de nom Namespace](https://gitlab.com/isc_cloud/fhiraas-microservice-kubernetes/-/blob/main/k8s/fhiraas_k8s_deployment.yml#L1-6), afin de disposer d'un rayon d'explosion dans lequel jouer pour l'instant. - [X] [Creez une ConfigMap](https://gitlab.com/isc_cloud/fhiraas-microservice-kubernetes/-/blob/main/k8s/fhiraas_k8s_deployment.yml#L7-29), il s'agit en fait de la folie du reverse proxy implémentée dans le nginx.conf. > ✏ IL FAUT MODIFIER QUELQUE CHOSE ICI > > Rappelez-vous la clé et le point de terminaison que nous avons générés à partir du service FHIR Accelerator ? Il faut les mettre à jour [ici, dans le déploiement](https://gitlab.com/isc_cloud/fhiraas-microservice-kubernetes/-/blob/main/k8s/fhiraas_k8s_deployment.yml#L24-26) - [ X] [Créez un déploiement](https://gitlab.com/isc_cloud/fhiraas-microservice-kubernetes/-/blob/main/k8s/fhiraas_k8s_deployment.yml#L30-60), voici les conteneurs eux-mêmes, avec 3 modules pour le groupe de répliques de déploiement. - [ X] [Créez un Service](https://gitlab.com/isc_cloud/fhiraas-microservice-kubernetes/-/blob/main/k8s/fhiraas_k8s_deployment.yml#L61-75), Exposez-le !, c'est un simple service NodePort qui lie un port sur le nœud pour accéder au service FHIR Accelerator. Il expose 30036 sur le nœud, et transmet au module de déploiement sur 52773. ``` cd fhir-microservice-kubernetes # devrait déjà être ici, mais juste pour être sûr. kubectl apply -f k8s/ ``` ![image](/sites/default/files/inline/images/k8s_deploy.png) ![image](/sites/default/files/inline/images/fhiraas_deployment.gif) ## Testez-le ! Faisons un test rapide pour vérifier si FHIR est bien servi à travers le NodePort. [✔] Port du noeud Socket en écoute ? [✔] Écouter le port du noeud Socket ? [✔] Consultation des patients ? [✔] Obtenez le patient ? ![image](/sites/default/files/inline/images/fhiraas_nodeport.gif) ## Mettre à l'échelle ! Nous sommes sur un seul nœud et exposons le service à un port de nœud, donc nous ne sommes pas sûrs que cela augmentera notre débit, mais allons-y quand même. ``` kubectl scale deployments/isc-fhiraas-deployment --replicas=30 -n isc-fhiraas ``` ![image](/sites/default/files/inline/images/scale_out.png) ![image](/sites/default/files/inline/images/fhiraas_scalout.gif) ## Mettons-y un peu de FHIR ! Ce dépôt contient un script shell hostile et rustique qui permet de placer des patients aléatoires dans la ressource Patient, avec quelques cloches et sans sifflets. J'ai besoin de quelques variables d'environnement ou vous pouvez simplement éditer les variables directement dans le script. Lors de l'exécution de ce script, assurez-vous du bon fonctionnement du ventilateur du processeur et déplacez les objets de la zone de l'ordinateur portable pour éviter le déplacement des objets dans le cas où votre ordinateur portable s'envole. ``` bash bin/fhirbench.sh ``` ![image](/sites/default/files/inline/images/fhiraas-benchanddescale.png) > 🏆 Résultats > > 50 placements, et 50 recherches en 13 secondes. # Personne responsable Ce matériel se trouve dans le référentiel, Ron Sweeney (ron.sweeney@integrationrequired.com) de [Intégration requise] (https://www.integrationrequired.com). Ce sont les opinions de mon employeur.
Article
Evgeny Shvarov · Juil 20, 2022

Comment trouver des applications installables en utilisant le Package Manager

Salut la communauté ! @Joan.Pérez a publié une critique selon laquelle il n'est pas très clair quelles applications sont disponibles pour InterSystems Package Manager. Merci Joan ! En effet, cela mérite un article. Il y a au moins deux façons que je connais pour les présenter : 1. Exécuter la commande find dans zpm : IRISAPP>zpm ============================================================================= || Welcome to the Package Manager Shell (ZPM). || || Enter q/quit to exit the shell. Enter ?/help to view available commands || ============================================================================= zpm:IRISAPP>find registry https://pm.community.intersystems.com: analytics-okr 1.0.0 analyzethis 1.2.4 aoc-2021-uvg 0.0.2 aoc2021-rcc 0.0.2 appmsw-dbdeploy 1.0.3 appmsw-docbook 1.0.5 appmsw-forbid-old-passwd 1.0.4 .... Ou find -d pour les lister avec des descriptions : zpm:IRISAPP>find -d registry https://pm.community.intersystems.com: analytics-okr 1.0.0 analyzethis 1.2.4 Description: Module that helps to generate cubes, pivots and dashboards vs IRIS data aoc-2021-uvg 0.0.2 Description: Advent of code 2021 in COS classes aoc2021-rcc 0.0.2 Description: AoC-2021 full Embedded Python demo appmsw-dbdeploy 1.0.3 Description: An example of deploying solutions with prepared databases, even without source code. appmsw-docbook 1.0.5 Description: Importing docbook ... 2. La deuxième façon est de filtrer les OEX sur ZPM: Partagez vos méthodes pour lister les paquets publics ? Ceci était lié aux dépôts publics, bien sûr il y a beaucoup de dépôts privés et nous ne savons pas ce qu'ils contiennent. Comment exposez-vous les paquets ?
Article
Sylvain Guilbaud · Fév 15, 2023

Intégration continue avec le gestionnaire de paquets ObjectScript, GitHub Actions et Docker

## Introduction Dans un [article précédent](https://community.intersystems.com/post/unit-tests-and-test-coverage-objectscript-package-manager), j'ai abordé les modèles d'exécution des tests unitaires via le gestionnaire de paquets ObjectScript. Cet article va un peu plus loin, en utilisant les actions GitHub pour piloter l'exécution des tests et la création de rapports. Le cas d'utilisation qui nous motive est l'exécution du CI pour l'un de mes projets Open Exchange, [AppS.REST](https://openexchange.intersystems.com/package/apps-rest) (voir l'article d'introduction à ce projet [ici](https://community.intersystems.com/post/appsrest-new-rest-framework-intersystems-iris)). Vous pouvez voir l'implémentation complète dont les extraits de cet article ont été tirés sur [GitHub](https://github.com/intersystems/apps-rest/blob/master/.github/workflows/main.yml) ; elle pourrait facilement servir de modèle pour l'exécution de l'IC pour d'autres projets utilisant le gestionnaire de paquets ObjectScript. Les fonctionnalités dont la mise en œuvre a été démontrée comprennent : * Compilation et test d'un paquet ObjectScript * Rapport sur la mesure de la couverture des tests (en utilisant le paquet [TestCoverage](https://openexchange.intersystems.com/package/Test-Coverage-Tool)) via [codecov.io](https://codecov.io) * Téléchargement d'un rapport sur les résultats des tests en tant qu'artefact de comppilation. ## L'environnement de compilation Il existe une documentation complète sur les actions GitHub [ici](https://docs.github.com/en/actions). Dans le cadre de cet article, nous nous contenterons d'explorer les aspects présentés dans cet exemple. Un flux de travail dans les actions GitHub est déclenché par un ensemble configurable d'événements et consiste en un certain nombre de tâches qui peuvent être exécutées séquentiellement ou en parallèle. Chaque tâche comporte un ensemble d'étapes - nous allons entrer dans le détail des étapes de notre exemple d'action plus tard. Ces étapes consistent en références à des actions disponibles sur GitHub, ou peuvent simplement être des commandes shell. Un extrait du modèle initial de notre exemple ressemble à ceci : # Flux de travail d'intégration continue name: CI # Contrôle le moment où l'action sera exécutée. Déclenche le flux de travail sur les événements push ou pull request # événements dans toutes les branches on: [push, pull_request] # Un flux de travail est composé d'une ou plusieurs tâches qui peuvent être exécutées séquentiellement ou en parallèle. jobs: # Ce flux de travail contient une seule tâche appelé "build". build : # Le type d'exécuteur sur lequel le travail sera exécuté runs-on : ubuntu-latest env: # Variables d'environnement utilisables tout au long de la tâche de "compilation", par exemple dans les commandes au niveau du système d'exploitation. package: apps.rest container_image : intersystemsdc/iris-community:2019.4.0.383.0-zpm # D'autres éléments seront abordés plus tard... # Les étapes représentent une séquence de tâches qui seront exécutées dans le cadre du travail. steps: # Ceux-ci seront montrés plus tard... Dans cet exemple, un certain nombre de variables d'environnement sont utilisées. Pour appliquer cet exemple à d'autres paquets utilisant le gestionnaire de paquets ObjectScript, la plupart d'entre elles n'auront pas besoin d'être modifiées, alors que certaines le seront. env: # ** POUR UN USAGE GÉNÉRAL, IL FAUDRA PROBABLEMENT CHANGER : ** package: apps.rest container_image: intersystemsdc/iris-community:2019.4.0.383.0-zpm # ** POUR UN USAGE GÉNÉRAL, IL FAUDRA PEUT-ÊTRE CHANGER : ** build_flags: -dev -verbose # Télécharger en mode -dev pour obtenir le code de test unitaire préchargé test_package: UnitTest # ** POUR UN USAGE GÉNÉRAL, IL NE FAUDRA PAS CHANGER : ** instance: iris # Remarque : la valeur test_reports est dupliquée dans la variable d'environnement test_flags. test_reports: test-reports test_flags: >- -verbose -DUnitTest.ManagerClass=TestCoverage.Manager -DUnitTest.JUnitOutput=/test-reports/junit.xml -DUnitTest.FailuresAreFatal=1 -DUnitTest.Manager=TestCoverage.Manager -DUnitTest.UserParam.CoverageReportClass=TestCoverage.Report.Cobertura.ReportGenerator -DUnitTest.UserParam.CoverageReportFile=/source/coverage.xml Si vous voulez adapter cela à votre propre paquet, il suffit de déposer votre propre nom de paquet et votre image de conteneur préférée (doit inclure zpm - voir ). Vous pourriez également vouloir changer le paquet de tests unitaires pour qu'il corresponde à la convention de votre propre paquet (si vous devez charger et compiler les tests unitaires avant de les exécuter pour gérer toutes les dépendances de chargement/compilation ; j'ai eu quelques problèmes bizarres spécifiques aux tests unitaires pour ce paquet, donc cela pourrait même ne pas être pertinent dans d'autres cas). Le nom de l'instance et le répertoire test\_reports ne devraient pas être modifiés pour d'autres utilisations, et les test\_flags fournissent un bon ensemble de valeurs par défaut - ils permettent de faire en sorte que les échecs des tests unitaires signalent l'échec de la compilation, et gèrent également l'exportation des résultats des tests au format jUnit et un rapport de couverture de code. ## Étapes de compilation ### Vérification des référentiels GitHub Dans notre exemple de motivation, deux dépôts doivent être vérifiés - celui qui est testé, et aussi mon fork de [Forgery](https://openexchange.intersystems.com/package/Forgery) (parce que les tests unitaires en ont besoin). # Vérifie ce référentiel sous $GITHUB_WORKSPACE, afin que votre tâche puisse y accéder. - uses: actions/checkout@v2 # Il faut aussi vérifier le timleavitt/forgery jusqu'à la version officielle installable via ZPM - uses: actions/checkout@v2 with: repository: timleavitt/forgery path: forgery $GITHUB_WORKSPACE est une variable d'environnement très importante, représentant le répertoire racine où tout cela fonctionne. Du point de vue des permissions, vous pouvez faire à peu près tout ce que vous voulez dans ce répertoire ; ailleurs, vous pouvez rencontrer des problèmes. ### Exécution du conteneur IRIS d'InterSystems Après avoir configuré un répertoire où nous finirons par placer nos rapports de résultats de tests, nous allons exécuter le conteneur InterSystems IRIS Community Edition (+ZPM) pour notre compilation. - name: Run Container run: | # Créer le répertoire test_reports pour partager les résultats des tests avant l'exécution du conteneur. mkdir $test_reports chmod 777 $test_reports # Lancer l'instance InterSystems IRIS docker pull $container_image docker run -d -h $instance --name $instance -v $GITHUB_WORKSPACE:/source -v $GITHUB_WORKSPACE/$test_reports:/$test_reports --init $container_image echo halt > wait # Attendez que l'instance soit prête until docker exec --interactive $instance iris session $instance < wait; do sleep 1; done Il y a deux volumes partagés avec le conteneur - l'espace de travail GitHub (pour que le code puisse être chargé ; nous y rapporterons également des informations sur la couverture des tests), et un répertoire séparé où nous placerons les résultats des tests jUnit. Après la fin de "docker run", cela ne signifie pas que l'instance est complètement démarrée et prête à être commandée. Pour attendre que l'instance soit prête, nous continuerons à essayer d'exécuter une commande "halt" via la session iris ; cela échouera et continuera à essayer une fois par seconde jusqu'à ce que cela réussisse (éventuellement), indiquant que l'instance est prête. ### Installation des bibliothèques liées aux tests Pour notre cas d'utilisation motivant, nous utiliserons deux autres bibliothèques pour les tests - [TestCoverage](https://openexchange.intersystems.com/package/Test-Coverage-Tool) et [Forgery](https://openexchange.intersystems.com/package/Forgery). TestCoverage peut être installé directement via le Community Package Manager ; Forgery (actuellement) doit être chargé via zpm "load" ; mais les deux approches sont valables. - name: Install TestCoverage run: | echo "zpm \"install testcoverage\":1:1" > install-testcoverage docker exec --interactive $instance iris session $instance -B < install-testcoverage # Solution aux problèmes de permissions dans TestCoverage (création d'un répertoire pour l'exportation des sources) chmod 777 $GITHUB_WORKSPACE - name: Install Forgery run: | echo "zpm \"load /source/forgery\":1:1" > load-forgery docker exec --interactive $instance iris session $instance -B < load-forgery L'approche générale consiste à écrire les commandes dans un fichier, puis à les exécuter en session IRIS. Le ":1:1" supplémentaire dans les commandes ZPM indique que la commande doit quitter le processus avec un code d'erreur si une erreur se produit, et s'arrêter à la fin si aucune erreur ne se produit ; cela signifie que si une erreur se produit, elle sera signalée comme une étape de compilation ayant échoué, et nous n'avons pas besoin d'ajouter une commande "halt" à la fin de chaque fichier. ### Compilation et test du paquet Enfin, nous pouvons effectivement compiler et exécuter des tests pour notre paquet. C'est assez simple - remarquez l'utilisation des variables d'environnement $build\_flags/$test\_flags que nous avons définies plus tôt. # Exécute un ensemble de commandes en utilisant l'exécuteur runners - name: Build and Test run: | # Exécution de compilation echo "zpm \"load /source $build_flags\":1:1" > build # Le paquet de test est compilé en premier comme solution de contournement pour certains problèmes de dépendance. echo "do \$System.OBJ.CompilePackage(\"$test_package\",\"ckd\") " > test # Exécution des tests echo "zpm \"$package test -only $test_flags\":1:1" >> test docker exec --interactive $instance iris session $instance -B < build && docker exec --interactive $instance iris session $instance -B < test && bash
Article
Irène Mykhailova · Mai 2, 2023

fhir-integratedml-example: aperçu général

En discutant avec un de mes amis, spécialiste du Machine Learning @Renato Banzai , il a évoqué l'un des plus grands défis pour les entreprises aujourd'hui : le déploiement du ML/IA dans des environnements réels. InterSystems IRIS propose la solution "IntegratedML". IntegratedML est une fonctionnalité très utile pour entraîner, tester et déployer des modèles de ML/IA. La partie la plus difficile dans la création de ML/IA est de faire le traitement des données, de les nettoyer et de les rendre fiables. C'est là que nous pouvons tirer parti de la puissante norme FHIR ! L'idée du projet montre comment nous pouvons créer/entraîner/valider des modèles MI/IA avec FHIR et les utiliser avec des données provenant de différentes sources. Nous pensons que ce projet a un grand potentiel, et que quelques idées peuvent être explorées : Réutilisation/extension des transformations DTL dans d'autres bases de données FHIR pour des modèles ML personnalisés Utilisation des transformations DTL pour normaliser les messages FHIR et publier les modèles ML en tant que services Création d'un référentiel de modèles et de règles de transformation à utiliser dans n'importe quel ensemble de données FHIR En explorant de nouvelles possibilités avec ce projet, nous pouvons imaginer des données provenant de différentes sources Dans l'image ci-dessus, la ressource FHIR, qui consomme l'API REST, peut être utilisée avec une solution FHIRaaS. Nous pouvons non seulement utiliser FHIRaaS sur AWS, mais aussi le nouveau service de transformation des messages HealthShare Message Transformation Services, qui automatise la conversion de HL7v2 en FHIR® pour alimenter Amazon HealthLake, où il est possible d'extraire une plus grande valeur de vos données. Avec ces petites démonstrations, je vois que ces ressources sont très bien utilisées dans des scénarios plus larges, permettant et fournissant plus facilement des déploiements en production dans des environnements vraiment innovants, comme le AWS Healthlake. Pourquoi pas ?! 😃
Annonce
Irène Mykhailova · Août 19, 2022

Version de la Communauté des Développeurs, juillet 2022

Bonjour et bienvenue sur la version de juillet 2022 de la Communauté des Développeurs ! Nous avons récemment apporté des modifications intéressantes à votre expérience au sein de la communauté InterSystems : 📌 notifications comme sur les réseaux sociaux 📌 paramètre d'abonnement amélioré 📌 nouvelle page "À propos de nous" 📌 page "Membres" plus conviviale Regardons de plus près toutes ces améliorations ! NOTIFICATIONS À partir de maintenant, vous pourrez voir que vous avez de nouvelles notifications dans le coin supérieur droit de la page, à côté de votre photo de profil. Cliquez simplement sur la cloche et vous obtiendrez un menu déroulant de toutes vos notifications récentes à partir duquel vous pourrez accéder à la page avec les détails : En cliquant sur le lien "Voir tout", vous serez redirigé vers une page où vous pourrez voir toutes vos notifications : À partir de cette page, vous pouvez "Marquer toutes comme lues" ou suivre le lien vers la page qui a généré la notification. Et gérez vos paramètres d'abonnement. ABONNEMENTS Nous avons modifié le design de la page Abonnements. J'espère que c'est plus convivial maintenant Vous pouvez choisir les notifications que vous recevez de la communauté des développeurs, que vous les receviez par e-mail ou via le site Web. Vous pouvez le trouver dans la section "Abonnements" de votre compte. À PROPOS DE NOUS Nous avons déjà mentionné que nous avions créé une toute nouvelle page "À propos de nous". Mais c'est aussi mignon comme un coeur, donc ça vaut la peine de le mentionner une fois de plus 🥰 Vous pouvez le trouver dans le menu supérieur, dans la section À propos -> À propos de nous : MEMBERS Et une autre page que nous avons modifiée pour votre commodité est la page "Membres". Nous avons ajouté une nouvelle colonne "Dernière activité". Et, bien sûr, n'oubliez pas que vous pouvez trier n'importe quelle colonne en cliquant simplement sur son nom. C'est tout pour le moment! J'espère que vous approuvez toutes nos améliorations ! A la prochaine avec plus de news !
Article
Lucas Enard · Sept 19, 2022

Formulaires et questionnaire dans FHIR : De la création à l'utilisation

Cet article aborde les questions de `Questionnaire` et `QuestionnaireResponse` de **FHIR** depuis la création du formulaire jusqu'au téléchargement sur le serveur et la façon de les remplir. # tl;dr : - En utilisant [cet outil en ligne](https://lhcformbuilder.nlm.nih.gov/beta/) vous pouvez facilement créer votre propre formulaire en partant de zéro ou en utilisant un modèle d'un formulaire existant. - En utilisant [ce serveur FHIR local d'InterSystems](https://github.com/intersystems-community/iris-fhir-template) you can easily store your FHIR resources and Questionnaire. - En utilisant [cet application](https://github.com/lhncbc/lforms-fhir-app) vous pouvez manipuler, comme si vous étiez un praticien, le questionnaire et la réponse pour chaque patient sur votre serveur FHIR. Il est à noter que l'application ne communique pas en utilisant le `Content-Type 'application/json+fhir'` mais juste le `Content-Type 'application/json'` donc cela ne fonctionnera pas de cette manière avec notre serveur FHIR local d' InterSystems. C'est pourquoi j'ai créé [ce repo GitHub](https://github.com/LucasEnard/fhir-form) contenant une version modifiée de l'application, fonctionnant avec `Content-Type 'application/json+fhir'`, contenant un serveur FHIR local et un lien vers l'outil de construction de questionnaires avec quelques explications. Après avoir cloné le repo, en faisant `docker-compose up -d`, `npm ci`, `npm run build` et ensuite `npm run start` vous serez accueilli avec un accès à l'app, en sélectionnant le serveur FHIR que vous voulez et le Patient avec lequel vous voulez travailler, vous pourrez remplir Questionnaire et les enregistrer sur votre serveur en 2 clics. **Fin de tl;dr** Ce qui suit est le ReadMe du GitHub. # 1. Application pour les formulaires FHIR utilisant un serveur fhir local - [1.Application pour les formulaires FHIR utilisant un serveur fhir local](#1-app-for-fhir-forms-using-a-local-fhir-server) - [2. Conditions requises](#2-requirements) - [2.1. Ajout de Node.js et npm à votre route](#21-add-nodejs-and-npm-to-your-path) - [2.2. Installation des dépendances](#22-install-dependencies) - [3. Serveur FHIR local](#3-local-fhir-server) - [4. Utilisation de l'application](#4-using-the-app) - [4.1. Construction de l'application](#41-build-the-application) - [4.2. Lancement de l'application](#42-run-the-application) - [5. Formulaire FHIR / questionnaire](#5-fhir-form--questionnaire) - [5.1. Développement de votre propre formulaire FHIR](#51-creating-your-own-fhir-form) - [5.2. Importation de votre propre formulaire FHIR](#52-importing-your-fhir-form) Il s'agit d'une application principalement basée sur [ce référentiel](https://github.com/lhncbc/lforms-fhir-app) qui peut être utilisée pour afficher les éléments suivants [FHIR](http://hl7.org/fhir/) [SDC](http://hl7.org/fhir/uv/sdc/2018Sep/index.html) [Questionnaire](http://hl7.org/fhir/uv/sdc/2018Sep/sdc-questionnaire.html) et collecter les données en tant que ressources FHIR QuestionnaireResponse. En la développant à l'aide de `docker-compose up -d` vous aurez accès à un [serveur FHIR local](#5-local-fhir-server) qui pourra ensuite être utilisé pour tester l'application. # 2. Conditions requises L'application s'appuie sur le widget de visualisation [LHC-Forms](http://lhncbc.github.io/lforms/) pour l'affichage des formulaires. Elle prend partiellement en charge les FHIR Questionnaires (versions STU3 et R4) et le [Guide d'implémentation de la capture de données structurées](http://build.fhir.org/ig/HL7/sdc/). Ce widget sera installé avec les dépendances. Pour essayer des exemples de formulaires, ce référentiel est livré avec des formulaires dans le répertoire `e2e-test/data/R4` qui sont automatiquement chargés dans le serveur FHIR local lors de la construction. ## 2.1. Ajout de Node.js et npm à votre route Le fichier bashrc.lforms-fhir-app spécifie la version de Node.js utilisée pour le développement. Téléchargez cette version de Node.js, et ajoutez son répertoire bin à votre route. ## 2.2. Installation des dépendances En exécutant cette commande, vous serez en mesure d'installer tout ce qui est nécessaire pour que l'application fonctionne. ``` npm ci ``` # 3. Serveur FHIR local Si vous ne disposez pas d'un serveur FHIR pour essayer cette application, vous pouvez démarrer et utiliser un serveur FHIR local alimenté par les technologies InterSystems en faisant dans le dossier `fhir-form` : ``` docker-compose up -d ``` After some wait, your local FHIR server is up and you can access it by using `http://localhost:32783/fhir/r4` Sachez que ce lien est déjà enregistré dans l'application. # 4. Utilisation de l'application Pour utiliser l'application, vous devez la [construire](#41-build-the-application) et ensuite la [lancer](#42-run-the-application). Vous pouvez maintenant accéder à n'importe quel serveur FHIR à l'aide du menu de l'application, mais si vous le souhaitez, vous pouvez utiliser ce [serveur FHIR local](#3-local-fhir-server) ## 4.1. Construction de l'application ``` npm run build ``` Les fichiers pour la production seront créés dans un répertoire "dist", mais certains fichiers nécessaires seront également copiés à partir de node_modules. ## 4.2. Lancement de l'application ``` npm run start ``` va lancer un serveur http fonctionnant sur le port 8000. Maintenant, naviguez vers l'application à `localhost:8000/lforms-fhir-app/`. Ici, vous pouvez choisir un serveur auquel vous voulez vous connecter. Si vous souhaitez utiliser le serveur FHIR local, [démarrez le serveur FHIR local](#3-local-fhir-server) puis, dans l'application, sélectionnez le premier choix `http://localhost:32783/fhir/r4` # 5. Formulaire FHIR / questionnaire ## 5.1. Développement de votre propre formulaire FHIR En utilisant [this online tool](https://lhcformbuilder.nlm.nih.gov/beta/) ous pouvez facilement créer votre propre formulaire en partant de zéro ou en utilisant un formulaire existant. Il est conseillé d'importer l'un de ceux qui existent dans le dossier `e2e-tests/data/R4` et de commencer à partir de là pour comprendre le fonctionnement de l'outil. ## 5.2. Importation de votre propre formulaire FHIR En utilisant l'application, vous pouvez facilement importer vos formulaires locaux et les utiliser immédiatement en utilisant le bouton de téléchargement `upload`. Si vous utilisez l'outil de construction de formulaires [formbuilder tool] (https://lhcformbuilder.nlm.nih.gov/beta/), vous pouvez, si votre serveur FHIR prend en charge le type de contenu 'application/json', exporter le formulaire que vous créez directement vers le serveur FHIR en utilisant le bouton d'exportation `export`. Si votre serveur ne supporte pas le Content-Type 'application/json' mais seulement le Content-Type 'application/json+fhir' par exemple, comme notre [serveur FHIR local](#3-local-fhir-server) vous devez `exporter` le formulaire dans un fichier, puis dans l'application, et télécharger par `upload` le fichier sur le serveur en tant que l'application communique en Content-Type 'application/json+fhir'. Tu aurais une idée pourquoi lorsque je fais le npm run build j'ai une erreur dans la partie build:pages en lien avec require("ssi")? Pourtant il est bien dans mon dossier nodes_module. Je ne sais pas si c'est parce que j'ai aucune idée de ce qu'il faut faire avec le fichier bashrc.lforms-fhir-app. J'ai la version node 16.13 et j'avais déjà le dossier npm dans mon PATH user\AppData\Roaming\npm @Lucas.Enard2487 Peux tu nous aider sur cette question ? Bonjour Alexandre, Tu trouveras sur ce git, la meme version que celle de lucas mais avec un docker-compose et un dockerfile mis à jour pour installer automatiquement la partie front. https://github.com/grongierisc/fhir-form Je n'ai pas eu de problème de dépendance avec node 14. Ton erreur vient peut etre du fait que tu es en node 16.
Article
Sylvain Guilbaud · Nov 11, 2022

Adopter une architecture Data Fabric pour améliorer les performances de sa Supply Chain

Selon une étude menée par IDC, 83% des CEO souhaitent que leur organisation soit plus axée sur l’utilisation de la donnée. Paradoxalement, 92% d’entre eux n’ont pas confiance dans les données de leur entreprise. Comment convaincre les décideurs d’appuyer davantage leurs décisions sur les données (Data Driven) plutôt que sur leurs intuitions et leurs connaissances du métier ? Les enjeux actuels dans la chaîne d’approvisionnement confirment que les données s’imposent comme un actif précieux et indispensable dans l’élaboration et l’exécution d’une stratégie Data Driven. Une Smart Data Fabric est le préalable à toute entreprise Data Driven Pour devenir une entreprise Data Driven, le préalable est de bâtir une Smart Data Fabric, une architecture visant à garantir que les données sont saines, c’est-à-dire, sécurisées, fiables, à jour, toujours disponibles, tracées, etc. Une brève histoire de l'architecture des données Il y a quelques décennies, les entreprises fonctionnaient avec un système d’information monolithique qui gérait dans un point central les données opérationnelles et analytiques. Cette approche architecturale offrait l’avantage d’un système d’information unifié, mais souffrait d’un manque de scalabilité pour répondre à la charge croissante du nombre d’utilisateurs et à la quantité de données. Une première solution, pour mieux absorber ces montées en charge, a été de séparer les systèmes transactionnels des systèmes décisionnels ; les opérations d’un côté, les analyses de l’autre. Quelques années plus tard, un autre problème est survenu : les systèmes transactionnels se sont tellement spécialisés, qu’une multitude d’applications en silos se sont développées d’un côté, pendant que de l’autre, les besoins métiers se sont également précisés, avec des systèmes décisionnels cherchant à offrir à chacun une vue spécifique à son domaine d’expertise. La conséquence est qu’un fossé s’est creusé entre le monde transactionnel et l’univers décisionnel, entraînant une désynchronisation entre les systèmes opérationnels et analytiques, sans avoir au passage réglé les nouveaux besoins de performances et de temps-réel. Comment réconcilier ces deux mondes ? La première option est la mise en place d’un data warehouse pour combler ce fossé. Le principe général est d’effectuer dans le data warehouse toutes les étapes de transformation des données, pour alimenter les différents data marts, eux-mêmes stockés au sein de cet entrepôt. L’inconvénient de cette approche est que les transformations des données dans l’entrepôt rendent les data marts peu flexibles pour couvrir rapidement un nouveau besoin métier, et qu’il est souvent nécessaire de dupliquer la donnée en créant de nouveaux data marts, dédiés à chaque nouveau besoin. La deuxième option est la mise en place d’un data lake dans lequel toutes les données vont être déposées dans leur format brut, sans transformation. Les étapes de transformation étant volontairement décalées dans un second temps, pour s’effectuer au plus proche des besoins métiers, qui peuvent dès lors évoluer sans impact sur les données d’origine. Malheureusement ces deux approches donnent rarement satisfaction : les projets sont complexes, longs, donc coûteux, sans être suivis de succès, les données sont dupliquées et, ce qui est plus problématique, les données ne sont toujours pas analysées en temps-réel, rendant les décisions Data Driven plus risquées. Une autre approche est possible : la mise en place d’une Smart Data Fabric. En fin d’année 2021, Gartner a publié son rapport sur les tendances technologiques actuelles qui identifie la Data Fabric comme la 1ère tendance pour 2022. De quoi s’agit-il ? Forrester définit la Data Fabric comme les moyens mis en œuvre pour « orchestrer intelligemment et en toute sécurité des sources de données disparates en libre-service, en tirant parti des platesformes de données telles que les lacs de données, les entrepôts de données, les bases de données NoSQL, les plateformes translytiques et autres, pour fournir une vue unifiée, fiable et complète des données clients et commerciales à travers l'entreprise pour prendre en charge les applications et les perspectives. ». De manière très simple, la Data Fabric est une architecture de données qui facilite le stockage, l’accès et le partage des données au sein des applications internes et externes de l’entreprise. Une Smart Data Fabric combine des technologies clés de gestion des données, telles que le catalogue de données, la gouvernance des données, l'intégration des données, la canalisation des données, l’orchestration des données, la persistance des données et l’analyse des données en temps-réel. Le principe général est de permettre, de manière fiable, le rapprochement entre les producteurs des données et les consommateurs de données. Le but ultime est de garantir que les différentes sources de données soient correctement transmises aux différents métiers, afin que les bonnes décisions puissent être prises, avec un minimum de risque, au bon moment. Dès l’instant où toutes les étapes et services déployés dans la Smart Data Fabric respectent les bonnes pratiques, les données peuvent être considérées comme saines. Une Smart Data Fabric doit également traiter les capacités techniques clés telles que : La scalabilité à hautes performances L'évolutivité dynamique à la hausse et à la baisse, de manière transparente, quelle que soit la taille du volume de données La Gestion des charges de travail opérationnelles et analytiques, à l'échelle de l'entreprise L’accessibilité La prise en charge de tous les modes d'accès aux données, sources de données et types de données, et intégration des données de référence et transactionnelles, au repos ou en transaction L'ingestion et unification des données des systèmes dans le Cloud, et On-Premise, dans n'importe quel format – structuré ou non structuré La couche d'accès logique de la structure de données doit permettre la consommation de données, quel que soit l'endroit ou la manière dont les données sont stockées ou distribuées Le déploiement Le support du déploiement dans un environnement multicloud, sur site ou hybride Le support d’une stratégie de virtualisation intelligente des données La sécurité Le chiffrement : les données doivent pouvoir être chiffrées et/ou masquées pour respecter les réglementations sur la confidentialité des données La traçabilité : être en mesure de fournir les informations d'identification des utilisateurs aux systèmes sources, afin que les droits d'accès soient correctement vérifiés et autorisés Quand la Smart Data Fabric a atteint son objectif, l’entreprise a elle-même atteint sa maturité Data Driven. La mise en place d’une Smart Data Fabric pour la Supply Chain La chaîne d’approvisionnement nécessite de coordonner un ensemble complexe d’intervenants et de SI différents : centrale d’achat, fournisseurs, site de production, plateforme de stockage, plateforme logistique, transport… jusqu’à la livraison et la satisfaction du client final. Si la mise en place d’une Data Fabric au sein de la supply chain est un pré-requis indispensable quant à la mise en place d’une stratégie autour de la donnée, c’est notamment parce qu’elle permet de lier et d’orchestrer tous ces systèmes d’information entre eux. Elle va aider les entreprises à exploiter tout le potentiel de leurs données afin de répondre aux besoins business et gagner en compétitivité. En effet, grâce à cette Data Fabric, les responsables de la chaîne d’approvisionnement pourront optimiser les coûts, améliorer les performances opérationnelles et renforcer l'efficacité et l’agilité de la chaîne d’approvisionnement quel que soit l'emplacement de leurs données et applications. Après avoir obtenu des informations exploitables tirées directement des données, les responsables métiers pourront anticiper les problèmes ou encore mieux gérer les risques de sécurité et de conformité. En somme, la Data Fabric permet d’avoir une vue d’ensemble complète, en temps réel, de toute l’activité de la chaîne d’approvisionnement. InterSystems, partenaire de confiance dans le déploiement d’une Data Fabric Depuis sa création, InterSystems aide les entreprises à exploiter tout le potentiel des données dont elles ont besoin pour être plus performantes et améliorer l'expérience clients. C’est donc naturellement que l’entreprise s’est lancée dans le développement d’une nouvelle génération de plateformes de gestion de données qui traite l’ensemble du cycle de vie de la donnée dans un socle unifié : InterSystems IRIS®. À destination des professionnels de la supply chain InterSystems IRIS permet de mieux valoriser vos données via la mise en place d’une architecture de type « Data Fabric ». Nous vous invitons à participer au Supply Chain Event 2022 durant lequel nous vous proposons un programme autour de la tour de contrôle afin de capturer et d'exploiter en temps réel les données opérationnelles provenant de l’ensemble de votre écosystème dans un seul outil. Rejoignez-nous pour découvrir notre atelier et nos démonstrations pendant Supply Chain Event 2022 !
Article
Guillaume Rongier · Mars 26

Génération des spécifications OpenAPI

Introduction Une API REST (Representational State Transfer) est une interface qui permet de faire communiquer différentes applications entre elles via le protocole HTTP, en utilisant des opérations standard telles que GET, POST, PUT, et DELETE. Les API REST sont largement utilisées dans le développement de logiciels pour exposer des services accessibles par d'autres applications, permettant ainsi l'intégration entre différents systèmes. Cependant, pour garantir que les APIs soient faciles à comprendre et à utiliser, une bonne documentation est essentielle. C'est là qu'OpenAPI entre en jeu. OpenAPI est une norme de description pour les APIs RESTful. Elle permet de définir de manière structurée les fonctionnalités d'une API, en spécifiant les extrémités disponibles, les types de données acceptés et renvoyés, les paramètres requis et les réponses attendues. Toutes ces informations sont rassemblées dans un fichier de spécification (généralement avec une extension .yaml ou .json), qui peut être interprété par des outils automatisés pour générer du code, de la documentation, etc. La spécification OpenAPI Specification est conçue pour être lisible par les machines et les humains, permettant la description, la production, la consommation et la visualisation de services web RESTful de manière standardisée. Par conséquent, un document OpenAPI représente une description formelle de l'API, utile à la fois pour les développeurs qui ont besoin de l'utiliser et pour les outils qui peuvent l'exploiter pour automatiser divers processus. Pourquoi est-il utile de définir un fichier de spécifications? L'adoption d'OpenAPI pour documenter une API offre plusieurs avantages, notamment: Clarté: elle fournit une documentation détaillée et structurée, permettant aux développeurs de comprendre rapidement comment interagir avec l'API, quelles requêtes doivent être envoyées et quelles données peuvent être attendues en réponse. Automatisation: la documentation peut être générée automatiquement à partir du code, et rester à jour avec tout changement d'API. Interactivité: des outils tels que Swagger, une suite open source de documentation et de test d'API, incluent Swagger UI. Cela vous permet d'explorer et de tester les API directement depuis le navigateur, ce qui simplifie le développement, la vérification et la compréhension des API. Normalisation: l'utilisation d'OpenAPI garantit que la documentation suit un format commun et reconnu, ce qui facilite l'intégration avec d'autres outils et services. Comment créer un document OpenAPI? Il existe deux approches principales pour générer un fichier de spécification OpenAPI: Approche "code-first" (automatique): si une API REST a déjà été développée dans InterSystems IRIS, vous pouvez générer automatiquement la documentation OpenAPI sans écrire de fichier de spécification manuellement. Approche "specification-first" (manuelle): dans ce cas, le fichier OpenAPI est écrit manuellement en YAML ou JSON, décrivant tous les points de terminaison, paramètres et réponses attendues. Cette approche est utile lorsque vous souhaitez définir l'API avant de la mettre en œuvre, ce qui facilite la conception et le partage avec d'autres développeurs ou parties prenantes. Approche automatique Il existe deux façons de générer automatiquement le fichier de spécification OpenAPI dans InterSystems IRIS. Méthode 1 : Utilisation de la fonction GetWebRESTApplication Une approche consiste à utiliser la fonction GetWebRESTApplication fournie par la classe %REST.API.Un exemple pratique d'utilisation consiste à ajouter la fonction suivante dans la classe de répartition: ClassMethod GenerateOpenAPI() As %Status { // Le nom de l'application REST Set webApplication = "MyAPP" // Remplacez par le nom de votre application web // Récupérez la documentation OpenAPI 2.0 Set sc = ##class(%REST.API).GetWebRESTApplication("", webApplication, .swagger) If $$$ISERR(sc) { Quit sc // Si une erreur s'est produite, quittez la méthode } // Renvoyez la documentation au format JSON Set %response.ContentType = "application/json" Do ##class(OMRREST.impl).%WriteResponse(swagger.%ToJSON()) Quit $$$OK } Ajoutez en outre le chemin d'accès suivant à l'UrlMap: <Route Url="/openapi" Method="GET" Call="GenerateOpenAPI"/> À ce stade, vous aurez tout ce qu'il vous faut pour générer le fichier de spécification à partir de votre classe d'envoi. Pour consulter la documentation, connectez-vous à l'URL indiquée (où MyWebapp est le nom de votre application web, tel que défini dans le portail de gestion): <host>:<port>/MyWebapp/openapi Le JSON ainsi généré représente la spécification OpenAPI de votre API. Après avoir exploré la deuxième méthode, nous verrons comment la visualiser et la tester dans Swagger. Méthode 2 : Utilisation de l'API de gestion Une autre façon de générer le fichier de spécification OpenAPI consiste à utiliser l' API de gestion InterSystems IRIS. Pour appeler ce service, vous pouvez utiliser des outils tels que Postman, un outil de développement qui vous permet de tester, documenter et automatiser les API.Postman fournit une interface simple et intuitive pour l'envoi de requêtes HTTP (GET, POST, PUT, DELETE, etc.), la visualisation des réponses, la gestion de l'authentification et la création de tests automatisés. Pour formuler la requête à l'aide de Postman, procédez comme suit: Cliquez sur le bouton New et créez une requête HTTP. Configurez la requête comme suit et envoyez-la: Sélectionnez la méthode GET comme méthode HTTP. Spécifiez l'URL dans le format suivant, en utilisant l' <baseURL> de votre instance: https://<baseURL>/api/mgmnt/v1/namespace/myapp Ici, namespace est le nom de l'espace de noms où vous avez créé d le service REST, et myapp et le nom de votre application. Définissez la méthode d' Authorisation sur Basic Auth et fournissez le nom d'utilisateur et le mot de passe d'un utilisateur ayant un accès en lecture à l'espace de noms spécifié. Une fois le JSON généré, il peut être visualisé et testé à l'aide d'outils tels que Swagger Editor. { "info":{ "title":"", "description":"", "version":"", "x-ISC_Namespace":"MyNamespace" }, "basePath":"/MyWebapp", "paths":{ "/loginForm":{ "post":{ "parameters":[ { "name":"payloadBody", "in":"body", "description":"Request body contents", "required":false, "schema":{ "type":"string" } } ], "operationId":"loginForm", "x-ISC_ServiceMethod":"loginForm", "responses":{ "default":{ "description":"(Unexpected Error)" }, "200":{ "description":"(Expected Result)" } } } }, "/refresh":{ "post":{ "parameters":[ { "name":"payloadBody", "in":"body", "description":"Request body contents", "required":false, "schema":{ "type":"string" } } ], "operationId":"refresh", "x-ISC_ServiceMethod":"refresh", "responses":{ "default":{ "description":"(Unexpected Error)" }, "200":{ "description":"(Expected Result)" } } } }, "/logout":{ "post":{ "parameters":[ { "name":"payloadBody", "in":"body", "description":"Request body contents", "required":false, "schema":{ "type":"string" } } ], "operationId":"logout", "x-ISC_ServiceMethod":"logout", "responses":{ "default":{ "description":"(Unexpected Error)" }, "200":{ "description":"(Expected Result)" } } } }, "/openapi":{ "get":{ "operationId":"GenerateOpenAPI", "x-ISC_ServiceMethod":"GenerateOpenAPI", "responses":{ "default":{ "description":"(Unexpected Error)" }, "200":{ "description":"(Expected Result)" } } } } }, "swagger":"2.0" } Approche manuelle L'approche manuelle pour générer un document OpenAPI consiste à écrire manuellement le fichier de spécification au format YAML ou JSON. Cette approche est particulièrement utile lorsque vous souhaitez contrôler entièrement la conception de l'API avant sa mise en œuvre, ou lorsque vous documentez une API déjà existante sans recourir à des outils automatisés. Pour rédiger le fichier de spécification OpenAPI, vous pouvez vous référer à , la documentation officielle de la version 2.0 de la spécification OpenAPI, où vous trouverez des renseignements sur les champs obligatoires et sur la manière de décrire les points de terminaison, les paramètres, les réponses, etc. Ce guide détaillé vous aidera à comprendre comment structurer correctement le fichier YAML ou JSON afin de respecter les normes OpenAPI. Un bon exemple d'utilisation de cette approche est la création d'un service REST à l'aide des méthodes décrites dans la documentation officielle d'InterSystems IRIS.Vous trouverez une introduction au développement et à la configuration d'une application REST dans IRIS sur cette page de la documentation, qui décrit étape par étape les méthodes nécessaires pour exposer une application RESTful avec IRIS. Merci pour la traduction, ça aide pour ceux qui sont moins à l'aise en anglais 😁Il manque juste le lien pour la documentation sur le dernier paragraphe
Article
Guillaume Rongier · Juin 15, 2022

Comment publier rapidement des RESTful API dans OAS 3.0 à l'aide de l'outil IRIS ApiPub

## Introduction Nous sommes à l'ère de **l'économie multiplateforme** et les API sont la *"colle "* de ce scénario numérique. Étant donné leur importance, les développeurs les considèrent comme un **service** ou un **produit** à consommer. Par conséquent, **l'expérience** d'utilisation est un facteur crucial de leur **succès**. Afin d'améliorer cette expérience, des normes de spécification telles que [la spécification OpenAPI (OAS)](https://swagger.io/specification/#:~:text=Introduction,or%20through%20network%20traffic%20inspection.) sont de plus en plus adoptées dans le développement des API RESTFul. ## IRIS ApiPub - qu'est-ce que c'est ? IRIS ApiPub est un projet de type code source ouvert [Open Source](https://en.wikipedia.org/wiki/Open_source) dont l'objectif principal est de **publier** automatiquement **les API RESTful** créées avec la technologie [Intersystems IRIS](https://www.intersystems.com/try-intersystems-iris-for-free/), de la manière la plus simple et la plus rapide possible en utilisant la norme [Open Specification API](https://swagger.io/specification/) (OAS) standard, version 3.0. Il permet à l'utilisateur de se concentrer sur la **mise en œuvre** et les **règles métier** (méthodes Web) de l'API, en abstrayant et en automatisant les autres aspects liés à **la documentation, l'exposition, l'exécution et la surveillance** des services. ![](/sites/default/files/inline/images/petstore.gif) Ce projet comprend également un exemple complet de mise en œuvre (**apiPub.samples.api**) de la [Swagger Petstore](https://app.swaggerhub.com/apis/Colon-Org/Swagger-PetStore-3.0/1.1), qui est l'*échantillon* officiel de [swagger](https://swagger.io/). ## Testez-le avec vos services SOAP actuels Si vous avez déjà publié des services SOAP, vous pouvez les tester en utilisant Rest/JSON avec OAS 3.0. ![](/sites/default/files/inline/images/soaptooasrest_0.png) Lors de la publication de méthodes avec des types complexes, la classe de l'objet doit être une sous-classe de %XML.Adapter. De cette manière, les services SOAP précédemment installés sont rendus automatiquement compatibles. ![](/sites/default/files/inline/images/xmladaptorcompat_0.png) ## Surveillez vos API avec IRIS Analytics Activez la surveillance des API pour **gérer** et **suivre** tous vos *Appels Rest*. Vous pouvez également configurer vos propres indicateurs. ![](/sites/default/files/inline/images/monitoryourapi.gif) ## Installation 1. Effectuez un *clone/git pull* depuis le dépôt dans le répertoire local. ``` $ git clone https://github.com/devecchijr/apiPub.git ``` 2. Ouvrez le terminal dans ce répertoire et exécutez la commande suivante : ``` $ docker-compose up -d ``` 3. Exécutez le conteneur IRIS avec le projet : ``` $ docker-compose up -d ``` ## Test de l'application Ouvrez l'URL http://localhost:52773/swagger-ui/index.html de swagger Essayez d'exécuter une opération à l'aide de l'API Petstore, par exemple en effectuant un *postage* d'un nouveau *pet*. Consultez la [table de bord du moniteur apiPub](http://localhost:52773/csp/irisapp/_DeepSee.UserPortal.DashboardViewer.zen?DASHBOARD=apiPub_Monitor_Dashboard/apiPub%20Monitor.dashboard). Essayez d'explorer le domaine petStore pour explorer et analyser les messages. Modifiez ou créez des méthodes dans la classe [apiPub.samples.api](https://github.com/devecchijr/apiPub/blob/master/src/apiPub/samples/api.cls) et revenez à la documentation générée. Notez que toutes les modifications sont automatiquement reflétées dans la documentation OAS ou dans les schémas. ## **Publiez votre API selon la norme OAS 3.0 en seulement 3 étapes :** ## Étape 1 Définissez la classe d'implémentation de votre API et **balises** les méthodes avec l'attribut [WebMethod] ![](/sites/default/files/inline/images/labelingimplementationmethod.gif) *Cette étape n'est pas nécessaire si vous disposez déjà d'une mise en œuvre de WebServices.* ## Étape 2 Créez une **sous-classe** de apiPub.core.service et définissez sa propriété DispatchClass comme la classe Implementation créée précédemment. Incluez également le chemin de la documentation OAS 3.0. Si vous le souhaitez, pointez vers la classe apiPub.samples.api (PetStore). ![](/sites/default/files/inline/images/configuringserviceclass.gif) ## Étape 3 Créez une application Web et définissez la classe de répartition comme la classe de service créée ci-dessus. ![](/sites/default/files/inline/images/creatingwebapp.gif) ## Utilisation de Swagger Avec [iris-web-swagger-ui](https://openexchange.intersystems.com/package/iris-web-swagger-ui) vous pouvez exposer votre spécification de service. Il vous suffit de pointer vers le chemin de la documentation et... **VOILÁ!!** ![](/sites/default/files/inline/images/testingfirstmethod.gif) ## Définition de l'en-tête de la spécification OAS ![](/sites/default/files/inline/images/oasheader.png) Il existe deux façons de définir l'en-tête OAS 3.0 : La première consiste à créer un bloc JSON XDATA nommé *apiPub* dans la classe d'implémentation. Cette méthode autorise plus d'une balise et la modélisation est compatible avec la norme OAS 3.0. Les propriétés qui peuvent être personnalisées sont *info, tags* et *servers*. ``` XData apiPub [ MimeType = application/json ] { { "info" : { "description" : "Il s'agit d'un exemple de serveur Petstore. Vous pouvez en savoir plus sur Swagger à l'adresse suivante\n[http://swagger.io](http://swagger.io) or on\n[irc.freenode.net, #swagger](http://swagger.io/irc/).\n", "version" : "1.0.0", "title" : "IRIS Petstore (Dev First)", "termsOfService" : "http://swagger.io/terms/", "contact" : { "email" : "apiteam@swagger.io" }, "license" : { "name" : "Apache 2.0", "url" : "http://www.apache.org/licenses/LICENSE-2.0.html" } }, "tags" : [ { "name" : "pet", "description" : "Tout sur vos Pets", "externalDocs" : { "description" : "Pour en savoir plus", "url" : "http://swagger.io" } }, { "name" : "store", "description" : "Accès aux commandes du Petstore" }, { "name" : "user", "description" : "Opérations sur l'utilisateur", "externalDocs" : { "description" : "En savoir plus sur notre magasin", "url" : "http://swagger.io" } } ] } } ``` La seconde méthode consiste à définir des paramètres dans la classe d'implémentation, comme dans l'exemple suivant : ``` Parameter SERVICENAME = "My Service"; Parameter SERVICEURL = "http://localhost:52776/apipub"; Parameter TITLE As %String = "REST aux API SOAP"; Parameter DESCRIPTION As %String = "API pour le proxy des services Web SOAP via REST"; Parameter TERMSOFSERVICE As %String = "http://www.intersystems.com/terms-of-service/"; Parameter CONTACTNAME As %String = "John Doe"; Parameter CONTACTURL As %String = "https://www.intersystems.com/who-we-are/contact-us/"; Parameter CONTACTEMAIL As %String = "support@intersystems.com"; Parameter LICENSENAME As %String = "Copyright InterSystems Corporation, tous droits réservés."; Parameter LICENSEURL As %String = "http://docs.intersystems.com/latest/csp/docbook/copyright.pdf"; Parameter VERSION As %String = "1.0.0"; Parameter TAGNAME As %String = "Services"; Parameter TAGDESCRIPTION As %String = "Services d'héritage"; Parameter TAGDOCSDESCRIPTION As %String = "Pour en savoir plus"; Parameter TAGDOCSURL As %String = "http://intersystems.com"; ``` ## Personnalisez vos API ![](/sites/default/files/inline/images/customizeyourapi.png) Vous pouvez personnaliser plusieurs aspects de l'API, tels que les ***balises, les chemins et les verbes***. Pour cela, vous devez utiliser une notation spéciale, déclarée dans le commentaire de la méthode personnalisée. Syntaxe: > ***/// @apiPub[assignment clause]*** > [*Method/ClassMethod*] *methodName(params as type) As returnType* { > > } Toutes les personnalisations présentées à titre d'exemple dans cette documentation se trouvent dans la classe [apiPub.samples.api](https://github.com/devecchijr/apiPub/blob/master/src/apiPub/samples/api.cls). ## Personnalisation des verbes Lorsqu'aucun type complexe n'est utilisé comme paramètre d'entrée, apiPub attribue automatiquement le verbe *Get*. Dans le cas contraire, le verbe *Post* sera attribué. Si vous souhaitez personnaliser la méthode, ajoutez la ligne suivante aux commentaires de la méthode. > /// @apiPub[verb="*verb*"] Où *verbe* peut être **get, post, put, delete ou patch**. Exemple: > /// @apiPub[verb="put"] ## Personnalisation des chemins Cet outil attribue automatiquement des *chemins* ou des routages aux *Méthodes Web*. Il utilise le nom de la méthode comme *chemin*, par défaut. Si vous souhaitez personnaliser le **chemin**, ajoutez la ligne suivante aux commentaires de la méthode. > /// @apiPub[path="*path*"] Où *chemin* peut être n'importe quelle valeur précédée d'un slash, tant qu'il n'entre pas en conflit avec un autre *chemin* dans la même classe d'implémentation. Exemple: > /// @apiPub[path="/pet"] Une autre utilisation très courante du chemin est de définir un ou plusieurs paramètres dans le chemin lui-même. Pour cela, le nom du paramètre défini dans la méthode doit être entouré d'accolades. Exemple: > /// @apiPub[path="/pet/{petId}"] > Method getPetById(petId As %Integer) As apiPub.samples.Pet [ WebMethod ] > { > } Lorsque le nom du paramètre interne diffère du nom du paramètre affiché, le nom peut être égalisé selon l'exemple suivant : > /// @apiPub[path="/pet/{petId}"] > /// @apiPub[params.pId.name="petId"] > Method getPetById(pId As %Integer) As apiPub.samples.Pet [ WebMethod ] > { > } Dans l'exemple ci-dessus, le paramètre interne *pId* est affiché sous la forme *petId*. ## Personnalisation des balises Il est possible de définir le **tag** (regroupement) de la méthode lorsque plus d'un tag est défini dans l'en-tête. > /// @apiPub[tag="*value*"] Exemple: > /// @apiPub[tag="user"] ## Personnalisation du succès *Code d'état* Si vous souhaitez modifier le *Code d'état* de réussite de la méthode, qui est ***200*** par défaut, il convient d'utiliser la notation suivante. > /// @apiPub[successfulCode="*code*"] Exemple: > /// @apiPub[successfulCode="201"] ## Personnalisation de l'exception *Code d'état* Cet outil traite toutes les exceptions comme ***Code d'état 500*** par défaut. Si vous souhaitez ajouter de nouveaux codes d'exception à la documentation, utilisez la notation suivante. > /// @apiPub[statusCodes=[{code:"*code*",description:"*description*"}]] Où la propriété *statusCodes* est un tableau d'objets contenant le code et la description. Exemple: > /// @apiPub[statusCodes=[ > /// {"code":"400","description":"Invalid ID supplied"} > /// ,{"code":"404","description":"Pet not found"}] > /// ] Lorsque vous soulevez l'exception, incluez *Code d'état* dans la description de l'exception entre les caractères "". Exemple: > Throw ##Class(%Exception.StatusException).CreateFromStatus($$$ERROR($$$GeneralError, "****** Invalid ID supplied"))} Voir la méthode ***getPetById*** de la classe [apiPub.samples.api](https://github.com/devecchijr/apiPub/blob/master/src/apiPub/samples/api.cls) ## Marquer l'API comme déconseillé Pour que l'API soit affichée comme ***déconseillée***, la notation suivante doit être utilisée : > /// @apiPub[deprecated="true"] ## Personnalisation de l'*operationId* Selon la spécification OAS, ***operationId*** est une chaîne unique utilisée pour identifier une API ou une opération. Dans cet outil, il est utilisé dans le même but lors des opérations de [surveillance et suivi](https://github.com/devecchijr/apiPub#monitore-a-chamada-das-suas-apis-com-o-iris-analytics) operations. Par défaut, elle porte le même nom que la méthode de la classe d'implémentation. Si vous souhaitez le modifier, utilisez la notation suivante > /// @apiPub[operationId="updatePetWithForm"] ## Modification du jeu de caractères de la méthode Le jeu de caractères par défaut est généralement défini à l'aide du paramètre CHARSET de la classe de service, décrit dans [étape 2](https://github.com/devecchijr/apiPub#passo-2). Si vous souhaitez personnaliser le jeu de caractères d'une méthode, vous devez utiliser la notation suivante :: > /// @apiPub[charset="*value*"] Exemple: > /// @apiPub[charset="UTF-8"] ## Personnalisation des noms et autres caractéristiques des paramètres Vous pouvez personnaliser plusieurs aspects des paramètres d'entrée et de sortie de chaque méthode, tels que les noms et les descriptions qui seront affichés pour chaque paramètre. Pour personnaliser un paramètre spécifique, utilisez la notation suivante > /// @apiPub[params.*paramId.property*="*value*"] ou pour des réponses : > /// @apiPub[response.*property*="*value*"] Exemple: > /// @apiPub[params.pId.name="petId"] > /// @apiPub[params.pId.description="ID of pet to return"] Dans ce cas, le nom *petId* et la description *ID du pet à rendre* sont attribués au paramètre défini comme *pId* Lorsque la personnalisation n'est pas spécifique à un paramètre donné, la notation suivante est utilisée > /// @apiPub[params.*property*="*value*"] Dans l'exemple suivant, la description *Ceci ne peut être fait que par l'utilisateur connecté* est attribuée à l'ensemble de la *demande*, et pas seulement à un seul paramètre : > /// @apiPub[params.description="Ceci ne peut être fait que par l'utilisateur connecté."] ## Autres propriétés qui peuvent être personnalisées pour des paramètres spécifiques Utilisez la notation suivante pour les paramètres d'entrée ou de sortie : > /// @apiPub[params.*paramId.property*="*value*"] Pour les reponses: > /// @apiPub[response.*property*="*value*"] | Propriété | | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ***required***: "true" si le paramètre est obligatoire. Tous les paramètres de type **path** sont déjà automatiquement requis | | ***schema.items.enum***: afficher les énumérateurs pour les types %String ou %Library.DynamicArray. Voir la méthode ***findByStatus*** de la classe [apiPub.samples.api](https://github.com/devecchijr/apiPub/blob/master/src/apiPub/samples/api.cls) | | ***schema.default***: Pointe vers une valeur par défaut pour les énumérateurs | | ***inputType***: Pour les types simples, il s'agit par défaut d'un **paramètre de requête**. Pour les types complexes (corps), il s'agit par défaut de **application/json**. Dans le cas où vous souhaitez changer le type d'entrée, vous pouvez utiliser ce paramètre. Exemple d'utilisation : Téléchargement d'une image, qui n'est généralement pas de type JSON. Voir la méthode ***uploadImage*** de la classe [apiPub.samples.api](https://github.com/devecchijr/apiPub/blob/master/src/apiPub/samples/api.cls). | | ***outputType***: Pour les types %Status, la valeur par défaut est **header**. Pour les autres types, la valeur par défaut est **application/json**. Si vous souhaitez modifier le type de sortie, vous pouvez utiliser ce paramètre. Exemple d'utilisation : Retourner un jeton ("text/plain"). Voir la méthode ***loginUser*** de la classe [apiPub.samples.api](https://github.com/devecchijr/apiPub/blob/master/src/apiPub/samples/api.cls) | ## Relier des schémas analysables à des types JSON dynamiques ***(%Library.DynamicObject)*** ![](parsingDynamicTypes.gif) Vous pouvez relier les schémas [OAS 3.0](https://swagger.io/docs/specification/data-models/) aux types dynamiques internes [](https://docs.intersystems.com/hs20201/csp/docbook/DocBook.UI.Page.cls?KEY=GJSON_create) L'avantage d'associer le schéma au paramètre, outre le fait d'informer l'utilisateur sur une spécification d'objet requise, est l'analyse automatique de la demande, qui est effectuée pendant l'appel API. Si l'utilisateur de l'API, par exemple, soumet une propriété qui ne figure pas dans le schéma, ou envoie une date dans un format non valide, ou n'inclut pas une propriété obligatoire, une ou plusieurs erreurs seront renvoyées à l'utilisateur contenant des informations sur ces problèmes. La première étape consiste à inclure le schéma souhaité dans le bloc XDATA, comme indiqué ci-dessous. Dans ce cas, le schéma appelé *User* peut être utilisé par n'importe quelle méthode. Il doit suivre les mêmes règles que celles utilisées dans la modélisation [OAS 3.0] (https://swagger.io/docs/specification/data-models/). ``` XData apiPub [ MimeType = application/json ] { { "schemas": { "User": { "type": "object", "required": [ "id" ], "properties": { "id": { "type": "integer", "format": "int64" }, "username": { "type": "string" }, "firstName": { "type": "string" }, "lastName": { "type": "string" }, "email": { "type": "string" }, "password": { "type": "string" }, "phone": { "type": "string" }, "userStatus": { "type": "integer", "description": "(short) User Status" } } } } } } ``` La deuxième étape consiste à associer le nom du schéma renseigné à l'étape précédente au paramètre interne de type [%Library.DynamicObject](https://docs.intersystems.com/hs20201/csp/docbook/DocBook.UI.Page.cls?KEY=GJSON_create) en utilisant la notation suivante : > /// @apiPub[params.*paramId*.*schema*="*schema name*"] Exemple associant le paramètre *user* au schéma *User* : ``` /// @apiPub[params.user.schema="User"] Method updateUserUsingOASSchema(username As %String, user As %Library.DynamicObject) As %Status [ WebMethod ] { code... } ``` Exemple de soumission d'une requête avec une erreur. La propriété username2 n'existe pas dans le schéma *User*. La propriété id n'est pas non plus définie alors qu'elle est requise : ``` { "username2": "devecchijr", "firstName": "claudio", "lastName": "devecchi junior", "email": "devecchijr@gmail.com", "password": "string", "phone": "string", "userStatus": 0 } ``` Exemple d'une réponse avec une erreur : ``` { "statusCode": 0, "message": "ERROR #5001: Path User.id is required; Invalid path: User.username2", "errorCode": 5001 } ``` Voir les méthodes ***updateUserUsingOASSchema*** et ***getInventory*** de la classe [apiPub.samples.api](https://github.com/devecchijr/apiPub/blob/master/src/apiPub/samples/api.cls). La méthode ***getInventory*** est un exemple de schéma associé à la sortie de la méthode (réponse), elle n'est donc pas analysable. ### Générer le schéma OAS 3.0 à partir d'un objet JSON Pour faciliter la génération du schéma OAS 3.0, vous pouvez utiliser les éléments suivants :: **Définissez** une variable avec un échantillon de l'objet JSON. ``` set myObject = {"prop1":"2020-10-15","prop2":true, "prop3":555.55, "prop4":["banana","orange","apple"]} ``` **Utilisez la méthode utilitaire** de la classe [apiPub.core.publisher](https://github.com/devecchijr/apiPub/blob/master/src/apiPub/core/publisher.cls) pour générer le schéma : ``` do ##class(apiPub.core.publisher).TemplateToOpenApiSchema(myObject,"objectName",.schema) ``` **Copiez et collez** le schéma renvoyé dans le bloc XDATA : Exemple: ``` XData apiPub [ MimeType = application/json ] { { "schemas": { { "objectName": { "type":"object", "properties":{ "prop1":{ "type":"string", "format":"date", "example":"2020-10-15" }, "prop2":{ "type":"boolean", "example":true }, "prop3":{ "type":"number", "example":555.55 }, "prop4":{ "type":"array", "items":{ "type":"string", "example":"apple" } } } } } } } } ``` ## Activer la surveillance *(facultatif)* 1 - Ajoutez et activez les composants suivants dans votre *Production* (*IRIS Interopérabilité*) | Composant | Type | | ---------------- | -------------- | | apiPub.tracer.bm | Service (BS) | | apiPub.tracer.bs | Service (BS) | | apiPub.tracer.bo | Opération (BO) | 2 - Activez la surveillance de la classe décrite dans [l'étape 2] (https://github.com/devecchijr/apiPub#passo-2) Le paramètre ***Traceable*** doit être activé. ``` Parameter Traceable As %Boolean = 1; Parameter TracerBSName = "apiPub.tracer.bs"; Parameter APIDomain = "samples"; ``` Le paramètre ***APIDomain*** est utilisé pour regrouper les API à surveiller. 3 - Importez les tableaux de bord ``` zn "IRISAPP" Set sc = ##class(%DeepSee.UserLibrary.Utils).%ProcessContainer("apiPub.tracer.dashboards",1) ``` Vous pouvez également créer d'autres tableaux de bord, basés sur le cube ***apiPub Monitor***. ## Utilisez cet outil conjointement avec Intersystems API Manager Acheminez vos API générées et bénéficiez de l'[Intersystems API Manager] (https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_IAM) ## Compatibilité [ApiPub](https://github.com/devecchijr/apiPub#iris-apipub) est compatible avec [Intersystems IRIS](https://www.intersystems.com/products/intersystems-iris/) ou [Intersystems IRIS pour la santé](https://www.intersystems.com/products/intersystems-iris-for-health/), à partir de la version 2018.1. ## Dépôt ***Github***: [apiPub](https://github.com/devecchijr/apiPub#iris-apipub) Excellent! @Damiano.Porrovecchio : Je pense que tu as testé et même modifié ce module. N'hésite pas à laisser un feedback J'ai repris le code dont j'avais besoin. Fonctionne super bien ! Merci pour le travail.
Article
Lorenzo Scalese · Avr 21, 2023

Créer un Chatbot avec IRIS et Python

![picture](https://raw.githubusercontent.com/renatobanzai/iris-python-covid19/master/img/chatbot.gif) # Créer un Chatbot avec IRIS et Python Dans cet article, je vais montrer comment intégrer la base de données IRIS d'InterSystems avec Python pour servir un Modèle d'apprentissage automatique du traitement du langage naturel (NLP). ### Pourquoi Python ? Avec une large adoption et utilisation dans le monde, Python a une grande communauté et un grand nombre d'accélérateurs et de bibliothèques pour déployer n'importe quel type d'application. Vous pouvez également consulter : https://www.python.org/about/apps/ pour en savoir plus. ### Globales Iris Lorsque j'ai commencé à me familiariser avec les globales (^globals), leur utilisation m'est devenue familière en tant que moyen rapide d'ingérer des données dans un modèle de données prêt à l'emploi. Dans un premier temps, je vais donc utiliser les globales (^globals) pour stocker les données d'entraînement et les conversations pour enregistrer le comportement du chatbot. ### Traitement du langage naturel Le traitement du langage naturel ou NLP (Natural Language Processing) est un domaine de l'IA qui crée la capacité de lire et de comprendre le sens de nos langues pour les machines. Comme vous pouvez l'imaginer, ce n'est pas très simple, mais je vais vous montrer comment faire vos premiers pas dans ce vaste et beau domaine. ### Démo - Essayez-le vous-même J'ai déployé l'application Chatbot en tant que démonstration ici : [http://iris-python-suite.eastus.cloudapp.azure.com:8080](http://iris-python-suite.eastus.cloudapp.azure.com:8080) ### Comment ça marche? ### Apprentissage automatique Il est tout d'abord bon de savoir que l'apprentissage automatique a un paradigme différent de celui du développement de logiciels courants. Le point principal qui est difficile à comprendre est le cycle de développement des modèles d'apprentissage automatique. **Alerte aux explications superficielles** Le cycle de développement d'une application standard est le suivant : Développer le code->Tester (avec des données de développement)->Déployer (en utilisant des données réelles) L'apprentissage automatique du code en lui-même n'a pas la même valeur. La responsabilité est partagée avec les données ! Et pas n'importe quelles données, mais de vraies données ! Car le code final à exécuter est généré par une fusion entre les concepts de développement et les données utilisées. Un cycle d'application de l'apprentissage automatique devrait donc se dérouler de la manière suivante : Développer (Former) Modèle+Données réelles->Valider->Déployer le résultat de ceci (un Modèle) ### Comment former le modèle? Il existe de nombreuses techniques pour entraîner les modèles et chaque cas et objectif nécessite une courbe d'apprentissage importante. Dans ce cas, j'utilise la bibliothèque [ChatterBot](https://github.com/gunthercox/ChatterBot) qui encapsule certaines techniques et fournit des méthodes d'entraînement et des données d'entraînement prétraitées pour nous aider à nous concentrer sur les résultats. ### Langages de modèles pré-entraînés et modèles personnalisés Vous pouvez commencer par cela pour avoir un chatbot conversationnel de base. Vous pouvez également créer toutes les données nécessaires à l'entraînement de votre chatbot, et cela peut être parfait pour vos besoins, mais terriblement difficile à réaliser en un temps limité. Dans ce projet, j'utilise en_core_web_sm comme base de conversation et je la fusionne avec des données d'entraînement personnalisées que vous pouvez créer à l'aide d'un [formulaire](http://iris-python-suite.eastus.cloudapp.azure.com/chatbot-training-data) ### Architecture de base ![image](https://raw.githubusercontent.com/renatobanzai/iris-python-covid19/master/img/chatbot_diagram.png) ### Qu'ai-je utilisé en Python ? Dans cet environnement d'application, j'utilise Python 3.7 avec les modules suivants : - PyYAML=1.0.0 - chatterbot>=1.0.0 - chatterbot-corpus>=1.2.0 - SQLAlchemy>=1.2 - ./nativeAPI_wheel/irisnative-1.0.0-cp34-abi3-linux_x86_64.whl ### Structure de projet Ce projet a une structure simple et facile à comprendre. Dans le dossier principal, nous avons trois sous-dossiers importants : - ./app: avec tout le **code d'application** et la configuration d'installation. - ./iris: avec **InterSystems IRIS dockerfile** préparant à servir l'application. - ./data: Pour relier l'hôte à l'environnement du conteneur par un **volume** ### Structure de l'application À l'intérieur du répertoire ./app, nous trouvons quelques fichiers : - chatbot.py : avec la mise en œuvre de l'application web - iris_python_suite.py : une classe avec quelques accélérateurs à utiliser avec IRIS Database et Python par l'API native d'IRIS. ### Structure de la base de données Cette application utilise Intersystems IRIS comme référentiel, les globales utilisées sont : - ^chatbot.training.data : stocke toutes les données d'entraînement personnalisées sous forme de questions et de réponses. - ^chatbot.conversation : stocke toutes les données de conversation. - ^chatbot.training.isupdated : contrôle le pipeline de formation. ### Produits de mon autre solution Je n'ai pas créé de rapport pour toutes les conversations mais ce n'est pas un problème, grâce à mon visualiseur de graphes globaux je peux suivre les conversations. ![image](https://raw.githubusercontent.com/renatobanzai/iris-python-covid19/master/img/conversations.png) ## Exécution de l'application par vous-même ### Conditions préalables * git * docker et docker-compose (et plus de paramètres de mémoire dans docker au moins 4 Go) * accès à un terminal dans votre environnement ### Étapes Avec docker-compose, vous pouvez facilement mettre en place un environnement avec toutes les pièces et configurations. Allez dans le dossier iris-python-covid19 et tapez ce texte : ``` $ docker compose build $ docker compose up ``` ### Durée estimée de mise en place des conteneurs La première exécution dépendra de votre lien internet pour télécharger les images et les dépendances. Si la durée est supérieure à 15 minutes, il est probable que quelque chose ne fonctionne pas, n'hésitez pas à nous en faire part ici. Après la première exécution, les exécutions suivantes seront plus performantes et prendront moins de 2 minutes. ### Si tout est correct Après un certain temps, vous pouvez ouvrir votre navigateur et aller à l'adresse : La forme des données d'apprentissage ``` http://localhost:8050/chatbot-training-data ``` Le chatbot ``` http://localhost:8080 ``` ### Vous devriez consulter le portail d'administration d'IRIS Pour le moment, j'utilise l'espace de noms USER. ``` http://localhost:9092 user: _SYSTEM pass: theansweris42 ``` ### Si cet article vous est utile ou si vous en aimez le contenu, votez : Cette application est au concours actuel sur open exchange, vous pouvez voter pour mon application **iris-python-suite** ici (https://openexchange.intersystems.com/contest/current)
Article
Guillaume Rongier · Avr 5, 2023

Pourquoi COVID-19 est-il également dangereux pour l'apprentissage automatique ? (Partie I)

Il y a quelques mois, j'ai lu [cet article intéressant de la MIT Technology Review](https://www.technologyreview.com/2020/05/11/1001563/covid-pandemic-broken-ai-machine-learning-amazon-retail-fraud-humans-in-the-loop/), qui explique comment la pandémie de COVID-19 pose des défis aux équipes informatiques du monde entier en ce qui concerne leurs systèmes d'apprentissage automatique (ML). Cet article m'a incité à réfléchir à la manière de traiter les problèmes de performance après le déploiement d'un modèle de ML. J'ai simulé un simple scénario de problème de performance dans une application modèle de la technologie Open Exchange - [iris-integratedml-monitor-example](https://openexchange.intersystems.com/package/iris-integratedml-monitor-example), qui participe au concours IA d'InterSystems IRIS (InterSystems IRIS AI Contest). S'il vous plaît, après avoir lu cet article, vous pouvez le consulter et, si vous l'aimez, [votez pour moi](https://openexchange.intersystems.com/contest/current)! :) # Contenu ### Partie I: * [Les systèmes IRIS IntegratedML et ML](#iris_integratedml_and_ml_systems) * [Entre les anciennes et les nouvelles normalités](#between_the_old_and_new_normal) ### Partie II: * [Surveillance des performances du ML](#monitoring_ml_performance) * [Un cas d'utilisation simple](#a_simple_use_case) * [Travaux futurs](#future_works) # Les systèmes IRIS IntegratedML et ML Avant de parler de COVID-19 et de son impact sur les systèmes ML dans le monde entier, parlons rapidement d'InterSystems IRIS IntegratedML. En automatisant des tâches telles que la sélection des caractéristiques et en s'intégrant au langage de manipulation de données SQL standard, IntegratedML pourrait nous aider à développer et à déployer une solution de ML. Par exemple, après avoir manipulé et analysé correctement des données provenant de rendez-vous médicaux, vous pouvez configurer un modèle de ML pour prédire la présence ou l'absence des patients à l'aide de ces instructions SQL : ```sql CREATE MODEL AppointmentsPredection PREDICTING (Show) FROM MedicalAppointments TRAIN MODEL AppointmentsPredection FROM MedicalAppointments VALIDATE MODEL AppointmentsPredection FROM MedicalAppointments ``` Le fournisseur AutoML choisira l'ensemble de caractéristiques et l'algorithme ML le plus performant. Dans ce cas, le fournisseur AutoML a sélectionné le modèle de régression logistique utilisant la bibliothèque scikit-learn, obtenant ainsi une exactitude de 90 %. ``` | | NOM_DU_MODÈLE | NOM_DU_MODÈLE_FORMÉ | FOURNISSEUR | HORODATAGE_FORMÉ | TYPE_DU_MODÈLE | INFOS_MODÈLE | |---|------------------------|-------------------------|----------|-------------------------|----------------|---------------------------------------------------| | 0 | AppointmentsPredection | AppointmentsPredection2 | AutoML | 2020-07-12 04:46:00.615 | classification | ModelType:Logistic Regression, Package:sklearn... | ``` ``` | NOM_MÉTRIQUE | Exactitude | Mesure F | Précision | Rappel | |--------------------------|----------|-----------|-----------|--------| | AppointmentsPredection21 | 0.9 | 0.94 | 0.98 | 0.91 | ``` Une fois que votre modèle de ML est déjà intégré à SQL, vous pouvez l'intégrer de manière transparente à votre système de réservation existant afin d'améliorer ses performances, en utilisant des estimations sur les patients qui seront présents et ceux qui ne le seront pas : ```sql SELECT PREDICT(AppointmentsPredection) As Predicted FROM MedicalAppointments WHERE ID = ? ``` Vous pouvez en savoir plus sur IntegrateML [ici](https://docs.intersystems.com/iris20202/csp/docbook/DocBook.UI.Page.cls?KEY=GIML). Si vous souhaitez obtenir un peu plus de détails sur ce modèle de prédiction simple, vous pouvez vous référer [à](https://github.com/jrpereirajr/iris-integratedml-monitor-example/blob/master/jupyter-samples/IntegeratedML-Monitor-Example.ipynb). Toutefois, comme les modèles d'IA/ML sont conçus pour s'adapter au comportement de la société, directement ou non, ils seront probablement très affectés lorsque ce comportement changera rapidement. Récemment, nous avons (malheureusement) pu expérimenter un tel scénario en raison de la pandémie de COVID-19. # Entre les anciennes et les nouvelles normalités Comme l'explique l'article de [MIT Technology Review](https://www.technologyreview.com/2020/05/11/1001563/covid-pandemic-broken-ai-machine-learning-amazon-retail-fraud-humans-in-the-loop/), la pandémie de COVID-19 a modifié remarquablement et rapidement le comportement de la société. J'ai effectué des recherches dans Google Trends pour des termes cités dans l'article, tels que masque N95, papier toilette et désinfectant pour les mains, afin de confirmer l'augmentation de leur popularité, à mesure que la pandémie se propageait dans le monde : Tel que cité dans l'article : > "Mais ils [les changements apportés par COVID-19] ont également affecté l'intelligence artificielle, causant des problèmes aux algorithmes qui fonctionnent dans les coulisses de la gestion des stocks, de la détection des fraudes, du marketing, et bien d'autres choses encore. Les modèles d'apprentissage automatique formés sur la base du comportement humain normal découvrent aujourd'hui que la normalité elle-même a changé, et certains d'entre eux ne fonctionnent plus comme ils le devraient." En d'autres termes, entre l'"ancienne normalité" et la "nouvelle normalité", nous vivons une "nouvelle anormalité". Une autre citation intéressante, également tirée de l'article : > "Les modèles d'apprentissage automatique sont conçus pour s'adapter aux changements. Mais la plupart d'entre eux sont également fragiles ; ils donnent de mauvais résultats lorsque les données d'entrée diffèrent trop de celles sur lesquelles ils ont été formés. (...) L'IA est un moteur vivant, qui respire." Cet article présente ensuite des exemples de modèles d'IA/ML dont les performances commencent soudainement à être affectées négativement, ou qui doivent être modifiés de toute urgence. Quelques exemples : * Les entreprises de vente au détail qui se sont retrouvées en rupture de stock après avoir passé des commandes en masse pour des produits inadaptés ; * Des conseils biaisés de la part de services de recommandation d'investissements basés sur l'analyse du sentiment des messages médiatiques, en raison de leur contenu pessimiste ; * Générateurs automatiques de phrases pour les conseils qui commencent à générer un contenu inadapté, en raison d'un nouveau contexte ; * Amazon a modifié son système de recommandation des vendeurs pour choisir ceux qui effectuent leurs propres livraisons, afin d'éviter que la logistique de ses entrepôts ne soit trop sollicitée. Nous devons donc surveiller nos modèles d'IA/ML afin de garantir leur fiabilité et de continuer à aider nos clients. Jusqu'à présent, j'espère vous avoir montré que la création, la formation et le déploiement de votre modèle de ML ne sont pas tout - vous devez en assurer le suivi. Dans le prochain article, je vous montrerai comment utiliser le framework %Monitor.Abstract d'IRIS pour surveiller les performances de votre système de ML et définir des alertes basées sur les métriques du moniteur. *En attendant, j'aimerais savoir si vous avez été confronté à l'un ou l'autre des problèmes soulevés par ces périodes de pandémie, et comment vous y faites face dans la section des commentaires !* Restez à l'écoute (et en sécurité 😊)!
Article
Lorenzo Scalese · Juin 30, 2023

Gestion de la configuration des conteneurs

Si vous déployez dans plus d'un environnement/région/cloud/client, vous rencontrerez inévitablement le problème de la gestion de la configuration. Alors que tous vos déploiements (ou juste certains) peuvent partager le même code source, certaines parties, telles que la configuration (paramètres, mots de passe) diffèrent d'un déploiement à l'autre et doivent être gérées différemment. Dans cet article, j'essaierai d'offrir quelques conseils à ce sujet. Cet article traite principalement des déploiements de conteneurs. ## ## Unification de la base de code Avant d'aborder la gestion de la configuration, parlons de l'unification des bases de code. Le problème est le suivant : la base de code _doit_ généralement viser à coalescer en une seule version. Bien sûr, à tout moment, vous aurez plusieurs versions de votre base de code - la version DEV avec de toutes nouvelles fonctionnalités, la version TEST avec du code de test supplémentaire, la version PROD, et ainsi de suite. Et c'est _fine_ parce que, dans cet exemple, les changements se regroupent en une seule version au fil du temps. Plusieurs branches DEV deviennent une branche TEST et ainsi de suite. Le problème commence lorsque nous avons plusieurs versions à l'étape finale de notre pipeline de déploiement. Par exemple, le client ABC a demandé une fonctionnalité particulière XYZ, et il existe maintenant deux versions de la base de code PROD - avec la fonctionnalité XYZ et sans elle. Cette situation est problématique car elle double immédiatement nos délais de construction et notre consommation de ressources. Bien sûr, il n'y a parfois aucun moyen d'y remédier. Cependant, supposons que vous ayez de telles divergences persistantes entre les bases de code. Dans ce cas, il peut être intéressant de rechercher si vous pouvez les regrouper en une seule version - dans ce scénario, la fonctionnalité XYZ est activée ou non au démarrage. Cela dit, passons à la gestion de la configuration. ##   ## Gestion de la configuration Qu'est-ce que nous voulons ? * Ne pas stocker toutes les configurations possibles dans un seul conteneur ( pour une part, ce n'est pas sûr, et pour une autre part, nous avons toujours besoin de choisir la configuration à appliquer). * Ne pas construire un conteneur pour chaque configuration (simplifie le pipeline CD) Nous devons transmettre la configuration (paramètres, secrets, ...) lors du démarrage d'InterSystems IRIS et l'appliquer à notre application.   ## Transmission de la configuration Il existe plusieurs façons de transmettre la configuration au démarrage. ### Les variables d'environnement Simple et rapide. Dans le cas où vous souhaitez tout stocker dans une seule variable, utilisez JSON pour la sérialisation. N'oubliez pas par ailleurs que Windows a une limite de 32K caractères pour les variables d'environnement (mégaoctets sous Linux). Pour récupérer une variable d'environnement, utilisez [$SYSTEM.Util.GetEnviron("ENV_VAR\NAME")](https://docs.intersystems.com/iris20212/csp/documatic/%25CSP.Documatic.cls?&LIBRARY=%25SYS&CLASSNAME=%25SYSTEM.Util#GetEnviron). Le principal avantage est la facilité de mise en œuvre. Vérifiez également votre outil CD - il a généralement un minimum de support des variables d'environnement pendant l'exécution du pipeline, parfois avec un support des secrets pour plus de sécurité. ### Les fichiers de montage La configuration peut être un fichier de montage au démarrage. L'avantage est qu'il n'y a pas de limite de longueur. L'inconvénient est que toutes les offres en nuage ne prennent pas en charge les fichiers de montage, et même si c'est le cas, la gestion des fichiers peut s'avérer plus délicate que celle des variables d'environnement. Sachez que les fichiers peuvent toujours être récupérés à partir des anciennes couches d'un conteneur, même s'ils ont été supprimés à une couche ultérieure. ### Fusion du CPF Les paramètres du système peuvent être transmis via le [Fichier de fusion de configuration](https://docs.intersystems.com/iris20212/csp/docbook/DocBook.UI.Page.cls?KEY=ACMF). Ainsi que ses fonctionnalités intégrées. Inconvénient : Le fichier de fusion CPF ne traite pas les paramètres au niveau de l'application. ### Les secrets de Docker/CSP Docker peut monter un secret sous une forme de fichier à l'intérieur d'un conteneur. Les offres en nuage proposent souvent une fonctionnalité similaire. Utilisez-la à la place des fichiers ordinaires pour améliorer la sécurité.   ## Traitement de la configuration Bien, vous avez passé la configuration à l'intérieur d'un conteneur. Que faire maintenant ? ### %ZSTART [%ZSTART](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GSTU_CUSTOMIZE_STARTSTOP) est votre code personnalisé, exécuté au démarrage du système. Il ressemble à ceci : SYSTEM try { new $namespace set $namespace = "USER" // apply configuration set $namespace = "%SYS" } catch ex { zn "%SYS" do ex.Log() } quit 1 Il est essentiel de noter que %ZSTART doit être testé _complètement_ - car InterSystems IRIS ne démarrera pas (ou se comportera de manière erratique) si la routine %ZSTART renvoie une erreur. Vous êtes maintenant prêt à appliquer vos paramètres. La manière dont vous stockez/appliquez les paramètres au niveau de l'application dépend naturellement de l'application, mais les paramètres par défaut du système[System Default Settings](https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=ECONFIG_other#ECONFIG_other_default_settings_purpose){.editor-rtfLink} sont disponibles si vous utilisez l'interopérabilité. Même si vous n'utilisez pas de productions interopérables, vous pouvez toujours utiliser les paramètres par défaut du système car ils sont disponibles pour tout le monde (tant que l'interopérabilité est activée dans un espace de noms). Pour créer un nouveau paramètre, exécutez : Set setting = ##class(Ens.Config.DefaultSettings).%New() Set setting.ProductionName = production Set setting.ItemName = itemname Set setting.HostClassName = hostclassname Set setting.SettingName = settingname Set setting.SettingValue = settingvalue Set setting.Description = description Set sc = setting.%Save() Et pour récupérer les paramètres, appelez : set sc = ##class(Ens.Config.DefaultSettings).%GetSetting(production, itemname, hostclassname, "", settingname, .settingvalue) set settingvalue = ##class(Ens.Director).GetProductionSettingValue(production, settingname, .sc) Les hôtes d'interopérabilité reçoivent leurs paramètres automatiquement au démarrage du travail de l'hôte commercial.   ## Summary Making your application configurable when deploying to more than one server is essential. It can be pretty easy at the early part of the development cycle, but the costs rise with each hardcoded URL. InterSystems IRIS offers several tools you can use to configure the state of your application at startup.   How do you manage multiple deployments?
Article
Guillaume Rongier · Jan 4, 2023

Conversion des messages de santé personnalisés en SDA

Les systèmes EHR (Electronic Health Record) sont modélisés dans un format/structure propriétaire et ne sont pas basés sur des modèles du marché tels que FHIR ou HL7. Certains de ces systèmes peuvent interopérer des données dans un format propriétaire pour FHIR et d'autres modèles de marché, mais pas tous. InterSystems dispose de deux plateformes capables d'interopérer des formats propriétaires pour ceux du marché : InterSystems HealthShare Connect et InterSystems IRIS for Health. La fonctionnalité de transformation (DTL - Data Transformation Language) de ces plateformes peut recevoir des données dans n'importe quel format, structure ou canal de communication (CSV, JSON, XML, et autres via FTP, File, HTTP, etc.) et les transformer directement en formats du marché (FHIR, CDA, HL7, etc.). Cependant, InterSystems dispose d'un format intermédiaire appelé SDA (Summary Document Architecture) qui est utilisé par ces plateformes pour générer sans effort des FHIR STU, R3, R4, HL7v2, HL7v3, etc. En outre, lorsqu'elles sont au format SDA, les données de santé peuvent être conservées dans le RCU HealthShare. Ainsi, le format propriétaire/personnel est d'abord transformé en SDA, puis les données peuvent être automatiquement converties dans n'importe quel format du marché, ainsi que sauvegardées dans HealthShare. Dans cet article, nous allons vous montrer comment transformer des données propriétaires/personnalisées en SDA à l'aide d'IRIS for Health. L'exemple de données que nous avons utilisé a été généré par le projet de génération de données en masse SYNTHEA (https://synthea.mitre.org/downloads). Nous allons convertir 1000 patients d'un fichier CSV en SDA, en utilisant les fonctions d'interopérabilité d'IRIS for Health. Application de soutien aux articles – custom2sda Installation de l'application d'exemple qui sera utilisée avec cet article en suivant les instructions : Si vous voulez installer en utilisant ZPM : 1. Ouvrez le Namespace IRIS avec l'interopérabilité activée.2. Ouvrez le Terminal et appelez : USER>zpm "install custom2sda" Si vous voulez installer en utilisant Docker : 1. Clonez Git et tirez le repo dans n'importe quel répertoire local : $ git clone https://github.com/yurimarx/custom2sda.git 2. Ouvrez le terminal dans ce répertoire et exécutez : $ docker-compose build 3. Lancez le conteneur IRIS avec votre projet : $ docker-compose up -d 4. Ouvrez la production (http://localhost:52775/csp/healthshare/user/EnsPortal.ProductionConfig.zen?PRODUCTION=customsda.CustomToSDAProduction) et la lancez. (utilizateur _SYSTEM et le mot de passe SYS). Elle lira le fichier patients.csv et le convertira en SDA. ## Créer une carte d'enregistrement CSV pour obtenir les données personnalisées/propriétaires Dans l'étape précédente, vous avez exécuté la production qui a lu le fichier patients.csv et l'a transformé en SDA. Maintenant nous allons faire la même chose avec patients2.csv. Nous pourrions profiter de la production actuelle, mais je voudrais montrer comment créer tout à partir de zéro. Donc, arrêtez cette production, et faisons ce qui suit. 1.    Allez au portail de gestion (http://localhost:52775/csp/sys/%25CSP.Portal.Home.zen?$NAMESPACE=USER, assurez-vous que vous êtes dans l'espace de noms de l'utilisateur). 2.    Créer un CSV Mapper pour le fichier patients2.csv. Interopérabilité > Build > CSV Record Wizard (Assistant d'enregistrement CSV) : ![](/sites/default/files/inline/images/images/image(4415).png) **_Remarque : sélectionnez CRLF pour Record Terminator (terminateur d'enregistrement)_** 3.    Cliquez sur "Create RecordMap" pour ouvrir l'interface utilisateur de Record Mapper et modifiez le nom de la classe cible en customsda.Patients2RecordMap.Record : ![](/sites/default/files/inline/images/images/image(4416).png) 4.    Sélectionnez BIRTHPLACE et définissez MAXLEN=200 dans le champ Paramètres du type de données. Par défaut, tous les champs %String contiennent 50 caractères, mais BIRTHPLACE et ADDRESS ont besoin de plus d'espace. Faites de même pour le champ ADDRESS : ![](/sites/default/files/inline/images/images/image(4417).png) 5.    Cliquez sur le bouton "Save" (Enregistrer) et sur le bouton "Generate" (Générer). Acceptez les options par défaut et cliquez sur Ok pour générer les classes RecordMap. ![](/sites/default/files/inline/images/images/image(4418).png) 6.    Cliquez sur "Interoperability" (Interopérabilité) pour passer aux tâches suivantes: ![](/sites/default/files/inline/images/images/image(4419).png) ## Créer la transformation de données de Custom à SDA Il est temps d'utiliser le DTL pour construire visuellement la carte de transformation de Custom à SDA. 1.    Cliquez sur Interoperability" > Build > Data Transformations (transformation de données) > Go : ![](/sites/default/files/inline/images/images/image(4420).png) 2.    Vous pouvez voir le Data Transformation Builder ici. Cliquez sur le bouton "New" (Nouveau) : ![](/sites/default/files/inline/images/images/image(4421).png) 3.    Dans Data Transformation Wizard (Assistant de transformation des données), changez le Package en customsda, et le Name en PatientDTL2 : ![](/sites/default/files/inline/images/images/image(4422).png) 4.    À ce stade, nous allons définir la classe de la source. Cliquez sur l'icône de la loupe près du champ "Source Class" : ![](/sites/default/files/inline/images/images/image(4423).png) 5.    Cliquez sur Message Classes > customsda > Patients2RecordMap > Record : ![](/sites/default/files/inline/images/images/image(4424).png) 6.    À ce stade, la classe "Source Class" devrait ressembler à ceci : ![](/sites/default/files/inline/images/images/image(4425).png) 7.    Dans la section Target Type, sélectionnez XML et acceptez Target Class avec la valeur EnsLib.EDI.XML.Document : ![](/sites/default/files/inline/images/images/image(4426).png) 8.    Sélectionnez l'icône de la loupe près du Type de document cible et cliquez sur Document XML > SDA3_schema > Container : ![](/sites/default/files/inline/images/images/image(4427).png) Remarque 1 : Le conteneur est l'élément racine de tous les éléments SDA, comme Patient. Remarque 2 : pour que SDA3_schema soit disponible, les actions suivantes sont nécessaires : Copier SDA3_schema.xsd dans votre système de fichiers local : ![](/sites/default/files/inline/images/images/image(4428).png) Importez le schéma XSD de SDA3 : ![](/sites/default/files/inline/images/images/image(4429).png) 9.    Maintenant, lorsque la source et la cible sont configurées, cliquez sur le bouton OK : ![](/sites/default/files/inline/images/images/image(4430).png) 10.    Les champs source et cible sont maintenant disponibles pour le mappage visuel : ![](/sites/default/files/inline/images/images/image(4431).png) 11.    Pour créer une transformation, vous devez faire glisser le cercle du champ source et le déposer dans la flèche du champ cible, ligne par ligne. ![](/sites/default/files/inline/images/images/image(4432).png) 12.    Dans la section Actions, vous pouvez voir les résultats obtenus : ![](/sites/default/files/inline/images/images/image(4433).png) 13.    Après avoir mappé tous les champs, votre liste d'actions ressemblera à ceci : ![](/sites/default/files/inline/images/images/image(4434).png) Remarque : pour les propriétés avec (), vous devez définir l'index car ces propriétés peuvent avoir plus d'un élément. Dans cet exemple, nous n'avons qu'une seule adresse, donc target.{Patient.Addresses(1)….} est configuré avec 1. 14.    Cliquez sur le bouton "Save" (enregistrer) et sur le bouton "Compile" (compiler). ![](/sites/default/files/inline/images/images/image(4435).png) 15.    Enfin, cliquez sur le raccourci "Interoperability" pour accéder au menu d'Interoperability : ![](/sites/default/files/inline/images/images/image(4436).png) ## Créer la production de l'interopérabilité (Interoperability Production), le dernier artefact pour compléter notre travail ! Les productions sont les mécanismes utilisés pour automatiser efficacement les flux d'intégration. Il est temps de créer notre production pour transformer les données des patients du fichier patients2.csv en SDA. 1.    Cliquez sur Interoperability > List > Productions : ![](/sites/default/files/inline/images/images/image(4437).png) 2.    Cliquez sur le bouton "New" : ![](/sites/default/files/inline/images/images/image(4438).png) 3.    Définissez Customsda sur Package, Patients2Production sur Production Name et Production Type sur Generic. Cliquez sur Ok : ![](/sites/default/files/inline/images/images/image(4439).png) 4.    Nous avons maintenant la configuration de production : ![](/sites/default/files/inline/images/images/image(4449).png) 5.    Cliquez sur le bouton "Plus" près de "Services" : ![](/sites/default/files/inline/images/images/image(4444).png) Remarque : Les services sont les composants utilisés par les productions pour obtenir des données sources. 6.    Configurez la classe "Service Class" avec la valeur EnsLib.RecordMap.Service.FileService, et le nom du service "Service Name" comme PatientCSVService, et cochez "Enable Now" : ![](/sites/default/files/inline/images/images/image(4445).png) 7.    Sélectionnez PatientCSVService et configurez l'onglet Paramètres avec les valeurs   et cliquez sur "Apply" (appliquer): ●    Chemin du fichier : /opt/user/data/ ●    Spécification du fichier : patients2.csv ●    Carte d'enregistrement : Patients2RecordMap ●    Noms des configurations cibles : PatientProcess ![](/sites/default/files/inline/images/images/image(4450).png) 8.    Cliquez sur le bouton "Plus" situé près des Opérations : ![](/sites/default/files/inline/images/images/image(4447).png) Remarque : Les opérations sont des composants de production utilisés pour écrire/persister des données sur une cible (bases de données, systèmes, API, services Web, FTP, fichier, etc.) 9.    Configurez l'Opération avec les valeurs suivantes : ●    Classe d'Opération : EnsLib.EDI.XML.Operation.FileOperation ●    Nom d'Opération : PatientSDAOperation ●    Cochez Enable Now ![](/sites/default/files/inline/images/images/image(4448).png) 10.    Sélectionnez PatientSDAOperation et définissez la valeur /opt/user/data/ comme chemin de fichier, puis cliquez sur le bouton "Apply" : ![](/sites/default/files/inline/images/images/image(4451).png) 11.    Cliquez sur le bouton "Plus" à côté de "Processes" (Processus) : ![](/sites/default/files/inline/images/images/image(4452).png) Remarque : les processus sont le composant de production permettant de coordonner le flux de données. 12.    Configurez le processus métier avec les valeurs suivantes : ●    Classe du processus métier: EnsLib.MsgRouter.RoutingEngine ●    Nom de règle de routage : customsda.PatientRouterRule2 ●    Nom du processus métier: PatientProcess ●    Cochez Enable Now ![](/sites/default/files/inline/images/images/image(4453).png) 13.    Jusqu'à présent, nous avons créé tous les composants : ![](/sites/default/files/inline/images/images/image(4454).png) 14.    Sélectionnez PatientProcess et allez à l'onglet "Settings" > icône de loupe près de "Business Rule Name" (Nom de règle de routage) : ![](/sites/default/files/inline/images/images/image(4455).png) 15.    Maintenant, nous allons configurer la règle de routage "Routing Rule" dans l'éditeur de règles "Rule Editor" : ![](/sites/default/files/inline/images/images/image(4456).png) 16.    Faites un double-clic sur le composant de contrainte et configurez la Source avec PatientCSVService et la Classe de message avec customsda.Patients2RecordMap.Record : ![](/sites/default/files/inline/images/images/image(4457).png) 17.    Actuellement, nous avons configuré la source et la cible : ![](/sites/default/files/inline/images/images/image(4458).png) 18.    Sélectionnez le composant de règle et cliquez sur le bouton "Green Plus" : ![](/sites/default/files/inline/images/images/image(4459).png) 19.    Sélectionnez Send (Envoyer) pour créer le composant When (Quand) : ![](/sites/default/files/inline/images/images/image(4460).png) 20.    Sélectionnez le composant "When", cliquez sur le bouton "Green Plus", puis sélectionnez le composant "Send" : ![](/sites/default/files/inline/images/images/image(4461).png) 21.    Vous êtes censé voir l'image affichée ci-dessous sur votre écran : ![](/sites/default/files/inline/images/images/image(4462).png) 22.    Faites un double-clic sur le composant cible et définissez les éléments de configuration sur PatientSDAOperation, puis cliquez sur le bouton OK : ![](/sites/default/files/inline/images/images/image(4463).png) 23.    Faites un double-clic sur le composant de transformation et définissez "Transforms" sur customsda.PatientDTL2, puis cliquez sur OK : ![](/sites/default/files/inline/images/images/image(4464).png) 24.    Maintenant, vous avez vos définitions de règles prêtes : ![](/sites/default/files/inline/images/images/image(4465).png) 25.    Cliquez sur le bouton "Save" et allez au menu "Interoperability" : ![](/sites/default/files/inline/images/images/image(4466).png) 26.    Allez à Interoperability > List > Productions : ![](/sites/default/files/inline/images/images/image(4467).png) 27.    Sélectionnez Patients2Production et cliquez sur le bouton "Open" : ![](/sites/default/files/inline/images/images/image(4468).png) 28.    Nous allons lancer notre nouvelle production ! Cliquez sur le bouton "Start" : ![](/sites/default/files/inline/images/images/image(4469).png) 29.    Sélectionnez PatentProcess et allez à l'onglet "Messages" pour voir les résultats (messages) : ![](/sites/default/files/inline/images/images/image(4470).png) 30.    Cliquez sur un message pour voir un diagramme de séquence "Sequence Diagram" avec les résultats de la transformation : ![](/sites/default/files/inline/images/images/image(4471).png) Comme vous pouvez le constater, il s'agit d'un processus de glisser-déposer facile et entièrement visuel, qui transforme les messages personnalisés en SDA ou en d'autres formats. Pour en savoir plus, consultez les liens ci-dessous : 1.    Création d'intégrations FHIR de base avec InterSystems IRIS for Health : 2.    Découvrez HealthShare pour les développeurs et les intégrateurs de systèmes : 3.    Création d'intégrations métier avec InterSystems IRIS 4.    Création d'intégrations de base HL7 avec InterSystems:  
Article
Guillaume Rongier · Fév 24, 2023

Bienvenue à irissqlcli - terminal avancé pour IRIS SQL

Je vous présente mon nouveau projet, qui est [irissqlcli](https://openexchange.intersystems.com/package/irissqlcli), REPL (Read-Eval-Print Loop) pour InterSystems IRIS SQL * Mise en évidence de la syntaxe * Suggestions (tableaux, fonctions) * Plus de 20 formats de sortie * Support de stdin * Sortie vers des fichiers  L'installez avec pip pip install irissqlcli Ou lancez avec docker docker run -it caretdev/irissqlcli irissqlcli iris://_SYSTEM:SYS@host.docker.internal:1972/USER Connection à IRIS $ irissqlcli iris://_SYSTEM@localhost:1972/USER -W Password for _SYSTEM: Server: InterSystems IRIS Version 2022.3.0.606 xDBC Protocol Version 65 Version: 0.1.0 [SQL]_SYSTEM@localhost:USER> select $ZVERSION +---------------------------------------------------------------------------------------------------------+ | Expression_1 | +---------------------------------------------------------------------------------------------------------+ | IRIS for UNIX (Ubuntu Server LTS for ARM64 Containers) 2022.3 (Build 606U) Mon Jan 30 2023 09:05:12 EST | +---------------------------------------------------------------------------------------------------------+ 1 row in set Time: 0.063s [SQL]_SYSTEM@localhost:USER> help +----------+-------------------+------------------------------------------------------------+ | Commande | Raccourci | Description | +----------+-------------------+------------------------------------------------------------+ | .exit | \q | Sortie. | | .mode | \T | Modifier le format de tableau utilisé pour les résultats. | | .once | \o [-o] filename | Ajout du résultat suivant à un fichier de sortie (écraser en utilisant -o). | | .schemas | \ds | Liste des schémas. | | .tables | \dt [schema] | Liste des tableaux. | | \e | \e | Commande d'édition avec éditeur (utilise $EDITOR). | | help | \? | Montre cette utilité. | | nopager | \n | Désactiver le pager, imprimer vers stdout. | | notee | notee | Arrête l'écriture des résultats dans un fichier de sortie. | | pager | \P [command] | Definition du PAGER. Impression des résultats de la requête via PAGER. | | prompt | \R | Modification du format de l'invite. | | quit | \q | Quit. | | tee | tee [-o] filename | Ajout de tous les résultats à un fichier de sortie (écraser en utilisant -o). | +----------+-------------------+------------------------------------------------------------+ Time: 0.012s [SQL]_SYSTEM@localhost:USER> $ irissqlcli --help Usage: irissqlcli [OPTIONS] [URI] [NOM D'UTILISATEUR] Options: -h, --host TEXT Adresse hôte de l'instance IRIS. -p, --port INTEGER Numéro de port sur lequel l'instance IRIS està l'écoute. -U, --username TEXT Nom d'utilisateur pour se connecter à l'instance IRIS. -u, --user TEXT Nom d'utilisateur pour se connecter à l'instance IRIS. -W, --password Invite de mot de passe forcée. -v, --version Version de irissqlcli. -n, --nspace TEXT nom de l'espace de nom auquel se connecter. -q, --quiet Mode silencieux, saut de l'intro au démarrage etau revoir à la sortie. -l, --logfile FILENAME Enregistrez chaque requête etses résultats dans un fichier. --irissqlclirc FILE L'emplacement du fichier irissqlclirc. --auto-vertical-output Passage automatique en mode de sortie verticale sile résultat est plus large que la largeur du terminal. résultat estplus large que la largeur du terminal. --row-limit INTEGER Définissez le seuil pour l'invite de limite de rangée de . Utilisez 0 pour désactiver l'invite. -t, --table Affichez la sortie du lot au format tableau . --csv Affichez la sortie du lot in au format CSV. --warn / --no-warn Avertissement avant d'exécuter une requête destructive. -e, --execute TEXT Exécutez la commande etquitter. --help Affichage de ce message et sortie. ou en Python Embedded (nécessite de %Service_CallIn activé) $ irissqlcli iris+emb:///USER Server: IRIS for UNIX (Ubuntu Server LTS for ARM64 Containers) 2022.2 (Build 368U) Fri Oct 21 2022 16:39:41 EDT Version: 0.1.0 [SQL]irisowner@/usr/irissys/:USER> L'application supporte stdin, ce qui vous permet d'envoyer un fichier SQL avec un tas de requêtes SQL et de commandes irissqcli. Par exemple, cette commande produira 3 fichiers dans différents formats (parmi plus de 20 formats disponibles) $ cat