accéder à la publication Sylvain Guilbaud · Juil 9, 2024 Bonjour Moussa, le messages.log indique une version IRIS 2023.1 : Si tu utilises ARG IMAGE=intersystemsdc/irishealth-community tu obtiendras une version 2024.1 NB : pour récupérer régulièrement les images plus récentes, le repository officiel InterSystems est https://containers.intersystems.com/contents Les noms des différentes images régulièrement mises-à-jour sont : EXTENDED_MAINTENANCE=latest-em CONTINUOUS_DELIVERY=latest-cd DEVELOPER_PREVIEW=latest-preview IMAGE_IRIS_EM=containers.intersystems.com/intersystems/irishealth-community:$EXTENDED_MAINTENANCE IMAGE_IRIS_CD=containers.intersystems.com/intersystems/irishealth-community:$CONTINUOUS_DELIVERY IMAGE_IRIS_PREVIEW=containers.intersystems.com/intersystems/irishealth-community:$DEVELOPER_PREVIEW Tu peux utiliser ce repo pour tester les différentes versions d'IRIS for Health : https://github.com/SylvainGuilbaud/IRISHealth_community
accéder à la publication Sylvain Guilbaud · Juin 6, 2024 Bonjour @Julia Pertin pour tester un objet dynamique vide tu peux utiliser la méthode d'instance %Size() qui renverra 0 IRISAPP>set monobjet={} IRISAPP>write monobjet.%Size() 0 IRISAPP>zw monobjet monobjet={} ; <DYNAMIC OBJECT> IRISAPP>set monobjet.data="une valeur" IRISAPP>write monobjet.%Size() 1 IRISAPP>zw monobjet monobjet={"data":"une valeur"} ; <DYNAMIC OBJECT>
accéder à la publication Sylvain Guilbaud · Avr 25, 2024 Simplement en utilisant l'option Resource dans une instruction CreateDatabase de la section [Actions] du fichier merge.cpf : [Actions] CreateResource:Name=%DB_IRISAPP_DATA,Description="IRISAPP_DATA database" CreateDatabase:Name=IRISAPP_DATA,Directory=/usr/irissys/mgr/IRISAPP_DATA,Resource=%DB_IRISAPP_DATA CreateResource:Name=%DB_IRISAPP_CODE,Description="IRISAPP_CODE database" CreateDatabase:Name=IRISAPP_CODE,Directory=/usr/irissys/mgr/IRISAPP_CODE,Resource=%DB_IRISAPP_CODE CreateNamespace:Name=IRISAPP,Globals=IRISAPP_DATA,Routines=IRISAPP_CODE,Interop=1
accéder à la publication Sylvain Guilbaud · Jan 25, 2024 Bonjour @Jean-Charles Cano si ton service FTP ne doit s'exécuter qu'une seule fois par jour, à une heure bien précise, la planification est effectivement le bon moyen, en veillant à ce que l'intervalle entre appel soit supérieur à la durée séparant l'heure du START et celle du STOP. L'autre moyen, sans planification, est de simplement mettre un intervalle entre appels de 86400 pour obtenir un appel une seule fois par jour. L'inconvénient ici étant que le service restera démarré 24h/24h sans utilité.
accéder à la publication Sylvain Guilbaud · Jan 15, 2024 Bonjour @Cyril Grosjean essaie d'utiliser embedded python, en remplaçant la connexion par create_engine('iris+emb:///'): from sqlalchemy import create_engine _engine = create_engine('iris+emb:///')
accéder à la publication Sylvain Guilbaud · Jan 15, 2024 Bonjour @Cyril Grosjean essaie d'utiliser embedded python, en remplaçant la connexion par create_engine('iris+emb:///'): from sqlalchemy import create_engine _engine = create_engine('iris+emb:///')
accéder à la publication Sylvain Guilbaud · Jan 12, 2024 Bonjour @Pierre LaFay pour rediriger la sortie standard du Terminal IRIS, tu peux ouvrir un fichier et l'indiquer via la commande USE Exemple ci-dessous et en ligne : Class utils.file { Parameter DIRECTORY = "/data/"; Parameter FILENAME = "results"; Parameter EXTENSION = ".txt"; /// Redirect standard output to a file ClassMethod results() As %Status { set sc = $$$OK SET file=..#DIRECTORY _ ..#FILENAME _ "_" _ $tr($zdt($h,8)," :")_..#EXTENSION OPEN file:("NRW"):5 USE file WRITE !,"BEGIN RESULTS ",$zdt($h,3),! do ##class(UnitTest.utils).run("Test3") WRITE !,"END RESULTS ",$zdt($h,3) CLOSE file WRITE !,"Results are in ",file,! return sc } } Avec le fichier contenant toutes les écritures vers la sortie :
accéder à la publication Sylvain Guilbaud · Jan 5, 2024 Réponse d' @Eduard Lebedyuk : L'approche la plus sûre consiste à utiliser Privileged Routine Application.
accéder à la publication Sylvain Guilbaud · Déc 27, 2023 Une fois obtenu le fichier Excel, il est possible de le convertir en CSV puis en PDF en utilisant les librairies pandas et csv2pdf ClassMethod toPDF(file As %String) As %Status [ Language = python ] { import pandas as pd from csv2pdf import convert PATH = '/home/irisowner/dev/data/' PATH_TO_XLSX = PATH+file+'.xlsx' PATH_TO_CSV = PATH+file+'.csv' PATH_TO_PDF = PATH+file+'.pdf' read_file = pd.read_excel (PATH_TO_XLSX) read_file.to_csv (PATH_TO_CSV, index = None, header=True) convert(PATH_TO_CSV , PATH_TO_PDF) }
accéder à la publication Sylvain Guilbaud · Déc 27, 2023 Bonjour @Pierre LaFay en m'inspirant des liens proposés par @Guillaume Rongier tu trouveras ci-dessous et en ligne un exemple de génération de feuille Excel à partir de openpyxl Code /// d ##class(apptools.python.xlsx).test() Class apptools.python.xlsx { Parameter DATADIRECTORY = "/home/irisowner/dev/data/"; /// d ##class(apptools.python.xlsx).test() ClassMethod test(name As %String = "titanicTest") As %Status { set name=name_$INCREMENT(^RunAppTest(name)) set sql="select * FROM dc_demo.titanic" #; set sql="select name,sex,age FROM dc_demo.titanic" set gn="^||tmp",format=",n,n,n,n,s5,s5,s40,s5,s50" set format("freeze")="B3" ;freeze set format("title")="Title "_sql set format("sheetname")="test" #; do ##class(apptools.core.sys).SaveSQL(sql,gn) set exec="##class(apptools.python.xlsx).MarkRed(.%AppLogInfoVal, .%AppLogInfoCol, .%AppLogInfoHead, .%AppLogInfoTemp)" #; do ##class(apptools.python.xlsx).gn2xlsx(gn,.format,..#DATADIRECTORY_"___gn2xlsx*.xlsx","Title "_sql,,,,exec) set format("freeze")="B4" ;freeze do ##class(apptools.python.xlsx).sql2xlsx(sql,.format,..#DATADIRECTORY_name_".xlsx") do ..toPDF(name) return $$$OK } ClassMethod sql2xlsx(sql, format = "", file As %String = "/home/irisowner/dev/data/sample-py-*.xlsx", title = "") { set st=$$$OK set statement = ##CLASS(%SQL.Statement).%New() set status=statement.%Prepare(sql) if $$$ISERR(status) {write "%Prepare failed:" do $SYSTEM.Status.DisplayError(status) quit} set rset=statement.%Execute() if (rset.%SQLCODE '= 0) {write "%Execute failed:", !, "SQLCODE ", rset.%SQLCODE, ": ", rset.%Message quit} ;prepare XLSX try { set openpyxl = ##class(%SYS.Python).Import("openpyxl") } catch err { do ..InstallPy("openpyxl") set openpyxl = ##class(%SYS.Python).Import("openpyxl") } set wb = openpyxl.Workbook() #; grab the active worksheet set ws = wb.active set ws.title = $select($D(format("sheetname"),ds):ds,1:"sheetname") set pybuiltins = $system.Python.Import("builtins") set pycols = pybuiltins.list() do pycols.append(" ") do ws.append(pycols) set pycols = pybuiltins.list() set (count)=0 set ColCount=statement.%Metadata.columns.Count() for i=1:1:ColCount { do pycols.append(statement.%Metadata.columns.GetAt(i).colName) set col=openpyxl.utils."get_column_letter"(i) } do ws.append(pycols) while (rset.%Next()) { set count=count+1 set pyrows = pybuiltins.list() for ii=1:1:ColCount { set val=..CleanCtrl(rset.%GetData(ii)) if $e($P(format,",",ii),1)="d" { //date set val=..ToPyDate(val) } elseif $e($P(format,",",ii),1,2)="dt" { //datetime set val=..ToPyDateTime(val) } elseif $e($P(format,",",ii),1)="n" { //number set val=+val } do pyrows.append(val) } do ws.append(pyrows) } ;} if $g(format("freeze"))'="" { ; set builtins = $system.Python.Import("builtins") zwrite builtins.type(ws) zwrite builtins.dir(wb) set ws."freeze_panes" = pybuiltins.str(format("freeze")) ;format("freeze") ;set ws."freeze_panes" = "B2" ;format("freeze") } else { set ws."freeze_panes" = pybuiltins.str("B2") ;default } if file["*" set file=$replace(file,"*","-"_$zd($h,3)_"_"_$tr($zt($p($h,",",2),1),":")) write !,"Save into "_file_" rows: "_count do wb.save(file) return $GET(count) } ClassMethod toPDF(file As %String) As %Status [ Language = python ] { import pandas as pd from csv2pdf import convert PATH = '/home/irisowner/dev/data/' PATH_TO_XLSX = PATH+file+'.xlsx' PATH_TO_CSV = PATH+file+'.csv' PATH_TO_PDF = PATH+file+'.pdf' read_file = pd.read_excel (PATH_TO_XLSX) read_file.to_csv (PATH_TO_CSV, index = None, header=True) convert(PATH_TO_CSV , PATH_TO_PDF) } /// set gn="^||tmp",format="n,s150,,,,,,,,d," /// set format("freeze")="B5" ;freeze /// d ##class(apptools.core.sys).SaveSQL("select * from apptools_core.Log order by id desc",gn) /// d ##class(apptools.python.xlsx).gn2xlsx(gn,.format,"/iris-backup/temp/test*.xlsx","Test") /// Example coloring a column values if is not null /// set exec="##class(apptools.python.xlsx).MarkRed(.%AppLogInfoVal, %AppLogInfoCol, %AppLogInfoHead, .%AppLogInfoTemp)" ClassMethod MarkRed(Val, Col, Head, openpyxl) { s res=Val if $g(Head) { if res.value="DispatchClass" set Col("DispatchClass",Col)="" } else { if $Data(Col("DispatchClass",Col)) { if res.value'="" { ;set argsfill = {"start_color":"D3D3D3", "end_color":"D3D3D3", "fill_type":"solid"} ;set fill = openpyxl.styles.PatternFill(argsfill...) set argsfont = {"color":"DC143C", "bold":true, "italic":false, "size":11} ;color Crimson set font = openpyxl.styles.Font(argsfont...) ;set res.value=$FN(res.value,"",2) ;set res.fill=fill set res.font=font } } } q res } /// do ##class(apptools.python.xlsx).InstallPy("openpyxl") ClassMethod InstallPy(lib) { // depricated ;set sc = ##class(%SYS.Python).Install("openpyxl") set cmd="pip3 install --target /usr/irissys/mgr/python/ "_lib if $zversion(1)'=3 { set tMgrDir = $System.Util.ManagerDirectory() set tBinDir = $System.Util.BinaryDirectory()_"irispip.exe" set cmd=tBinDir_" install --target "_tMgrDir_"python "_lib } set st=##class(%ZPM.PackageManager.Developer.Utils).RunCommandViaZF(cmd,.tLog,.tErr) quit $$$OK } /// Date YYYY-MM-DD HH:MM:SS to Python dt.datetime ClassMethod ToPyDateTime(val, ByRef dt) { quit:'val val if val["." set val=$p(val,".",3)_"-"_$p(val,".",2)_"-"_$p(val,".",1) // format YYYY-MM-DD if val'["-" set val=$zd(+val,3) // $h format set dt = ##class(%SYS.Python).Import("datetime") set val=dt.datetime(+$p(val,"-",1), +$p(val,"-",2), +$p($p(val,"-",3)," "),+$p($p(val,":",1)," ",2),+$p($p(val,":",2)," ",2),+$p($p(val,":",3)," ",2)) quit val } /// Date YYYY-MM-DD to Python dt.date ClassMethod ToPyDate(val, ByRef dt) { quit:'val val if val["." set val=$p(val,".",3)_"-"_$p(val,".",2)_"-"_$p(val,".",1) // format YYYY-MM-DD if val'["-" w 111_val_111 set val=$zd(+val,3) // $h format set dt = ##class(%SYS.Python).Import("datetime") set val=dt.date(+$p(val,"-",1), +$p(val,"-",2), +$p($p(val,"-",3)," ")) quit val } ClassMethod CleanCtrl(val) { quit $zstrip(val,"*C") } }
accéder à la publication Sylvain Guilbaud · Sept 26, 2023 Réponse de @Ashok Kumar Bonjour @Muhammad Waseem Vous pouvez peut-être essayer d'extraire la ressource patient du bundle ou l'utiliser si c'est déjà une ressource. Chargez la classe du modèle patient FHIR HS.FHIR.DTL.vR4.Model.Resource.Patient avec la ressource extraite. Ensuite, vous pouvez convertir la date de naissance et valider l'âge. Vous pouvez utiliser la même logique dans votre code DTL dans un processus FHIR entre le service FHIR (HS.FHIRServer.Interop.Service) et l'opération FHIR (HS.FHIRServer.Interop.Operation). ClassMethod VaidatePatientResource(patientResourceStreram As %Stream.Object) { #dim patient As HS.FHIR.DTL.vR4.Model.Resource.Patient try { set patient = ##class(HS.FHIR.DTL.vR4.Model.Resource.Patient).FromJSON(patientResourceStreram) Set age = $horolog - $ZdateH(patient.birthDate,3)\360 if age<18 $$$ThrowStatus($$$ERROR($$$GeneralError, "Age is less than 18")) } catch ex { w ex.DisplayString() } }
accéder à la publication Sylvain Guilbaud · Sept 20, 2023 Bonjour @Julia Pertin, si j'ai bien compris ton besoin, pour régler ton problème qui consiste à éviter de récupérer plusieurs fois le même flux json, ton Business Service doit servir uniquement à appeler un Business Process, qui lui va se charger de récupérer le flux json pour le passer à une Business Operation. Dans le cas où ton Business Service appelle le Business Process de manière synchrone, il attendra bien la réponse avant de s'exécuter à nouveau.Dans le cas contraire, c'est à dire si le Business Process est appelé de manière asynchrone, le Business Service fera un nouvel appel à chaque atteinte du temps prévu par le paramètre "INTERVALLE ENTRE APPELS".
accéder à la publication Sylvain Guilbaud · Sept 15, 2023 Réponse de @Dmitry Maslennikov Pour quelques versions déjà, Caché et IRIS prennent déjà en charge OAuth2 dès le départ. Regardez la documentation. Cela dépend de votre architecture, vous pouvez utiliser cette méthode ou utiliser n'importe quel fournisseur d'identité externe comme keycloack. Et je pense qu'IAM peut également vous aider.
accéder à la publication Sylvain Guilbaud · Sept 15, 2023 Réponse de @Rob Tweed Nous avons deux produits Open Source qui prendront en charge les JWT pour vous de la manière correspondant à ce que vous demandez (c'est-à-dire les services REST avec IRIS) : - QEWD, si vous souhaitez tout implémenter en back-end dans Node.js / JavaScript - mgweb-server si vous souhaitez utiliser la logique ObjectScript pour votre logique back-end Pour QEWD et IRIS, voir : https://github.com/robtweed/qewd-starter-kit-iris-networked En particulier pour les services REST, voir : https://github.com/robtweed/qewd-starter-kit-iris-networked/blob/master/... et plus précisément cette section: https://github.com/robtweed/qewd-starter-kit-iris-networked/blob/master/... Pour le serveur mgweb, voir : https://github.com/robtweed/mgweb-server spécifiquement utilisé avec IRIS : https://github.com/robtweed/mgweb-server/blob/master/IRIS.md et dans ce document, cette section sur les JWT : https://github.com/robtweed/mgweb-server/blob/master/IRIS.md#using-json-... Rob
accéder à la publication Sylvain Guilbaud · Sept 12, 2023 @Luis Angel Pérez Ramos propose une autre solution, hors Embedded Python : Eh bien, si votre instance IRIS ne prend pas en charge Embedded Python, vous pouvez procéder comme suit (si vous utilisez un serveur Linux) : Installez une application comme ImageMagick sur votre serveur À partir de votre opération commerciale, utilisez la fonction $ZF(-100) pour exécuter sur le serveur la commande magique permettant de convertir le PDG en JPG, quelque chose comme : $ZF(-100,"","magick","\usr\image.pdf","\usr\image.jpg") Peut-être que cela prend un certain temps, vous pouvez attendre la fin de l'exécution ou simplement créer un service métier pour obtenir tous les nouveaux fichiers PDF.
accéder à la publication Sylvain Guilbaud · Sept 12, 2023 Dans ce cas, @Ben Spead propose d'installer Python sur le serveur avec la bibliothèque que l'on souhaitez utiliser et d'appeler le script Python via $zf(-100). Plus tard, lorsque d'une mise à niveau de l'environnement, il sera possible de passer directement à l’utilisation de Embedded Python.
accéder à la publication Sylvain Guilbaud · Sept 12, 2023 Malheureusement, l'environnement de @Gilberto Alves n'est pas prêt à utiliser Embedded Python.
accéder à la publication Sylvain Guilbaud · Sept 12, 2023 @Ben Spead a donné une première réponse en proposant d'utiliser Embedded Python : Cela ressemble à un exemple classique d'exploitation de Python intégré dans IRIS pour utiliser le très grand nombre de bibliothèques Python qui font à peu près n'importe quoi :) Voici un article que j'ai trouvé lors d'une recherche rapide sur Google sur la façon de procéder en Python : https://www.geeksforgeeks.org/convert-pdf-to-image-using-python/ Vous pouvez simplement exploiter les capacités Python d'InterSystems IRIS pour utiliser la façon dont ce problème a été résolu en Python !
accéder à la publication Sylvain Guilbaud · Août 31, 2023 Le moyen le plus simple de toujours rester dans le siècle en cours est : $ZDATEH("26/05/23",4,,6) Il suffit d'utiliser yearopt = 6 pour obtenir toutes les dates qui n'ont que 2 chiffres dans le siècle courant. w $zdt($ZDATEH("26/05/23",4,,6),3) 2023-05-26 w $zdt($ZDATEH("26/05/1923",4,,6),3) 1923-05-26