Mark Moes

  • 04/06/2019
  • 4 minuten leestijd
Avatar

Conferentie: Pygrunn 2019

De reis naar Groningen betekende vroeg opstaan, en met een aantal autos en een enkele trein vertrok de Python groep naar het Groninger Forum. Dit culturele centrum is al diverse jaren de thuisbasis van de grootste Python conferentie van Nederland. Het was een stralende dag en het programma zag er veelbelovend uit, iedereen had er zin in!

Flask Monitoring Dashboard

Patrick Vogel en Bogdan Petre vertelden over een oplossing die ze gemaakt hebben om Flask APIs te monitoren. In essentie worden alle application routes van Flask gepatched, waardoor diverse soorten metrics kunnen worden bijgehouden. Deze worden weggeschreven naar een database en op diverse manieren inzichtelijk gemaakt door middel van een dashboard.

Per Flask endpoint kunnen verschillende monitorings niveaus worden ingesteld. Het eerste is “performance and utilization” waarbij duur, tijdstip, Flask versie en IP adres worden opgeslagen, alsook de waarde van een functie die je zelf schrijft, bijvoorbeeld om de user id terug te geven. Een niveau daarboven is “profiling”, hiermee wordt inzichtelijk welke code in een endpoint de meeste tijd kost. De overhead wordt beperkt door een extra thread te spawnen om hiermee statistical profiling (sampling op basis van stacktraces) op het Main thread toe te passen.

Tot slot is er een “outliers” niveau dat, naast de voorgenoemde metrics, request context (headers, values, cpu, ram) bewaart voor requests die langer duren dan een bepaalde drempel. Zoals hun eigen benchmark aantoonde kan dit tot 20% overhead op requests betekenen wanneer er veel data wordt verstuurd. Voor productie systemen raadden ze daarom ook aan de minder intensieve niveaus te gebruiken.

De tool lijkt goed in elkaar zitten, en het toepassen is erg simpel. Er is ruimte voor verbetering, bijvoorbeeld een optie om een percentage van de requests te monitoren. (zie django-silk) Daarnaast is overhead van de profiling en outlier methode aanzienlijk, maar doorgaans trek je die pas uit de kast als er iets aan de hand is. Ik zal de library zeker eens uitproberen, om te zien wat de meerwaarde is ten opzichte van bijvoorbeeld prometheus_client.

Scalable and secure Python REST backends

De talk door Gerard Lutterop behandelde een REST API framework dat hij met een team heeft ontwikkeld. Uitgangspunten waren database en webframework onafhankelijk te zijn, het niet hoeven schrijven van database migraties, en geen libraries te gebruiken die teveel “magie” doen. Toevoegen van nieuwe REST endpoints moest daarbij mogelijk zijn zonder database schema aanpassingen.

Het ontworpen framework vormt een abstractielaag tussen een Postgresql database en Flask API. Aan de basis staat RAML, een op YAML gebaseerde definitie voor RESTful APIs. dat door het framework wordt geïnterpreteerd en omgezet naar rows in de database. Inderdaad, er worden geen tabellen gemaakt, want daar zijn er altijd exact 3 van: items, relations en mappings. De items tabel heeft een uuid kolom en daarnaast generieke kolommen voor alle mogelijke datatypes, met namen als bijvoorbeeld int11, string7 of json3. De relations tabel bevat alle mogelijke foreign-key relaties tussen items. Tot slot legt de mappings tabel, als ik het goed interpreteerde, de link tussen properties van een resource en de juiste kolom in items. Van een voorbeeld RAML schema, dat 5 resources Person, Student, Teacher, Class, Course definieerde met elk 2-3 properties, werd verteld dat de applicatie 30 seconden nodig heeft om deze te verwerken en de database op de juiste manier in te richten.

Er rezen bij ons na afloop van de talk diverse vragen. Hoe presteert dit framework bij een stuk groter aantal resources en properties? Wat gebeurt er met performance van SELECT queries bij een serieuze hoeveelheid items, aangezien de database geen zinnige indexes kan maken? Al met al een bijzondere aanpak, waarvan we ons ten zeerste afvroegen of het een betere oplossing is dan een ORM. Schema migraties zijn hiermee dan wel verleden tijd, maar tegen welke prijs?

Lessons from using GraphQL in production

Niek Hoekstra en Jean-Paul van Oosten deelden hun ervaringen in het gebruik van GraphQL. Het selectief kunnen queryen van informatie was een belangrijke factor om hun API zo op te bouwen in plaats van een traditionele REST API. Groot voordeel van GraphQL is dat je feitelijk nog maar 1 endpoint hebt die dynamische queries mogelijk maakt, waardoor de caller precies kan opvragen wat hij nodig heeft. Deze queries dienen in de backend te worden afgebakend met Graphene, wat ervoor zorgt dat de API volledig self-documenting is. Niek en Jean-Paul gebruiken de Graphene-Django integratie, maar er zijn ook libraries voor SQLAlchemy of Google AppEngine.

Natuurlijk zijn er ook nadelen. Zo vertelden ze dat het lastig kan zijn om efficiënte Django queries uit te voeren wanneer je foreign-key relaties exposed. En als je daar toch mee bezig bent, let dan ook op recursieve queries:

query { contacts { address { contacts { address { ...

Mits met het correcte aantal haakjes afgesloten is dit een geldige GraphQL query die je zult moeten afvangen in je validatie. Gebeurt dit niet, dan wordt voor elk niveau een database query uitgevoerd, met alle gevolgen van dien.

Hun frontend was gebouwd in ReactJS, dat door middel van Relay efficiënt kan integreren met GraphQL als backend. Daar kwam een ander nadeel aan het licht: file uploads worden niet ondersteund. Dit losten ze op met een speciaal endpoint dat de upload verwerkt en een id returnt in base64, om compliant te zijn met Relay. (base64.b64encode(b"Node:1") # b'Tm9kZTox')

Het eindoordeel luidde: GraphQL is geen silver bullet, het heeft zijn tekortkomingen, en om het toe te passen in een API vereist wat geduld om het schema goed en veilig te configureren. Maar desondanks:

developing