futurefinity.web – FutureFinty Web Application and Web RequestHandler

futurefinity.web contains Application and RequestHandler class, which are essential of building an web application based on futurefinity.

To use futurefinity.web,you need to import it and asyncio, and create an instance of Application class:

import futurefinity.web
import asyncio

app = futurefinity.web.Application()

Then, you need to inherit RequestHandler class to create handlers, and override methods in the class named with HTTP methods with async def. After that, decorate the created class with the app.add_handler with link that this class will handle:

@app.add_handler("/")
class RootHandler(futurefinity.web.RequestHandler):
    async def get(self, *args, **kwargs):
        return "Hello, World!"

Finally, listen to the port you want, and start asyncio event loop:

app.listen(23333)
asyncio.get_event_loop().run_forever()
class futurefinity.web.Application(**kwargs)[source]

Class that its instance creates asyncio compatible servers, stores handler list, finds every request’s handler, and passes it to server.

Parameters:
  • loop – A Custom EventLoop, or FutureFinity will use the result of asyncio.get_event_loop().
  • template_path – The default template_path. This will also initialize the default template loader if it is set.
  • security_secret – The secret for security purpose. Treat it like a password. If the secret is changed, all secure cookies will become invalid. This will also initialize the default security object if it is set.
  • aes_security – Default: True. Use security.AESGCMSecurityObject to secure the data (such as: cookies). Turn it to false to use security.HMACSecurityObject. This attribute will not work unless the security_secret attribute is set.
  • allow_keep_alive – Default: True. Allow Keep Alive or not. This attribute will be passed to server.HTTPServer as an attribute.
  • debug – Enable Debug Feature.
  • csrf_protect – Enable Cross Site Request Forgeries(CSRF) protection.
  • static_path – Add a default static file handler with the static path.
  • static_handler_path – Default: r”/static/(?P<file>.*?)”. This is an regualr expression that indicates routing path will be used for the default static file handler. The attribute file in the regualr expression will be passed to the default static file handler.
  • **kwargs – All the other keyword arguments will be in the application settings too.
add_handler(path: str, *args, name: str=None, handler: futurefinity.web.RequestHandler=None, **kwargs) → typing.Union[source]

Add a handler to handler list. If you specific a handler in parameter, it will return nothing.

On the other hand, if you use it as a decorator, you should not pass a handler to this function or it will cause unexcepted result.

That is:

@app.add_handler("/")
class RootHandler(ReuqestHandler): pass

or:

class RootHandler(ReuqestHandler): pass
app.add_handler("/", handler=RootHandler)
listen(port: int, address: str='127.0.0.1', context: typing.Union=None) → coroutine[source]

Make the server to listen to the specified port and address.

Parameters:
  • port – The port number that futurefinity is going to bind.
  • address – the address that futurefinity is going to bind.
  • context – The TLS Context used to the server.
make_server() → asyncio.protocols.Protocol[source]

Make a asyncio compatible server.

exception futurefinity.web.HTTPError(status_code: int=200, message: str=None, *args, **kwargs)[source]

Common HTTPError class, this Error should be raised when a non-200 status need to be responded.

Any additional message can be added to the response by message attribute.

async def get(self, *args, **kwargs):
    raise HTTPError(500, message='Please contact system administrator.')
class futurefinity.web.NotFoundHandler(app: 'Application', server: futurefinity.web.ApplicationHTTPServer, request: futurefinity.protocol.HTTPIncomingRequest, path_args: typing.Mapping=None, path_kwargs: typing.Mapping=None)[source]

Default RequestHandler when link matches no handler.

By default, it just returns a 404 Error to the client.

class futurefinity.web.RequestHandler(app: 'Application', server: futurefinity.web.ApplicationHTTPServer, request: futurefinity.protocol.HTTPIncomingRequest, path_args: typing.Mapping=None, path_kwargs: typing.Mapping=None)[source]

Basic Request Handler.

This class should not be used directly, subclass must inherit this class and override functions that represents the HTTP method.

add_header(name: str, value: str)[source]

Add a response header with the name and value, this will not override any former value(s) with the same name.

check_body_etag() → bool[source]

Check etag header of response_body.

check_csrf_value()[source]

Validate if csrf value is valid.

FutureFinity uses a secure cookie _csrf and a body argument _csrf to prevent CSRF attack.

To stop checking CSRF value, override this function and return None.

clear_all_cookies()[source]

Clear response cookie(s).

clear_all_headers()[source]

Clear all response header(s).

Clear a cookie with the name.

clear_header(name: str)[source]

Clear response header(s) with the name.

csrf_form_html

Return a HTML form field contains _csrf value.

data_received()[source]

For StreamRequestHandler. If you use this as a stream handler, you must overrride this function.

delete(*args, **kwargs)[source]

Must be overridden in subclass if you want to handle DELETE request, or it will raise an HTTPError(405) – Method Not Allowed.

This is a Coroutine.

finish(text: typing.Union=None)[source]

Finish the request, send the response. If a text is passed, it will be write first, after that, the request will be finished.

If it is called more than one time, it will raise an error.

get(*args, **kwargs)[source]

Must be overridden in subclass if you want to handle GET request, or it will raise an HTTPError(405) – Method Not Allowed.

