PEP 333 Application Instances and Objects

I recently tried to learn about WSGI and more, how the website works in relation to Python. So I read Werkzeug and PEP333 to find out.

However, I ran into a small question that I think I understand but probably not, so I would appreciate your steering in the right direction.

PEP333:

An application object is simply a callable object that takes two arguments. The term "object" should not be misunderstood as requiring an actual instance of an object: a function, method, class, or instance with a method invocation is acceptable for use as an application object. Application objects must be able to reference more than once, as virtually all servers / gateways (except CGI) will be retrying requests.

Implementation:

class AppClass:
    """Produce the same output, but using a class

    (Note: 'AppClass' is the "application" here, so calling it
    returns an instance of 'AppClass', which is then the iterable
    return value of the "application callable" as required by
    the spec.

    If we wanted to use *instances* of 'AppClass' as application
    objects instead, we would have to implement a '__call__'
    method, which would be invoked to execute the application,
    and we would need to create an instance for use by the
    server or gateway.
    """

    def __init__(self, environ, start_response):
        self.environ = environ
        self.start = start_response

    def __iter__(self):
        status = '200 OK'
        response_headers = [('Content-type', 'text/plain')]
        self.start(status, response_headers)
        yield "Hello world!\n"

      

My question is here just to clarify if I got it right.

It states that AppClass is an application and when we call it, it returns an instance of AppClass. But then further down it says that "if we wanted to use the AppClass ass object instances instead of", does that mean that when the WSGI server side calls the AppClass object, only one instance is running?

For example. The server can issue multiple requests (200 OK) to the application for more responses, so iter is placed in this class . But every request goes through the same unique AppClass instance, every request to the server basically doesn't instantiate more than one AppClass instance?

Sorry if this is a long exhausting, and again I apologize if I didn't make a lot of sense. I am trying to improve atm.

Rate your entries as always.

Thank.

+3


source to share


2 answers


Server-side technology will call yours app

(in this case, the class AppClass

that calls the object construct) for each request. This is because each request will be potentially unique environ

.

The optimal thing about this is not that yours app

should be a class, I often find it useful to define my wsgi application (or middleware) as a function returning a function:

# I'd strongly suggest using a web framework instead to define your application
def my_application(environ, start_response):
    start_response(str('200 OK'), [(str('Content-Type'), str('text/plain'))])
    return [b'hello world!\n']

def my_middleware(app):
    def middleware_func(environ, start_response):
        # do something or call the inner app
        return app(environ, start_response)
    return middleware_func

# expose `app` for whatever server tech you're using (such as uwsgi)
app = my_application
app = my_middleware(app)

      



Another common pattern involves defining an object to store some application state, which is created once:

class MyApplication(object):
    def __init__(self):
        # potentially some expensive initialization
        self.routes = ...

    def __call__(self, environ, start_response):
        # Called once per request, must call `start_response` and then
        # return something iterable -- could even be `return self` if
        # this class were to define `__iter__`
        ...
        return [...]

app = MyApplication(...)

      

As for PEP333, I would suggest reading PEP3333 instead - it contains mostly the same information, but clarifies the data types used.

+1


source


For a background on different ways to implement WSGI application objects, read this blog post on the topic.

I also suggest reading the following, which talks about how Python web servers work in general.



If you really have a need, you probably just want to use a framework. Don't try to write anything from scratch with WSGI.

+1


source







All Articles