Skip to main content

CoMRAD Framework - Component-MVC Rapid Appliction Driven Framework

CoMRAD Logo - Panda and Python hugging

Opinionated, Component-Driven MVC Framework For Data Apps

  • Router - This is the entry point for the application. It is responsible for routing the request to the appropriate controller and action. It also handles the response from the controller and sends it back to the client.

  • Session - This is the application state. A simple key-value store. Custom class can be provided but has to behave like a dict

  • Model - This is the current view state. It is a key-value store. It is updated by the controller and used by the view to render the current view of the application.

  • Controller - Provides the business logic for the application. It is responsible for handling the request and returning the response. It updates the model from the current request, and then returns the appropriate response, which can either be a view, and error or a redirect (full semantics of HTTP Response should be possible - but for now we will only support 200, 302, 400, 404, 500)

  • View - This is the presentation layer. It is responsible for rendering the model to the client. For PATCh this will be a set of patch components.

  • Component - A component is a part of a view. It is responsible for sending the information to the front end required for the component to render. It is also responsible for updating the model with the current state of the component. It can also indicate if it is complete or if there are any errors.

  • Page - A page is a semantic structure to help configuration. It combines a view and a controller representing a single page in the application. We provide default configuration, such as requiring all input components with a required flag to be filled in before the controller redirects to the next view.

  • Application - This is the top level object. It is responsible for configuring the application. It is responsible for creating the router, model, controller and view. It is also responsible for creating the page objects and configuring them.

In our standard application, each view must have a unique 'name' used for the routing. The first view should always be called 'index'.

The current view name is stored in the session under the key 'view'.

Each view has a controller associated with it. The controller is responsible for updating the model with the current state of the application. Then making a decision as to whether to render the view or redirect to another view.

To keep configuration to a minimum, components can be 'smart' and manage their own state. For example, a text input component can manage its own value. This means that the controller does not need to update the model with the current value of the input component. This is a trade off between configuration and flexibility. Of course, the controller can override any changes made by the component.

Similarly a component can indicate if it's "complete", i.e. that its state is fully configured or it can flag any errors relating to the state of the component.

The default controller will pass over all components and check if they are complete. If all components are complete and there are no errors, then the controller will redirect to the next view.

Some Pages may be 'final', i.e. they represent the end-point of a flow. In this case, the controller will not redirect to the next view, but instead will re-render the current view.

A very simple configuration may look like:

from patch import Application, Page, TextInput, Button, Paragraph

app = Application()

app.add_page(Page(
    name='index',
    controller={'next': 'greeting'},
    components=[TextInput(name='name', required=True)],
))

def reset_handler(session, model, request):
    """
    This function is called when the user clicks the button.

    Buttons are automatically submitted to the server, unless `submit=False` 
    is set on the Button.
    """
    model.clear()

def render_greeting_page(session, model, request):
    """
    Instead of providing a fixed list of components, we can also set a function
    that will be used to decide which components to show, and their configuration.
    """
    return [
        Paragraph(f'Hello {model['name']}'),
        Button('Back', handler=action_reset)
        ]

app.add_page(Page(
    name='greeting',
    components=say_hello,
))

Some components can also take a render function. For a chart component, for example, the render function would be called when the controller asks the component to update the model and state and convert the response to an object suitable for the front-end to render.

## Standard components:

* Button - a clickable button that either sets a value in the model or runs a handler function

* ButtonBar - a layout component that renders a set of buttons in a row

* Chart - a component that renders a chart - the chart is

* Checkbox - a component that renders a checkbox

* DateSelect - a component that renders a date picker

* Expando - an expanding section of the page

* FileUpload - a component that renders a file upload

* Fragment - a single component that can hold others but is itself invisible

* Paragraph - a component that renders a paragraph of text

* Select - a component that renders a select box

* TextInput - a component that renders a text input

Release files for comrad 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for comrad 0.0.1
File Size Uploaded
comrad-0.0.1.tar.gz 8.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for comrad 0.0.1
File Interpreter ABI Platform
comrad-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 15.8 kB

Release files / comrad-0.0.1.tar.gz

Download URL comrad-0.0.1.tar.gz
Size 8.3 kB
Tags Source
SHA-256 checksum
How to use checksums
9f36062b6aea7d313fe26c79bee3ea155a4583aa97dc0d89e51b3b14e270ba2b
BLAKE2b-256 checksum
How to use checksums
8ef92e26b949f2270eaaad7c03cf09cb37fac0ea270d61b9f68b11c044891062
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.2.2 CPython/3.8.12 Darwin/22.3.0

Release files / comrad-0.0.1-py3-none-any.whl

Download URL comrad-0.0.1-py3-none-any.whl
Size 7.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
765113bcb8903424d268664d83f35c85f296dee00adce3186810a25bffcb9399
BLAKE2b-256 checksum
How to use checksums
79756d65b4df18292be4780a0adb74d5ecf099fd02a64388c18a8d42c0e733cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.2.2 CPython/3.8.12 Darwin/22.3.0

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page