accéder à la publication Guillaume Rongier · Oct 31, 2023 Bonjour, Pour se connecter à IRIS, il est recommandé d'utiliser un login/password. A ma connaissance, il n'y a pas de moyen de se connecter avec des certificats. Pour se connecter avec un login/password dans le cas d'une connexion à IRIS en TCP, il est recommandé d'utiliser des variables d'environnement. Example en python avec le module sqlachemy: import os from sqlalchemy import create_engine,text engine = create_engine( "iris://", connect_args={ "hostname": os.environ.get("IRIS_HOST", "localhost"), "port": os.environ.get("IRIS_PORT", 1972), "username": os.environ.get("IRIS_USERNAME", "SuperUser"), "password": os.environ.get("IRIS_PASSWORD", "SYS"), "namespace": os.environ.get("IRIS_DATABASE", "USER"), }, ) with engine.connect() as conn: result = conn.execute(text("SELECT 1")) print(result.fetchall()) Le cas d'embedded Python est un peu différent car la connexion ne se fait pas par TCP, la connexion se fait par "shared memory". La connexion dans ce cas est définie par le service "%Service_CallIn" (pour information, les connexions TCP sont définies par le service "%Service_Bindings"). Regardons maintenant les possibilités de connexion offert par le service "%Service_CallIn". Unauthenticated L'utilisateur par défault sera alors "UnknownUser" Operating System Connexion avec l'utilisateur du système d'exploitation Ce doit etre le même user que celui qui a lancé le processus IRIS Password Connexion classique d'embedded Python avec les variables d'environnement suivantes: IRISUSERNAME IRISPASSWORD IRISNAMESPACE Kerberos Authentification Kerberos Kerberos Credentials Cache Authentification Kerberos avec un cache de credentials Dans votre cas, peut etre que Operating System est la meilleure solution. Kerberos est aussi une bonne solution mais il faut que votre environnement soit configuré pour. Pour plus d'information, je vous invite à suivre la discution suivante : https://fr.community.intersystems.com/post/acc%C3%A8s-au-terminal-iris-s...
accéder à la publication Guillaume Rongier · Oct 30, 2023 Pour information : Ce depot git fait exatement ce que vous chercher à faire. Il implemente `djangorestframework` pour des tables pré-existante. https://github.com/grongierisc/django-iris-template
accéder à la publication Guillaume Rongier · Oct 25, 2023 Vous pouvez utiliser Django pour créer des API sur votre base de données. Les options avec inspectdb ou la création manuelle de modèles sont possibles et ne dupliqueront pas votre base de données. Elles sont là pour creer un mapping entre votre base de données et des objets Python (les modèles Django). Vous etes donc dans un contexte "MVC" (en fait MTV pour Model Template View si vous utilisez Django en tant que framework web). Si vous utilisez uniquement Django pour créer des API, vous n'avez pas besoin de templates et de vues, mais vous pouvez utiliser les modèles Django pour créer des objets Python qui représentent vos tables de base de données et donc utiliser les capacités d'ORM (Object Relational Mapping) de Django pour manipuler vos données.
accéder à la publication Guillaume Rongier · Oct 24, 2023 Bonjour, Je pense que c'est possible, cependant je n'ai pas encore eu l'occasion de le faire. L'idée est la suivante : Creer votre modèle Django en utilisant les classes Python qui vont bien. example : class MyModel(models.Model): # … fields … class Meta: managed = False # No database creation or deletion operations db_table = 'MyTable' Note : il faut bien mettre managed = False pour éviter que Django ne crée la table. Ou alors vous pouvez utiliser la commande django inspectdb pour générer le modèle Django à partir de votre base de données. python3 manage.py inspectdb ou encore python3 manage.py inspectdb > app_name/models.py
accéder à la publication Guillaume Rongier · Oct 17, 2023 Bonjour, Pour compléter la réponse de Lorenzo, il y aussi les librairies suivantes : iris_tar iris_zip Ou encore utiliser du code python comme car vous utilisez iris 2021.2+: Class ZIP.demo Extends %RegisteredObject { ClassMethod Demo(pFileName As %String) As %Status { // Read a zip file into a stream set zipStream = ##class(%Stream.FileBinary).%New() // Link the stream to the file do zipStream.LinkToFile(pFileName) // Call the unzip method set sc = ##class(ZIP.demo).UnzipStream(zipStream, "/tmp/unzip") Quit sc } ClassMethod UnzipStream( pZipStream As %Stream.GlobalBinary, pDestDir As %String) As %Status { // Import python lib unzip set unzip = ##class(%SYS.Python).Import("zipfile") // Write the stream to a temporary file set tZipStream = ##class(%Stream.FileBinary).%New() do tZipStream.LinkToFile("/tmp/zipfile.zip") do tZipStream.CopyFromAndSave(pZipStream) // Create a new zip object set zip = unzip.ZipFile("/tmp/zipfile.zip") // Extract the zip file do zip.extractall(pDestDir) // Close the zip file do zip.close() Quit $$$OK } }
accéder à la publication Guillaume Rongier · Oct 16, 2023 Bonjour @Jean-Charles Cano , Pour le passage d'un stream à un autre, j'éviterai d'utiliser la fonction Write si vous ne bouclez pas sur le stream d'entrée. En effet, la fonction Write fonctionne par chunks, donc si vous n'avez pas lu tout le stream d'entrée, vous risquez de ne pas avoir tout écrit dans le stream de sortie. Comme vous utilisez la classe Ens.StreamContainer, vous pouvez utiliser le constructeur qui prend en paramètre un stream d'entrée et qui copie le contenu complet du stream d'entrée dans la variable de Stream du StreamContainer. Method OnProcessInput(pInput As %RegisteredObject, Output pOutput As %RegisteredObject) As %Status { Set sc = $$$OK set res = ##class(Ens.StringResponse).%New() set request = ##class(%Net.HttpRequest).%New() set response = ##class(%Net.HttpResponse).%New() set request.Https = 1 set request.Server = ..ServerAddress set request.Port = ..Port set request.SSLConfiguration = ..SSLConfiguration Try { set url = ..Path _ "/exportArticles_"_$ZDATE($HOROLOG,8)_".csv" set status = request.Get(url) $$$TRACE("request.HttpResponse.Data :"_request.HttpResponse.Data) #; Commented code to show the difference between the two methods #; set content = ##class(Ens.StreamContainer).%New() #; set stream = ##class(%Stream.GlobalCharacter).%New() #; do stream.Write(request.HttpResponse.Data) #; Recommended method set content = ##class(Ens.StreamContainer).%New(request.HttpResponse.Data) #; Other methods by looping on the stream #; set content = ##class(Ens.StreamContainer).%New() #; set stream = ##class(%Stream.GlobalCharacter).%New() #; while 'request.HttpResponse.Data.AtEnd { #; set stream.Write(request.HttpResponse.Data.Read()) #; } #; set content.Stream = stream $$$TRACE("sc : " _ request.HttpResponse.StatusCode) #; Old code #; $$$TRACE("stream size:"_stream.Size) #; set content.Stream = stream #; $$$TRACE("stream :"_stream.Read(1000)) #; New code $$$TRACE("content.Stream.Size :"_content.Stream.Size) $$$TRACE("content.Stream :"_content.Stream.Read(1000)) set sc = ..SendRequestSync(..TargetConfigNames, content) } Catch ex { set status= ex.AsStatus() $$$TRACE("erreur : "_status) } set result = request.HttpResponse.StatusCode if (result '= 200) { $$$TRACE("status: "_ result) } return $$$OK } Ensuite pour la partie écriture avec l'adapter FTP,vous pouvez utiliser la methode PutStream de l'adapter FTP. Class SupplyChain.exportArticleHaby Extends Ens.BusinessOperation { Property Adapter As EnsLib.FTP.OutboundAdapter; Parameter ADAPTER = "EnsLib.FTP.OutboundAdapter"; Parameter INVOCATION = "Queue"; Method putFileStream(pRequest As Ens.StreamContainer, Output pResponse As Ens.Response) As %Status { $$$TRACE("pRequest : "_ pRequest) Try { set fileName = "exportArticles_"_$ZDATE($HOROLOG,8)_".csv" set esc = ..Adapter.PutStream(fileName, pRequest.Stream) } Catch ex { $$$TRACE("statusCode: " _ esc) Set tSC=ex.AsStatus() } return $$$OK } XData MessageMap { <MapItems> <MapItem MessageType="Ens.StreamContainer"> <Method>putFileStream</Method> </MapItem> </MapItems> } }
accéder à la publication Guillaume Rongier · Sept 18, 2023 Bonjour, %Net.HttpRequest n'est pas une classe de type message (Ens.Request). Il faut encapsuler le JSON en provenance du Service dans une classe qui herite de Ens.Request.
accéder à la publication Guillaume Rongier · Déc 12, 2022 Les versions client d'IRIS/ HealthShare sont fournis avec l'installation du Serveur dans le dossier suivant : <dossier d'install>/dev example sous linux : /usr/irissys/dev/dotnet/ `-- bin |-- InterSystems.Data.Bindings.2.0.0.nupkg |-- InterSystems.Data.IRISClient.2.0.0.nupkg |-- InterSystems.Data.Utils.2.0.0.nupkg |-- InterSystems.Data.XEP.2.0.0.nupkg |-- net5.0 | |-- InterSystems.Data.Gateway.pdb | |-- InterSystems.Data.Gateway.xml | |-- InterSystems.Data.GatewayArm | |-- InterSystems.Data.GatewayLinux | |-- InterSystems.Data.GatewayOSX | |-- InterSystems.Data.IRISClient.dll | |-- InterSystems.Data.IRISClient.xml | |-- InterSystems.Data.Utils.dll | |-- InterSystems.Data.Utils.xml | `-- Newtonsoft.Json.dll `-- net6.0 |-- InterSystems.Data.Gateway.pdb |-- InterSystems.Data.Gateway.xml |-- InterSystems.Data.GatewayArm |-- InterSystems.Data.GatewayLinux |-- InterSystems.Data.GatewayOSX |-- InterSystems.Data.IRISClient.dll |-- InterSystems.Data.IRISClient.xml |-- InterSystems.Data.Utils.dll |-- InterSystems.Data.Utils.xml `-- Newtonsoft.Json.dll Toutes ces libraires peuvent etre utilisées sur une autre machine, elles ouvreront une socket TCP pour effectuer la connection sur le superserver port (1972 par default, 51773 pour HealthShare, enfin je crois).