Skip to content

Latest commit

 

History

History
360 lines (255 loc) · 11.7 KB

cookbook.rst

File metadata and controls

360 lines (255 loc) · 11.7 KB

Cookbook

Equivalent to "Press any key to continue"

actions(buttons=["Continue"]) put_text("Go next") # ..demo-only

Output pandas dataframe

import numpy as np import pandas as pd

df = pd.DataFrame(np.random.randn(6, 4), columns=list("ABCD")) put_html(df.to_html(border=0))

Output Matplotlib figure

Simply do not call matplotlib.pyplot.show, directly save the figure to in-memory buffer and output the buffer via pywebio.output.put_image:

import matplotlib import matplotlib.pyplot as plt import io import pywebio

matplotlib.use('agg') # required, use a non-interactive backend

fig, ax = plt.subplots() # Create a figure containing a single axes. ax.plot([1, 2, 3, 4], [1, 4, 2, 3]) # Plot some data on the axes.

buf = io.BytesIO() fig.savefig(buf) pywebio.output.put_image(buf.getvalue())

The matplotlib.use('agg') is required so that the server does not try to create (and then destroy) GUI windows that will never be seen.

When using Matplotlib in a web server (multiple threads environment), pyplot may cause some conflicts in some cases, read the following articles for more information:

Blocking confirm model

The following code uses the lock mechanism to make the button callback function synchronous:

Click to expand the code

import threading from pywebio import output

def confirm(title, content=None, timeout=None):

"""Show a confirm model.

param str title

Model title.

param list/put_xxx() content

Model content.

param None/float timeout

Seconds for operation time out.

return

Return True when the "CONFIRM" button is clicked, return False when the "CANCEL" button is clicked, return None when a timeout is given and the operation times out.

""" if not isinstance(content, list): content = [content]

event = threading.Event() result = None

def onclick(val):

nonlocal result result = val event.set()

content.append(output.put_buttons([

{'label': 'CONFIRM', 'value': True}, {'label': 'CANCEL', 'value': False, 'color': 'danger'},

], onclick=onclick)) output.popup(title=title, content=content, closable=False)

event.wait(timeout=timeout) # wait the model buttons are clicked output.close_popup() return result

res = confirm('Confirm', 'You have 5 seconds to make s choice', timeout=5) output.put_text("Your choice is:", res)

Input in the popup

In the following code, we define a popup_input() function, which can be used to get input in popup:

Click to expand the code

import threading

def popup_input(pins, names, title='Please fill out the form'):

"""Show a form in popup window.

param list pins

pin output list.

param list pins

pin name list.

param str title

model title.

return

return the form as dict, return None when user cancel the form.

""" if not isinstance(pins, list): pins = [pins]

event = threading.Event() confirmed_form = None

def onclick(val):

nonlocal confirmed_form confirmed_form = val event.set()

pins.append(put_buttons([

{'label': 'Submit', 'value': True}, {'label': 'Cancel', 'value': False, 'color': 'danger'},

], onclick=onclick)) popup(title=title, content=pins, closable=False)

event.wait() close_popup() if not confirmed_form: return None

from pywebio.pin import pin return {name: pin[name] for name in names}

from pywebio.pin import put_input

result = popup_input([

put_input('name', label='Input your name'), put_input('age', label='Input your age', type="number")

], names=['name', 'age']) put_text(result)

The code uses pin module </pin> to add input widgets to popup window, and uses the lock mechanism to wait the form buttons to be clicked.

Redirect stdout to PyWebIO application

The following code shows how to redirect stdout of python code and subprocess to PyWebIO application:

Click to expand the code

import io import time import subprocess # ..doc-only from contextlib import redirect_stdout

# redirect print() to pywebio class WebIO(io.IOBase): def write(self, content): put_text(content, inline=True)

with redirect_stdout(WebIO()):
for i in range(10):

print(i, time.time()) time.sleep(0.2)

## ----import subprocess # ..demo-only # redirect a subprocess' stdout to pywebio process = subprocess.Popen("ls -ahl", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while True: output = process.stdout.readline() if output: put_text(output.decode('utf8'), inline=True)

if not output and process.poll() is not None:

break

Add missing syntax highlight for code output

When output code via put_markdown() or put_code(), PyWebIO provides syntax highlight for some common languages. If you find your code have no syntax highlight, you can add the syntax highlighter by two following steps:

  1. Go to prismjs CDN page to get your syntax highlighter link.
  2. Use config(js_file=...) <pywebio.config> to load the syntax highlight module
@config(js_file="https://cdn.jsdelivr.net/npm/prismjs@1.23.0/components/prism-diff.min.js")
def main():
    put_code("""
+ AAA
- BBB
CCC
    """.strip(), language='diff')

    put_markdown("""
    ```diff
    + AAA
    - BBB
    CCC
    ```
    """, lstrip=True)

Get URL parameters of current page

You can use URL parameter (known also as "query strings" or "URL query parameters") to pass information to your web application. In PyWebIO application, you can use the following code to get the URL parameters as a Python dict.

# query is a dict query = eval_js("Object.fromEntries(new URLSearchParams(window.location.search))") put_text(query)

Add Google AdSense/Analytics code

When you setup Google AdSense/Analytics, you will get a javascript file and a piece of code that needs to be inserted into your application page, you can use pywebio.config() to inject js file and code to your PyWebIO application:

from pywebio import start_server, output, config

js_file = "https://www.googletagmanager.com/gtag/js?id=G-xxxxxxx"
js_code = """
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());

gtag('config', 'G-xxxxxxx');
"""

@config(js_file=js_file, js_code=js_code)
def main():
    output.put_text("hello world")

start_server(main, port=8080)

Refresh page on connection lost

Add the following code to the beginning of your PyWebIO application main function:

session.run_js('WebIO._state.CurrentSession.on_session_close(()=>{setTimeout(()=>location.reload(), 4000})')

You can use pywebio.session.run_js() and pywebio.session.eval_js() to deal with cookies or localStorage with js.

localStorage manipulation:

set_localstorage = lambda key, value: run_js("localStorage.setItem(key, value)", key=key, value=value) get_localstorage = lambda key: eval_js("localStorage.getItem(key)", key=key)

set_localstorage('hello', 'world') val = get_localstorage('hello') put_text(val)

Cookie manipulation:

Click to expand the code