Get help from the marimo community

Updated last week

deployment on gitlab pages: issue with dependencies

Trying to deploy my marimo SVG tutorial as gitlab pages from https://gitlab.kuleuven.be/aida-lab/teaching/g0r72a-tutorial-pythonsvg, but having an issue with dependencies. One of these dependencies is svg.py. This can be installed using uv add svg.py. To import it, you use from svg import SVG instead of from svg.py import SVG. I think this is why the error below happens.

Step 1: I first build the marimo exports like this:
Plain Text
#!/bin/bash
files=("batch_and_form.py" "data_explorer.py")

source .venv/bin/activate

for file in "${files[@]}"; do
  without_extension="${file%.*}"
  uv run marimo export html-wasm "$file" -o public/"$without_extension".html --mode run
done

deactivate


  1. git push with the following .gitlab-ci.yml:
Plain Text
pages:
  script:
    - echo "Deploying to GitLab Pages..."
  artifacts:
    paths:
      - ./public
  only:
    - main


After pushing to our institute's gitlab server, I can indeed get to the exported HTML files, but get an error:
Plain Text
Traceback (most recent call last):
File "/lib/python3.12/site-packages/marimo/_runtime/executor.py", line 141, in execute_cell exec(cell.body, glbls)
Cell marimo://notebook.py#cell=cell-0, line 3, in <module> from svg import SVG, G, Circle, PathModuleNotFoundError: No module named 'svg'


So it cannot find the svg module, even though it is in the requirements.txt as svg-py. Another page that uses D3 has no issues.

Any idea what may cause this, and how it can be fixed?
J
M
A
26 comments
I may have found a workaround, but it is far from elegant. It seems to work when I add the following to the notebook:
Plain Text
import micropip
await micropip.install('svg-py')


It makes it work on gitlab pages, but will give an error svg-py was not installed: micropip is only available in WASM notebooks. if run locally.

Ideas for better solutions are welcome 🙂
This is the current suggested approach, but with a try catch
It seems that there are still some bugs to be fixed. For example, looking at the brushing/linking tutorial (the last one: https://g0r72a-tutorial-pythonsvg-466697.pages.gitlab.kuleuven.be/brushlink_brushable.html): one of the mo.ui.anywidgets is not shown, even if it works correctly when run locally. You'll see a single scatterplot at the end of that page, but there should be two. Looking into the source of the page shows that they are indeed both included, but one of them now has a width of 0 pixels. Also: the brush is not activated.
I imagine that it is somehow fixable with an mo.iframe but no luck yet.
I took a quick look and I'm not sure what the issue is. It seems to be flaky locally too, at least for me — the first time only one plot rendered, but when I removed the output and re-added it I got both.

Perhaps @manzt might have an idea of what's going on? At the very least I'm sure he'd love to see this course if he hasn't already 🙂
I hope to get it fixed before we get to that section in the course. @manzt ?
I saw the issue locally now as well: I noticed that when I have the two anywidget plots in an array (i.e. [mo.ui.anywidget(my_widget1),mo.ui.anywidget(widget2)]) and "collapse" the array in marimo, they may or may not reappear when I expand that array again. They will reappear when I restart the kernel. Could this be a general stability issue?
That could be a bug in marimo, yes. Would you be able to file an issue on our repository, with code that helps us reproduce it?
I may have found something that illustrates the same problem but in a different way, and using a minimal anywidget. See my comment on the issue. @manzt This may actually be an anywidget issue.
@Myles Scolnick I see a bugfix on github. Thanks! What's the easiest way to use this last version? (I'm using uv).
you can do uv run --with marimo marimo edit
this just runs the latest. if you want to install the latest, i'd do uv pip install -U marimo
It seems that the issue persists (sorry...). Now using marimo 0.11.6 (version mentioned in pyproject.toml, uv.lock and at the top of the notebook itself in __generated_with. Can the issue be reopened?
Yea I’ll take a look again. Maybe regressed it in a refactor at the end
This fix still works for me, but you brought up another semi-related issue.
This issue is about re-rendering. The repro you included is helpful, so I can debug from here, thank you again for the repro steps
I have a fix, but will put up a PR for @manzt to review.
The issue is because there is model/state initialization code in the render function, which doesn't get called the second time (since we were trying to avoid extra re-renders if the JS hasn't changed).
This fix is for us to do the re-renders (for correctness) but i wonder if this is bad practice for anywidgets, or if there is an alternative
Thanks, Myles! Hopefully the PR gets accepted soon.
Hey Myles. From what I can see in 0.11.17, the second problem is indeed solved (i.e. the example with widget_instance = MyWidget(in_value=7) where m.widget.out_value would not change). Thank you so much for following up on this.

The issue with the disappearing SVGs when collapsing/expanding the array still exists. Is that correct? I think it is related to the fact that we can't see 2 plots on the deployed notebooks either (see https://g0r72a-tutorial-pythonsvg-466697.pages.gitlab.kuleuven.be/brushlink_brushable.html at the bottom) in mo.hstack([mo.ui.anywidget(brushable_sepals),mo.ui.anywidget(brushable_petals)], justify="start").
@Jan Aerts , i was looking at your code. it might be this step:

Plain Text
// Things to do ONLY ONCE
    if (!svg) {
        parser = new DOMParser();
i can look if its something on marimo, but removing that check does fix the issue
the svg is already set when the widget goes from hidden to not hidden. i would try to avoid global state, or try to check another way if the svg is already set (i.e. like checking the dom)
I'll have a look at it tomorrow. Thanks for the tip.
It may be something to do with the last change. The brush/link also does not work anymore when running the marimo notebook locally. When brushing, the moment that the first datapoint enters the brush the plots disappear completely from the notebook (see screen recording). I've been refactoring the brushable_widget to try and solve it, but it looks like the
Plain Text
brushable_sepals.observe(lambda x: set_selected(x["new"]), names="selected_ids")
brushable_petals.observe(lambda x: set_selected(x["new"]), names="selected_ids")

does not trigger the selected_ids in the other plot to update anymore.
It is indeed an issue with marimo/anywidget, I think (my apologies for keeping on digging). Using the minimal example from the anywidget.dev webpage:

Cel 1:
Plain Text
class CounterWidget(anywidget.AnyWidget):
    _esm = """
    function render({ model, el }) {
      let count = () => model.get("value");
      let btn = document.createElement("button");
      btn.innerHTML = `count is ${count()}`;
      btn.addEventListener("click", () => {
        model.set("value", count() + 1);
        model.save_changes();
      });
      model.on("change:value", () => {
        btn.innerHTML = `count is ${count()}`;
      });
      el.appendChild(btn);
    }
    export default { render };
    """
    value = traitlets.Int(123).tag(sync=True)


Cel 2:
Plain Text
get_value, set_value = mo.state(456)


Cel 3:
Plain Text
cw1 = CounterWidget()
cw2 = CounterWidget()


Cel 4:
Plain Text
cw1.observe(lambda x: set_value(x["new"]), names="value")
cw2.observe(lambda x: set_value(x["new"]), names="value")


Cel 5:
Plain Text
aw1 = mo.ui.anywidget(cw1)
aw2 = mo.ui.anywidget(cw2)

aw1


Cel 6:
Plain Text
aw1.widget.value

The output increases as expected when clicking on the aw1 widget.

Cel 7:
Plain Text
aw2.widget.value

This output is initialised at value 123 and does not change when the value of aw1.widget.value changes, even though it should given the observe in cell 4.

@manzt Any idea what this could be?
Add a reply
Sign up and join the conversation on Discord