This is a Coroutine.

get_all_body_args(name: str) → typing.List[source]

Return all body args with the name by list.

If the arg cannot be found, it will return an empty list.

get_all_headers(name: str) → typing.List[source]

Return all headers with the name by list.

If the header cannot be found, it will return an empty list.

Return all link args with the name by list.

If the arg cannot be found, it will return an empty list.

get_body_arg(name: str, default: object=<object object>) → str[source]

Return first argument in the body with the name.

Parameters:
  • name – the name of the argument.
  • default – the default value if no value is found. If the default value is not specified, it means that the argument is required, it will produce an error if the argument cannot be found.

Return first Cookie in the request header(s) with the name.

If the cookie is expired or doesn’t exist, it will return the default value.

get_header(name: str, default: object=<object object>) → str[source]

Return First Header with the name.

Parameters:
  • name – the name of the header.
  • default – the default value if no value is found. If the default value is not specified, it means that the header is required, it will produce an error if the header cannot be found.

Return first argument in the link with the name.

Parameters:
  • name – the name of the argument.
  • default – the default value if no value is found. If the default value is not specified, it means that the argument is required, it will produce an error if the argument cannot be found.

Get a secure cookie with the name, if it is valid, or None.

By default, FutureFinity will use AES GCM Security Object as the backend of secure cookie.

Parameters:
  • name – is the name of the secure cookie.
  • default – is the default value if the cookie is invalid.
Max_age_days:

is the valid length of the secure cookie, it you want it always be valid, please set it to None.

head(*args, **kwargs)[source]

Respond the Head Request.

This is a Coroutine.

options(*args, **kwargs)[source]

Must be overridden in subclass if you want to handle OPTIONS request, or it will raise an HTTPError(405) – Method Not Allowed.

This is a Coroutine.

patch(*args, **kwargs)[source]

Must be overridden in subclass if you want to handle PATCH request, or it will raise an HTTPError(405) – Method Not Allowed.

This is a Coroutine.

post(*args, **kwargs)[source]

Must be overridden in subclass if you want to handle POST request, or it will raise an HTTPError(405) – Method Not Allowed.

This is a Coroutine.

put(*args, **kwargs)[source]

Must be overridden in subclass if you want to handle PUT request, or it will raise an HTTPError(405) – Method Not Allowed.

This is a Coroutine.

redirect(url: str, permanent: bool=False, status: typing.Union=None)[source]

Rediect request to other location.

Parameters:
  • url – is the relative url or absolute url that the client will be redirected to.
  • permanent – True if this is 301 or 302.
  • status – Custom the status code.
render(template_name: str, template_dict: typing.Union=None)[source]

Render the template with render_string, and write them into response body directly.

render_string(template_name: str, template_dict: typing.Union=None) → str[source]

Render Template in template folder into string.

Currently, FutureFinity uses Jinja2 as the Default Template Rendering Engine. However, You can Specify Template Engine by override this function.

set_body_etag()[source]

Set etag header of response_body.

Set a cookie with attribute(s).

Parameters:
  • name – is the name of the cookie.
  • value – is the value of the cookie.
  • domain – is the domain of the cookie.
  • path – is the path of the cookie.
  • expires_days – is the lifetime of the cookie.
  • secure – is the property if the cookie can only be passed via https.
  • httponly – is the property if the cookie can only be passed by http.
set_csrf_value()[source]

Set the csrf value.

set_header(name: str, value: str)[source]

Set a response header with the name and value, this will override any former value(s) with the same name.

Set a secure cookie.

By default, FutureFinity will use AES GCM Security Object as the backend of secure cookie.

You must set a security_secret in Application Settings before

you use this method. It can be generated by:

futurefinity.security.get_random_str(length=32)

Once security_secret is generated, treat it like a password, change security_secret will cause all secure_cookie become invalid.

Parameters:
  • name – is the name of the secure cookie.
  • value – is the value of the secure cookie.
  • expires_days – is the lifetime of the cookie.
  • **kwargs – all the other keyword arguments will be passed to RequestHandler.set_cookie.
write(text: typing.Union, clear_text: bool=False)[source]

Write response body.

If write() is called for many times, it will connect all text together.

If it is called after the request finished, it will raise an error.

write_error(error_code: int, message: typing.Union=None, exc_info: typing.Union=None)[source]

Respond an error to client.

You may override this page if you want to custom the error page.

write_initial()[source]

Send the Initial Part(e.g.: Headers) of a Response to the remote.

This function should be only called once.

Usually this function is called by RequestHandler.flush automatically.

After this function is called, you cannot add any new headers, cookies, or change the status_code. If an error is raised after this function is called, FutureFinity is going to close the connection directly.

class futurefinity.web.StaticFileHandler(app: 'Application', server: futurefinity.web.ApplicationHTTPServer, request: futurefinity.protocol.HTTPIncomingRequest, path_args: typing.Mapping=None, path_kwargs: typing.Mapping=None)[source]

Handler that handles static files.

Warning: You should use Web Server(such as: Nginx) to handle Static Files.
StaticFileHandler should only be used in development.
handle_static_file(file_uri_path: str, *args, **kwargs)[source]

Get the file from the given file path. Override this function if you want to customize the way to get file.