Files
responder/docs/source/tour.rst
T

198 lines
4.5 KiB
ReStructuredText

Feature Tour
============
Class-Based Views
-----------------
Class-based views (and setting some headers and stuff)::
@api.route("/{greeting}")
class GreetingResource:
def on_request(req, resp, *, greeting): # or on_get...
resp.text = f"{greeting}, world!"
resp.headers.update({'X-Life': '42'})
resp.status_code = api.status_codes.HTTP_416
Background Tasks
----------------
Here, you can spawn off a background thread to run any function, out-of-request::
@api.route("/")
def hello(req, resp):
@api.background.task
def sleep(s=10):
time.sleep(s)
print("slept!")
sleep()
resp.content = "processing"
GraphQL
-------
Serve a GraphQL API::
import graphene
class Query(graphene.ObjectType):
hello = graphene.String(name=graphene.String(default_value="stranger"))
def resolve_hello(self, info, name):
return f"Hello {name}"
api.add_route("/graph", graphene.Schema(query=Query))
Visiting the endpoint will render a *GraphiQL* instance, in the browser.
OpenAPI Schema Support
----------------------
Responder comes with built-in support for OpenAPI / marshmallow::
import responder
from marshmallow import Schema, fields
api = responder.API(title="Web Service", version="1.0", openapi="3.0")
@api.schema("Pet")
class PetSchema(Schema):
name = fields.Str()
@api.route("/")
def route(req, resp):
"""A cute furry animal endpoint.
---
get:
description: Get a random pet
responses:
200:
description: A pet to be returned
schema:
$ref = "#/components/schemas/Pet"
"""
resp.media = PetSchema().dump({"name": "little orange"})
::
>>> r = api.session().get("http://;/schema.yml")
>>> print(r.text)
components:
parameters: {}
schemas:
Pet:
properties:
name: {type: string}
type: object
info: {title: Web Service, version: 1.0}
openapi: '3.0'
paths:
/:
get:
description: Get a random pet
responses:
200: {description: A pet to be returned, schema: $ref = "#/components/schemas/Pet"}
tags: []
Mount a WSGI App (e.g. Flask)
-----------------------------
Responder gives you the ability to mount another ASGI / WSGI app at a subroute::
import responder
from flask import Flask
api = responder.API()
flask = Flask(__name__)
@flask.route('/')
def hello():
return 'hello'
api.mount('/flask', flask)
That's it!
Single-Page Web Apps
--------------------
If you have a single-page webapp, you can tell Responder to serve up your ``static/index.html`` at a route, like so::
api.add_route("/", static=True)
This will make ``index.html`` the default response to all undefined routes.
Reading / Writing Cookies
-------------------------
Responder makes it very easy to interact with cookies from a Request, or add some to a Response::
>>> resp.cookies["hello"] = "world"
>>> req.cookies
{"hello": "world"}
Using Cookie-Based Sessions
---------------------------
Responder has built-in support for cookie-based sessions. To enable cookie-based sessions, simply add something to the ``resp.session`` dictionary::
>>> resp.session['username'] = 'kennethreitz'
A cookie called ``Responder-Session`` will be set, which contains all the data in ``resp.session``. It is signed, for verification purposes.
You can easily read a Request's session data, that can be trusted to have originated from the API::
>>> req.session
{'username': 'kennethreitz'}
**Note**: if you are using this in production, you should pass the ``secret_key`` argument to ``API(...)``::
api = responder.API(secret_key=os.environ['SECRET_KEY']
Using Requests Test Client
--------------------------
Responder comes with a first-class, well supported test client for your ASGI web services: **Requests**.
Here's an example of a test (written with pytest)::
import myapi
@pytest.fixture
def api():
return myapi.api
def test_response(api):
hello = "hello, world!"
@api.route('/some-url')
def some_view(req, resp):
resp.text = hello
r = api.requests.get(url=api.url_for(some_view))
assert r.text = hello
HSTS (Redirect to HTTPS)
------------------------
Want HSTS (to redirect all traffic to HTTPS)?
::
api = responder.API(enable_hsts=True)
Boom.