# `webob.dec` -- WSGIfy decorator

Decorators to wrap functions to make them WSGI applications.

The main decorator `wsgify` turns a function into a WSGI application (while also allowing normal calling of the method with an instantiated request).

## Decorator

class webob.dec.wsgify(func=None, RequestClass=None, args=(), kwargs=None, middleware_wraps=None)

  Turns a request-taking, response-returning function into a WSGI app

  You can use this like:

      @wsgify
      def myfunc(req):
          return webob.Response('hey there')

  With that `myfunc` will be a WSGI application, callable like `app_iter = myfunc(environ, start_response)`. You can also call it like normal, e.g., `resp = myfunc(req)`. (You can also wrap methods, like `def myfunc(self, req)`.)

  If you raise exceptions from `webob.exc` they will be turned into WSGI responses.

  There are also several parameters you can use to customize the decorator. Most notably, you can use a `webob.Request` subclass, like:

      class MyRequest(webob.Request):
          @property
          def is_local(self):
              return self.remote_addr == '127.0.0.1'
      @wsgify(RequestClass=MyRequest)
      def myfunc(req):
          if req.is_local:
              return Response('hi!')
          else:
              raise webob.exc.HTTPForbidden

  Another customization you can add is to add args (positional arguments) or kwargs (of course, keyword arguments). While generally not that useful, you can use this to create multiple WSGI apps from one function, like:

      import simplejson
      def serve_json(req, json_obj):
          return Response(json.dumps(json_obj),
                          content_type='application/json')

      serve_ob1 = wsgify(serve_json, args=(ob1,))
      serve_ob2 = wsgify(serve_json, args=(ob2,))

  You can return several things from a function:

  - A `webob.Response` object (or subclass)

  - Any WSGI application

  - None, and then `req.response` will be used (a pre-instantiated Response object)

  - A string, which will be written to `req.response` and then that response will be used.

  - Raise an exception from `webob.exc`

  Also see `wsgify.middleware()` for a way to make middleware.

  You can also subclass this decorator; the most useful things to do in a subclass would be to change RequestClass or override call_func (e.g., to add `req.urlvars` as keyword arguments to the function).

  RequestClass

    alias of `Request`

  get(url, **kw)

    Run a GET request on this application, returning a Response.

    This creates a request object using the given URL, and any other keyword arguments are set on the request object (e.g., `last_modified=datetime.now()`).

        resp = myapp.get('/article?id=10')

  post(url, POST=None, **kw)

    Run a POST request on this application, returning a Response.

    The second argument (POST) can be the request body (a string), or a dictionary or list of two-tuples, that give the POST body.

        resp = myapp.post('/article/new',
                          dict(title='My Day',
                               content='I ate a sandwich'))

  request(url, **kw)

    Run a request on this application, returning a Response.

    This can be used for DELETE, PUT, etc requests. E.g.:

        resp = myapp.request('/article/1', method='PUT', body='New article')

  call_func(req, *args, **kwargs)

    Call the wrapped function; override this in a subclass to change how the function is called.

  clone(func=None, **kw)

    Creates a copy/clone of this object, but with some parameters rebound

  classmethod middleware(middle_func=None, app=None, **kw)

    Creates middleware

    Use this like:

        @wsgify.middleware
        def restrict_ip(req, app, ips):
            if req.remote_addr not in ips:
                raise webob.exc.HTTPForbidden('Bad IP: %s' % req.remote_addr)
            return app

        @wsgify
        def app(req):
            return 'hi'

        wrapped = restrict_ip(app, ips=['127.0.0.1'])

    Or as a decorator:

        @restrict_ip(ips=['127.0.0.1'])
        @wsgify
        def wrapped_app(req):
            return 'hi'

    Or if you want to write output-rewriting middleware:

        @wsgify.middleware
        def all_caps(req, app):
            resp = req.get_response(app)
            resp.body = resp.body.upper()
            return resp

        wrapped = all_caps(app)

    Note that you must call `req.get_response(app)` to get a WebOb response object. If you are not modifying the output, you can just return the app.

    As you can see, this method doesn't actually create an application, but creates "middleware" that can be bound to an application, along with "configuration" (that is, any other keyword arguments you pass when binding the application).