Run streamlit from PyCharm

Hi,
I used to run and debug streamlit (version below 1.0) from PyCharm as a module according to this manual:
stack overflow: How to run/debug a streamlit application from an IDE

TL;DR:
PyCharm runs streamlit as:

python -m streamlit.cli run app.py

Now I have updated streamlit to version 1.5 and it does not work anymore:

File "/some/path/python3.8/site-packages/streamlit/cli.py", line 214, in _get_command_line_as_string
    assert parent.command_path == "streamlit"
AssertionError

Is there a quick fix or is this way of running streamlit not supported anymore, as the assertion now requires that streamlit is run from the streamlit executable?

3 Likes

Hey @schilli,

This is a bit of a fun story. We actually didn’t realize there was a pretty large group of people (mostly PyCharm and VSCode users) running streamlit via python -m streamlit.cli <command>. This method was discovered by the community and seems to have spread through the StackOverflow post that you linked, but internally we never really considered it a “supported” method (it’s undocumented so isn’t considered part of our public API. It just so happens that you used to be able to run the submodule to get functionality equivalent to using streamlit run <command>).

A very similar and equivalent way of invoking streamlit that is supported (so has guarantees to not be broken in the future) is to simply run:

python -m streamlit <command>

instead. Alternatively, another way of running streamlit from PyCharm is described here: Version 1.5.0 - #11 by tim

We’re discussing this internally since it is unfortunate that we inadvertently broke some people’s dev envs, and while a decision hasn’t been finalized, it sounds like we’ll likely keep things as-is (but improve the error message / add official documentation for setting up Streamlit with PyCharm/VSCode) since

  • it feels a bit weird adding official support for a way of invoking streamlit that we never intended to officially support (my guess is that that particular file is only runnable because it made it easier to build/debug when streamlit was first being built, and we just forgot to remove those lines)
  • it’s not too much effort to just remove the .cli so that streamlit is now being started using a supported method
4 Likes

In Pycharm i run streamlit like i would through a terminal as Pycharm gives you good terminal access.

1 Like

But that is not as nice for debugging for example!

1 Like

Hi @vdonato,
Great answer, I really appreciate your effort!
I just tried your solution of removing the .cli and it works like a (py)charm :grin:!
Cheers
Oliver

3 Likes

Can confirm running through Pycharm is very nice, especially for debugging. Removing cli is working for me too.

1 Like


anyone can you help with the problem here

1 Like

It works with pdf breakpoint() inserted in code.

1 Like

Hello knowledgeable Streamlit-ers!

I’ve been trying for the last few hours to debug my streamlit application using the methods described in this thread and the various linked threads but have not been able to get it working. The app runs fine using the streamlit run command.

My environment:

  • Windows 10
  • Anaconda
  • PyCharm
  • python 3.10.13
  • streamlit 1.26.0

Here is my configuration which, based on reading these threads, seems to be the recommended approach:

When I try to debug using this configuration, I see the following error:

I’ve also tried using streamlit.cli as the module name which yields the following error:
image

I’ve also tried the debug configuration where you specify a script instead of a module:

which yields the following error:

Any suggestions would be greatly appreciated! I’m nearing my wits’ end here on this problem.

2 Likes

I managed to solve the issue! One of the folders in my project was named “streamlit” which seemed to be causing conflict issues with the actual streamlit module.

2 Likes

In recent versions i use streamlit.web.cli module in pycharm configurations.
Works with pycharm debugger as well.

2 Likes

hi suhas,

i am having the same issue did you figure it out?

thank you

1 Like

Hi @vdonato
I am trying to run streamlit in PyCharm 2023.3.4 Professional like you describe, and am getting the below error.
Any suggestions on how to fix that?

Exception in callback <Task pending name='Task-1' coro=<run.<locals>.run_server() running at C:\Users\egor.kraev\AppData\Local\miniconda3\envs\llm3.11\Lib\site-packages\streamlit\web\bootstrap.py:391> cb=[_run_until_complete_cb() at C:\Users\egor.kraev\AppData\Local\miniconda3\envs\llm3.11\Lib\asyncio\base_events.py:180]>()
handle: <Handle <Task pending name='Task-1' coro=<run.<locals>.run_server() running at C:\Users\egor.kraev\AppData\Local\miniconda3\envs\llm3.11\Lib\site-packages\streamlit\web\bootstrap.py:391> cb=[_run_until_complete_cb() at C:\Users\egor.kraev\AppData\Local\miniconda3\envs\llm3.11\Lib\asyncio\base_events.py:180]>()>
Traceback (most recent call last):
  File "C:\Users\egor.kraev\AppData\Local\miniconda3\envs\llm3.11\Lib\asyncio\events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
