Skip to content

Add model editor app for building YAML model files#42

Closed
Copilot wants to merge 13 commits into
mainfrom
copilot/create-model-file-editor-app
Closed

Add model editor app for building YAML model files#42
Copilot wants to merge 13 commits into
mainfrom
copilot/create-model-file-editor-app

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 17, 2026

  • Locate all emoji in source files
  • Remove emoji from src/epicc/editor/__main__.py UI strings
  • All 107 tests pass

Copilot AI and others added 2 commits April 17, 2026 21:45
…tion

Create a separate Streamlit app for building and editing YAML model files:
- src/epicc/editor/ package with helpers.py (pure logic) and __main__.py (UI)
- editor.py entry point at repository root
- Makefile 'editor' target
- 29 tests covering helpers, validation, and round-trip serialization

Agent-Logs-Url: https://github.com/EpiForeSITE/epicc/sessions/a4e6dd31-6c9a-4ef2-9059-59a5f3af997d

Co-authored-by: gvegayon <893619+gvegayon@users.noreply.github.com>
Copilot AI changed the title [WIP] Add a separate app for building model files Add model editor app for building YAML model files Apr 17, 2026
Copilot AI requested a review from gvegayon April 17, 2026 21:47
Copy link
Copy Markdown
Member

@gvegayon gvegayon left a comment

Choose a reason for hiding this comment

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

@copilot, I tried the new app, and it is not working as expected. The main issues I saw:

  • The list of authors failed to properly load the authors of the measles model:
Image
  • The buttons to add or remove anything are not working. I tried adding/removing authors, parameters, scenarios, etc., and none worked.

Copilot AI and others added 2 commits April 17, 2026 22:09
- Use on_click callbacks for all add/remove buttons so state changes
  happen before the next render cycle (fixes buttons appearing to do nothing)
- Track uploaded file identity to prevent re-processing on every rerun
- Use st.rerun() after file upload to force fresh widget creation
- Embed a version counter in all dynamic widget keys so structural
  changes (upload, add, remove) create truly new widgets that honour
  the value parameter from loaded data (fixes author names not loading)

Agent-Logs-Url: https://github.com/EpiForeSITE/epicc/sessions/f7916fb3-4db3-4e2d-b88a-1306009dcf25

Co-authored-by: gvegayon <893619+gvegayon@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Apr 17, 2026

@copilot, I tried the new app, and it is not working as expected. The main issues I saw:

  • The list of authors failed to properly load the authors of the measles model:...

Fixed both issues in 93c8b1f:

Authors not loading: Streamlit caches widget values by key — even after updating st.session_state["authors"] from the uploaded file, the old widget keys (author_name_0, etc.) retained their empty values. Fixed by embedding a version counter in all dynamic widget keys and calling st.rerun() after upload, so widgets are genuinely new and use the loaded data.

Add/remove buttons not working: The old code used st.button() return values which only update after rendering — too late for the current frame. Fixed by switching all add/remove buttons to on_click callbacks, which execute before the next render cycle.

Editor with measles.yaml loaded — both authors show correctly

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • checkip.amazonaws.com
    • Triggering command: /home/REDACTED/work/epicc/epicc/.venv/bin/streamlit streamlit run editor.py --server.headless true --server.port 8502 (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from gvegayon April 17, 2026 22:11
@gvegayon gvegayon marked this pull request as ready for review April 17, 2026 22:14
Copilot AI review requested due to automatic review settings April 17, 2026 22:14
Copy link
Copy Markdown
Contributor

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

Adds a dedicated Streamlit “Model Editor” app for creating/editing EPICC YAML model files, with pure-logic helpers and accompanying tests.

Changes:

  • Introduce epicc.editor package with YAML↔state parsing, validation, and serialization helpers.
  • Add a Streamlit UI app (epicc.editor.__main__) plus editor.py entrypoint to run it similarly to app.py.
  • Add pytest coverage for helper logic and YAML/state round-trips.

Reviewed changes

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

Show a summary per file
File Description
src/epicc/editor/helpers.py Implements editor helper functions (coercion/parsing, YAML→state, state→doc, validation, YAML serialization).
src/epicc/editor/__main__.py Streamlit UI for editing model metadata, parameters, equations, scenarios, report blocks, and figures; supports upload/validate/download/preview.
src/epicc/editor/__init__.py Declares the new epicc.editor package.
editor.py Entry point to run the editor app via streamlit run editor.py.
Makefile Adds make editor target for launching the editor.
tests/epicc/test_editor.py Adds tests for helper functions and YAML/state/document round-trips.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/epicc/editor/helpers.py Outdated
Comment thread src/epicc/editor/helpers.py
Comment thread src/epicc/editor/helpers.py
Comment thread src/epicc/editor/__main__.py
Changed '\n'.join(p.get('references', [])) to '\n'.join(p.get('references') or [])
to prevent TypeError when references is null or invalid type.
…y swallowing them

Agent-Logs-Url: https://github.com/EpiForeSITE/epicc/sessions/180e9200-681b-41c4-bc4b-545f4c14acc6

Co-authored-by: olivia-banks <53623746+olivia-banks@users.noreply.github.com>
Copilot AI and others added 2 commits April 21, 2026 18:48
…or; show structured field errors in editor UI

Agent-Logs-Url: https://github.com/EpiForeSITE/epicc/sessions/a5e3de79-3ec7-4a80-8bcc-72bd03c603b5

Co-authored-by: olivia-banks <53623746+olivia-banks@users.noreply.github.com>
…_word variable for readability

Agent-Logs-Url: https://github.com/EpiForeSITE/epicc/sessions/a5e3de79-3ec7-4a80-8bcc-72bd03c603b5

Co-authored-by: olivia-banks <53623746+olivia-banks@users.noreply.github.com>
Agent-Logs-Url: https://github.com/EpiForeSITE/epicc/sessions/760e0c5a-25bc-4a30-8aa6-82a77e634550

Co-authored-by: olivia-banks <53623746+olivia-banks@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

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

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +117 to +118
file_id = f"{uploaded.name}:{uploaded.size}"
if st.session_state.get("_uploaded_file_id") != file_id:
Comment on lines +263 to +266
param: dict[str, Any] = {
"type": p["type"],
"label": p["label"],
"default": coerce_numeric(str(p["default"])),
Comment on lines +281 to +283
if p["type"] == "enum" and p.get("options"):
options = parse_key_value_lines(p["options"])
param["options"] = {str(k): str(v) for k, v in options.items()}
Comment on lines +56 to +69
"""Parse ``key: value`` lines into a dict, coercing numeric values."""
result: dict[str, Any] = {}
for line in text.strip().splitlines():
if ":" not in line:
continue
key, _, val = line.partition(":")
val = val.strip()
try:
result[key.strip()] = int(val)
except ValueError:
try:
result[key.strip()] = float(val)
except ValueError:
result[key.strip()] = val
Comment on lines +143 to +147
# Authors
authors_raw = data.get("authors", [])
state["authors"] = [
{"name": a.get("name", ""), "email": a.get("email", "")} for a in authors_raw
] or [{"name": "", "email": ""}]
@olivia-banks
Copy link
Copy Markdown
Member

olivia-banks commented May 5, 2026

@gvegayon I'm looking through the code in earnest now, and it's really not all that great. Copilot didn't really seem to read the rest of the code and emitted something that sort of exists along a tangent (e.g., the code for creating models with graphs hardcodes a bunch of information even though this is readily exposed by the block Pydantic models).

I think I'm going to use some of this code as a base but then write the rest myself. Closing for now unless you think we should pursue this route.

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.

Create a separate app for building model files

5 participants