Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b88e533
Refactoring for ReactPy 2.0
shawncrawley Feb 12, 2026
e2a974d
Revert router syntax change
shawncrawley Feb 13, 2026
4f9cc9c
Refactor the client
Archmonger Feb 14, 2026
00be62b
Remove built-in `html.pyscript` vdom shortcut
Archmonger Feb 14, 2026
807c519
Remove old nest_asyncio patch
Archmonger Feb 14, 2026
2677970
fix a few tests
Archmonger Feb 16, 2026
35e1a40
Switch ReactPy django components to class-based alternatives (could n…
Archmonger Feb 16, 2026
942ebb0
Fix warnings
Archmonger Feb 16, 2026
e320cb8
reduce amount of times quirks mode is used
Archmonger Feb 17, 2026
106513e
prevent queries and mutations from being cancelled by asyncio
Archmonger Feb 17, 2026
54e44f4
Fix Django forms (convert new ReactPy `Event` type to a plain `dict`)
Archmonger Feb 17, 2026
c8a1740
Use the ReactPy core's PyScript hooks (new PR, coming soon in v2.0.0b…
Archmonger Feb 17, 2026
52bbbce
hatch fmt
Archmonger Feb 17, 2026
9c02410
fix url router
Archmonger Feb 18, 2026
e221ded
Add new dev helpful scripts
Archmonger Feb 18, 2026
061c902
auto-copy reactpy embedded wheel at start-up
Archmonger Apr 18, 2026
176bd42
fix test runner deprecation warnings
Archmonger Apr 18, 2026
bd4c863
bump deps
Archmonger Jul 9, 2026
2fef5c7
prepare for reactpy 2.0.0b13
Archmonger Jul 9, 2026
557aa8c
Merge remote-tracking branch 'github-desktop-shawncrawley/refactor-fo…
Archmonger Jul 9, 2026
58a8fef
small bugfixes
Archmonger Jul 10, 2026
785b5ca
make pyscript override more resilient to upstream changes
Archmonger Jul 11, 2026
282c559
bump reactpy version
Archmonger Jul 14, 2026
ad5348f
fix type check
Archmonger Jul 14, 2026
17a371c
bump ci python versions
Archmonger Jul 14, 2026
6bdce4e
reformat to match latest python versions
Archmonger Jul 14, 2026
24bd3fc
update changelog
Archmonger Jul 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
runs-on: ${{ matrix.operating-system }}
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.11", "3.12", "3.13", "3.14"]
settings-module: ["single_db", "multi_db"]
operating-system: ["ubuntu-latest", "windows-latest"]
steps:
Expand Down
423 changes: 222 additions & 201 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ Additionally, you can pass in `args` and `kwargs` into your component function.
<!--html-code-start-->

```jinja
{% load reactpy %}
<!DOCTYPE html>
{% load reactpy %}
<html>
<body>
{% component "example_project.my_app.components.hello_world" recipient="World" %}
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/html/pyscript_component.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% load reactpy %}
<!DOCTYPE html>
{% load reactpy %}
<html>

<head>
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/html/pyscript_local_import.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% load reactpy %}
<!DOCTYPE html>
{% load reactpy %}
<html>

<head>
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/html/pyscript_multiple_files.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% load reactpy %}
<!DOCTYPE html>
{% load reactpy %}
<html>

<head>
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/html/pyscript_setup_extra_js_object.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% load reactpy %}
<!DOCTYPE html>
{% load reactpy %}
<html>

<head>
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/html/pyscript_setup_extra_js_string.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% load reactpy %}
<!DOCTYPE html>
{% load reactpy %}
<html>

<head>
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/html/pyscript_ssr_parent.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% load reactpy %}
<!DOCTYPE html>
{% load reactpy %}
<html>

<head>
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/html/pyscript_tag.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{% load reactpy %}
<!DOCTYPE html>
{% load reactpy %}
<html>

<head>
Expand Down
4 changes: 1 addition & 3 deletions docs/examples/python/pyscript_component_initial_object.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from reactpy import component, html

from reactpy_django.components import pyscript_component
from reactpy import component, html, pyscript_component


@component
Expand Down
4 changes: 1 addition & 3 deletions docs/examples/python/pyscript_component_initial_string.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from reactpy import component, html

from reactpy_django.components import pyscript_component
from reactpy import component, html, pyscript_component


@component
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from reactpy import component, html

from reactpy_django.components import pyscript_component
from reactpy import component, html, pyscript_component


@component
Expand Down
4 changes: 1 addition & 3 deletions docs/examples/python/pyscript_component_root.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from reactpy import component, html

from reactpy_django.components import pyscript_component
from reactpy import component, html, pyscript_component


@component
Expand Down
8 changes: 4 additions & 4 deletions docs/examples/python/pyscript_ssr_parent.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from reactpy import component, html

from reactpy_django.components import pyscript_component
from reactpy import component, html, pyscript_component


@component
def server_side_component():
return html.div(
"This text is from my server-side component",
pyscript_component("./example_project/my_app/components/root.py"),
pyscript_component(
"./example_project/my_app/components/root.py",
),
)
6 changes: 1 addition & 5 deletions docs/examples/python/pyscript_tag.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
from reactpy import component, html

from reactpy_django.html import pyscript

example_source_code = """
import js

Expand All @@ -11,6 +9,4 @@

@component
def server_side_component():
return html.div(
pyscript(example_source_code.strip()),
)
return html.py_script(example_source_code.strip())
2 changes: 1 addition & 1 deletion docs/examples/python/use_location.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
def my_component():
location = use_location()

return html.div(location.pathname + location.search)
return html.div(location.path + location.query_string)
2 changes: 1 addition & 1 deletion docs/overrides/homepage_examples/add_interactivity.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def searchable_video_list(videos):
search_text, set_search_text = use_state("")
found_videos = filter_videos(videos, search_text)

return html._(
return html(
search_input(
{"onChange": lambda event: set_search_text(event["target"]["value"])},
value=search_text,
Expand Down
8 changes: 4 additions & 4 deletions docs/src/about/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@

If you plan to make code changes to this repository, you will need to install the following dependencies first:

- [Git](https://git-scm.com/downloads)
- [Python 3.9+](https://www.python.org/downloads/)
- [Hatch](https://hatch.pypa.io/latest/)
- [Bun](https://bun.sh/)
- [Git](https://git-scm.com/downloads)
- [Python 3.11+](https://www.python.org/downloads/)
- [Hatch](https://hatch.pypa.io/latest/)
- [Bun](https://bun.sh/)

Once you finish installing these dependencies, you can clone this repository:

Expand Down
2 changes: 1 addition & 1 deletion docs/src/reference/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ This allows you to embedded any number of client-side PyScript components within
| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `#!python *file_paths` | `#!python str` | File path to your client-side component. If multiple paths are provided, the contents are automatically merged. | N/A |
| `#!python initial` | `#!python str | VdomDict | ComponentType` | The initial HTML that is displayed prior to the PyScript component loads. This can either be a string containing raw HTML, a `#!python reactpy.html` snippet, or a non-interactive component. | `#!python ""` |
| `#!python initial` | `#!python str | VdomDict | Component` | The initial HTML that is displayed prior to the PyScript component loads. This can either be a string containing raw HTML, a `#!python reactpy.html` snippet, or a non-interactive component. | `#!python ""` |
| `#!python root` | `#!python str` | The name of the root component function. | `#!python "root"` |

<!--pyscript-setup-required-start-->
Expand Down
2 changes: 1 addition & 1 deletion docs/src/reference/hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ Shortcut that returns the browser's current `#!python Location`.

| Type | Description |
| --- | --- |
| `#!python Location` | An object containing the current URL's `#!python pathname` and `#!python search` query. |
| `#!python Location` | An object containing the current URL's `#!python path` and `#!python query_string` query. |

---

Expand Down
4 changes: 2 additions & 2 deletions docs/src/reference/template-tag.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ Each component loaded via this template tag will receive a dedicated WebSocket c
=== "my_template.html"

```jinja
{% load reactpy %}
<!DOCTYPE html>
{% load reactpy %}
<html>
<body>
<h1>{% component "example_project.my_app.components.my_title" %}</h1>
Expand Down Expand Up @@ -191,7 +191,7 @@ Your Python component file will be directly loaded into the browser. It must hav
| Name | Type | Description | Default |
| --- | --- | --- | --- |
| `#!python *file_paths` | `#!python str` | File path to your client-side component. If multiple paths are provided, the contents are automatically merged. | N/A |
| `#!python initial` | `#!python str | VdomDict | ComponentType` | The initial HTML that is displayed prior to the PyScript component loads. This can either be a string containing raw HTML, a `#!python reactpy.html` snippet, or a non-interactive component. | `#!python ""` |
| `#!python initial` | `#!python str | VdomDict | Component` | The initial HTML that is displayed prior to the PyScript component loads. This can either be a string containing raw HTML, a `#!python reactpy.html` snippet, or a non-interactive component. | `#!python ""` |
| `#!python root` | `#!python str` | The name of the root component function. | `#!python "root"` |

<!--pyscript-webtypy-start-->
Expand Down
44 changes: 20 additions & 24 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,10 @@ classifiers = [
dependencies = [
"channels>=4.0.0",
"django>=4.2.0",
"reactpy>=1.1.0, <2.0.0",
"reactpy-router>=1.0.3, <2.0.0",
"reactpy>=2.0.0b13, <3.0.0",
"reactpy-router>=3.0.0b1, <4.0.0",
"dill>=0.3.5",
"orjson>=3.6.0",
"nest_asyncio>=1.5.0",
"typing_extensions",
]
dynamic = ["version"]
Expand All @@ -68,6 +67,7 @@ artifacts = ["/src/reactpy_django/static/"]

[tool.hatch.metadata]
license-files = { paths = ["LICENSE.md"] }
allow-direct-references = true

[tool.hatch.envs.default]
installer = "uv"
Expand All @@ -76,8 +76,8 @@ installer = "uv"
commands = [
"bun install --cwd src/js",
'bun build src/js/src/index.ts --outdir="src/reactpy_django/static/reactpy_django/" --minify --sourcemap=linked',
'cd src/build_scripts && python copy_dir.py "src/js/node_modules/@pyscript/core/dist" "src/reactpy_django/static/reactpy_django/pyscript"',
'cd src/build_scripts && python copy_dir.py "src/js/node_modules/morphdom/dist" "src/reactpy_django/static/reactpy_django/morphdom"',
'cd src/scripts && python copy_dir.py "src/js/node_modules/@pyscript/core/dist" "src/reactpy_django/static/reactpy_django/pyscript"',
'cd src/scripts && python copy_dir.py "src/js/node_modules/morphdom/dist" "src/reactpy_django/static/reactpy_django/morphdom"',
]
artifacts = []

Expand All @@ -96,36 +96,29 @@ extra-dependencies = [
"servestatic",
"django-bootstrap5",
"decorator",

"uvicorn[standard]",
]
matrix-name-format = "{variable}-{value}"

# Django 4.2
[[tool.hatch.envs.hatch-test.matrix]]
python = ["3.9", "3.10", "3.11", "3.12"]
django = ["4.2"]

# Django 5.0
# Django 5.2
[[tool.hatch.envs.hatch-test.matrix]]
python = ["3.10", "3.11", "3.12"]
django = ["5.0"]
python = ["3.11", "3.12", "3.13", "3.14"]
django = ["5.2"]

# Django 5.1
# Django 6
[[tool.hatch.envs.hatch-test.matrix]]
python = ["3.10", "3.11", "3.12", "3.13"]
django = ["5.1"]
python = ["3.12", "3.13", "3.14"]
django = ["6.0"]

[tool.hatch.envs.hatch-test.overrides]
matrix.django.dependencies = [
{ if = [
"4.2",
], value = "django~=4.2" },
{ if = [
"5.0",
], value = "django~=5.0" },
"5.2",
], value = "django~=5.2" },
{ if = [
"5.1",
], value = "django~=5.1" },
"6.0",
], value = "django~=6.0" },
]

