## 1.15.2 Writing Applications

It can be slightly complicated to write your own WSGI applications so the `web.wsgi.base` provides a sample class from which you can derive your own application class. The class has the following API:

class `BaseApplication`( | [status='200 OK'], [headers=[('Content-type','text/html')]])

  The class defines the following attributes:

  `environ`
    A dictionary of environment variables similar to `os.environ` but also containing entries from the WSGI server and any middleware being used. The `environ` dictionary is the main way your application will have access to the environment. You should not need to change `environ`.
  `status`
    A string of the form `'error_code messgae'` which can be used to set the HTTP status code of the application. For example `'200 OK'` for a normal application, `'500 Error'` if there was a server error.
  `headers`
    A list of `(field-name, field-value)` tuples suitable for use in the WSGI `start_response` function. Any headers your application needs to send should be specified by this list in the order they should be sent. Note: The default value of the `headers` attribute is set to be `[('Content-type','text/html')]` in the class constructor, so if you do not want this HTTP header you should set a different value in the constrcutor or in your application.

    The `(field-name, field-value)` format could be easily made into HTTP header messages suitable for direct printing:

        messages = []
        for header in self.headers:
            messages.append("%s: %s"%header)

    Warning: WSGI applications and middleware should not normally use the `print` statement in the same way as in CGI scripts. Instead strings should be sent to the `output()` method where they will be returned at the end of execution of the class in accordance with the WSGI specification.

  `_output`
    A list of strings to be returned at the end of the application. The class defines the `output()` method which is used to directly append strings to `_output` so there should be no need to access `_output` directly.

  The class defines the following methods:

  `start`( | )

    This method should be over-ridden in derived classes to provide your application's functionality.

  `output`( | *text)

    Takes one or more strings and appends them to the `_output` attribute when they will be returned at the end of program execution to display the program output. For example:

        self.output('one')
        self.output('one', 'two')

    Note: If the values are not strings, they are convertes to strings using the builtin function `str()`.

  `__call__`( | environ, start_response)

    You should not need to modify this method but is documented here for a complete understanding as it provides the functionality which makes derived classes WSGI applications. This method sets up the `environ` attribute and calls `start()`. Once `start()` returns, it calls `start_response(self.status, self.headers)` to set the status and headers and returns `self._output`.

To create the `'Hello World!'` example used at the start of the documentation with the `BaseApplication` class we could do the following:

    import web.wsgi.base

    class Application(web.wsgi.base.BaseApplication):
        def start(self):
            self.output('Hello World!')

    application = Application()

Note: In this example we have used a class instance as the application whereas we previously used a function definition. Class instances must be initialised.

To use different HTTP headers we could do the following:

    application = Application(headers=[('Content-type','text/plain')])

For application to always be treated as having failed we could set the status to `'500 Error'`

    application = Application(status='500 Error')

To allow be able to set the text of the `'Hello World!'` message from the class constructor we need to modify the class:

    import web.wsgi.base

    class Application(web.wsgi.base.BaseApplication):

        def __init__(self, status='200 OK', headers=[('Content-type','text/html'), text='Hello World!']):
            self.text = text
            web.wsgi.base.BaseApplication.__init__(self, status, headers)

        def start(self):
            self.output(self.text)

    application = Application(text='Hello World Again!')

Warning: When deriving your own classes it is important you do not accidently over-write any of the attributes or methods of the base class, otherwise your class may not function as you intended.