Giter VIP home page Giter VIP logo

wolframwebengineforpython's Introduction

Wolfram Web Engine for Python

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.

Getting Started

Prerequisites

  1. Python 3.5 or higher
  2. Wolfram Language 11.3 or higher (Mathematica, Wolfram Desktop, or Wolfram Engine)
  3. WolframClientForPython

Install Using pip (Recommended)

Recommended for most users. It installs the latest stable version released by Wolfram Research.

Evaluate the following command in a terminal:

>>> pip3 install wolframwebengine

Install Using Git

Recommended for developers who want to install the library along with the full source code. Clone the library’s repository:

>>> git clone git://github.com/WolframResearch/WolframWebEngineForPython

Install the library in your site-package directory:

>>> cd WolframWebEngineForPython
>>> pip3 install .

The following method is not installing the library globally, therefore all the example commands needs to run from the cloned directory.

Start a demo server

Start a demo server by doing:

python3 -m wolframwebengine --demo
----------------------------------------------------------------------
Address         http://localhost:18000/
Folder          /Users/rdv/Desktop/wolframengineforpython/wolframwebengine/examples/demoapp
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit) 

Now you can open your web browser at the address http://localhost:18000/

image

Two different ways of structuring an application:

  1. Use a single file with URLDispatcher
  2. Use multiple files in a directory layout

Single file with URLDispatcher

One way to run your server is to direct all requests to a single file that runs a Wolfram Language URLDispatcher function.

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

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

From the same location run:

>>> python3 -m wolframwebengine dispatcher.m
----------------------------------------------------------------------
Address         http://localhost:18000/
File            /Users/rdv/Desktop/dispatcher.m
----------------------------------------------------------------------
(Press CTRL+C to quit) 

All incoming requests will now be routed to the URLDispatcher function in dispatcher.m. You can now open the following urls in your browser:

http://localhost:18000/
http://localhost:18000/form
http://localhost:18000/api

For more information about URLDispatcher please refer to the online documentation.

Multiple files in a directory layout

Another way to write an application is to create a directory structure that is served by the server. The url for each file will match the file's directory path.

The server will serve content with the following rules:

  1. All files with extensions '.m', '.mx', '.wxf', '.wl' will be evaluated in the Kernel using GenerateHTTPResponse on the content of the file.
  2. Any other file will be served as static content.
  3. If the request path corresponds to a directory on disk, the server will search for a file named index.wl in that directory. This convention can be changed with the --index option.

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

mkdir testapp
mkdir testapp/form
mkdir testapp/api
echo 'ExportForm[{"hello", UnixTime[]}, "JSON"]' >  testapp/index.wl
echo 'FormFunction["x" -> "String"]'             >  testapp/form/index.wl
echo 'APIFunction["x" -> "Number", #x! &]'       >  testapp/api/index.wl
echo 'HTTPResponse["hello world"]'               >  testapp/response.wl
echo '["some", "static", "JSON"]'                >  testapp/static.json

Start the application by running:

>>> python3 -m wolframwebengine testapp
----------------------------------------------------------------------
Address         http://localhost:18000/
Folder          /Users/rdv/Desktop/testapp
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit) 

Then open the browser at the following locations:

http://localhost:18000/
http://localhost:18000/form
http://localhost:18000/api?x=4
http://localhost:18000/response.wl
http://localhost:18000/static.json

One advantage of a multi-file application structure is that is very easy to extend the application. You can simply place new files into the appropriate location in your application directory and they will automatically be served.

Using Docker

Wolfram Web Engine for Python is available as a container image from Docker Hub for use in containerized environments.

This image is based on the official Wolfram Engine Docker image; information on product activation and license terms is available on the Docker Hub page for the latter image.

# exposes the server on port 8080 of the host machine
>>> docker run -ti -p 8080:18000 wolframresearch/wolframwebengineforpython --demo

# serve files from the /srv directory
>>> docker run -ti -p 8080:18000 wolframresearch/wolframwebengineforpython /srv

The commands above do not include activation/licensing configuration; see the official Wolfram Engine Docker image for information on activating the Wolfram Engine kernel.

Note regarding on-demand licensing: As Wolfram Web Engine for Python does not use WolframScript, the -entitlement command-line option and the WOLFRAMSCRIPT_ENTITLEMENTID environment variable cannot be used to pass an on-demand license entitlement ID to the Wolfram Engine kernel inside this image. As a workaround, the WOLFRAMINIT environment variable can be set to pass both the entitlement ID and the license server address to the kernel:

