Pesquisar

Artigo
· Jul. 14 3min de leitura

Hosting a Flask REST API on InterSystems IRIS using WSGI

For my intern project, I am building a Flask REST API backend. My goal is to host it on InterSystems IRIS using the WSGI interface. This is a relatively new approach and is currently only being used in a handful of projects such as AskMe. To help others get started, I decided to write this article to simplify the process.

 

Creating a Basic Flask App

First, let’s create a minimal Flask application. Here is the code:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route('/test')
def test():
    return "Test"
if __name__ == "__main__":
    app.run()

This simple app runs a Flask server with one API endpoint at /test that returns the text “Test.”

 

Let's analyze our code line by line:

from flask import Flask
from flask_cors import CORS
  • We are using Flask as our web framework to build the REST API, so we import Flask .
  • CORS (Cross-Origin Resource Sharing) is imported via flask_cors to allow requests from different domains (important for frontend apps hosted elsewhere to access your API without security errors).
app = Flask(__name__)
CORS(app)
  • We create an instance of the Flask application named app.
  • We then wrap this app with CORS middleware, enabling cross-origin requests by default. Without this, browsers might block API calls from other domains.
@app.route('/test')
def test():
    return "Test"
  • Here we define a route /test using the @app.route decorator. This binds the URL /test to the Python function test().
  • When a user sends an HTTP GET request to /test, Flask will invoke the test() function, which simply returns the string "Test". This serves as a simple API endpoint for testing connectivity.
if __name__ == "__main__":
    app.run()
  • This block checks if the script is being run directly (not imported as a module).
  • If so, it starts Flask’s built-in development server locally on your machine.
  • Note: When deploying on InterSystems IRIS using WSGI, this section is ignored because IRIS manages the server.

 

Configuring the Web App on IRIS

Once your Flask app is ready, the next step is to host it on IRIS by configuring a Web Application with the WSGI option.

  1. Open the IRIS Management Portal for your instance.
  2. Go to System > Security Management > Web Applications or search Web Applications.
  3. Click the Create New Web Application button.
  4. Fill out the form as follows:
    • Name: Give your web app a path, for example: /flaskapp1/api.
    • Description: Add a brief description like My Flask API backend.
    • Enabled: Make sure this checkbox is checked.
  5. Scroll down and check the WSGI (Experimental) option to enable running Python WSGI apps.
  6. Then fill in the WSGI details:
    • Application Name: main (This corresponds to the WSGI callable you want IRIS to use.)
    • Callable Name: app (This matches the Flask application variable name in your code.)
    • WSGI App Directory: Enter the full file path to your main.py file where the Flask app is defined. For example: /path/to/main.py.
    • Debug: Unchecked
  7. Click Save.

 

Here’s what this configuration looks like in the portal:

   

 

 

Testing Your API

After saving, your Flask API should now be available at:

https://base.<your-domain>.com/flaskapp1/api/test or more generally, https://base.<your-domain>.com/<path>/test

 

Open this URL in your browser or test it using Postman or curl. You should see the response:

'Test'

 

What’s Next?

This setup lets you run a Flask REST API hosted directly on IRIS using the WSGI integration. From here, you can expand your API with more endpoints and connect to IRIS data sources to build powerful applications.

Put in the comments what you plan on building with Flask 
😜

Discussão (0)1
Entre ou crie uma conta para continuar
Job
· Jul. 14

MUMPS DTM to InterSystems IRIS Database Conversion Expert

Seeking an experienced troubleshooter to assist with the conversion of a MUMPS DTM to InterSystems IRIS Database. The ideal candidate will have a strong background in database conversion processes within IRIS and expert knowledge of MUMPS DTM Routines and Globals. Your primary responsibility will be to troubleshoot and resolve issues that arise with the IRIS Database and the refactoring of MUMPS routines. If you have experience converting MUMPS DTM and are InterSystems Certified with a problem-solving mindset, we would like to collaborate with you. Contract position for US based residents send email of interest to Medica@outlook.com

Discussão (0)1
Entre ou crie uma conta para continuar
Pergunta
· Jul. 14

Use of FHIRPath.API not returning results as expected

