Clear filter
Article
Guillaume Rongier · Feb 7, 2022
# 1. interoperability-embedded-python
This proof of concept aims to show how the **iris interoperability framework** can be use with **embedded python**.
## 1.1. Table of Contents
- [1. interoperability-embedded-python](#1-interoperability-embedded-python)
- [1.1. Table of Contents](#11-table-of-contents)
- [1.2. Example](#12-example)
- [1.3. Register a component](#13-register-a-component)
- [2. Demo](#2-demo)
- [3. Prerequisites](#3-prerequisites)
- [4. Installation](#4-installation)
- [4.1. With Docker](#41-with-docker)
- [4.2. Without Docker](#42-without-docker)
- [4.3. With ZPM](#43-with-zpm)
- [4.4. With PyPI](#44-with-pypi)
- [4.4.1. Known issues](#441-known-issues)
- [5. How to Run the Sample](#5-how-to-run-the-sample)
- [5.1. Docker containers](#51-docker-containers)
- [5.2. Management Portal and VSCode](#52-management-portal-and-vscode)
- [5.3. Open the production](#53-open-the-production)
- [6. What's inside the repository](#6-whats-inside-the-repository)
- [6.1. Dockerfile](#61-dockerfile)
- [6.2. .vscode/settings.json](#62-vscodesettingsjson)
- [6.3. .vscode/launch.json](#63-vscodelaunchjson)
- [6.4. .vscode/extensions.json](#64-vscodeextensionsjson)
- [6.5. src folder](#65-src-folder)
- [7. How it works](#7-how-it-works)
- [7.1. The `__init__.py`file](#71-the-__init__pyfile)
- [7.2. The `common` class](#72-the-common-class)
- [7.3. The `business_host` class](#73-the-business_host-class)
- [7.4. The `inbound_adapter` class](#74-the-inbound_adapter-class)
- [7.5. The `outbound_adapter` class](#75-the-outbound_adapter-class)
- [7.6. The `business_service` class](#76-the-business_service-class)
- [7.7. The `business_process` class](#77-the-business_process-class)
- [7.8. The `business_operation` class](#78-the-business_operation-class)
- [7.8.1. The dispacth system](#781-the-dispacth-system)
- [7.8.2. The methods](#782-the-methods)
- [7.9. The `director` class](#79-the-director-class)
- [7.10. The `objects`](#710-the-objects)
- [7.11. The `messages`](#711-the-messages)
- [7.12. How to regsiter a component](#712-how-to-regsiter-a-component)
- [7.12.1. register\_component](#7121-register_component)
- [7.12.2. register\_file](#7122-register_file)
- [7.12.3. register\_folder](#7123-register_folder)
- [7.12.4. migrate](#7124-migrate)
- [7.12.4.1. setting.py file](#71241-settingpy-file)
- [7.12.4.1.1. CLASSES section](#712411-classes-section)
- [7.12.4.1.2. Productions section](#712412-productions-section)
- [7.13. Direct use of Grongier.PEX](#713-direct-use-of-grongierpex)
- [8. Command line](#8-command-line)
- [8.1. help](#81-help)
- [8.2. default](#82-default)
- [8.3. lists](#83-lists)
- [8.4. start](#84-start)
- [8.5. kill](#85-kill)
- [8.6. stop](#86-stop)
- [8.7. restart](#87-restart)
- [8.8. migrate](#88-migrate)
- [8.9. export](#89-export)
- [8.10. status](#810-status)
- [8.11. version](#811-version)
- [8.12. log](#812-log)
- [9. Credits](#9-credits)
## 1.2. Example
```python
from grongier.pex import BusinessOperation,Message
class MyBusinessOperation(BusinessOperation):
def on_init(self):
#This method is called when the component is becoming active in the production
self.log_info("[Python] ...MyBusinessOperation:on_init() is called")
return
def on_teardown(self):
#This method is called when the component is becoming inactive in the production
self.log_info("[Python] ...MyBusinessOperation:on_teardown() is called")
return
def on_message(self, message_input:MyRequest):
# called from service/process/operation, message is of type MyRequest with property 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
@dataclass
class MyRequest(Message):
request_string:str = None
@dataclass
class MyResponse(Message):
my_string:str = None
```
## 1.3. Register a component
Thanks to the method grongier.pex.Utils.register_component() :
Start an embedded python shell :
```sh
/usr/irissys/bin/irispython
```
Then use this class method to add a python class to the component list for interoperability.
```python
from grongier.pex import Utils
Utils.register_component(,,,,)
```
e.g :
```python
from grongier.pex import Utils
Utils.register_component("MyCombinedBusinessOperation","MyCombinedBusinessOperation","/irisdev/app/src/python/demo/",1,"PEX.MyCombinedBusinessOperation")
```
This is a hack, this not for production.
# 2. Demo
The demo can be found inside `src/python/demo/reddit/` and is composed of :
- An `adapter.py` file that holds a `RedditInboundAdapter` that will, given a service, fetch Reddit recent posts.
- A `bs.py` file that holds three `services` that does the same thing, they will call our `Process` and send it reddit post. One work on his own, one use the `RedditInBoundAdapter` we talked about earlier and the last one use a reddit inbound adapter coded in ObjectScript.
- A `bp.py` file that holds a `FilterPostRoutingRule` process that will analyze our reddit posts and send it to our `operations` if it contains certain words.
- A `bo.py` file that holds :
- Two **email operations** that will send a mail to a certain company depending on the words analyzed before, one works on his own and the other one works with an OutBoundAdapter.
- Two **file operations** that will write in a text file depending on the words analyzed before, one works on his own and the other one works with an OutBoundAdapter.
New json trace for python native messages :
# 3. Prerequisites
Make sure you have [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [Docker desktop](https://www.docker.com/products/docker-desktop) installed.
# 4. Installation
## 4.1. With Docker
Clone/git pull the repo into any local directory
```sh
git clone https://github.com/grongierisc/interpeorability-embedded-python
```
Open the terminal in this directory and run:
```sh
docker-compose build
```
Run the IRIS container with your project:
```sh
docker-compose up -d
```
## 4.2. Without Docker
Install the *grongier_pex-1.2.4-py3-none-any.whl* on you local iris instance :
```sh
/usr/irissys/bin/irispython -m pip install grongier_pex-1.2.4-py3-none-any.whl
```
Then load the ObjectScript classes :
```ObjectScript
do $System.OBJ.LoadDir("/opt/irisapp/src","cubk","*.cls",1)
```
## 4.3. With ZPM
```objectscript
zpm "install pex-embbeded-python"
```
## 4.4. With PyPI
```sh
pip3 install iris_pex_embedded_python
```
Import the ObjectScript classes, open an embedded python shell and run :
```python
from grongier.pex import Utils
Utils.setup()
```
### 4.4.1. Known issues
If the module is not updated, make sure to remove the old version :
```sh
pip3 uninstall iris_pex_embedded_python
```
or manually remove the `grongier` folder in `/lib/python/`
or force the installation with pip :
```sh
pip3 install --upgrade iris_pex_embedded_python --target /lib/python/
```
# 5. How to Run the Sample
## 5.1. Docker containers
In order to have access to the InterSystems images, we need to go to the following url: http://container.intersystems.com. After connecting with our InterSystems credentials, we will get our password to connect to the registry. In the docker VScode addon, in the image tab, by pressing connect registry and entering the same url as before (http://container.intersystems.com) as a generic registry, we will be asked to give our credentials. The login is the usual one but the password is the one we got from the website.
From there, we should be able to build and compose our containers (with the `docker-compose.yml` and `Dockerfile` files given).
## 5.2. Management Portal and VSCode
This repository is ready for [VS Code](https://code.visualstudio.com/).
Open the locally-cloned `interoperability-embedeed-python` folder in VS Code.
If prompted (bottom right corner), install the recommended extensions.
**IMPORTANT**: When prompted, reopen the folder inside the container so you will be able to use the python components within it. The first time you do this it may take several minutes while the container is readied.
By opening the folder remote you enable VS Code and any terminals you open within it to use the python components within the container. Configure these to use `/usr/irissys/bin/irispython`
## 5.3. Open the production
To open the production you can go to [production](http://localhost:52773/csp/irisapp/EnsPortal.ProductionConfig.zen?PRODUCTION=PEX.Production).
You can also click on the bottom on the `127.0.0.1:52773[IRISAPP]` button and select `Open Management Portal` then, click on [Interoperability] and [Configure] menus then click [productions] and [Go].
The production already has some code sample.
Here we can see the production and our pure python services and operations:
New json trace for python native messages :
# 6. What's inside the repository
## 6.1. Dockerfile
A dockerfile which install some python dependancies (pip, venv) and sudo in the container for conviencies.
Then it create the dev directory and copy in it this git repository.
It starts IRIS and activates **%Service_CallIn** for **Python Shell**.
Use the related docker-compose.yml to easily setup additional parametes like port number and where you map keys and host folders.
This dockerfile ends with the installation of requirements for python modules.
Use .env/ file to adjust the dockerfile being used in docker-compose.
## 6.2. .vscode/settings.json
Settings file to let you immedietly code in VSCode with [VSCode ObjectScript plugin](https://marketplace.visualstudio.com/items?itemName=daimor.vscode-objectscript)
## 6.3. .vscode/launch.json
Config file if you want to debug with VSCode ObjectScript
[Read about all the files in this article](https://community.intersystems.com/post/dockerfile-and-friends-or-how-run-and-collaborate-objectscript-projects-intersystems-iris)
## 6.4. .vscode/extensions.json
Recommendation file to add extensions if you want to run with VSCode in the container.
[More information here](https://code.visualstudio.com/docs/remote/containers)

This is very useful to work with embedded python.
## 6.5. src folder
```
src
├── Grongier
│ └── PEX // ObjectScript classes that wrap python code
│ ├── BusinessOperation.cls
│ ├── BusinessProcess.cls
│ ├── BusinessService.cls
│ ├── Common.cls
│ ├── Director.cls
│ ├── InboundAdapter.cls
│ ├── Message.cls
│ ├── OutboundAdapter.cls
│ ├── Python.cls
│ ├── Test.cls
│ └── _utils.cls
├── PEX // Some example of wrapped classes
│ └── Production.cls
└── python
├── demo // Actual python code to run this demo
| `-- reddit
| |-- adapter.py
| |-- bo.py
| |-- bp.py
| |-- bs.py
| |-- message.py
| `-- obj.py
├── dist // Wheel used to implement python interoperability components
│ └── grongier_pex-1.2.4-py3-none-any.whl
├── grongier
│ └── pex // Helper classes to implement interoperability components
│ ├── _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 // setup to build the wheel
```
# 7. How it works
## 7.1. The `__init__.py`file
This file will allow us to create the classes to import in the code.
It gets from the multiple files seen earlier the classes and make them into callable classes.
That way, when you wish to create a business operation, for example, you can just do:
```python
from grongier.pex import BusinessOperation
```
## 7.2. The `common` class
The common class shouldn't be called by the user, it defines almost all the other classes.
This class defines:
`on_init`: The on_init() method is called when the component is started. Use the on_init() method to initialize any structures needed by the component.
`on_tear_down`: Called before the component is terminated. Use it to free any structures.
`on_connected`: The on_connected() method is called when the component is connected or reconnected after being disconnected.Use the on_connected() method to initialize any structures needed by the component.
`log_info`: Write a log entry of type "info". :log entries can be viewed in the management portal.
`log_alert`: Write a log entry of type "alert". :log entries can be viewed in the management portal.
`log_warning`: Write a log entry of type "warning". :log entries can be viewed in the management portal.
`log_error`: Write a log entry of type "error". :log entries can be viewed in the management portal.
## 7.3. The `business_host` class
The business host class shouldn't be called by the user, it is the base class for all the business classes.
This class defines:
`send_request_sync`: Send the specified message to the target business process or business operation synchronously.
**Parameters**:
- **target**: a string that specifies the name of the business process or operation to receive the request.
The target is the name of the component as specified in the Item Name property in the production definition, not the class name of the component.
- **request**: specifies the message to send to the target. The request is either an instance of a class that is a subclass of Message class or of IRISObject class.
If the target is a build-in ObjectScript component, you should use the IRISObject class. The IRISObject class enables the PEX framework to convert the message to a class supported by the target.
- **timeout**: an optional integer that specifies the number of seconds to wait before treating the send request as a failure. The default value is -1, which means wait forever.
description: an optional string parameter that sets a description property in the message header. The default is None.
**Returns**:
the response object from target.
**Raises**:
TypeError: if request is not of type Message or IRISObject.
`send_request_async`: Send the specified message to the target business process or business operation asynchronously.
**Parameters**:
- **target**: a string that specifies the name of the business process or operation to receive the request.
The target is the name of the component as specified in the Item Name property in the production definition, not the class name of the component.
- **request**: specifies the message to send to the target. The request is an instance of IRISObject or of a subclass of Message.
If the target is a built-in ObjectScript component, you should use the IRISObject class. The IRISObject class enables the PEX framework to convert the message to a class supported by the target.
- **description**: an optional string parameter that sets a description property in the message header. The default is None.
**Raises**:
TypeError: if request is not of type Message or IRISObject.
`get_adapter_type`: Name of the registred Adapter.
## 7.4. The `inbound_adapter` class
Inbound Adapter in Python are subclass from grongier.pex.InboundAdapter in Python, that inherit from all the functions of the [common class](#72-the-common-class).
This class is responsible for receiving the data from the external system, validating the data, and sending it to the business service by calling the BusinessHost process_input method.
This class defines:
`on_task`: Called by the production framework at intervals determined by the business service CallInterval property.
The message can have any structure agreed upon by the inbound adapter and the business service.
Example of an inbound adapter ( situated in the src/python/demo/reddit/adapter.py file ):
```python
from grongier.pex import InboundAdapter
import requests
import iris
import json
class RedditInboundAdapter(InboundAdapter):
"""
This adapter use requests to fetch self.limit posts as data from the reddit
API before calling process_input for each post.
"""
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
# HTTP Request
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
```
## 7.5. The `outbound_adapter` class
Outbound Adapter in Python are subclass from grongier.pex.OutboundAdapter in Python, that inherit from all the functions of the [common class](#72-the-common-class).
This class is responsible for sending the data to the external system.
The Outbound Adapter gives the Operation the possibility to have a heartbeat notion.
To activate this option, the CallInterval parameter of the adapter must be strictly greater than 0.
Example of an outbound adapter ( situated in the src/python/demo/reddit/adapter.py file ):
```python
class TestHeartBeat(OutboundAdapter):
def on_keepalive(self):
self.log_info('beep')
def on_task(self):
self.log_info('on_task')
```
## 7.6. The `business_service` class
This class is responsible for receiving the data from external system and sending it to business processes or business operations in the production.
The business service can use an adapter to access the external system, which is specified overriding the get_adapter_type method.
There are three ways of implementing a business service:
- Polling business service with an adapter - The production framework at regular intervals calls the adapter’s OnTask() method,
which sends the incoming data to the the business service ProcessInput() method, which, in turn calls the OnProcessInput method with your code.
- Polling business service that uses the default adapter - In this case, the framework calls the default adapter's OnTask method with no data.
The OnProcessInput() method then performs the role of the adapter and is responsible for accessing the external system and receiving the data.
- Nonpolling business service - The production framework does not initiate the business service. Instead custom code in either a long-running process
or one that is started at regular intervals initiates the business service by calling the Director.CreateBusinessService() method.
Business service in Python are subclass from grongier.pex.BusinessService in Python, that inherit from all the functions of the [business host](#73-the-business_host-class).
This class defines:
`on_process_input`: Receives the message from the inbond adapter via the PRocessInput method and is responsible for forwarding it to target business processes or operations.
If the business service does not specify an adapter, then the default adapter calls this method with no message and the business service is responsible for receiving the data from the external system and validating it.
**Parameters**:
- **message_input**: an instance of IRISObject or subclass of Message containing the data that the inbound adapter passes in.
The message can have any structure agreed upon by the inbound adapter and the business service.
Example of a business service ( situated in the src/python/demo/reddit/bs.py file ):
```python
from grongier.pex import BusinessService
import iris
from message import PostMessage
from obj import PostClass
class RedditServiceWithPexAdapter(BusinessService):
"""
This service use our python Python.RedditInboundAdapter to receive post
from reddit and call the FilterPostRoutingRule process.
"""
def get_adapter_type():
"""
Name of the registred Adapter
"""
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
```
## 7.7. The `business_process` class
Typically contains most of the logic in a production.
A business process can receive messages from a business service, another business process, or a business operation.
It can modify the message, convert it to a different format, or route it based on the message contents.
The business process can route a message to a business operation or another business process.
Business processes in Python are subclass from grongier.pex.BusinessProcess in Python, that inherit from all the functions of the [business host](#73-the-business_host-class).
This class defines:
`on_request`: Handles requests sent to the business process. A production calls this method whenever an initial request for a specific business process arrives on the appropriate queue and is assigned a job in which to execute.
**Parameters**:
- **request**: An instance of IRISObject or subclass of Message that contains the request message sent to the business process.
**Returns**:
An instance of IRISObject or subclass of Message that contains the response message that this business process can return
to the production component that sent the initial message.
`on_response`: Handles responses sent to the business process in response to messages that it sent to the target.
A production calls this method whenever a response for a specific business process arrives on the appropriate queue and is assigned a job in which to execute.
Typically this is a response to an asynchronous request made by the business process where the responseRequired parameter has a true value.
**Parameters**:
- **request**: An instance of IRISObject or subclass of Message that contains the initial request message sent to the business process.
- **response**: An instance of IRISObject or subclass of Message that contains the response message that this business process can return to the production component that sent the initial message.
- **callRequest**: An instance of IRISObject or subclass of Message that contains the request that the business process sent to its target.
- **callResponse**: An instance of IRISObject or subclass of Message that contains the incoming response.
- **completionKey**: A string that contains the completionKey specified in the completionKey parameter of the outgoing SendAsync() method.
**Returns**:
An instance of IRISObject or subclass of Message that contains the response message that this business process can return
to the production component that sent the initial message.
`on_complete`: Called after the business process has received and handled all responses to requests it has sent to targets.
**Parameters**:
- **request**: An instance of IRISObject or subclass of Message that contains the initial request message sent to the business process.
- **response**: An instance of IRISObject or subclass of Message that contains the response message that this business process can return to the production component that sent the initial message.
**Returns**:
An instance of IRISObject or subclass of Message that contains the response message that this business process can return to the production component that sent the initial message.
Example of a business process ( situated in the src/python/demo/reddit/bp.py file ):
```python
from grongier.pex import BusinessProcess
from message import PostMessage
from obj import PostClass
class FilterPostRoutingRule(BusinessProcess):
"""
This process receive a PostMessage containing a reddit post.
It then understand if the post is about a dog or a cat or nothing and
fill the right infomation inside the PostMessage before sending it to
the FileOperation operation.
"""
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
```
## 7.8. The `business_operation` class
This class is responsible for sending the data to an external system or a local system such as an iris database.
The business operation can optionally use an adapter to handle the outgoing message which is specified overriding the get_adapter_type method.
If the business operation has an adapter, it uses the adapter to send the message to the external system.
The adapter can either be a PEX adapter, an ObjectScript adapter or a [python adapter](#75-the-outbound_adapter-class).
Business operation in Python are subclass from grongier.pex.BusinessOperation in Python, that inherit from all the functions of the [business host](#73-the-business_host-class).
### 7.8.1. The dispacth system
In a business operation it is possbile to create any number of function [similar to the on_message method](#782-the-methods) that will take as argument a [typed request](#711-the-messages) like this `my_special_message_method(self,request: MySpecialMessage)`.
The dispatch system will automatically analyze any request arriving to the operation and dispacth the requests depending of their type. If the type of the request is not recognized or is not specified in any **on_message like function**, the dispatch system will send it to the `on_message` function.
### 7.8.2. The methods
This class defines:
`on_message`: Called when the business operation receives a message from another production component [that can not be dispatched to another function](#781-the-dispacth-system).
Typically, the operation will either send the message to the external system or forward it to a business process or another business operation.
If the operation has an adapter, it uses the Adapter.invoke() method to call the method on the adapter that sends the message to the external system.
If the operation is forwarding the message to another production component, it uses the SendRequestAsync() or the SendRequestSync() method.
**Parameters**:
- **request**: An instance of either a subclass of Message or of IRISObject containing the incoming message for the business operation.
**Returns**:
The response object
Example of a business operation ( situated in the src/python/demo/reddit/bo.py file ):
```python
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):
"""
This operation receive a PostMessage and send an email with all the
important information to the concerned company ( dog or cat company )
"""
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")
```
If this operation is called using a MyRequest message, the my_message function will be called thanks to the dispatcher, otherwise the on_message function will be called.
## 7.9. The `director` class
The Director class is used for nonpolling business services, that is, business services which are not automatically called by the production framework (through the inbound adapter) at the call interval.
Instead these business services are created by a custom application by calling the Director.create_business_service() method.
This class defines:
`create_business_service`: The create_business_service() method initiates the specified business service.
**Parameters**:
- **connection**: an IRISConnection object that specifies the connection to an IRIS instance for Java.
- **target**: a string that specifies the name of the business service in the production definition.
**Returns**:
an object that contains an instance of IRISBusinessService
`start_production`: The start_production() method starts the production.
**Parameters**:
- **production_name**: a string that specifies the name of the production to start.
`stop_production`: The stop_production() method stops the production.
**Parameters**:
- **production_name**: a string that specifies the name of the production to stop.
`restart_production`: The restart_production() method restarts the production.
**Parameters**:
- **production_name**: a string that specifies the name of the production to restart.
`list_productions`: The list_productions() method returns a dictionary of the names of the productions that are currently running.
## 7.10. The `objects`
We will use `dataclass` to hold information in our [messages](#711-the-messages) in a `obj.py` file.
Example of an object ( situated in the src/python/demo/reddit/obj.py file ):
```python
from dataclasses import dataclass
@dataclass
class PostClass:
title: str
selftext : str
author: str
url: str
created_utc: float = None
original_json: str = None
```
## 7.11. The `messages`
The messages will contain one or more [objects](#710-the-objects), located in the `obj.py` file.
Messages, requests and responses all inherit from the `grongier.pex.Message` class.
These messages will allow us to transfer information between any business service/process/operation.
Example of a message ( situated in the src/python/demo/reddit/message.py file ):
```python
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
```
WIP It is to be noted that it is needed to use types when you define an object or a message.
## 7.12. How to regsiter a component
You can register a component to iris in many way :
* Only one component with `register_component`
* All the component in a file with `register_file`
* All the component in a folder with `register_folder`
### 7.12.1. register_component
Start an embedded python shell :
```sh
/usr/irissys/bin/irispython
```
Then use this class method to add a new py file to the component list for interoperability.
```python
from grongier.pex import Utils
Utils.register_component(,,,,)
```
e.g :
```python
from grongier.pex import Utils
Utils.register_component("MyCombinedBusinessOperation","MyCombinedBusinessOperation","/irisdev/app/src/python/demo/",1,"PEX.MyCombinedBusinessOperation")
```
### 7.12.2. register_file
Start an embedded python shell :
```sh
/usr/irissys/bin/irispython
```
Then use this class method to add a new py file to the component list for interoperability.
```python
from grongier.pex import Utils
Utils.register_file(,,)
```
e.g :
```python
from grongier.pex import Utils
Utils.register_file("/irisdev/app/src/python/demo/bo.py",1,"PEX")
```
### 7.12.3. register_folder
Start an embedded python shell :
```sh
/usr/irissys/bin/irispython
```
Then use this class method to add a new py file to the component list for interoperability.
```python
from grongier.pex import Utils
Utils.register_folder(,,)
```
e.g :
```python
from grongier.pex import Utils
Utils.register_folder("/irisdev/app/src/python/demo/",1,"PEX")
```
### 7.12.4. migrate
Start an embedded python shell :
```sh
/usr/irissys/bin/irispython
```
Then use this static method to migrate the settings file to the iris framework.
```python
from grongier.pex import Utils
Utils.migrate()
```
#### 7.12.4.1. setting.py file
This file is used to store the settings of the interoperability components.
It has two sections :
* `CLASSES` : This section is used to store the classes of the interoperability components.
* `PRODUCTIONS` : This section is used to store the productions of the interoperability components.
e.g :
```python
import bp
from bo import *
from bs import *
CLASSES = {
'Python.RedditService': RedditService,
'Python.FilterPostRoutingRule': bp.FilterPostRoutingRule,
'Python.FileOperation': FileOperation,
'Python.FileOperationWithIrisAdapter': FileOperationWithIrisAdapter,
}
PRODUCTIONS = [
{
'dc.Python.Production': {
"@Name": "dc.Demo.Production",
"@TestingEnabled": "true",
"@LogGeneralTraceEvents": "false",
"Description": "",
"ActorPoolSize": "2",
"Item": [
{
"@Name": "Python.FileOperation",
"@Category": "",
"@ClassName": "Python.FileOperation",
"@PoolSize": "1",
"@Enabled": "true",
"@Foreground": "false",
"@Comment": "",
"@LogTraceEvents": "true",
"@Schedule": "",
"Setting": {
"@Target": "Host",
"@Name": "%settings",
"#text": "path=/tmp"
}
},
{
"@Name": "Python.RedditService",
"@Category": "",
"@ClassName": "Python.RedditService",
"@PoolSize": "1",
"@Enabled": "true",
"@Foreground": "false",
"@Comment": "",
"@LogTraceEvents": "false",
"@Schedule": "",
"Setting": [
{
"@Target": "Host",
"@Name": "%settings",
"#text": "limit=10\nother
Article
Yuri Marx Pereira Gomes · Jan 12, 2022
The JSON is a data document free of types and validation rules. However, in some scenarios it is important that the JSON document has type and business rules validation, especially in interoperability scenarios. This article demonstrates how you can leverage a market-defined JSONSchema technology that is open for everyone to use and do advanced validations.
About JSON
According to json.org, “JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language”. (Source: https://www.json.org/json-en.html). An example of a JSON document could be:
About JSON Schema
According to json-schema.org, “JSON Schema is a vocabulary that allows you to annotate and validate JSON documents.”.If JSON is easy for humans to read, write and understand, why do we need to apply a schema to validate JSON documents/content? The main reasons are:
To define a clear contract to interoperate JSON based data between partners and their applications.
To detail, document and describe your JSON files, making it easier to use.
To validate JSON data for automated testing, ensuring the quality of the requests and responses.
To generate JSON sample and/or real data from the JSON Schema.
To apply business/validation rules into JSON content, instead of creating language dependent validations.
To support the “contract first approach” on the development of REST API. More details on https://swagger.io/blog/api-design/design-first-or-code-first-api-development/.
JSON Syntax
To understand the role of JSON Schema in a JSON game, it is necessary to know more about JSON syntax. The JSON syntax is derived from JavaScript object notation syntax, so, the syntax rules are equal to JavaScript objects. The JSON rules are next (source: https://www.w3schools.com/js/js_json_syntax.asp):
Data must be specified in name/value pairs.
Data must be separated by commas.
Curly braces hold objects.
Square brackets hold arrays.
The JSON Data consists of a name/value pair with a field name (in double quotes), followed by a colon and followed by a value. Example:
JSON names require double quotes and refers to JavaScript objects and to InterSystems IRIS ObjectScript Dynamic Object (%Library.DynamicObject) too. More details in https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=GJSON_intro#GJSON_intro_methods.
In JSON, values must be one of the following data types:
A string, must be between “”. Sample: “a string”.
A number, must be integer or decimal values. Sample: 10 or 20.23.
An object, must be between {}. Sample: {“firstName”: “John”}.
An array, must be between []. Sample: [{“firstName: “John”},{“firstName”: “Anna”}].
A Boolean, must be true or false. Sample: {“isDead”: false}.
A null, to set no value.
When you apply a JSON document to a language object, these syntax rules are validated, but sometimes, it is necessary to establish business rules too. JSON Schema is used for this, to expand JSON basic rules with rules specified in JSON Schema documents.The InterSystems IRIS has full support for JSON basic rules, and JSON content is very elegant to read or write.. It is easier than any other programming language, see a sample:
InterSystems IRIS Object Script writing JSON
Java writing JSON
set dynObject1 = ##class(%DynamicObject).%New()set dynObject1.SomeNumber = 42set dynObject1.SomeString = "a string"set dynObject1.SomeArray = ##class(%DynamicArray).%New()set dynObject1.SomeArray."0" = "an array element"set dynObject1.SomeArray."1" = 123dynObject1.%ToJSON()
//First EmployeeJSONObject employeeDetails = new JSONObject();employeeDetails.put("firstName","Lokesh");employeeDetails.put("lastName", "Gupta");employeeDetails.put("website","howtodoinjava.com");JSONObject employeeObject = new JSONObject(); employeeObject.put("employee", employeeDetails);
//Second EmployeeJSONObject employeeDetails2 = new JSONObject();employeeDetails2.put("firstName", "Brian");employeeDetails2.put("lastName", "Schultz");employeeDetails2.put("website", "example.com");
JSONObject employeeObject2 = new JSONObject(); employeeObject2.put("employee", employeeDetails2);
//Add employees to listJSONArray employeeList = new JSONArray();employeeList.add(employeeObject);employeeList.add(employeeObject2);employeeList.toJSONString();
While ObjectScript is a dynamic language, allowing setting JSON properties as object properties, other languages, like Java, force you to set key and values inside objects. On the other hand, Java and other languages support JSON Schema using open source and commercial packages, but the ObjectScript does not support JSON Schema at the moment. See the list from json-schema.org (source: https://json-schema.org/implementations.html):
NET
Json.NET Schema 2019-09, draft-07, -06, -04, -03 (AGPL-3.0-only)
JsonSchema.Net 2020-12, 2019-09, draft-07, -06 (MIT)
C++
f5-json-schema draft-07 (Boost Software License 1.0)
JSON schema validator for JSON for Modern C++ draft-07 (MIT)
Valijson draft-07 header-only library, works with many JSON parser implementations (BSD-2-Clause)
Jsoncons draft-07 header-only library (Boost Software License 1.0)
Java
Snow 2019-09, draft-07, -06 Uses Maven for the project and Gson under the hood. (GNU Affero General Public License v3.0)
Vert.x Json Schema 2019-09, draft-07 includes custom keywords support, custom dialect support, asynchronous validation (Apache License, Version 2.0)
Everit-org/json-schema draft-07, -06, -04 (Apache License 2.0)
Justify draft-07, -06, -04 (Apache License 2.0)
Networknt/json-schema-validator draft-07, -06, -04 Support OpenAPI 3.0 with Jackson parser (Apache License 2.0)
Jsonschemafriend 2019-09, draft-07, -06, -04, -03 (Apache License 2.0)
JavaScript
Ajv 2019-09, 2020-12, draft-07, -06, -04 for Node.js and browsers - supports user-defined keywords and $data reference (MIT)
Djv draft-06, -04 for Node.js and browsers (MIT)
Hyperjump JSV 2019-09, 2020-12, draft-07, -06, -04 Built for Node.js and browsers. Includes support for custom vocabularies. (MIT)
Vue-vuelidate-jsonschema draft-06 (MIT)
@cfworker/json-schema 2019-09, draft-07, -06, -04 Built for Cloudflare workers, browsers, and Node.js (MIT)
Python
jschon 2019-09, 2020-12 (MIT)
jsonschema 2019-09, 2020-12, draft-07, -06, -04, -03 (MIT)
fastjsonschema draft-07, -06, -04 Great performance thanks to code generation. (BSD-3-Clause)
jsonschema-rs draft-07, -06, -04 Python bindings to Rust’s jsonschema crate (MIT)
This is a sample how to use JSON schema to validate JSON content (using Python, source: https://jschon.readthedocs.io/en/latest/):
Fortunately, IRIS allows you to create packages or frameworks using the programming language of your choice (.NET or Java using PEX or Language Server). So, it is possible to create an IRIS extension package to handle JSON Schema in IRIS. Another possibility is to use Embedded Python and create a JSON validation method class (in the version 2021.2+).
Extending the InterSystems IRIS to support JSON Schema using Java Language Server (Java Gateway)
Among Java frameworks, the networknt/json-schema-validator is used the most to validate JSON using JSON Schema.To use this Java framework, you can get the application https://openexchange.intersystems.com/package/IRIS-JSON-Schema-Validator. This application has the following files and folders:
1. The folder jgw has the necessary files to create a Java Gateway (bridge to allow communication between Java and IRIS classes);
2. The iris-json-schema-1.0.0.jar has the Java classes and libraries (including json-schema-validator) to service JSON Schema validations;
3. The JSONSchemaValidator.cls has the ObjectScript code to use the Java class and do JSON validations using JSON schema by the validation rules;
4. The Dockerfile and docker-compose.yml run the Java Gateway and the IRIS as docker instances.
The Java Class has a validation method, which uses the framework json-schema-validator to validate the JSON Schema and the JSON, and to return the validation results. See the Java Code:
Java Class for JSON Schema Validation
package dc.irisjsonschema;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Set;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.networknt.schema.JsonSchema;
import com.networknt.schema.JsonSchemaFactory;
import com.networknt.schema.SpecVersion;
import com.networknt.schema.ValidationMessage;
public class JSONSchemaService {
public String validate(String jsonSchemaContent, String jsonContent) {
// create instance of the ObjectMapper class
ObjectMapper objectMapper = new ObjectMapper();
// create an instance of the JsonSchemaFactory using version flag
JsonSchemaFactory schemaFactory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V201909);
try {
// read data from the stream and store it into JsonNode
JsonNode json = objectMapper.readTree(jsonContent);
// get schema from the schemaStream and store it into JsonSchema
JsonSchema schema = schemaFactory.getSchema(jsonSchemaContent);
// create set of validation message and store result in it
Set<ValidationMessage> validationResult = schema.validate(json);
if(validationResult.isEmpty()) {
return "{\"message\": \"JSON is valid\", \"valid\":true}";
} else {
return "{\"message\": \"" +
validationResult.toString() + "\", \"valid\":false}";
}
} catch (JsonProcessingException e) {
return e.getMessage();
}
}
}
The InterSystems IRIS uses this Java validation method to validate JSON content. To do that it is necessary to create a JAR file with the validate class inside (iris-json-schema-1.0.0.jar) and to configure a Java Gateway (bridge between Java and IRIS communication), allowing ObjectScript to call the Java methods.The ObjectScript code which uses the Java Class and the JSONSchemaValidator class is presented here:
Final Java Class read to Validate JSON inside IRIS
/// Validate JSON documents using JSON Schema documents
Class dc.irisjsonschema.JSONSchemaValidator
{
/// Get json and json schema em return validation results
ClassMethod Validate(JSONSchemaContent As %String, JSONContent As %String, Output ValidationResult As %String) As %Status
{
Set sc = $$$OK
// Connect a Gateway instance to server JavaGateway on the host machine
set GW = ##class(%Net.Remote.Gateway).%New()
set st = GW.%Connect("jgw", "55555", "IRISAPP",,)
//instantiate java class
set JSONSchemaValidator = ##class(%Net.Remote.Object).%New(GW,"dc.irisjsonschema.JSONSchemaService")
//validate the JSON using a JSON Schema
set ValidationResult = JSONSchemaValidator.validate(JSONSchemaContent, JSONContent)
Write ValidationResult
Return sc
}
With this ObjectScript class and the Validate class method, it is possible to use any JSON content and any JSON Schema definition to validate basic and advanced validation rules.To see this, execute these steps:
1. Go to https://openexchange.intersystems.com/package/IRIS-JSON-Schema-Validator
2. Git-clone the repository into any local directory
$ git clone https://github.com/yurimarx/iris-json-schema.git
3. Open the terminal in this directory and run it:
$ docker-compose build
4. Run the IRIS container with your project:
$ docker-compose up
5. Go to the IRIS terminal (open a new VSCode Terminal)
docker exec -it iris-json-schema_iris_1 bash iris session iris
6. Change to the IRISAPP namespace
set $namespace = "IRISAPP"
7. Get a sample JSON Schema
set jsonSchema = ##class(dc.irisjsonschema.JSONSchemaValidator).GetJSONSchema()
8. Get a sample valid JSON
set jsonContent = ##class(dc.irisjsonschema.JSONSchemaValidator).GetValidSampleJSON()
9. Get a validation equals to valid
set st = ##class(dc.irisjsonschema.JSONSchemaValidator).Validate(jsonSchema,jsonContent,.result)
write result
10. Now, get a sample INVALID JSON
set jsonContent = ##class(dc.irisjsonschema.JSONSchemaValidator).GetInvalidSampleJSON()
11. After that, get validation equals to INVALID
set st = ##class(dc.irisjsonschema.JSONSchemaValidator).Validate(jsonSchema,jsonContent,.result)
write result
12. The JSON Schema used was:
JSON Schema used to define the validation rules
{ "$schema": "https://json-schema.org/draft/2019-09/schema#", "type": "object", "title": "Movie art", "description": "Information about actors", "additionalProperties": true, "required": [ "name", "artist", "description", "tags" ], "properties": { "name": { "type": "string", "description": "Painting name" }, "artist": { "type": "string", "maxLength": 50, "description": "Name of the artist" }, "description": { "type": [ "string", "null" ], "description": "Painting description" }, "tags": { "type": "array", "items": { "$ref": "#/$defs/tag" } } }, "$defs": { "tag": { "type": "string", "enum": [ "action", "suspense", "UK", "famous", "license", "kill" ] } }}
This JSON Schema configured the fields and the tags array with limited values (enum) as required.
The types of the JSON fields are defined too. So, for this schema the following JSON Object is valid:
set obj = {}set obj.name = "Agent 007"set obj.artist = "Pierce Brosman"set obj.description = "007 actor"set tags = ["license","kill"]set obj.tags = tags
All properties use the right data type and the tags use values inside values allowed in the Schema for this array. Now, see a JSON Object invalid:
set obj = {}set obj.name = "Agent 007"set obj.artist = "Pierce Brosman"set obj.description = 1set tags = []set tags."0" = "license" set tags."1" = "love"set obj.tags = tags
This object sets an integer property to a description (the valid type is string) and sets the value “love”, out of valid values allowed to array tags.The site https://json-schema.org/ has tools, samples and learning resources to learn on how to validate and write advanced validation rules using JSON Schema.
Announcement
Evgeny Shvarov · Jan 12, 2022
Hi contestants!
We've introduced a set of bonuses for the projects for the Datasets Contest!
Here are the projects that scored it:
Project
Demo Repo
LOAD DATA
Questionnaire
Unique Real Dataset
Docker
ZPM
Online Demo
Code Quality
First Article on DC
Second Article on DC
Video on YouTube
Total Bonus
Nominal
4
3
2
4
2
3
2
1
2
1
3
27
Medical Datasets
3
2
2
3
2
1
2
1
3
19
Dataset OEX reviews
2
2
3
1
2
10
Dataset Lightweight M:N
2
2
3
1
2
10
openflights_dataset
3
2
2
1
2
1
11
iris-kaggle-socrata-generator
2
2
3
1
2
1
3
14
dataset-covid19-fake-news
3
2
2
-
1
8
Health Dataset
4
2
2
3
1
2
1
3
18
exchange-rate-cbrf
4
3
2
2
3
2
1
2
1
20
iris-python-faker
2
2
3
2
1
2
12
ApacheLog-Dataset
4
3
2
2
3
2
1
2
1
3
23
dataset-finance
4
3
2
2
3
2
1
2
1
3
23
Please apply with your comments here in the posts or in Discord. I claim youtube bonus (the video is linked with app already) for the app Health Dataset Hi Mr. EvgenyThanks for sharing the Bonuses Results.Please note that online demo is available now for Medical Datasets application.
Regards
I claim bonus second article: https://community.intersystems.com/post/predict-maternal-health-risks
and bonus to app repo: https://openexchange.intersystems.com/package/Predict-Maternal-Risk I claim online demo bonus, my online app is hosted into http://ymservices.tech:52773/csp/sys/UtilHome.csp But this is Management Portal, right? Where is the demo? Hi Community!
We decided to change the results for the Online Demo bonus category.The main reason is that the online server with the dataset hosted on it is not a sufficient demonstration.
Please re-read the bonuses descriptions post to find out about the additions to the Usage Demo and Online Demo categories. And read contest chat in Discord. I set up an online [demo.]( https://cbrf.demo.community.intersystems.com/apptoolsrest/a/rate&class=a...)
And mentioned it in the [readme.](https://github.com/SergeyMi37/exchange-rate-cbrf)
First Article on DC [published](https://community.intersystems.com/post/database-exchange-rates-central-bank-russian-federation) Hi!. EvgenyI posted Second Article on DC:https://community.intersystems.com/post/exchange-rate-cbrf-ui-project-demonstration-application-exchange-rate-database-contest Hi!. Evgeny
I Added example LOAD DATA
And mentioned it in the readme.
Announcement
Anastasia Dyubaylo · Jan 26, 2022
Hey Community,
We invite you to join the next French stream on InterSystems Technologies #8, hosted by @Guillaume.Rongier7183!
Date & Time: February 3rd, 12:00 Paris time.
👉 Direct link to join: https://youtu.be/2PFgnuF8bO8
On the agenda this month:
🗞 News
What's new in InterSystems IRIS 2021.2
https://community.intersystems.com/post/email-templating-csp
https://community.intersystems.com/post/intersystems-iris-and-iris-health-20212-published
https://community.intersystems.com/post/intersystems-iris-20212-python-examples-embedded-native-apis-and-notebooks
https://community.intersystems.com/post/intersystems-evaluation-service
https://wrc.intersystems.com/wrc/coDistEvaluation.csp
💡 Did you know?
How to create a SQL connector without code?
https://docs.intersystems.com/irisforhealth20212/csp/docbook/DocBook.UI.Page.cls?KEY=HXIHRN_new#HXIHRN_new_sqladapters
🗂 Focus on
A new demo on python but on the interoperability framework side
Interoperability Embedded Python
👨💻 Let’s talk with @Benjamin.DeBoe, Product Manager, SQL et Analytics.
New SQL Loader command & features in the analysis of relational tables.
https://docs.intersystems.com/irisforhealth20212/csp/docbook/DocBook.UI.Page.cls?KEY=RSQL_loaddata
https://community.intersystems.com/post/20212-sql-feature-spotlight-run-time-plan-choice
https://community.intersystems.com/post/20212-sql-feature-spotlight-smart-sampling-automation-table-statistics
https://community.intersystems.com/post/20212-sql-feature-spotlight-advanced-table-statistics
Don’t miss the French stream #8 👉 https://youtu.be/2PFgnuF8bO8
Enjoy watching the prev streams on YouTube:
Stream #1
Stream #2
Stream #3
Stream #4
Stream #5
Stream #6
Stream #7
Stay tuned!
Announcement
Anastasia Dyubaylo · Feb 3, 2022
Hey Developers,
It's time to announce the Top Contributors of the InterSystems Developer Community for 2021!🎉
We are pleased to reward the most active contributors across all regional DC sites (EN, ES, PT, JP, CHN):
Top Authors
Top Experts
Top Opinion Makers
Let's take a closer look at the DC Wall of Fame 2021 and greet everyone with big applause! 👏🏼
Badge's Name
Winners
Rules
Nomination: InterSystems Best-Selling Author
1st place: Gold Best-Selling Author 2021
@Yuri.Gomes
1st / 2nd/ 3rd / 4-20th place in "DC Best-Selling Author 2021" nomination.
Given to authors whose articles gathered the maximum amount of views for 2021. Awarded to authors whose articles received the maximum number of views for 2021.
2nd place: Silver Best-Selling Author 2021
@Mihoko.Iijima
@Robert.Cemper1003
3rd place: Bronze Best-Selling Author 2021
@姚.鑫
@Toshihiko.Minamoto
4 - 20th places: Best-Selling Author 2021
@Tani.Frankel @Alberto.Fuentes @Xuying.Zheng @Yunfei.Lei @Hao.Ma @Dmitry.Maslennikov@Evgeny.Shvarov @Henrique.GonçalvesDias@Anton.Umnikov @Megumi.Kakechi @Ricardo.Paiva @Shintaro.Kaminaka @Muhammad.Waseem @Jose-Tomas.Salvador @Nigel.Salm9724
Nomination: InterSystems Expert
1st place: Gold Expert 2021
@Robert.Cemper1003
1st / 2nd / 3rd / 4-20th place in “DC Expert 2021” nomination.
Given to authors, who got the largest number of accepted answers for 2021.
2nd place: SilverExpert 2021
@Dmitry.Maslennikov
@Eduard.Lebedyuk
3rd place: Bronze Expert 2021
@Vic.Sun
@Marc.Mundt
4 - 20th places: DC Expert 2021
@Julius.Kavay@Vitaliy.Serdtsev @Jeffrey.Drumm @Timothy.Leavitt@Julian.Matthews7786 @David.Hockenbroch @Tani.Frankel @Nigel.Salm9724@Evgeny.Shvarov @Lin.Zhu@Yunfei.Lei@David.Reche @Toshihiko.Minamoto @Louis.Lu @Guillaume.Rongier7183
Nomination: InterSystems Opinion Leader
1st place: Gold Opinion Leader 2021
@Anastasia.Dyubaylo
1st / 2nd / 3rd / 4-20th place in “DC Opinion Leader 2021” nomination.
Given to authors whose posts and answers scored the highest number of likes for 2021.
2nd place: Silver Opinion Leader 2021
@Robert.Cemper1003
3rd place: Bronze Opinion Leader 2021
@Yuri.Gomes
4 - 20th places: DC Opinion Leader 2021
@Angelo.Braga5765 @Dmitry.Maslennikov @Evgeny.Shvarov @Eduard.Lebedyuk@Andre.LarsenBarbosa @Nigel.Salm9724 @Olga.Zavrazhnova2637 @Henrique.GonçalvesDias@Henry.HamonPereira @Benjamin.DeBoe@Timothy.Leavitt@MikhailenkoSergey @John.Murray @Muhammad.Waseem @Oliver.Wilms @Benjamin.Spead @Mihoko.Iijima
This list is a good reason to start following some of the great authors of the Developer Community.
BIG APPLAUSE TO OUR WINNERS!
Congratulations to all of you and thank you for your great contribution to the InterSystems Developer Community for 2021!
P.S. Please take part in our annual survey and help us become better:
👉🏼 InterSystems Developer Community Annual Survey 2021 👈🏼 Big THANKS to the whole community for the interest and the trust in my contribution,Not to forget to thank the excellent support team and the fruitful cooperation within the community! I'm very happy to be top author on the best dev community. I love write about intersystems technologies. Many thanks for all. The badges design are very beautiful! Congratulations to everyone for a great 2021!! yeah! our brand new design 🔥 Good job guys.
Article
Yuri Marx Pereira Gomes · Jan 30, 2022
If you need create a upload REST API with IRIS is very simple. Do these procedures:
From Postman client you send a file
P.S.: It is a multipart form with a file type using "file" in the name. The request type is form/multipart. See the http request:
POST /image-analyzer/postFile HTTP/1.1
Host: localhost:52773
Content-Length: 213
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="/C:/Users/yurim/OneDrive/Imagens/salesschema.png"
Content-Type: image/png
(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW
Do a REST API backend to get the file and save (upload):
P.S.: pay attention if the destination folder has write permissions.
Class dc.upload.UploadRESTApp Extends %CSP.REST
{
Parameter CHARSET = "utf-8";
Parameter CONVERTINPUTSTREAM = 1;
Parameter CONTENTTYPE = "application/json";
Parameter Version = "1.0.0";
Parameter HandleCorsRequest = 1;
XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>
<!-- post image -->
<Route Url="/postFile" Method="POST" Call="PostFile" />
</Routes>
}
ClassMethod PostFile() As %Status
{
//try to do the actions
try {
Set info = {}
Set source = %request.GetMimeData("file")
Set destination=##class(%Stream.FileBinary).%New()
Set destination.Filename="/opt/irisbuild/output/"_source.FileName
set tSC=destination.CopyFrom(source) //reader open the file
set result=destination.%Save()
set info.return = result
set info.message = "File saved into /opt/irisbuild/output/"_source.FileName
Set %response.ContentType = ..#CONTENTTYPEJSON
Set %response.Headers("Access-Control-Allow-Origin")="*"
Write info.%ToJSON()
Set tSC=$$$OK
//returns error message to the user
} catch e {
Set tSC=e.AsStatus()
Set pOutput = tSC
}
Quit tSC
}
}
Announcement
Anastasia Dyubaylo · Apr 4, 2022
Hey Developers,
Let the voting week begin! It's time to cast your votes for the best applications in the Globals Contest!
🔥 You decide: VOTE HERE 🔥
How to vote? Details below.
Experts nomination:
InterSystems experienced jury will choose the best apps to nominate the prizes in the Experts Nomination. Please welcome our experts:
⭐️ @Benjamin.DeBoe, Product Manager⭐️ @Alexander.Koblov, Support Specialist⭐️ @Robert.Kuszewski, Product Manager⭐️ @Daniel.Kutac, Senior Sales Engineer⭐️ @Stefan.Wittmann, Product Manager⭐️ @Joel.Solon, Senior Technical Trainer⭐️ @Eduard.Lebedyuk, Sales Engineer⭐️ @Timothy.Leavitt, Development Manager ⭐️ @Steve.Pisani, Senior Solution Architect⭐️ @Evgeny.Shvarov, Developer Ecosystem Manager
Community nomination:
For each user, a higher score is selected from two categories below:
Conditions
Place
1st
2nd
3rd
If you have an article posted on DC and an app uploaded to Open Exchange (OEX)
9
6
3
If you have at least 1 article posted on DC or 1 app uploaded to OEX
6
4
2
If you make any valid contribution to DC (posted a comment/question, etc.)
3
2
1
Level
Place
1st
2nd
3rd
VIP Global Masters level or ISC Product Managers
15
10
5
Ambassador GM level
12
8
4
Expert GM level or DC Moderators
9
6
3
Specialist GM level
6
4
2
Advocate GM level or ISC Employees
3
2
1
Blind vote!
The number of votes for each app will be hidden from everyone. Once a day we will publish the leaderboard in the comments to this post.
The order of projects on the contest page will be as follows: the earlier an application was submitted to the competition, the higher it will be in the list.
P.S. Don't forget to subscribe to this post (click on the bell icon) to be notified of new comments.
To take part in the voting, you need:
Sign in to Open Exchange – DC credentials will work.
Make any valid contribution to the Developer Community – answer or ask questions, write an article, contribute applications on Open Exchange – and you'll be able to vote. Check this post on the options to make helpful contributions to the Developer Community.
If you changed your mind, cancel the choice and give your vote to another application!
Support the application you like!
Note: contest participants are allowed to fix the bugs and make improvements to their applications during the voting week, so don't miss and subscribe to application releases! Since the beginning of the voting we have the results:
Expert Nomination, Top 3
iris-globals-graphDB by @Muhammad Waseem
global-mindmap by @Yuri Marx
Student score query by @yang.shijie
➡️ Voting is here.
Community Nomination, Top 3
iris-globals-graphDB by @Muhammad Waseem
global-mindmap by @Yuri Marx
globals-tool by @Dmitry.Maslennikov
➡️ Voting is here.
So, the voting continues.
Please support the application you like! Here are the results after 2 days of voting:
Expert Nomination, Top 3
global-mindmap by @Yuri.Gomes
iris-globals-graphDB by @Muhammad Waseem
➡️ Voting is here.
Community Nomination, Top 3
global-mindmap by @Yuri Marx
Globals: Embedded Python vs. ObjectScript by @Robert.Cemper1003
globals-tool by @Dmitry Maslennikov
➡️ Voting is here.
Experts we are waiting for your votes!Good luck to everybody! Voting for the InterSystems Globals Contest goes ahead!
And here're the results at the moment:
Expert Nomination, Top 3
iris-globals-graphDB by @Muhammad Waseem
blockchain - [ IRIS python ] by @davimassaru.teixeiramuta
global-mindmap by @Yuri Marx
➡️ Voting is here.
Community Nomination, Top 3
Student score query by @yang.shiji
iris-globals-graphDB by @Muhammad Waseem
Globals: Embedded Python vs. ObjectScript by @Robert.Cemper1003
➡️ Voting is here. What are current results? Developers!
Only 2 days left till the end of the voting period. Please support our participants with your votes!
At the moment we have next results:
Expert Nomination, Top 3
global-mindmap by @Yuri.Gomes
iris-globals-graphDB by @Muhammad Waseem
globals-tool by @Dmitry.Maslennikov
➡️ Voting is here.
Community Nomination, Top 3
globals-tool by @Dmitry.Maslennikov
iris-globals-graphDB by @Muhammad Waseem
Student score query by @yang.shiji
➡️ Voting is here.
And don't forget! You can use your Technology bonuses to gain more points for your application!
Have a nice weekend! Last day of voting! ⌛
Please check out the Contest Board.Our contestants need your votes! 📢 what is the result so far?
Question
Nagarjuna Podapati · Feb 10, 2022
Dear Comminuty,Can you provide learning path recommendations to start on "InterSystems IRIS for Health"? Please check this article of @Yuri.Gomes https://community.intersystems.com/post/learning-path-beginners Thanks Waseem!This content is good enough to start.. Hi @Nagarjuna.Podapati We're building out several learning programs based on roles that will better help in the future here. But the paths exist today! What are you trying to accomplish with IRIS for Health? Based on what you're trying to accomplish, we can recommend a personalized set of learning paths.
That said, if you're going to need to do most things or you're not sure yet, I recommend Getting Started with InterSystems (Health).
Announcement
Anastasia Dyubaylo · Sep 29, 2021
Hey Community,
Get ready for the next French Stream on InterSystems Technologies!
The new monthly event hosted by @Guillaume.Rongier7183 for French-speaking developers familiar with InterSystems technologies will be live stream October 7th at 12:00 Paris time. You will discover all the news and tips related to our solutions!
👉 Direct link to join: https://youtu.be/Rbp-u-3vY-8
On the Agenda:
🗞 News
https://marcusnoble.co.uk/2021-09-01-migrating-from-docker-to-podman/
https://community.intersystems.com/post/scrollable-resulset-pagination-sample
https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme
https://globalmasters.intersystems.com/challenges
https://community.intersystems.com/post/use-systemexternal-interface-python
💡 Did you know?
How to use a debugger on VSCode
🗂 Focus on
InterSystems Analytics demo
👨💻 Let's talk with
@Jacques.Huser, Technical Specialist at InterSystems
Don’t miss the French Stream #5 👉 https://youtu.be/Rbp-u-3vY-8!
Enjoy watching the prev streams on YouTube:
Stream #1
Stream #2
Stream #3
Stream #4
Stay tuned!
Discussion
Yuri Marx Pereira Gomes · Oct 25, 2021
Hi community,
The parquet file format is the evolution of the CSV file format. See the differences when you process data in the AWS using CSV and Parquet:
Do you like to have support to parquet files in the InterSystems IRIS? Can you elaborate on what it would mean to support Parquet? The diagram appears to have come from this post:
https://blog.openbridge.com/how-to-be-a-hero-with-powerful-parquet-google-and-amazon-f2ae0f35ee04
In that context, the query run time refers to acting on the file directly with something like Amazon Athena. Do you have in mind importing the file (which is what an IRIS user would currently do with CSV), or somehow querying the file directly? Support features:
1 - convert parquet file to an objectscript dynamic array and vice versa.
2 - pex business service to get parquet data.
3 - pex business operation to write parquet data. Ok, the below is from my limited knowledge so may need correcting.
The base file format is simple, the complication is the compression methods (which includes encoding) used and making sure that is all supported as it is part of the actual file format specification.
I have issues with some of the speed claims as they seem to stem from statements that the column based, as opposed to row based layout, means it doesn't have to read the whole file but that is pretty limited, as long as you need to look at a single record and the last field then you still have to read through the whole file. It also ignores that for most of the usage I have had of CSV files I have needed to ingest the whole file anyway.
Any other speed improvements are likely due to the code and database ingesting/searching the data not the format itself.
That doesn't mean there aren't advantages. It may be easier to write more efficient code and the built in compression can reduce time and costs.
So the question is how popular is this format. Well it's pretty new and so hasn't made great inroads as yet, however, given Intersystems interest in "Big Data", ML, and it's integration with Spark etc... it does make sense as it is part of Hadoop and Spark.
One thing to note though is that python already supports this through the PyArrow package and so this might be the best solution, simply use embedded python to process the files. Ok, thanks
Announcement
Anastasia Dyubaylo · Jan 10, 2022
Hey Developers,
Let the voting week begin! It's time to cast your votes for the best applications in the Datasets Contest!
🔥 You decide: VOTE HERE 🔥
How to vote? Details below.
Experts nomination:
InterSystems experienced jury will choose the best apps to nominate the prizes in the Experts Nomination. Please welcome our experts:
⭐️ @Benjamin.DeBoe, Product Manager⭐️ @Robert.Kuszewski, Product Manager⭐️ @Raj.Singh5479, Product Manager⭐️ @Carmen.Logue, Product Manager⭐️ @Stefan.Wittmann, Product Manager⭐️ @Thomas.Dyar, Product Manager⭐️ @Eduard.Lebedyuk, Sales Engineer⭐️ @Guillaume.Rongier7183, Sales Engineer⭐️ @Evgeny.Shvarov, Developer Ecosystem Manager
Community nomination:
For each user, a higher score is selected from two categories below:
Conditions
Place
1st
2nd
3rd
If you have an article posted on DC and an app uploaded to Open Exchange (OEX)
9
6
3
If you have at least 1 article posted on DC or 1 app uploaded to OEX
6
4
2
If you make any valid contribution to DC (posted a comment/question, etc.)
3
2
1
Level
Place
1st
2nd
3rd
VIP Global Masters level or ISC Product Managers
15
10
5
Ambassador GM level
12
8
4
Expert GM level or DC Moderators
9
6
3
Specialist GM level
6
4
2
Advocate GM level or ISC Employees
3
2
1
Blind vote!
The number of votes for each app will be hidden from everyone. Once a day we will publish the leaderboard in the comments to this post.
The order of projects on the Contest Page will be as follows: the earlier an application was submitted to the competition, the higher it will be in the list.
P.S. Don't forget to subscribe to this post (click on the bell icon) to be notified of new comments.
To take part in the voting, you need:
Sign in to Open Exchange – DC credentials will work.
Make any valid contribution to the Developer Community – answer or ask questions, write an article, contribute applications on Open Exchange – and you'll be able to vote. Check this post on the options to make helpful contributions to the Developer Community.
If you changed your mind, cancel the choice and give your vote to another application!
Support the application you like!
Note: contest participants are allowed to fix the bugs and make improvements to their applications during the voting week, so don't miss and subscribe to application releases! Developers!
Do not forget, that you can get extra points for your application by using Technology Bonuses!
To earn bonuses, please, complete this quick survey. Since the beginning of the voting we have the results:
Expert Nomination, Top 3
Medical Datasets by @Muhammad.Waseem
Health Dataset by @Yuri.Gomes
ApacheLog-Dataset by @Evgeniy.Potapov
➡️ Voting is here.
Community Nomination, Top 3
Medical Datasets by @Muhammad.Waseem
Health Dataset by @Yuri.Gomes
ApacheLog-Dataset by @Evgeniy.Potapov
➡️ Voting is here.
So, the voting continues.
Please support the application you like! Voting for the Datasets Contest goes ahead!
And here're the results at the moment:
Expert Nomination, Top 3
Medical Datasets by @Muhammad Waseem
Health Dataset by @YURI MARX GOMES
iris-kaggle-socrata-generator by @Henrique.GonçalvesDias
➡️ Voting is here.
Community Nomination, Top 3
Health Dataset by @YURI MARX GOMES
iris-python-faker by @Dmitry.Maslennikov
iris-kaggle-socrata-generator by @Henrique.GonçalvesDias
➡️ Voting is here. Developers!
Only 4 days left till the end of the voting period!
And here are the results:
Expert Nomination, Top 3
Medical Datasets by @Muhammad Waseem
iris-kaggle-socrata-generator by @Henrique Dias
Health Dataset by @YURI MARX GOMES
➡️ Voting is here.
Community Nomination, Top 3
Medical Datasets by @Muhammad Waseem
iris-kaggle-socrata-generator by @Henrique Dias
iris-python-faker by @Dmitry Maslennikov
➡️ Voting is here. Today we have the next results:
Expert Nomination, Top 3
Medical Datasets by @Muhammad Waseem
iris-kaggle-socrata-generator by @Henrique Dias
Health Dataset by @YURI MARX GOMES
➡️ Voting is here.
Community Nomination, Top 3
iris-kaggle-socrata-generator by @Henrique Dias
Medical Datasets by @Muhammad Waseem
Health Dataset by @YURI MARX GOMES
➡️ Voting is here.
Happy weekends! Last day of voting! ⌛
Please check out the Contest Board.Our contestants need your votes! 📢
Announcement
Derek Robinson · Jul 27, 2021
Episode 20 of Data Points features a conversation with Bob Kuszewski about the Kubernetes and the InterSystems Kubernetes Operator (IKO). Take a listen to hear about some of the use cases and features of IKO, plus how it compares to InterSystems Cloud Manager (ICM) within the cloud space.
For all episodes of Data Points and to subscribe on your favorite app, check out https://datapoints.intersystems.com.
Announcement
Marco Alemagna · Jul 28, 2021
An international Company ,whose Headquarter is based in Switzerland, is looking for a Senior InterSystems Developer who will join the new IT center based in Turin.
The Senior developers will design, develop and help the operation of Event Processing Solution based on the IRIS Data Platform. He will work with the global teams (India, USA and Europe) and with external partners/vendors. He/she works in coordination with the in-place Community of Practices to ensure the coherence of the development with the program architecture. The Senior Developer will need to deliver several work packages with local/offshore resources. He/She will play a key role during the release process in coordination with both the development team and the Application operational team.
QUALIFICATION AND EXPERIENCE
Required:
-At least 5 years' experience with InterSystems Technology (IRIS/CACHE) with experience in the following subjects:
- COS (cache object script) & OO (object oriented) development using classes
-SQL (both embedded and dynamic), class queries & SP (stored procedures)
-Proven experience with Interoperability (aka Ensamble) in both design and implement solution in a complex production, experience with use of varius adaptators ( e.g. SQL, REST, HTTP)
If you're interested in receiving more information about the company and the position, please fill free to send your curriculum at the following email address:
marco.alemagna@ellipsis-partners.com
Article
Crys · Aug 12, 2021
Being equipped by science and technology, human being have walked a long way by great inventions such as steam-engines or aeroplannes; while after decades, people gradually recognize that single creation could not lauch an industry-boom again. That is why and when, technologies grow up with a community, where are we now=P. An eco-system of technology would be born with the power of a system and grow up with the power of system-science, such as InterSystems, with which seated the letters "s-y-s-t-e-m". Graduated with M.S. of Information Systems, I've been deeply recognized the power of a system, in which is there the planet of Earth itself.
Inter-discinplines with Computer Science and Health Care need quite a lot considerations. Difficulties are all-over and everywhere, which conducts very few contributor and explorers since it's too hard. Struggling in the dealing with issues in the area of health care by IT-solutions, encountered me the Ensemble. Out of my imagination, brought me it to a great world. The interoperability with consensus on Hl7 launches the IT-ecosystem towards integration. System Science tell-s us the power of Systems Thinking, while the Ensemble show-s us. That was the point where I found a good set of facilities and tools. Later on, together with Ensemble, IRIS and ai- machineLearning are also compatible on CloudComputing. Gradually being clear-er and clearer, the interoperability single "tree" has grown up into a forest/ecosystem like a base-electricity factory supplying electricPower. World is always going too fast to be predicted. For a world built by Cncf- CloudNativeS, the basic infrastruture by interoperability would be the core contributor in supporting a booming technological and scientific world=P.
{p.s. grammer mistakes there or not. fixing and enjoying.} GPT-3 generated? ) i'm telling u: No. keep smiling pls.
Question
Bren Mochocki · Aug 16, 2021
It appears the link to download IRIS is down:https://download.intersystems.com/download/login.csp
Thanks for the heads up @Bren.Mochocki! This is being looked into as we speak. No eta on when it will be restored as of right now.... @Bren.Mochocki , the link worked for me today; downloading is back. Try it again, please, and post back if you still have troubles.
Erik