|
2 | 2 |
|
3 | 3 | import contextlib
|
4 | 4 | import inspect
|
5 |
| -import json |
6 | 5 | import logging
|
7 | 6 | import os
|
8 | 7 | import re
|
9 |
| -import textwrap |
10 | 8 | from asyncio import iscoroutinefunction
|
11 | 9 | from concurrent.futures import ThreadPoolExecutor
|
12 |
| -from copy import deepcopy |
13 | 10 | from fnmatch import fnmatch
|
14 | 11 | from functools import wraps
|
15 | 12 | from importlib import import_module
|
16 |
| -from pathlib import Path |
17 |
| -from typing import TYPE_CHECKING, Any, Callable |
| 13 | +from typing import TYPE_CHECKING, Any, Awaitable, Callable |
18 | 14 | from uuid import UUID, uuid4
|
19 | 15 |
|
20 | 16 | import dill
|
21 |
| -import jsonpointer |
22 |
| -import orjson |
23 |
| -import reactpy |
24 | 17 | from asgiref.sync import async_to_sync
|
25 | 18 | from channels.db import database_sync_to_async
|
26 | 19 | from django.db.models import ManyToManyField, ManyToOneRel, prefetch_related_objects
|
27 | 20 | from django.db.models.base import Model
|
28 | 21 | from django.db.models.query import QuerySet
|
29 | 22 | from django.http import HttpRequest, HttpResponse
|
30 | 23 | from django.template import engines
|
31 |
| -from django.templatetags.static import static |
32 | 24 | from django.utils.encoding import smart_str
|
33 | 25 | from reactpy import vdom_to_html
|
34 | 26 | from reactpy.backend.types import Connection, Location
|
|
41 | 33 | InvalidHostError,
|
42 | 34 | ViewDoesNotExistError,
|
43 | 35 | )
|
| 36 | +from reactpy_django.types import FuncParams, Inferred |
44 | 37 |
|
45 | 38 | if TYPE_CHECKING:
|
46 | 39 | from collections.abc import Awaitable, Mapping, Sequence
|
|
65 | 58 | + rf"({_OFFLINE_KWARG_PATTERN}|{_GENERIC_KWARG_PATTERN})*?"
|
66 | 59 | + r"\s*%}"
|
67 | 60 | )
|
68 |
| -PYSCRIPT_COMPONENT_TEMPLATE = (Path(__file__).parent / "pyscript" / "component_template.py").read_text(encoding="utf-8") |
69 |
| -PYSCRIPT_LAYOUT_HANDLER = (Path(__file__).parent / "pyscript" / "layout_handler.py").read_text(encoding="utf-8") |
70 |
| -PYSCRIPT_DEFAULT_CONFIG: dict[str, Any] = {} |
71 | 61 | FILE_ASYNC_ITERATOR_THREAD = ThreadPoolExecutor(max_workers=1, thread_name_prefix="ReactPy-Django-FileAsyncIterator")
|
72 | 62 |
|
73 | 63 |
|
@@ -441,72 +431,6 @@ def vdom_or_component_to_string(
|
441 | 431 | raise ValueError(msg)
|
442 | 432 |
|
443 | 433 |
|
444 |
| -def render_pyscript_template(file_paths: Sequence[str], uuid: str, root: str): |
445 |
| - """Inserts the user's code into the PyScript template using pattern matching.""" |
446 |
| - from django.core.cache import caches |
447 |
| - |
448 |
| - from reactpy_django.config import REACTPY_CACHE |
449 |
| - |
450 |
| - # Create a valid PyScript executor by replacing the template values |
451 |
| - executor = PYSCRIPT_COMPONENT_TEMPLATE.replace("UUID", uuid) |
452 |
| - executor = executor.replace("return root()", f"return {root}()") |
453 |
| - |
454 |
| - # Fetch the user's PyScript code |
455 |
| - all_file_contents: list[str] = [] |
456 |
| - for file_path in file_paths: |
457 |
| - # Try to get user code from cache |
458 |
| - cache_key = create_cache_key("pyscript", file_path) |
459 |
| - last_modified_time = os.stat(file_path).st_mtime |
460 |
| - file_contents: str = caches[REACTPY_CACHE].get(cache_key, version=int(last_modified_time)) |
461 |
| - if file_contents: |
462 |
| - all_file_contents.append(file_contents) |
463 |
| - |
464 |
| - # If not cached, read from file system |
465 |
| - else: |
466 |
| - file_contents = Path(file_path).read_text(encoding="utf-8").strip() |
467 |
| - all_file_contents.append(file_contents) |
468 |
| - caches[REACTPY_CACHE].set(cache_key, file_contents, version=int(last_modified_time)) |
469 |
| - |
470 |
| - # Prepare the PyScript code block |
471 |
| - user_code = "\n".join(all_file_contents) # Combine all user code |
472 |
| - user_code = user_code.replace("\t", " ") # Normalize the text |
473 |
| - user_code = textwrap.indent(user_code, " ") # Add indentation to match template |
474 |
| - |
475 |
| - # Insert the user code into the PyScript template |
476 |
| - return executor.replace(" def root(): ...", user_code) |
477 |
| - |
478 |
| - |
479 |
| -def extend_pyscript_config(extra_py: Sequence, extra_js: dict | str, config: dict | str) -> str: |
480 |
| - """Extends ReactPy's default PyScript config with user provided values.""" |
481 |
| - # Lazily set up the initial config in to wait for Django's static file system |
482 |
| - if not PYSCRIPT_DEFAULT_CONFIG: |
483 |
| - PYSCRIPT_DEFAULT_CONFIG.update({ |
484 |
| - "packages": [ |
485 |
| - f"reactpy=={reactpy.__version__}", |
486 |
| - f"jsonpointer=={jsonpointer.__version__}", |
487 |
| - "ssl", |
488 |
| - ], |
489 |
| - "js_modules": {"main": {static("reactpy_django/morphdom/morphdom-esm.js"): "morphdom"}}, |
490 |
| - }) |
491 |
| - |
492 |
| - # Extend the Python dependency list |
493 |
| - pyscript_config = deepcopy(PYSCRIPT_DEFAULT_CONFIG) |
494 |
| - pyscript_config["packages"].extend(extra_py) |
495 |
| - |
496 |
| - # Extend the JavaScript dependency list |
497 |
| - if extra_js and isinstance(extra_js, str): |
498 |
| - pyscript_config["js_modules"]["main"].update(json.loads(extra_js)) |
499 |
| - elif extra_js and isinstance(extra_js, dict): |
500 |
| - pyscript_config["js_modules"]["main"].update(extra_py) |
501 |
| - |
502 |
| - # Update the config |
503 |
| - if config and isinstance(config, str): |
504 |
| - pyscript_config.update(json.loads(config)) |
505 |
| - elif config and isinstance(config, dict): |
506 |
| - pyscript_config.update(config) |
507 |
| - return orjson.dumps(pyscript_config).decode("utf-8") |
508 |
| - |
509 |
| - |
510 | 434 | def save_component_params(args, kwargs, uuid) -> None:
|
511 | 435 | """Saves the component parameters to the database.
|
512 | 436 | This is used within our template tag in order to propogate
|
|
0 commit comments