main.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #!/usr/bin/env python3
  2. from pathlib import Path
  3. from pygments.formatters import HtmlFormatter
  4. from nicegui import Client, ui
  5. from website import demo_card, reference, svg
  6. from website.example import bash_window, browser_window, python_window
  7. from website.style import example_link, features, header_link, heading, link_target, section_heading, subtitle, title
  8. ui.add_static_files('/favicon', Path(__file__).parent / 'website' / 'favicon')
  9. def add_head_html() -> None:
  10. ui.add_head_html((Path(__file__).parent / 'website' / 'static' / 'header.html').read_text())
  11. ui.add_head_html(f'<style>{HtmlFormatter(nobackground=True).get_style_defs(".codehilite")}</style>')
  12. ui.add_head_html(f"<style>{(Path(__file__).parent / 'website' / 'static' / 'style.css').read_text()}</style>")
  13. def add_header() -> None:
  14. with ui.header() \
  15. .classes('items-center duration-200 p-0 px-4') \
  16. .style('box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1)'):
  17. with ui.link(target=index_page).classes('row gap-4 items-center'):
  18. svg.face().classes('w-8 stroke-white stroke-2')
  19. svg.word().classes('w-24')
  20. with ui.row().classes('items-center ml-auto'):
  21. header_link('Features', '/#features')
  22. header_link('Installation', '/#installation')
  23. header_link('Examples', '/#examples')
  24. header_link('API Reference', reference_page)
  25. header_link('Demos', '/#demos')
  26. header_link('Why?', '/#why')
  27. with ui.link(target='https://github.com/zauberzeug/nicegui/'):
  28. svg.github().classes('fill-white scale-125 m-1')
  29. @ui.page('/')
  30. async def index_page(client: Client):
  31. client.content.classes(remove='q-pa-md gap-4')
  32. add_head_html()
  33. add_header()
  34. with ui.row().classes('w-full h-screen items-center gap-16 no-wrap').style(f'transform: translateX(-250px)'):
  35. svg.face().classes('stroke-black w-[500px]')
  36. with ui.column().classes('gap-8'):
  37. title('Meet the *NiceGUI*.')
  38. subtitle('And let any browser be the frontend\n\nof your Python code.')
  39. with ui.link(target='#about') \
  40. .classes('column mt-6 items-center ml-[-12px] hover:translate-y-1 duration-100 ease-out'):
  41. ui.icon('keyboard_arrow_down').classes('text-4xl text-grey-5 mb-[-0.95em]')
  42. ui.icon('keyboard_arrow_down').classes('text-6xl text-black')
  43. ui.icon('keyboard_arrow_down').classes('text-4xl text-grey-5 mt-[-0.85em]')
  44. link_target('about', '-20px')
  45. with ui.row().classes('dark-box h-screen items-center gap-28 p-32 no-wrap'):
  46. with ui.column().classes('gap-6 text-white'):
  47. heading('Interact with Python through buttons, dialogs, 3D scenes, plots and much more.')
  48. with ui.column().classes('gap-2 text-xl'):
  49. ui.html('''
  50. NiceGUI handles all the web development details for you.
  51. So you can focus on writing Python code.
  52. Anything from short scripts and dashboards to full robotics projects, IoT solutions,
  53. smart home automations and machine learning projects can benefit from having all code in one place.
  54. ''')
  55. ui.html('''
  56. Available as
  57. <a href="https://pypi.org/project/nicegui/"><strong>PyPI package</strong><span class="material-icons">north_east</span></a>,
  58. <a href="https://hub.docker.com/r/zauberzeug/nicegui"><strong>Docker image</strong><span class="material-icons">north_east</span></a> and on
  59. <a href="https://github.com/zauberzeug/nicegui"><strong>GitHub</strong><span class="material-icons">north_east</span></a>.
  60. ''')
  61. demo_card.create()
  62. link_target('features', '-50px')
  63. with ui.column().classes('w-full q-pa-xl q-mb-xl'):
  64. section_heading('Features', 'Code *nicely*')
  65. with ui.row().classes('w-full no-wrap text-lg leading-tight justify-between q-mb-xl'):
  66. features('swap_horiz', 'Interaction', [
  67. 'buttons, switches, sliders, inputs, ...',
  68. 'notifications, dialogs and menus',
  69. 'keyboard input',
  70. 'on-screen joystick',
  71. ])
  72. features('space_dashboard', 'Layout', [
  73. 'navigation bars, tabs, panels, ...',
  74. 'grouping with rows, columns and cards',
  75. 'HTML and markdown elements',
  76. 'flex layout by default',
  77. ])
  78. features('insights', 'Visualization', [
  79. 'charts, diagrams and tables',
  80. '3D scenes',
  81. 'progress bars',
  82. 'built-in timer for data refresh',
  83. ])
  84. with ui.row().classes('w-full no-wrap text-lg leading-tight justify-between'):
  85. features('brush', 'Styling', [
  86. 'customizable color themes',
  87. 'custom CSS and classes',
  88. 'modern look with material design',
  89. 'built-in [Tailwind](https://tailwindcss.com/) support',
  90. ])
  91. features('source', 'Coding', [
  92. 'live-cycle events',
  93. 'implicit reload on code change',
  94. 'straight-forward data binding',
  95. 'execute javascript from Python',
  96. ])
  97. features('anchor', 'Foundation', [
  98. 'generic [Vue](https://vuejs.org/) to Python bridge',
  99. 'dynamic GUI through [Quasar](https://quasar.dev/)',
  100. 'content is served with [FastAPI](http://fastapi.tiangolo.com/)',
  101. 'Python 3.7+',
  102. ])
  103. link_target('installation', '-50px')
  104. with ui.column().classes('w-full q-pa-xl q-mb-xl'):
  105. section_heading('Installation', 'Get *started*')
  106. with ui.row().classes('w-full no-wrap text-lg leading-tight'):
  107. with ui.column().classes('w-1/3 gap-2'):
  108. ui.html('<em>1.</em>').classes('text-3xl text-bold')
  109. ui.markdown('Create __main.py__').classes('text-lg')
  110. with python_window().classes('w-full h-52'):
  111. ui.markdown('''```python\n
  112. from nicegui import ui
  113. ui.label('Hello NiceGUI!')
  114. ui.run()
  115. ```''')
  116. with ui.column().classes('w-1/3 gap-2'):
  117. ui.html('<em>2.</em>').classes('text-3xl text-bold')
  118. ui.markdown('Install and launch').classes('text-lg')
  119. with bash_window().classes('w-full h-52'):
  120. ui.markdown('```bash\npip3 install nicegui\npython3 main.py\n```')
  121. with ui.column().classes('w-1/3 gap-2'):
  122. ui.html('<em>3.</em>').classes('text-3xl text-bold')
  123. ui.markdown('Enjoy').classes('text-lg')
  124. with browser_window().classes('w-full h-52'):
  125. ui.label('Hello NiceGUI!')
  126. link_target('examples', '-50px')
  127. with ui.column().classes('w-full q-pa-xl q-mb-xl'):
  128. section_heading('Examples', 'Try *this*')
  129. with ui.row().classes('justify-center w-full'), ui.column().classes('w-[65rem]'):
  130. reference.create_intro()
  131. with ui.row().classes('dark-box items-center gap-28 px-32 py-16'):
  132. with ui.column().classes('gap-2'):
  133. ui.markdown('Browse through plenty of live examples.').classes('text-3xl text-white font-medium')
  134. ui.html('Fun-Fact: This whole website is also coded with NiceGUI.').classes('text-xl text-white')
  135. ui.link('API reference', '/reference').classes('rounded-full mx-auto px-12 py-2 text-xl text-bold bg-white')
  136. link_target('demos', '-50px')
  137. with ui.column().classes('w-full q-pa-xl q-mb-xl'):
  138. section_heading('In-depth demonstrations', 'Pick your *solution*')
  139. with ui.row().classes('w-full no-wrap text-lg leading-tight'):
  140. with ui.column().classes('w-1/3'):
  141. example_link('Slideshow', 'implements a keyboard-controlled image slideshow')
  142. example_link('Authentication', 'shows how to use sessions to build a login screen')
  143. example_link(
  144. 'Modularization',
  145. 'provides an example of how to modularize your application into multiple files and reuse code')
  146. example_link(
  147. 'FastAPI',
  148. 'illustrates the integration of NiceGUI with an existing FastAPI application')
  149. with ui.column().classes('w-1/3'):
  150. example_link(
  151. 'Map',
  152. 'demonstrates wrapping the JavaScript library leaflet to display a map at specific locations')
  153. example_link(
  154. 'AI Interface',
  155. 'utilizes the [replicate](https://replicate.com) library to perform voice-to-text transcription and generate images from prompts with Stable Diffusion')
  156. example_link('3D Scene', 'creates a webGL view and loads an STL mesh illuminated with a spotlight')
  157. with ui.column().classes('w-1/3'):
  158. example_link('Custom Vue Component', 'shows how to write and integrate a custom vue component')
  159. example_link('Image Mask Overlay', 'shows how to overlay an image with a mask')
  160. example_link('Infinite Scroll', 'presents an infinitely scrolling image gallery')
  161. link_target('why', '0')
  162. with ui.row().classes('dark-box h-screen items-center gap-28 p-32 no-wrap'):
  163. with ui.column().classes('gap-8'):
  164. heading('Why?')
  165. with ui.column().classes('gap-2 text-xl text-white'):
  166. ui.html('''
  167. We like
  168. <strong><a href="https://streamlit.io/">Streamlit</a></strong>
  169. but find it does
  170. <strong><a href="https://github.com/zauberzeug/nicegui/issues/1#issuecomment-847413651">too much magic</a></strong>
  171. when it comes to state handling.
  172. In search for an alternative nice library to write simple graphical user interfaces in Python we discovered
  173. <strong><a href="https://justpy.io/">JustPy</a></strong>.
  174. Although we liked the approach, it is too "low-level HTML" for our daily usage.
  175. But it inspired us to use
  176. <strong><a href="https://vuejs.org/">Vue</a></strong>
  177. and
  178. <strong><a href="https://quasar.dev/">Quasar</a></strong>
  179. for the frontend.
  180. ''')
  181. ui.html('''
  182. We have built on top of
  183. <strong><a href="https://fastapi.tiangolo.com/">FastAPI</a></strong>,
  184. which itself is based on the ASGI framework
  185. <strong><a href="https://www.starlette.io/">Starlette</a></strong>,
  186. and the ASGI webserver
  187. <strong><a href="https://www.uvicorn.org/">Uvicorn</a></strong>
  188. because of their great performance and ease of use.
  189. ''')
  190. svg.face().classes('stroke-white').style('width: 1500px')
  191. @ui.page('/reference')
  192. def reference_page():
  193. add_head_html()
  194. add_header()
  195. reference.create_full()
  196. ui.run(uvicorn_reload_includes='*.py, *.css, *.html')