Python API
pyjs_core
this module is the core of pyjs, it contains the C++ implementation of most of the functions and classes used by pyjs.
JsValue
A class holding a javascript object/value.
__await__()
Wait for the javascript object to resolve.
__call__(*args)
Call the javascript object as a function.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*args
|
Any
|
The arguments to pass to the function. |
()
|
Returns:
Type | Description |
---|---|
Any
|
The result of the function call. |
__contains__(q)
Check if the javascript object contains a value.
__delattr__(__name)
Delete an attribute from the javascript object.
__delitem__(__name)
Delete an item from the javascript object.
__eq__(q)
Check if the javascript object is equal to a value.
__init__(value)
Create a new JsValue from a python value.
Args:
value: The value to convert to a JsValue.
If the value is a primitive type (int, float, str, bool) it will be converted to the corresponding javascript type.
For any other python object, it will be converted to the javascript class pyjs.pyobject
which is a wrapper around the python object on the javascript side.
__iter__()
Get an iterator for the javascript object.
__len__()
Get the length of the javascript object.
__next__()
Get the next value from the iterator.
__repr__()
Convert the javascript object to a string.
__str__()
Convert the javascript object to a string.
new(*args)
Create a new instance of a JavaScript class.
pyjs
JsToPyConverterOptions
Bases: object
Source code in module/pyjs/convert.py
WebLoop
Bases: AbstractEventLoop
A custom event loop for use in pyodide
Schedules tasks on the browser event loop. Does no lifecycle management and runs forever.
run_forever
and run_until_complete
cannot block like a normal event loop would
because we only have one thread so blocking would stall the browser event loop
and prevent anything from ever happening.
We defer all work to the browser event loop using the setTimeout function.
To ensure that this event loop doesn't stall out UI and other browser handling,
we want to make sure that each task is scheduled on the browser event loop as a
task not as a microtask. setTimeout(callback, 0)
enqueues the callback as a
task so it works well for our purposes.
See Event Loop Methods
<https://docs.python.org/3/library/asyncio-eventloop.html#asyncio-event-loop>
_.
Source code in module/pyjs/webloop.py
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
|
call_at(when, callback, *args, context=None)
Like call_later()
, but uses an absolute time.
Absolute time corresponds to the event loop's time()
method.
This uses setTimeout(callback, when - cur_time)
Source code in module/pyjs/webloop.py
call_exception_handler(context)
Call the current event loop's exception handler. The context argument is a dict containing the following keys:
message
: Error message;exception
(optional): Exception object;future
(optional): Future instance;task
(optional): Task instance;handle
(optional): Handle instance;protocol
(optional): Protocol instance;transport
(optional): Transport instance;socket
(optional): Socket instance;asyncgen
(optional): Asynchronous generator that caused the exception.
New keys maybe introduced in the future.
Note: do not overload this method in an event loop subclass.
For custom exception handling, use the
set_exception_handler()
method.
Source code in module/pyjs/webloop.py
call_later(delay, callback, *args, context=None)
Arrange for a callback to be called at a given time.
Return a Handle: an opaque object with a cancel() method that can be used to cancel the call.
The delay can be an int or float, expressed in seconds. It is always relative to the current time.
Each callback will be called exactly once. If two callbacks are scheduled for exactly the same time, it undefined which will be called first.
Any positional arguments after the callback will be passed to the callback when it is called.
This uses setTimeout(callback, delay)
Source code in module/pyjs/webloop.py
call_soon(callback, *args, context=None)
Arrange for a callback to be called as soon as possible.
Any positional arguments after the callback will be passed to the callback when it is called.
This schedules the callback on the browser event loop using setTimeout(callback, 0)
.
Source code in module/pyjs/webloop.py
call_soon_threadsafe(callback, *args, context=None)
Like call_soon()
, but thread-safe.
We have no threads so everything is "thread safe", and we just use call_soon
.
Source code in module/pyjs/webloop.py
create_future()
Create a Future object attached to the loop.
Copied from BaseEventLoop.create_future
create_task(coro, *, name=None)
Schedule a coroutine object.
Return a task object.
Copied from BaseEventLoop.create_task
Source code in module/pyjs/webloop.py
default_exception_handler(context)
Default exception handler.
This is called when an exception occurs and no exception handler is set, and can be called by a custom exception handler that wants to defer to the default behavior. This default handler logs the error message and other context-dependent information.
In debug mode, a truncated stack trace is also appended showing where
the given object (e.g. a handle or future or task) was created, if any.
The context parameter has the same meaning as in
call_exception_handler()
.
Source code in module/pyjs/webloop.py
get_exception_handler()
get_task_factory()
Return a task factory, or None if the default one is in use.
Copied from BaseEventLoop.get_task_factory
is_closed()
Returns True
if the event loop was closed.
Always returns False
because WebLoop has no lifecycle management.
is_running()
Returns True
if the event loop is running.
Always returns True
because WebLoop has no lifecycle management.
run_forever()
Run the event loop forever. Does nothing in this implementation.
We cannot block like a normal event loop would because we only have one thread so blocking would stall the browser event loop and prevent anything from ever happening.
Source code in module/pyjs/webloop.py
run_in_executor(executor, func, *args)
Arrange for func to be called in the specified executor.
This is normally supposed to run func(*args) in a separate process or thread and signal back to our event loop when it is done. It's possible to make the executor, but if we actually try to submit any functions to it, it will try to create a thread and throw an error. Best we can do is to run func(args) in this thread and stick the result into a future.
Source code in module/pyjs/webloop.py
run_until_complete(future)
Run until future is done.
If the argument is a coroutine, it is wrapped in a Task.
The native event loop run_until_complete
blocks until evaluation of the
future is complete and then returns the result of the future.
Since we cannot block, we just ensure that the future is scheduled and
return the future. This makes this method a bit useless. Instead, use
future.add_done_callback(do_something_with_result)
or:
Source code in module/pyjs/webloop.py
set_exception_handler(handler)
Set handler as the new event loop exception handler.
If handler is None, the default exception handler will be set.
If handler is a callable object, it should have a signature matching
'(loop, context)', where 'loop' will be a reference to the active event
loop, 'context' will be a dict object (see call_exception_handler()
documentation for details about context).
Source code in module/pyjs/webloop.py
set_task_factory(factory)
Set a task factory that will be used by loop.create_task().
If factory is None the default task factory will be set.
If factory is a callable, it should have a signature matching '(loop, coro)', where 'loop' will be a reference to the active event loop, 'coro' will be a coroutine object. The callable must return a Future.
Copied from BaseEventLoop.set_task_factory
Source code in module/pyjs/webloop.py
time()
Return the time according to the event loop's clock.
This is a float expressed in seconds since an epoch, but the epoch, precision, accuracy and drift are unspecified and may differ per event loop.
Copied from BaseEventLoop.time
Source code in module/pyjs/webloop.py
JsException
Bases: JsHolder
, Exception
Source code in module/pyjs/error_handling.py
JsGenericError
JsError
JsInternalError
JsRangeError
JsReferenceError
JsSyntaxError
JsTypeError
JsURIError
to_js(value, cache=None, depth=0, max_depth=None)
Convert a Python object to a JavaScript object.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value
|
The Python object to convert. |
required | |
cache
|
A dictionary to use as a cache for already converted objects. |
None
|
|
depth
|
The current depth of of nested object conversion. |
0
|
|
max_depth
|
The maximum depth of nested object conversion. |
None
|
Returns:
a JavaScript stored in a pyjs_core.JsValue
Source code in module/pyjs/convert_py_to_js.py
to_py(js_val, depth=0, cache=None, converter_options=None)
Source code in module/pyjs/convert.py
register_converter(cls_name, converter)
Register a custom JavaScript to Python converter.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
cls_name
|
str
|
The name of the JavaScript class to convert. |
required |
converter
|
callable
|
A function that takes a JavaScript object and returns a Python object. |
required |
Example
For this example we define the JavaScript class Rectangle on the fly and create an instance of it. We then register a custom converter for the Rectangle class and convert the instance to a Python object.
# Define JavaScript Rectangle class
# and create an instance of it
rectangle = pyjs.js.Function("""
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
return new Rectangle(10,20)
""")()
# A Python Rectangle class
class Rectangle(object):
def __init__(self, height, width):
self.height = height
self.width = width
# the custom converter
def rectangle_converter(js_val, depth, cache, converter_options):
return Rectangle(js_val.height, js_val.width)
# Register the custom converter
pyjs.register_converter("Rectangle", rectangle_converter)
# Convert the JavaScript Rectangle to a Python Rectangle
r = pyjs.to_py(rectangle)
assert isinstance(r, Rectangle)
assert r.height == 10
assert r.width == 20
Source code in module/pyjs/convert.py
new(cls_, *args)
Create a new instance of a JavaScript class.
This function is a wrapper around the new
operator in JavaScript.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
cls_
|
JsValue
|
The JavaScript class to create an instance of |
required |
*args
|
Any
|
The arguments to pass to the constructor of the JavaScript class |
()
|
Source code in module/pyjs/core.py
create_callable(py_function)
Create a JavaScript callable from a Python function.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
py_function
|
Callable
|
The Python function to create a JavaScript callable from. |
required |
Example:
def py_function(x, y):
return x + y
js_callable, js_py_object = create_callable(py_function)
# this function can be passed to JavaScript.
# lets create some JavaScript code to test it
higher_order_function = pyjs.js.Function("f", "x", "y", "z", """
return z * f(x, y);
""")
# call the higher order JavaScript function with py_function wrapped as a JavaScript callable
result = higher_order_function(js_callable, 1, 2, 3)
assert result == 9
js_py_object.delete()
Returns:
Name | Type | Description |
---|---|---|
callable |
The JavaScript callable |
|
js_py_object |
this object needs to be deleted after the callable is no longer needed |
Source code in module/pyjs/core.py
callable_context(py_function)
Create a JavaScript callable from a Python function and delete it when the context is exited.
See create_callable
for more information.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
py_function
|
Callable
|
The Python function to create a JavaScript callable from. |
required |
Example:
def py_function(x, y):
return x + y
with pyjs.callable_context(py_function) as js_function:
# js_function is a JavaScript callable and could be passed and called from JavaScript
# here we just call it from Python
print(js_function(1,2))
Source code in module/pyjs/core.py
create_once_callable(py_function)
Create a JavaScript callable from a Python function that can only be called once.
Since this function can only be called once, it will be deleted after the first call.
Therefore no manual deletion is necessary.
See create_callable
for more information.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
py_function
|
Callable
|
The Python function to create a JavaScript callable from. |
required |
Returns:
Name | Type | Description |
---|---|---|
callable |
The JavaScript callable |
Example:
def py_function(x, y):
return x + y
js_function = pyjs.create_once_callable(py_function)
print(js_function(1,2)) # this will print 3
# the following will raise an error
try:
print(js_function(1,2))
except Exception as e:
print(e)
Source code in module/pyjs/core.py
promise(py_resolve_reject)
Create a new JavaScript promise with a python callback to resolve or reject the promise.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
py_resolve_reject
|
Callable
|
A Python function that takes two arguments, resolve and reject, which are both functions. |
required |
Example:
import asyncio
import pyjs
def f(resolve, reject):
async def task():
try:
print("start task")
await asyncio.sleep(1)
print("end task")
# resolve when everything is done
resolve()
except:
# reject the promise in case of an error
reject()
asyncio.create_task(task())
js_promise = pyjs.promise(f)
print("await the js promise from python")
await js_promise
print("the wait has an end")
print(js_promise)
Source code in module/pyjs/core.py
apply(js_function, args)
Call a JavaScript function with the given arguments.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
js_function
|
JsValue
|
The JavaScript function to call |
required |
args
|
List
|
The arguments to pass to the JavaScript function |
required |
Returns:
Name | Type | Description |
---|---|---|
Any |
The result of the JavaScript function |
Example:
# create a JavaScript function on the fly
js_function = pyjs.js.Function("x", "y", """
return x + y;
""")
result = pyjs.apply(js_function, [1, 2])
assert result == 3
Source code in module/pyjs/core.py
pyjs_core
this module is the core of pyjs, it contains the C++ implementation of most of the functions and classes used by pyjs.
JsValue
A class holding a javascript object/value.
__await__()
Wait for the javascript object to resolve.
__call__(*args)
Call the javascript object as a function.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*args
|
Any
|
The arguments to pass to the function. |
()
|
Returns:
Type | Description |
---|---|
Any
|
The result of the function call. |
__contains__(q)
Check if the javascript object contains a value.
__delattr__(__name)
Delete an attribute from the javascript object.
__delitem__(__name)
Delete an item from the javascript object.
__eq__(q)
Check if the javascript object is equal to a value.
__init__(value)
Create a new JsValue from a python value.
Args:
value: The value to convert to a JsValue.
If the value is a primitive type (int, float, str, bool) it will be converted to the corresponding javascript type.
For any other python object, it will be converted to the javascript class pyjs.pyobject
which is a wrapper around the python object on the javascript side.
__iter__()
Get an iterator for the javascript object.
__len__()
Get the length of the javascript object.
__next__()
Get the next value from the iterator.
__repr__()
Convert the javascript object to a string.
__str__()
Convert the javascript object to a string.
new(*args)
Create a new instance of a JavaScript class.