I have been struggling sometime with trying to take a FHIR Bundle Response, extract the "entry.resourceType", extract the MRN and Name from the Patient FHIR Response...

Going through learning.intersystems.com, it suggested that I try using fhirPathAPI to parse and search my response for certain values, however I am not sure my syntax is correct. Using the AI code, it suggested to set my tree = "Bundle.entry.resource.resourceType"

ClassMethod Transform(source As HS.FHIRServer.Interop.Response, target As osuwmc.Epic.FHIR.DataStructures.PatientSearch.Record) As %Status
{
  Set tSC=$$$OK
  set tQuickStream = ##Class(HS.SDA3.QuickStream).%OpenId(source.QuickStreamId)
  set tRawJSON = ##Class(%Library.DynamicObject).%FromJSON(tQuickStream)
  set fhirVersion = $lb("hl7.fhir.r4.core@4.0.1")
  set fhirPathAPI = ##class(HS.FHIRPath.API).getInstance(fhirVersion)
  set tree = fhirPathAPI.parse("Bundle.entry.resource.resourceType")
  do fhirPathAPI.evaluate(tRawJSON, tree, .OUTPUT)
  $$$TRACE("FHIRResponseToPatient Transform: FHIR resource type: "_OUTPUT)
  return tSC
}

however, nothing is returned, but I do see it within the raw JSON that there is an Entry within the Bundle message...

{"resourceType":"Bundle","type":"searchset","total":1,"link":[{"relation":"self","url":"https://xxxxxxxxxxxxxx/fhir-poc/api/FHIR/R4/Patient?identifier=OSUMRN|xxxxxxxxxxx"}],"entry":[{"link":[{"relation":"self","url":"https://ihismufhirnp.osumc.edu/fhir-poc/api/FHIR/R4/Patient/xxxxxxxxxxxxxx"}],"fullUrl":"https://ihismufhirnp.osumc.edu/fhir-poc/api/FHIR/R4/Patient/xxxxxxxxxxxxxx","resource":{"resourceType":"Patient","id":"xxxxxxxxxxxxxx","extension":[{"valueCodeableConcept":{"coding":[{"system":"xxxx","code":"male","display":"male"}]},"url":"http://xxxxxxxxxxxxxx/FHIR/StructureDefinition/extension/legal-sex"},{"valueCodeableConcept":{"coding":[{"system":"urn:oid:1.2.840.114350.1.13.172.3.7.10.698084.130.768080.35144","code":"male","display":"male"}]},"url":"http://xxxxxxxxxxxxxx/FHIR/StructureDefinition/extension/sex-for-clinical-use"},{"extension":[{"valueCoding":{"system":"http://terminology.hl7.org/CodeSystem/v3-NullFlavor","code":"UNK","display":"Unknown"},"url":"ombCategory"},{"valueString":"Unknown","url":"text"}],"url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-race"},{"extension":[{"valueString":"Unknown","url":"text"}],"url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity"},{"valueCode":"248153007","url":"http://hl7.org/fhir/us/core/StructureDefinition/us-core-sex"},{"valueCodeableConcept":{"coding":[{"system":"http://loinc.org","code":"LA29518-0","display":"he/him/his/his/himself"}]},"url":"http://xxxxxxxxxxxxxx/FHIR/StructureDefinition/extension/calculated-pronouns-to-use-for-text"}],"identifier":[{"use":"usual","type":{"text":"CEID"},"system":"urn:oid:1.2.840.114350.1.13.172.3.7.3.688884.100","value":"OSRXRLK0HT3BTSZ"},{"use":"usual","type":{"text":"EPI"},"system":"urn:oid:1.2.840.114350.1.13.172.3.7.5.737384.0","value":"E5187"},{"use":"usual","type":{"text":"EXTERNAL"},"system":"urn:oid:1.2.840.114350.1.13.172.3.7.2.698084","value":"Z5152089"},{"use":"usual","type":{"text":"FHIR"},"system":"http://xxxxxxxxxxxxxx/FHIR/StructureDefinition/patient-dstu2-fhir-id","value":"T2JMC02.7EzU1Fy7Yne0Uo2qv78rgw81tU41q3T2Egc4B"},{"use":"usual","type":{"text":"FHIR STU3"},"system":"http://xxxxxxxxxxxxxx/FHIR/StructureDefinition/patient-fhir-id","value":"xxxxxxxxxxxxxx"},{"use":"usual","type":{"text":"INTERNAL"},"system":"urn:oid:1.2.840.114350.1.13.172.3.7.2.698084","value":"  Z5152089"},{"use":"usual","type":{"text":"OSUMRN"},"system":"urn:oid:1.2.840.114350.1.13.172.2.7.5.737384.100","value":"415013564"}],"active":true,"name":[{"use":"official","text":"xxxxx xxxxxx","family":"xxxxxxxx","given":["xxxxx"]},{"use":"usual","text":"xxxx xcxxxx","family":"xxxxxx","given":["xxxxxx"]}],"gender":"male","birthDate":"1956-04-04","deceasedBoolean":false,"managingOrganization":{"reference":"Organization/e1waNSScbiPHZpqWn-ohD0w3","display":"xxxxxxxxxxx"}},"search":{"mode":"match"}}]}

 

