Skip to content

Comments

Feature/client upload script#417

Merged
ascibisz merged 16 commits intomainfrom
feature/client-upload-script
Dec 1, 2025
Merged

Feature/client upload script#417
ascibisz merged 16 commits intomainfrom
feature/client-upload-script

Conversation

@ascibisz
Copy link
Collaborator

@ascibisz ascibisz commented Oct 22, 2025

Problem

Add upload script for uploading recipes that we want to show up on the cellpack client site
Link to story or ticket

Solution

I decided it makes more sense to have this upload script in this repo rather than the cellpack-client repo so we could reuse the upload python code rather than re-implementing it in typescript.

Also added some documentation to explain how to use this code to upload the necessary metadata for the cellpack client.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 22, 2025

Packing analysis report

Analysis for packing results located at cellpack/tests/outputs/test_spheres/spheresSST

Ingredient name Encapsulating radius Average number packed
ext_A 25 236.0

Packing image

Packing image

Distance analysis

Expected minimum distance: 50.00
Actual minimum distance: 50.01

Ingredient key Pairwise distance distribution
ext_A Distance distribution ext_A

@ascibisz ascibisz marked this pull request as ready for review October 22, 2025 23:27
@ascibisz ascibisz requested review from Copilot and rugeli October 22, 2025 23:28
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds functionality to upload cellPACK recipes to the client site by introducing an upload script and supporting documentation. The main goal is to enable uploading recipes with their metadata to Firebase for display on the cellpack-client site.

  • Added documentation explaining how to publish recipes to the client site
  • Created example editable fields JSON schema for client-side recipe configuration
  • Updated upload methods to return IDs for tracking uploaded resources

Reviewed Changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 3 comments.

File Description
examples/client-data/example_editable_fields.json Added example schema demonstrating editable field configuration for client site
docs/CLIENT_SITE.md Added documentation on publishing recipes to the client site
cellpack/autopack/DBRecipeHandler.py Modified upload methods to return resource IDs

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@ascibisz ascibisz requested a review from meganrm October 23, 2025 19:05
Copy link
Collaborator

Choose a reason for hiding this comment

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

Love it! The structure makes much more sense now, just two quick thoughts here:

  • do we want to add step_size to settings at all?
  • for gradient strength, we could wait for the decision on decay_length display

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We could definitely add step_size and change the terminology to decay_length! But those changes also need to happen on the cellpack-client site side of things, currently the client wouldn't read either of those two fields, so I would be hesitant to update this example documentation until those changes are actually in effect on the client side.

:param name: string argument
display name for recipe in client selection menu
"""
db_handler = FirebaseHandler()
Copy link
Collaborator

Choose a reason for hiding this comment

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

This works great as is! just a nit for consistency: we have a shared handler for database initiation in cellpack/autopack/interface_objects/database_ids.py. we could reuse the pattern here instead of importing firebase directly, similar to how upload.py selects the database via db_id:

def upload(
    recipe_path=None,
    config_path=None,
    db_id=DATABASE_IDS.FIREBASE,
):
    """
    Uploads a recipe to the database

    :return: void
    """
    if db_id == DATABASE_IDS.FIREBASE:
        # fetch the service key json file
        db_handler = FirebaseHandler()
        if FirebaseHandler._initialized:
            db_handler = DBUploader(db_handler)
            if recipe_path:
                recipe_loader = RecipeLoader(recipe_path)
                recipe_full_data = recipe_loader._read(resolve_inheritance=False)
                recipe_meta_data = get_recipe_metadata(recipe_loader)
                db_handler.upload_recipe(recipe_meta_data, recipe_full_data)
            if config_path:
                config_data = ConfigLoader(config_path).config
                db_handler.upload_config(config_data, config_path)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm not sure if I understand. Are you suggesting that I add the if db_id == DATABASE_IDS.FIREBASE: line?

Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah, this follows the pattern we use so there's no need to import any handlers directly. In this file, we can remove line4 from cellpack.autopack.FirebaseHandler import FirebaseHandler

editable_fields_ids.append(id)
recipe_metadata = {
"name": name,
"recipe": recipe_id,
Copy link
Member

Choose a reason for hiding this comment

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

can these be changed to either display_name and id (are these nested in an object called 'recipe_metadata'?) or recipe_display_name and recipe_id without causing too many problems? or should this be a separate PR?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@ascibisz I tried the script to upload a recipe to my testing database, it mostly worked well! I ran into a few bugs and have some questions we can go over in our next meeting.

Copy link
Collaborator

@rugeli rugeli left a comment

Choose a reason for hiding this comment

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

I tested the new changes and they worked well! Just have a few ideas for non-critical refinements. I agree we can move forward with this pr and follow up with improvements after the submission.

  • when params like config, db_id, name aren't set, the metadata ends up with null values, which may affect frontend display. add warning/error handing, making these options required or add some frontend checks?
  • Ruge's todo: FirebaseHandler shouldn't be imported here, this is a missed spot from the previous handler refactor. we can do an overall cleanup later

@ascibisz ascibisz requested review from meganrm and rugeli November 20, 2025 17:52
Comment on lines +54 to +57
:param name: string argument
display name for recipe in studio selection menu
:param output_file: string argument
path to local simularium output file to upload
Copy link
Collaborator

Choose a reason for hiding this comment

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

the doc strings are very clear and helpful!

Comment on lines 61 to 63
if studio and (not name or not recipe_path or not config_path or not fields):
sys.exit(
"To upload a recipe for cellPACK studio, please provide --name, --recipe_path, --config_path, and --fields arguments."
Copy link
Collaborator

Choose a reason for hiding this comment

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

I’m debating between making config optional here and updating the frontend to still show the recipe when config is null, or adding a default config file with all the values in backend. I’m leaning toward making it optional, since the backend already runs packings with default configs when no config file is specified. we can discuss about it later

1. Set up access to the staging Firebase account, following [these instructions](https://github.com/mesoscope/cellpack/blob/main/docs/REMOTE_DATABASES.md#firebase-firestore)
2. Determine which recipe fields should be editable in the client, and create a JSON file specifying these editable fields following the schema outlined in [this example](https://github.com/mesoscope/cellpack/blob/0f140859824086d73edab008ff381b5e5717db8b/examples/client-data/example_editable_fields.json)
3. Follow cellPACK installation requirements [in README](https://github.com/mesoscope/cellpack?tab=readme-ov-file#installation)
4. Run the following script to upload necessary files to Firebase: `upload -s -r <path_to_recipe_file> -c <path_to_config_file> -f <path_to_editable_fields_file> -n "Name of Recipe" -o <path_to_simularium_result_file>`
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: It might help to update the parameter description to something like <local_path_to_simularium_result_file> to make it clearer that it expects a path such as out/one_sphere/spheresSST/results_one_sphere_debug_1.0.0_seed_0.simularium

@github-actions
Copy link
Contributor

Packing analysis report

Analysis for packing results located at cellpack/tests/outputs/test_spheres/spheresSST

Ingredient name Encapsulating radius Average number packed
ext_A 25 236.0

Packing image

Packing image

Distance analysis

Expected minimum distance: 50.00
Actual minimum distance: 50.01

Ingredient key Pairwise distance distribution
ext_A Distance distribution ext_A

@ascibisz ascibisz merged commit b994239 into main Dec 1, 2025
9 of 10 checks passed
@ascibisz ascibisz deleted the feature/client-upload-script branch December 1, 2025 18:11
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