Welcome to PyApp’s documentation!¶
Contents:
PyApp Reference¶
Contents:
Application¶
Application with bindings for commands
Quick demo:
>>> import sample
>>> from pyapp.app import CliApplication, add_argument
>>> app = CliApplication(sample)
>>> @add_argument('--verbose', target='verbose', action='store_true')
>>> @app.register_handler()
>>> def hello(opts):
... if opts.verbose:
... print("Being verbose!")
... print("Hello")
>>> if __name__ == '__main__':
... app.dispatch()
This example provides an application with a command hello that takes an
optional verbose flag. The framework also provides help, configures and loads
settings (using pyapp.conf
), an interface to the checks framework
and configures the Python logging framework.
There are however a few more things that are required to get this going. The
CliApplication
class expects a certain structure of your
application to allow for it’s (customisable) defaults to be applied.
Your application should have the following structure:
my_app/__init__.py # Include a __version__ variable
__main__.py # This is where the quick demo is located
default_settings.py # The default settings file
CliApplication¶
-
class
pyapp.app.
CliApplication
(root_module, name=None, description=None, version=None, application_settings=None, application_checks=None, env_settings_key=None, env_loglevel_key=None, default_handler=None)[source]¶ Parameters: - root_module – The root module for this application (used for discovery of other modules)
- name – Name of your application; defaults to sys.argv[0]
- description – A description of your application for –help.
- version – Specify a specific version; defaults to getattr(root_module, ‘__version__’)
- application_settings – The default settings for this application; defaults to root_module.default_settings
- application_checks – Location of application checks file; defaults to root_module.checks if it exists.
-
register_handler
(handler=None, cli_name=None)¶ Decorator for registering handlers.
The description for help is taken from the handlers doc string.
Parameters: - handler – Handler function
- cli_name – Optional name to use for CLI; defaults to the function name.
Return type: HandlerProxy
Checks¶
Provides an interface and reports of simple pre-flight sanity checks for your application.
Configuration¶
Provides a simple woy to add settings to your application.
Management of loading of settings from different file types and merging into a simple easy to use settings object.
Usage:
>>> from pyapp.conf import settings
>>> # Configure default settings
>>> settings.configure('my_app.default_settings')
>>> settings.MY_CONFIG_VALUE
'foo'
The settings object also has helper methods to simplify your testing:
>>> from pyapp.conf import settings
>>> with settings.modify() as patch:
... patch.MY_CONFIG_VALUE = 'bar'
... settings.MY_CONFIG_VALUE
'bar'
>>> settings.MY_CONFIG_VALUE
'foo'
In addition to changing values new values can be added or existing values removed using the del keyword. Once the context has been exited all changes are reverted.
Note
All settings must be UPPER_CASE. If a setting is not upper case it will not be imported into the settings object.
Settings¶
-
class
pyapp.conf.
Settings
(base_settings=<module 'pyapp.conf.default_settings' from '/home/docs/checkouts/readthedocs.org/user_builds/pyapp/checkouts/support-3.4/pyapp/conf/default_settings.py'>)[source]¶ Settings container
-
configure
(application_settings, runtime_settings=None, additional_loaders=None, env_settings_key='PYAPP_SETTINGS')[source]¶ Configure the settings object
Parameters: - application_settings (str | unicode) – Your applications default settings file.
- runtime_settings (str | unicode) – Settings defined for the current runtime (eg from the command line)
- additional_loaders (list()) – Additional loaders to execute
- env_settings_key (str | unicode) – Environment variable key used to override the runtime_settings.
-
is_configured
¶ Settings have been configured.
-
load
(loader, apply_method=<slot wrapper '__setitem__' of 'dict' objects>)[source]¶ Load settings from a loader instance. A loader is an iterator that yields key/value pairs.
See
pyapp.conf.loaders.ModuleLoader
as an example.
-
modify
()[source]¶ Apply changes to settings file using a context manager that will roll back the changes on exit of a with block. Designed to simplify test cases.
This should be used with a context manager:
>>> settings = Settings() >>> with settings.modify() as patch: >>> # Change a setting >>> patch.FOO = 'foo' >>> # Remove a setting >>> del patch.BAR
Return type: ModifySettingsContext
-
Loaders¶
Loaders are used to load settings from an external source, eg a Python module
(using ModuleLoader
).
A loader provides key/value pairs to the settings container to merge into the application settings.
ModuleLoader¶
Default Settings¶
-
pyapp.conf.default_settings.
CHECK_LOCATIONS
= []¶ Locations to import to ensure checks are registered.
-
pyapp.conf.default_settings.
DEBUG
= False¶ Enable debug mode
-
pyapp.conf.default_settings.
EXT
= []¶ List of extensions currently in use. Will cause pyapp to import any checks, load default_configuration etc that are supplied by any extension.
Should be a list of modules to import eg:
EXT = ( 'pyapp_sqlalchemy', 'my_custom_extension', )
-
pyapp.conf.default_settings.
LOGGING
= {}¶ Logging configuration.
The following configuration is applied by default:
LOGGING = { 'formatters': { 'default': { 'format': '%(asctime)s | %(levelname)s | %(name)s | %(message)s', }, }, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'formatter': 'default', 'stream': 'ext://sys.stderr', }, }, 'root': { # 'level' : 'INFO', # Set from command line arg parser. 'handlers': ['console'], } }
Configuration Helpers¶
The configuration helpers are a collection of tools that simplify building configuration structures. They also provide a set of factory objects for the generation of named instances from configuration.
The root helper is the NamedConfiguration, this object provides a simple interface over configuration eg:
>>> my_values = NamedConfiguration('MY_VALUES')
>>> my_values.get('foo')
'123'
# With the following in your settings file
MY_VALUES = {
'foo': '123',
'bar': '456',
}
Simple factories¶
These factory objects come in three flavours:
- Basic - returns an instance for each request for a named object
- Singleton - returns the same instance (lazily created) for each named object
- ThreadLocalSingleton - returns an instance of each named object per thread
These classes are all ABS classes that the developer must inherit from and
provide an implementation of the create_instance
method.
-
class
pyapp.conf.helpers.
NamedFactory
(setting, defaults=None, required_keys=None, optional_keys=None, default_name='default')[source]¶ Factory for creating instances from a named configuration.
-
class
pyapp.conf.helpers.
NamedSingletonFactory
(*args, **kwargs)[source]¶ ”
NamedFactory
that provides a single instance of an object.This instance factory type is useful for instance types that only require a single instance eg database connections, web service agents.
If your instance types are not thread safe it is recommended that the
ThreadLocalNamedSingletonFactory
is used.
-
class
pyapp.conf.helpers.
ThreadLocalNamedSingletonFactory
(*args, **kwargs)[source]¶ NamedFactory
that provides a single instance of an object per thread.This instance factory type is useful for instance types that only require a single instance eg database connections, web service agents and that are not thread safe.
Plugin factories¶
Similar to simple factories, plugin factories also come in the same three flavours, however they include the additional functionality of supporting the creation of object instances based off configuration. The definition is slightly more complex in your settings file.
-
class
pyapp.conf.helpers.
NamedPluginFactory
(setting, abc=None, default_name='default')[source]¶ Factory object that generates a named instance from a definition in settings. Can optionally verify an instance type against a specified ABC (Abstract Base Class). The factory will cache imported types.
Named instances are defined in settings using the following definition:
MY_TYPE = { 'default': ( 'my.module.MyClass', { 'param1': 123, 'param2': 'foo', } ) }
The
NamedPluginFactory
is thread safe.
-
class
pyapp.conf.helpers.
NamedSingletonPluginFactory
(*args, **kwargs)[source]¶ NamedPluginFactory
that provides a single instance of an object.This instance factory type is useful for instance types that only require a single instance eg database connections, web service agents.
If your instance types are not thread safe it is recommended that the
ThreadLocalNamedSingletonPluginFactory
is used.
-
class
pyapp.conf.helpers.
ThreadLocalNamedSingletonPluginFactory
(*args, **kwargs)[source]¶ NamedPluginFactory
that provides a single instance of a plugin per thread.This instance factory type is useful for instance types that only require a single instance eg database connections, web service agents and that are not thread safe.
IoC (Inversion of Control) Dependency Injection¶
Support for automatic resolution of dependencies from factories.
These methods are built around data annotations and the abc module.
Usage:
>>> from pyapp.injection import register_factory, inject, Arg
>>> register_factory(FooObject, foo_factory)
# Markup methods for injection
>>> @inject
>>> def my_function(foo=Arg(FooObject)):
... ...
When my_function is called foo_factory is used to instantiate a concrete instance of a FooObject.
Extensions¶
Provides extensions to PyApp that allows other modules to register checks and default settings.
Extensions are registered with PyApp via the settings file pyapp.conf.default_settings.EXT
setting. Usually extensions will be a python package that contains at least default_settings.py
and
checks.py
files.
Details of the package can be declared in the __init__.py
file using the following attributes:
__name__ = 'Name of the Extension`
__version__ = '0.1.0'
__checks__ = '.checks' # This can be a relative path or fully qualified
__default_settings__ = '.default_settings' # This can be a relative path or fully qualified
- The
__checks__
and__default_settings__
attributes tell PyApp to include these when loading - settings or determining what checks are available.
Use the extensions
command provided by the PyApp CLI to list the extensions (and version) installed
in your application.
Ready State¶
Once settings have been loaded, logging configured etc a ready callback is triggered to let the extension perform any initialisation that is required:
def ready(**_):
# Do any initialise
pass