set tree = fhirPathAPI.parse("Bundle.total")

I can get the total number of records returned. 

How do I get the entry level tree, then iterate through identity and name to get the values I need? I seem not to be able to find any examples or clear documentation on how to handle FHIR responses if you are not hosting the repository but getting data from one.

Discussão (0)2
Entre ou crie uma conta para continuar
Anúncio
· Jul. 14

[Video] InterSystems IRIS: Easy to Consume and Easy to Use

Hi Community,

Enjoy the new video on InterSystems Developers YouTube:

⏯  InterSystems IRIS: Easy to Consume and Easy to Use @ Global Summit 2024

Watch this video to learn the company’s vision for IRIS Data Platform and its evolving role in supporting next-generation data architectures. It explores how IRIS is expanding to meet the demands of AI, data fabrics, and real-time analytics, emphasizing scalability, trust, and agility.

🗣 Presenter: Scott Gnau, Vice President, Data Platforms, InterSystems  

Stay ahead of the curve! Watch the video and subscribe to keep learning! 👍

Discussão (0)1
Entre ou crie uma conta para continuar
InterSystems Oficial
· Jul. 14

Advisory for IRISSECURITY in InterSystems IRIS 2025.2

InterSystems IRIS 2025.2 introduces the IRISSECURITY database, the new home for security data. Unlike IRISSYS, the previous home for security data, IRISSECURITY can be encrypted, which secures your sensitive data at rest. In a future version, IRISSECURITY will be mirrorable.

This version also introduces the %SecurityAdministrator role for general security administration tasks. 

The changes described here affect both continuous delivery (CD) and extended maintenance (EM) release tracks. That is, starting with versions 2025.2 (CD, released on 23 July, 2025) and 2026.1 (EM), InterSystems IRIS will include the IRISSECURITY database, and all security data is automatically moved from IRISSYS to IRISSECURITY when you upgrade.

Before You Upgrade 

IRISSECURITY makes several potentially breaking changes to how users interact with security data: 

  • Users can no longer directly access security globals without %All and must instead use the APIs provided by the various security classes.
  • OAuth2 globals can no longer be mapped to a different database.
  • Users can no longer arbitrarily query security tables, even when SQL security is disabled. 
  • System databases now use predefined resources that cannot be changed. On Unix, if you created and assigned a new resource to a system database in a previous version, it will be replaced by the predefined resource when you upgrade (though if any roles reference the non-default resource, they must be changed manually to use the default resource to keep database access). On Windows, you must change the resource back to the default. If you attempt to upgrade on Windows while databases have non-default resources, the upgrade will halt (the instance is not modified) and display an error message "Database must have a resource label of..."

The following sections go into detail about these changes and what you should do instead if you depended on the original behavior, but in general, before you upgrade, you should verify and test that your applications and macros: 

  • Use the provided security APIs to administer security (as opposed to direct global access). 
  • Have the necessary permissions (%DB_IRISSYS:R and Admin_Secure:U) for using those APIs. 

Global Access 