[tool.pytest.ini_options]
Expand Down Expand Up @@ -177,7 +170,7 @@ template = "docs"
extra-dependencies = [
"mkdocs",
"mkdocs-git-revision-date-localized-plugin",
"mkdocs-material==9.4.0",
"mkdocs-material",
"mkdocs-include-markdown-plugin",
"mkdocs-spellcheck[all]",
"mkdocs-git-authors-plugin",
Expand Down Expand Up @@ -245,6 +238,9 @@ lint.extend-ignore = [
"S403", # `dill` module is possibly insecure
"S301", # `dill` deserialization is possibly insecure unless using trusted data
"RUF029", # Function is declared async but doesn't contain await expression
"DOC201", # `return` is not documented in docstring
"DOC501", # `Exception` is not documented in docstring
"S308", # Django `mark_safe` may expose cross-site scripting vulnerabilities
]
lint.preview = true
lint.isort.known-first-party = ["reactpy_django", "test_app", "example"]
Expand Down
Binary file modified src/js/bun.lockb
Binary file not shown.
28 changes: 12 additions & 16 deletions src/js/package.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
{
"dependencies": {
"@pyscript/core": "^0.6",
"@reactpy/client": "^0.3.2",
"event-to-object": "^0.1.2",
"morphdom": "^2.7.4",
"preact": "^10.26.9",
"react": "npm:@preact/compat@17.1.2",
"react-dom": "npm:@preact/compat@17.1.2"
"@pyscript/core": "^0.7.29",
"@reactpy/client": "^1.3.0",
"morphdom": "^2.7.8"
},
"devDependencies": {
"@eslint/js": "^9.29.0",
"bun-types": "^0.5.0",
"eslint": "^9.13.0",
"globals": "^16.2.0",
"prettier": "^3.3.3",
"typescript": "^5.8.3",
"typescript-eslint": "^8.34.0"
"@eslint/js": "^10.0.1",
"bun-types": "^1.3.14",
"eslint": "^10.6.0",
"globals": "^17.7.0",
"prettier": "^3.9.4",
"typescript": "^6.0.3",
"typescript-eslint": "^8.63.0"
},
"license": "MIT",
"name": "@reactpy-django/app",
"scripts": {
"check": "prettier --check . && eslint",
"format": "prettier --write . && eslint --fix"
},
"type": "module"
}
}
Loading
Loading