Docker har blivit det nya sättet att paketera och köra Python-skript, även när skripten körs från exempelvis ett cronjob. Men ibland behöver vi inte en hel Docker-miljö med den overhead det innebär för väldigt små skript. Då är det smidigare att göra om skriptet till en körbar binärfil. Då kan vi även enkelt flytta filen mellan olika Linuxsystem.

Python Bild: Oskar YildizUnsplash

För att skapa en binärfil av ett Python-projekt använder vi pyinstaller som går att installera via pip. Som exempelprojekt kommer vi här att använda samma Python-skript som vi använde i Pythonmiljö i Docker – men utan loopen.

Vi placerar alla filerna i en egen katalog så att vi kan installera en virtuell Pythonmiljö längre fram. Skapa en ny katalog och döp den till temperatur eller liknande.

Skriptet består av några få rader kod som hämtar aktuell lufttemperatur i Ängelholm från SMHIs öppna data. Skriptet, som vi döper till temperatur.py, ser ut som nedan:

import requests
import time
import datetime
url = "http://opendata-download-metobs.smhi.se/api/version/1.0/parameter/1/station/62180/period/latest-hour/data.json"

data = requests.get(url).json()
timestamp = data['updated'] / 1000 # SMHIs tidstämpel är i millisekunder
humandate = datetime.datetime.fromtimestamp(timestamp)
print("Temperatur i Ängelholm (" + str(humandate) + "):", data['value'][0]['value'] + "C")

Vi har också skapat en requirements.txt-fil med följande innehåll:

requests

Testkör skriptet i en Pythonmiljö

Vi börjar med att initialisera en Pythonmiljö och installera de moduler som krävs för att testköra skriptet:

$ pwd
/home/jake/temperatur
$ python3 -m venv env
$ source env/bin/activate
$ pip install -r requirmenets.txt
Collecting requests
  Downloading requests-2.31.0-py3-none-any.whl (62 kB)
     |████████████████████████████████| 62 kB 882 kB/s 
Collecting urllib3<3,>=1.21.1
  Downloading urllib3-2.0.2-py3-none-any.whl (123 kB)
     |████████████████████████████████| 123 kB 9.5 MB/s 
[...]
Successfully installed certifi-2023.5.7 charset-normalizer-3.1.0 idna-3.4
requests-2.31.0 urllib3-2.0.2

Nu kan vi testköra temperatur.py genom att starta det med python-tolkaren, precis som vi brukar göra.

$ python temperatur.py
Temperatur i Ängelholm (2023-06-03 14:00:00): 16.2C

Skapa en fristående binärfil

Nu när vi vet att skriptet fungerar som tänkt är det dags att skapa en fristående binär av det. Då kan vi enkelt placera binärfilen i exempelvis crontab. Vi kan också flytta filen mellan olika Linuxsystem, så länge det är samma processorarkitektur och samma libc-version. Det gör det enklare att distribuera skriptet till ett stort antal datorer, utan att behöva tänka på att sätta upp en virtuell Pythonmiljö och installera de nödvändiga modulerna på varje dator.

ANNONS FÖR VÅRA EGNA BÖCKER Demonerna på internet

Medan vi fortfarande är i den virtuella Pythonmiljö installerar vi pyinstaller.

$ pip install pyinstaller
Collecting pyinstaller
  Downloading pyinstaller-5.11.0-py3-none-manylinux2014_x86_64.whl (653 kB)
     |████████████████████████████████| 653 kB 4.4 MB/s
[...]
Successfully installed altgraph-0.17.3 pyinstaller-5.11.0
pyinstaller-hooks-contrib-2023.3

Nu kan vi skapa den körbara filen:

$ pyinstaller temperatur.py --onefile
73 INFO: PyInstaller: 5.11.0
73 INFO: Python: 3.9.2
75 INFO: Platform: Linux-6.1.0-0.deb11.5-amd64-x86_64-with-glibc2.31
[...]

Nu är programmet klart och finns under dist-katalogen.

$ cd dist
$ ls -l
total 6296
-rwxr-xr-x 1 jake jake 6446528 jun  3 15:13 temperatur
$ ./temperatur
Temperatur i Ängelholm (2023-06-03 14:00:00): 16.2C

Nu kan vi flytta filen till en annan dator om vi skulle vilja, så länge det är samma libc-version och arkitektur.

$ scp temperatur 192.168.0.5:temperatur
temperatur        100% 6295KB  84.7MB/s   00:00

$ ssh 192.168.0.5
$ ./temperatur
Temperatur i Ängelholm (2023-06-03 14:00:00): 16.2C
$ exit

Om programmet inte fungerar på ett annat system

Skulle programmet inte fungera på ett annat system kan vi kontrollera vilka bibliotek som det är länkat till och dess versioner. Det gör vi med ldd.

$ ldd temperatur
        linux-vdso.so.1 (0x00007ffff34fe000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f9976383000)
        libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f9976366000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f9976344000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f997617f000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f997638f000)

Det enklaste är att helt enkelt bygga om binärfilen med pyinstall på de system där den inte fungerar. Filen kommer då att fungera på alla liknande system med samma version av exempelvis libc.


Nyhetsbrev
Nyhetsuppdateringar från tidningen direkt till din inkorg, helt kostnadsfritt. Avsluta när du vill.

Kommentarer

Kommentarsfältet är modererat. Det innebär att alla kommentarer granskas av ansvarig utgivare före publicering.

Du väljer själv om du vill ange ditt riktiga namn, en pseudonym eller vara helt anonym. Ingen registrering behövs.