TypeError: 'Task' object is not callable

2 Likes

nm found an answer here

1 Like

This is my set up:

And I had to edit the local streamlit .toml file to get it to connect to my account

(venv) (base) joergbln@iMac-von-Jorg Weather-Bot % streamlit config show

Below are all the sections and options you can have in

~/.streamlit/config.toml.

[global]

By default, Streamlit displays a warning when a user sets both a widget

default value in the function defining the widget and a widget value via

the widget’s key in st.session_state.

If you’d like to turn off this warning, set this to True.

Default: false

disableWidgetStateDuplicationWarning = false

If True, will show a warning when you run a Streamlit-enabled script

via “python my_script.py”.

Default: true

showWarningOnDirectExecution = true

[logger]

Level of logging: ‘error’, ‘warning’, ‘info’, or ‘debug’.

Default: ‘info’

level = “info”

String format for logging messages. If logger.datetimeFormat is set,

logger messages will default to %(asctime)s.%(msecs)03d %(message)s. See

Python’s documentation

for available attributes.

Default: “%(asctime)s %(message)s”

messageFormat = “%(asctime)s %(message)s”

[client]

Controls whether uncaught app exceptions and deprecation warnings

are displayed in the browser. By default, this is set to True and

Streamlit displays app exceptions and associated tracebacks, and

deprecation warnings, in the browser.

If set to False, deprecation warnings and full exception messages

will print to the console only. Exceptions will still display in the

browser with a generic error message. For now, the exception type and

traceback show in the browser also, but they will be removed in the

future.

Default: true

showErrorDetails = true

Change the visibility of items in the toolbar, options menu,

and settings dialog (top right of the app).

Allowed values:

* “auto” : Show the developer options if the app is accessed through

localhost or through Streamlit Community Cloud as a developer.

Hide them otherwise.

* “developer” : Show the developer options.

* “viewer” : Hide the developer options.

* “minimal” : Show only options set externally (e.g. through

Streamlit Community Cloud) or through st.set_page_config.

If there are no options left, hide the menu.

Default: “auto”

toolbarMode = “auto”

Controls whether the default sidebar page navigation in a multi-page app is displayed.

Default: true

showSidebarNavigation = true

[runner]

Allows you to type a variable or string by itself in a single line of

Python code to write it to the app.

Default: true

magicEnabled = true

Handle script rerun requests immediately, rather than waiting for script

execution to reach a yield point. This makes Streamlit much more

responsive to user interaction, but it can lead to race conditions in

apps that mutate session_state data outside of explicit session_state

assignment statements.

Default: true

fastReruns = true

Raise an exception after adding unserializable data to Session State.

Some execution environments may require serializing all data in Session

State, so it may be useful to detect incompatibility during development,

or when the execution environment will stop supporting it in the future.

Default: false

enforceSerializableSessionState = false

Adjust how certain ‘options’ widgets like radio, selectbox, and

multiselect coerce Enum members when the Enum class gets

re-defined during a script re-run.

Allowed values:

* “off”: Disables Enum coercion.

* “nameOnly”: Enum classes can be coerced if their member names match.

* “nameAndValue”: Enum classes can be coerced if their member names AND

member values match.

Default: “nameOnly”

enumCoercion = “nameOnly”

[server]

List of folders that should not be watched for changes. This

impacts both “Run on Save” and @st.cache.

Relative paths will be taken as relative to the current working directory.

Example: [‘/home/user1/env’, ‘relative/path/to/folder’]

Default:

folderWatchBlacklist =

Change the type of file watcher used by Streamlit, or turn it off

completely.

Allowed values:

* “auto” : Streamlit will attempt to use the watchdog module, and

falls back to polling if watchdog is not available.

* “watchdog” : Force Streamlit to use the watchdog module.

* “poll” : Force Streamlit to always use polling.

* “none” : Streamlit will not watch files.

