Menu
Introduction
Getting Started
Use cases
Cell Culture App
Technical documentations
Version
Publication date

Sep 19, 2024

Confidentiality
Public
Reactions
0
Share

Steps 6-7: Main App & Translations

Step 6: Create the Main App


Wire everything together in a Streamlit app with proper routing.


# main.py
import streamlit as st
import os
from gws_core.streamlit import StreamlitRouter
from gws_plate_reader.cell_culture_app_core.pages import (
    first_page, recipe_page, settings
)
from .my_custom_state import MyCustomState
from .pages import new_recipe_page


# Get translation folder path
current_dir = os.path.dirname(__file__)
core_dir = os.path.join(current_dir, '..', '_my_custom_core')
lang_translation_folder_path = os.path.abspath(core_dir)

# Initialize state (global variable for the module)
custom_state = MyCustomState(lang_translation_folder_path)


def display_first_page(custom_state: MyCustomState):
    """Display the first page (recipe list)."""
    first_page.render_first_page(custom_state)


def add_first_page(router: StreamlitRouter, custom_state: MyCustomState):
    """Add first page to router."""
    translate_service = custom_state.get_translate_service()
    router.add_page(
        lambda: display_first_page(custom_state),
        title=translate_service.translate('page_title_analyses'),
        url_path='first-page',
        icon='🧬',
        hide_from_sidebar=False
    )


def display_new_analysis_page(custom_state: MyCustomState):
    """Display the new analysis creation page."""
    new_recipe_page.render_new_recipe_page(custom_state)


def add_new_analysis_page(router: StreamlitRouter, custom_state: MyCustomState):
    """Add new analysis page to router."""
    router.add_page(
        lambda: display_new_analysis_page(custom_state),
        title='New Analysis',  # Hidden from sidebar, no need to translate
        url_path='new-analysis',
        icon='➕',
        hide_from_sidebar=True
    )


def display_analysis_page(custom_state: MyCustomState):
    """Display the analysis page (recipe details)."""
    recipe_page.render_recipe_page(custom_state)


def add_analysis_page(router: StreamlitRouter, custom_state: MyCustomState):
    """Add analysis page to router."""
    router.add_page(
        lambda: display_analysis_page(custom_state),
        title='Analysis',  # Hidden from sidebar
        url_path='analysis',
        icon='📊',
        hide_from_sidebar=True
    )


def display_settings_page(custom_state: MyCustomState):
    """Display the settings page."""
    settings.render_settings_page(custom_state)


def add_settings_page(router: StreamlitRouter, custom_state: MyCustomState):
    """Add settings page to router."""
    translate_service = custom_state.get_translate_service()
    router.add_page(
        lambda: display_settings_page(custom_state),
        title=translate_service.translate('page_title_settings'),
        url_path='settings',
        icon=':material/settings:',
        hide_from_sidebar=False
    )


# Create router and add all pages
router = StreamlitRouter.load_from_session()
add_first_page(router, custom_state)
add_new_analysis_page(router, custom_state)
add_analysis_page(router, custom_state)
add_settings_page(router, custom_state)

# Run the router (this renders the current page)
router.run()