>>> docker run -ti -p 8080:18000 --env WOLFRAMINIT='-pwfile !cloudlm.wolfram.com -entitlement O-WSTD-DA42-GKX4Z6NR2DSZR' wolframresearch/wolframwebengineforpython --demo

Options

>>> python3 -m wolframwebengine --help
usage: __main__.py [-h] [--port PORT] [--domain DOMAIN] [--kernel KERNEL]
                   [--poolsize POOLSIZE] [--cached] [--lazy] [--index INDEX]
                   [--demo [{None,ask,trip,ca,form}]]
                   [path]

positional arguments:
  path

optional arguments:
  -h, --help            show this help message and exit
  --port PORT           Insert the port.
  --domain DOMAIN       Insert the domain.
  --kernel KERNEL       Insert the kernel path.
  --poolsize POOLSIZE   Insert the kernel pool size.
  --startuptimeout SECONDS
                        Startup timeout (in seconds) for kernels in the pool.
  --cached              The server will cache the WL input expression.
  --lazy                The server will start the kernels on the first
                        request.
  --index INDEX         The file name to search for folder index.
  --demo [{None,ask,trip,ca,form}]
                        Run a demo application

demo

Run a demo application:

  1. ask: Marginal Tax rate calculator using AskFunction.
  2. trip: Trip calculator using FormFunction and TravelDirections.
  3. ca: Cellular Automaton demo gallery using URLDispatcher and GalleryView.
  4. form: ImageProcessing demo using FormFunction.
>>> python3 -m wolframwebengine --demo ca
----------------------------------------------------------------------
Address         http://localhost:18000/
File            /Users/rdv/Wolfram/git/wolframengineforpython/wolframwebengine/examples/demo/ca.wl
----------------------------------------------------------------------
(Press CTRL+C to quit) 

path

The first argument can be a folder or a single file.

Write a file on your current folder:

>>> mkdir testapp
>>> echo 'ExportForm[{"hello", "from", "Kernel", UnixTime[]}, "JSON"]' > testapp/index.wl

Then from a command line run:

>>> python3 -m wolframwebengine testapp
----------------------------------------------------------------------
Address         http://localhost:18000/
Folder          /Users/rdv/Desktop/testapp
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit) 

If the first argument is a file, requests will be redirected to files in that directory if the url extension is '.m', '.mx', '.wxf', '.wl'. If the extension cannot be handled by a kernel, the file will be served as static content.

If the request path is a folder the server will search for an index.wl in the same folder.

--index

Specify the default file name for the folder index. Defaults to index.wl

python3 -m wolframwebengine --index index.wxf
----------------------------------------------------------------------
Address         http://localhost:18000/
Folder          /Users/rdv/Desktop
Index           index.wxf
----------------------------------------------------------------------
(Press CTRL+C to quit) 

--cached

If --cached is present the code in each file will be run only once, with subsequent requests retrieving the cached result.

>>> python3 -m wolframwebengine --cached
----------------------------------------------------------------------
Address         http://localhost:18000/
Folder          /Users/rdv/Desktop
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit) 

Visit the browser and refresh the page.

--port PORT

Allows you to specify the PORT of the webserver. Defaults to 18000.

>>> python3 -m wolframwebengine --port 9090
----------------------------------------------------------------------
Address         http://localhost:9090/
Folder          /Users/rdv/Desktop
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit) 

--domain DOMAIN

Allows you to specify the DOMAIN of the webserver. By default the webserver only listens to localhost, use 0.0.0.0 to listen on all network interfaces.

>>> python3 -m wolframwebengine --domain 0.0.0.0
----------------------------------------------------------------------
Address         http://0.0.0.0:18000/
Folder          /Users/rdv/Desktop
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit) 

--initfile FILE

Allows you to specify a custom file containing code to be run when a new kernel is started

>>> python3 -m wolframwebengine --initfile myinit.m
----------------------------------------------------------------------
Address         http://localhost:18000/
Folder          /Users/rdv/Desktop
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit) 

--kernel KERNEL

Allows you to specify the Kernel path

>>> python3 -m wolframwebengine --kernel '/Applications/Wolfram Desktop 12.app/Contents/MacOS/WolframKernel'
----------------------------------------------------------------------
Address         http://localhost:18000/
Folder          /Users/rdv/Desktop
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit) 

--poolsize SIZE

