Skip to content

Comments

feat: add --download_only flag and visdom-download CLI for offline setups#960

Open
pankajbaid567 wants to merge 1 commit intofossasia:masterfrom
pankajbaid567:feature/download-only-cli
Open

feat: add --download_only flag and visdom-download CLI for offline setups#960
pankajbaid567 wants to merge 1 commit intofossasia:masterfrom
pankajbaid567:feature/download-only-cli

Conversation

@pankajbaid567
Copy link

@pankajbaid567 pankajbaid567 commented Feb 19, 2026

Description

Adds a dedicated mechanism to download all required static assets (JS, CSS, fonts) without starting the Tornado server. Users on air-gapped/offline machines currently have to manually hack run_server.py (comment out main()) just to download dependencies on an online machine — this change makes that a first-class feature.

Three ways to use:

  • visdom --download_only — new flag on the existing CLI
  • visdom-download — new dedicated console-script entry point
  • python -m visdom.server --download_only — module invocation

Files changed:

  • py/visdom/server/run_server.py — added --download_only arg to the parser and a new download_only() function
  • setup.py — added visdom-download console-script entry point
  • py/visdom/server/__main__.py — routes --download_only to download_only() when invoked as a module

Motivation and Context

Fixes #942. Users with offline Linux servers need to download Visdom's JS/CSS/font dependencies on an online machine and then copy them over. The current workaround requires manually editing run_server.py to comment out main(). This change provides a clean, supported way to do that.

How Has This Been Tested?

  • All three modified files verified with ast.parse — no syntax errors.
  • Manual verification: confirmed --download_only flag triggers download_scripts() and exits without starting the Tornado server (no "It's Alive!" message).
  • Confirmed that the normal visdom command still works as before (backward compatible).

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Code refactor or cleanup (changes to existing code for improved readability or performance)

Checklist:

  • I adapted the version number under py/visdom/VERSION according to Semantic Versioning
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.

Summary by Sourcery

Introduce a dedicated offline asset download mode for Visdom without starting the server.

New Features:

  • Add a --download_only flag to the Visdom server CLI to download static assets and exit without running the server.
  • Expose a new visdom-download console script entry point for downloading Visdom client assets in isolation.

Copilot AI review requested due to automatic review settings February 19, 2026 21:29
@sourcery-ai
Copy link

sourcery-ai bot commented Feb 19, 2026

Reviewer's Guide

Adds a first-class offline asset download mechanism for Visdom by introducing a --download_only flag, a dedicated visdom-download entry point, and wiring module/CLI entry points to invoke a new download-only helper without starting the Tornado server.

Sequence diagram for new CLI and module download_only invocations

sequenceDiagram
    actor User
    participant Shell
    participant ConsoleScript_visdom as visdom_console_script
    participant ConsoleScript_visdom_download as visdom_download_console_script
    participant PyModule_main as visdom_server___main__
    participant RunServer as visdom_server_run_server

    %% visdom --download_only path
    User->>Shell: visdom --download_only
    Shell->>ConsoleScript_visdom: invoke entry_point visdom
    ConsoleScript_visdom->>RunServer: call download_scripts_and_run()
    RunServer->>RunServer: parse_args()
    RunServer->>RunServer: FLAGS.download_only == True
    RunServer->>RunServer: download_scripts()
    RunServer->>User: print Downloaded all required scripts. Exiting.
    RunServer-->>ConsoleScript_visdom: return

    %% visdom-download path
    User->>Shell: visdom-download
    Shell->>ConsoleScript_visdom_download: invoke entry_point visdom-download
    ConsoleScript_visdom_download->>RunServer: call download_only()
    RunServer->>RunServer: download_scripts()
    RunServer->>User: print Downloaded all required scripts. Exiting.
    RunServer-->>ConsoleScript_visdom_download: return

    %% python -m visdom.server --download_only path
    User->>Shell: python -m visdom.server --download_only
    Shell->>PyModule_main: run visdom.server.__main__
    PyModule_main->>PyModule_main: detect --download_only in sys.argv
    PyModule_main->>RunServer: import download_only
    PyModule_main->>RunServer: call download_only()
    RunServer->>RunServer: download_scripts()
    RunServer->>User: print Downloaded all required scripts. Exiting.
    RunServer-->>PyModule_main: return
Loading

File-Level Changes

Change Details Files
Add --download_only CLI flag to run_server.main to download assets and exit without starting the server.
  • Extend the argument parser in main() with a --download_only store_true flag defaulting to False.
  • Short-circuit main() when --download_only is set to call download_scripts(), print a confirmation message, and return before server startup logic.
  • Ensure existing server startup flow remains the same when --download_only is not provided.
py/visdom/server/run_server.py
Introduce a reusable download_only() helper to centralize non-server asset downloads.
  • Add download_only() function that calls download_scripts() and prints a standardized completion message.
  • Leave existing download_scripts_and_run() entry point intact for normal behavior.
  • Reuse the same "Downloaded all required scripts. Exiting." message as in the CLI flag path for consistency.
py/visdom/server/run_server.py
Wire Python module entry point (main) to support --download_only without starting the server.
  • In main.py, inspect sys.argv for --download_only before importing run_server entry functions.
  • When --download_only is present, import and invoke download_only(); otherwise, import and invoke download_scripts_and_run().
  • Preserve Python 3 version assertion and default behavior for standard module invocation.
