Skip to content

Commit 8db659d

Browse files
committed
update cookbook
and a demo in doc
1 parent f4f698d commit 8db659d

File tree

4 files changed

+298
-126
lines changed

4 files changed

+298
-126
lines changed

docs/cookbook.rst

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ read the following articles for more information:
7171
Blocking confirm model
7272
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7373

74-
.. collapse:: Code
74+
The following code uses the lock mechanism to make the button callback function synchronous:
75+
76+
.. collapse:: Click to expand the code
7577

7678
.. exportable-codeblock::
7779
:name: cookbook-confirm-model
@@ -115,6 +117,105 @@ Blocking confirm model
115117
res = confirm('Confirm', 'You have 5 seconds to make s choice', timeout=5)
116118
output.put_text("Your choice is:", res)
117119

120+
Input in the popup
121+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
122+
.. https://github.com/pywebio/PyWebIO/discussions/132
123+
124+
In the following code, we define a ``popup_input()`` function, which can be used to get input in popup:
125+
126+
.. collapse:: Click to expand the code
127+
128+
.. exportable-codeblock::
129+
:name: cookbook-redirect-stdout
130+
:summary: Redirect stdout to PyWebIO
131+
132+
import threading
133+
134+
135+
def popup_input(pins, names, title='Please fill out the form'):
136+
"""Show a form in popup window.
137+
138+
:param list pins: pin output list.
139+
:param list pins: pin name list.
140+
:param str title: model title.
141+
:return: return the form as dict, return None when user cancel the form.
142+
"""
143+
if not isinstance(pins, list):
144+
pins = [pins]
145+
146+
event = threading.Event()
147+
confirmed_form = None
148+
149+
def onclick(val):
150+
nonlocal confirmed_form
151+
confirmed_form = val
152+
event.set()
153+
154+
pins.append(put_buttons([
155+
{'label': 'Submit', 'value': True},
156+
{'label': 'Cancel', 'value': False, 'color': 'danger'},
157+
], onclick=onclick))
158+
popup(title=title, content=pins, closable=False)
159+
160+
event.wait()
161+
close_popup()
162+
if not confirmed_form:
163+
return None
164+
165+
from pywebio.pin import pin
166+
return {name: pin[name] for name in names}
167+
168+
169+
from pywebio.pin import put_input
170+
171+
result = popup_input([
172+
put_input('name', label='Input your name'),
173+
put_input('age', label='Input your age', type="number")
174+
], names=['name', 'age'])
175+
put_text(result)
176+
177+
The code uses :doc:`pin module </pin>` to add input widgets to popup window,
178+
and uses the lock mechanism to wait the form buttons to be clicked.
179+
180+
181+
Redirect stdout to PyWebIO application
182+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
183+
.. https://github.com/pywebio/PyWebIO/discussions/21
184+
185+
The following code shows how to redirect stdout of python code and subprocess to PyWebIO application:
186+
187+
.. collapse:: Click to expand the code
188+
189+
.. exportable-codeblock::
190+
:name: cookbook-redirect-stdout
191+
:summary: Redirect stdout to PyWebIO
192+
193+
import io
194+
import time
195+
import subprocess # ..doc-only
196+
from contextlib import redirect_stdout
197+
198+
# redirect `print()` to pywebio
199+
class WebIO(io.IOBase):
200+
def write(self, content):
201+
put_text(content, inline=True)
202+
203+
with redirect_stdout(WebIO()):
204+
for i in range(10):
205+
print(i, time.time())
206+
time.sleep(0.2)
207+
208+
## ----
209+
import subprocess # ..demo-only
210+
# redirect a subprocess' stdout to pywebio
211+
process = subprocess.Popen("ls -ahl", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
212+
while True:
213+
output = process.stdout.readline()
214+
if output == '' and process.poll() is not None:
215+
break
216+
if output:
217+
put_text(output.decode('utf8'), inline=True)
218+
118219

119220

120221
Web application related
@@ -166,3 +267,65 @@ Add the following code to the beginning of your PyWebIO application main functio
166267

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

270+
Cookie and localStorage manipulation
271+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
272+
.. https://github.com/pywebio/PyWebIO/discussions/99
273+
274+
You can use `pywebio.session.run_js()` and `pywebio.session.eval_js()` to deal with cookies or localStorage with js.
275+
276+
``localStorage`` manipulation:
277+
278+
.. exportable-codeblock::
279+
:name: cookbook-localStorage
280+
:summary: ``localStorage`` manipulation
281+
282+
set_localstorage = lambda key, value: run_js("localStorage.setItem(key, value)", key=key, value=value)
283+
get_localstorage = lambda key: eval_js("localStorage.getItem(key)", key=key)
284+
285+
set_localstorage('hello', 'world')
286+
val = get_localstorage('hello')
287+
put_text(val)
288+
289+
290+
Cookie manipulation:
291+
292+
.. collapse:: Click to expand the code
293+
294+
.. exportable-codeblock::
295+
:name: cookbook-cookie
296+
:summary: Cookie manipulation
297+
298+
# https://stackoverflow.com/questions/14573223/set-cookie-and-get-cookie-with-javascript
299+
run_js("""
300+
window.setCookie = function(name,value,days) {
301+
var expires = "";
302+
if (days) {
303+
var date = new Date();
304+
date.setTime(date.getTime() + (days*24*60*60*1000));
305+
expires = "; expires=" + date.toUTCString();
306+
}
307+
document.cookie = name + "=" + (value || "") + expires + "; path=/";
308+
}
309+
window.getCookie = function(name) {
310+
var nameEQ = name + "=";
311+
var ca = document.cookie.split(';');
312+
for(var i=0;i < ca.length;i++) {
313+
var c = ca[i];
314+
while (c.charAt(0)==' ') c = c.substring(1,c.length);
315+
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
316+
}
317+
return null;
318+
}
319+
""")
320+
321+
def setcookie(key, value, days=0):
322+
run_js("setCookie(key, value, days)", key=key, value=value, days=days)
323+
324+
def getcookie(key):
325+
return eval_js("getCookie(key)", key=key)
326+
327+
setcookie('hello', 'world')
328+
val = getcookie('hello')
329+
put_text(val)
330+
331+

docs/guide.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,8 @@ By now, you already get the most important features of PyWebIO and can start to
741741
However, there are some other useful features we don't cover in the above. Here we just make a briefly explain about them.
742742
When you need them in your application, you can refer to their document.
743743

744+
Also, :doc:`here </cookbook>` is a cookbook where you can find some useful code snippets for your PyWebIO application.
745+
744746
``session`` module
745747
^^^^^^^^^^^^^^^^^^^^
746748
The :doc:`pywebio.session </session>` module give you more control to session.

0 commit comments

Comments
 (0)