Wolfram Web Engine for Python will launch a pool of Wolfram Language kernels to handle incoming requests. Running more than one kernel can improve responsiveness if multiple requests arrive at the same time. The --poolsize option lets you change the number of kernels that will be launched. Defaults to 1.

>>> python3 -m wolframwebengine --poolsize 4
----------------------------------------------------------------------
Address         http://localhost:18000/
Folder          /Users/rdv/Desktop
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit)

--startuptimeout SECONDS

By default, an attempt to start a kernel will be aborted if the kernel is not ready after 20 seconds. If your application contains long-running initialization code, you may need to raise this timeout.

>>> python3 -m wolframwebengine
(...)
Kernel process started with PID: 485
Socket exception: Failed to read any message from socket tcp://127.0.0.1:5106 after 20.0 seconds and 245 retries.
Failed to start.


>>> python3 -m wolframwebengine --startuptimeout 50
(...)
Kernel process started with PID: 511
Connected to logging socket: tcp://127.0.0.1:5447
Kernel 511 is ready. Startup took 35.43 seconds.

--lazy

If the option is present the server will wait for the first request to spawn the kernels, instead of spawning them immediately.

--client_max_size MB

The maximum amount of megabytes allowed for file upload. Defaults to 10.

>>> python3 -m wolframwebengine --client_max_size 150
----------------------------------------------------------------------
Address         http://localhost:18000/
Folder          /Users/rdv/Desktop
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit)

Integrating an existing application

Wolfram Web Engine for Python can be used to augment an existing python application instead of creating a new one. We currently support the following frameworks:

Django

If you have an existing Django application you can use the django_wl_view decorator to evaluate Wolfram Language code during a web request.

from __future__ import absolute_import, print_function, unicode_literals

from django.http import HttpResponse
from django.urls import path

from wolframclient.language import wl
from wolframclient.evaluation import WolframLanguageSession
from wolframwebengine.web import django_wl_view

session = WolframLanguageSession()

def django_view(request):
    return HttpResponse("hello from django")

@django_wl_view(session)
def form_view(request):
    return wl.FormFunction({"x": "String"}, wl.Identity, "JSON")


@django_wl_view(session)
def api_view(request):
    return wl.APIFunction({"x": "String"}, wl.Identity, "JSON")


urlpatterns = [
    path("", django_view, name="home"),
    path("form", form_view, name="form"),
    path("api", api_view, name="api"),
]

The decorator can be used with any kind of synchronous evaluator exposed and documented in WolframClientForPython.

Aiohttp

If you have an existing Aiohttp server running you can use the aiohttp_wl_view decorator to evaluate Wolfram Language code during a web request.

from aiohttp import web

from wolframclient.evaluation import WolframEvaluatorPool
from wolframclient.language import wl
from wolframwebengine.web import aiohttp_wl_view

session = WolframEvaluatorPool(poolsize=4)
routes = web.RouteTableDef()


@routes.get("/")
async def hello(request):
    return web.Response(text="Hello from aiohttp")


@routes.get("/form")
@aiohttp_wl_view(session)
async def form_view(request):
    return wl.FormFunction(
        {"x": "String"}, wl.Identity, AppearanceRules={"Title": "Hello from WL!"}
    )


@routes.get("/api")
@aiohttp_wl_view(session)
async def api_view(request):
    return wl.APIFunction({"x": "String"}, wl.Identity)


@routes.get("/app")
@aiohttp_wl_view(session)
async def app_view(request):
    return wl.Once(wl.Get("path/to/my/complex/wl/app.wl"))


app = web.Application()
app.add_routes(routes)

if __name__ == "__main__":
    web.run_app(app)

The decorator can be used with any kind of asynchronous evaluator exposed and documented in WolframClientForPython.

wolframwebengineforpython's People

Contributors

arnoudbuzing avatar crazyeng avatar jfultz avatar okofish avatar riccardodivirgilio avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wolframwebengineforpython's Issues

How to handle POST requests with JSON payload in the body?

Here is simple example of what I am doing:

APIFunction[
    {},
    If[HTTPRequestData["Method"] === "GET",
        "400 Bad Request",
        ExportForm[HTTPRequestData["Body"], "JSON"]
    ]&
]

I pass the following JSON object to the endpoint:

{
    x: 1,
    y: 2,
    z: 3
}

I have tried using postman, insomnia and fetch function in javascript to send the payload. All of them complain Expression "None" cannot be exported as JSON. Upon closer inspection, I found that HTTPRequestData["Body"] remains None for some reason.