Default: “auto”

fileWatcherType = “auto”

Symmetric key used to produce signed cookies. If deploying on multiple replicas, this should

be set to the same value across all replicas to ensure they all share the same secret.

Default: randomly generated secret key.

cookieSecret = “17c8c38fd26cb3f8848c0502b3fd0cb5fa7e769971a6105d034e938e045fbe93”

If false, will attempt to open a browser window on start.

Default: false unless (1) we are on a Linux box where DISPLAY is unset, or

(2) we are running in the Streamlit Atom plugin.

headless = false

Automatically rerun script when the file is modified on disk.

Default: false

runOnSave = false

The address where the server will listen for client and browser

connections. Use this if you want to bind the server to a specific address.

If set, the server will only be accessible from this address, and not from

any aliases (like localhost).

Default: (unset)

address =

The port where the server will listen for browser connections.

Don’t use port 3000 which is reserved for internal development.

Default: 8501

port = 8501

The base path for the URL where Streamlit should be served from.

Default: “”

baseUrlPath = “”

Enables support for Cross-Origin Resource Sharing (CORS) protection, for added security.

Due to conflicts between CORS and XSRF, if server.enableXsrfProtection is on and

server.enableCORS is off at the same time, we will prioritize server.enableXsrfProtection.

Default: true

enableCORS = true

Enables support for Cross-Site Request Forgery (XSRF) protection, for added security.

Due to conflicts between CORS and XSRF, if server.enableXsrfProtection is on and

server.enableCORS is off at the same time, we will prioritize server.enableXsrfProtection.

Default: true

enableXsrfProtection = true

Max size, in megabytes, for files uploaded with the file_uploader.

Default: 200

maxUploadSize = 200

Max size, in megabytes, of messages that can be sent via the WebSocket connection.

Default: 200

maxMessageSize = 200

Enables support for websocket compression.

Default: false

enableWebsocketCompression = false

Enable serving files from a static directory in the running app’s directory.

Default: false

enableStaticServing = false

Server certificate file for connecting via HTTPS.

Must be set at the same time as “server.sslKeyFile”.

[‘DO NOT USE THIS OPTION IN A PRODUCTION ENVIRONMENT. It has not gone through security audits or performance tests. For the production environment, we recommend performing SSL termination by the load balancer or the reverse proxy.’]

sslCertFile =

Cryptographic key file for connecting via HTTPS.

Must be set at the same time as “server.sslCertFile”.

[‘DO NOT USE THIS OPTION IN A PRODUCTION ENVIRONMENT. It has not gone through security audits or performance tests. For the production environment, we recommend performing SSL termination by the load balancer or the reverse proxy.’]

sslKeyFile =

[browser]

Internet address where users should point their browsers in order to

connect to the app. Can be IP address or DNS name and path.

This is used to:

- Set the correct URL for CORS and XSRF protection purposes.

- Show the URL on the terminal

- Open the browser

Default: “localhost”

serverAddress = “localhost”

Whether to send usage statistics to Streamlit.

Default: true

gatherUsageStats = true

Port where users should point their browsers in order to connect to the

app.

This is used to:

- Set the correct URL for XSRF protection purposes.

- Show the URL on the terminal (part of streamlit run).

- Open the browser automatically (part of streamlit run).

This option is for advanced use cases. To change the port of your app, use

server.Port instead. Don’t use port 3000 which is reserved for internal

development.

Default: whatever value is set in server.port.

serverPort = 8501

[mapbox]

Configure Streamlit to use a custom Mapbox

token for elements like st.pydeck_chart and st.map.

To get a token for yourself, create an account at

https://mapbox.com. It’s free (for moderate usage levels)!

Default: “”

token = “”

[theme]

The preset Streamlit theme that your custom theme inherits from.

One of “light” or “dark”.

base =

Primary accent color for interactive elements.

primaryColor =

Background color for the main content area.

backgroundColor =

Background color used for the sidebar and most interactive widgets.

secondaryBackgroundColor =

Color used for almost all text.

textColor =

Font family for all text in the app, except code blocks. One of “sans serif”,

“serif”, or “monospace”.

font =

(venv) (base) joergbln@iMac-von-Jorg Weather-Bot % cd ~/.streamlit

(venv) (base) joergbln@iMac-von-Jorg .streamlit % ls

credentials.toml

(venv) (base) joergbln@iMac-von-Jorg .streamlit % touch config.toml

(venv) (base) joergbln@iMac-von-Jorg .streamlit % nano config.toml

add your email under general

Another PyCharm debug question.

Trying to get the debugger running in PyCharm. Here’s my run config:

dataframe.py:

import streamlit as st
import pandas as pd
# Matplotlib must be imported or the code will fail.
import matplotlib.pyplot as plt  # Ensure Matplotlib is imported

st.title("DataFrame Formatting Example")

# Create a sample DataFrame
df = pd.DataFrame({
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [24, 27, 22],
    'Score': [85, 90, 95]
})

# Display DataFrame with default styling
st.dataframe(df)

# Custom styling using pandas
styled_df = df.style.background_gradient(cmap='Blues')
st.dataframe(styled_df)

Here’s the terminal when the RUN mode is used: (works fine)

Heres the terminal output when running in debug mode:

import sys; print('Python %s on %s' % (sys.version, sys.platform))
C:\Users\pmora\Documents\Git\GitHub\StreamLitTest\StreamLitTest\.venv\Scripts\python.exe -X pycache_prefix=C:\Users\pmora\AppData\Local\JetBrains\PyCharm2024.1\cpython-cache C:\Users\pmora\AppData\Roaming\JetBrains\PyCharm2024.1\plugins\evaluate-async-code\_pydevd_async_debug.py "C:/Program Files/JetBrains/PyCharm 2023.1.3/plugins/python/helpers/pydev/pydevd.py" --multiprocess --qt-support=auto --client 127.0.0.1 --port 49893 --file .venv\Scripts\streamlit.exe run dataframe.py 
Connected to pydev debugger (build 241.18034.82)
Traceback (most recent call last):
  File "C:\Users\pmora\AppData\Local\Programs\Python\Python311\Lib\tokenize.py", line 334, in find_cookie
    line_string = line.decode('utf-8')
                  ^^^^^^^^^^^^^^^^^^^^
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x90 in position 2: invalid start byte
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "C:\Users\pmora\AppData\Local\Programs\Python\Python311\Lib\tokenize.py", line 398, in open
    encoding, lines = detect_encoding(buffer.readline)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\pmora\AppData\Local\Programs\Python\Python311\Lib\tokenize.py", line 375, in detect_encoding
    encoding = find_cookie(first)
               ^^^^^^^^^^^^^^^^^^
  File "C:\Users\pmora\AppData\Local\Programs\Python\Python311\Lib\tokenize.py", line 339, in find_cookie
    raise SyntaxError(msg)
SyntaxError: invalid or missing encoding declaration for '.venv\\Scripts\\streamlit.exe'
python-BaseException

Streamlit, version 1.36.0
Python 3.11.4
PyCharm 2024.1.4 (Build #PY-241.18034.82, built on June 24, 2024)

Any ideas/ comments? It looks like it might be an asyncio debugger issue in PyCharm???

OK I figured it out!

A module called main.py contains this code:

import streamlit as st


# Define a callback function
def my_callback():
    st.sidebar.write("settings clicked!")

st.title("Complex Layout Example")

# Sidebar for navigation
st.sidebar.header("Navigation")
st.sidebar.button("Home")
if st.sidebar.button("Settings"):
    my_callback()

# Main content with columns and expander
col1, col2 = st.columns([2, 1])


with col1:
    st.header("Main Content")
    with st.expander("More Information"):
        st.write("Additional details can go here")
        st.button("Expander Button")

with col2:
    st.header("Sidebar Content")
    st.button("Sidebar Button")

# Additional content in a container
with st.container():
    st.header("Footer Section")
    st.write("Footer content goes here")

The key that worked for me is to create another module called run.py

try:
    # for streamlit >= 1.12.1
    from streamlit.web import bootstrap
except ImportError:
    from streamlit import bootstrap

real_script = 'main.py'
bootstrap.run(real_script, False, [f'run.py {real_script}'], {})

Then setup a run configuration as follow:

Then set a Registry value in pycharm: python.debug.asyncio.repl
The registry can be modified by pressing Shift Shift from within PyCharm


Uncheck the python.debug.asyncio.repl value, save and restart PyCharm.