PythonAppTemplate
July 2020 (458 Words, 3 Minutes)
Introduzione
Spesso capita di dover implemetare un applicazione a linea di comando in tempi molto rapidi, quello che segue è un esempio di codice di partenza; questo template risponde all’esigienza di disporre in breve tempo di un implemetazione flessibile ed estensibile.
Il codice è pubblicco ed è disponibile su github
Template
In generale quando bisogna scrivere un applicazione a linea di comando serve:
- un main in cui inizialezzare tutti i componenti
- un logger per poter debuggare eventuali problemi
- un parser per interpretare i parametri da linea di comando
- un pattern per gestire tutte le opzioni che si hanno in mente di implementare
Questo template cerca di rispondere a tutti i punti precedenti.
Struttura
Files presenti nel progetto
$ tree
.
├── app # questo file contiene il main dell'applicazione
├── app_modules
│ ├── commands
│ │ ├── commandline_parser.py # parser della linea di comando
│ │ ├── command.py # classe base per gestire i comandi
│ │ ├── __init__.py
│ │ ├── runner
│ │ │ ├── __init__.py
│ │ │ └── run_version.py # esempio di comando che stampa la versione
│ │ └── setter
│ │ ├── __init__.py
│ │ ├── set_conf.py
│ │ └── set_env.py
│ ├── core
│ │ ├── config.py
│ │ ├── constants.py
│ │ ├── __init__.py
│ │ └── mlogger.py
│ └── __init__.py
├── build.sh
├── LICENSE
├── README.md
└── requirements.txt
5 directories, 18 files
Diagramma di flusso delle classi
Durante l’esecuzione l’applicazione seguirà i seguenti passi:
- la classe app inizia l’esecuzione e prepara il logger
- la classe app instanzia la classe commandline_parser
- la classe commandline_parser inizializza tutti i comandi
- la classe commandline_parser analizza gli argomenti passati da linea e costruisce l’elenco dei comandi da eseguire
- la classe commandline_parse ritorna alla classe app l’elenco dei comandi
- la classe app esegue tutti i comandi gestendo eventuali eccezzioni
Estendere il template
Per estendere il template bisognerà per prima cosa inserire i codici specifici dell’applicazione dentro la cartella app_module, e poi iniziare a creare i nuovi comandi.
I comandi vengono distinit in :
- setter: comandi utilizzati per passare valori all’applicazione
- runner : comandi utilizzati per specificare quale azione compiere
Esempio di nuovo comando
Supponiamo di voler creare l’opzione --say-hello
, bisognerà creare il file :
app_modules/commands/runner/sey_hello.py
from app_modules.core import LoggerFactory
from app_modules.core import SingleConfig
from app_modules.core import AppConstants
from app_modules.commands.command import Command
class Say_hello ( Command ):
short_arg = None
long_arg = 'say-hello'
cmd_help = 'print hello world'
cmd_type = None
cmd_action = 'store_true'
def __init__ ( self, param = None ):
super(). __init__ ()
self.logger = LoggerFactory.getLogger( str( self. __class__ ))
def run( self ):
print('hello world')
successivamente è necessario aggiornare il file
app_modules/commands/runner/ __init__.py
in maniera che il nuovo comando sia richiamabile:
__all__ = [
'Run_version',
'Say_hello'
]
# deprecated to keep older scripts who import this from breaking
from app_modules.commands.runner.run_version import Run_version
from app_modules.commands.runner.say_hello import Say_hello
A questo punto è necessario registrare nel parser il nuovo comando :
# file app_modules/commands/commandline_parser.py
# linea 38
self.rcl = [
Run_version,
Say_hello
]
Infine è possibile provare il nuovo comando:
$ python app -h
usage: App [-h] [--version] [--say-hello] [--conf CONF]
A sample python app
optional arguments:
-h, --help show this help message and exit
--version, -V print version
--say-hello print hello world
--conf CONF, -c CONF pass a configuration file
$ python app --say-hello
hello world
Conclusine
Il codice dell’esempio è disponibile sul branch hello-world.
Invito tutti a forcare il mio codice per migliorarlo o fornirmi un feedback sulle scelte fatte.
Riferimenti
Quest'opera è distribuita con Licenza Creative Commons Attribuzione - Condividi allo stesso modo 4.0 Internazionale Theme Moonwalk