What would be the best way to deal with JSON payloads in POST requests? It may be helpful to know that the above function works fine when deployed in Wolfram Application Server.

client_max_size exceeded

Is it possible to influence client_max_size used by aiohttp?

Currently relatively large files (more than 1MB encoded) can't be uploaded.

FormFunction[{"file" -> "CachedFile"},ToString[#file]&]

Invalid state error for long (and frequent) requests

I've made some relatively long running APIFunction:

Export["~/Projects/webengine/http.wl", 
 APIFunction[{"a" -> "Integer"}, 
  ExportForm[
    Graphics3D[Translate[Sphere[], RandomReal[{-20, 20}, {#a, 3}]]], 
    "JPEG"] &]]

This runs ok:

image

GET /http.wl done in 0.1067s: 200

But if you press Ctrl/Cmd - R in browser (or use some performance testing tool like ab) there're state errors in wolframwebengine which effectively bring the server to its knees:

 GET /http.wl done in 0.1071s: 200
GET /http.wl done in 0.1078s: 200
Start termination on kernel 
Killing kernel process: 8634
Exception in thread wolfram-kernel-1:
Traceback (most recent call last):
  File "/usr/local/Cellar/[email protected]/3.9.1_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.9/site-packages/wolframclient/evaluation/kernel/kernelcontroller.py", line 599, in run
Kernel writes commands to socket: 
Kernel receives evaluated expressions from socket: 
    raise e
  File "/usr/local/lib/python3.9/site-packages/wolframclient/evaluation/kernel/kernelcontroller.py", line 583, in run
    self._do_evaluate(payload, future, result_update_callback)
  File "/usr/local/lib/python3.9/site-packages/wolframclient/evaluation/kernel/kernelcontroller.py", line 547, in _do_evaluate
Kernel process started with PID: 8645
    future.set_result(result)
  File "/usr/local/Cellar/[email protected]/3.9.1_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/concurrent/futures/_base.py", line 525, in set_result
    raise InvalidStateError('{}: {!r}'.format(self._state, self))
concurrent.futures._base.InvalidStateError: CANCELLED: 
Kernel 8645 is ready. Startup took 1.82 seconds.
Start termination on kernel 
Killing kernel process: 8645
Exception in thread wolfram-kernel-2:
Traceback (most recent call last):
  File "/usr/local/Cellar/[email protected]/3.9.1_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.9/site-packages/wolframclient/evaluation/kernel/kernelcontroller.py", line 599, in run
    raise e
  File "/usr/local/lib/python3.9/site-packages/wolframclient/evaluation/kernel/kernelcontroller.py", line 558, in run
    future.set_result(True)
  File "/usr/local/Cellar/[email protected]/3.9.1_1/Frameworks/Python.framework/Versions/3.9/lib/python3.9/concurrent/futures/_base.py", line 525, in set_result
    raise InvalidStateError('{}: {!r}'.format(self._state, self))
concurrent.futures._base.InvalidStateError: CANCELLED: 
Kernel writes commands to socket: 
Kernel receives evaluated expressions from socket: 
Kernel process started with PID: 8646
Kernel 8646 is ready. Startup took 1.81 seconds.

Windows support

Hi,

Excellent documentation of Wolfram Web Engine.
I have Wolfram engine, I also have python in my system. But I am using Windows 10 OS.
How do i run this from my system?
Help would be really appreciated

Problem when working with multiple choice of random values

This form cannot work

list = RandomReal[{}, 3];

FormPage[{"x" -> "Real",  "y" -> list} ,  #x + #y &]

because list gets updated right after the selection of "y". I think list should be updated only after submitting the whole form or after a refresh, not while still selecting the values to be submitted.

Branding Question

When serving FormFunctions, the dialogs that are served are Wolfram branded.
I'm curious if there is an option to license this for commercial use with branding removed.
Perhaps this is a Wolfram Engine question rather than a Wolfram Web Engine question, but I'm not exactly sure at what stage the branding is created.
Thanks!
John

Load resources at web engine startup

I'm enjoying using the Wolfram Web Engine.
I'd like to load some resources (specifically a classifier object) from Wolfram Cloud into memory when the server starts up, rather than at the time of an API call.
Is there a way to specify this into an "initialization" file that is consumed at server startup?
Many thanks!
John

Unable to pass custom init file

I would like to preload some data when starting the server. When I load it through the init file from the default locations e.g. $UserBaseDirectory/Kernel/init.m, it works fine. But when I try to pass a custom init file with the option --initfile, the server does not start and it returns a big error message.

(wwe) s4m13337@s4m13337-MBA wwe $ python3 -m wolframwebengine --initfile myinit.m testapp
----------------------------------------------------------------------
Address         http://localhost:18000/
Folder          /Users/som/Developer/wwe/testapp
Index           index.wl
----------------------------------------------------------------------
(Press CTRL+C to quit)

Kernel writes commands to socket: <Socket: uri=tcp://127.0.0.1:53654>
Kernel receives evaluated expressions from socket: <Socket: uri=tcp://127.0.0.1:53655>
Initializing Kernel logger on socket tcp://127.0.0.1:53656
Kernel process started with PID: 85336
Socket exception: Failed to read any message from socket tcp://127.0.0.1:53655 after 20.0 seconds and 198 retries.
Failed to start.
Start termination on kernel <WolframKernelController[wolfram-kernel-1 ✅], "/Applications/Mathematica.app/Contents/MacOS/WolframKernel", pid:85336, kernel sockets: (in:tcp://127.0.0.1:53655, out:tcp://127.0.0.1:53654)>
Killing kernel process: 85336
Terminating kernel logger thread.
Start termination on kernel <WolframKernelController[wolfram-kernel-1 ❌], "/Applications/Mathematica.app/Contents/MacOS/WolframKernel">
Traceback (most recent call last):
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframclient/evaluation/kernel/kernelcontroller.py", line 435, in _kernel_start
    response = self.kernel_socket_in.recv_abortable(
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframclient/evaluation/kernel/zmqsocket.py", line 53, in recv_abortable
    raise SocketOperationTimeout(
wolframclient.evaluation.kernel.zmqsocket.SocketOperationTimeout: Failed to read any message from socket tcp://127.0.0.1:53655 after 20.0 seconds and 198 retries.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/som/Developer/wwe/bin/wolframwebengine", line 8, in <module>
    sys.exit(main())
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframwebengine/__main__.py", line 7, in main
    Command().main()
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframclient/cli/utils.py", line 83, in main
    return self.handle(*args, **cmd_options)
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframwebengine/cli/commands/runserver.py", line 199, in handle
    loop.run_until_complete(main())
  File "/Users/s4m13337/.pyenv/versions/3.10.10/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
    return future.result()
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframwebengine/cli/commands/runserver.py", line 193, in main
    await session.start()
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframclient/evaluation/kernel/asyncsession.py", line 135, in start
    await asyncio.wrap_future(future)
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframclient/evaluation/kernel/kernelcontroller.py", line 557, in run
    self._safe_kernel_start()
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframclient/evaluation/kernel/kernelcontroller.py", line 366, in _safe_kernel_start
    raise e
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframclient/evaluation/kernel/kernelcontroller.py", line 360, in _safe_kernel_start
    self._kernel_start()
  File "/Users/som/Developer/wwe/lib/python3.10/site-packages/wolframclient/evaluation/kernel/kernelcontroller.py", line 455, in _kernel_start
    raise WolframKernelException(
wolframclient.exception.WolframKernelException: Failed to communicate with kernel: /Applications/Mathematica.app/Contents/MacOS/WolframKernel.

For testing purpose, the content of myinit.m is just test = 123 and to verify if it works, I added ExportForm[{"hello", UnixTime[], test}, "JSON"] in the testapp/index.wl file. I have tried both inside and outside a python virtual environment.

More details on how to activate the Docker image

The current README.md file states that

The commands above do not include activation/licensing configuration; see the official Wolfram Engine Docker image for information on activating the Wolfram Engine kernel.

The problem is that when running the WolframWebEngineForPython (WEPy for short) Docker container, the Python server code is started which invokes the Wolfram kernel and then immediately crashes as there's no license yet. The activation of the Wolfram Engine's Docker image is easy because that image launches WolframScript, but for the WEPy container a workaround is needed:

docker run -it --entrypoint=/bin/bash wolframresearch/wolframwebengineforpython

The --entrypoint /bin/bash overrides the Python server code and launches a shell instead "inside" the container. From that shell one can invoke wolframscript and then it's possible to activate by following the instructions for the Wolfram Engine Docker image. Perhaps it's also possible to invoke WolframScript directly by typing --entrypoint wolframscript but I haven't tried that.

I'd like to suggest that the README.md be updated with this extra information.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.