Sharing objects between view and application with Pyramid

I am trying to create a web interface for a data analysis pipeline using Pyramid. I use warp and colander to create shapes. I adapted this example:

http://pyramid-tutorials.readthedocs.org/en/latest/humans/security/step02/

Most of the work is done when the form is submitted, but there are a few general steps that only need to be done once. Can I load some things into memory when the server starts up so they can be accessed from the view?

+3


source to share


2 answers


You can define some module-level variables in your application's main file (or maybe somewhere else) and then use them by importing them as per your requirement.

I use this method to generate parameters such as database connection string for SQLAlchemy from environment variables.

By default, a module will only be parsed once in Python, so module-level code will only run once.

Update 1

Suppose the directory structure of the pyramid project looks like this:

.
├── __init__.py
├── models
│   ├── __init__.py
│   ├── meta
│   │   ├── base.py
│   │   ├── __init__.py
│   │   ├── orm.py
│   │   ├── schema.py
│   │   ├── types.py
│   ├── users.py
├── security.py
├── settings
│   ├── database.py
│   ├── email.py
│   ├── __init__.py
│   ├── redis.py
│   ├── security.py
├── static
│   ├── css
│   │   └── main.css
│   └── js
│       ├── app.js
│       ├── app-services.js
│       ├── controllers
│       │   └── excel_preview.js
├── templates
│   ├── auth
│   │   └── login.html
│   ├── base.html
│   ├── home.html
├── views
│   ├── auth.py
│   ├── home.py
│   ├── __init__.py

      



Let's say we have some code in settings/redis.py

:

import os
import redis


def get_redis_client():
    # Read settings from environment variables
    redis_db_name = os.environ.get('REDIS_NAME')
    redis_host = os.environ.get('REDIS_HOST')
    redis_port = os.environ['REDIS_PORT']

    # create a redis connection
    redis_client = redis.StrictRedis(
        host=redis_host,
        port=redis_port,
        db=redis_db_name,
    )

    # return newly created redis connection
    return redis_client


redis_client = get_redis_client()

SOME_SETTING_STORED_IN_REDIS = redis_client.get('some_setting_stored_in_redis')

      

You can use this variable SOME_SETTING_STORED_IN_REDIS

from anywhere. If the name of your application example_app

then example_app/views/home.py

you can use it like this:

from pyramid.view import view_config

from example_app.settings.redis import SOME_SETTING_STORED_IN_REDIS


def includeme(config):
    config.add_route('home', '/')


@view_config(
    route_name='home',
    renderer='home.html',
    permission='authenticated'
)
def home_view(request):

    return {
        "some_setting": SOME_SETTING_STORED_IN_REDIS,
    }

      

I think you are trying to achieve something similar.

0


source


If by "things that only need to be run once" you mean something like a database connection, some configuration data, etc. - in other words, something that never changes during the lifecycle of a process and then defines them as global and reusable in the application is fine. Example:

APP_TITLE = 'Data Analysis Pipeline using Pyramid'

@view_config(...)
def home_view(request):
    return "Welcome to %s" % APP_TITLE

      

If you are thinking about storing some kind of global state and reusing it in views, this is not a good idea. Example (bad, don't):



subscription_step = 1

@view_config(...)
def next_subscription_step(request):
    global subscription_step
    subscription_step += 1 
    return HTTPFound('/subscription/step_%s' % subscription_step)

      

The above code might work for you locally, but things start to fall apart as soon as more than one user is accessing the application, or if the web server creates another worker process or the web server restarts or a million other reasons.

0


source







All Articles