marimo-team / marimo

A reactive notebook for Python — run reproducible experiments, execute as a script, deploy as an app, and version with git.
https://marimo.io
Apache License 2.0
6.67k stars 233 forks source link

Document preserved shebangs #2369

Open dmadisetti opened 2 weeks ago

dmadisetti commented 2 weeks ago

Description

I think with the new sandbox change, editing does not strip the shebangs- which is great. Now this works out of the box, and is very nice:

cat notebook.py

#!/usr/bin/env -S marimo export html --no-include-code
import marimo
# ...

chmod +x notebook.py

./notebook.py


You can push this further and can now create an environment with nix:

#! /usr/bin/env nix
#! nix shell --impure --expr ``
#! nix with (import (builtins.getFlake ''nixpkgs'') {});
#! nix    let
#! nix        venv = python311.withPackages (
#! nix            ps: with ps; [ marimo matplotlib numpy ]
#! nix        );
#! nix    in pkgs.buildEnv {
#! nix        name = "marimo-env";
#! nix        # NB adding ffmpeg, openmpi and gcc as a nix shell dep.
#! nix        paths=[venv ffmpeg gcc-unwrapped.lib openmpi];
#! nix    } 
#! nix ``
#! nix --command marimo run

import marimo
# ...

Note, you can even combine this with sandbox to pin your python and UV to nix:

#! /usr/bin/env nix
#! nix shell --impure --expr ``
#! nix with (import (builtins.getFlake ''nixpkgs'') {});
#! nix    python311.withPackages (
#! nix            ps: with ps; [ marimo uv setuptools ]
#! nix    )
#! nix ``
#! nix --command marimo edit --sandbox
# /// script
# requires-python = ">=3.11"
# dependencies = [
#     "numpy",
# ]
# ///

import marimo
# ...

In theory, you could even have nix build or launch an actual container

Suggested solution

This already works, so could just be an undocumented feature. However, I'm thinking of preserving #! nix and script sandboxes in the markdown format (e.g):

---
title: Notebook
marimo-version: 0.0.0
width: medium
nix: |
    with import <nixpkgs> {};
    python311.withPackages (
        ps: with ps; [ marimo uv jaxlibWithCuda ]
    )
---   

(and or script: |) So having the documentation for the normal case would be nice too.

I am also very conscious that I am full on with the nix koolaid :grimacing:, so documenting and then potentially having to retain support might not be appealing.

Alternative

No response

Additional context

No response

mscolnick commented 2 weeks ago

could it be header_comment or just header in the markdown? since it would be nice to preserve these comments and since both script and nix are slightly different in their comment structuer

dmadisetti commented 2 weeks ago

That would be nice because there might be other header comments that could be leveraged. Arguments for having sections:

mscolnick commented 2 weeks ago

the block would still have to be parsed to be usable and require sandbox / nix particular logic for the consumer

Why does it? Why can't we just not touch the header and leave it as is? I don't think marimo can/should be opinionated on how to construct the env, especially since there isn't one way.

dmadisetti commented 2 weeks ago

I think there should be parity with the python format. So even if there isn't a nix section, maybe there should be a sandbox section that extracts the relevant # /// script section. Even though there's not one way to bootstrap an env, the marimo seems to be embracing the PEP specification

mscolnick commented 2 weeks ago

Could we not go a level higher, and instead of preserving # /// script, we just preserve the whole comment as-in without any modification?

---
title: Notebook
marimo-version: 0.0.0
width: medium
comment: |
    #! /usr/bin/env nix
    #! nix shell --impure --expr ``
    #! nix with (import (builtins.getFlake ''nixpkgs'') {});
    #! nix    python311.withPackages (
    #! nix            ps: with ps; [ marimo uv setuptools ]
    #! nix    )
    #! nix ``
    #! nix --command marimo edit --sandbox
    # /// script
    # requires-python = ">=3.11"
    # dependencies = [
    #     "numpy",
    # ]
    # ///
---   
dmadisetti commented 1 week ago

Yeah, this works, but seems a little bulky when marimo does offer first class --sandbox support

---
title: Notebook
marimo-version: 0.0.0
width: medium
header: |
    #! /usr/bin/env nix
    #! nix shell --impure --expr ``
    #! nix with (import (builtins.getFlake ''nixpkgs'') {});
    #! nix    python311.withPackages (
    #! nix            ps: with ps; [ marimo uv setuptools ]
    #! nix    )
    #! nix ``
    #! nix --command marimo edit --sandbox
    """
    Maybe preserve doc strings too
    """
sandbox: |
    requires-python = ">=3.11"
    dependencies = [
        "numpy",
    ]
---

Why add the prefix overhead for users?

Related, https://github.com/marimo-team/marimo/issues/1451 may only offer limited backwards compatibility So there might be an opportunity to play with the md format more

mscolnick commented 1 week ago

Why add the prefix overhead for users?

I dont see this as overhead but rather transparency. It's very WYSIWYG.

Also we don't need to track which prefix types there are # vs # script vs#! and all the possible executable types.