{"id":22588850,"url":"https://github.com/wolframresearch/wolframwebengineforpython","last_synced_at":"2025-11-10T12:04:50.368Z","repository":{"id":48649499,"uuid":"207578815","full_name":"WolframResearch/WolframWebEngineForPython","owner":"WolframResearch","description":"Integrates the Wolfram Language seamlessly with Python AIOHTTP","archived":false,"fork":false,"pushed_at":"2023-11-28T17:47:59.000Z","size":538,"stargazers_count":91,"open_issues_count":4,"forks_count":14,"subscribers_count":23,"default_branch":"master","last_synced_at":"2024-12-08T08:11:11.405Z","etag":null,"topics":["aiohttp","django","python","wolfram-engine","wolfram-language","wolfram-web-engine"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WolframResearch.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-09-10T14:16:26.000Z","updated_at":"2024-09-14T01:47:28.000Z","dependencies_parsed_at":"2024-01-18T04:56:26.935Z","dependency_job_id":"225eabd4-6dae-4ed0-a677-c8ae5da176b9","html_url":"https://github.com/WolframResearch/WolframWebEngineForPython","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WolframResearch%2FWolframWebEngineForPython","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WolframResearch%2FWolframWebEngineForPython/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WolframResearch%2FWolframWebEngineForPython/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WolframResearch%2FWolframWebEngineForPython/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WolframResearch","download_url":"https://codeload.github.com/WolframResearch/WolframWebEngineForPython/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230479864,"owners_count":18232630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aiohttp","django","python","wolfram-engine","wolfram-language","wolfram-web-engine"],"created_at":"2024-12-08T08:11:22.142Z","updated_at":"2025-11-10T12:04:50.315Z","avatar_url":"https://github.com/WolframResearch.png","language":"Python","readme":"# Wolfram Web Engine for Python\n\nWolfram Web Engine for Python uses the Python AIOHTTP web server to handle requests for a Wolfram Engine.\nWeb pages are specified on the server with standard Wolfram Language functions such as [APIFunction](https://reference.wolfram.com/language/ref/APIFunction.html), [FormFunction](https://reference.wolfram.com/language/ref/FormFunction.html), [FormPage](https://reference.wolfram.com/language/ref/FormPage.html),\n[URLDispatcher](https://reference.wolfram.com/language/ref/URLDispatcher.html), [AskFunction](https://reference.wolfram.com/language/ref/AskFunction.html), [HTTPResponse](https://reference.wolfram.com/language/ref/HTTPResponse.html), [HTTPRedirect](https://reference.wolfram.com/language/ref/HTTPRedirect.html), etc. This allows you to integrate Wolfram Language \nfunctionality seamlessly with existing Python web applications like Django and AIOHTTP.\n\n## Getting Started\n\n### Prerequisites\n\n1. Python 3.5 or higher\n2. Wolfram Language 11.3 or higher (Mathematica, Wolfram Desktop, or Wolfram Engine)\n3. [WolframClientForPython](!https://github.com/WolframResearch/WolframClientForPython)\n\n### Install Using pip (Recommended)\nRecommended for most users. It installs the latest stable version released by Wolfram Research.\n\nEvaluate the following command in a terminal:\n\n```\n\u003e\u003e\u003e pip3 install wolframwebengine\n```\n\n### Install Using Git\n\nRecommended for developers who want to install the library along with the full source code.\nClone the library’s repository:\n\n```\n\u003e\u003e\u003e git clone git://github.com/WolframResearch/WolframWebEngineForPython\n```\n\nInstall the library in your site-package directory:\n\n```\n\u003e\u003e\u003e cd WolframWebEngineForPython\n\u003e\u003e\u003e pip3 install .\n```\n\nThe following method is not installing the library globally, therefore all the example commands needs to run from the cloned directory.\n\n### Start a demo server\n\nStart a demo server by doing:\n\n```\npython3 -m wolframwebengine --demo\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFolder          /Users/rdv/Desktop/wolframengineforpython/wolframwebengine/examples/demoapp\nIndex           index.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\nNow you can open your web browser at the address http://localhost:18000/\n\n![image](https://raw.githubusercontent.com/WolframResearch/WolframWebEngineForPython/master/docs/assets/image1.png)\n\n## Two different ways of structuring an application:\n\n1. Use a single file with URLDispatcher\n2. Use multiple files in a directory layout\n\n### Single file with URLDispatcher\n\nOne way to run your server is to direct all requests to a single file\nthat runs a Wolfram Language [URLDispatcher](https://reference.wolfram.com/language/ref/URLDispatcher.html) function.\n\nWrite the following content in a file called `dispatcher.m`:\n\n```\nURLDispatcher[{\n    \"/api\" -\u003e APIFunction[\"x\" -\u003e \"String\"], \n    \"/form\" -\u003e FormFunction[\"x\" -\u003e \"String\"], \n    \"/\" -\u003e \"hello world!\"\n}]\n```\n\nFrom the same location run:\n\n```\n\u003e\u003e\u003e python3 -m wolframwebengine dispatcher.m\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFile            /Users/rdv/Desktop/dispatcher.m\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\nAll incoming requests will now be routed to the `URLDispatcher` function in `dispatcher.m`.\nYou can now open the following urls in your browser:\n\n```\nhttp://localhost:18000/\nhttp://localhost:18000/form\nhttp://localhost:18000/api\n```\n\nFor more information about `URLDispatcher` please refer to the [online documentation](https://reference.wolfram.com/language/ref/URLDispatcher.html).\n\n### Multiple files in a directory layout\n\nAnother 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.\n\nThe server will serve content with the following rules:\n\n1. All files with extensions '.m', '.mx', '.wxf', '.wl' will be evaluated in the Kernel using [GenerateHTTPResponse](https://reference.wolfram.com/language/ref/GenerateHTTPResponse.html) on the content of the file.\n2. Any other file will be served as static content.\n3. 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.\n\nCreate an application by running the following code in your current location:\n\n```\nmkdir testapp\nmkdir testapp/form\nmkdir testapp/api\necho 'ExportForm[{\"hello\", UnixTime[]}, \"JSON\"]' \u003e  testapp/index.wl\necho 'FormFunction[\"x\" -\u003e \"String\"]'             \u003e  testapp/form/index.wl\necho 'APIFunction[\"x\" -\u003e \"Number\", #x! \u0026]'       \u003e  testapp/api/index.wl\necho 'HTTPResponse[\"hello world\"]'               \u003e  testapp/response.wl\necho '[\"some\", \"static\", \"JSON\"]'                \u003e  testapp/static.json\n```\n\nStart the application by running:\n\n```\n\u003e\u003e\u003e python3 -m wolframwebengine testapp\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFolder          /Users/rdv/Desktop/testapp\nIndex           index.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\nThen open the browser at the following locations:\n\n```\nhttp://localhost:18000/\nhttp://localhost:18000/form\nhttp://localhost:18000/api?x=4\nhttp://localhost:18000/response.wl\nhttp://localhost:18000/static.json\n```\n\nOne 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.\n\n\n## Using Docker\n\nWolfram Web Engine for Python is available as [a container image from Docker Hub](https://hub.docker.com/r/wolframresearch/wolframwebengineforpython) for use in containerized environments.\n\nThis image is based on the [official Wolfram Engine Docker image](https://hub.docker.com/r/wolframresearch/wolframengine); information on product activation and license terms\nis available on the [Docker Hub page](https://hub.docker.com/r/wolframresearch/wolframengine) for the latter image.\n\n```\n# exposes the server on port 8080 of the host machine\n\u003e\u003e\u003e docker run -ti -p 8080:18000 wolframresearch/wolframwebengineforpython --demo\n\n# serve files from the /srv directory\n\u003e\u003e\u003e docker run -ti -p 8080:18000 wolframresearch/wolframwebengineforpython /srv\n```\n\nThe commands above do not include activation/licensing configuration; see the [official Wolfram Engine Docker image](https://hub.docker.com/r/wolframresearch/wolframengine) for information on activating the Wolfram Engine kernel.\n\n\nNote regarding on-demand licensing: As Wolfram Web Engine for Python does not use WolframScript, the `-entitlement` command-line option and the `WOLFRAMSCRIPT_ENTITLEMENTID`\nenvironment variable cannot be used to pass an on-demand license entitlement ID to the Wolfram Engine kernel inside this image.\nAs a workaround, the `WOLFRAMINIT` environment variable can be set to pass both the entitlement ID and the license server address to the kernel:\n\n```\n\u003e\u003e\u003e docker run -ti -p 8080:18000 --env WOLFRAMINIT='-pwfile !cloudlm.wolfram.com -entitlement O-WSTD-DA42-GKX4Z6NR2DSZR' wolframresearch/wolframwebengineforpython --demo\n```\n\n\n## Options\n\n```\n\u003e\u003e\u003e python3 -m wolframwebengine --help\nusage: __main__.py [-h] [--port PORT] [--domain DOMAIN] [--kernel KERNEL]\n                   [--poolsize POOLSIZE] [--cached] [--lazy] [--index INDEX]\n                   [--demo [{None,ask,trip,ca,form}]]\n                   [path]\n\npositional arguments:\n  path\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --port PORT           Insert the port.\n  --domain DOMAIN       Insert the domain.\n  --kernel KERNEL       Insert the kernel path.\n  --poolsize POOLSIZE   Insert the kernel pool size.\n  --startuptimeout SECONDS\n                        Startup timeout (in seconds) for kernels in the pool.\n  --cached              The server will cache the WL input expression.\n  --lazy                The server will start the kernels on the first\n                        request.\n  --index INDEX         The file name to search for folder index.\n  --demo [{None,ask,trip,ca,form}]\n                        Run a demo application\n```\n\n#### demo\n\nRun a demo application:\n\n 1. __ask__: Marginal Tax rate calculator using AskFunction.\n 2. __trip__: Trip calculator using FormFunction and TravelDirections.\n 3. __ca__: Cellular Automaton demo gallery using URLDispatcher and GalleryView.\n 4. __form__: ImageProcessing demo using FormFunction.\n\n```\n\u003e\u003e\u003e python3 -m wolframwebengine --demo ca\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFile            /Users/rdv/Wolfram/git/wolframengineforpython/wolframwebengine/examples/demo/ca.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\n#### path\n\nThe first argument can be a folder or a single file.\n\nWrite a file on your current folder:\n\n```\n\u003e\u003e\u003e mkdir testapp\n\u003e\u003e\u003e echo 'ExportForm[{\"hello\", \"from\", \"Kernel\", UnixTime[]}, \"JSON\"]' \u003e testapp/index.wl\n```\n\nThen from a command line run:\n\n```\n\u003e\u003e\u003e python3 -m wolframwebengine testapp\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFolder          /Users/rdv/Desktop/testapp\nIndex           index.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\nIf 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.\n\nIf the request path is a folder the server will search for an index.wl in the same folder.\n\n#### --index\n\nSpecify the default file name for the folder index.\nDefaults to index.wl\n\n```\npython3 -m wolframwebengine --index index.wxf\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFolder          /Users/rdv/Desktop\nIndex           index.wxf\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\n\n#### --cached\n\nIf --cached is present the code in each file will be run only once, with subsequent requests retrieving the cached result.\n\n```\n\u003e\u003e\u003e python3 -m wolframwebengine --cached\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFolder          /Users/rdv/Desktop\nIndex           index.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\nVisit the browser and refresh the page.\n\n\n#### --port PORT\n\nAllows you to specify the PORT of the webserver. Defaults to 18000.\n\n```\n\u003e\u003e\u003e python3 -m wolframwebengine --port 9090\n----------------------------------------------------------------------\nAddress         http://localhost:9090/\nFolder          /Users/rdv/Desktop\nIndex           index.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\n#### --domain DOMAIN\n\nAllows 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.\n\n```\n\u003e\u003e\u003e python3 -m wolframwebengine --domain 0.0.0.0\n----------------------------------------------------------------------\nAddress         http://0.0.0.0:18000/\nFolder          /Users/rdv/Desktop\nIndex           index.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\n#### --initfile FILE\n\nAllows you to specify a custom file containing code to be run when a new kernel is started\n\n```\n\u003e\u003e\u003e python3 -m wolframwebengine --initfile myinit.m\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFolder          /Users/rdv/Desktop\nIndex           index.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\n#### --kernel KERNEL\n\nAllows you to specify the Kernel path\n\n```\n\u003e\u003e\u003e python3 -m wolframwebengine --kernel '/Applications/Wolfram Desktop 12.app/Contents/MacOS/WolframKernel'\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFolder          /Users/rdv/Desktop\nIndex           index.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit) \n```\n\n#### --poolsize SIZE\n\nWolfram 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.\n```\n\u003e\u003e\u003e python3 -m wolframwebengine --poolsize 4\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFolder          /Users/rdv/Desktop\nIndex           index.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit)\n```\n\n#### --startuptimeout SECONDS\n\nBy 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.\n```\n\u003e\u003e\u003e python3 -m wolframwebengine\n(...)\nKernel process started with PID: 485\nSocket exception: Failed to read any message from socket tcp://127.0.0.1:5106 after 20.0 seconds and 245 retries.\nFailed to start.\n\n\n\u003e\u003e\u003e python3 -m wolframwebengine --startuptimeout 50\n(...)\nKernel process started with PID: 511\nConnected to logging socket: tcp://127.0.0.1:5447\nKernel 511 is ready. Startup took 35.43 seconds.\n```\n\n#### --lazy \n\nIf the option is present the server will wait for the first request to spawn the kernels, instead of spawning them immediately.\n\n\n#### --client_max_size MB\n\nThe maximum amount of megabytes allowed for file upload. Defaults to 10.\n```\n\u003e\u003e\u003e python3 -m wolframwebengine --client_max_size 150\n----------------------------------------------------------------------\nAddress         http://localhost:18000/\nFolder          /Users/rdv/Desktop\nIndex           index.wl\n----------------------------------------------------------------------\n(Press CTRL+C to quit)\n```\n\n## Integrating an existing application\n\nWolfram Web Engine for Python can be used to augment an existing python application instead of creating a new one.\nWe currently support the following frameworks:\n\n### Django\n\nIf you have an existing [Django](!https://www.djangoproject.com/) application you can use the `django_wl_view` decorator to evaluate Wolfram Language code during a web request.\n\n```python\nfrom __future__ import absolute_import, print_function, unicode_literals\n\nfrom django.http import HttpResponse\nfrom django.urls import path\n\nfrom wolframclient.language import wl\nfrom wolframclient.evaluation import WolframLanguageSession\nfrom wolframwebengine.web import django_wl_view\n\nsession = WolframLanguageSession()\n\ndef django_view(request):\n    return HttpResponse(\"hello from django\")\n\n@django_wl_view(session)\ndef form_view(request):\n    return wl.FormFunction({\"x\": \"String\"}, wl.Identity, \"JSON\")\n\n\n@django_wl_view(session)\ndef api_view(request):\n    return wl.APIFunction({\"x\": \"String\"}, wl.Identity, \"JSON\")\n\n\nurlpatterns = [\n    path(\"\", django_view, name=\"home\"),\n    path(\"form\", form_view, name=\"form\"),\n    path(\"api\", api_view, name=\"api\"),\n]\n```\n\nThe decorator can be used with any kind of synchronous evaluator exposed and documented in [WolframClientForPython](!https://github.com/WolframResearch/WolframClientForPython).\n\n### Aiohttp\n\nIf you have an existing [Aiohttp](!https://docs.aiohttp.org/en/stable/web_reference.html) server running you can use the `aiohttp_wl_view` decorator to evaluate Wolfram Language code during a web request.\n\n```python\nfrom aiohttp import web\n\nfrom wolframclient.evaluation import WolframEvaluatorPool\nfrom wolframclient.language import wl\nfrom wolframwebengine.web import aiohttp_wl_view\n\nsession = WolframEvaluatorPool(poolsize=4)\nroutes = web.RouteTableDef()\n\n\n@routes.get(\"/\")\nasync def hello(request):\n    return web.Response(text=\"Hello from aiohttp\")\n\n\n@routes.get(\"/form\")\n@aiohttp_wl_view(session)\nasync def form_view(request):\n    return wl.FormFunction(\n        {\"x\": \"String\"}, wl.Identity, AppearanceRules={\"Title\": \"Hello from WL!\"}\n    )\n\n\n@routes.get(\"/api\")\n@aiohttp_wl_view(session)\nasync def api_view(request):\n    return wl.APIFunction({\"x\": \"String\"}, wl.Identity)\n\n\n@routes.get(\"/app\")\n@aiohttp_wl_view(session)\nasync def app_view(request):\n    return wl.Once(wl.Get(\"path/to/my/complex/wl/app.wl\"))\n\n\napp = web.Application()\napp.add_routes(routes)\n\nif __name__ == \"__main__\":\n    web.run_app(app)\n```\n\nThe decorator can be used with any kind of asynchronous evaluator exposed and documented in [WolframClientForPython](!https://github.com/WolframResearch/WolframClientForPython).\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwolframresearch%2Fwolframwebengineforpython","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwolframresearch%2Fwolframwebengineforpython","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwolframresearch%2Fwolframwebengineforpython/lists"}