PIP Environment variables

Een eenvoudige tip die goud waard is: bij Pip kan je iedere optie vervangen door een environment variable van de vorm PIP_OPTIE (bv. PIP_TRUSTED_HOST). Superhandig bij het bouwen van images op OpenShift!

Environment variables in wsgi-applicaties

Soms heb je een environment variable nodig in een wsgi-applicatie, zoals bijvoorbeeld LD_LIBRARY_PATH omdat een bepaalde C-bibliotheek niet beschikbaar is.

De normale manier om dat te doen is via mod_env en SetEnv in de VirtualHost-definitie, maar voor wsgi-applicaties werkt dat niet, omdat die gestart worden voor de eerste request. SetEnv wordt enkel uitgevoerd bij de eerste request naar een site.

Je moet die variables meegeven aan het apache (httpd)-proces zelf, met dien verstande dat ze dan voor alle websites en webapplicaties beschikbaar zijn (wat misschien niet de bedoeling is). Op Ubuntu-gebaseerde systemen moet dat in /etc/apache2/envvars, op RedHat-gebaseerde systemen gebruiken /etc/sysconfig/httpd:

LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/opt/apa/lib"

Een procesherstart later zou de variable moeten beschikbaar zijn.

ObjectId & PyMongo

Het is een beetje weggestopt in de documentatie, maar het staat er gelukkig wel in. Wanneer je een document uit een mongodatabase wil halen op basis van zijn _id, dan moet je dat id eerst omzetten naar een ObjectId, anders krijg je onbegrijpelijke “Document not found“-foutmeldingen.

Alweer een uur gespaard!

WSGIPassAuthorization

Een RESTful API die niet helemaal publiek mag zijn is meestal beveiligd met een variant van HTTP Basic Authentication. Daar is natuurlijk niets mis mee, want het is veruit de eenvoudigste manier voor een API-consument om zich te identificeren.

Maar onlangs stootte ik toch op een caveat emptor: wanneer je een API in Python (bv. Flask) via mod_wsgi beschikbaar stelt, dan werkt het plots niet meer om met Basic Authentication aan te melden. Mysterie, mysterie, zeker omdat het in de ontwikkelomgeving wel werkte.

Na lang (~ 1/2e dag) zoeken bleek mod_wsgi de schuldige (en mijn gebrekkige lectuur van de handleiding, want het is gedocumenteerd). In een standaardopstelling worden de authorization headers immers onderschept door Apache, die zelf de authenticatie wil uitvoeren. Uiteraard wist ik dat niet, en had Apache ook niet zo geconfigureerd. En dus stond ik voor het mysterie van de missende header.

Maar via wat google-fu en een blogpost kwam ik dan toch op de oplossing. In de vhost (of elders, al naargelang) waar je de wsgi-applicatie hebt geconfigureerd moet je de instelling WSGIPassAuthorization op On zetten (en dan de webserver herstarten, dat spreekt).

WSGIPassAuthorization On

En hoera! De authenticatie werkt! Op naar het volgende probleem!

RPM’s van Python-libraries

Het is niet zo moeilijk als het lijkt. Tenminste, wanneer je setup.py gebruikt, wat de nieuwe (Python 2.7+, dus niet meer zo nieuw) manier is om Pythonpackages te maken. setup.py bevat een call naar de setup-functie, wat een deel is van setuptools.

Hoe je zo’n functie opbouwt kan je in de documentatie vinden, of in de fantastische Python packaging tutorial. Met setup.py kan je de package installeren, maar om te delen met vrienden (die toevallig een RPM-distro gebruiken), kan je ook een echte OS-package maken.

python setup.py bdist_rpm

Je kan eventueel nog extra opties toevoegen, zoals dependencies (–requires) of een specifieke release tag (de RPM-versie, bv. -1) (–release). Zo wordt het heel simpel om een repository op te bouwen van extra, custom, libraries die je zelf hebt gefabriceerd en gebruikt voor jouw projecten. Ook applicaties kan je zo verspreiden.