Manpage für Konfigurationsdatei mit Python automatisch erzeugen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
buhtz
Beiträge: 1105
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Manpage für Konfigurationsdatei mit Python automatisch erzeugen

Beitrag von buhtz » 08.11.2022 17:26:32

Ich habe gerade in einem fremden Python Projekt kreativen Code entdeckt. Die Anwendung hat ein config.py was im Grunde eine Art Config-Datei handler mit settern/gettern und allerhand Extras ist.

Es gibt ein weiteres py-Script dass diese config.py nicht ausführt, sondern zeilenweise parsed und basierend auf diesen Informationen eine manpage automatisiert erzeugt. Ein Beispiel zur Veranschaulichung:

Code: Alles auswählen

    def bwlimit(self, profile_id = None):
        #?Bandwidth limit in KB/sec.
        return self.profileIntValue('snapshots.bwlimit.value', 3000, profile_id)
Der Kommentar beginnend mit #? wird als Text in die manpage übernommen. Der Aufruf in der letzten Zeile wird per regex geparsed und auch daraus allerhand Informationen (Datentyp, Default-Wert, usw) gewonnen.

Den Wunsch eine Konfigurationsdatei, mit Ihren Variablen/Feldern, Datentypen, Default-Werten und validen Wertebereichen für die User zu dokumentieren (z.B. in einer manpage) ist naheliegend.
Dies automatisiert zu tun ist auch schlüssig, da ja alles schon irgendwie im Code steht.

Das obige Beispiel funktioniert zwar, ist aber sehr anfällig für Änderungen in der config.py und für Contributors, die den Prozess nicht kennen und sich wundern, warum da so komische python-untypische ? in den Kommentaren stehen.

Mir viel bereits Debianhelp2man auf, dass eine manpage basierend auf der usage Ausgabe einer Anwendung erzeugen kann. Aber hier geht es ja um eine (INI-artige) Konfig-Datei.

Fällt euch da irgendeine Lösung oder Idee dazu ein, wie sich dies erreichen lässt? Oder ein besseres Konzept wie man so einen config-Handler schreibt der selbstdokumentierend ist?
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

JTH
Moderator
Beiträge: 3023
Registriert: 13.08.2008 17:01:41
Wohnort: Berlin

Re: Manpage für Konfigurationsdatei mit Python automatisch erzeugen

Beitrag von JTH » 08.11.2022 19:21:53

buhtz hat geschrieben: ↑ zum Beitrag ↑
08.11.2022 17:26:32
Ich habe gerade in einem fremden Python Projekt kreativen Code entdeckt. Die Anwendung hat ein config.py […]

Es gibt ein weiteres py-Script dass diese config.py nicht ausführt, sondern zeilenweise parsed […]
Kreativ trifft es da wohl ;) Kann man natürlich so machen, aber es gibt für Python, wie für eigentlich alle anderen verbreiteten Sprachen, fertige Wege und Werkzeuge, Dokumentation aus dem Code zu erzeugen. Wobei man sich dabei evtl. an ein paar Konventionen halten muss.

Besonders auskennen tu ich mich da allerdings leider nicht. Nur ein paar Anregungen:

buhtz hat geschrieben: ↑ zum Beitrag ↑
08.11.2022 17:26:32

Code: Alles auswählen

    def bwlimit(self, profile_id = None):
        #?Bandwidth limit in KB/sec.
        return self.profileIntValue('snapshots.bwlimit.value', 3000, profile_id)
Der Kommentar beginnend mit #? wird als Text in die manpage übernommen.
Das benutzt hier einen Kommentar, um Doku einzubetten. In Python üblich sind dafür aber Docstrings, siehe PEP 287 – reStructuredText Docstring Format uvm. Die lassen sich für Module und Pakete dann janz einfach mit pydoc3 anzeigen, z.B.

Code: Alles auswählen

pydoc3 asyncio
ähnlich zur Benutzung von man.


buhtz hat geschrieben: ↑ zum Beitrag ↑
08.11.2022 17:26:32
Der Aufruf in der letzten Zeile wird per regex geparsed und auch daraus allerhand Informationen (Datentyp, Default-Wert, usw) gewonnen.
Das ist beides unnötig. Default-Werte stehen – müssen stehen – in der Funktionssignatur. Datentypen kann man per Type-Annotations direkt auch in selbige schreiben. Das wird auch von etlichen Werkzeugen, Lintern etc. unterstützt. Siehe PEP 483 – The Theory of Type Hints und andere, praktischere Quellen. Würde hier dann etwa so aussehen:

Code: Alles auswählen

from typing import Optional
   
def bwlimit(self, profile_id: Optional[str] = None) -> int:
    return self.profileIntValue('snapshots.bwlimit.value', 3000, profile_id)

Ein bekanntes Werkzeug, das Dokumentation aus dem Python-Code heraus erzeugen kann, wär z.B. Sphinx. Gibt definitiv noch anderes, aber wie gesagt, kenne mich da nicht so speziell aus.

Aus einem RST, wie im PEP oben beschrieben, eine Manpage erzeugen kann z.B. /usr/share/docutils/scripts/python3/rst2man aus Debianpython3-docutils. Ich weiß allerdings nicht adhoc, wie man die Docstrings dafür passend aus dem Python-Code herausbekommt.

help2man + pydoc3 könnt man bestimmt auch irgendwie mit ein bisschen Handarbeit dafür benutzen. Irgendein Code:

Code: Alles auswählen

import typing

class Foo:
    """Foo value type."""
    pass

class Bar:
    """Bar value type."""
    pass

def foobar(v: typing.Union[Foo, Bar]):
    """Foobar bla blubb."""
    pass
Und

Code: Alles auswählen

man <(help2man -S "my module" -n "my Python 3 module" -N --version-string=42 -h my pydoc3)
liefert z.B. eine erste Manpage. Könnt man wohl drauf aufbauen. Ob sie hilfreich ist, hängt natürlich hauptsächlich vom Inhalt der Docstrings ab ;)
Manchmal bekannt als Just (another) Terminal Hacker.

buhtz
Beiträge: 1105
Registriert: 04.12.2015 17:54:49
Kontaktdaten:

Re: Manpage für Konfigurationsdatei mit Python automatisch erzeugen

Beitrag von buhtz » 08.11.2022 21:14:38

Vielen herzliche Dank für deine Rückmeldung, deine Gedanken und Anregungen.

Das gibt mir durchaus ein paar interessante Ideen.

EDIT: Ich überlege gerade, ob es nicht sinnvoller wäre, die Spezifikationen der einzelnen Config-Variablen in einem Python-Dictionary festzuhalten. Das muss man nicht parsen. Und es könnte vom config handler selbst auch dazu genutzt werden, seine setter/getter zu verbessern, oder gar zu generalisieren. So ein dict (ähnlich einem JSON) ist lesbar für den Menschen, den config-handler und dem manpage-erzeugenden Script. Mhm... Klingt sexy. ;)
Debian 11 & 12; Desktop-PC, Headless-NAS, Raspberry Pi 4
Teil des Upstream Betreuer Teams von Back In Time (Debianbackintime)

Antworten