Cette preuve de concept vise à montrer comment le cadre d'interopérabilité de l'iris peut être utilisé avec d'Embedded Python.
1.1. Table des matières
- 1. interoperability-embedded-python
- 2. Démo
- 3. Conditions préalables
- 4. Installation
- 5. Comment exécuter l'échantillon
- 6. Que trouve-t-on dans le référentiel ?
- 7. Comment ça marche
- 7.1. Le fichier__init__.py
- 7.2. La classe common
- 7.3. La classe business_host
- 7.4. La classe inbound_adapter
- 7.5. La classe outbound_adapter
- 7.6. Le classebusiness_service
- 7.7. La classe business_process
- 7.8. La classe business_operation
- 7.9. La classe director
- 7.10. Les objets
- 7.11. Les messages
- 7.12. Comment enregistrer un composant
- 7.13. Utilisation directe de Grongier.PEX
- 8. Générique
1.2. Exemple
from grongier.pex import BusinessOperation,Message
@dataclass
class MyRequest(Message):
request_string:str = None
@dataclass
class MyResponse(Message):
my_string:str = None
class MyBusinessOperation(BusinessOperation):
def on_init(self):
#Cette méthode est appelée lorsque le composant devient actif dans la production.
self.log_info("[Python] ...MyBusinessOperation:on_init() is called")
return
def on_teardown(self):
#Cette méthode est appelée lorsque le composant devient inactif dans la production.
self.log_info("[Python] ...MyBusinessOperation:on_teardown() is called")
return
def on_message(self, message_input:MyRequest):
# Appelé depuis le service/process/opération, le message est de type MyRequest avec la propriété request_string
self.log_info("[Python] ...MyBusinessOperation:on_message() is called with message:"+message_input.request_string)
response = MyResponse("...MyBusinessOperation:on_message() echos")
return response
PythonPython
1.3. Enregistrer un composant
Grâce à la méthode grongier.pex.Utils.register_component() :
Lancer un shell python intégré :
/usr/irissys/bin/irispython
BashBash
Utilisez ensuite cette méthode de classe pour ajouter une classe python à la liste des composants pour l'interopérabilité.
from grongier.pex import Utils
Utils.register_component(<ModuleName>,<ClassName>,<PathToPyFile>,<OverWrite>,<NameOfTheComponent>)
PythonPython
par exemple :
from grongier.pex import Utils
Utils.register_component("MyCombinedBusinessOperation","MyCombinedBusinessOperation","/irisdev/app/src/python/demo/",1,"PEX.MyCombinedBusinessOperation")
PythonPython
C'est un hack, ce n'est pas pour la production.
2. Démo
La démo se trouve dans src/python/demo/reddit/ et se compose de :
- Un fichier adapter.py contenant un RedditInboundAdapter qui, étant donné un service, récupérera les messages récents de Reddit.
- Un fichier bs.py contient trois services qui font la même chose, ils appelleront notre Processus et l'enverront à reddit post. Le premier travaille seul, le second utilise l'adaptateur RedditInBoundAdapter dont nous avons parlé précédemment et le troisième utilise un adaptateur reddit inbound codé en ObjectScript.
- Un fichier bp.py contenant un processus FilterPostRoutingRule qui va analyser nos posts reddit et les envoyer à nos opérations s'ils contiennent certains mots.
- Un fichier bo.py contenant :
- Deux opérations de courrier électronique qui enverront un courriel à une certaine entreprise selon les mots analysés précédemment, l'une fonctionne seule et l'autre avec un OutBoundAdapter.
- Deux opérations de fichier qui écriront dans un fichier texte selon les mots analysés auparavant, l'une fonctionne seule et l'autre avec un OutBoundAdapter.
Nouvelle trace json pour les messages natifs de python :
3. Conditions préalables
Assurez-vous que vous avez installé git et Docker desktop.
4. Installation
4.1. Avec Docker
Clone/git extrait le référentiel dans n'importe quel répertoire local.
git clone https://github.com/grongierisc/interpeorability-embedded-python
BashBash
Ouvrez le terminal dans ce répertoire et lancez:
docker-compose build
BashBash
Lancez le conteneur IRIS avec votre projet:
docker-compose up -d
BashBash
4.2. Sans Docker
Avec PyPi :
pip3 install iris_pex_embedded_python
Puis dans un shell python :
from grongier.pex import Utils Utils.setup()
4.3. Avec ZPM
zpm "install pex-embbeded-python"
5. Comment exécuter l'échantillon
5.1. Conteneurs Docker
Afin d'avoir accès aux images d'InterSystems, nous devons nous rendre à l'adresse suivante URL :http://container.intersystems.com. Après avoir connecté avec nos informations d'identification InterSystems, nous obtiendrons notre mot de passe pour nous connecter au registre. Dans l'extension docker VScode, dans l'onglet image, en appuyant sur "connect registry" (connecter le registre) et en entrant la même url que précédemment (http://container.intersystems.com) comme registre générique, il nous sera demandé de donner nos informations d'identification. L'identifiant est le même que d'habitude mais le mot de passe est celui que nous avons obtenu du site web.
À partir de là, nous devrions être en mesure de construire et de composer nos conteneurs (avec les fichiers docker-compose.yml et donnés de Dockerfile).
5.2. Portail de gestion et VSCode
Ce dépôt est prêt pour VS Code.
Ouvrez le dossier interoperability-embedeed-python cloné localement dans VS Code.
Si vous y êtes invité (dans le coin inférieur droit), installez les extensions recommandées.
IMPORTANT: Lorsque vous y êtes invité, rouvrez le dossier à l'intérieur du conteneur afin de pouvoir utiliser les composants python qu'il contient. La première fois que vous effectuez cette opération, cela peut prendre plusieurs minutes, le temps que le conteneur soit préparé.
En ouvrant le dossier à distance, vous permettez à VS Code et à tous les terminaux ouverts dans ce dossier d'utiliser les composants python dans le conteneur. Configurez-les pour utiliser /usr/irissys/bin/irispython
5.3. Ouverture de la production
Pour ouvrir la production, vous pouvez aller à production.
Vous pouvez également cliquer en bas sur le bouton 127.0.0.1:52773 [IRISAPP] et sélectionner Open Management Portal et cliquer sur les menus d'Interopérabilité [Interoperability] et configuration [Configurer] puis cliquer sur [productions] et [Go].
La production a déjà quelques exemples de code.
Ici, nous pouvons voir la production et nos services et opérations en python pur :
Nouvelle trace json pour les messages natifs de Python :
6. Que trouve-t-on dans le référentiel ?
6.1. Dockerfile
Un dockerfile qui installe quelques dépendances de python (pip, venv) et sudo dans le conteneur pour les besoins. Puis il crée le répertoire dev et y copie ce dépôt git.
Il démarre IRIS et active %Service_CallIn pour Python Shell. Utilisez le fichier docker-compose.yml correspondant pour configurer facilement des paramètres supplémentaires tels que le numéro de port et l'emplacement des clés et des dossiers d'hôte.
Ce dockerfile se termine par l'installation des exigences pour les modules python.
Utilisez le fichier .env/ pour ajuster le dockerfile utilisé dans docker-compose.
6.2. .vscode/settings.json
Fichier de configuration pour vous permettre de coder immédiatement en VSCode avec le plugin VSCode ObjectScript.
6.3. .vscode/launch.json
Fichier de configuration si vous voulez déboguer avec VSCode ObjectScript
Découvrez tous les fichiers dans cet article
6.4. .vscode/extensions.json
Fichier de recommandation pour ajouter des extensions si vous voulez fonctionner avec VSCode dans le conteneur.
Ceci est très utile pour travailler avec python intégré.
6.5. dossier src
src
├── Grongier
│ └── PEX // Classes d'ObjectScript qui enveloppent le code python
│ ├── BusinessOperation.cls
│ ├── BusinessProcess.cls
│ ├── BusinessService.cls
│ ├── Common.cls
│ ├── Director.cls
│ ├── InboundAdapter.cls
│ ├── Message.cls
│ ├── OutboundAdapter.cls
│ ├── Python.cls
│ ├── Test.cls
│ └── _utils.cls
├── PEX // Quelques exemples de classes enveloppées
│ └── Production.cls
└── python
├── demo // Code python actuel pour exécuter cette démo
| `-- reddit
| |-- adapter.py
| |-- bo.py
| |-- bp.py
| |-- bs.py
| |-- message.py
| `-- obj.py
├── dist // Roue utilisée pour pour la mise en œuvre des composants d'interopérabilité python
│ └── grongier_pex-1.2.4-py3-none-any.whl
├── grongier
│ └── pex // Classes d'aide pour la mise en œuvre des composants d'interopérabilité
│ ├── _business_host.py
│ ├── _business_operation.py
│ ├── _business_process.py
│ ├── _business_service.py
│ ├── _common.py
│ ├── _director.py
│ ├── _inbound_adapter.py
│ ├── _message.py
│ ├── _outbound_adapter.py
│ ├── __init__.py
│ └── _utils.py
─ ─ ─ setup.py // configuration pour construire la roue
Shell SessionShell Session
7. Comment ça marche
7.1. Le fichier __init__.py
Ce fichier va nous permettre de créer les classes à importer dans le code.
Il récupère les classes dans les multiples fichiers vus précédemment et les transforme en classes appelables. Ainsi, lorsque vous souhaitez créer une opération métier, par exemple, il vous suffit de faire ceci :
from grongier.pex import BusinessOperation
PythonPython
7.2. La classe common
La classe "common" ne doit pas être appelée par l'utilisateur, elle définit presque toutes les autres classes.
Cette classe définit le suivant:
on_init: La méthode on_init() est appelée lorsque le composant est lancé.
Utilisez la méthode on_init() pour initialiser toutes les structures nécessaires au composant.
on_tear_down: La méthode est appelée avant que le composant ne soit terminé.
Utilisez-la pour libérer toutes les structures.
on_connected: La méthode on_connected() est appelée lorsque le composant est connecté ou reconnecté après avoir été déconnecté.
Utilisez la méthode on_connected() pour initialiser toutes les structures nécessaires au composant.
log_info: Rédigez une entrée de journal de type "info". :log - ces entrées de journal peuvent être consultées dans le portail de gestion.
log_alert: Rédigez une entrée de journal de type "alerte". :log - ces entrées de journal peuvent être consultées dans le portail de gestion.
log_warning: Rédigez une entrée de journal de type "avertissement". :log - ces entrées de journal peuvent être consultées dans le portail de gestion.
log_error: Rédigez une entrée de journal de type "erreur". :log - ces entrées de journal peuvent être consultées dans le portail de gestion.
7.3. La classe business_host
La classe hôte métier ne doit pas être appelée par l'utilisateur, c'est la classe de base pour toutes les classes d'entreprise.
Cette classe définit le suivant:
send_request_sync: Envoyer le message spécifié au processus d'entreprise ou à l'opération métier cible de manière synchrone.
Paramètre:
- target: une chaîne de caractères qui spécifie le nom du processus métier ou de l'opération devant recevoir la requête. La cible est le nom du composant tel que spécifié dans la propriété Item Name de la définition de production, et non le nom de la classe du composant.
- request: spécifie le message à envoyer à la cible. La requête est soit une instance d'une classe appartenant à la classe Message soit une instance de la classe IRISObject. Si la cible est un composant ObjectScript intégré, vous devez utiliser la classe IRISObject. La classe IRISObject permet au cadre PEX de convertir le message en une classe prise en charge par la cible.
- timeouts: un nombre entier facultatif qui spécifie le nombre de secondes à attendre avant de traiter la requête d'envoi comme un échec. La valeur par défaut est -1, ce qui signifie attendre indéfiniment. description : un paramètre facultatif de type chaîne qui définit une propriété de description dans l'en-tête du message. La valeur par défaut est None.
Retour : l'objet de réponse de la cible.
Renvoie : TypeError: si la requête n'est pas de type Message ou IRISObject.
send_request_async: Envoyez le message spécifié au processus métier ou à l'opération d'entreprise cible de manière asynchrone.
Paramètre:
- target: une chaîne de caractères qui spécifie le nom du processus métier ou de l'opération devant recevoir la requête. La cible est le nom du composant tel que spécifié dans la propriété Item Name de la définition de production, et non le nom de la classe du composant.
- request: spécifie le message à envoyer à la cible. La requête est une instance d' IRISObject ou d'une sous-classe de Message. Si la cible est un composant ObjectScript intégré, vous devez utiliser la classe IRISObject. La classe IRISObject permet au cadre PEX de convertir le message en une classe prise en charge par la cible.
- description: un paramètre facultatif de type chaîne qui définit une propriété de description dans l'en-tête du message. La valeur par défaut est None.
Renvoie : TypeError: si la requête n'est pas de type Message ou IRISObject.
get_adapter_type: Nom de l'adaptateur enregistré.
7.4. La classe inbound_adapter
Inbound Adapter en Python sont des sous-classes de grongier.pex.InboundAdapter en Python, qui héritent de toutes les fonctions de la common class.
Cette classe est chargée de recevoir les données du système externe, de les valider et de les envoyer au service métier en appelant la méthode process_input de BusinessHost. Cette classe définit le suivant:
on_task: Appelé par le cadre de production à des intervalles déterminés par la propriété CallInterval du service métier.
Le message peut avoir n'importe quelle structure convenue par l'adaptateur entrant et le service métier.
Exemple d'un adaptateur entrant (situé dans le fichier src/python/demo/reddit/adapter.py):
from grongier.pex import InboundAdapter
import requests
import iris
import json
class RedditInboundAdapter(InboundAdapter):
"""
Cet adaptateur utilise des requêtes pour récupérer les messages de self.limit en tant que données
de l'API reddit avant d'appeler process_input pour chaque message.
"""
def on_init(self):
if not hasattr(self,'feed'):
self.feed = "/new/"
if self.limit is None:
raise TypeError('no Limit field')
self.last_post_name = ""
return 1
def on_task(self):
self.log_info(f"LIMIT:{self.limit}")
if self.feed == "" :
return 1
tSC = 1
# Requête HTTP
try:
server = "https://www.reddit.com"
request_string = self.feed+".json?before="+self.last_post_name+"&limit="+self.limit
self.log_info(server+request_string)
response = requests.get(server+request_string)
response.raise_for_status()
data = response.json()
updateLast = 0
for key, value in enumerate(data['data']['children']):
if value['data']['selftext']=="":
continue
post = iris.cls('dc.Reddit.Post')._New()
post._JSONImport(json.dumps(value['data']))
post.OriginalJSON = json.dumps(value)
if not updateLast:
self.LastPostName = value['data']['name']
updateLast = 1
response = self.BusinessHost.ProcessInput(post)
except requests.exceptions.HTTPError as err:
if err.response.status_code == 429:
self.log_warning(err.__str__())
else:
raise err
except Exception as err:
self.log_error(err.__str__())
raise err
return tSC
PythonPython
7.5. La classe outbound_adapter
Outbound Adapter en Python sont des sous-classes de grongier.pex.OutboundAdapter en Python, qui héritent de toutes les fonctions de la common class.
Cette classe est responsable de l'envoi des données au système externe.
L'adaptateur entrant Outbound Adapter donne à l'opération la possibilité d'avoir une notion de battement de cœur. Pour activer cette option, le paramètre CallInterval de l'adaptateur doit impérativement être supérieur à 0.
Exemple d'un adaptateur sortant (situé dans le fichier src/python/demo/reddit/adapter.py):
class TestHeartBeat(OutboundAdapter):
def on_keepalive(self):
self.log_info('beep')
def on_task(self):
self.log_info('on_task')
PythonPython
7.6. La classe business_service
Cette classe est responsable de la réception des données provenant d'un système externe et de leur envoi aux processus ou aux opérations métier dans la production.
Le service métier peut utiliser un adaptateur pour accéder au système externe, qui est spécifié en surchargeant la méthode get_adapter_type.
Il y a trois façons de mettre en œuvre un service métier :
- Service métier au sondage avec un adaptateur - Le cadre de production appelle à intervalles réguliers la méthode OnTask() de l'adaptateur, qui envoie les données entrantes à la méthode ProcessInput() du service métier, qui, à son tour, appelle la méthode OnProcessInput avec votre code.
- Service métier au sondage qui utilise l'adaptateur par défaut - Dans ce cas, le cadre appelle la méthode OnTask de l'adaptateur par défaut sans données. La méthode OnProcessInput() joue alors le rôle de l'adaptateur et se charge d'accéder au système externe et de recevoir les données..
- Service métier sans sondage - Le cadre de production ne lance pas le service métier. Au lieu de cela, le code personnalisé d'un processus à long terme ou d'un processus lancé à intervalles réguliers lance le service métier en appelant la méthode Director.CreateBusinessService().
Les services métier en Python sont des sous-classes de grongier.pex.BusinessService en Python, qui héritent de toutes les fonctions de l'hôte métier.
Cette classe définit le suivant:
on_process_input: Reçoit le message de l'adaptateur entrant via la méthode PRocessInput et est chargé de le transmettre aux processus ou opérations cibles.
Si le service métier ne spécifie pas d'adaptateur, alors l'adaptateur par défaut appelle cette méthode sans message et le service métier est chargé de recevoir les données du système externe et de les valider.
Paramètre :
- message_input: une instance d'IRISObject ou une sous-classe de Message contenant les données que l'adaptateur entrant transmet. Le message peut avoir n'importe quelle structure convenue par l'adaptateur entrant et le service métier.
Exemple de service métier (situé dans le fichier src/python/demo/reddit/bs.py):
from grongier.pex import BusinessService
import iris
from message import PostMessage
from obj import PostClass
class RedditServiceWithPexAdapter(BusinessService):
"""
Ce service utilise notre python Python.RedditInboundAdapter pour recevoir le message
du site reddit et appeler le processus FilterPostRoutingRule.
"""
def get_adapter_type():
"""
Nom de l'adaptateur enregistré
"""
return "Python.RedditInboundAdapter"
def on_process_input(self, message_input):
msg = iris.cls("dc.Demo.PostMessage")._New()
msg.Post = message_input
return self.send_request_sync(self.target,msg)
def on_init(self):
if not hasattr(self,'target'):
self.target = "Python.FilterPostRoutingRule"
return
PythonPython
7.7. La classe business_process
Contient généralement la majeure partie de la logique d'une production.
Un processus métier peut recevoir des messages d'un service métier, d'un autre processus métier ou d'une opération métier.
Il peut modifier le message, le convertir dans un format différent ou l'acheminer en fonction de son contenu.
Le processus métier peut acheminer un message vers une opération métier ou un autre processus métier.
Le processus métier en Python sont des sous-classes de grongier.pex.BusinessProcess en Python, qui héritent de toutes les fonctions de l'hôte métier.
Cette classe définit le suivant:
on_request: Gère les requêtes envoyées au processus métier. Une production appelle cette méthode chaque fois qu'une requête initiale pour un processus métier spécifique arrive dans la file d'attente appropriée et se voit attribuer un travail à exécuter.
Paramètre:
- request: Une instance d'IRISObject ou une sous-classe de Message qui contient le message de requête envoyé au processus métier.
Retour : Une instance d'IRISObject ou une sous-classe de Message qui contient le message de réponse que ce processus métier peut renvoyer au composant de production qui a envoyé le message initial.
on_response: Gère les réponses envoyées au processus métier en réponse aux messages que celui-ci a envoyés à la cible.
Une production appelle cette méthode chaque fois qu'une réponse pour un processus métier spécifique arrive dans la file d'attente appropriée et se voit attribuer un travail à exécuter.
Il s'agit généralement d'une réponse à une requête asynchrone faite par le processus métier où le paramètre responseRequired a une valeur vraie.
Paramètre:
- request: Une instance d'IRISObject ou une sous-classe de Message qui contient le message initiale de requête envoyé au processus métier.
- response: Une instance d'IRISObject ou une sous-classe de Message qui contient le message de réponse que ce processus métier peut renvoyer au composant de production qui a envoyé le message initial.
- callRequest: Une instance d'IRISObject ou une sous-classe de Message qui contient la requête que le processus métier a envoyée à sa cible.
- callResponse: Une instance d'IRISObject ou une sous-classe de Message qui contient la réponse entrante.
- completionKey: Une chaîne qui contient la clé d'achèvement completionKey spécifiée dans le paramètre completionKey de la méthode sortante SendAsync().
Retour : Une instance d'IRISObject ou une sous-classe de Message qui contient le message de réponse que ce processus métier peut renvoyer au composant de production qui a envoyé le message initial.
on_complète: Appelé après que le processus métier a reçu et traité toutes les réponses aux requêtes qu'il a envoyées aux cibles.
Paramètre:
- request: Une instance d'IRISObject ou une sous-classe de Message qui contient le message initiale de requête envoyé au processus métier.
- response: Une instance d'IRISObject ou une sous-classe de Message qui contient le message de réponse que ce processus métier peut renvoyer au composant de production qui a envoyé le message initial.
Retour : Une instance d'IRISObject ou une sous-classe de Message qui contient le message de réponse que ce processus métier peut renvoyer au composant de production qui a envoyé le message initial.
Exemple de service métier (situé dans le fichers src/python/demo/reddit/bp.py):
from grongier.pex import BusinessProcess
from message import PostMessage
from obj import PostClass
class FilterPostRoutingRule(BusinessProcess):
"""
Ce processus reçoit un PostMessage contenant un post reddit.
Il reconnaît alors si le message parle d'un chien, d'un chat ou de rien
et remplit les informations appropriées dans le PostMessage avant de l'envoyer
à l'opération FileOperation.
"""
def on_init(self):
if not hasattr(self,'target'):
self.target = "Python.FileOperation"
return
def on_request(self, request):
if 'dog'.upper() in request.post.selftext.upper():
request.to_email_address = 'dog@company.com'
request.found = 'Dog'
if 'cat'.upper() in request.post.selftext.upper():
request.to_email_address = 'cat@company.com'
request.found = 'Cat'
if request.found is not None:
return self.send_request_sync(self.target,request)
else:
return
PythonPython
7.8. La classe business_operation
Cette classe est chargée d'envoyer les données à un système externe ou à un système local tel qu'une base de données d'iris.
L'opération métier peut utiliser comme une option un adaptateur pour traîter le message sortant, qui est spécifié en surchargeant la méthode get_adapter_type.
Si la transaction métier dispose d'un adaptateur, elle l'utilise pour envoyer le message au système externe.
L'adaptateur peut être un adaptateur PEX, un adaptateur ObjectScript ou un adaptateur python.
L'opération métier en Python sont des sous-classes de grongier.pex.BusinessOperation en Python, qui héritent de toutes les fonctions de l'hôte métier.
7.8.1. Le système de répartition
Dans une opération métier, il est possible de créer un certain nombre de fonctions similaires à la méthode on_message qui prendront comme argument une requête typée comme ceci my_special_message_method(self,request: MySpecialMessage).
Le système de répartition analysera automatiquement toute requête arrivant à l'opération et répartira les requêtes en fonction de leur type. Si le type de la requête n'est pas reconnu ou n'est pas spécifié dans une fonction similaire à la fonction type on_message, le système de répartition l'envoie à la fonction on_message.
7.8.2. Les méthodes
Cette classe définit le suivant:
on_message: Appelé lorsque l'opération métier reçoit un message d'un autre composant de production qui ne peut pas être distribué à une autre fonction.
En règle générale, l'opération envoie le message au système externe ou le transmet à un processus métier ou à une autre opération métier. Si l'opération a un adaptateur, elle utilise la méthode Adapter.invoke() pour appeler la méthode sur l'adaptateur qui envoie le message au système externe. Si l'opération transmet le message à un autre composant de production, elle utilise la méthode SendRequestAsync() ou SendRequestSync().
Paramètre:
- request: Une instance d'une sous-classe de Message ou d'IRISObject contenant le message entrant pour l'opération métier.
Retour : L'objet de réponse
Exemple d'une opération métier (située dans le fichier src/python/demo/reddit/bo.py):
from grongier.pex import BusinessOperation
from message import MyRequest,MyMessage
import iris
import os
import datetime
import smtplib
from email.mime.text import MIMEText
class EmailOperation(BusinessOperation):
"""
Cette opération reçoit un PostMessage et envoie un courriel contenant toutes
les informations importantes à l'entreprise concernée (entreprise de chiens ou de chats).
"""
def my_message(self,request:MyMessage):
sender = 'admin@example.com'
receivers = 'toto@example.com'
port = 1025
msg = MIMEText(request.toto)
msg['Subject'] = 'MyMessage'
msg['From'] = sender
msg['To'] = receivers
with smtplib.SMTP('localhost', port) as server:
server.sendmail(sender, receivers, msg.as_string())
print("Successfully sent email")
def on_message(self, request):
sender = 'admin@example.com'
receivers = [ request.to_email_address ]
port = 1025
msg = MIMEText('This is test mail')
msg['Subject'] = request.found+" found"
msg['From'] = 'admin@example.com'
msg['To'] = request.to_email_address
with smtplib.SMTP('localhost', port) as server:
# server.login('username', 'password')
server.sendmail(sender, receivers, msg.as_string())
print("Successfully sent email")
PythonPython
Si cette opération est appelée en utilisant un message MyRequest, la fonction my_message sera appelée grâce au distributeur, sinon la fonction on_message sera appelée.
7.9. La classe director
La classe Directorclass est utilisée pour les services métier sans sondage, c'est-à-dire les services métier qui ne sont pas automatiquement appelés par le cadre de production (via l'adaptateur entrant) à l'intervalle d'appel.
Au lieu de cela, ces services métier sont créés par une application personnalisée en appelant la méthode Director.create_business_service().
Cette classe définit le suivant:
create_business_service: La méthode create_business_service() lance le service métier spécifié.
Paramètre:
- connection: un objet IRISConnection qui spécifie la connexion à une instance IRIS pour Java.
- target: une chaîne qui spécifie le nom du service métier dans la définition de production.
Retour : un objet qui contient une instance d' IRISBusinessService
Exemple de TEC
7.10. Les objets
Nous utiliserons dataclass pour contenir les informations dans nos messages dans un fichier obj.py.
Exemple d'un objet (situé dans le fichier src/python/demo/reddit/obj.py):
from dataclasses import dataclass
@dataclass
class PostClass:
title: str
selftext : str
author: str
url: str
created_utc: float = None
original_json: str = None
PythonPython
7.11. Les messages
Les messages contiendront un ou plusieurs objets, situé dans le fichier obj.py.
Les messages, les requêtes et les réponses sont tous hérités de la classe grongier.pex.Message.
Ces messages nous permettront de transférer des informations entre n'importe quel service/processus/opération métier.
Exemple d'un message (situé dans le fichier src/python/demo/reddit/message.py):
from grongier.pex import Message
from dataclasses import dataclass
from obj import PostClass
@dataclass
class PostMessage(Message):
post:PostClass = None
to_email_address:str = None
found:str = None
PythonPython
TEC Il est à noter qu'il est nécessaire d'utiliser des types lorsque vous définissez un objet ou un message.
7.12. Comment enregistrer un composant
Vous pouvez enregistrer un composant dans iris de plusieurs manières :
- Un seul composant avec register_component
- Tous les composants dans un fichier avec register_file
- Tous les composants dans un dossier avec register_folder
7.12.1. register_component
Lancer un shell python intégré :
/usr/irissys/bin/irispython
BashBash
Utilisez ensuite cette méthode de classe pour ajouter un nouveau fuchier py à la liste des composants pour l'interopérabilité.
from grongier.pex import Utils
Utils.register_component(<ModuleName>,<ClassName>,<PathToPyFile>,<OverWrite>,<NameOfTheComponent>)
PythonPython
par exemple :
from grongier.pex import Utils
Utils.register_component("MyCombinedBusinessOperation","MyCombinedBusinessOperation","/irisdev/app/src/python/demo/",1,"PEX.MyCombinedBusinessOperation")
PythonPython
7.12.2. register_file
Lancer un shell python intégré :
/usr/irissys/bin/irispython
BashBash
Utilisez ensuite cette méthode de classe pour ajouter un nouveau fuchier py à la liste des composants pour l'interopérabilité.
from grongier.pex import Utils
Utils.register_file(<File>,<OverWrite>,<PackageName>)
PythonPython
par exemple :
from grongier.pex import Utils
Utils.register_file("/irisdev/app/src/python/demo/bo.py",1,"PEX")
PythonPython
7.12.3. register_folder
Lancer un shell python intégré :
/usr/irissys/bin/irispython
BashBash
Utilisez ensuite cette méthode de classe pour ajouter un nouveau fuchier py à la liste des composants pour l'interopérabilité.
from grongier.pex import Utils
Utils.register_folder(<Path>,<OverWrite>,<PackageName>)
PythonPython
par exemple :
from grongier.pex import Utils
Utils.register_folder("/irisdev/app/src/python/demo/",1,"PEX")
PythonPython
7.13. Utilisation directe de Grongier.PEX
Si vous ne souhaitez pas utiliser l'utilitaire register_component, Vous pouvez ajouter un composant Grongier.PEX.BusinessService directement dans le portail de gestion et configurer les propriétés :
- %module :
- Nom du module de votre code python
- %classname :
- Nom de classe de votre composant
- %classpaths
- Chemin où se trouve votre composant.
- Cela peut nécessiter un chemin ou plusieurs chemins de classe (séparés par le caractère '|') en plus de PYTHON_PATH
- Chemin où se trouve votre composant.
par exemple :
8. Générique
La plupart du code provient de PEX for Python de Mo Cheng et Summer Gerry.
Fonctionne uniquement sur IRIS 2021.2 +