示例#1
0
def serve_eggs_with_spam():
    box = picobox.Box()

    # on requests to /eggs, override the value of magic with 'spam'
    if request.path == "/eggs":
        box.put("magic", "spam")

    picobox.push(box, chain=True)
示例#2
0
def main(args=sys.argv[1:]):
    # write access/error logs to stderr
    logging.basicConfig()
    logging.getLogger('aiohttp').setLevel(logging.INFO)

    conf = get_conf()
    database = create_connection(conf)

    # The secret is required to sign issued JWT tokens, therefore it's crucial
    # to warn about importance of settings secret before going production. The
    # only reason why we don't enforce it's setting is because we want the app
    # to fly (at least for development purpose) using defaults.
    if not conf.get('AUTH_SECRET', ''):
        warnings.warn(
            'Auth secret has not been provided. Please generate a long random '
            'secret before going to production.')
        conf['AUTH_SECRET'] = binascii.hexlify(os.urandom(32)).decode('ascii')

    with picobox.push(picobox.Box()) as box:
        box.put('conf', conf)
        box.put('database', database)

        web.run_app(
            create_app(conf, database),
            host=conf['SERVER_HOST'],
            port=conf['SERVER_PORT'],
            access_log_format=conf['SERVER_ACCESS_LOG_FORMAT'],
        )
示例#3
0
async def testapp(request, aiohttp_client, testconf, testdatabase):
    box = picobox.Box()
    box.put('conf', testconf)
    box.put('database', testdatabase)

    picobox.push(box)

    # Python 3.5 does not support yield statement inside coroutines, hence we
    # cannot use yield fixtures here and are forced to use finalizers instead.
    # This is especially weird as Picobox provides convenient context manager
    # and no plain functions, that's why manual triggering is required.
    request.addfinalizer(lambda: picobox.pop())
    return await aiohttp_client(
        create_app(),

        # If 'Content-Type' is not passed to HTTP request, aiohttp client will
        # report 'Content-Type: text/plain' to server. This is completely
        # ridiculous because in case of RESTful API this is completely wrong
        # and APIs usually have their own defaults. So turn off this feature,
        # and do not set 'Content-Type' for us if it wasn't passed.
        skip_auto_headers={'Content-Type'},
    )
示例#4
0
import picobox


@picobox.pass_("conf")
def session(conf):
    class Session:
        connection = conf["connection"]

    return Session()


@picobox.pass_("session")
def compute(session):
    print(session.connection)


box = picobox.Box()
box.put("conf", {"connection": "sqlite://"})
box.put("session", factory=session)

with picobox.push(box):
    compute()
示例#5
0
import picobox


def spam():
    return eggs()


def eggs():
    return rice()


@picobox.pass_("secret")
def rice(secret):
    print(secret)


with picobox.push(picobox.Box()) as box:
    box.put("secret", 42)

    # We don't need to propagate a secret down to rice which is good because
    # we kept interface clear (i.e. no changes in spam and eggs signatures).
    spam()

    # The other good thing is despite injection rice can explicitly receive
    # a secret which means its signature wasn't changed either.
    rice(13)
示例#6
0
import picobox


box = picobox.Box()
box.put("magic", 12)

# The app instance exposed via this module is used to run the app for
# development (flask run) as well as for production (uWSGI, Gunicorn).
# Therefore, we need to push a box without popping so it will be used
# no matter which way we want to run the app.
#
# Examples:
#
#   $ FLASK_APP=wsgi.py flask run
#   $ gunicorn wsgi:app
#
# Alternatively, one can push and pop the box before and after the
# request (see Flask request context), but this way it would be harder
# to test the app since any attempt to override dependencies in tests
# will fail due to later attempt to push a new box by request hooks.
picobox.push(box)
from example import app  # noqa