Previously, when security globals were stored in the IRISSYS database, users could access security data with the following privileges: 

  • %DB_IRISSYS:R: Read security globals both directly and through security APIs.
  • %DB_IRISSYS:RW: Read and write security globals. 
  • %DB_IRISSYS:RW and Admin_Secure:U: Administer security through security APIs. 

In InterSystems IRIS 2025.2: 

  • Users can no longer access security globals directly without %All.
  • Both %DB_IRISSYS:R and %Admin_Secure:U are the minimum privileges needed to both access security data (through the provided security APIs) and administer security through the various security classes. 
  • For general security administration, you can use the new %SecurityAdministrator role. 
  • Read-only access to security data (previously available through %DB_IRISSYS:R) has been removed. 

Global Locations

In InterSystems IRIS 2025.2, the following security globals have been moved from IRISSYS to the ^SECURITY global located in IRISSECURITY:

  • ^SYS("SECURITY")
  • ^OAuth2.*
  • ^PKI.*
  • ^SYS.TokenAuthD

The following table lists the most notable globals that have been moved, their security classes, old locations, and new locations:

Security Class Old Location (IRISSYS) New Location (IRISSECURITY)
N/A ^SYS("Security","Version") ^SECURITY("Version")
Security.Applications ^SYS("Security","ApplicationsD") ^SECURITY("ApplicationsD")
Security.DocDBs ^SYS("Security","DocDBsD") ^SECURITY("DocDBsD")
Security.Events ^SYS("Security","EventsD") ^SECURITY("EventsD")
Security.LDAPConfigs ^SYS("Security","LDAPConfigsD") ^SECURITY("LDAPConfigsD")
Security.KMIPServers ^SYS("Security","KMIPServerD") ^SECURITY("KMIPServerD")
Security.Resources ^SYS("Security","ResourcesD") ^SECURITY("ResourcesD")
Security.Roles ^SYS("Security","RolesD") ^SECURITY("RolesD")
Security.Services ^SYS("Security","ServicesD") ^SECURITY("ServicesD")
Security.SSLConfigs ^SYS("Security","SSLConfigsD") ^SECURITY("SSLConfigsD")
Security.System ^SYS("Security","SystemD") ^SECURITY("SystemD")
Security.Users ^SYS("Security","UsersD") ^SECURITY("UsersD")
%SYS.PhoneProviders ^SYS("Security","PhoneProvidersD") ^SECURITY("PhoneProvidersD ")
%SYS.X509Credentials ^SYS("Security","X509CredentialsD") ^SECURITY("X509CredentialsD ")
%SYS.OpenAIM.IdentityServices ^SYS("Security","OpenAIMIdentityServersD") ^SECURITY("OpenAIMIdentityServersD")
OAuth2.AccessToken ^OAuth2. AccessTokenD ^SECURITY("OAuth2.AccessToken ")
OAuth2.Client ^OAuth2.ClientD ^SECURITY("OAuth2.Client")
OAuth2.ServerDefinition ^OAuth2.ServerDefinitionD ^SECURITY("OAuth2.ServerDefinitionD")
OAuth2.Client.MetaData ^OAuth2.Client.MetaDataD ^SECURITY("OAuth2.Client.MetaDataD")
OAuth2.Server.AccessToken ^OAuth2.Server.AccessTokenD ^SECURITY("OAuth2.Server.AccessTokenD")
OAuth2.Server.Client ^OAuth2.Server.ClientD ^SECURITY("OAuth2.Server.ClientD")
OAuth2.Server.Configuration ^OAuth2.Server.ConfigurationD ^SECURITY("OAuth2.Server.ConfigurationD")
OAuth2.Server.JWTid ^OAuth2.Server.JWTidD ^SECURITY("OAuth2.Server.JWTidD")
OAuth2.Server.Metadata ^OAuth2.Server.MetadataD ^SECURITY("OAuth2.Server.MetadataD")
PKI.CAClient ^PKI.CAClientD ^SECURITY("PKI.CAClient")
PKI.CAServer ^PKI.CAServerD ^SECURITY("PKI.CAServer")
PKI.Certificate ^PKI.CertificateD ^SECURITY("PKI.Certificate")
%SYS.TokenAuth ^SYS.TokenAuthD ^SECURITY("TokenAuthD")

