reactpy 1.1.0__tar.gz → 2.0.0b2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) hide show
  1. reactpy-2.0.0b2/.gitignore +48 -0
  2. reactpy-2.0.0b2/LICENSE +9 -0
  3. reactpy-2.0.0b2/PKG-INFO +121 -0
  4. reactpy-2.0.0b2/README.md +71 -0
  5. reactpy-2.0.0b2/pyproject.toml +335 -0
  6. reactpy-2.0.0b2/src/build_scripts/clean_js_dir.py +41 -0
  7. reactpy-2.0.0b2/src/build_scripts/copy_dir.py +40 -0
  8. reactpy-2.0.0b2/src/js/.gitignore +5 -0
  9. reactpy-2.0.0b2/src/js/README.md +3 -0
  10. reactpy-2.0.0b2/src/js/bun.lockb +0 -0
  11. reactpy-2.0.0b2/src/js/eslint.config.mjs +58 -0
  12. reactpy-2.0.0b2/src/js/package.json +17 -0
  13. reactpy-2.0.0b2/src/js/packages/@reactpy/app/bun.lockb +0 -0
  14. reactpy-2.0.0b2/src/js/packages/@reactpy/app/eslint.config.mjs +42 -0
  15. reactpy-2.0.0b2/src/js/packages/@reactpy/app/package.json +19 -0
  16. reactpy-2.0.0b2/src/js/packages/@reactpy/app/src/index.ts +1 -0
  17. reactpy-2.0.0b2/src/js/packages/@reactpy/app/tsconfig.json +14 -0
  18. reactpy-2.0.0b2/src/js/packages/@reactpy/client/README.md +3 -0
  19. reactpy-2.0.0b2/src/js/packages/@reactpy/client/bun.lockb +0 -0
  20. reactpy-2.0.0b2/src/js/packages/@reactpy/client/package.json +36 -0
  21. reactpy-2.0.0b2/src/js/packages/@reactpy/client/src/client.ts +83 -0
  22. reactpy-2.0.0b2/src/js/packages/@reactpy/client/src/components.tsx +229 -0
  23. reactpy-2.0.0b2/src/js/packages/@reactpy/client/src/index.ts +8 -0
  24. reactpy-2.0.0b2/src/js/packages/@reactpy/client/src/logger.ts +6 -0
  25. reactpy-2.0.0b2/src/js/packages/@reactpy/client/src/mount.tsx +41 -0
  26. reactpy-2.0.0b2/src/js/packages/@reactpy/client/src/types.ts +152 -0
  27. reactpy-2.0.0b2/src/js/packages/@reactpy/client/src/vdom.tsx +254 -0
  28. reactpy-2.0.0b2/src/js/packages/@reactpy/client/src/websocket.ts +75 -0
  29. reactpy-2.0.0b2/src/js/packages/@reactpy/client/tsconfig.json +14 -0
  30. reactpy-2.0.0b2/src/js/packages/@reactpy/client/tsconfig.tsbuildinfo +1 -0
  31. reactpy-2.0.0b2/src/js/packages/event-to-object/README.md +3 -0
  32. reactpy-2.0.0b2/src/js/packages/event-to-object/bun.lockb +0 -0
  33. reactpy-2.0.0b2/src/js/packages/event-to-object/package.json +34 -0
  34. reactpy-2.0.0b2/src/js/packages/event-to-object/src/events.ts +257 -0
  35. reactpy-2.0.0b2/src/js/packages/event-to-object/src/index.ts +421 -0
  36. reactpy-2.0.0b2/src/js/packages/event-to-object/tests/event-to-object.test.ts +381 -0
  37. reactpy-2.0.0b2/src/js/packages/event-to-object/tests/tooling/check.ts +46 -0
  38. reactpy-2.0.0b2/src/js/packages/event-to-object/tests/tooling/mock.ts +56 -0
  39. reactpy-2.0.0b2/src/js/packages/event-to-object/tests/tooling/setup.js +22 -0
  40. reactpy-2.0.0b2/src/js/packages/event-to-object/tsconfig.json +9 -0
  41. reactpy-2.0.0b2/src/js/packages/event-to-object/tsconfig.tsbuildinfo +1 -0
  42. reactpy-2.0.0b2/src/js/tsconfig.json +22 -0
  43. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/__init__.py +12 -12
  44. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/_console/ast_utils.py +1 -0
  45. reactpy-2.0.0b2/src/reactpy/_console/cli.py +19 -0
  46. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/_console/rewrite_keys.py +0 -4
  47. reactpy-1.1.0/reactpy/_console/rewrite_camel_case_props.py → reactpy-2.0.0b2/src/reactpy/_console/rewrite_props.py +41 -20
  48. reactpy-2.0.0b2/src/reactpy/_html.py +425 -0
  49. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/_warnings.py +2 -2
  50. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/config.py +50 -8
  51. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/core/_life_cycle_hook.py +44 -18
  52. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/core/_thread_local.py +4 -2
  53. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/core/component.py +2 -2
  54. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/core/events.py +3 -3
  55. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/core/hooks.py +175 -80
  56. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/core/layout.py +27 -20
  57. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/core/serve.py +31 -19
  58. reactpy-2.0.0b2/src/reactpy/core/vdom.py +285 -0
  59. reactpy-2.0.0b2/src/reactpy/executors/asgi/__init__.py +5 -0
  60. reactpy-2.0.0b2/src/reactpy/executors/asgi/middleware.py +295 -0
  61. reactpy-2.0.0b2/src/reactpy/executors/asgi/pyscript.py +123 -0
  62. reactpy-2.0.0b2/src/reactpy/executors/asgi/standalone.py +244 -0
  63. reactpy-2.0.0b2/src/reactpy/executors/asgi/types.py +109 -0
  64. reactpy-2.0.0b2/src/reactpy/executors/utils.py +81 -0
  65. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/logging.py +3 -9
  66. reactpy-2.0.0b2/src/reactpy/pyscript/__init__.py +0 -0
  67. reactpy-2.0.0b2/src/reactpy/pyscript/component_template.py +28 -0
  68. reactpy-2.0.0b2/src/reactpy/pyscript/components.py +62 -0
  69. reactpy-2.0.0b2/src/reactpy/pyscript/layout_handler.py +159 -0
  70. reactpy-2.0.0b2/src/reactpy/pyscript/utils.py +239 -0
  71. reactpy-2.0.0b2/src/reactpy/static/index.js +4 -0
  72. reactpy-2.0.0b2/src/reactpy/static/index.js.map +21 -0
  73. reactpy-2.0.0b2/src/reactpy/static/morphdom/morphdom-esm.js +769 -0
  74. reactpy-2.0.0b2/src/reactpy/static/morphdom/morphdom-factory.js +705 -0
  75. reactpy-2.0.0b2/src/reactpy/static/morphdom/morphdom-umd.js +777 -0
  76. reactpy-2.0.0b2/src/reactpy/static/morphdom/morphdom-umd.min.js +1 -0
  77. reactpy-2.0.0b2/src/reactpy/static/morphdom/morphdom.js +771 -0
  78. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror-DNtCVICy.js +2 -0
  79. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror-DNtCVICy.js.map +1 -0
  80. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror_commands-DvCG1qNv.js +2 -0
  81. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror_commands-DvCG1qNv.js.map +1 -0
  82. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror_lang-python-BgZ6XoEX.js +2 -0
  83. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror_lang-python-BgZ6XoEX.js.map +1 -0
  84. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror_language-ddx8nifT.js +2 -0
  85. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror_language-ddx8nifT.js.map +1 -0
  86. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror_state-1UkzIAPK.js +2 -0
  87. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror_state-1UkzIAPK.js.map +1 -0
  88. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror_view-C2ObO--u.js +2 -0
  89. reactpy-2.0.0b2/src/reactpy/static/pyscript/codemirror_view-C2ObO--u.js.map +1 -0
  90. reactpy-2.0.0b2/src/reactpy/static/pyscript/core-BsIVS0z4.js +4 -0
  91. reactpy-2.0.0b2/src/reactpy/static/pyscript/core-BsIVS0z4.js.map +1 -0
  92. reactpy-2.0.0b2/src/reactpy/static/pyscript/core.css +1 -0
  93. reactpy-2.0.0b2/src/reactpy/static/pyscript/core.js +2 -0
  94. reactpy-2.0.0b2/src/reactpy/static/pyscript/core.js.map +1 -0
  95. reactpy-2.0.0b2/src/reactpy/static/pyscript/deprecations-manager-B8Tz2RBD.js +2 -0
  96. reactpy-2.0.0b2/src/reactpy/static/pyscript/deprecations-manager-B8Tz2RBD.js.map +1 -0
  97. reactpy-2.0.0b2/src/reactpy/static/pyscript/donkey-83vCPSep.js +2 -0
  98. reactpy-2.0.0b2/src/reactpy/static/pyscript/donkey-83vCPSep.js.map +1 -0
  99. reactpy-2.0.0b2/src/reactpy/static/pyscript/error-Bd5T9j4s.js +2 -0
  100. reactpy-2.0.0b2/src/reactpy/static/pyscript/error-Bd5T9j4s.js.map +1 -0
  101. reactpy-2.0.0b2/src/reactpy/static/pyscript/index-978lpDXp.js +2 -0
  102. reactpy-2.0.0b2/src/reactpy/static/pyscript/index-978lpDXp.js.map +1 -0
  103. reactpy-2.0.0b2/src/reactpy/static/pyscript/mpy-De_qSCIU.js +2 -0
  104. reactpy-2.0.0b2/src/reactpy/static/pyscript/mpy-De_qSCIU.js.map +1 -0
  105. reactpy-2.0.0b2/src/reactpy/static/pyscript/py-CdW1_TfR.js +2 -0
  106. reactpy-2.0.0b2/src/reactpy/static/pyscript/py-CdW1_TfR.js.map +1 -0
  107. reactpy-2.0.0b2/src/reactpy/static/pyscript/py-editor-MNjBwLfD.js +2 -0
  108. reactpy-2.0.0b2/src/reactpy/static/pyscript/py-editor-MNjBwLfD.js.map +1 -0
  109. reactpy-2.0.0b2/src/reactpy/static/pyscript/py-game-Did5BuBI.js +2 -0
  110. reactpy-2.0.0b2/src/reactpy/static/pyscript/py-game-Did5BuBI.js.map +1 -0
  111. reactpy-2.0.0b2/src/reactpy/static/pyscript/py-terminal-C3QERaDG.js +2 -0
  112. reactpy-2.0.0b2/src/reactpy/static/pyscript/py-terminal-C3QERaDG.js.map +1 -0
  113. reactpy-2.0.0b2/src/reactpy/static/pyscript/storage.js +2 -0
  114. reactpy-2.0.0b2/src/reactpy/static/pyscript/storage.js.map +1 -0
  115. reactpy-2.0.0b2/src/reactpy/static/pyscript/toml-BLBSZ43A.js +3 -0
  116. reactpy-2.0.0b2/src/reactpy/static/pyscript/toml-BLBSZ43A.js.map +1 -0
  117. reactpy-2.0.0b2/src/reactpy/static/pyscript/toml-DiUM0_qs.js +3 -0
  118. reactpy-2.0.0b2/src/reactpy/static/pyscript/toml-DiUM0_qs.js.map +1 -0
  119. reactpy-2.0.0b2/src/reactpy/static/pyscript/xterm-7LwxAMsn.js +2 -0
  120. reactpy-2.0.0b2/src/reactpy/static/pyscript/xterm-7LwxAMsn.js.map +1 -0
  121. reactpy-2.0.0b2/src/reactpy/static/pyscript/xterm-readline-e8QPhSrm.js +2 -0
  122. reactpy-2.0.0b2/src/reactpy/static/pyscript/xterm-readline-e8QPhSrm.js.map +1 -0
  123. reactpy-2.0.0b2/src/reactpy/static/pyscript/xterm.css +7 -0
  124. reactpy-2.0.0b2/src/reactpy/static/pyscript/xterm_addon-fit--gyF3PcZ.js +2 -0
  125. reactpy-2.0.0b2/src/reactpy/static/pyscript/xterm_addon-fit--gyF3PcZ.js.map +1 -0
  126. reactpy-2.0.0b2/src/reactpy/static/pyscript/xterm_addon-web-links-Cnej-nJ6.js +2 -0
  127. reactpy-2.0.0b2/src/reactpy/static/pyscript/xterm_addon-web-links-Cnej-nJ6.js.map +1 -0
  128. reactpy-2.0.0b2/src/reactpy/static/pyscript/zip-CFEEYRfx.js +2 -0
  129. reactpy-2.0.0b2/src/reactpy/static/pyscript/zip-CFEEYRfx.js.map +1 -0
  130. reactpy-2.0.0b2/src/reactpy/static/pyscript-hide-debug.css +3 -0
  131. reactpy-2.0.0b2/src/reactpy/templatetags/__init__.py +3 -0
  132. reactpy-2.0.0b2/src/reactpy/templatetags/jinja.py +42 -0
  133. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/testing/backend.py +52 -51
  134. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/testing/common.py +13 -9
  135. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/testing/display.py +5 -22
  136. reactpy-2.0.0b2/src/reactpy/testing/utils.py +27 -0
  137. reactpy-2.0.0b2/src/reactpy/transforms.py +409 -0
  138. reactpy-2.0.0b2/src/reactpy/types.py +1073 -0
  139. reactpy-2.0.0b2/src/reactpy/utils.py +311 -0
  140. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/web/__init__.py +1 -3
  141. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/web/module.py +17 -100
  142. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/web/templates/react.js +1 -1
  143. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/widgets.py +5 -5
  144. reactpy-1.1.0/.gitignore +0 -5
  145. reactpy-1.1.0/MANIFEST.in +0 -3
  146. reactpy-1.1.0/PKG-INFO +0 -88
  147. reactpy-1.1.0/README.md +0 -23
  148. reactpy-1.1.0/pyproject.toml +0 -158
  149. reactpy-1.1.0/reactpy/__main__.py +0 -19
  150. reactpy-1.1.0/reactpy/_static/assets/index.1a2d86bf.js +0 -1
  151. reactpy-1.1.0/reactpy/_static/assets/reactpy-logo.ico +0 -0
  152. reactpy-1.1.0/reactpy/_static/index.html +0 -13
  153. reactpy-1.1.0/reactpy/backend/__init__.py +0 -22
  154. reactpy-1.1.0/reactpy/backend/_common.py +0 -144
  155. reactpy-1.1.0/reactpy/backend/default.py +0 -78
  156. reactpy-1.1.0/reactpy/backend/fastapi.py +0 -25
  157. reactpy-1.1.0/reactpy/backend/flask.py +0 -303
  158. reactpy-1.1.0/reactpy/backend/hooks.py +0 -45
  159. reactpy-1.1.0/reactpy/backend/sanic.py +0 -231
  160. reactpy-1.1.0/reactpy/backend/starlette.py +0 -185
  161. reactpy-1.1.0/reactpy/backend/tornado.py +0 -235
  162. reactpy-1.1.0/reactpy/backend/types.py +0 -76
  163. reactpy-1.1.0/reactpy/backend/utils.py +0 -87
  164. reactpy-1.1.0/reactpy/core/types.py +0 -248
  165. reactpy-1.1.0/reactpy/core/vdom.py +0 -351
  166. reactpy-1.1.0/reactpy/html.py +0 -544
  167. reactpy-1.1.0/reactpy/sample.py +0 -21
  168. reactpy-1.1.0/reactpy/svg.py +0 -139
  169. reactpy-1.1.0/reactpy/types.py +0 -51
  170. reactpy-1.1.0/reactpy/utils.py +0 -307
  171. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/_console/__init__.py +0 -0
  172. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/_option.py +0 -0
  173. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/core/__init__.py +0 -0
  174. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/core/_f_back.py +0 -0
  175. reactpy-1.1.0/reactpy/future.py → reactpy-2.0.0b2/src/reactpy/executors/__init__.py +0 -0
  176. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/py.typed +0 -0
  177. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/testing/__init__.py +6 -6
  178. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/testing/logs.py +0 -0
  179. {reactpy-1.1.0 → reactpy-2.0.0b2/src}/reactpy/web/utils.py +0 -0
