rattail-manual/docs/base/scripts.rst
Lance Edgar 0838cdb93c update docs for commands, scripts
per changes regarding typer, wuttjamaican etc.
2024-07-01 10:55:32 -05:00

104 lines
3.1 KiB
ReStructuredText

Writing Scripts
===============
There are 2 types of scripts you may need to write: Python and shell.
The reason for writing a script is usually for sake of automating some task,
logic for which is either "not important enough" or perhaps is "too custom" to
warrant adding it to the app proper. For instance app upgrade scripts are
closely tied to the machine/environment on which the app is installed and so
are kept outside of the app proper.
Which isn't to say, by the way, that these scripts shouldn't be tracked via
source control. All scripts needed to manage the app *should* ideally be
committed to a Git repo somewhere; see :doc:`/deploy/index` for more on that.
As a rule, shell scripts are "simpler" but of course are limited to the
commands defined by the app (and underlying shell). Python scripts bring
maximum flexibility but can sometimes be overkill.
Python Scripts
--------------
A "complete" sample Python script is shown below. It may be more complex than
you typically need, but hopefully not too bad; modify as you like.
(See also :doc:`wuttjamaican:narr/cli/scripts` for more simple examples.)
If you use :doc:`/data/versioning` then it is important to "postpone" most
module imports, until the config has been fully created. (Even if you don't
use versioning it's a good habit, in case you ever change your mind.) This is
why, in the example below, the import from ``rattail.db`` happens within the
main function, instead of at the top of the script.
.. code-block:: python
#!/srv/envs/poser/bin/python3
"""
This script is useful for such and such.
"""
import argparse
from rattail.config import make_config
def do_something(config):
# most imports should not happen until config is made
from rattail.db.auth import administrator_role
app = config.get_app()
model = app.model
# open db connection
session = app.make_session()
# not doing anything useful here, just an example
admin = administrator_role(session)
print(admin)
# do something else...for instance count the departments
print(session.query(model.Department).count())
# must commit session to save any changes
#session.commit()
session.close()
if __name__ == '__main__':
# here we define available command line args
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--config', metavar='PATH',
action='append', dest='config_paths')
# here we determine what args caller specified
args = parser.parse_args()
# okay let's make that config, per command line
config = make_config(args.config_paths)
# if you'd rather skip command line parsing altogether,
# you can instead do something like this:
#config = make_config('/srv/envs/poser/app/quiet.conf')
# and finally let's do something useful
do_something(config)
Let's say you name this script ``foo.py`` and put it in your app dir, so
running it would look like:
.. code-block:: sh
cd /srv/envs/poser
bin/python3 app/foo.py --help
Shell Scripts
-------------
TODO