Wir leben in einer schnellen Zeit. Nicht nur schaut man sich heute scrollend Videos im 2-10 Sekundentakt an, was die Aufmerksamkeitsspannweite vieler Menschen künftig weiter spürbar senken dürfte. Auch in der IT schiessen neue Produkte und Funktionen wie Pilze aus dem Boden. So hat bspw. Google an der diesjährigen Next-Konferenz nach eigenen Angaben 218 Ankündigungen gemacht. Das entspricht fast einer pro Arbeitstag im Jahr.
Dabei darf man nicht vergessen, dass die Entwicklungszeit von neuen Produkten und Funktionen, von der Idee bis zum Rollout, auch heut zu Tage durchaus etwas länger dauern kann.
Ich freue mich, heute mein jüngstes Open-Source-Projekt vorstellen zu können. Die Freude kommt dabei natürlich auch wegen dem Inhalt der Lösung. Aber nicht nur. Es ist der vorläufige Abschluss einer gut 3-jährigen Reise. Schaut man sich den Source-Code an ist man versucht zu denken, gut - dafür braucht aber niemand 3 Jahre. So gesehen stimmt das natürlich. Bevor ich die Story zu den 3 Jahren erzähle, möchte ich Papys kurz vorstellen.
Rest-API as a DAG
API und insb. Rest-API sind allgegenwärtig und es gibt für fast alle gängigen Programmiersprachen irgendwelche Frameworks, mit denen sich mehr oder eben weniger einfach solche API implementieren lassen. Der theoretische Hintergrund von Papys ist, dass solche Rest-API als sog. DAG, also (azyklische) Graphen (DAG = Directed Acyclic Graph) implementiert werden. Dies hat verschiedene Vorteile:
- Der Code ist übersichtlich und der "Weg" den eine Anfrage durchläuft, ist direkt sichtbar.
- Der Code lässt sich bei Bedarf auch mit verhältnismässig wenig Aufwand übersichtlich grafisch darstellen.
- Einzelne Graphen können kombiniert und vor allem auch wiederverwendet werden.
Eine einfache "Hello world!"-Anweisung lässt sich mit Papys wie folgt formulieren:
![]() |
Abb.1: "Hello world!" mit Papys |
Damit lassen sich in kurzer Zeit gut wartbare Rest-API in Python entwickeln.
Detaillierte Informationen mit Instruktion und Beispiel-Applikation gibt es auf der Projekt-Website: https://papys.asderix.com/
Den Soruce-Code findet man bei Github: https://github.com/asderix/Papys
Und installieren lässt es sich einfach via PyPi: https://pypi.org/project/papys/
Und für was 3 Jahre?
Zurück zur langen Dauer. Ich habe in der Vergangenheit mit verschiedenen Frameworks in verschiedenen Sprachen verschiedene API implementiert. Scala, JavaScript, C#; Play, Akka, Express, Fastify, um ein paar zu nennen. Obwohl es für mich besser geeignete und weniger gut geeignete gab, empfand ich es mit allen irgendwie nicht ganz zufriedenstellend. Da ist der Lern- und Implementierungsaufwand, aber dann vor allem auch die Übersicht und Wartbarkeit, die mich nicht ganz zufrieden stellte.
Ich lernte wie wichtig gutes API-Design ist. Gedacht aus Sicht eines Entwicklers, für spezifische Use Cases optimiert. Nicht zuletzt durch meine Arbeit in der ersten API Arbeitsgruppe vom SFTI, als wir die ersten API-Spezifikationen erstellten. Ebenso lernte ich auch, wie wichtig eine nachhaltige Implementierung ist. Wer mich etwas kennt ahnt, dass ich wenig von generierten Boilerplate Implementationen halte. OpenAPI-Spezifikation zu Code Generatoren - kann man machen. Muss man aber definitiv nicht. Man verfolgt eine API first Strategie und die eigentliche Implementierung überlässt man einem Generator? Nicht mein Ding.
Und so kam der Wunsch in mir auf, die Implementierung von Rest-API zu vereinfachen. Und zwar so, dass man sich als Entwickler auf das Wesentliche, nämlich die Implementierung der Business-Logik, fokussieren kann. Und den Ablauf der Anfrage auf eine natürliche Art und Weise modellieren kann. Den genauen Zeitpunkt, wann ich mit ersten konkreten Überlegungen und Skizzen angefangen habe, weiss ich nicht mehr. Es ist aber gut 3 Jahre her.
Dabei stand ich immer wieder an. Verwarf die Idee und legte sie bei Seite. Später kam mir eine neue Idee, oder eine alte hatte sich wieder bei mir mit Hoffnung gemeldet. Dazwischen lagen manchmal Wochen, manchmal Monate. Der iterative Prozess gestaltete sich dabei so, dass ich zwar eine Technologie neutrale Lösung definieren wollte. Aber erstens wusste, dass sie irgendwann mit Technologie umgesetzt werden muss und zweitens ertappte ich mich immer wieder dabei, dass mein Denken von den Möglichkeiten bestimmter Sprachen - zuerst unbewusst - beeinflusst wurde. Als sich in mir der Ansatz von DAG manifestiert hatte, kam das nächste iterative Problem: Überlege ich mir zuerst, wie es implementiert wird, oder wie es ein Entwickler dann anwenden kann? Ich entschied mich für die Anwenderseite. Stellte dann aber nach 2-3 Iterationen von Versuchen fest, dass ich einen Schritt zurück machen muss. Immer noch grundsätzlich aus der Optik eines Anwenders (Entwicklers), aber zuerst mit gängigen, mir bekannten Sprachelementen. Ich bemerkte, dass man mit für diesen zweck neu implementierten Sprachelementen die Anwendung deutlich vereinfachen und vor allem besser lesbar machen konnte. Ich war aber zunächst damit überfordert, die grundsätzliche Art und Weise der Definition zu spezifizieren und dies gleichzeitig mit neuen Sprachelementen. Also machte ich eine Definition mit mir bekannten Elementen, die funktionierte aber noch nicht schön war. Und ging im Anschluss auf den Weg, diese Definition mit neuen Sprachelementen für diesen Zweck zu optimieren. Das alles passierte zu einem grossen Teil auf A4-Blättern mit Minenbleistift.
![]() |
Eine der Notizen |
Vielleicht ist jetzt besser nachvollziehbar, weshalb es gut 3 Jahre dauerte. Zudem war ich ja nur ab und zu damit beschäftigt. Auf der Zeitachse waren es aber insgesamt wohl um die 90 % in Gedanken und Papier, nichts mit Programmieren. Von der aufgewendeten Zeit, gehen geschätzt nur rund 20 bis 30 % auf das Konto Programmieren.
Dieser Gedanke musste einfach reif werden. Kein 10-Sekunden Video. Beharrlich, immer wieder neu denken und neue Erkenntnisse aus verwandten und auch weniger verwandten Themen mit einfliessen lassen. Für mich ist es eine Form der Kreativität, welche am Schluss mit echtem Handwerk der Programmierung in unsere Realität umgesetzt wird. Wird Papys je von jemandem (anderen) genutzt werden? Ich weiss es nicht. Aber auch das gehört für mich zur Kreativität. Der Künstler erstellt das Kunstwerk nicht der Nutzung willen. Der Mensch braucht Raum um Gedanken formen und verdichten zu können. Um sich Dinge vorzustellen und Teil seiner gelebten Realität werden zu lassen - schöpferisch tätig zu sein. Unabhängig von (rein) wirtschaftlichen Interessen.
Warum Python?
Ich war gedanklich lange bei anderen Sprachen, insbesondere JavaScript und Scala. Bei JavaScript gelang ich irgendwann zur Kenntnis, dass die fehlende Möglichkeit, Operatoren zu überschreiben, eine zu starke Einschränkung für mein Vorhaben darstellt. Scala bietet dazu alles was man braucht. Ich war aber hin- und hergerissen betreffend die starke Typisierung. Ist es für meinen Kontext eine Stärke, oder eher ein Nachteil (starke Typisierung möchte ich nicht als Schwäche bezeichnen)? Dazu kommt, dass man mit dem JVM-Stack zwar ein riesiges Ökosystem von Bibliotheken für die Implementierung der Business-Logik hat, aber fast niemand Scala dafür nutzt. Die Sprachvorteile einer Domäne spezifischen Sprache (DSL) verliert man, wenn man eine Scala-Bibliothek in Java nutzt. Der Vorteil für die meisten Entwickler wäre nicht gegeben. Deshalb habe ich mich gegen Scala für dieses Vorhaben entschieden und in Python die optimale Sprache für meine Anforderungen gefunden. Sie lässt eine DSL zu und ist auch sonst sehr übersichtlich und hat ein riesige Ökosystem an Bibliotheken. Wie immer ist es hilfreich, wenn man einen vielfältigen Werkzeugkasten hat. Mit nur einem Hammer sieht bekanntlich jedes Problem wie ein Nagel aus.