Important Notes:


  • Initialize state once as a module-level variable
    • Use StreamlitRouter.load_from_session() to get the router
      • Pages hidden from sidebar (hide_from_sidebar=True) don't need translated titles
        • Call router.run() at the end to render the current page
          • Each page has a display function and an add function

            Step 7: Create Translation Files


            Create JSON files for internationalization by combining the core framework translations with your custom translations.


            Process:


            1. Copy the base translation files from cell_culture_app_core:Copy gws_plate_reader/cell_culture_app_core/en.json → _my_custom_core/en.jsonCopy gws_plate_reader/cell_culture_app_core/fr.json → _my_custom_core/fr.json
              1. Add your custom translation keys to the copied files. The core files contain ~600 keys for all Cell Culture framework features. You need to add your application-specific keys on top.

                Structure of translation files:


                _my_custom_core/en.json:


                {
                    // ========================================
                    // CORE CELL CULTURE APP TRANSLATIONS (~600 keys)
                    // ========================================
                    "page_title_analyses": "Analyses",
                    "page_title_overview": "Overview",
                    "page_title_selection": "Selection",
                    "page_title_quality_check": "Quality Check",
                    "page_title_table_view": "Table View",
                    "page_title_graph_view": "Graph View",
                    "page_title_medium_view": "Medium View",
                    "page_title_pca": "PCA Analysis",
                    "page_title_umap": "UMAP Analysis",
                    "page_title_feature_extraction": "Feature Extraction",
                    "page_title_pls_regression": "PLS Regression",
                    "page_title_random_forest": "Random Forest",
                    "page_title_settings": "Settings",
                    // ... (600+ core keys)
                    
                    // ========================================
                    // YOUR CUSTOM TRANSLATIONS (~50-200 keys)
                    // ========================================
                    "new_recipe_my_custom": "New Custom Analysis",
                    "my_custom_app_title": "My Custom Fermentation Analysis",
                    "recipe_name_label": "Recipe Name",
                    "recipe_name_placeholder": "Enter recipe name...",
                    "upload_info_file": "Upload Info File",
                    "upload_medium_file": "Upload Medium File",
                    "upload_raw_data_file": "Upload Raw Data File",
                    "upload_follow_up_file": "Upload Follow-up File",
                    "file_upload_success": "File uploaded successfully",
                    "file_upload_error": "Error uploading file",
                    "launch_analysis_button": "Launch Analysis",
                    "return_to_recipes": "Return to recipes",
                    "analysis_type_standard": "Standard Analysis",
                    "analysis_type_microplate": "Microplate Analysis",
                    "select_existing_resources": "Select Existing Resources",
                    "upload_new_files": "Upload New Files",
                    "error_missing_files": "Please provide all required files",
                    "error_missing_recipe_name": "Please provide a recipe name",
                    "success_analysis_launched": "Analysis launched successfully"
                }

                _my_custom_core/fr.json:


                {
                    // ========================================
                    // CORE CELL CULTURE APP TRANSLATIONS (~600 keys)
                    // ========================================
                    "page_title_analyses": "Analyses",
                    "page_title_overview": "Vue d'ensemble",
                    "page_title_selection": "Sélection",
                    "page_title_quality_check": "Contrôle qualité",
                    "page_title_table_view": "Vue tableau",
                    "page_title_graph_view": "Vue graphique",
                    "page_title_medium_view": "Vue milieu",
                    "page_title_pca": "Analyse PCA",
                    "page_title_umap": "Analyse UMAP",
                    "page_title_feature_extraction": "Extraction de caractéristiques",
                    "page_title_pls_regression": "Régression PLS",
                    "page_title_random_forest": "Forêt aléatoire",
                    "page_title_settings": "Paramètres",
                    // ... (600+ core keys)
                    
                    // ========================================
                    // YOUR CUSTOM TRANSLATIONS (~50-200 keys)
                    // ========================================
                    "new_recipe_my_custom": "Nouvelle Analyse Personnalisée",
                    "my_custom_app_title": "Mon Analyse de Fermentation Personnalisée",
                    "recipe_name_label": "Nom de la recette",
                    "recipe_name_placeholder": "Entrez le nom de la recette...",
                    "upload_info_file": "Télécharger le fichier Info",
                    "upload_medium_file": "Télécharger le fichier Milieu",
                    "upload_raw_data_file": "Télécharger le fichier Données brutes",
                    "upload_follow_up_file": "Télécharger le fichier Suivi",
                    "file_upload_success": "Fichier téléchargé avec succès",
                    "file_upload_error": "Erreur lors du téléchargement du fichier",
                    "launch_analysis_button": "Lancer l'analyse",
                    "return_to_recipes": "Retour aux recettes",
                    "analysis_type_standard": "Analyse standard",
                    "analysis_type_microplate": "Analyse microplaque",
                    "select_existing_resources": "Sélectionner les ressources existantes",
                    "upload_new_files": "Télécharger de nouveaux fichiers",
                    "error_missing_files": "Veuillez fournir tous les fichiers requis",
                    "error_missing_recipe_name": "Veuillez fournir un nom de recette",
                    "success_analysis_launched": "Analyse lancée avec succès"
                }

                Important Notes:


                • Do NOT modify the core translation keys (the ~600 keys from cell_culture_app_core)
                  • Only add your custom keys at the end of the files
                    • Keep both files synchronized: Every key in en.json must exist in fr.json
                      • Use consistent naming: Prefix your custom keys with a unique identifier (e.g., my_custom_myapp_)
                        • Total keys: Core (~600) + Custom (~50-200) = ~650-800 keys per file

                          Technical bricks to reuse or customize

                          Have you developed a brick?

                          Share it to accelerate projects for the entire community.