OAuth2 Global Mapping

Previously, you could map OAuth2 globals to a different database, which allowed OAuth2 configurations to be mirrored.

In InterSystems IRIS 2025.2, OAuth2 globals can no longer be mapped, and IRISSECURITY cannot be mirrored. If you depended on this behavior for mirroring, you can use any of the following workarounds:

  • Manually make changes to both the primary and failover.
  • Export the settings from the primary and then import them to the failover (requires %ALL).

To export OAuth2 configuration data: 

set items = $name(^|"^^:ds:IRISSECURITY"|SECURITY("OAuth2"))_".gbl"
set filename = "/home/oauth2data.gbl"
do $SYSTEM.OBJ.Export(items,filename)

To import OAuth2 configuration data:

do $SYSTEM.OBJ.Import(filename)

SQL Security 

Previously, SQL security was controlled by the CPF parameter DBMSSecurity. When DBMSSecurity was disabled, users with SQL privileges could arbitrarily query all tables in the database. 

In InterSystems IRIS 2025.2:

  • The DBMSSecurity CPF parameter has been replaced with the system-wide SQL security property. You can set this in several ways:
    • Management Portal: System Administration > Security > System Security > System-wide Security Parameters > Enable SQL security
    • SetOption##class(%SYSTEM.SQL.Util).SetOption("SQLSecurity", "1")
    • Security.System.Modify: ##Class(Security.System).Modify(,.properties), where properties is properties("SQLSecurity")=1
  • Security tables can now only be queried through the Detail and List APIs, which require both %DB_IRISSYS:R and %Admin_Secure:U even when SQL security is disabled. 

For example, to get a list of roles, you can no longer directly query the Security.Roles table. Instead, you should use the Security.Roles_List() query:

SELECT Name, Description FROM Security.Roles_List()

Encrypting IRISSECURITY 

To encrypt IRISSECURITY, use the following procedure: 

  1. Create a new encryption key. Go to System Administration > Encryption > Create New Encryption Key File and specify the following:
    • Key File – The name of the encryption key. 
    • Administrator Name – The name of the administrator. 
    • Password – The password for the key file. 
  2. Activate the encryption key. Go to System Administration > Encryption > Database Encryption and select Activate Key, specifying the Key File, Administrator Name, and Password from step 1. 
  3. Go to System Administration > Encryption > Database Encryption and select Configure Startup Settings.
  4. From the Key Activation at Startup dropdown menu, select a key activation method. InterSystems highly recommends Interactive key activation.
  5. From the Encrypt IRISSECURITY Database dropdown, select Yes.
  6. Restart your system to encrypt IRISSECURITY. 

Percent-class Access Rules 

In previous versions of InterSystems IRIS, the procedure for managing a web application’s access to additional percent classes involved writing to security globals. You can accomplish this in InterSystems IRIS 2025.2 through the Management Portal or the ^SECURITY routine. 

Management Portal 

To create a percent-class access rule with the Management Portal: 

  1. Go to System Administration > Security > Web Applications
  2. Select your web application.
  3. In the Percent Class Access tab, set the following options: 
    • Type: Controls whether the rule applies to the application’s access to just the specified percent class (AllowClass) or all classes that contain the specified prefix (AllowPrefix). 
    • Class name: The percent class or prefix to give the application access to. 
    • Allow access: Whether to give the application access to the specified percent class or package. 
    • Add this same access to ALL applications: Whether to apply the rule for all applications. 

^SECURITY 

To create a class access rule with the ^SECURITY routine:

  1. From the %SYS namespace, run the ^SECURITY routine:
    DO ^SECURITY
  2. Choose options 5, 1, 8, and 1 to enter the class access rule prompt. 
  3. Follow the prompts, specifying the following:
    • Application? – The name of the application. 
    • Allow type? – Whether the rule applies to the application's ability to access a particular class (AllowClass) or all classes that contain the specified prefix (AllowPrefix). 
    • Class or package name? – The class or prefix to give the application access to. 
    • Allow access? – Whether to give the application access to the specified class or package. 
2 Comments
Discussão (2)3
Entre ou crie uma conta para continuar