Resources¶
Creating resources¶
-
class
tangled.web.resource.resource.
Resource
(app, request, name=None, urlvars=None)[source]¶ Base resource class.
Usually, you will want to subclass
Resource
when creating your own resources. Doing so will ensure your resources are properly initialized.Subclasses will automatically return a
405 Method Not Allowed
response for unimplemented methods.Subclasses also have
url()
andpath()
methods that generate URLs and paths to the “current resource”. E.g., in a template, you can doresource.path()
to generate the application-relative path to the current resource. You can also pass in query parameters and alternate URL vars to generate URLs and paths based on the current resource.-
DELETE
()¶ Delete resource.
Return
- 204 if no body
- 200 if body
- 202 if accepted but not yet deleted
-
GET
()¶ Get resource.
Return:
- 200 body
-
HEAD
()¶ Get resource metadata.
Return:
- 204 no body (same headers as GET)
-
OPTIONS
()[source]¶ Get resource options.
By default, this will add an
Allow
header to the response that lists the methods implemented by the resource.
-
PATCH
()¶ Update resource.
Return:
- 200 (body)
- 204 (no body)
- 303 (instead of 204)
-
POST
()¶ Create a new child resource.
Return:
- If resource created and identifiable w/ URL:
- 201 w/ body and Location header (for XHR?)
- 303 w/ Location header (for browser?)
- If resource not identifiable:
- 200 if body
- 204 if no body
-
PUT
()¶ Update resource or create if it doesn’t exist.
Return:
- If new resource created, same as
POST()
- If updated:
- 200 (body)
- 204 (no body)
- 303 (instead of 204)
- If new resource created, same as
-
Configuring resources¶
-
class
tangled.web.resource.config.
config
[source]¶ Decorator for configuring resources methods.
When used on a resource class, the class level configuration will be applied to all methods.
Example:
class MyResource: @config('text/html', template='my_resource.mako') def GET(self): pass
Example of defaults and overrides:
@config('*/*', status=303, response_attrs={'location': '/'}) class MyResource: @config('*/*', status=302) @config('text/html', status=None, response_attrs={}) def GET(self): pass
Mounting Resources¶
-
Application.
mount_resource
(name, factory, path, methods=(), method_name=None, add_slash=False, _level=3)[source]¶ Mount a resource at the specified path.
Basic example:
app.mount_resource('home', 'mypackage.resources:Home', '/')
Specifying URL vars:
app.mount_resource( 'user', 'mypackage.resources:User', '/user/<id>')
A unique
name
for the mounted resource must be specified. This can be any string. It’s used when generating resource URLs viarequest.Request.resource_url()
.A
factory
must also be specified. This can be any class or function that produces objects that implement the resource interface (typically a subclass ofresource.resource.Resource
). The factory may be passed as a string with the following format:package.module:factory
.The
path
is an application relative path that may or may not include URL vars.A list of HTTP
methods
can be passed to constrain which methods the resource will respond to. By default, it’s assumed that a resource will respond to all methods. Note however that when subclassingresource.resource.Resource
, unimplemented methods will return a405 Method Not Allowed
response, so it’s often unnecessary to specify the list of allowed methods here; this is mainly useful if you want to mount different resources at the same path for different methods.If
path
ends with a slash oradd_slash
is True, requests topath
without a trailing slash will be redirected to thepath
with a slash appended.About URL vars:
The format of a URL var is
<(converter)identifier:regex>
. Angle brackets delimit URL vars. Only theidentifier
is required; it can be any valid Python identifier.If a
converter
is specified, it can be a built-in name, the name of a converter intangled.util.converters
, or apackage.module:callable
path that points to a callable that accepts a single argument. URL vars found in a request path will be converted automatically.The
regex
can be almost any regular expression. The exception is that<
and>
can’t be used. In practice, this means that named groups ((?P<name>regex)
) can’t be used (which would be pointless anyway), nor can “look behinds”.Mounting Subresources
Subresources can be mounted like this:
parent = app.mount_resource('parent', factory, '/parent') parent.mount('child', 'child')
or like this:
with app.mount_resource('parent', factory, '/parent') as parent: parent.mount('child', 'child')
In either case, the subresource’s
name
will be prepended with its parent’s name plus a slash, and itspath
will be prepended with its parent’s path plus a slash. If nofactory
is specified, the parent’s factory will be used.methods
will be propagated as well.method_name
andadd_slash
are not propagated.In the examples above, the child’s name would be
parent/child
and its path would be/parent/child
.