Web Controllers¶
Controllers¶
Controllers need to provide extensibility, much like
Model, but can’t use the same mechanism as the
pre-requisites (a database with loaded modules) may not be available yet (e.g.
no database created, or no database selected).
Controllers thus provide their own extension mechanism, separate from that of models:
Controllers are created by inheriting from Controller.
Routes are defined through methods decorated with route():
class MyController(odoo.http.Controller):
@route('/some_url', auth='public')
def handler(self):
return stuff()
To override a controller, inherit from its class and override relevant methods, re-exposing them if necessary:
class Extension(MyController):
@route()
def handler(self):
do_before()
return super(Extension, self).handler()
decorating with
route()is necessary to keep the method (and route) visible: if the method is redefined without decorating, it will be “unpublished”the decorators of all methods are combined, if the overriding method’s decorator has no argument all previous ones will be kept, any provided argument will override previously defined ones e.g.:
class Restrict(MyController): @route(auth='user') def handler(self): return super(Restrict, self).handler()
will change
/some_urlfrom public authentication to user (requiring a log-in)
API¶
Routing¶
- @odoo.http.route(route: str | Sequence[str] | None = None, **routing: typing.Unpack[RoutingOpts])[código fonte]¶
Decorate a controller method in order to route incoming requests matching the given URL and options to the decorated method.
Aviso
It is mandatory to re-decorate any method that is overridden in controller extensions but the arguments can be omitted. See
Controllerfor more details.- Parâmetros
route (Union[str, Iterable[str]]) – The paths that the decorated method is serving. Incoming HTTP request paths matching this route will be routed to this decorated method. See werkzeug routing documentation for the format of route expressions.
type (str) – The type of request, either
'jsonrpc'or'http'. It describes where to find the request parameters and how to serialize the response.auth (str) –
The authentication method, one of the following:
'user': The user must be authenticated and the current request will be executed using the rights of the user.'bearer': The user is authenticated using an “Authorization” request header, using the Bearer scheme with an API token. The request will be executed with the permissions of the corresponding user. If the header is missing, the request must belong to an authentication session, as for the “user” authentication method.'public': The user may or may not be authenticated. If he isn’t, the current request will be executed using the shared Public user.'none': The method is always active, even if there is no database. Mainly used by the framework and authentication modules. The request code will not have any facilities to access the current user.
methods (Iterable[str]) – A list of http methods (verbs) this route applies to. If not specified, all methods are allowed.
cors (str) – The Access-Control-Allow-Origin cors directive value.
csrf (bool) – Whether CSRF protection should be enabled for the route. Enabled by default for
'http'-type requests, disabled by default for'jsonrpc'-type requests.readonly (Union[bool, Callable[[registry, request], bool]]) – Whether this endpoint should open a cursor on a read-only replica instead of (by default) the primary read/write database.
handle_params_access_error (Callable[[Exception], Response]) – Implement a custom behavior if an error occurred when retrieving the record from the URL parameters (access error or missing error).
captcha (str) – The action name of the captcha. When set the request will be validated against a captcha implementation. Upon failing these requests will return a UserError.
save_session (bool) – Whether it should set a session_id cookie on the http response and save dirty session on disk.
Falseby default forauth='bearer'.Trueby default otherwise.
Request¶
The request object is automatically set on odoo.http.request at
the start of the request.
- class odoo.http.requestlib.Request(httprequest: odoo.http._facade.HTTPRequest)[código fonte]¶
Wrapper around the incoming HTTP request with deserialized request parameters, session utilities and request dispatching logic.
- update_env(user: int | BaseModel | None = None, context: dict | None = None, su: bool | None = None) None[código fonte]¶
Update the environment of the current request.
- update_context(**overrides) None[código fonte]¶
Override the environment context of the current request with the values of
overrides. To replace the entire context, please useupdate_env()instead.
- csrf_token(time_limit: int | None = None) str[código fonte]¶
Generates and returns a CSRF token for the current session
- Parâmetros
time_limit – the CSRF token should only be valid for the specified duration (in second), by default 48h,
Nonefor the token to be valid as long as the current user’s session is.- Retorna
ASCII token string
- validate_csrf(csrf: str) bool[código fonte]¶
Is the given csrf token valid?
- Parâmetros
csrf – The token to validate.
- Retorna
Truewhen valid,Falsewhen not.
- default_lang() str[código fonte]¶
Returns default user language according to request specification
- Retorna
Preferred language if specified or ‘en_US’
- get_http_params() dict[código fonte]¶
Extract key=value pairs from the query string and the forms present in the body (both application/x-www-form-urlencoded and multipart/form-data).
- Retorna
The merged key-value pairs.
- make_response(data: str, headers: HeaderType | None = None, cookies: Mapping | None = None, status: int = 200) Response[código fonte]¶
Helper for non-HTML responses, or HTML responses with custom response headers or cookies.
While handlers can just return the HTML markup of a page they want to send as a string if non-HTML data is returned they need to create a complete response object, or the returned data will not be correctly interpreted by the clients.
- Parâmetros
data – response body
status – http status code
headers – HTTP headers to set on the response
cookies – cookies to set on the client
- Retorna
a response object.
- make_json_response(data: typing.Any, headers: HeaderType | None = None, cookies: Mapping | None = None, status: int = 200) Response[código fonte]¶
Helper for JSON responses, it json-serializes
dataand sets the Content-Type header accordingly if none is provided.- Parâmetros
data – the data that will be json-serialized into the response body
status – http status code
headers – HTTP headers to set on the response
cookies – cookies to set on the client
- not_found(description: str | None = None) werkzeug.exceptions.NotFound[código fonte]¶
Shortcut for a HTTP 404 (Not Found) response
- render(template: str, qcontext: dict | None = None, lazy: bool = True, **kw) odoo.http.response.Response[código fonte]¶
Lazy render of a QWeb template.
The actual rendering of the given template will occur at then end of the dispatching. Meanwhile, the template and/or qcontext can be altered or even replaced by a static response.
- Parâmetros
template – template to render
qcontext – Rendering context to use
lazy – whether the template rendering should be deferred until the last possible moment
kw – forwarded to werkzeug’s Response object
- reroute(path: str | bytes, query_string=None) None[código fonte]¶
Rewrite the current request URL using the new path and query string. This act as a light redirection, it does not return a 3xx responses to the browser but still change the current URL.
- class odoo.http.dispatcher.JsonRPCDispatcher(request)[código fonte]¶
- classmethod is_compatible_with(request)[código fonte]¶
Determine if the current request is compatible with this dispatcher.
- dispatch(endpoint, args)[código fonte]¶
JSON-RPC 2 over HTTP.
Our implementation differs from the specification on two points:
The
methodmember of the JSON-RPC request payload is ignored as the HTTP path is already used to route the request to the controller.We only support parameter structures by-name, i.e. the
paramsmember of the JSON-RPC request payload MUST be a JSON Object and not a JSON Array.
In addition, it is possible to pass a context that replaces the session context via a special
contextargument that is removed prior to calling the endpoint.Successful request:
--> {"jsonrpc": "2.0", "method": "call", "params": {"arg1": "val1" }, "id": null} <-- {"jsonrpc": "2.0", "result": { "res1": "val1" }, "id": null}
Request producing a error:
--> {"jsonrpc": "2.0", "method": "call", "params": {"arg1": "val1" }, "id": null} <-- {"jsonrpc": "2.0", "error": {"code": 1, "message": "End user error message.", "data": {"code": "codestring", "debug": "traceback" } }, "id": null}
- handle_error(exc)[código fonte]¶
Handle any exception that occurred while dispatching a request to a
type='jsonrpc'route. Also handle exceptions that occurred when no route matched the request path, that no fallback page could be delivered and that the requestContent-Typewas json.- Parâmetros
exc – the exception that occurred.
- Retorna
a WSGI application
- class odoo.http.dispatcher.HttpDispatcher(request: Request)[código fonte]¶
- classmethod is_compatible_with(request)[código fonte]¶
Determine if the current request is compatible with this dispatcher.
- dispatch(endpoint, args)[código fonte]¶
Perform http-related actions such as deserializing the request body and query-string and checking cors/csrf while dispatching a request to a
type='http'route.See
load()method for the compatible endpoint return types.
- handle_error(exc)[código fonte]¶
Handle any exception that occurred while dispatching a request to a
type='http'route. Also handle exceptions that occurred when no route matched the request path, when no fallback page could be delivered and that the requestContent-Typewas not json.- Parâmetros
exc (Exception) – the exception that occurred.
- Retorna
a WSGI response
Response¶
- class odoo.http.Response(*args, **kwargs)[código fonte]¶
Outgoing HTTP response with body, status, headers and qweb support. In addition to the
werkzeug.wrappers.Responseparameters, this class’s constructor can take the following additional parameters for QWeb Lazy Rendering.- Parâmetros
template – template to render
qcontext – Rendering context to use
uid – User id to use for the ir.ui.view render call,
Noneto use the request’s user (the default)
these attributes are available as parameters on the Response object and can be altered at any time before rendering
Also exposes all the attributes and methods of
werkzeug.wrappers.Response.- classmethod load(fname: str = '<function>') odoo.http.response.Response[código fonte]¶
Convert the return value of an endpoint into a Response.
- render() Any[código fonte]¶
Renders the Response’s template, returns the result.
- flatten() None[código fonte]¶
Forces the rendering of the response’s template, sets the result as response body and unsets
template
- set_cookie(key, value='', max_age=None, expires=- 1, path='/', domain=None, secure=False, httponly=False, samesite=None, cookie_type='required')[código fonte]¶
The default expires in Werkzeug is None, which means a session cookie. We want to continue to support the session cookie, but not by default. Now the default is arbitrary 1 year. So if you want a cookie of session, you have to explicitly pass expires=None.
- add_etag(overwrite: bool = False, weak: bool = False) None[código fonte]¶
Add an etag for the current response if there is none yet.
Alterado na versão 2.0: SHA-1 is used to generate the value. MD5 may not be available in some environments.
- call_on_close(func: Callable[[], Any]) Callable[[], Any][código fonte]¶
Adds a function to the internal list of functions that should be called as part of closing down the response. Since 0.7 this function also returns the function that was passed so that this can be used as a decorator.
Novo na versão 0.6.
- delete_cookie(key: str, path: str | None = '/', domain: str | None = None, secure: bool = False, httponly: bool = False, samesite: str | None = None) None[código fonte]¶
Delete a cookie. Fails silently if key doesn’t exist.
- Parâmetros
key – the key (name) of the cookie to be deleted.
path – if the cookie that should be deleted was limited to a path, the path has to be defined here.
domain – if the cookie that should be deleted was limited to a domain, that domain has to be defined here.
secure – If
True, the cookie will only be available via HTTPS.httponly – Disallow JavaScript access to the cookie.
samesite – Limit the scope of the cookie to only be attached to requests that are “same-site”.
- classmethod force_type(environ: WSGIEnvironment | None = None) Response[código fonte]¶
Enforce that the WSGI response is a response object of the current type. Werkzeug will use the
Responseinternally in many situations like the exceptions. If you callget_response()on an exception you will get back a regularResponseobject, even if you are using a custom subclass.This method can enforce a given response type, and it will also convert arbitrary WSGI callables into response objects if an environ is provided:
# convert a Werkzeug response object into an instance of the # MyResponseClass subclass. response = MyResponseClass.force_type(response) # convert any WSGI application into a response object response = MyResponseClass.force_type(response, environ)
This is especially useful if you want to post-process responses in the main dispatcher and use functionality provided by your subclass.
Keep in mind that this will modify response objects in place if possible!
- Parâmetros
response – a response object or wsgi application.
environ – a WSGI environment object.
- Retorna
a response object.
- freeze() None[código fonte]¶
Make the response object ready to be pickled. Does the following:
Buffer the response into a list, ignoring
implicity_sequence_conversionanddirect_passthrough.Set the
Content-Lengthheader.Generate an
ETagheader if one is not already set.
Alterado na versão 2.1: Removed the
no_etagparameter.Alterado na versão 2.0: An
ETagheader is always added.Alterado na versão 0.6: The
Content-Lengthheader is set.
- get_data(as_text: bool = False) bytes | str[código fonte]¶
The string representation of the response body. Whenever you call this property the response iterable is encoded and flattened. This can lead to unwanted behavior if you stream big data.
This behavior can be disabled by setting
implicit_sequence_conversiontoFalse.If
as_textis set toTruethe return value will be a decoded string.Novo na versão 0.9.
- get_etag() tuple[str, bool] | tuple[None, None][código fonte]¶
Return a tuple in the form
(etag, is_weak). If there is no ETag the return value is(None, None).
- get_json(force: bool = False, silent: bool = False) Any | None[código fonte]¶
Parse
dataas JSON. Useful during testing.If the mimetype does not indicate JSON (application/json, see
is_json), this returnsNone.Unlike
Request.get_json(), the result is not cached.- Parâmetros
force – Ignore the mimetype and always try to parse JSON.
silent – Silence parsing errors and return
Noneinstead.
- iter_encoded() Iterator[bytes][código fonte]¶
Iter the response encoded with the encoding of the response. If the response object is invoked as WSGI application the return value of this method is used as application iterator unless
direct_passthroughwas activated.
- make_conditional(request_or_environ: WSGIEnvironment | Request, accept_ranges: bool | str = False, complete_length: int | None = None) Response[código fonte]¶
Make the response conditional to the request. This method works best if an etag was defined for the response already. The
add_etagmethod can be used to do that. If called without etag just the date header is set.This does nothing if the request method in the request or environ is anything but GET or HEAD.
For optimal performance when handling range requests, it’s recommended that your response data object implements
seekable,seekandtellmethods as described byio.IOBase. Objects returned bywrap_file()automatically implement those methods.It does not remove the body of the response because that’s something the
__call__()function does for us automatically.Returns self so that you can do
return resp.make_conditional(req)but modifies the object in-place.- Parâmetros
request_or_environ – a request object or WSGI environment to be used to make the response conditional against.
accept_ranges – This parameter dictates the value of
Accept-Rangesheader. IfFalse(default), the header is not set. IfTrue, it will be set to"bytes". If it’s a string, it will use this value.complete_length – Will be used only in valid Range Requests. It will set
Content-Rangecomplete length value and computeContent-Lengthreal value. This parameter is mandatory for successful Range Requests completion.
- Raises
RequestedRangeNotSatisfiableifRangeheader could not be parsed or satisfied.
Alterado na versão 2.0: Range processing is skipped if length is 0 instead of raising a 416 Range Not Satisfiable error.
- make_sequence() None[código fonte]¶
Converts the response iterator in a list. By default this happens automatically if required. If
implicit_sequence_conversionis disabled, this method is not automatically called and some properties might raise exceptions. This also encodes all the items.Novo na versão 0.6.
- set_data(value: bytes | str) None[código fonte]¶
Sets a new string as response. The value must be a string or bytes. If a string is set it’s encoded to the charset of the response (utf-8 by default).
Novo na versão 0.9.
- set_etag(etag: str, weak: bool = False) None[código fonte]¶
Set the etag, and override the old one if there was one.