Welcome to rivr’s documentation!¶
rivr is a BSD Licensed WSGI web framework, written in Python.
import rivr
def hello_world(request):
return rivr.Response('<html><body>Hello world!</body></html>')
if __name__ == '__main__':
rivr.serve(hello_world)
Contents:
Release History¶
Master¶
Breaking¶
- rivr.templates has been removed, please migrate to rivr-jinja.
- RESTView has been removed. Either vendor the old RESTView, or migrate to rivr-rest.
0.6.0¶
Views¶
- Generic View class now has a default implementation of HEAD.
- Generic View class now has a default implementation of OPTIONS, which simply returns the supported HTTP methods.
Contrib¶
- Completely removed the MongoDB module. This hasn’t been maintained in a while, if anyone still uses it or is interested in maintaining it. It should be moved to a separate module.
- Moved jinja support out into a separate project rivr-jinja.
- Removed the BrowserID module.
Views¶
A view is a simple function which takes a request and returns a response. The response is then sent to the user, it can be a simple HTML page, a request or anything.
import rivr
def example_view(request):
return rivr.Response('<html><body>Hello world!</body></html>')
Class-based views¶
A class-based view is a class which is callable, so it acts just like a normal function based view. rivr provides a base view class which allows you to implement methods for the different HTTP methods it wants to handle. For exaple:
class BasicView(View):
def get(self, request):
return rivr.Response('Get request!')
def post(self, request):
return rivr.Response('Post request!')
rivr also provides a other views such as RedirectView.
Request and Response objects¶
HTTP Message¶
-
class
rivr.http.message.
HTTPMessage
(headers: Union[wsgiref.headers.Headers, Dict[str, str], None] = None)¶ Members: headers, content_type, content_length
Request¶
-
class
rivr.http.request.
Query
(query: Union[str, Dict[str, str], None] = None)¶ -
__str__
() → str¶ >>> query = Query({'category': 'fruits'}) >>> str(query) 'category=fruits'
-
__len__
() → int¶ >>> query = Query('category=fruits&limit=10') >>> len(query) 2
-
__contains__
(name: str) → bool¶ >>> query = Query('category=fruits') >>> 'category' in query True
-
__getitem__
(name: str) → Optional[str]¶ >>> query = Query('category=fruits') >>> query['category'] 'fruits'
-
-
class
rivr.http.
Request
(path: str = '/', method: str = 'GET', query: Optional[Dict[str, str]] = None, headers: Optional[Dict[str, str]] = None, body: Union[bytes, IO[bytes], None] = None)¶ A request is an object which represents a HTTP request. You wouldn’t normally create a request yourself but instead be passed a request. Each view gets passed the clients request.
Members: method, path, query, headers, cookies, body
Response¶
-
class
rivr.http.
Response
(content: Union[str, bytes] = '', status: Optional[int] = None, content_type: Optional[str] = 'text/html; charset=utf8')¶ Response is an object for describing a HTTP response. Every view is responsible for either returning a response or raising an exception.
-
status_code
= 200¶ The HTTP status code for the response.
-
-
class
rivr.http.
ResponseNoContent
(content: Union[str, bytes] = '', status: Optional[int] = None, content_type: Optional[str] = 'text/html; charset=utf8')¶ A response that uses the 204 status code to indicate no content.
-
class
rivr.http.
ResponseRedirect
(redirect_to: str)¶ Acts just like a ResponseRedirect, but uses a 302 status code. It takes a URL to redirect the user to.
-
url
¶ A property that returns the URL for the redirect.
-
-
class
rivr.http.
ResponsePermanentRedirect
(redirect_to: str)¶ Acts just like a ResponseRedirect, but uses a 301 status code.
-
class
rivr.http.
ResponseNotFound
(content: Union[str, bytes] = '', status: Optional[int] = None, content_type: Optional[str] = 'text/html; charset=utf8')¶ Acts just like a Response, but uses a 404 status code.
-
class
rivr.http.
ResponseNotModified
(content: Union[str, bytes] = '', status: Optional[int] = None, content_type: Optional[str] = 'text/html; charset=utf8')¶ Acts just like a Response, but uses a 304 status code.
-
class
rivr.http.
ResponseNotAllowed
(permitted_methods: List[str])¶ A response that uses the 405 status code and takes a list of permitted HTTP methods.
Middleware¶
-
class
rivr.middleware.
Middleware
(**kwargs)¶ -
classmethod
wrap
(view, **kwargs)¶ The wrap method allows you to wrap a view calling the middleware’s process_request and process_response before and after the view.
If the view raises an exception, the process_exception method will be called.
Example:
view = Middleware.wrap(view) response = view(request)
-
process_request
(self, request)¶ This method is called before the view on each request. This method should either return a response or None. If it returns a response, then the middleware will not call the view. If it returns None, then we will call the view.
-
process_response
(self, request, response)¶ This method will take the response, either from process_request or the view. This method will always be called for each request unless there is an exception.
This method must return a response, this can either be the response passed to it, or a completely new response.
-
classmethod
-
class
rivr.middleware.
MiddlewareController
(*middleware)¶ The middleware controller allows you to wrap a view in multiple middleware.
Example usage:
view = MiddlewareController.wrap(view, FirstMiddleware(), SecondMiddleware() ) response = view(request)
Server¶
You can serve rivr with either the build in development server, or you can use any WSGI compatible server such as gunicorn.
Development Server¶
By default, the development server can be used with any rivr callable view, this includes middleware and views.
-
rivr.
serve
(handler: Callable[[rivr.http.request.Request], rivr.http.response.Response], host: str = 'localhost', port: int = 8080, debug: bool = True)¶ Starts a developent server on the local machine. By default, the server runs on port 8080 on localhost. You can pass in a different hostname and/or IP using the keyword arguments.
The development server automatically returns pretty HTML error pages, this can be turned off by setting the debug keyword to False.
import rivr
def example_view(request):
return rivr.Response('<html><body>Hello world!</body></html>')
if __name__ == '__main__':
rivr.serve(example_view)
WSGI Server¶
It’s really simple to use a WSGI server, you can use rivr’s WSGIHandler to wrap your rivr callable view.
import rivr
from rivr.wsgi import WSGIHandler
def example_view(request):
return rivr.Response('<html><body>Hello world!</body></html>')
wsgi = WSGIHandler(example_view)
Then you can simply point your WSGI server to the wsgi method. For example, to do this with gunicorn you can run the following:
$ gunicorn example_wsgi:wsgi
Router¶
rivr comes with a powerful regex based path router similar to the url patterns system in Django.
Example usage:
import rivr
router = rivr.Router()
@router.register(r'^$')
def index(request):
return rivr.Response('Hello world')
@router.register(r'example/$')
def example(request):
return rivr.Response('Example')
Similar to Django, it will also pull out pattern matches from the regex and feed them as arguments and keyword-arguments to your view. For example:
@router.register(r'^(?P<username>[-\w]+)/$')
def index(request, username):
return rivr.Response('Hello %s' % username)
-
class
rivr.router.
Router
(*urls)¶ -
__init__
(*urls)¶ Router takes URLs which you can register on creation.
Example:
router = rivr.Router( (r'^$', index), (r'^test/$', test), )
-
append_slash
= True¶ When append_slash is True, if the request URL does not match any patterns in the router and it doesn’t end in a slash. The router will HTTP redirect any issues to the same URL with a slash appended.
-
register
(*t)¶ Register a URL pattern with a view. This can either be used as a decorator, or it can be used as a method with a view.
Decorator Example:
@router.register(r'^$') def view(request): return Response()
View Example:
router.register(r'^$', view)
-