diff --git a/README.md b/README.md index 7046a1830d571ecaa95e455b2509044bd2e5db69..ec6eff0d211a012eb01cebc54cf696857962e4bb 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,276 @@ -# SAMSHub - -Die SAMSHub Klasse ermöglicht es einen Modularen Anwendungsserver zu schreiben. -Die Klasse sätzt für Module ein einheitlich definiertes Format voraus und erlaubt -das dynamische einladen von Modulen auf basis einer Konfigurationsdatei. - -## Projektlayout - -Das Layout eines SAMSHub Projektes sieht im Wesendlichen wie folgt aus- - -- Project_Dir/ - - \_\_init\_\_.py - - views.py - - modules/ - - hallo_modul/ - - \_\_init\_\_.py - - manifest.yaml - - languages/ - - templates/ - - hallo_modul/ - - hallo_modul.html - - sub_view.html - - static/ - - templates/ - - static/ +# sams_classes + +Dieses Python3 Modul stellt die Grundlage für die Implementierung von +Applicationservern in der Selve-/ Administravie-Microservice-Structure dar. +Das Künftige MIPortal, ZID und andere Anwendungen sollen diese Klassen verwenden +verwenden können. + +## Klassen + +Derzeit enthält die Bibliothek drei Klassen + +- SAMSHub +- SAMApp +- SAMSProxy + +### SAMSHub + +SAMSHub stellt eine gewöhnliche flask App bereit, die alle grundsätzlich +für die Konkreten Server immer benötigten Eigenschaften mitbringt. +die Flask App besitzt bereits einen context_processor um Sprach-Dictionaries +der Apps und Menüeinträge den jeweiligen Termplates verfügbar zu machen. +Der SAMSHub folgt dem Designprinzip 'Komposition über Vererbung'. Dadurch lassen +sich das gesamte Wissen über Flask und alle möglichkeiten von Flask auch auf die +vom SAMSHub bereitgestellte flaskApp anwenden. Der SAMSHub erledigt lediglich +einige Aufgaben die so bei allen Zukünftigen Anwendungen anfallen werden. + +#### Methoden + +##### Konstruktor + +```python +hub = SAMSHub(name=__name__, config = {'default_language': 'de'}) +``` +Pflichtparameter sind name und config. Das Konfigurationsdictionary muss +eine angabe tur 'default_language' beinhalten. + +##### addApp + +```python +hub.addApp(app=samsApp) +``` +Die Methode fügt dem hub eine SAMSApp hinzu. Es muss sich bei app um eine +Instanz von SAMSApp handeln. Der Name der app (app.name) wird als name für +die Ansprache mit hub.app(name) verwendet. + +##### app + +```python +samsApp = hub.app(name) +``` +Die Methode gibt die SAMSApp mit dem betreffenden Namen zurück. + +##### menu + +```python +menu = hub.menu(langCode = 'de') +``` +Gibt eine Liste mit allen Menüeinträgen aller hinzugefügter Apps in der +geforderten Sprache zurück. Falls die sprache bei einigen Einträgen +nicht verfügbar ist wird die default Sprache der App verwendet. +Die Reihenfolge der Einträge wird durch die reihenfolge, in der die Apps +hinzugefügt wurden, bestimmt. + +#### Eigenschaften + +##### appKeys + +```python +for key in hub.appKeys: + print(key + '\n') +``` +Die Methode gibt eine Liste der keys aller dem hub hinzugefügten apps aus. +Über einen Key lässt sich mit ```hub.app(key)``` die jeweilige app Instanz +zurückgeben. + +##### flaskApp + +```python +hub.flaskApp.run() +``` +Mit flaskApp lässt sich die vom hub erzeugte flask App zurückgeben und z.B. +dann über run starten. Für die flask App kann die flask Dokumentation zu Rate +gezogen werden. + +### SAMSApp + +Die SAMSApstellt ein flask blueprint mit zusätzlichen Vereinfachungen für eine +verwendung mit SAMSHub bereit. +Die SAMSApp erleichtert das bereitstellen von sprachspezifischen Variablen +oder einer mehrsprachigen Liste von Menüeinträgen. + +#### Methoden + +##### Konstruktor + +Minimalistischste App: +```python +app = SAMSApp(name = 'appname', manifest = {'default_language': 'en'} + , langDict = {'en':{}}) +``` +Eine SAMSApp benötigt name (name des python packages oder moduls der app), +langDict und manifest. Das Dictionary vom manifest muss eine default_language +definieren, die im langDict enthalten ist. +Eine derart definierte App beinhaltet keine views und keinen Proxy, macht also +relativ wenig Sinn. +In der Regel wird eine SAMSApp eher so aussehen: +```python +app = SAMSApp( + manifest = { + 'default_language': 'en', + 'views': [{'url': 'test/do_nothing', 'function': 'views.do_nothing'}], + 'menu':[ + {'url': '', + 'name_string': menu_main}, + {'url': 'topic', 'name_string': 'menu_topic', + 'menu':[ + {'url': 'topic/subtopic01', + 'name_string': 'menu_topic_subtopic01'}, + {'url': 'topic/subtopic02', + 'name_string': 'menu_topic_subtopic02'} + ] + } + ] + }, name = 'test.app', + langDict={'en': {'menu_main': 'Home', 'menu_topic': 'Topic', + 'menu_topic_subtopic01': 'Subtopic 01', + 'menu_topic_subtopic02': 'Subtopic 02'}, + 'de':{'menu_main': 'Startseite'} + } +) +``` + +##### lang + +```python +langDict = app.lang(langCode = 'de') +``` + +Gibt ein Dictionary für die angeforderte Sprache zurück. Sind Einträge im default +dictionary und nicht in der Angeforderten Sprache vorhanden, werden diese verwendet. + +##### menu + +```python +# mandatory +menuEntries = SAMSApp.menu(langCode = 'de') +# optional +menuEntries = SAMSApp.menu(langCode = 'de', urlPrefix = '/app/') +``` +Gibt eine Liste von Menüeinträgen zurück. Jeder Eintrag ist ein Dictionary. +Dieses Dictionary enthält immer 'url' und 'name' und kann außerdem wieder +über 'menu' ein Menü enthalten. Der Anzeigename ('name') ist entweder der zu +langCode passende oder der, der defaultSprache. + +#### Eigenschaften + +##### module + +Das zur App gehörende python Modul. Führt zu einer Exception falls das +Modul nicht geladen werden kann, + +##### name + +Der Name der app. + +##### blueprint + +Das flask Blueprint der app. + +##### manifest + +Das manifest Dictionary. Hier wird folgendes festgelegt: + +- Standardsprache über ```default_language``` +- Menüeinträge über ```menu``` +- URL View regeln über ```views``` +- proxies + +Die Menüeinträge bestehen jeweils aus einem Eintrag 'url' und dem 'name_string' +Die zeichenkette in 'name_string' wird über einen Eintrag im langDict aufgelöst. + +Eine View besteht aus 'url' und dem Namen der function in 'function'. + +Die ist eine Liste von Proxy definitionen. Die Proxydefinition wird als proxySpec +für SAMSProxy verwendet. + +##### proxies + +Eine Liste an SAMSProxy Objekten erzeugt aus den Spezifikationen im Manifest. + +### SAMProxy + +Ein SAMS Proxy stellt eine proxy Funktion zur verfügung. Jeder Proxy hat einen +Ausgang und es gibt verschiedenen Konfogurationsmöglichkeiten zusätzliche Daten +aus der Session der Anfrage hinzu zu fügen. + +#### Methoden + +##### Konstruktor + +###### Minimalistisch: + +```python +proxy = SAMSProxy(proxySpec = { + 'in': '/testapi/ + 'out': 'https://my.testapi.host/api/' +}) +``` + +Jeder Proxy hat in seiner proxySpec einen 'in' und einen 'out' defineirt. +Der Proxy stellt der SAMSApp eine URL Regel wie unter 'in' zur verfügung, die +dann im Hub noch um ein App-Präfix ergänz wird, falls essich nicht um die +Main-App handelt. +Alle Anfragen die an 'in' gehen werden an 'out' weiter geleitet, wobei der +URL-Teil bis zum ende von 'in' durch 'out' ersetzt wird. +Aus einer Anfrage an '/testapi/user' wird also bei obigem Beispiel +'https://my.testapi.host/api/user'. +Die Ursprüngliche Anfrage bleibt bei dieser Minimalkonfiguration unverändert. + +###### Definieren eines Token + +```python +proxy = SAMSProxy(proxySpec = { + 'in': '/testapi/ + 'out': 'https://my.testapi.host/api/' + 'token': {'name': 'Api-Token', 'value': 'C001C01A', 'param-type' : 'header'} +}) +``` + +Wird ein Token, wie Oben angegeben, definiert, wird der Header der Nachricht um +die entsprehende Angabe ergänz. Sollte im aufruf ebenfalls der gleiche Name für +einen Header verwendet worden sein, dann gewinnt der Proxy. +Alle unterstützten 'param-type' Werte: + +- header (für Header) +- url (für URL-Parameter) +- body (für JSON oder form Parameter je nach Anfrage Content-Type) + +###### Session Daten Weitergeben + +```python +proxy = SAMSProxy(proxySpec = { + 'in': '/testapi/ + 'out': 'https://my.testapi.host/api/' + 'session-passthrough': { + 'default':{ + 'user': {'name': 'u', 'param-type': 'body'}, + 'group': {'name': 'g', 'param-type': 'url'} +}) +``` + +Es ist möglich Parameter aus der Session an 'out' weiter zu reichen. +Hierbei muss zwingend ein default Dictionary existieren, auch wenn dieses lehr ist. +für die anderen HTTP-Verben kann dann zusätzlich ein dictionary existieren, +falls sich die erforderlichen Parameter vom default unterscheiden. +Es wird immer das zur HTTP Methode passende Dictionary als Grundlage verwendet. +Das Default wird nur verwendet, wenn für die HTTP Methode kein Dictionary existiert. + +Das Defaut / Methoden Dictionary gibt im key immer den weiter zu leitenden +Session-Patrameter an. Die Werte sind selbst wieder dictionaries ähnlich dem bei +'token'. Allerdings wird hier kein 'value' benötigt, dieses wird aus der Session +gelesen. + +Die HTTP Methode muss wie bei HTTP Methoden üblich in Blockschrift angegeben sein. + +##### proxy + +Methode zum registrieren als view in der flask app. Diese Methode erfüllt dann +die eigendliche Proxy aufgabe, wenn eine Anfrage durch sie behandelt wird. + +#### Eigenschaften + +##### urlRule + +Flask kompatible urlRule für den Proxy. Zur verwendung mit +```flask_app.register_url``` \ No newline at end of file