WSGI Applications

Application

class chisel.Application

The chisel application base class. Override this class if you need additional state for your application (like application configuration). Add functionality to your application by adding Request or Action objects to it using add_request() or add_requests()).

__call__(environ, start_response)

The chisel application WSGI callback. When the application recieves an HTTP request, this method matches the appropriate __call__ method. The application and URL path arguments (e.g. '/documents/{id}') are made available to the request through the request’s Context object.

Parameters:
  • environ (dict) – The WSGI environ dictionary

  • start_response (Callable) – The WSGI start-response callable

Returns:

The WSGI content iterable

add_request(request)

Add a Request to the application.

Parameters:

request (Request) – The request object.

add_requests(requests)

Add a series of Request objects to the application.

Parameters:

requests (Iterable(Request)) – A list of Request objects.

log_format

The application’s log format string. The default is '%(levelname)s [%(process)s / %(thread)s] %(message)s'.

log_level

The application’s logging level. The default is logging.WARNING.

match_request(request_method, path_info)

Match an application request by request method and path

Parameters:
  • request_method (str) – The request method

  • path_info (str) – The request path

Returns:

A tuple of Request and URL argument dict. If the request is None, there is no matching request. If the URL argument dict is None, there are no URL arguments.

Return type:

tuple(chisel.Request or None, dict or None)

pretty_output

Set to True for “pretty” request output. Individual requests can : use this application state they see fit. For example, Action : requests return indented JSON when this value is True. Default is False.

request(request_method, path_info, query_string='', wsgi_input=b'', environ=None)

Execute an application request

Parameters:
  • request_method (str) – The HTTP request method string (e.g. 'GET')

  • path_info (str) – The request URL path (e.g. '/doc/')

  • query_string (str) – Optional query string

  • wsgi_input (bytes) – Optional request content

  • environ (dict) – Optional environ dict. If not provided, a minimal default environ is created.

Returns:

Response status, headers, and content bytes

requests

The chisel application’s map of request name to Request object map.

validate_output

Set to True to validate request output. Individual requests can use this application state as they see fit. For example, Action requests schema-validate return content data when this value is True. Default is True.

request decorator

@chisel.request(wsgi_callback=None, **kwargs)

Decorator for creating a Request object that wraps a WSGI application function. For example:

>>> @chisel.request
... def my_request(environ, start_response):
...    start_response('200 OK', [('Content-Type', 'text/plain')])
...    return [b'Hello, World!']
...
>>> my_request.name, my_request.urls, my_request.doc, my_request.doc_group
...
('my_request', ((None, '/my_request'),), None, None)

You can also pass Request initialization parameters to the request decorator:

>>> @chisel.request(urls=[('GET', None)], doc='This is my request')
... def my_request(environ, start_response):
...    start_response('200 OK', [('Content-Type', 'text/plain')])
...    return [b'Hello, World!']
...
>>> my_request.name, my_request.urls, my_request.doc, my_request.doc_group
...
('my_request', (('GET', '/my_request'),), 'This is my request', None)

The created Request object is passed to an application’s add_request() method to host it with that applicaton.

>>> application = chisel.Application()
>>> application.add_request(my_request)
>>> application.request('GET', '/my_request')
('200 OK', [('Content-Type', 'text/plain')], b'Hello, World!')
Parameters:

wsgi_callback (Callable) – A WSGI application function

Returns Request:

The created Request object

Context

class chisel.Context(app, environ=None, start_response=None, url_args=None)

Class to encapsulate HTTP request state. Application passes a Context object to each request in the WSGI environ dict, environ[chisel.Context.ENVIRON_CTX].

Parameters:
  • app (Application) – The chisel application object

  • environ (dict) – The WSGI environ dictionary

  • start_response (Callable) – The WSGI start-response callable

  • url_args (dict) – The parsed URL arguments dictionary

ENVIRON_CTX = 'chisel.ctx'

The context WSGI environ key

add_cache_headers(control, ttl_seconds=None, utcnow=None)

Add a cache header to the response. You can specify a public or private cache with a time-to-live. You can specify no-cache by passing control as None.

>>> from datetime import datetime
>>> from pprint import pprint
...
>>> @chisel.action(spec='''
... action my_action
...     urls
...         GET
... ''')
... def my_action(ctx, req):
...    ctx.add_cache_headers('private', ttl_seconds=300, utcnow=datetime.fromisoformat('2020-05-19T17:19:00-07:00'))
...    return {}
...
>>> application = chisel.Application()
>>> application.add_request(my_action)
>>> pprint(application.request('GET', '/my_action'))
('200 OK',
 [('Cache-Control', 'private,max-age=300'),
  ('Content-Type', 'application/json'),
  ('Expires', 'Wed, 20 May 2020 00:24:00 GMT')],
 b'{}')
Parameters:
  • control (str) – 'public', 'private', or None (for no-cache)

  • ttl_seconds (int) – Cache duration in seconds. Do not specify for no-cache.

  • utcnow (datetime) – A datetime() to use as the current datetime

add_header(key, value)

Add a header key/value to the request’s response

>>> @chisel.action(spec='''
... action my_action
...     urls
...         GET
... ''')
... def my_action(ctx, req):
...    ctx.add_header('ETag', 'foo')
...    return {}
...
>>> application = chisel.Application()
>>> application.add_request(my_action)
>>> application.request('GET', '/my_action')
('200 OK', [('Content-Type', 'application/json'), ('ETag', 'foo')], b'{}')
Parameters:
  • key (str) – The header key

  • value (str) – The header value

