Repository: streamlit/streamlit

Issue:
streamlit 1.5 won't start app from vscode debugger
### Summary

streamlit 1.5 does not work with vscode debugger while streamlit 1.3 does on Ubuntu 20

### Steps to reproduce

Code snippet:

```
import streamlit as st
import pandas as pd

st.title("File uploader example")

st.write(
    """
This is an example of how to use a file uploader.
Here, we are simply going to upload a CSV file and display it.
It should serve as a minimal example
for you to jump off and do more complex things.
"""
)

st.header("Upload CSV")
csv_file = st.file_uploader(label="Upload a CSV file", type=["csv"], encoding="utf-8")

if csv_file is not None:
    data = pd.read_csv(csv_file)
    st.dataframe(data)

st.header("Upload Images")

st.write(
    """
Below is another example, where we upload an image and display it.
"""
)

image_file = st.file_uploader(label="Upload an image", type=["png", "jpg", "tiff"], encoding=None)

if image_file is not None:
    st.image(image_file)

```

Then in vscode, use a launch.json that launches treamlit

```
{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "streamlit",
      "type": "python",
      "request": "launch",
      "program": "/home/rave/aquacrop-streamlit/.venv/bin/streamlit",
      "args": ["run", "${file}"],
      "console": "integratedTerminal"
    },
    {
      "name": "Python: Current File",
      "type": "python",
      "request": "launch",
      "program": "${file}",
      "console": "integratedTerminal"
    }
  ]
}
```

**Expected behavior:**

app opens, I can debug it just like with streamlit 1.3

**Actual behavior:**

this error pops up in vscode. the streamlit file in `bin/` is opened

```python
Exception has occurred: AssertionError X
exception: no description
  File "[/home/rave/aquacrop-streamlit/.venv/bin/streamlit]()", line 8, in <module>
    sys.exit(main())
```
If I press continue on the debugger the full traceback shows

```python
Traceback (most recent call last):
  File "/home/rave/miniconda3/lib/python3.8/runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/home/rave/miniconda3/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/rave/.vscode/extensions/ms-python.python-2022.0.1786462952/pythonFiles/lib/python/debugpy/__main__.py", line 45, in <module>
    cli.main()
  File "/home/rave/.vscode/extensions/ms-python.python-2022.0.1786462952/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 444, in main
    run()
  File "/home/rave/.vscode/extensions/ms-python.python-2022.0.1786462952/pythonFiles/lib/python/debugpy/../debugpy/server/cli.py", line 285, in run_file
    runpy.run_path(target_as_str, run_name=compat.force_str("__main__"))
  File "/home/rave/miniconda3/lib/python3.8/runpy.py", line 265, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "/home/rave/miniconda3/lib/python3.8/runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "/home/rave/miniconda3/lib/python3.8/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/rave/aquacrop-streamlit/.venv/bin/streamlit", line 8, in <module>
    sys.exit(main())
  File "/home/rave/aquacrop-streamlit/.venv/lib/python3.8/site-packages/click/core.py", line 1128, in __call__
    return self.main(*args, **kwargs)
  File "/home/rave/aquacrop-streamlit/.venv/lib/python3.8/site-packages/click/core.py", line 1053, in main
    rv = self.invoke(ctx)
  File "/home/rave/aquacrop-streamlit/.venv/lib/python3.8/site-packages/click/core.py", line 1659, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/rave/aquacrop-streamlit/.venv/lib/python3.8/site-packages/click/core.py", line 1395, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/rave/aquacrop-streamlit/.venv/lib/python3.8/site-packages/click/core.py", line 754, in invoke
    return __callback(*args, **kwargs)
  File "/home/rave/aquacrop-streamlit/.venv/lib/python3.8/site-packages/streamlit/cli.py", line 202, in main_run
    _main_run(target, args, flag_options=kwargs)
  File "/home/rave/aquacrop-streamlit/.venv/lib/python3.8/site-packages/streamlit/cli.py", line 228, in _main_run
    command_line = _get_command_line_as_string()
  File "/home/rave/aquacrop-streamlit/.venv/lib/python3.8/site-packages/streamlit/cli.py", line 214, in _get_command_line_as_string
    assert parent.command_path == "streamlit"
AssertionError
```

I tried to debug the streamlit file in site-packages to see what `parent.command_path` was but it said it was not defined.

### Is this a regression?

That is, did this use to work the way you expected in the past?
yes

### Debug info

- Streamlit version: Streamlit, version 1.5.0
- Python version: Python 3.8.12
- I'm using venv with pip
- OS version: Ubuntu 20
- Browser version: not sure but I don't think it's a browser issue


## Env
create a new virtual environment. then
```
pip install streamlit==1.5.0
```
this environment errors as described above

and my 1.3 env that works

```
pip install streamlit==1.3
```


Discussion:
Hi @rbavery, thanks for reporting this!

There were some related issues that people had with running streamlit in IDE/editor debuggers, but in those cases people were using an internal/undocumented API. Looking at your config, I would have thought this should work just fine.