@@ -0,0 +1,48 @@
1
+ # --- Build Artifacts ---
2
+ src/reactpy/static/index.js*
3
+ src/reactpy/static/morphdom/
4
+ src/reactpy/static/pyscript/
5
+
6
+ # --- Jupyter ---
7
+ *.ipynb_checkpoints
8
+ *Untitled*.ipynb
9
+
10
+ # --- Jupyter Repo 2 Docker ---
11
+ .local
12
+ .ipython
13
+ .cache
14
+ .bash_history
15
+ .python_history
16
+ .jupyter
17
+
18
+ # --- Python ---
19
+ .hatch
20
+ .venv*
21
+ venv*
22
+ MANIFEST
23
+ build
24
+ dist
25
+ .eggs
26
+ *.egg-info
27
+ __pycache__/
28
+ *.py[cod]
29
+ .tox
30
+ .nox
31
+ pip-wheel-metadata
32
+
33
+ # --- PyEnv ---
34
+ .python-version
35
+
36
+ # -- Python Tests ---
37
+ .coverage.*
38
+ *.coverage
39
+ *.pytest_cache
40
+ *.mypy_cache
41
+
42
+ # --- IDE ---
43
+ .idea
44
+ .vscode
45
+
46
+ # --- JS ---
47
+ node_modules
48
+
@@ -0,0 +1,9 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) Reactive Python and affiliates.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,121 @@
1
+ Metadata-Version: 2.4
2
+ Name: reactpy
3
+ Version: 2.0.0b2
4
+ Summary: It's React, but in Python.
5
+ Project-URL: Changelog, https://reactpy.dev/docs/about/changelog.html
6
+ Project-URL: Documentation, https://reactpy.dev/
7
+ Project-URL: Source, https://github.com/reactive-python/reactpy
8
+ Author-email: Mark Bakhit <archiethemonger@gmail.com>, Ryan Morshead <ryan.morshead@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: component,javascript,react,reactpy
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Programming Language :: Python
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: Implementation :: CPython
19
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
20
+ Requires-Python: >=3.9
21
+ Requires-Dist: anyio>=3
22
+ Requires-Dist: fastjsonschema>=2.14.5
23
+ Requires-Dist: lxml>=4
24
+ Requires-Dist: requests>=2
25
+ Requires-Dist: typing-extensions>=3.10
26
+ Provides-Extra: all
27
+ Requires-Dist: asgi-tools; extra == 'all'
28
+ Requires-Dist: asgiref; extra == 'all'
29
+ Requires-Dist: jinja2-simple-tags; extra == 'all'
30
+ Requires-Dist: jinja2>=3; extra == 'all'
31
+ Requires-Dist: orjson; extra == 'all'
32
+ Requires-Dist: pip; extra == 'all'
33
+ Requires-Dist: playwright; extra == 'all'
34
+ Requires-Dist: servestatic; extra == 'all'
35
+ Requires-Dist: uvicorn[standard]; extra == 'all'
36
+ Provides-Extra: asgi
37
+ Requires-Dist: asgi-tools; extra == 'asgi'
38
+ Requires-Dist: asgiref; extra == 'asgi'
39
+ Requires-Dist: orjson; extra == 'asgi'
40
+ Requires-Dist: pip; extra == 'asgi'
41
+ Requires-Dist: servestatic; extra == 'asgi'
42
+ Provides-Extra: jinja
43
+ Requires-Dist: jinja2-simple-tags; extra == 'jinja'
44
+ Requires-Dist: jinja2>=3; extra == 'jinja'
45
+ Provides-Extra: testing
46
+ Requires-Dist: playwright; extra == 'testing'
47
+ Provides-Extra: uvicorn
48
+ Requires-Dist: uvicorn[standard]; extra == 'uvicorn'
49
+ Description-Content-Type: text/markdown
50
+
51
+ # <img src="https://raw.githubusercontent.com/reactive-python/reactpy/main/branding/svg/reactpy-logo-square.svg" align="left" height="45"/> ReactPy
52
+
53
+ <p>
54
+ <a href="https://github.com/reactive-python/reactpy/actions/workflows/check.yml">
55
+ <img src="https://github.com/reactive-python/reactpy/actions/workflows/check.yml/badge.svg">
56
+ </a>
57
+ <a href="https://pypi.org/project/reactpy/">
58
+ <img src="https://img.shields.io/pypi/v/reactpy.svg?label=PyPI">
59
+ </a>
60
+ <a href="https://github.com/reactive-python/reactpy/blob/main/LICENSE">
61
+ <img src="https://img.shields.io/badge/License-MIT-purple.svg">
62
+ </a>
63
+ <a href="https://reactpy.dev/">
64
+ <img src="https://img.shields.io/website?down_message=offline&label=Docs&logo=read-the-docs&logoColor=white&up_message=online&url=https%3A%2F%2Freactpy.dev%2Fdocs%2Findex.html">
65
+ </a>
66
+ <a href="https://discord.gg/uNb5P4hA9X">
67
+ <img src="https://img.shields.io/discord/1111078259854168116?label=Discord&logo=discord">
68
+ </a>
69
+ </p>
70
+
71
+ [ReactPy](https://reactpy.dev/) is a library for building user interfaces in Python without Javascript. ReactPy interfaces are made from components that look and behave similar to those found in [ReactJS](https://reactjs.org/). Designed with simplicity in mind, ReactPy can be used by those without web development experience while also being powerful enough to grow with your ambitions.
72
+
73
+ <table align="center">
74
+ <thead>
75
+ <tr>
76
+ <th colspan="2" style="text-align: center">Supported Backends</th>
77
+ <tr>
78
+ <th style="text-align: center">Built-in</th>
79
+ <th style="text-align: center">External</th>
80
+ </tr>
81
+ </thead>
82
+ <tbody>
83
+ <tr>
84
+ <td>
85
+ <a href="https://reactpy.dev/docs/guides/getting-started/installing-reactpy.html#officially-supported-servers">
86
+ Flask, FastAPI, Sanic, Tornado
87
+ </a>
88
+ </td>
89
+ <td>
90
+ <a href="https://github.com/reactive-python/reactpy-django">Django</a>,
91
+ <a href="https://github.com/reactive-python/reactpy-jupyter">Jupyter</a>,
92
+ <a href="https://github.com/idom-team/idom-dash">Plotly-Dash</a>
93
+ </td>
94
+ </tr>
95
+ </tbody>
96
+ </table>
97
+
98
+ # At a Glance
99
+
100
+ To get a rough idea of how to write apps in ReactPy, take a look at this tiny _Hello World_ application.
101
+
102
+ ```python
103
+ from reactpy import component, html, run
104
+
105
+ @component
106
+ def hello_world():
107
+ return html.h1("Hello, World!")
108
+
109
+ run(hello_world)
110
+ ```
111
+
112
+ # Resources
113
+
114
+ Follow the links below to find out more about this project.
115
+
116
+ - [Try ReactPy (Jupyter Notebook)](https://mybinder.org/v2/gh/reactive-python/reactpy-jupyter/main?urlpath=lab/tree/notebooks/introduction.ipynb)
117
+ - [Documentation](https://reactpy.dev/)
118
+ - [GitHub Discussions](https://github.com/reactive-python/reactpy/discussions)
119
+ - [Discord](https://discord.gg/uNb5P4hA9X)
120
+ - [Contributor Guide](https://reactpy.dev/docs/about/contributor-guide.html)
121
+ - [Code of Conduct](https://github.com/reactive-python/reactpy/blob/main/CODE_OF_CONDUCT.md)
@@ -0,0 +1,71 @@
1
+ # <img src="https://raw.githubusercontent.com/reactive-python/reactpy/main/branding/svg/reactpy-logo-square.svg" align="left" height="45"/> ReactPy
2
+
3
+ <p>
4
+ <a href="https://github.com/reactive-python/reactpy/actions/workflows/check.yml">
5
+ <img src="https://github.com/reactive-python/reactpy/actions/workflows/check.yml/badge.svg">
6
+ </a>
7
+ <a href="https://pypi.org/project/reactpy/">
8
+ <img src="https://img.shields.io/pypi/v/reactpy.svg?label=PyPI">
9
+ </a>
10
+ <a href="https://github.com/reactive-python/reactpy/blob/main/LICENSE">
11
+ <img src="https://img.shields.io/badge/License-MIT-purple.svg">
12
+ </a>
13
+ <a href="https://reactpy.dev/">
14
+ <img src="https://img.shields.io/website?down_message=offline&label=Docs&logo=read-the-docs&logoColor=white&up_message=online&url=https%3A%2F%2Freactpy.dev%2Fdocs%2Findex.html">
15
+ </a>
16
+ <a href="https://discord.gg/uNb5P4hA9X">
17
+ <img src="https://img.shields.io/discord/1111078259854168116?label=Discord&logo=discord">
18
+ </a>
19
+ </p>
20
+
21
+ [ReactPy](https://reactpy.dev/) is a library for building user interfaces in Python without Javascript. ReactPy interfaces are made from components that look and behave similar to those found in [ReactJS](https://reactjs.org/). Designed with simplicity in mind, ReactPy can be used by those without web development experience while also being powerful enough to grow with your ambitions.
22
+
23
+ <table align="center">
24
+ <thead>
25
+ <tr>
26
+ <th colspan="2" style="text-align: center">Supported Backends</th>
27
+ <tr>
28
+ <th style="text-align: center">Built-in</th>
29
+ <th style="text-align: center">External</th>
30
+ </tr>
31
+ </thead>
32
+ <tbody>
33
+ <tr>
34
+ <td>
35
+ <a href="https://reactpy.dev/docs/guides/getting-started/installing-reactpy.html#officially-supported-servers">
36
+ Flask, FastAPI, Sanic, Tornado
37
+ </a>
38
+ </td>
39
+ <td>
40
+ <a href="https://github.com/reactive-python/reactpy-django">Django</a>,
41
+ <a href="https://github.com/reactive-python/reactpy-jupyter">Jupyter</a>,
42
+ <a href="https://github.com/idom-team/idom-dash">Plotly-Dash</a>
43
+ </td>
44
+ </tr>
45
+ </tbody>
46
+ </table>
47
+
48
+ # At a Glance
49
+
50
+ To get a rough idea of how to write apps in ReactPy, take a look at this tiny _Hello World_ application.
51
+
52
+ ```python
53
+ from reactpy import component, html, run
54
+
55
+ @component
56
+ def hello_world():
57
+ return html.h1("Hello, World!")
58
+
59
+ run(hello_world)
60
+ ```
61
+
62
+ # Resources
63
+
64
+ Follow the links below to find out more about this project.
65
+
66
+ - [Try ReactPy (Jupyter Notebook)](https://mybinder.org/v2/gh/reactive-python/reactpy-jupyter/main?urlpath=lab/tree/notebooks/introduction.ipynb)
67
+ - [Documentation](https://reactpy.dev/)
68
+ - [GitHub Discussions](https://github.com/reactive-python/reactpy/discussions)
69
+ - [Discord](https://discord.gg/uNb5P4hA9X)
70
+ - [Contributor Guide](https://reactpy.dev/docs/about/contributor-guide.html)
71
+ - [Code of Conduct](https://github.com/reactive-python/reactpy/blob/main/CODE_OF_CONDUCT.md)
@@ -0,0 +1,335 @@
1
+ [build-system]
2
+ build-backend = "hatchling.build"
3
+ requires = ["hatchling", "hatch-build-scripts"]
4
+
5
+ ##############################
6
+ # >>> Hatch Build Config <<< #
7
+ ##############################
8
+
9
+ [project]
10
+ name = "reactpy"
11
+ description = "It's React, but in Python."
12
+ readme = "README.md"
13
+ keywords = ["react", "javascript", "reactpy", "component"]
14
+ license = "MIT"
15
+ authors = [
16
+ { name = "Mark Bakhit", email = "archiethemonger@gmail.com" },
17
+ { name = "Ryan Morshead", email = "ryan.morshead@gmail.com" },
18
+ ]
19
+ requires-python = ">=3.9"
20
+ classifiers = [
21
+ "Development Status :: 5 - Production/Stable",
22
+ "Programming Language :: Python",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Programming Language :: Python :: Implementation :: CPython",
28
+ "Programming Language :: Python :: Implementation :: PyPy",
29
+ ]
30
+ dependencies = [
31
+ "fastjsonschema >=2.14.5",
32
+ "requests >=2",
33
+ "lxml >=4",
34
+ "anyio >=3",
35
+ "typing-extensions >=3.10",
36
+ ]
37
+ dynamic = ["version"]
38
+ urls.Changelog = "https://reactpy.dev/docs/about/changelog.html"
39
+ urls.Documentation = "https://reactpy.dev/"
40
+ urls.Source = "https://github.com/reactive-python/reactpy"
41
+
42
+ [project.optional-dependencies]
43
+ all = ["reactpy[asgi,jinja,uvicorn,testing]"]
44
+ asgi = ["asgiref", "asgi-tools", "servestatic", "orjson", "pip"]
45
+ jinja = ["jinja2-simple-tags", "jinja2 >=3"]
46
+ uvicorn = ["uvicorn[standard]"]
47
+ testing = ["playwright"]
48
+
49
+ [tool.hatch.version]
50
+ path = "src/reactpy/__init__.py"
51
+
52
+ [tool.hatch.build.targets.sdist]
53
+ include = ["/src"]
54
+ artifacts = ["/src/reactpy/static/"]
55
+
56
+ [tool.hatch.build.targets.wheel]
57
+ artifacts = ["/src/reactpy/static/"]
58
+
59
+ [tool.hatch.metadata]
60
+ license-files = { paths = ["LICENSE"] }
61
+
62
+ [tool.hatch.envs.default]
63
+ installer = "uv"
64
+
65
+ [project.scripts]
66
+ reactpy = "reactpy._console.cli:entry_point"
67
+
68
+ [[tool.hatch.build.hooks.build-scripts.scripts]]
69
+ # Note: `hatch` can't be called within `build-scripts` when installing packages in editable mode, so we have to write the commands long-form
70
+ commands = [
71
+ 'python "src/build_scripts/clean_js_dir.py"',
72
+ 'bun install --cwd "src/js/packages/event-to-object"',
73
+ 'bun run --cwd "src/js/packages/event-to-object" build',
74
+ 'bun install --cwd "src/js/packages/@reactpy/client"',
75
+ 'bun run --cwd "src/js/packages/@reactpy/client" build',
76
+ 'bun install --cwd "src/js/packages/@reactpy/app"',
77
+ 'bun run --cwd "src/js/packages/@reactpy/app" build',
78
+ 'python "src/build_scripts/copy_dir.py" "src/js/packages/@reactpy/app/node_modules/@pyscript/core/dist" "src/reactpy/static/pyscript"',
79
+ 'python "src/build_scripts/copy_dir.py" "src/js/packages/@reactpy/app/node_modules/morphdom/dist" "src/reactpy/static/morphdom"',
80
+ ]
81
+ artifacts = []
82
+
83
+ #############################
84
+ # >>> Hatch Test Runner <<< #
85
+ #############################
86
+
87
+ [tool.hatch.envs.hatch-test]
88
+ extra-dependencies = [
89
+ "reactpy[all]",
90
+ "pytest-sugar",
91
+ "pytest-asyncio",
92
+ "responses",
93
+ "exceptiongroup",
94
+ "jsonpointer",
95
+ "starlette",
96
+ ]
97
+
98
+ [[tool.hatch.envs.hatch-test.matrix]]
99
+ python = ["3.10", "3.11", "3.12", "3.13"]
100
+
101
+ [tool.pytest.ini_options]
102
+ addopts = """\
103
+ --strict-config
104
+ --strict-markers
105
+ """
106
+ filterwarnings = """
107
+ ignore::DeprecationWarning:uvicorn.*
108
+ ignore::DeprecationWarning:websockets.*
109
+ ignore::UserWarning:tests.test_core.test_vdom
110
+ ignore::UserWarning:tests.test_pyscript.test_components
111
+ ignore::UserWarning:tests.test_utils
112
+ """
113
+ testpaths = "tests"
114
+ xfail_strict = true
115
+ asyncio_mode = "auto"
116
+ asyncio_default_fixture_loop_scope = "function"
117
+ log_cli_level = "INFO"
118
+
119
+ #######################################
120
+ # >>> Hatch Documentation Scripts <<< #
121
+ #######################################
122
+ [tool.hatch.envs.docs]
123
+ template = "docs"
124
+ dependencies = ["poetry"]
125
+ detached = true
126
+
127
+ [tool.hatch.envs.docs.scripts]
128
+ build = [
129
+ "cd docs && poetry install",
130
+ "cd docs && poetry run sphinx-build -a -T -W --keep-going -b doctest source build",
131
+ ]
132
+ docker_build = [
133
+ "hatch run docs:build",
134
+ "docker build . --file ./docs/Dockerfile --tag reactpy-docs:latest",
135
+ ]
136
+ docker_serve = [
137
+ "hatch run docs:docker_build",
138
+ "docker run --rm -p 5000:5000 reactpy-docs:latest",
139
+ ]
140
+ check = [
141
+ "cd docs && poetry install",
142
+ "cd docs && poetry run sphinx-build -a -T -W --keep-going -b doctest source build",
143
+ "docker build . --file ./docs/Dockerfile",
144
+ ]
145
+ serve = [
146
+ "cd docs && poetry install",
147
+ "cd docs && poetry run python main.py --watch=../src/ --ignore=**/_auto/* --ignore=**/custom.js --ignore=**/node_modules/* --ignore=**/package-lock.json -a -E -b html source build",
148
+ ]
149
+
150
+ ################################
151
+ # >>> Hatch Python Scripts <<< #
152
+ ################################
153
+
154
+ [tool.hatch.envs.python]
155
+ extra-dependencies = [
156
+ "reactpy[all]",
157
+ "pyright",
158
+ "types-toml",
159
+ "types-click",
160
+ "types-requests",
161
+ "types-lxml",
162
+ "jsonpointer",
163
+ ]
164
+
165
+ [tool.hatch.envs.python.scripts]
166
+ type_check = ["pyright src/reactpy"]
167
+
168
+ ############################
169
+ # >>> Hatch JS Scripts <<< #
170
+ ############################
171
+
172
+ [tool.hatch.envs.javascript]
173
+ detached = true
174
+
175
+ [tool.hatch.envs.javascript.scripts]
176
+ check = [
177
+ 'hatch run javascript:build',
178
+ 'bun install --cwd "src/js"',
179
+ 'bun run --cwd "src/js" lint',
180
+ 'bun run --cwd "src/js/packages/event-to-object" checkTypes',
181
+ 'bun run --cwd "src/js/packages/@reactpy/client" checkTypes',
182
+ 'bun run --cwd "src/js/packages/@reactpy/app" checkTypes',
183
+ ]
184
+ fix = ['bun install --cwd "src/js"', 'bun run --cwd "src/js" format']
185
+ test = [
186
+ 'hatch run javascript:build_event_to_object',
187
+ 'bun run --cwd "src/js/packages/event-to-object" test',
188
+ ]
189
+ build = [
190
+ 'hatch run "src/build_scripts/clean_js_dir.py"',
191
+ 'bun install --cwd "src/js"',
192
+ 'hatch run javascript:build_event_to_object',
193
+ 'hatch run javascript:build_client',
194
+ 'hatch run javascript:build_app',
195
+ ]
196
+ build_event_to_object = [
197
+ 'bun install --cwd "src/js/packages/event-to-object"',
198
+ 'bun run --cwd "src/js/packages/event-to-object" build',
199
+ ]
200
+ build_client = [
201
+ 'bun install --cwd "src/js/packages/@reactpy/client"',
202
+ 'bun run --cwd "src/js/packages/@reactpy/client" build',
203
+ ]
204
+ build_app = [
205
+ 'bun install --cwd "src/js/packages/@reactpy/app"',
206
+ 'bun run --cwd "src/js/packages/@reactpy/app" build',
207
+ ]
208
+ publish_event_to_object = [
209
+ 'hatch run javascript:build_event_to_object',
210
+ 'cd "src/js/packages/event-to-object" && bun publish --access public',
211
+ ]
212
+ publish_client = [
213
+ 'hatch run javascript:build_client',
214
+ 'cd "src/js/packages/@reactpy/client" && bun publish --access public',
215
+ ]
216
+
217
+ #########################
218
+ # >>> Generic Tools <<< #
219
+ #########################
220
+
221
+ [tool.pyright]
222
+ reportIncompatibleVariableOverride = false
223
+
224
+ [tool.coverage.run]
225
+ source_pkgs = ["reactpy"]
226
+ branch = false
227
+ parallel = false
228
+ omit = [
229
+ "src/reactpy/__init__.py",
230
+ "src/reactpy/_console/*",
231
+ "src/reactpy/__main__.py",
232
+ "src/reactpy/pyscript/layout_handler.py",
233
+ "src/reactpy/pyscript/component_template.py",
234
+ ]
235
+
236
+ [tool.coverage.report]
237
+ fail_under = 100
238
+ show_missing = true
239
+ skip_covered = true
240
+ sort = "Name"
241
+ exclude_also = [
242
+ "no ?cov",
243
+ '\.\.\.',
244
+ "if __name__ == .__main__.:",
245
+ "if TYPE_CHECKING:",
246
+ ]
247
+
248
+ [tool.ruff]
249
+ line-length = 88
250
+ lint.select = [
251
+ "A",
252
+ "ARG",
253
+ "B",
254
+ "C",
255
+ "DTZ",
256
+ "E",
257
+ # error message linting is overkill
258
+ # "EM",
259
+ "F",
260
+ # TODO: turn this on later
261
+ # "FBT",
262
+ "I",
263
+ "ICN",
264
+ "N",
265
+ "PLC",
266
+ "PLE",
267
+ "PLR",
268
+ "PLW",
269
+ "Q",
270
+ "RUF",
271
+ "S",
272
+ "T",
273
+ "TID",
274
+ "UP",
275
+ "W",
276
+ "YTT",
277
+ ]
278
+ lint.ignore = [
279
+ # TODO: turn this on later
280
+ "N802",
281
+ "N806", # allow TitleCase functions/variables
282
+ # We're not any cryptography
283
+ "S311",
284
+ # For loop variable re-assignment seems like an uncommon mistake
285
+ "PLW2901",
286
+ # Let Black deal with line-length
287
+ "E501",
288
+ # Allow args/attrs to shadow built-ins
289
+ "A002",
290
+ "A003",
291
+ # Allow unused args (useful for documenting what the parameter is for later)
292
+ "ARG001",
293
+ "ARG002",
294
+ "ARG005",
295
+ # Allow non-abstract empty methods in abstract base classes
296
+ "B027",
297
+ # Allow boolean positional values in function calls, like `dict.get(... True)`
298
+ "FBT003",
299
+ # If we're making an explicit comparison to a falsy value it was probably intentional
300
+ "PLC1901",
301
+ # Ignore checks for possible passwords
302
+ "S105",
303
+ "S106",
304
+ "S107",
305
+ # Ignore complexity
306
+ "C901",
307
+ "PLR0911",
308
+ "PLR0912",
309
+ "PLR0913",
310
+ "PLR0915",
311
+ ]
312
+ lint.unfixable = [
313
+ # Don't touch unused imports
314
+ "F401",
315
+ ]
316
+
317
+ [tool.ruff.lint.isort]
318
+ known-first-party = ["reactpy"]
319
+ known-third-party = ["js"]
320
+
321
+ [tool.ruff.lint.per-file-ignores]
322
+ # Tests can use magic values, assertions, and relative imports
323
+ "**/tests/**/*" = ["PLR2004", "S101", "TID252"]
324
+ "docs/**/*.py" = [
325
+ # Examples require some extra setup before import
326
+ "E402",
327
+ # Allow exec
328
+ "S102",
329
+ # Allow print
330
+ "T201",
331
+ ]
332
+ "scripts/**/*.py" = [
333
+ # Allow print
334
+ "T201",
335
+ ]
@@ -0,0 +1,41 @@
1
+ # /// script
2
+ # requires-python = ">=3.11"
3
+ # dependencies = []
4
+ # ///
5
+
6
+ # Deletes `dist`, `node_modules`, and `tsconfig.tsbuildinfo` from all JS packages in the JS source directory.
7
+
8
+ import contextlib
9
+ import glob
10
+ import os
11
+ import pathlib
12
+ import shutil
13
+
14
+ # Get the path to the JS source directory
15
+ js_src_dir = pathlib.Path(__file__).parent.parent / "js"
16
+
17
+ # Get the paths to all `dist` folders in the JS source directory
18
+ dist_dirs = glob.glob(str(js_src_dir / "**/dist"), recursive=True)
19
+
20
+ # Get the paths to all `node_modules` folders in the JS source directory
21
+ node_modules_dirs = glob.glob(str(js_src_dir / "**/node_modules"), recursive=True)
22
+
23
+ # Get the paths to all `tsconfig.tsbuildinfo` files in the JS source directory
24
+ tsconfig_tsbuildinfo_files = glob.glob(
25
+ str(js_src_dir / "**/tsconfig.tsbuildinfo"), recursive=True
26
+ )
27
+
28
+ # Delete all `dist` folders
29
+ for dist_dir in dist_dirs:
30
+ with contextlib.suppress(FileNotFoundError):
31
+ shutil.rmtree(dist_dir)
32
+
33
+ # Delete all `node_modules` folders
34
+ for node_modules_dir in node_modules_dirs:
35
+ with contextlib.suppress(FileNotFoundError):
36
+ shutil.rmtree(node_modules_dir)
37
+
38
+ # Delete all `tsconfig.tsbuildinfo` files
39
+ for tsconfig_tsbuildinfo_file in tsconfig_tsbuildinfo_files:
40
+ with contextlib.suppress(FileNotFoundError):
41
+ os.remove(tsconfig_tsbuildinfo_file)
@@ -0,0 +1,40 @@
1
+ # /// script
2
+ # requires-python = ">=3.11"
3
+ # dependencies = []
4
+ # ///
5
+
6
+ # ruff: noqa: INP001
7
+ import logging
8
+ import shutil
9
+ import sys
10
+ from pathlib import Path
11
+
12
+
13
+ def copy_files(source: Path, destination: Path) -> None:
14
+ if destination.exists():
15
+ shutil.rmtree(destination)
16
+ destination.mkdir()
17
+
18
+ for file in source.iterdir():
19
+ if file.is_file():
20
+ shutil.copy(file, destination / file.name)
21
+ else:
22
+ copy_files(file, destination / file.name)
23
+
24
+
25
+ if __name__ == "__main__":
26
+ if len(sys.argv) != 3: # noqa
27
+ logging.error(
28
+ "Script used incorrectly!\nUsage: python copy_dir.py <source_dir> <destination>"
29
+ )
30
+ sys.exit(1)
31
+
32
+ root_dir = Path(__file__).parent.parent.parent
33
+ src = Path(root_dir / sys.argv[1])
34
+ dest = Path(root_dir / sys.argv[2])
35
+
36
+ if not src.exists():
37
+ logging.error("Source directory %s does not exist", src)
38
+ sys.exit(1)
39
+
40
+ copy_files(src, dest)
@@ -0,0 +1,5 @@
1
+ tsconfig.tsbuildinfo
2
+ packages/**/package-lock.json
3
+ **/dist/*
4
+ node_modules
5
+ *.tgz
@@ -0,0 +1,3 @@
1
+ # ReactPy Client
2
+
3
+ An ES6 Javascript client for ReactPy
Binary file