py/visdom/server/__main__.py
Expose a new visdom-download console script for offline asset downloads.
  • Update setup.py entry_points.console_scripts to keep visdom mapped to download_scripts_and_run.
  • Add visdom-download entry point mapped to visdom.server.run_server:download_only for a dedicated download-only CLI.
  • Maintain packaging metadata and existing requirements unchanged.
setup.py

Assessment against linked issues

Issue Objective Addressed Explanation
#942 Provide a built-in, officially supported way to download all required Visdom static assets (JS, CSS, fonts) without starting the server, so users with offline/air‑gapped Linux servers no longer need to manually edit run_server.py.

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • Using the existing visdom console script with --download_only will currently call download_scripts() twice (via download_scripts_and_run() and then again in main()), so consider either wiring the entry point to main() directly or skipping the initial download when the flag is present.
  • The download-only behavior is duplicated between the if FLAGS.download_only branch in main() and the separate download_only() function; it would be cleaner to have main() delegate to download_only() to keep the logic in one place.
  • Instead of manually checking for "--download_only" in sys.argv inside __main__.py, consider delegating to run_server.main() and relying on its argument parsing so that option handling stays centralized and consistent.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Using the existing `visdom` console script with `--download_only` will currently call `download_scripts()` twice (via `download_scripts_and_run()` and then again in `main()`), so consider either wiring the entry point to `main()` directly or skipping the initial download when the flag is present.
- The download-only behavior is duplicated between the `if FLAGS.download_only` branch in `main()` and the separate `download_only()` function; it would be cleaner to have `main()` delegate to `download_only()` to keep the logic in one place.
- Instead of manually checking for "--download_only" in `sys.argv` inside `__main__.py`, consider delegating to `run_server.main()` and relying on its argument parsing so that option handling stays centralized and consistent.

## Individual Comments

### Comment 1
<location> `py/visdom/server/run_server.py:155-158` </location>
<code_context>
+    )
     FLAGS = parser.parse_args()

+    if FLAGS.download_only:
+        download_scripts()
+        print("Downloaded all required scripts. Exiting.")
+        return
+
     # Process base_url
</code_context>

<issue_to_address>
**issue (bug_risk):** Avoid running `download_scripts()` twice when `--download_only` is used via the `visdom` console script.

Because the `visdom` entry point always calls `download_scripts_and_run()`, which unconditionally runs `download_scripts()` before `main()`, adding another `download_scripts()` in the `if FLAGS.download_only` block makes `visdom --download_only` download twice. In contrast, `python -m visdom.server --download_only` (which uses `download_only()`) only downloads once.

To fix this, ensure `download_scripts()` is called in exactly one place per invocation, e.g. by:
- Moving the call into `main()` and gating it on parsed flags, or
- Letting `download_scripts_and_run()` inspect the flags/argv and skip its initial call when `--download_only` is present.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link

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

This PR adds a dedicated mechanism to download Visdom's static assets (JavaScript, CSS, fonts) without starting the Tornado server, addressing a common pain point for users with air-gapped/offline systems. Previously, users had to manually modify run_server.py to achieve this. The change provides three ways to invoke the download-only mode: visdom --download_only, visdom-download, and python -m visdom.server --download_only.

Changes:

  • Added --download_only CLI flag to the existing visdom command
  • Created new visdom-download console script entry point
  • Implemented module invocation support via __main__.py

Reviewed changes

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

File Description
setup.py Adds visdom-download as a new console script entry point
py/visdom/server/run_server.py Adds --download_only argument parser flag and new download_only() function
py/visdom/server/main.py Routes --download_only flag to appropriate function when module is invoked

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

@pankajbaid567 pankajbaid567 force-pushed the feature/download-only-cli branch from 3c6c79e to 0f7d947 Compare February 19, 2026 21:34
…tups

Adds a dedicated mechanism to download all required static assets
(JS, CSS, fonts) without starting the Tornado server. This addresses
the workflow described in issue fossasia#942 where users on air-gapped machines
need to pre-download assets on an online machine.

Three ways to use:
  - visdom --download_only
  - visdom-download
  - python -m visdom.server --download_only

Closes fossasia#942
@pankajbaid567 pankajbaid567 force-pushed the feature/download-only-cli branch from 0f7d947 to 9928d0d Compare February 19, 2026 21:43
@norbusan
Copy link
Member

A few things worth addressing:

  1. Double download risk: download_scripts_and_run() (run_server.py:234) already calls download_scripts() before main(). If main() also calls download_scripts() when it detects --download_only, assets get downloaded twice when using the visdom console script with that flag. Consider having download_scripts_and_run() drop its own download_scripts() call and let main() be the single place that decides whether and when to download, or restructure so the download happens in exactly one place regardless of entry point.

  2. download_only() wrapper: This function exists only to call main() via a private _download_only kwarg. It would be cleaner for the visdom-download entry point to call a properly documented public function rather than tunnelling through an internal flag.

  3. Test coverage: Is there a way to add a smoke test that verifies the flag exits cleanly without starting the server? Even a simple check that "It's Alive!" is absent from stdout would prevent regressions.

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.

quickly and manually download all the required packages by the following method

2 participants