app

The Application serving the request

static create_environ(request_method, path_info, query_string='', wsgi_input=b'', environ=None)

Create a minimal, test WSGI environ dict

Parameters:
  • request_method (str) – The HTTP request method (e.g. 'GET')

  • path_info (str) – The request URL path (e.g. '/doc/')

  • query_string (str) – Optional query string

  • wsgi_input (bytes) – Optional request content

  • environ (dict) – Optional environ dict. If not provided, a minimal default environ is created.

Returns:

The created Context object

environ

The WSGI environ dictionary

headers

The request’s header map. These headers are added to the response.

log

The python logger instance. Write log messages using this object directly.

reconstruct_url(path_info=None, query_string=None, relative=False)

Reconstruct the request’s URL

>>> application = chisel.Application()
>>> ctx = chisel.Context(application, chisel.Context.create_environ('GET', '/hello'))
>>> ctx.reconstruct_url()
'http://localhost:80/hello'
Parameters:
  • path_info (str) – Optional replacement for the URL path

  • query_string (str) – Optional replacement for the query string

  • relative (bool) – If True, creates a relative URL. Default is False.

response(status, content_type, content, headers=None)

A generic WSGI response

>>> from http import HTTPStatus
...
>>> @chisel.action(wsgi_response=True, spec='''
... action my_action
...     urls
...         GET
... ''')
... def my_action(ctx, req):
...    return ctx.response(HTTPStatus.OK, 'text/plain', [b'Hello'])
...
>>> application = chisel.Application()
>>> application.add_request(my_action)
>>> application.request('GET', '/my_action')
('200 OK', [('Content-Type', 'text/plain')], b'Hello')
Parameters:
  • status (HTTPStatus or str) – The HTTP response status

  • content_type (str) – The response content type

  • content (Iterable(bytes)) – The WSGI response content

  • headers (list(tuple)) – Optional list of key/value header tuples to add to the response

Returns:

The WSGI response content iterable

response_json(status, response, content_type='application/json', encoding='utf-8', headers=None, jsonp=None)

A JSON response

>>> from http import HTTPStatus
...
>>> @chisel.action(wsgi_response=True, spec='''
... action my_action
...     urls
...         GET
... ''')
... def my_action(ctx, req):
...    return ctx.response_json(HTTPStatus.OK, {'a': 5, 'b': 7})
...
>>> application = chisel.Application()
>>> application.add_request(my_action)
>>> application.request('GET', '/my_action')
('200 OK', [('Content-Type', 'application/json')], b'{"a":5,"b":7}')
Parameters:
  • status (HTTPStatus or str) – The HTTP response status

  • response (dict) – The response dictionary

  • content_type (str) – The response content type. The default is “application/json”.

  • encoding (str) – The content encoding. The default is “utf-8”.

  • headers (list(tuple)) – Optional list of key/value header tuples to add to the response

  • jsonp (str) – Optional JSONP key

response_text(status, text=None, content_type='text/plain', encoding='utf-8', headers=None)

A plain-text WSGI response

>>> from http import HTTPStatus
...
>>> @chisel.action(wsgi_response=True, spec='''
... action my_action
...     urls
...         GET
... ''')
... def my_action(ctx, req):
...    return ctx.response_text(HTTPStatus.OK, "Hello")
...
>>> application = chisel.Application()
>>> application.add_request(my_action)
>>> application.request('GET', '/my_action')
('200 OK', [('Content-Type', 'text/plain')], b'Hello')
Parameters:
  • status (HTTPStatus or str) – The HTTP response status

  • text (str) – The response text

  • content_type (str) – The response content type. The default is “text/plain”.

  • encoding (str) – The content encoding. The default is “utf-8”.

  • headers (list(tuple)) – Optional list of key/value header tuples to add to the response

start_response(status, headers)

Call start response on the WSGI request’s start_response function. Any headers added using add_header() are included.

Parameters:
  • status (HTTPStatus or str) – The response HTTP status (e.g. “HTTPStatus.OK”)

  • headers (list(tuple)) – List of key/value header tuples

url_args

The URL path arguments, if any

Request

class chisel.Request(wsgi_callback=None, name=None, urls=None, doc=None, doc_group=None)

The Chisel Request object is a wrapper that associates hosting metadata with a WSGI application function. See the request() decorator for a common way to create Request objects.

Parameters:
  • wsgi_callback (Callable) – A WSGI application function

  • name (str) – The request name. The default name is the callback function’s name.

  • urls (list(tuple)) – The list of URL method/path tuples. The first value is the HTTP request method (e.g. ‘GET’) or None to match any. The second value is the URL path or None to use the default path.

  • doc (str or list(str)) – The documentation markdown text lines

  • doc_group (str) – The documentation group

__call__(environ, start_response)

The request WSGI application method. By default the wrapped wsgi_callback is called. Sub-classes may override this method without calling this method.

Parameters:
  • environ (dict) – The WSGI environ dictionary.

  • start_response (Callable) – The WSGI start-response callable.

doc

The documentation markdown text lines

doc_group

The documentation group

name

The request name

urls

The list of URL method/path tuples

wsgi_callback

The WSGI application function