Skip to content

Using PIP in Docker

sillyfrog edited this page Nov 16, 2018 · 2 revisions

These are the steps I have taken to get pip going in the openHAB Docker container. They should work for any deployment with tweaking of the relevant paths.

To use pip, you must be running Jython v2.7.1 (downloaded from here: http://search.maven.org/remotecontent?filepath=org/python/jython-standalone/2.7.1/jython-standalone-2.7.1.jar). This is not compatible with Esper, so be sure to remove all of these files before upgrading (this problem should go away a new directory structure proposed), ie:

rm -rf ./automation/jsr223/000_components/000_Esper.py ./automation/lib/python/esper

With v2.7.1 installed, we can run the Jython from the openHAB installation to install pip

java -jar /openhab/conf/automation/jython/jython-standalone-2.7.1.jar -m ensurepip

Important: Do not upgrade pip, v18.1 in Jython/openHAB appears to have issues with some packages, v9.0.1 continues to work OK.

Ignore errors such as:

  Failed to open /openhab/conf/automation/jython/bin/jython

This is pip/Python trying to run jython as a shell application, which as it's running in Java won't work (there's probably an easy solution using a wrapper script, but as the only goal is to install packages, I have not done any work to make this happen)

You can then install any (pure Python) packages you want, for example, to install Requests (Note: Unfortunately Requests does not work out of the box with jython, work around below):

java -jar /openhab/conf/automation/jython/jython-standalone-2.7.1.jar -m pip install requests

Note: you may have to restart openHAB to get access to the new libraries as the module cache is not reloaded. If nothing has attempted to import the module, it should just work with a reload of the script, however a full restart of the openHAB container is safest to ensure it's pulling all of the new modules in.

Python Requests

If you want to use Python Requests, you'll need to do the following as there appears to be a bug in the Java zlib implementation. If you get a trace-back such as this:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/openhab/conf/automation/jython/Lib/site-packages/requests/api.py", line 75, in get
    return request('get', url, params=params, **kwargs)
  File "/openhab/conf/automation/jython/Lib/site-packages/requests/api.py", line 60, in request
    return session.request(method=method, url=url, **kwargs)
  File "/openhab/conf/automation/jython/Lib/site-packages/requests/sessions.py", line 524, in request
    resp = self.send(prep, **send_kwargs)
  File "/openhab/conf/automation/jython/Lib/site-packages/requests/sessions.py", line 677, in send
    r.content
  File "/openhab/conf/automation/jython/Lib/site-packages/requests/models.py", line 828, in content
    self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b''
  File "/openhab/conf/automation/jython/Lib/site-packages/requests/models.py", line 750, in generate
    for chunk in self.raw.stream(chunk_size, decode_content=True):
  File "/openhab/conf/automation/jython/Lib/site-packages/requests/models.py", line 750, in generate
    for chunk in self.raw.stream(chunk_size, decode_content=True):
  File "/openhab/conf/automation/jython/Lib/site-packages/urllib3/response.py", line 490, in stream
    for line in self.read_chunked(amt, decode_content=decode_content):
  File "/openhab/conf/automation/jython/Lib/site-packages/urllib3/response.py", line 679, in read_chunked
    decoded = self._flush_decoder()
  File "/openhab/conf/automation/jython/Lib/site-packages/urllib3/response.py", line 343, in _flush_decoder
    return buf + self._decoder.flush()
  File "/openhab/conf/automation/jython/jython-standalone-2.7.1.jar/Lib/zlib.py", line 244, in flush
  File "/openhab/conf/automation/jython/jython-standalone-2.7.1.jar/Lib/zlib.py", line 281, in _get_inflate_data
zlib.error: java.util.zip.DataFormatException: invalid stored block lengths

You can modify your requests call to disable the use of zlib, by including the keyword argument headers={'Accept-Encoding':''}, for example:

r = requests.get("http://example.com/", headers={'Accept-Encoding':''})

(There maybe a better way, but this appears to work)

Clone this wiki locally