Skip to content

eng: Added docs for canvas code #26

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,30 @@
class UnsupportedButtonError(Exception):
pass

"""
This file contains examples of how to handle a user clicking a button on a canvas
For examples of initialization, check out canvas_initialize.py
"""

def route_interaction_webhook(app: App, canvas_interaction: CanvasInteractionWebhookV2) -> None:
canvas_id = canvas_interaction.canvas_id

# Access the different actions by checking which button was clicked
if canvas_interaction.button_id == SEARCH_BUTTON_ID:
with app.create_session_context("Search Chemicals", timeout_seconds=20) as session:
session.attach_canvas(canvas_id)

# Use a CanvasBuilder to update an existing canvas
canvas_builder = _canvas_builder_from_canvas_id(app, canvas_id)
canvas_inputs = canvas_builder.inputs_to_dict_single_value()

# Validate and sanitize the user's search input
sanitized_inputs = _validate_and_sanitize_inputs(canvas_inputs)

# Search for the chemical
results = search(sanitized_inputs[SEARCH_TEXT_ID])

# Render the preview canvas
render_preview_canvas(results, canvas_id, canvas_builder, session)
elif canvas_interaction.button_id == CANCEL_BUTTON_ID:
# Set session_id = None to detach and prior state or messages (essentially, reset)
Expand All @@ -46,12 +60,17 @@ def route_interaction_webhook(app: App, canvas_interaction: CanvasInteractionWeb
.with_session_id(None)\
.with_blocks(input_blocks())\
.to_update()

# Update the canvas
app.benchling.apps.update_canvas(canvas_id, canvas_update)
elif canvas_interaction.button_id == CREATE_BUTTON_ID:
with app.create_session_context("Create Molecules", timeout_seconds=20) as session:
session.attach_canvas(canvas_id)

# Use a CanvasBuilder to create a new molecule
canvas_builder = _canvas_builder_from_canvas_id(app, canvas_id)
molecule = _create_molecule_from_canvas(app, canvas_builder)

render_completed_canvas(molecule, canvas_id, canvas_builder, session)
else:
# Re-enable the Canvas, or it will stay disabled and the user will be stuck
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,25 @@ class UnsupportedWebhookError(Exception):

def handle_webhook(webhook_dict: dict[str, Any]) -> None:
logger.debug("Handling webhook with payload: %s", webhook_dict)

# Receive the webhook and initialize the app
webhook = WebhookEnvelopeV0.from_dict(webhook_dict)
app = init_app_from_webhook(webhook)

# Route the webhook to the appropriate handler
# Could also choose to route on webhook.message.type

# Note: if your manifest specifies more than one item in `features`,
# then `webhook.message.feature_id` may also need to be part of your routing logic
try:
if isinstance(webhook.message, CanvasInitializeWebhookV2):
# This webhook is triggered when a canvas is initialized as a part of a run
render_search_canvas(app, webhook.message)
elif isinstance(webhook.message, CanvasInteractionWebhookV2):
# This webhook is triggered when a user clicks a button on the canvas
route_interaction_webhook(app, webhook.message)
elif isinstance(webhook.message, CanvasCreatedWebhookV2Beta):
# This webhook is triggered when a canvas is created in an entry
render_search_canvas_for_created_canvas(app, webhook.message)
else:
# Should only happen if the app's manifest requests webhooks that aren't handled in its code paths
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@

from local_app.benchling_app.views.constants import SEARCH_BUTTON_ID, SEARCH_TEXT_ID

"""
This file contains examples of how create a canvas at initialization
For examples of updates, check out canvas_interaction.py

Use a CanvasBuilder to create or update a canvas associated with your app
This sdk tool can be used for easy creation and updates

Check out https://benchling.com/sdk-docs/1.22.0/benchling_sdk.apps.canvas.framework.html
for more details on the CanvasBuilder class
"""


def render_search_canvas(app: App, canvas_initialized: CanvasInitializeWebhookV2) -> None:
with app.create_session_context("Show Sync Search", timeout_seconds=20):
Expand All @@ -24,7 +35,11 @@ def render_search_canvas(app: App, canvas_initialized: CanvasInitializeWebhookV2
feature_id=canvas_initialized.feature_id,
resource_id=canvas_initialized.resource_id,
)

# Add the input blocks to the canvas
canvas_builder.blocks.append(input_blocks())

# Create the canvas
app.benchling.apps.create_canvas(canvas_builder.to_create())


Expand All @@ -36,6 +51,13 @@ def render_search_canvas_for_created_canvas(app: App, canvas_created: CanvasCrea


def input_blocks() -> list[UiBlock]:
"""
Create 3 blocks to populate the canvas:

Markdown block to display text
TextInput block to capture user input
Button block to trigger the search
"""
return [
MarkdownUiBlock(
id="top_instructions",
Expand Down