I'll look into this ASAP
@rbavery I'm still working on diagnosing the issue / fixing this exact way of invoking streamlit (I think it has something to do with how the VSCode debugger works), but in the meantime, changing your `launch.json` to launch streamlit as a module using a config file that looks something like 

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Streamlit",
            "type": "python",
            "request": "launch",
            "module": "streamlit",
            "args": [
                "run",
                "${file}",
            ],
        },
    ]
}
```

should fix things for you and should otherwise be equivalent 🙂 

Resolving patch:
diff --git a/lib/streamlit/cli.py b/lib/streamlit/cli.py
--- a/lib/streamlit/cli.py
+++ b/lib/streamlit/cli.py
@@ -111,7 +111,7 @@ def help(ctx):
     # Pretend user typed 'streamlit --help' instead of 'streamlit help'.
     import sys
 
-    # We use _get_command_line_as_string to run some assertions but don't do
+    # We use _get_command_line_as_string to run some error checks but don't do
     # anything with its return value.
     _get_command_line_as_string()
 
@@ -127,7 +127,7 @@ def main_version(ctx):
     # Pretend user typed 'streamlit --version' instead of 'streamlit version'
     import sys
 
-    # We use _get_command_line_as_string to run some assertions but don't do
+    # We use _get_command_line_as_string to run some error checks but don't do
     # anything with its return value.
     _get_command_line_as_string()
 
@@ -215,10 +215,6 @@ def _get_command_line_as_string() -> Optional[str]:
             " unsupported. Please use `python -m streamlit <command>` instead."
         )
 
-    # Assert that the program name we see here is `streamlit`, even if we ran
-    # streamlit some other way than `streamlit run`.
-    assert parent.command_path == "streamlit"
-
     cmd_line_as_list = [parent.command_path]
     cmd_line_as_list.extend(click.get_os_args())
     return subprocess.list2cmdline(cmd_line_as_list)
@@ -303,5 +299,35 @@ def activate_reset():
     Credentials.get_current().reset()
 
 
+# SUBCOMMAND: test
+
+
+@main.group("test", hidden=True)
+def test():
+    """Internal-only commands used for testing.
+
+    These commands are not included in the output of `streamlit help`.
+    """
+    pass
+
+
+@test.command("prog_name")
+def test_prog_name():
+    """Assert that the program name is set to `streamlit test`.
+
+    This is used by our cli-smoke-tests to verify that the program name is set
+    to `streamlit ...` whether the streamlit binary is invoked directly or via
+    `python -m streamlit ...`.
+    """
+    # We use _get_command_line_as_string to run some error checks but don't do
+    # anything with its return value.
+    _get_command_line_as_string()
+
+    parent = click.get_current_context().parent
+
+    assert parent is not None
+    assert parent.command_path == "streamlit test"
+
+
 if __name__ == "__main__":
     main()


Test patch:
diff --git a/scripts/cli_smoke_tests.py b/scripts/cli_smoke_tests.py
--- a/scripts/cli_smoke_tests.py
+++ b/scripts/cli_smoke_tests.py
@@ -20,29 +20,29 @@
 
 
 def main():
-    standard_cli = ["streamlit", "help"]
-    if not _can_run_streamlit_help(standard_cli):
-        sys.exit("Failed to run `streamlit help`")
+    standard_cli = ["streamlit", "test", "prog_name"]
+    if not _can_run_streamlit(standard_cli):
+        sys.exit("Failed to run `streamlit test prog_name`")
 
     # When calling from module, the called argv[0] is updated by
     # __main__.py to be "streamlit" instead of "__main__.py".
     # If this doesn't occur, an assert stops execution of the program.
-    module_cli = ["python", "-m", "streamlit", "help"]
-    if not _can_run_streamlit_help(module_cli):
-        sys.exit("Failed to run `python -m streamlit help`")
+    module_cli = ["python", "-m", "streamlit", "test", "prog_name"]
+    if not _can_run_streamlit(module_cli):
+        sys.exit("Failed to run `python -m streamlit test prog_name`")
 
     # Invoking streamlit via `python -m streamlit.cli <command>` is a method
     # that we previously accidentally supported, but we decided that we should
     # only keep official support for the similar `python -m streamlit <command>`
     # invocation.
-    unsupported_module_cli = ["python", "-m", "streamlit.cli", "help"]
-    if _can_run_streamlit_help(unsupported_module_cli):
-        sys.exit("`python -m streamlit.cli help` should not run")
+    unsupported_module_cli = ["python", "-m", "streamlit.cli", "test", "prog_name"]
+    if _can_run_streamlit(unsupported_module_cli):
+        sys.exit("`python -m streamlit.cli test prog_name` should not run")
 
     click.secho("CLI smoke tests succeeded!", fg="green", bold=True)
 
 
-def _can_run_streamlit_help(command_list):
+def _can_run_streamlit(command_list):
     result = subprocess.run(command_list, stdout=subprocess.DEVNULL)
     return result.returncode == 0