Ignition - create simple HTTP Server

Hello guys, I am trying to create a simple HTTP Server in Ignition that listen on a port for http requests like GET, POST ecc... and send back a response.
Is there a way to implement this in Python or with external libraries like Flask for example?
I attach the example code

from flask import Flask, jsonify

app = Flask(__name__)

def hello():
    return "Hello, world!"

@app.route('/api/data', methods=['GET'])
def get_data():
    data = {"key": "value"}
    return jsonify(data)

if __name__ == '__main__':

I think you'll achieve this most easily with the WebDev module, that is exactly what it is intended for.

Hello @kcollins1 thanks for your reply. I know there is a dedicated module but for now we can't buy the license for it, so I was thinking about to do this by script if possible

Basically, no. There's no way via scripting to introduce something durable enough that isn't also a massive memory leak.

If you really want to trade engineering time for a solution, you can always develop a custom module that replicates the "load a servlet" part of the Webdev module:

Custom modules can do whatever you want (except on Edge) and are free.

1 Like

What can't they do on Maker?

1 Like

You're right - Maker is just an opt-in flag on the hook. I thought there was some third party module restriction, but the only difference is which first party modules will load.

Thanks @PGriffith thought there was a way to achieve this via script. If I have enough time, I will take your suggestion into consideration

Hi @PGriffith

How big of a memory leak are we really talking about ?

I have an external application that needs to send its data to Ignition every hour via a POST request, I've created a simple HTTP server (code below) that runs in Ignition.

HTTP server code
from com.sun.net.httpserver import HttpServer, HttpHandler, HttpExchange
from java.net import InetSocketAddress
from java.io import IOException
from java.io import InputStreamReader
from java.io import BufferedReader
from java.lang import StringBuilder

# Define a simple HTTP handler
class MyHandler(HttpHandler):
	def handle(self, exchange):
			if exchange.getRequestMethod().upper() == "POST":
				length = exchange.getRequestHeaders().getFirst("Content-length")
				content_length = int(length) if length else 0	
				if content_length > 0:
					input_stream = exchange.getRequestBody()
					isr = InputStreamReader(input_stream, 'utf-8')
					reader = BufferedReader(isr)
					buffer = StringBuilder()
					while True:
						line = reader.readLine()
						if line is None:
					post_data = buffer.toString()
					system.util.getLogger("HTTP_SERVER").info("Received POST data:"+ str(post_data))
					response = "Received POST data: " + post_data
					exchange.sendResponseHeaders(200, len(response))
					outputStream = exchange.getResponseBody()
			if exchange.getRequestMethod().upper() == "GET":
				response = "Hello, World!"
				exchange.sendResponseHeaders(200, len(response))
				outputStream = exchange.getResponseBody()
		except IOException as e:

# Function to start the HTTP server
def start_server():
    server_address = InetSocketAddress(7999)
    http_server = HttpServer.create(server_address, 0)
    http_server.createContext("/", MyHandler())
    http_server.setExecutor(None)  # Use the default executor
    system.util.globals["http_server"] = http_server
    system.util.getLogger("HTTP_SERVER").info("HTTP server started...")
    print("HTTP server started on port 7999")

def init():
	# Run the server
	if "http_server" in system.util.globals and system.util.globals["http_server"] is not None:
		print("server stopped")

def close():
	if "http_server" in system.util.globals and system.util.globals["http_server"] is not None:

What could happen ? If the thread runs for too long, it could take up the whole memory ?
Considering the fact that the application sends its data every hour, would the memory leak be under control if I restart this server say every half an hour or so ?

I have a hard time justifying the use of the WebDev module to my client considering only one client will send its data, and it's only once an hour.


1 Like

We had tried a NODEJS server connected with Ignition in TCP/IP socket thru scripts and clients communicating with NODEJS server thru REST APIs. Please see demo link. Perhaps you can try something like that! Or simply let you application connect to Ignition on TCP/IP socket if its not a web application.

If you're caching any custom class in system.util.globals, you're implicitly storing the entire Jython interpreter state (and all of its associated memory usage, which includes all parsed project script libraries, all parsed third party libraries, etc), for at least as long as that instance is alive.

Your server creation and shutdown code is also racy - multiple threads could be running script initialization at once (because we create and shut down the whole Jython lifecycle all the time, whenever you change any script related resources), so one lifecycle might pass the first if at the same time as another and both end up attempting to create a server (and bind to the same address) at the same time. You should use Python's builtin setdefault to atomically update the dictionary.

If you really can restart the server every hour, then, sure, I guess you're successfully band-aid patching a memory leak. How maintainable is that in six months, in five years, etc?

1 Like

Thanks a lot for your reply, you've convinced myself and the client that the WebDev module would prove much more reliable than this crafty solution of mine, also far from being an expert so thanks for the tips regarding python's setdefault!

WebDev is worth, rather than trying some round about solution to save fraction of Ignition cost's and writing some bug ridden code of our own !

1 Like