Browser interface
Brython-specific built-in modules
Working with Brython
Cookbook
|
module browser.aio
This module supports asynchronous programming in Brython, using the keywords
async and await .
It replaces the asyncio module in CPython standard library, which cannot
work in the browser context:
- it uses blocking functions such as
run() or run_until_complete() ,
and the way browsers work make it impossible to define functions whose
execution is suspended until an event occurs.
- the browser has its own implicit event loop, it is not possible to define
another one as the asyncio modules does with the function
set_event_loop() .
The module browser.aio defines the following asynchronous functions:
Ajax requests
ajax( method, url[, format="text", headers=None, data=None, cache=False])
req = await ajax("GET", url) inside an asynchronous function gives back
control to the main program, and resumes the function when the Ajax request
of the type method ("GET", "POST", "PUT", etc.) to the specified URL is
completed. The return value is an instance of the class Request (see
below).
format is the expected response format. It can be one of:
"text" : the response is a string
"binary" : an instance of class bytes
"dataURL" : a string formatted as
dataURL
headers is a dictionary with the HTTP headers to send with the request.
data is a string or a dictionary that will be sent with the request to
form the query string for a "GET" request, or the request body for "POST".
cache is a boolean indicating if the browser cache should be used
get( url[, format="text", headers=None, data=None, cache=False])
shortcut for ajax("GET", url...)
post( url[, format="text", headers=None, data=None])
shortcut for ajax("POST", url...)
Request instances
Instances of class Request , as returned by await ajax() , await get() or
await post() , have the following attributes:
data : the response body, with the format defined by argument format
response_headers : a dictionary matching the response headers
status : HTTP response status as an integer (200, 404...)
statusText : HTTP response status as a string ("200 Ok", "404 File not
found"...)
Other asynchronous functions
event( element, name)
evt = await aio.event(element, "click") suspends execution of an
asynchronous function until the user clicks on the specified element.
The return value is an instance of the DOMEvent class (cf. section
events)
sleep( seconds)
In an asynchronous function, await sleep(n) gives back control to the main
program and resumes function execution after n seconds.
Running an asynchronous function
run( coroutine)
Runs a coroutine, ie the result of a call to an asynchronous function
defined by async def . This is a non blocking function: it doesn't wait
until the asynchronous function is completed to execute the instructions
in the following lines. The time when the next instructions are run is
not (easily) predictable.
Futures
ao implements a Future class which is inspired by the class of the same name
in asyncio . This allows you to convert functions using callbacks to
asynchronous functions that can be used with the keyword await .
The version of Brython is basic, it currently implements only the methods
set_result and set_exception . Please refer to [the asyncio
documentation](https://docs.python.org/3/library/asyncio-future.html) for
details.
Examples
Entering text in an INPUT element (customised input() function)
from browser import alert, document, html, aio
async def main():
input = html.INPUT()
document <= input
while True:
ev = await aio.event(input, "blur")
try:
v = int(ev.target.value)
input.remove()
alert(f"Value: {v}")
break
except ValueError:
input.value = ""
aio.run(main())
Reading files asynchronously
from browser import document, html, aio
async def main():
# Text file
req = await aio.ajax("GET", "test.html")
print(len(req.data))
# Binary file
req = await aio.get("memo.pdf", format="binary")
print(len(req.data))
# Read binary file as dataURL
req = await aio.get("eraser.png", format="dataURL")
# display the image in an IMG tag
document <= html.IMG(src=req.data)
aio.run(main())
Use a function with callbacks
from browser import timer, aio
async def main():
fut = aio.Future()
timer.set_timeout(lambda: fut.set_result("timeout!"), 2000)
print("awaiting...")
result = await fut
print(f"future awaited, result: {result}")
aio.run(main())
|