Skip to content

Featuring Notebook (Colab/Jupyter) Compatibility#42

Merged
p-e-w merged 7 commits intop-e-w:masterfrom
Vinay-Umrethe:master
Nov 24, 2025
Merged

Featuring Notebook (Colab/Jupyter) Compatibility#42
p-e-w merged 7 commits intop-e-w:masterfrom
Vinay-Umrethe:master

Conversation

@Vinay-Umrethe
Copy link
Contributor

This time freshly added compatiblity so it's preserves TUI experience with arrow keys for local terminal usage, while also making it usable to people using a notebook environment

Notes:

Practically tested but your suggestion of rich for _jupyter didn't worked that import doesn't work since that function in rich library is not so robust

Even tried hardcoding that same function exactly from the library itself, yet didn't worked.
So TO Ensure it works used a better is_notebook function

It works properly as tested other don't

Copy link
Owner

@p-e-w p-e-w left a comment

Choose a reason for hiding this comment

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

Thanks, this is looking much better now!

I'm surprised that Rich, which is used by tens of thousands of Python projects, should have broken notebook detection. Can you describe where Rich's function failed in your tests?

if is_notebook():
print()
if password:
return getpass.getpass(message)
Copy link
Owner

Choose a reason for hiding this comment

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

Please move password handling into prompt_password. There is no need to clutter this function with unrelated functionality.

# For text input, we might need unsafe_ask if requested
kwargs = {"default": default}
if qmark:
kwargs["qmark"] = qmark
Copy link
Owner

Choose a reason for hiding this comment

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

You can just set the qmark default to "?" in the arguments (which is what Questionary uses) and save yourself this kwargs trick. Just pass the parameters regularly then.

