Solara Documentation

repository·master·Indexed 24 days ago

https://github.com/widgetti/solara

A pure Python, React-style framework for building scalable Jupyter and web applications. Solara leverages ipywidgets to provide component-based code organization and reactive state management. It features an opt-in state persistence mechanism using Redis for high availability and cross-instance failover, allowing applications to recover state during websocket reconnections without page reloads.

Tokens
71.8K
Snippets
176
Records
329
Agent score
80%

What's inside Solara

  1. Overview of deploying a Solara app

    master

    Solara applications and dashboards can be deployed using two primary methods:

    1. Self-hosted: You manage the infrastructure and run the application on your own servers.
    2. Cloud-hosted: You use a cloud platform provider to host the application.

    Scaling and Reliability: When running your application across multiple instances, you should implement state persistence to ensure that user sessions can be recovered after a crash, during scale-in operations, or during new deployments.

  2. What is ipyvuetify and how does it relate to Solara?

    master

    ipyvuetify is an ipywidgets-based library that wraps the Vuetify JavaScript component library to provide Material Design widgets for Python.

    Solara integrates with ipyvuetify in two ways:

    1. Direct usage: You can use ipyvuetify widgets via the reacton.ipyvuetify (rv) wrapper for type safety and better integration with Solara's reactivity.
    2. Built-in components: Many native Solara components are themselves built on top of ipyvuetify. You can inspect the Solara component source code to learn how to build your own custom components using these primitives.
  3. Manage state size limits

    master

    To prevent a single runaway reactive variable from exhausting Redis memory or spiking server memory, Solara implements size guard rails:

    • Warning: If a serialized value exceeds SOLARA_STATE_WARN_VALUE_BYTES (default 1 MB), it is logged.
    • Hard Cap: If a value exceeds SOLARA_STATE_MAX_VALUE_BYTES (default 5 MB), it is skipped and will not be restored. This is tracked via the sync_oversize_dropped metric on /resourcez.
    • Disabling Caps: To disable the hard cap, set SOLARA_STATE_MAX_VALUE_BYTES=0.

    Best Practice: Do not persist large DataFrames directly. Instead, persist a reference (like an ID or URL) and recompute the data from your database upon restoration.

  4. Avoid in-place mutation of persisted reactives

    master

    When using persisted reactives, you must follow the standard Solara rule: do not mutate reactives in place.

    If you mutate an object in place (e.g., my_list.append(1)), the internal equals check used for change detection will compare the object to itself and conclude nothing has changed. This results in the mutation being silently not persisted to the backend.

    Always use .set() or replace the value entirely to ensure the change is detected and the dirty-tracking mechanism triggers a flush to the storage backend.

  5. Understand the core components of Solara

    master

    Solara is a framework for building data-focused web applications by combining ipywidgets and reacton. It is composed of two primary functional parts:

    1. Solara-ui: A collection of opinionated React components and hooks designed to accelerate the development of web and data applications.
    2. Solara-server: A web framework used for deploying these applications in production. It provides opinionated handling for pages and routing, allowing applications to run as standalone apps or dashboards.
  6. Avoid the Orphaned-Selection Trap in Dependent Reactives

    master

    A common error occurs when you persist a 'leaf' selection (e.g., a selected Country) but fail to persist the 'parent' selection (e.g., the Continent) that defines the available options. Upon failover, the parent resets to its default, making the restored leaf value invalid or 'orphaned'.

    Strategies to prevent orphaned selections:

    1. Persist the leaf identifier only and derive parents upward: Instead of persisting both continent and country, persist only a unique city_id. Use a Computed or a function to look up the corresponding country and continent from that ID.

    2. Persist top inputs and re-validate downward: If you must persist both, add a guard inside your component to reset the child value if it is no longer present in the recomputed list of options.

    3. Never persist the derived list: Always recompute option lists (e.g., country_options) from the persisted inputs to ensure they match the current data state.

    # STRATEGY 1: Persist leaf ID, derive parents
    city_id = solara.reactive(None, persist=True, key="geo.city_id")
    
    @solara.lab.computed
    def country() -> str | None:
        return city_lookup(city_id.value).country if city_id.value is not None else None
    
    # STRATEGY 2: Persist top input and re-validate
    continent = solara.reactive("", persist=True, key="geo.continent")
    country = solara.reactive("", persist=True, key="geo.country")
    
    @solara.component
    def CountrySelect():
        options = country_options.value  # recomputed from the restored continent
        if country.value and country.value not in options:
            country.set("")  # reset orphaned value
        ...
  7. How to trigger component re-renders

    master

    In Solara, a component only re-renders if it manages internal state via hooks (such as solara.use_state) and that state is updated. To trigger a re-render, you must call the setter function (the second return value of the hook) with a new value.

    Because Solara is declarative, the entire render function is re-executed after a state change. Solara then calculates the difference and updates the associated widgets automatically.

  8. Understand the Solara architecture

    master

    Solara is composed of two main parts:

    1. Solara UI: Built on top of Reacton (the Python equivalent of ReactJS) and IPywidgets. It provides a consistent set of modern UI components with a Material Design look and specialized hooks for data-heavy applications.
    2. Solara server: A production-grade server that renders ipywidgets efficiently in the browser and manages features like routing and Static Site Generation (SSG). It allows you to run applications without needing a full Jupyter kernel environment.
  9. What are hooks and how to use them correctly

    master

    Hooks are Python functions whose names start with use_ (e.g., solara.use_state). They are used to manage state or other lifecycle logic within a component.

    The Golden Rule: Hooks must only be called at the top level of a function component or a custom hook. They cannot be called inside loops, conditions, nested functions, or after early returns.

    This restriction exists because Solara relies on the exact order of hook calls to maintain state between renders. If the order or number of calls changes (e.g., due to an if statement), the internal state 'slots' will get mixed up, leading to unpredictable bugs.

    import solara
    
    @solara.component
    def Page():
        # Correct: Hook is at the top level
        x, set_x = solara.use_state(1)
        solara.Text(f"Value: {x}")