This is a pre-production deployment of Warehouse, however changes made here WILL affect the production instance of PyPI.
Latest Version Dependencies status unknown Test status unknown Test coverage unknown
Project Description

The Startup class implements a function-call graph dependency resolver for decoupling complex program initialization sequence.

To use startup, you annotate functions with which variables they read or write (remainder: you must annotate all non-optional parameters). Then startup generates a dependency graph from the annotations, and call them in a stable and predictable order. Each function will be called exactly once, and if a function has never been called (due to unsatisfiable dependency), startup will raise a StartupError.

Sample usage:

from startup import startup

# 'argv' is the variable name that parse_argv reads from, and
# 'args' is the variable name that parse_argv writes to.
# NOTE: All non-optional parameters must be annotated.
@startup
def parse_argv(argv: 'argv') -> 'args':
    args = {'config_path': argv[1]}
    return args

@startup
def read_config(args: 'args') -> 'config':
    with open(args['config_path']) as config_file:
        return config_file.read()

def main(argv):
    # You may provide variable values to startup, like argv in this
    # case, and you may read variable, like config, which will be
    # returned by startup.call().
    config = startup.call(argv=argv)['config']

You must annotate all non-optional parameters with a variable name, but annotating return value is optional. A parameter annotation can be annotated in the form ['var'], and this function will read all values written to 'var' (see below). A return value annotation can be a tuple of variable names, which means unpacking return value.

The variables in function annotations are not real but merely dict keys that startup stores internally (startup.call() will return this dict so that you too may read these variables).

NOTE: Currently the annotation formats are very strict: A parameter annotation must be either a str or an one-element list of str, and a return value annotation must be either a str or a tuple of str. The flexibility is reserved for future extensions.

The functions that are satisfied by the same set of dependencies are called in lexicographical order by their module name and qualified name. This way, even if you change code layout and/or import order, the functions would still be called in the same order, and thus startup is stable and predictable.

A variable may be written multiple times (if multiple functions are annotated to write to it). In this case, startup will call the reader functions only after all writer functions are called. The reader functions may choose to read the latest value or all the values written to that variable (by ['var'] annotation form).

The fact that all readers are blocked by all writers can be used to express common patterns of program initialization, such as joining or sequencing function calls.

Why startup?

Starting up a program could be complex but should not be complicated. For example, main.py imports orm.py and orm.py imports db.py. Say you want to initialize them in the order of db.py, main.py, and then orm.py. Then main.py has to know that it transitively imports db.py and should initialize db.py before itself. Things get even more complex when each module requires phases of initialization. We usually end up with main.py importing all other modules and manually order the initializations. I think this kind of problem can be better solved with topological sort on the dependency graphs. Basically you annotate each module’s dependencies and then startup will resolve a stable and predictable function-call ordering for you.

Release History

Release History

0.3.0

This version

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.2.1

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

0.2.0

History Node

TODO: Figure out how to actually get changelog content.

Changelog content for this version goes here.

Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit.

Show More

Download Files

Download Files

TODO: Brief introduction on what you do with files - including link to relevant help section.

File Name & Checksum SHA256 Checksum Help Version File Type Upload Date
startup-0.3.0.tar.gz (10.6 kB) Copy SHA256 Checksum SHA256 Source Aug 15, 2015

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS HPE HPE Development Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting