vscode-jupyter icon indicating copy to clipboard operation
vscode-jupyter copied to clipboard

Ability to add command line arguments for terminal or in interactive window

Open memoakten opened this issue 5 years ago • 5 comments

This is related to bug microsoft/vscode-python#11206 which is currently addressed with a workaround. and specifically this comment https://github.com/microsoft/vscode-python/issues/11206#issuecomment-615393463

To summarize here: Currently, using argparse fails (crashes) in the Interactive Window. A workaround is to run sys.argv = [''].

It would be helpful if we could provide command line arguments which are taken into account when running in the terminal, debugging and in the interactive window. These should be stored per file, not per project, since a single project could have multiple files which are run, each with different arguments.

test code:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--test', default='Hello')
args = parser.parse_args()
print(vars(args))

memoakten avatar Apr 27 '20 12:04 memoakten

Thanks for the feedback, @memo!

greazer avatar Jul 27 '20 22:07 greazer

Same problem here, is there any improvement?

melsophos avatar May 14 '21 03:05 melsophos

In-between, I have a question on the workaround: is there any way to say that sys.argv = [''] must be executed only in the interactive window, and not when the file is executed directly with python?

melsophos avatar May 14 '21 18:05 melsophos

Same issue -- would like to

  1. call my script with arguments from a separate cli.py module (this file contains cli commands for all scripts)
  2. run script interactively

Test example:

Script that allows for interactive programming

# ~/script.py

import argparse
import sys

# sys.argv = [
#     ""
# ]  # eliminates the additional args VSCODE passes in, but nullifies cli calls too...

_parser = argparse.ArgumentParser(
    prog="generate",
    description="General purpose data generator script. Executed via CLI or interactively",
)

_parser.add_argument(
    "--dataset", dest="dataset", type=str, default="DEFAULT-DATASET"
)

_parser.add_argument(
    "--output-path", dest="output_path", type=str, default="default/path"
)

_parser.add_argument(
    "--output-filename",
    dest="output_filename",
    type=str,
    default="default-filename.csv",
)

_parsed_args = vars(_parser.parse_args())

print(_parsed_args)

# %%
dataset = _parsed_args.get("dataset")
out_dir = _parsed_args.get("output-path")
f_name = _parsed_args.get("output-filename")

##  rest of interactive script program ##
print("Downloading dataset...")
print("Validating data...")
print("Visualizing statustics...")
print("Storing results...")

CLI that allows for execution from shell

Allows for:

  • executing a command against a docker image
  • central module that serves as an entry-point / interface for all scripts in the software
  • nice CLI tools like Typer
# ~/cli.py
import typer
import subprocess
import os

app = typer.Typer()


@app.command()
def generate(
    dataset: str = typer.Argument(..., help="Dataset name."),
    output_path: str = typer.Option(..., help="Output directory"),
    output_filename: str = typer.Option("item_history.csv"),
):
    cur_dir = os.path.dirname(os.path.abspath(__file__))  # so the two files can be tested in the same folder
    args = [
        "python",
        f"{cur_dir}/script.py",
        "--dataset",
        dataset,
        "--output-path",
        output_path,
        "--output-filename",
        output_filename,
    ]

    subprocess.call(args)


if __name__ == "__main__":
    app()

Problem is that without the sys.args = [''], the cli.py program can pass arguments to the script, but interactive mode fails:

import argparse...
usage: generate [-h] [--dataset DATASET] [--output-path OUTPUT_PATH]
               [--output-filename OUTPUT_FILENAME]
generate: error: unrecognized arguments: --ip=127.0.0.1 --stdin=9081 --control=9079 --hb=9078 --Session.signature_scheme="hmac-sha256" --Session.key=b"c0876012-9ffc-4684-b1a6-7e934ed67b31" --shell=9080 --transport="tcp" --iopub=9082 --f=/var/folders/h9/9wjcb40106v08lqqz3kzp6cm157k5j/T/tmp-28825nt45P9tAmbKy.json
An exception has occurred, use %tb to see the full traceback.

With sys.args = [""] interactive programming works, but the arguments from a cli.py call get erased.

I am aware I can wrap the whole script.py program in a single function and call it from cli.py via import, but this means no interactive programming. Or "importing" the script.py in the cli.py does execute it, but then it's not trivial to pass in parameters to the script.

JoshZastrow avatar Jul 23 '21 18:07 JoshZastrow

update -> at least for the example above, workaround using _parsed_args = vars(_parser.parse_known_args()) will ignore what VScode provided when booting up interactive mode. No need to clear sys.args

JoshZastrow avatar Jul 23 '21 18:07 JoshZastrow

Applies to startup of the kernels, and I believe we've had similar requests for nb as well.

DonJayamanne avatar Aug 15 '22 01:08 DonJayamanne

Closing this issue as there haven't been enough upvotes on this feature request

DonJayamanne avatar Dec 04 '22 18:12 DonJayamanne