return result if result else default
else:
return questionary.path(
message, default=default, only_directories=only_directories
Copy link
Owner

Choose a reason for hiding this comment

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

Adding only_directories is a good improvement, but you aren't using it! The path prompt for saving the model should use only_directories=True to make this actually work.

@Vinay-Umrethe
Copy link
Contributor Author

Vinay-Umrethe commented Nov 24, 2025

I'm surprised that Rich, which is used by tens of thousands of Python projects, should have broken notebook detection. Can you describe where Rich's function failed in your tests?

You can review those fixes you told they are done, regarding rich for notebook detection this is what we got :

def _is_jupyter() -> bool:  # pragma: no cover
    """Check if we're running in a Jupyter notebook."""
    try:
        get_ipython  # type: ignore[name-defined]
    except NameError:
        return False
    ipython = get_ipython()  # type: ignore[name-defined]
    shell = ipython.__class__.__name__
    if (
        "google.colab" in str(ipython.__class__)
        or os.getenv("DATABRICKS_RUNTIME_VERSION")
        or shell == "ZMQInteractiveShell"
    ):
        return True  # Jupyter notebook or qtconsole
    elif shell == "TerminalInteractiveShell":
        return False  # Terminal running IPython
    else:
        return False  # Other type (?)

THIS FUNCTION ABOVE IS FROM THE RICH LIBRARY ITSELF, WHICH DOESN'T LOOK SO ROBUST ENOUGHT, AS I BUILD THE VERSION THAT USED THIS IMPORT FUNCTION, + ALSO HARDCODED THIS FUNCTION AS WELL EXACTLY SAME, BOTH TESTS DIDN'T WORKED. (ON COLAB)

WHILE THIS IS MY NEW FUNCTION WHICH IS BETTER AND ACTUALLY WORKS:

def is_notebook() -> bool:
    # Check for specific environment variables (Colab, Kaggle)
    # This is necessary because when running as a subprocess (e.g. !heretic),
    # get_ipython() might not be available or might not reflect the notebook environment.
    if os.getenv("COLAB_GPU") or os.getenv("KAGGLE_KERNEL_RUN_TYPE"):
        return True

    # Check IPython shell type (for library usage)
    try:
        from IPython import get_ipython

        shell = get_ipython()
        if shell is None:
            return False

        shell_name = shell.__class__.__name__
        if shell_name in ["ZMQInteractiveShell", "Shell"]:
            return True

        if "google.colab" in str(shell.__class__):
            return True

        return False
    except (ImportError, NameError, AttributeError):
        return False

possible issues

  1. Rich's _is_jupyter relies entirely on get_ipython()
  2. When a user runs !heretic in a notebook cell, it executes your program as a subprocess (a separate system process). Subprocesses do not inherit the active Python kernel or the get_ipython() object from the notebook. To the subprocess, it just looks like a standard terminal.

@Vinay-Umrethe Vinay-Umrethe requested a review from p-e-w November 24, 2025 13:22
@p-e-w p-e-w merged commit 1efc4ee into p-e-w:master Nov 24, 2025
4 checks passed
@p-e-w
Copy link
Owner

p-e-w commented Nov 24, 2025

Merged! Thank you for the PR, being able to run Heretic from Colab is a useful feature.

@Filippide8864
Copy link

Excuse me, but on kaggle the program don't let me choose anythin' because I can't use inputs. Maybe there is an error by me or I don't know what to do. Can you help me?

@Vinay-Umrethe
Copy link
Contributor Author

@Filippide8864 actually, for colab since it supports input() typing normally no matter we run a code using a script path or directly in code cell, but kaggle only supports input() when we run the code in cell

it's not just for heretic but for all kind of code, so it's a issue with kaggle which is there for years

@Vinay-Umrethe Vinay-Umrethe changed the title Featuring Notebook (Colab/Kaggle) Compatibility Featuring Notebook (Colab/Jupyter) Compatibility Feb 19, 2026
@Filippide8864
Copy link

So, what can I do for use heretic on Kaggle?

@Vinay-Umrethe
Copy link
Contributor Author

Vinay-Umrethe commented Feb 19, 2026

well as I remember the 1st options when all trials are done is likely save the model? that's what you can do or select a trial normally the best trial is at top of list, so just try hitting enter or mouse clicks somehow might work as I remember,

since the 2x t4 GPU is what I assume mostly matter to you + it's 12 hour session time, instead of a single t4 on colab.

You can route heretic into a gradio app or different tunneling options you can find, and run heretic from there, the backend will be kaggle GPUs though the frontend would be hosted to a link you'll get there

OR, you can also try setting up modal.com GPUs they provide literal most powerful GPUs with minimal setup, you can even run anything from your own device in your terminal/IDE and all process will be done in their GPU clusters

@Filippide8864
Copy link

Thanks, but I use the P100, cuz I only run it on less then 4B models; so I don't need a lot of time, but I can't find a gradio app for heretic. There is a good one or I have to do it myself?

@Vinay-Umrethe
Copy link
Contributor Author

You can do it yourself, but if need help, here's what gemini suggests:

To achieve a full terminal interface (TUI) for running heretic on Kaggle from another tab, you can use ttyd (a tool to share your terminal over the web) combined with Cloudflared for tunneling. This creates a secure, web-based terminal that executes commands directly on the Kaggle GPU backend.

Step-by-Step Implementation

  • Enable Internet: In your Kaggle notebook, ensure Internet on is toggled in the right-hand "Settings" sidebar.
  • Install Tools: Run the following in a notebook cell to install ttyd (terminal-over-http) and cloudflared (tunneling):
!apt-get update && apt-get install -y ttyd
!wget -q https://github.com
!dpkg -i cloudflared-linux-amd64.deb
  • Launch the Terminal and Tunnel: Use this Python snippet to start the terminal on a local port and tunnel it to a public URL:
import subprocess
import time

# 1. Start ttyd on port 7681 in the background
# This hosts a bash shell that you can access via browser
subprocess.Popen(["ttyd", "-p", "7681", "bash"])

# 2. Start Cloudflare Tunnel to expose port 7681
# 'trycloudflare' generates a free, random public URL
proc = subprocess.Popen(
    ["cloudflared", "tunnel", "--url", "http://localhost:7681"],
    stdout=subprocess.PIPE,
    stderr=subprocess.STDOUT,
    text=True
)

# 3. Print the public URL so you can click it
print("Wait for the 'trycloudflare.com' link to appear...")
for line in iter(proc.stdout.readline, ""):
    if "trycloudflare.com" in line:
        print(f"\n--- ACCESS YOUR TERMINAL HERE ---\n{line.strip()}\n----------------------------------")
        break

Open the Link: Click the trycloudflare.com link printed in the output. A new browser tab will open with a fully functional Linux terminal.

Why this works for Heretic

  • Persistent Backend: The terminal runs on the Kaggle kernel. You can start the long-running heretic --model ... command in the terminal tab, and it will continue processing even if you close the terminal tab (as long as the Kaggle notebook session is active).

NOT TESTED BY ME BUT YOU CAN TRY...

daggerstuff pushed a commit to daggerstuff/heretic that referenced this pull request Feb 22, 2026
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