De uitrol

Ik heb mijn tools altijd zitten maken binnen de omgeving die mijn OS me biedt. Dat betekent dat ik altijd de Python versie van mijn systeem gebruik en eigenlijk alleen met packages werk die de package manager beschikbaar heeft.

Mijn programma's installeer je dan ook niet, zoals ze gemaakt zijn zijn ze als het ware al geïnstalleerd.

Ik heb dat gedoe met virtual envs altijd wat links laten liggen omdat het me ingewikkeld en voor mijn doeleinden niet nodig leek (en dat laatste was ook zo).

Maar onlangs had ik een paar zaken waarvoor ik geen door mijn Linux distributie gepackagede versie kon krijgen waardoor ik ze met pip moest installeren en dat kun je toch beter in een venv doen. En het inrichten daarvan en het installeren van een package daarin bleek nog wel mee te vallen ook. Ik draai nu Trac (mijn ticket systeem) in een venv en pdb++ (een uitbreiding op de ingebouwde python debugger) blijkt ook vanuit een venv te werken dankzij wat trucerij die misschien niet helemaal "officieel" is (vergelijkbaar met hoe ik mijn css editor kan gebruiken vanuit mijn html editor).

Mijn eigen producten zo maken dat ze geïnstalleerd kunnen worden gaat me echter nog steeds een paar bruggen te ver denk ik - ik heb in elk geval nog steeds niet de behoefte om dat eens rustig uit te gaan zoeken. Dat komt ook doordat ik niet (meer) verder wil gaan dan ze voor mezelf werkend te laten zijn en dat zijn ze.

Over packaging tools

Een van de problemen die packaging tools willen oplossen is als ik het goed gelezen heb, dat je een applicatie of een library vanaf elke plaats in je systeem kunt opstarten of gebruiken. Toen ik begon met Python had je daar eigenlijk alleen maar de directory "site_packages" in de Python omgeving waar je iets kon vinden dat niet onder de directory waar je script in zat. Dat is eigenlijk nog steeds zo maar eigenlijk hoor je hier niet mee te prutsen want zeker op Linux is je systeeminfrastructuur afhankelijk van wat hier in staat. Daarom zijn er allerlei manieren gezocht en gevonden om dit niet te hoeven doen. De manier die ik er zelf voor gevonden heb is om eigenlijk alleen maar spullen te gebruiken die mijn systeem zelf ook gebruikt, of gegarandeerd helemaal niet gebruikt.

Doorgaans heb ik een opstartscript in de root van de projectdirectory en maak ik een symlink naar dat script in een eigen directory die in het uitvoeringspad van de shell zit. Het packaging tool maakt waarschijnlijk gebruik van een locatie die standaard gedefinieerd is, en maakt het aanmaken van dat script onderdeel van het packaging proces. Mijn aanpak doet dat niet en ik vraag me af en toe af of dat niet een goede reden is om toch te gaan packagen. Aan de andere kant hou ik liever zelf de controle over hoe ik zoiets oplos...

Een ander aandachtspunt bij het packagen is dependency management. Het is mogelijk verschillende versies van Python naast elkaar op je computer te hebben en je programma moet weten welke versie er gebruikt moet worden. Persoonlijk heb ik dit altijd omzeild door er van uit te gaan dat er een zekere versie bestaat die door het OS gebruikt wordt (en in mijn Windows tijd: die ik zelf erop gezet heb) en dat mijn Python programma's die ook allemaal gebruiken.

Het wordt pas ingewikkeld als je programma's third-party libraries gebruiken die mogelijk afhankelijk zijn van andere versies van weer andere libraries dan die die je systeem gebruikt. Ook dat omzeil ik door alles dat mijn programma's gebruiken de libraries te laten zijn die mijn systeem ook gebruikt. Tot nu toe heeft dit me nog geen problemen opgeleverd en dus voel ik zo niet de noodzaak voor het me onafhankelijk te maken van wat er toevallig op het systeem beschikbaar is. Een enkele keer betekende dat iets binnenhalen dat mijn systeem nog niet gebruikt en in dat geval kijk ik altijd of het beschikbaar is in de packages die mijn distro levert, vanuit de gedachte dat de package managers de dependencies hebben uitgezocht. Als ik dan tijdens het installeren een waarschuwing krijg kan ik altijd nog bedenken wat te doen en ook daar heb ik nog geen issues door gehad voor zover ik me herinner. Een aardige bijkomstigheid is dat bijvoorbeeld PyQt5 en PyQt6, die beide door zowel mijn systeem als door mijzelf worden gebruikt, naast elkaar kunnen bestaan.

Terug naar venvs

Laat ik nu een ticket registratie systeem - applicatie waarmee je foutrapporten en wijzigingssuggesties kunt vastleggen en de voortgang erover bijhouden - gebruiken dat ik niet zelf gemaakt heb (al heb ik dat wel) en dat NIET (meer) door de Manjaro package manager gesupport wordt. Als ik zo'n applicatie op de aangeraden manier (met het tool pip) wil installeren krijg ik een melding dat dat niet zomaar kan omdat dat afhankelijkheden kan binnenhalen die mijn systeem (dat zelf ook Python gebruikt voor veel taken) kunnen verstoren. Ik kan dat wel omzeilen maar dan moet ik wel zeker weten dat ik dan kan en wil doen. Eerder kon ik in plaats daarvan nog een gepackagede versie downloaden uit een soort onofficiële repository maar daar kon ik na de laatste systeemupdate niet meer bij en hoe meer ik daar over lees hoe meer ik me afvraag of dat gebruiken wel zo'n goed idee is. Ik zag me nu toch voor de keuze gesteld alles weer om te vormen zodat mijn eigen ticketsysteem het kan gebruiken - wat ik eerder gedaan heb waarna ik merkte dat wat ik daarvoor gebruikte me toch beter beviel - of toch maar eens kijken of de aangeraden manier om een Python applicatie te gebruiken voor mij te doen was. Dat ging nog niet zover als een package manager uit het Python ecosysteem te installeren maar wel om een "virtuele omgeving" aan te maken waarin ik pip kan uitvoeren zonder gemopper van mijn systeem. Wat je in feite aangeeft is dat je vanuit een bepaalde directory werkt waarin de systeem-Python gebruikt kan worden samen met eventuele extra libraries die alleen voor die directory gelden. Het is eigenlijk een trucje dat je door moet krijgen: zorgen dat de manier van opstarten garandeert dat je in die omgeving bent en dat bleek makkelijker dan ik dacht. Daar zorgt namelijk de shebang (#! gevolgd door de naam en de locatie van de uitvoerende interpreter als eerste regel van het script) voor.

Ik heb nu zelfs één van mijn eigen applicaties op zo'n manier aan het werk: ik heb een Tkinter versie van mijn Stardew Valley mod manager gemaakt om op de SteamDeck te draaien (in Desktop mode is dat namelijk gewoon een Linux Box). Ik heb een virtual env gemaakt in de desktop root en daarbij aangegeven dat die gewoon de systeem python moet gebruiken; in de virtual env zit een subdirectory waarin de git repo van mijn applicatie zich bevindt; in de bin directory van de virtual env zit een script dat mijn applicatie opstart met een shebang naar de python van de virtual env; en dat script kan opgestart worden van een willekeurige locatie.