WhosWhoPy

From A-Eskwiki
Revision as of 23:40, 13 March 2019 by Timb (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

WhosWhoPy is bedoeld als equivalent van WhosWho4, maar dan in Python. Het is oorspronkelijk gebouwd voor databasemigraties.

Aan de slag met Python

WhosWhoPy vereist een redelijk recente editie van Python 3 en pip. Als je manage build uitvoert, worden de rest van de benodigdheden geïnstalleerd in een virtuele omgeving. Het idee van deze virtuele omgeving is dat we hierin al onze dependencies installeren zonder dat dit systeembreed is of conflicten geeft met projecten met andere dependencies. Het volgende is dus belangrijk: voordat je een python-commando uitvoert, run source venv/bin/activate in de debugrootdir. (Alle pythoncommando's gaan ervan uit dat dit gebeurd is, en je in de debugrootdir zit.)

Zie ook WhosWhoPy op een webcie-vm.

Architectuur

WhosWhoPy heeft als kern een hoop modelklassen (de (klein)kindklassen van Entiteit) die gegenereerd worden op basis van een klassediagram. Daarnaast hebben we wat hulpfuncties om de klassen op elkaar te laten werken, en een paar scripts die die hulpfuncties aanroepen. Specifiekere onderdelen worden hieronder toegelicht.

whoswhopy.app

Zet de Flask-app op die de uiteindelijke pagina's produceert. Maakt gebruik van de andere modules om dit voor elkaar te krijgen.

whoswhopy.auth

Authorisatie werkt op basis van de Auth-klasse, die bijhoudt welke db-user wordt gebruikt voor de huidige request, en die bepaalt welke rechten (waarden in de enum AuthRecht) de huidige gebruiker heeft.

Een waarde in AuthRecht staat voor een extra privilege bovenop wat een niet-ingelogde gast mag doen. Merk op dat we dus in de Auth-klasse bepalen welk recht bij welke soort user hoort, in tegenstelling tot de PHP-architectuur waar we voor het aanroepen van de Auth-klasse al bepalen of het gaat om tbc/vakidioot/spocie/etc.-rechten.

whoswhopy.config

Module om configuratiewaarden uit te lezen. Bij het importeren van deze module worden de configuratiewaarden ingelezen. Er zijn generieke functies geef en geef_verplicht voor stringvormige configuratiewaarden, en waardespecifieke functies zoals debug die waarden parsen en andere types geven (zoals hier een bool).

whoswhopy.database

Module om databaseverbinding te maken. Bij het importeren wordt deze verbinding gemaakt en in de variabele wsw4db (van type sqlalchemy.Session) gezet.

whoswhopy.gen

Bevat de gegenereerde code van dia2py, zie verderop.

whoswhopy.php

Verscheidene modules om integratie met PHP in het algemeen, en Space/WhosWho4 in het bijzonder, mogelijk te maken. Aan de basis ligt whoswhopy.php.vreemde_functie, die een wrapper geeft om PHP-functies, zodat ze vanuit Python aangeroepen kunnen worden.

Hoe requests werken

Als een request naar WhosWhoPy binnenkomt in Apache, gebeuren er een paar dingen.

Ten eerste geeft Apache door middel van mod_wsgi de request door aan de Flask-applicatie. Flask zorgt voor routing, die je bijvoorbeeld ziet als @app.route('/dingweb/een/of/ander/bestand') in whoswhopy.app. In het normale geval komt de route uit bij een Pythonfunctie die gewoon werkt als een normale Flask-endpoint. Misschien is er nog iets nodig als een databaseverbinding, wat we doen door middel van een decorator die de WhosWhoPy-klasse ondersteunt.

In een iets ingewikkelder geval, moeten we gebruik maken van oude PHP-code om de request af te handelen. Dit is qua programmeren niet veel anders dan een normale request, alleen wordt er een whoswhopy.php.vreemde_functie.VreemdeFunctie aangeroepen, en daarvoor dus snel een PHP-proces opgestart om de functie af te handelen.

Als we de hele endpoint nog in PHP hebben staan, wordt de whoswhopy.php.entry.Entry-klasse gebruikt. Die zorgt ervoor dat PHP in CGI-modus wordt opgestart en een gegeven functie de request afhandelt. Het resultaat, de response, wordt dan letterlijk doorgegeven. In feite werkt Python dan als een soort webserver die een CGI-script aanroept.

Als de endpoint niet in Python gedefinieerd is, gebruiken we de fallback: deze werkt net als de PHP-entry door middel van CGI maar gooit de hele request, inclusief URL, door Benamite. Vervolgens wordt weer de bijbehorende functie aangeroepen en de response doorgestuurd.

Codestijl

We houden de canonieke stijl van PEP-8 aan, dus indentatie is 4 spaties en geen alignment alsjeblieft dankjewel.

Programmeertools

Voor codekwaliteit hebben we ook wat tools:

  • pytest en [hypothesis https://virtualenv.pypa.io/en/stable/]: een fijn unittestframework en volautomatische testcasegeneratie. Je kan pytest aanroepen in de debugrootdir om tests te runnen.
  • pylint om je te wijzen op code smells/lelijke codestijl (moet misschien nog een beetje getweakt worden).

Generated code

Zie ook: Dia en generated code.

Het script dia2py zet een gegeven klassediagram, in de vorm van een .dia-bestand, om in Pythonklassen. Je kan de resulterende klassen importeren als from whoswhopy.gen.Bla import Bla (of from whoswhopy.gen.Intro.Bla import Bla als de code in een package zit). Deze klassen zijn SQLAlchemy ORM-gebaseerde klassen, en je kan ermee werken zoals je van SQLAlchemy gewend bent.

Mocht je alle klassen willen gebruiken, dan kun je doen import whoswhopy.gen.alles as alles. Deze functionaliteit is bijvoorbeeld nodig om alle klassen aan de migratiegenerator door te geven.

Reloaden na wijzigingen

Apache herstart de daemon, en past dus eventuele wijzigingen toe, zodra je de modificatietijd van whoswhopy.wsgi aanpast. Oftewel je kan je wijzigingen op je debug toepassen door te doen: touch whoswhopy.wsgi. Zie ook https://modwsgi.readthedocs.io/en/develop/user-guides/reloading-source-code.html