26. December 2019

Build Installer for your Python application – PyInstaller

Do you have your Python application ready? Now it’s time to distribute it. The question is how to bundle it?

One way of bundling Python application into exe/binary file is to use PyInstaller.

You can do it using following commands:

pip install pyinstaller
pyinstaller file_with_main.py

The result will be stored in directory dist. The directory contains one build for the operating system that you’re running.

Do you need support with building package? Or do you need to build the package for different OS/Architecture, but you do not have target OS in your disposal (e.g. Linux, Windows, macOS, Raspberry PI, IBM Z-systems)? Let us know.

24. July 2019

Creating Python virtualenv fails with error: Could not find a suitable TLS CA

You can create Python virtualenv using command:

virtualenv -p /usr/bin/python3 py-env3

You may encounter following strange error:

  Collecting setuptools
Exception:
Traceback (most recent call last):
  File "/usr/share/python-wheels
...
OSError: Could not find a suitable TLS CA certificate bundle, invalid path: /etc/ssl/certs/ca-certificates.crt
...
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 145, in apport_excepthook
    os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o640), 'wb') as f:
FileNotFoundError: [Errno 2] No such file or directory: '/var/crash/_usr_bin_virtualenv.1000.crash'

The error message is not very clear. Problem is caused by ca-certificates and it could be fixed by command:

sudo update-ca-certificates

20. February 2017

How to send command from Python via MQTT to RGB LED connected to ESP8266

I’ve described how to send server load as a number to MQTT in the previous article. The number could be then translated via Node-RED to command for LampESP with RGB LED. The result is simple. LED indicates server load by displaying different colors.

The other option is to deliver color command directly from the server using Python.

Just install paho-mqtt:

pip install paho-mqtt

Here is small snippet of Python code (publish_server_load.py):

#!/usr/bin/env python3

import paho.mqtt.publish as publish
import os

color = 'red'
load = os.getloadavg()[0]
if load < 0.7:
    color = 'black'
elif load < 1.5:
    color = 'blue'
elif load < 3:
    color = 'green'
elif load < 7:
    color = 'orange'

publish.single('/server/monitoring/command', color, hostname='iot.sinusgear.com')

ESP should listen to /server/monitoring. Code of LampESP 0.3 is available at GitHub.

Put this code into crontab

* * * * * /usr/local/bin/publish_server_load.py

If you’re using virtualenv the command should be:

* * * * * /opt/my-python-env3/bin/python /usr/local/bin/publish_server_load.py

24. May 2015

How to revert no-site-packages for virtualenv on Windows with Python 3.4

Python has support for virtual environment. It’s very handy to set up isolated space where you can store specific packages for the project. You can use command virtualenv to create virtual environment.

It’s very common to add option --no-site-packages which will isolate environment from packages installed in system.

Sometimes it is necessary to revert this option.

Linux and Mac users can control it by mechanism based on one file:

venv/lib/python3.4/no-global-site-packages.txt

When this file exists Python is ignoring packages from system.

In case of Windows there is configuration file stored in venv/pyenv.cfg and you can change configuration of global packages:

home = c:\Python34
include-system-site-packages = true
version = 3.4.3

Change the configuration and call Scripts\Activate.ps1 to load Python virtualenv to PowerShell.

23. May 2015

Flask OAuthlib Multiple Scope Values for calling Google API

Google provides myriad of APIs for invoking operations on Google App Platform. It’s possible to integrate this calls with custom app using OAuth.

One option is to write app based on Flask (Python Microframework) with OAuth support provided by Flask-OAuthlib.

There is simple example of web app in Lepture’s repo.

The key practice in OAuth world is to get user’s consent to access API on her/his behalf. Often implemented by simple consent screen.

google-consent

You need to perform two steps to display consent screen:

  • enable API in Developer Console
  • define scope in your application

The second step is straightdorward:

google = oauth.remote_app(
    'google',
    ...
    request_token_params={
        'scope': 'https://www.googleapis.com/auth/userinfo.email'
    },
    ...
)

It works perfectly. The only problem is that this solution provides access just to one API.

The question is: How to request access to multiple scopes?

You can find many hints about OAtuh for other frameworks, that you should separate scopes by comma. That won’t work.

Correct solution is to use white space as delimiter of scopes (as suggested for HTML forms).

google = oauth.remote_app(
    'google',
    ...
    request_token_params={
        'scope': 'https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/calendar.readonly https://www.googleapis.com/auth/tasks'
    },
    ...
)