Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reactpy fixes and updates #1162

Merged
merged 14 commits into from
Mar 4, 2025
Merged

Reactpy fixes and updates #1162

merged 14 commits into from
Mar 4, 2025

Conversation

shawncrawley
Copy link
Contributor

Description

The work herein was initiated to fix a critical bug with Tethys ReactPy apps, but became somewhat gold-plated with a few additional features and fixes.

Critical bugfix:
Namely, having separate ComponentLibrary instances - one per app page - rather having a single, global instance. The ComponentLibrary was designed to dynamically keep track of an app's dependencies. On initial development, it was implemented as a single, global library shared by all apps and pages. This led to the issue of separate apps and pages essentially fighting over the ComponentLibrary, overwriting the dependencies for each other or injecting unneeded ones for other apps/pages.

Other Bugfixes:

  • use_workspace is now built on the correct ReactPy use_query paradigm that allows the Django ORM to be queried to check quotas without raising an error or having to do other hokey workarounds. The use_query Promise-like object was wrapped and customized to substitute checking_quota and quota_exceeded for loading and error, respectively. It is now used as follows:
@App.page
def my_page(lib):
    user_workspace = lib.hooks.use_workspace(user=user)
    if user_workspace.checking_quota:
        return lib.html.h1("Loading")
    elif user_workspace.quota_exceeded:
        return lib.html.h2("You have exceeded your storage quota")
    else:
        user_file_path = user_workspace.path / "user.file"
        ...
  • Test app/extension setup.py files were replaces with pyproject.toml files to resolve broken installation of those resources during testing

Additional features:

  • Removes the need for the Props argument by implementing a new syntactical interface for defining ReactPy code: <elem>(**props_as_kwargs)(*children_as_args). For example:
lib.html.div(class_name="my-containers")(
    lib.html.img(class_name="my-images", src="/path/to/my-image.png")
)

Instead of

lib.html.div(Props(class_name="my-containers"), 
    lib.html.img(Props(class_name="my-images", src="/path/to/my-image.png"))
)
  • Condenses ReactPy scaffold down to app.py as the only required app file:
from tethys_sdk.base import ReactPyBase


class App(ReactPyBase):
    """
    Tethys app class for {{proper_name}}.
    """

    name = '{{proper_name}}'
    description = '{{description|default("Place a brief description of your app here.")}}'
    package = '{{project}}'  # WARNING: Do not change this value
    index = 'home'
    icon = f'{package}/images/icon.png'
    root_url = '{{project_url}}'
    color = '{{color}}'
    tags = '{{tags}}'
    enable_feedback = False
    feedback_emails = []
    exit_url = '/apps/'
    default_layout = "NavHeader"
    nav_links = "auto"


@App.page
def home(lib):
    map_center, set_map_center = lib.hooks.use_state([39.254852, -98.593853])
    map_zoom, set_map_zoom = lib.hooks.use_state(4)
    
    return lib.html.div(
        lib.pm.Map(
            height="calc(100vh - 62px)",
            defaultCenter=map_center,
            defaultZoom=map_zoom
        )
    )

  • New hooks were created for all Paths API objects: use_workspace(user=None), use_media(user=None), use_resources() and use_public()

Changes Made to Code

Additional Notes

Quality Checks

  • At least one new test has been written for new code
  • New code has 100% test coverage
  • Code has been formatted with Black
  • Code has been linted with flake8
  • Docstrings for new methods have been added
  • The documentation has been updated appropriately (there's no documentation yet, that's what I'll be overhauling in my next PR)

The tethys_components.library contained a singleton implementation of the ComponentLibrary class. This was found to have bugs when running multiple apps. Thus, the underlying framework had to be reworked a bit to have the separate library instances exist at the page level.

Tests still need to be written.
Here is that interface: <component>(**props_as_kwargs)(*children_as_args)
Highlights true single-file/language app development
@coveralls
Copy link

coveralls commented Mar 3, 2025

Coverage Status

coverage: 99.991% (-0.009%) from 100.0%
when pulling fbce1f4 on reactpy-fixes
into f06fa71 on main.

Copy link
Member

@swainn swainn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comments

Copy link
Member

@swainn swainn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved on the contingency of a future debate on the naming conventions.

@swainn swainn merged commit 1130e3a into main Mar 4, 2025
42 checks passed
@swainn swainn deleted the reactpy-fixes branch March 4, 2025 23:53
swainn pushed a commit that referenced this pull request Mar 5, 2025
* Components lib no longer singleton but tied to app

The tethys_components.library contained a singleton implementation of the ComponentLibrary class. This was found to have bugs when running multiple apps. Thus, the underlying framework had to be reworked a bit to have the separate library instances exist at the page level.

Tests still need to be written.

* reactpy tests added/updated

* Adds docstrings and makes methods private

* Uncomments necessary code

* Fixes test to restore full coverage

* Fixes incomplete refactor

* Implements new ReactPy interface w/o Props
Here is that interface: <component>(**props_as_kwargs)(*children_as_args)

* Remove pages and add scaffold page to app.py
Highlights true single-file/language app development

* Fixes and formats reactpy scaffold template files

* Tweak to app.py_tmpl

* Removes workspaces from reactpy scaffold

* Formats from black and flake8

* Tweaks per feeback by @NSwain
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants