Package: scruffington
Scruffy. The Janitor.Scruffy is a framework for taking care of a bunch of boilerplate in Python apps. It handles the loading of configuration files, the loading and management of plugins, and the management of other filesystem resources such as temporary files and directories, log files, etc.A typical use case for Scruffy is a command-line Python tool with some or all of the following requirements:Read a set of configuration defaultsRead a local configuration file and apply it on top of the defaultsAllow overriding some configuration options with command line flags or at runtimeLoad a core set of Python-based pluginsLoad a set of user-defined Python-based pluginsGenerate log files whose name, location and other logging settings are based on configurationStore application state between runs in a file or databaseScruffy is used byVoltronandCalculonInstallationA standard python setup script is included.$ python setup.py installThis will install the Scruffy package wherever that happens on your system.Alternately, Scruffy can be installed withpipfrom PyPi (where it’s calledscruffington, because I didn’t check for a conflict before I named it).$ pip install scruffingtonDocumentationFull documentation is hosted atreadthedocsQuick startConfigLoad a user config file, and apply it on top of a set of defaults loaded from inside the Python package we’re currently running from.thingy.yaml:some_property:1other_property:a thingthingy.py:fromscruffyimportConfigFilec=ConfigFile('thingy.yaml',load=True,defaults=File('defaults.yaml',parent=PackageDirectory()))print("c.some_property =={c.some_property}".format(c=c))print("c.other_property =={c.other_property}".format(c=c))Run it:$ python thingy.py
c.some_property == 1
c.other_property == a thingPluginsLoad some plugins.~/.thingy/plugins/example.py:fromscruffyimportPluginclassExamplePlugin(Plugin):defdo_a_thing(self):print('{}.{}is doing a thing'.format(__name__,self.__class__.__name__))thingy.py:fromscruffyimportPluginDirectory,PluginRegistrypd=PluginDirectory('~/.thingy/plugins')pd.load()forpinPluginRegistry.plugins:print("Initialising plugin{}".format(p))p().do_a_thing()Run it:$ python thingy.py
Initialising plugin <class 'example.ExamplePlugin'>
example.ExamplePlugin is doing a thingLoggingScruffy’sLogFileclass will do some configuration of Python’sloggingmodule.log.py:importloggingfromscruffyimportLogFilelog=logging.getLogger('main')log.setLevel(logging.INFO)LogFile('/tmp/thingy.log',logger='main').configure()log.info('Hello from log.py')/tmp/thingy.log:Hello from log.pyEnvironmentScruffy’sEnvironmentclass ties all the other stuff together. The other classes can be instantiated as named children of anEnvironment, which will load anyConfigobjects, apply the configs to the other objects, and then prepare the other objects.~/.thingy/config:log_dir:/tmp/logslog_file:thingy.logenv.py:fromscruffyimport*e=Environment(main_dir=Directory('~/.thingy',create=True,config=ConfigFile('config',defaults=File('defaults.yaml',parent=PackageDirectory())),lock=LockFile('lock')user_plugins=PluginDirectory('plugins')),log_dir=Directory('{config:log_dir}',create=TrueLogFile('{config:log_file}',logger='main')),pkg_plugins=PluginDirectory('plugins',parent=PackageDirectory()))LicenseSee LICENSE file. If you use this and don’t hate it, buy me a beer at a conference some time.CreditsProps toricho. Flat duck pride.