cookbook.rst 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. Cookbook
  2. ==========================
  3. .. contents::
  4. :local:
  5. Interaction related
  6. ----------------------------------------------------------------------------------------------
  7. Equivalent to "Press any key to continue"
  8. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  9. .. exportable-codeblock::
  10. :name: cookbook-press-anykey-continue
  11. :summary: Press any key to continue
  12. actions(buttons=["Continue"])
  13. put_text("Go next") # ..demo-only
  14. Output pandas dataframe
  15. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  16. .. exportable-codeblock::
  17. :name: cookbook-pandas-df
  18. :summary: Output pandas dataframe
  19. import numpy as np
  20. import pandas as pd
  21. df = pd.DataFrame(np.random.randn(6, 4), columns=list("ABCD"))
  22. put_html(df.to_html(border=0))
  23. .. seealso:: `pandas.DataFrame.to_html — pandas documentation <https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_html.html#pandas-dataframe-to-html>`_
  24. Output Matplotlib figure
  25. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  26. Simply do not call ``matplotlib.pyplot.show``, directly save the figure to in-memory buffer and output the buffer
  27. via :func:`pywebio.output.put_image`:
  28. .. exportable-codeblock::
  29. :name: cookbook-matplotlib
  30. :summary: Output Matplotlib plot
  31. import matplotlib
  32. import matplotlib.pyplot as plt
  33. import io
  34. import pywebio
  35. matplotlib.use('agg') # required, use a non-interactive backend
  36. fig, ax = plt.subplots() # Create a figure containing a single axes.
  37. ax.plot([1, 2, 3, 4], [1, 4, 2, 3]) # Plot some data on the axes.
  38. buf = io.BytesIO()
  39. fig.savefig(buf)
  40. pywebio.output.put_image(buf.getvalue())
  41. The ``matplotlib.use('agg')`` is required so that the server does not try to create (and then destroy) GUI windows
  42. that will never be seen.
  43. When using Matplotlib in a web server (multiple threads environment), pyplot may cause some conflicts in some cases,
  44. read the following articles for more information:
  45. * `Multi Threading in Python and Pyplot | by Ranjitha Korrapati | Medium <https://medium.com/@ranjitha.korrapati/multi-threading-in-python-and-pyplot-46f325e6a9d0>`_
  46. * `Embedding in a web application server (Flask) — Matplotlib documentation <https://matplotlib.org/stable/gallery/user_interfaces/web_application_server_sgskip.html>`_
  47. Blocking confirm model
  48. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  49. .. collapse:: Code
  50. .. exportable-codeblock::
  51. :name: cookbook-confirm-model
  52. :summary: Blocking confirm model
  53. import threading
  54. from pywebio import output
  55. def confirm(title, content=None, timeout=None):
  56. """Show a confirm model.
  57. :param str title: Model title.
  58. :param list/put_xxx() content: Model content.
  59. :param None/float timeout: Seconds for operation time out.
  60. :return: Return `True` when the "CONFIRM" button is clicked,
  61. return `False` when the "CANCEL" button is clicked,
  62. return `None` when a timeout is given and the operation times out.
  63. """
  64. if not isinstance(content, list):
  65. content = [content]
  66. event = threading.Event()
  67. result = None
  68. def onclick(val):
  69. nonlocal result
  70. result = val
  71. event.set()
  72. content.append(output.put_buttons([
  73. {'label': 'CONFIRM', 'value': True},
  74. {'label': 'CANCEL', 'value': False, 'color': 'danger'},
  75. ], onclick=onclick))
  76. output.popup(title=title, content=content, closable=False)
  77. event.wait(timeout=timeout) # wait the model buttons are clicked
  78. output.close_popup()
  79. return result
  80. res = confirm('Confirm', 'You have 5 seconds to make s choice', timeout=5)
  81. output.put_text("Your choice is:", res)
  82. Web application related
  83. ----------------------------------------------------------------------------------------------
  84. Get URL parameters of current page
  85. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  86. You can use URL parameter (known also as "query strings" or "URL query parameters") to pass information to your web
  87. application. In PyWebIO application, you can use the following code to get the URL parameters as a Python dict.
  88. .. exportable-codeblock::
  89. :name: cookbook-url-query
  90. :summary: Get URL parameters of current page
  91. # `query` is a dict
  92. query = eval_js("Object.fromEntries(new URLSearchParams(window.location.search))")
  93. put_text(query)
  94. Add Google AdSense/Analytics code
  95. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  96. When you setup Google AdSense/Analytics, you will get a javascript file and a piece of code that needs to be inserted
  97. into your application page, you can use :func:`pywebio.config()` to inject js file and code to your PyWebIO application::
  98. from pywebio import start_server, output, config
  99. js_file = "https://www.googletagmanager.com/gtag/js?id=G-xxxxxxx"
  100. js_code = """
  101. window.dataLayer = window.dataLayer || [];
  102. function gtag(){dataLayer.push(arguments);}
  103. gtag('js', new Date());
  104. gtag('config', 'G-xxxxxxx');
  105. """
  106. @config(js_file=js_file, js_code=js_code)
  107. def main():
  108. output.put_text("hello world")
  109. start_server(main, port=8080)
  110. Refresh page on connection lost
  111. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  112. Add the following code to the beginning of your PyWebIO application main function::
  113. session.run_js('WebIO._state.CurrentSession.on_session_close(()=>{setTimeout(()=>location.reload(), 4000})')