vscode-jupyter
vscode-jupyter copied to clipboard
Ability to add command line arguments for terminal or in interactive window
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))
Thanks for the feedback, @memo!
Same problem here, is there any improvement?
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?
Same issue -- would like to
- call my script with arguments from a separate
cli.pymodule (this file contains cli commands for all scripts) - 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.
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
Applies to startup of the kernels, and I believe we've had similar requests for nb as well.
Closing this issue as there haven't been enough upvotes on this feature request