Wolfram Web Engine for Python

Riccardo Di Virgilio

Wolfram Web Engine for Python

Wolfram Web Engine for Python is an open source library that allows you to develop and publish web applications locally using Wolfram Language.
The library can be used with any Wolfram Kernel, including the free Wolfram Engine for Developers, to create new applications from scratch or to integrate existing Python applications.
In this talk we will see how to create a web application using Wolfram Language only and how to start serving content in an existing python application (Django and Aiohttp).
We will show how to take an existing Wolfram Cloud application and start developing and serving content from a local machine, we will show how with this system you have some of the advantages of Wolfram Enterprise Cloud (ability to run arbitrary binaries using RunProcess, connect to external databases, etc...), and we will show which functions are currently supported (Delayed, APIFunction, FormFunction, URLDispatcher, etc...).

How to get started

Wolfram Web Engine for Python is available for download on github:

To quickly start open a terminal session and do:

> pip install wolframwebengine

WolframClient for Python source code and documentation

How it works

Wolfram Web Engine for Python uses the Python AIOHTTP web server to handle requests for a Wolfram Engine. Web pages are specified on the server with standard Wolfram Language functions such as APIFunction, FormFunction, FormPage, URLDispatcher, AskFunction, HTTPResponse, HTTPRedirect, etc. This allows you to integrate Wolfram Language functionality seamlessly with existing Python web applications like Django and AIOHTTP.

Start the demo program

python3 -m wolframwebengine --demo

Open the browser

Two different ways of structuring an application:

Use a single file with URLDispatcher

Use multiple files in a directory layout

Single file with URLDispatcher:

expr = URLDispatcher[{
    "/api" -> APIFunction["x" -> "String"], 
    "/form" -> FormFunction["x" -> "String"], 
    "/" -> "hello world!"
}];

Write the following content in a file called dispatcher.m :

Export[FileNameJoin[{$HomeDirectory, "Desktop", "dispatcher.m"}], expr]

Multiple files in a directory layout:

Create an application by running the following code in your current location :

$app = FileNameJoin[{$HomeDirectory, "Desktop", "testapp"}]

makeDir[s_] := If[
	! FileExistsQ[s],
	CreateDirectory[s, CreateIntermediateDirectories->True]
]
makeDir[$app];
makeDir[FileNameJoin[{$app, "form"}]];
makeDir[FileNameJoin[{$app, "api"}]];

Scan[
	Export[FileNameJoin[{$app, #Path}], #Expr, #Format] &, {
		<|
			"Path" -> "index.wl",
			"Expr" -> Delayed[{"hello", UnixTime[]}, "JSON"],
			"Format" -> "Package"
		|>,
		<|
			"Path" -> "form/index.wl",
			"Expr" -> FormFunction["x" -> "String"],
			"Format" -> "Package"
		|>,
		<|
			"Path" -> "api/index.wl",
			"Expr" -> APIFunction["x" -> "Number", #x! &],
			"Format" -> "Package"
		|>,
		<|
			"Path" -> "response.wl",
			"Expr" -> HTTPResponse["hello world"],
			"Format" -> "Package"
		|>,
		<|
			"Path" -> "static.json",
			"Expr" -> {"some", "static", "JSON"},
			"Format" -> "JSON"
		|>
	}
]

Open the folder:

$app

SystemOpen[$app]

Integrating an existing application:

Wolfram Web Engine for Python can be used to augment an existing python application instead of creating a new one.

path = ExternalEvaluate["Python", "import wolframwebengine; wolframwebengine.__file__"]

SystemOpen[DirectoryName[path]]

Differences with the Wolfram Cloud

Disadvantages

You need to manage the hardware

you need to manage the deployment

Advantages

On your machine you can run any binary (not a limitation of EPC)

Faster development and bug debugging

Easy to understand and reason with

Microservice architecture

Easy to integrate with an existing service