The aim of OTP scripting is to be able to use and automate OTP from within scripts.
Note: Jython is a Python-flavor using a Java JVM as runtime. Python and Jython are mostly compatible.
There are currently 3 different modes for using scripting:
- Launching OTP with the
--scriptcommand-line parameter, providing the script filename as an option.
- Starting an OTP server with the
--enableScriptingWebServicecommand-line parameter, and posting a script to execute to the
- Launching a Jython script with
otp-x.y.z-shaded.jarin the classpath and creating the scripting entry-point bean in the script itself.
Launching a script from OTP
The main advantage of this method is its simplicity. The drawback is that you need to start OTP everytime you run a script, which can be slow to startup for large graphs. The second drawback is that you can't import custom packages from within the script, you are limited to the "plain basic" Jython.
Note: The Jython (or Groovy) JAR are not included in the OTP shaded JAR. You thus have to add one of them (depending on your script) to the java classpath (see command below). Jython jar can be downloaded here. Make sure you select the "standalone" version of jython, otherwise some classes will be missing.
Note: Due a guava bug, there is an incompatibility between Jython 2.3 / 2.5 and OTP. To solve it, make sure otp.jar is added before jython-standalone.jar in the classpath. This bug should be solved in jython starting 2.7.
Start OTP specifying the classpath and adding the
$ java -cp otp-x.y.z-shaded.jar:jython-standalone.jar org.opentripplanner.standalone.OTPMain --graphs . --script myscript.py
This will start OTP with a default graph in the current directory and execute the script
The return value of the script is discarded and printed to the log as a warning if the return value is not
The main advantage of this method is that you do not need to start a new OTP server (which can take some time for large graphs) each time you start a new script. This mode is well-adapted for script development and debugging. The drawback is about security: it is not advisable to use this method for public-facing servers.
Start an OTP server as usual, adding the
$ java -cp otp-x.y.z-shaded.jar:jython-standalone.jar org.opentripplanner.standalone.OTPMain --graphs . --server --enableScriptingWebService
The API end-point
/ws/scripting/run now accepts script content to be run, posted as multi-part form data.
To post a script to be executed, you can use either:
- The online form at
http://host:8080/scripting.html, where you can upload a localfile to the server;
curlfrom the command-line, such as:
$ curl --form "email@example.com" host:8080/otp/scripting/run
The return value of the script is passed as the return value of the web-service, in textual form. This can be used to return some value to the client (for example data in CSV form).
The standard output / error streams of the script (the place where the various
The default location where files are loaded or saved is the working directory of the server, usually the directory from where you started the OTP server.
Warning: Enable this web-service on public-facing server is rather dangerous as this will open a whole range of exploits on the application.
Using OTP as a library
The advantage of this method is its versatility. You can import any custom library in your script, and you are free to create the OTP server instance when you need it. The drawback is that you need to have an external Jython interpreter installed, and you need to startup OTP yourself within the script (2 lines of code, see below).
Example of use using python:
#!/usr/bin/jython from org.opentripplanner.scripting.api import * otp = OtpsEntryPoint.fromArgs([ "--graphs", "/path/to/graphs", "--router", "amsterdam" ]) # ... the rest of your script goes here ...
$ java -cp otp-x.y.z-shaded.jar:jython-standalone.jar org.python.util.jython myscript.py
$ jython -Dpython.path=otp-x.y.z-shaded.jar myscript.py
Note that contrary to java custom the jython "main" class is all lowercase, this is not a typo.
For a simple but functional example, please see this script. With the embedded comments it should be self-explanatory. In order to use this demo in the "library" mode, insert the 3 python lines given in the previous section at the beginning of the script.
For a complete documentation, please see the online JavaDoc of all classes within the
Classes in this package are meant to be kept stable in time, at least regarding backward compatibility. Be careful as scripting is still in development phase; so there is no strong guarantee about the stability of the API, which is only a stated long-term goal. The aim is to achieve a stable API for the 1.0 OTP release.