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...

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.

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

Bonjour,

Pour compléter la réponse de Lorenzo, il y aussi les librairies suivantes :

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
}

}

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>
}

}

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).