streamlit-nightly 1.45.1.dev20250510__py3-none-any.whl → 1.45.2.dev20250512__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- streamlit/commands/experimental_query_params.py +1 -1
- streamlit/commands/navigation.py +1 -4
- streamlit/commands/page_config.py +6 -26
- streamlit/config.py +9 -11
- streamlit/config_util.py +1 -1
- streamlit/connections/sql_connection.py +1 -1
- streamlit/dataframe_util.py +50 -51
- streamlit/elements/arrow.py +1 -1
- streamlit/elements/deck_gl_json_chart.py +1 -4
- streamlit/elements/doc_string.py +1 -4
- streamlit/elements/exception.py +5 -7
- streamlit/elements/layouts.py +4 -3
- streamlit/elements/lib/built_in_chart_utils.py +9 -14
- streamlit/elements/lib/pandas_styler_utils.py +6 -8
- streamlit/elements/map.py +2 -8
- streamlit/elements/markdown.py +1 -4
- streamlit/elements/media.py +50 -2
- streamlit/elements/metric.py +9 -10
- streamlit/elements/widgets/audio_input.py +1 -4
- streamlit/elements/widgets/camera_input.py +1 -4
- streamlit/elements/widgets/chat.py +52 -5
- streamlit/elements/widgets/data_editor.py +1 -1
- streamlit/elements/widgets/slider.py +3 -4
- streamlit/elements/widgets/time_widgets.py +1 -4
- streamlit/env_util.py +2 -7
- streamlit/errors.py +1 -14
- streamlit/logger.py +4 -5
- streamlit/proto/Audio_pb2.py +4 -3
- streamlit/proto/Audio_pb2.pyi +8 -1
- streamlit/proto/Block_pb2.py +5 -5
- streamlit/proto/Block_pb2.pyi +7 -1
- streamlit/proto/ChatInput_pb2.py +8 -7
- streamlit/proto/ChatInput_pb2.pyi +10 -1
- streamlit/proto/PageConfig_pb2.py +7 -7
- streamlit/proto/PageConfig_pb2.pyi +5 -1
- streamlit/proto/Video_pb2.py +8 -7
- streamlit/proto/Video_pb2.pyi +8 -1
- streamlit/runtime/app_session.py +1 -1
- streamlit/runtime/caching/hashing.py +8 -8
- streamlit/runtime/credentials.py +5 -4
- streamlit/runtime/memory_media_file_storage.py +5 -4
- streamlit/runtime/metrics_util.py +1 -1
- streamlit/runtime/scriptrunner/script_runner.py +1 -1
- streamlit/runtime/scriptrunner_utils/script_run_context.py +0 -15
- streamlit/runtime/state/query_params.py +2 -4
- streamlit/runtime/state/session_state.py +15 -15
- streamlit/static/index.html +1 -1
- streamlit/static/static/js/{ErrorOutline.esm.BewaDzzJ.js → ErrorOutline.esm.Cfhrjz42.js} +1 -1
- streamlit/static/static/js/{FileDownload.esm.D6ilL7v-.js → FileDownload.esm.BN5DkI-d.js} +1 -1
- streamlit/static/static/js/{FileHelper.q7erXtkb.js → FileHelper.BWWhRdUs.js} +1 -1
- streamlit/static/static/js/{FormClearHelper.Dd0v0IXt.js → FormClearHelper.CHPGUkGG.js} +1 -1
- streamlit/static/static/js/{Hooks.CchmJZGs.js → Hooks.DjxyUmgD.js} +1 -1
- streamlit/static/static/js/{InputInstructions.DI9h4PJ7.js → InputInstructions.Bkai2tFZ.js} +1 -1
- streamlit/static/static/js/{ProgressBar.DfcVR_JA.js → ProgressBar.DFiqS51i.js} +1 -1
- streamlit/static/static/js/{RenderInPortalIfExists.BAkT-LV5.js → RenderInPortalIfExists.DWTzV71R.js} +1 -1
- streamlit/static/static/js/{Toolbar.CNzefYiX.js → Toolbar.Dk2A3VxL.js} +1 -1
- streamlit/static/static/js/{base-input.BmA1ZV9Y.js → base-input.DfiT3r4p.js} +1 -1
- streamlit/static/static/js/{checkbox.mT4TKcAG.js → checkbox.DLXFjls2.js} +1 -1
- streamlit/static/static/js/{createSuper.Duo43uhY.js → createSuper.n2DV0o-4.js} +1 -1
- streamlit/static/static/js/{data-grid-overlay-editor.CY3l_gmP.js → data-grid-overlay-editor.v1LF25Ml.js} +1 -1
- streamlit/static/static/js/{downloader.CM5asV91.js → downloader.CI8EFE9Y.js} +1 -1
- streamlit/static/static/js/{es6.uiOeU51e.js → es6.CH6Tf3Uw.js} +2 -2
- streamlit/static/static/js/{iframeResizer.contentWindow.ClkMmI3q.js → iframeResizer.contentWindow.VCjyiSg6.js} +1 -1
- streamlit/static/static/js/{index.wiodyGjO.js → index.7XN_jSTW.js} +1 -1
- streamlit/static/static/js/{index.JA6OF_5t.js → index.9p279joF.js} +1 -1
- streamlit/static/static/js/{index.D56z-_rt.js → index.B-Q1qQil.js} +1 -1
- streamlit/static/static/js/{index.3d64wPzr.js → index.B1j5m20t.js} +1 -1
- streamlit/static/static/js/{index.BWubePhz.js → index.BEE4v1Vc.js} +1 -1
- streamlit/static/static/js/{index.C6tuB1Tp.js → index.BFEA8ufN.js} +1 -1
- streamlit/static/static/js/{index.BPK3aPVr.js → index.BROoC18J.js} +1 -1
- streamlit/static/static/js/{index.BnmoQ0mJ.js → index.BWVpiUBA.js} +1 -1
- streamlit/static/static/js/{index.DLO5_tVd.js → index.BgY_Js0s.js} +1 -1
- streamlit/static/static/js/{index.DAEzs_UL.js → index.C1P3O0oI.js} +1 -1
- streamlit/static/static/js/index.C1TEsRV0.js +779 -0
- streamlit/static/static/js/{index.DLyB6OQM.js → index.C9ORVZvA.js} +1 -1
- streamlit/static/static/js/{index.IqYlA3jn.js → index.CR4eM0Q3.js} +1 -1
- streamlit/static/static/js/{index.DeLPvnoy.js → index.CXpQxU0G.js} +1 -1
- streamlit/static/static/js/{index.Dhu_cVNQ.js → index.Cdsxte9t.js} +1 -1
- streamlit/static/static/js/{index.CB8SwV8L.js → index.CmsMgepL.js} +1 -1
- streamlit/static/static/js/{index.D6AKDy4z.js → index.D1An7GDs.js} +1 -1
- streamlit/static/static/js/{index.WlA_Ju7i.js → index.D1DxKfIm.js} +1 -1
- streamlit/static/static/js/{index.DNWXtL99.js → index.DKsDSPTo.js} +1 -1
- streamlit/static/static/js/{index.C1_voZpt.js → index.DMDjQhhk.js} +1 -1
- streamlit/static/static/js/{index.D9lEoddJ.js → index.DM_jnlWC.js} +1 -1
- streamlit/static/static/js/{index.Dj8nqcpI.js → index.DUU38l7N.js} +1 -1
- streamlit/static/static/js/{index.blwBIOHe.js → index.DXDmqevk.js} +1 -1
- streamlit/static/static/js/{index.DeeFVG0Y.js → index.D_Bv6KD1.js} +1 -1
- streamlit/static/static/js/{index.B2EfQ-qM.js → index.DcH46Eo2.js} +1 -1
- streamlit/static/static/js/{index.SW3uv22k.js → index.DgeyRl4J.js} +1 -1
- streamlit/static/static/js/{index.B6y8ns6u.js → index.DoM9A12Z.js} +1 -1
- streamlit/static/static/js/{index.BArkjssT.js → index.LqvX_Kr6.js} +1 -1
- streamlit/static/static/js/{index.CXmZFP__.js → index.Ovig-AMR.js} +62 -62
- streamlit/static/static/js/{index.BmBUBll0.js → index.SPkHHODG.js} +1 -1
- streamlit/static/static/js/{index.DbgE46VI.js → index.STF1QdPr.js} +1 -1
- streamlit/static/static/js/{index.B-oXGsp7.js → index.ZuW7Olhm.js} +1 -1
- streamlit/static/static/js/{index.CYAmxIg2.js → index.hFB9saa3.js} +1 -1
- streamlit/static/static/js/{index.D-zMZsin.js → index.jZkr87Ly.js} +1 -1
- streamlit/static/static/js/{index.B5wTpdet.js → index.nmbrjghZ.js} +1 -1
- streamlit/static/static/js/{index.1tDlzcmX.js → index.uN3TP5oq.js} +1 -1
- streamlit/static/static/js/{index.DpWg6flp.js → index.uhNJX5pn.js} +1 -1
- streamlit/static/static/js/{input.B3uNJm6d.js → input.BAfiLByr.js} +1 -1
- streamlit/static/static/js/{memory.BWtwV556.js → memory.CvD1KGKJ.js} +1 -1
- streamlit/static/static/js/{mergeWith.BeTmYGS_.js → mergeWith.Dy4BuY-h.js} +1 -1
- streamlit/static/static/js/{number-overlay-editor.MW9-6kFx.js → number-overlay-editor.Bl84FLfp.js} +1 -1
- streamlit/static/static/js/{possibleConstructorReturn.ZgHiGHSO.js → possibleConstructorReturn.gffiKeDQ.js} +1 -1
- streamlit/static/static/js/{sandbox.BZyTt4zT.js → sandbox.BXw8ya9t.js} +1 -1
- streamlit/static/static/js/{textarea.CgvEg9Xi.js → textarea.DNNNKi6n.js} +1 -1
- streamlit/static/static/js/{timepicker.CHPC9KOb.js → timepicker.CgHlrhoy.js} +1 -1
- streamlit/static/static/js/{toConsumableArray.6GvveewD.js → toConsumableArray.MtZ-3vir.js} +1 -1
- streamlit/static/static/js/{uniqueId.BV5h1uCx.js → uniqueId.CFcd6g0d.js} +1 -1
- streamlit/static/static/js/{useBasicWidgetState.DzE2MsN8.js → useBasicWidgetState.DadZUraL.js} +1 -1
- streamlit/static/static/js/{useOnInputChange.sGAnyCSU.js → useOnInputChange.V6d5TCFH.js} +1 -1
- streamlit/static/static/js/{withFullScreenWrapper.Bh08pTH8.js → withFullScreenWrapper.8qpius26.js} +1 -1
- streamlit/string_util.py +1 -4
- streamlit/testing/v1/element_tree.py +5 -4
- streamlit/testing/v1/local_script_runner.py +1 -4
- streamlit/type_util.py +2 -5
- streamlit/watcher/path_watcher.py +2 -5
- streamlit/watcher/polling_path_watcher.py +7 -6
- {streamlit_nightly-1.45.1.dev20250510.dist-info → streamlit_nightly-1.45.2.dev20250512.dist-info}/METADATA +1 -1
- {streamlit_nightly-1.45.1.dev20250510.dist-info → streamlit_nightly-1.45.2.dev20250512.dist-info}/RECORD +125 -125
- streamlit/static/static/js/index.PoIwzrI7.js +0 -779
- {streamlit_nightly-1.45.1.dev20250510.data → streamlit_nightly-1.45.2.dev20250512.data}/scripts/streamlit.cmd +0 -0
- {streamlit_nightly-1.45.1.dev20250510.dist-info → streamlit_nightly-1.45.2.dev20250512.dist-info}/WHEEL +0 -0
- {streamlit_nightly-1.45.1.dev20250510.dist-info → streamlit_nightly-1.45.2.dev20250512.dist-info}/entry_points.txt +0 -0
- {streamlit_nightly-1.45.1.dev20250510.dist-info → streamlit_nightly-1.45.2.dev20250512.dist-info}/top_level.txt +0 -0
@@ -123,7 +123,7 @@ def _extract_key_query_params(
|
|
123
123
|
item.lower()
|
124
124
|
for sublist in [
|
125
125
|
[value.lower() for value in query_params[key]]
|
126
|
-
for key in query_params
|
126
|
+
for key in query_params
|
127
127
|
if key.lower() == param_key and query_params.get(key)
|
128
128
|
]
|
129
129
|
for item in sublist
|
streamlit/commands/navigation.py
CHANGED
@@ -311,10 +311,7 @@ def _navigation(
|
|
311
311
|
# Build the pagehash-to-pageinfo mapping.
|
312
312
|
for section_header in nav_sections:
|
313
313
|
for page in nav_sections[section_header]:
|
314
|
-
if isinstance(page._page, Path)
|
315
|
-
script_path = str(page._page)
|
316
|
-
else:
|
317
|
-
script_path = ""
|
314
|
+
script_path = str(page._page) if isinstance(page._page, Path) else ""
|
318
315
|
|
319
316
|
script_hash = page._script_hash
|
320
317
|
if script_hash in pagehash_to_pageinfo:
|
@@ -52,34 +52,10 @@ _About: TypeAlias = Literal["About", "about"]
|
|
52
52
|
MenuKey: TypeAlias = Literal[_GetHelp, _ReportABug, _About]
|
53
53
|
MenuItems: TypeAlias = Mapping[MenuKey, Union[str, None]]
|
54
54
|
|
55
|
-
# Emojis recommended by https://share.streamlit.io/rensdimmendaal/emoji-recommender/main/app/streamlit.py
|
56
|
-
# for the term "streamlit". Watch out for zero-width joiners,
|
57
|
-
# as they won't parse correctly in the list() call!
|
58
55
|
RANDOM_EMOJIS: Final = list(
|
59
56
|
"🔥™🎉🚀🌌💣✨🌙🎆🎇💥🤩🤙🌛🤘⬆💡🤪🥂⚡💨🌠🎊🍿😛🔮🤟🌃🍃🍾💫▪🌴🎈🎬🌀🎄😝☔⛽🍂💃😎🍸🎨🥳☀😍🅱🌞😻🌟😜💦💅🦄😋😉👻🍁🤤👯🌻‼🌈👌🎃💛😚🔫🙌👽🍬🌅☁🍷👭☕🌚💁👅🥰🍜😌🎥🕺❕🧡☄💕🍻✅🌸🚬🤓🍹®☺💪😙☘🤠✊🤗🍵🤞😂💯😏📻🎂💗💜🌊❣🌝😘💆🤑🌿🦋😈⛄🚿😊🌹🥴😽💋😭🖤🙆👐⚪💟☃🙈🍭💻🥀🚗🤧🍝💎💓🤝💄💖🔞⁉⏰🕊🎧☠♥🌳🏾🙉⭐💊🍳🌎🙊💸❤🔪😆🌾✈📚💀🏠✌🏃🌵🚨💂🤫🤭😗😄🍒👏🙃🖖💞😅🎅🍄🆓👉💩🔊🤷⌚👸😇🚮💏👳🏽💘💿💉👠🎼🎶🎤👗❄🔐🎵🤒🍰👓🏄🌲🎮🙂📈🚙📍😵🗣❗🌺🙄👄🚘🥺🌍🏡♦💍🌱👑👙☑👾🍩🥶📣🏼🤣☯👵🍫➡🎀😃✋🍞🙇😹🙏👼🐝⚫🎁🍪🔨🌼👆👀😳🌏📖👃🎸👧💇🔒💙😞⛅🏻🍴😼🗿🍗♠🦁✔🤖☮🐢🐎💤😀🍺😁😴📺☹😲👍🎭💚🍆🍋🔵🏁🔴🔔🧐👰☎🏆🤡🐠📲🙋📌🐬✍🔑📱💰🐱💧🎓🍕👟🐣👫🍑😸🍦👁🆗🎯📢🚶🦅🐧💢🏀🚫💑🐟🌽🏊🍟💝💲🐍🍥🐸☝♣👊⚓❌🐯🏈📰🌧👿🐳💷🐺📞🆒🍀🤐🚲🍔👹🙍🌷🙎🐥💵🔝📸⚠❓🎩✂🍼😑⬇⚾🍎💔🐔⚽💭🏌🐷🍍✖🍇📝🍊🐙👋🤔🥊🗽🐑🐘🐰💐🐴♀🐦🍓✏👂🏴👇🆘😡🏉👩💌😺✝🐼🐒🐶👺🖕👬🍉🐻🐾⬅⏬▶👮🍌♂🔸👶🐮👪⛳🐐🎾🐕👴🐨🐊🔹©🎣👦👣👨👈💬⭕📹📷"
|
60
57
|
)
|
61
58
|
|
62
|
-
# Also pick out some vanity emojis.
|
63
|
-
ENG_EMOJIS: Final = [
|
64
|
-
"🎈", # st.balloons 🎈🎈
|
65
|
-
"🤓", # Abhi
|
66
|
-
"🏈", # Amey
|
67
|
-
"🚲", # Thiago
|
68
|
-
"🐧", # Matteo
|
69
|
-
"🦒", # Ken
|
70
|
-
"🐳", # Karrie
|
71
|
-
"🕹️", # Jonathan
|
72
|
-
"🇦🇲", # Henrikh
|
73
|
-
"🎸", # Guido
|
74
|
-
"🦈", # Austin
|
75
|
-
"💎", # Emiliano
|
76
|
-
"👩🎤", # Naomi
|
77
|
-
"🧙♂️", # Jon
|
78
|
-
"🐻", # Brandon
|
79
|
-
"🎎", # James
|
80
|
-
# TODO: Solicit emojis from the rest of Streamlit
|
81
|
-
]
|
82
|
-
|
83
59
|
|
84
60
|
def _lower_clean_dict_keys(dict: MenuItems) -> dict[str, Any]:
|
85
61
|
return {str(k).lower().strip(): v for k, v in dict.items()}
|
@@ -243,6 +219,7 @@ def set_page_config(
|
|
243
219
|
elif layout == "wide":
|
244
220
|
pb_layout = PageConfigProto.WIDE
|
245
221
|
else:
|
222
|
+
# Note: Pylance incorrectly notes this error as unreachable
|
246
223
|
raise StreamlitInvalidPageLayoutError(layout=layout)
|
247
224
|
|
248
225
|
msg.page_config_changed.layout = pb_layout
|
@@ -255,6 +232,7 @@ def set_page_config(
|
|
255
232
|
elif initial_sidebar_state == "collapsed":
|
256
233
|
pb_sidebar_state = PageConfigProto.COLLAPSED
|
257
234
|
else:
|
235
|
+
# Note: Pylance incorrectly notes this error as unreachable
|
258
236
|
raise StreamlitInvalidSidebarStateError(
|
259
237
|
initial_sidebar_state=initial_sidebar_state
|
260
238
|
)
|
@@ -274,9 +252,8 @@ def set_page_config(
|
|
274
252
|
|
275
253
|
|
276
254
|
def get_random_emoji() -> str:
|
277
|
-
# Weigh our emojis 10x, cuz we're awesome!
|
278
255
|
# TODO: fix the random seed with a hash of the user's app code, for stability?
|
279
|
-
return random.choice(RANDOM_EMOJIS
|
256
|
+
return random.choice(RANDOM_EMOJIS) # noqa: S311
|
280
257
|
|
281
258
|
|
282
259
|
def set_menu_items_proto(
|
@@ -297,6 +274,9 @@ def set_menu_items_proto(
|
|
297
274
|
if ABOUT_KEY in lowercase_menu_items:
|
298
275
|
if lowercase_menu_items[ABOUT_KEY] is not None:
|
299
276
|
menu_items_proto.about_section_md = dedent(lowercase_menu_items[ABOUT_KEY])
|
277
|
+
else:
|
278
|
+
# For multiple calls to set_page_config, clears previously set about markdown
|
279
|
+
menu_items_proto.clear_about_md = True
|
300
280
|
|
301
281
|
|
302
282
|
def validate_menu_items(menu_items: MenuItems) -> None:
|
streamlit/config.py
CHANGED
@@ -728,15 +728,12 @@ def _server_headless() -> bool:
|
|
728
728
|
Default: false unless (1) we are on a Linux box where DISPLAY is unset, or
|
729
729
|
(2) we are running in the Streamlit Atom plugin.
|
730
730
|
"""
|
731
|
-
if
|
731
|
+
# Check if we are running in Linux and DISPLAY is unset
|
732
|
+
return (
|
732
733
|
env_util.IS_LINUX_OR_BSD
|
733
734
|
and not os.getenv("DISPLAY")
|
734
735
|
and not os.getenv("WAYLAND_DISPLAY")
|
735
|
-
)
|
736
|
-
# We're running in Linux and DISPLAY is unset
|
737
|
-
return True
|
738
|
-
|
739
|
-
return False
|
736
|
+
)
|
740
737
|
|
741
738
|
|
742
739
|
_create_option(
|
@@ -1629,10 +1626,11 @@ def _check_conflicts() -> None:
|
|
1629
1626
|
)
|
1630
1627
|
|
1631
1628
|
# XSRF conflicts
|
1632
|
-
if get_option("server.enableXsrfProtection")
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1629
|
+
if get_option("server.enableXsrfProtection") and (
|
1630
|
+
not get_option("server.enableCORS") or get_option("global.developmentMode")
|
1631
|
+
):
|
1632
|
+
LOGGER.warning(
|
1633
|
+
"""
|
1636
1634
|
Warning: the config option 'server.enableCORS=false' is not compatible with
|
1637
1635
|
'server.enableXsrfProtection=true'.
|
1638
1636
|
As a result, 'server.enableCORS' is being overridden to 'true'.
|
@@ -1644,7 +1642,7 @@ cross-origin resource sharing.
|
|
1644
1642
|
|
1645
1643
|
If cross origin resource sharing is required, please disable server.enableXsrfProtection.
|
1646
1644
|
"""
|
1647
|
-
|
1645
|
+
)
|
1648
1646
|
|
1649
1647
|
|
1650
1648
|
def _set_development_mode() -> None:
|
streamlit/config_util.py
CHANGED
@@ -66,7 +66,7 @@ def show_config(
|
|
66
66
|
def append_setting(text):
|
67
67
|
out.append(cli_util.style_for_cli(text, fg="green"))
|
68
68
|
|
69
|
-
for section in section_descriptions
|
69
|
+
for section in section_descriptions:
|
70
70
|
# We inject a fake config section used for unit tests that we exclude here as
|
71
71
|
# its options are often missing required properties, which confuses the code
|
72
72
|
# below.
|
@@ -207,7 +207,7 @@ class SQLConnection(BaseConnection["Engine"]):
|
|
207
207
|
host=conn_params["host"],
|
208
208
|
port=int(conn_params["port"]) if "port" in conn_params else None,
|
209
209
|
database=conn_params.get("database"),
|
210
|
-
query=conn_params
|
210
|
+
query=conn_params.get("query", {}),
|
211
211
|
)
|
212
212
|
|
213
213
|
create_engine_kwargs = ChainMap(
|
streamlit/dataframe_util.py
CHANGED
@@ -1067,7 +1067,7 @@ def is_colum_type_arrow_incompatible(column: Series[Any] | Index) -> bool:
|
|
1067
1067
|
"complex",
|
1068
1068
|
]:
|
1069
1069
|
return True
|
1070
|
-
|
1070
|
+
if inferred_type == "mixed":
|
1071
1071
|
# This includes most of the more complex/custom types (objects, dicts,
|
1072
1072
|
# lists, ...)
|
1073
1073
|
if len(column) == 0 or not hasattr(column, "iloc"):
|
@@ -1079,7 +1079,7 @@ def is_colum_type_arrow_incompatible(column: Series[Any] | Index) -> bool:
|
|
1079
1079
|
# Get the first value to check if it is a supported list-like type.
|
1080
1080
|
first_value = column.iloc[0]
|
1081
1081
|
|
1082
|
-
if (
|
1082
|
+
if ( # noqa: SIM103
|
1083
1083
|
not is_list_like(first_value)
|
1084
1084
|
# dicts are list-like, but have issues in Arrow JS (see comments in
|
1085
1085
|
# Quiver.ts)
|
@@ -1164,53 +1164,53 @@ def determine_data_format(input_data: Any) -> DataFormat:
|
|
1164
1164
|
|
1165
1165
|
if input_data is None:
|
1166
1166
|
return DataFormat.EMPTY
|
1167
|
-
|
1167
|
+
if isinstance(input_data, pd.DataFrame):
|
1168
1168
|
return DataFormat.PANDAS_DATAFRAME
|
1169
|
-
|
1169
|
+
if isinstance(input_data, np.ndarray):
|
1170
1170
|
if len(cast("NumpyShape", input_data.shape)) == 1:
|
1171
1171
|
# For technical reasons, we need to distinguish one
|
1172
1172
|
# one-dimensional numpy array from multidimensional ones.
|
1173
1173
|
return DataFormat.NUMPY_LIST
|
1174
1174
|
return DataFormat.NUMPY_MATRIX
|
1175
|
-
|
1175
|
+
if isinstance(input_data, pa.Table):
|
1176
1176
|
return DataFormat.PYARROW_TABLE
|
1177
|
-
|
1177
|
+
if isinstance(input_data, pa.Array):
|
1178
1178
|
return DataFormat.PYARROW_ARRAY
|
1179
|
-
|
1179
|
+
if isinstance(input_data, pd.Series):
|
1180
1180
|
return DataFormat.PANDAS_SERIES
|
1181
|
-
|
1181
|
+
if isinstance(input_data, pd.Index):
|
1182
1182
|
return DataFormat.PANDAS_INDEX
|
1183
|
-
|
1183
|
+
if is_pandas_styler(input_data):
|
1184
1184
|
return DataFormat.PANDAS_STYLER
|
1185
|
-
|
1185
|
+
if isinstance(input_data, pd.api.extensions.ExtensionArray):
|
1186
1186
|
return DataFormat.PANDAS_ARRAY
|
1187
|
-
|
1187
|
+
if is_polars_series(input_data):
|
1188
1188
|
return DataFormat.POLARS_SERIES
|
1189
|
-
|
1189
|
+
if is_polars_dataframe(input_data):
|
1190
1190
|
return DataFormat.POLARS_DATAFRAME
|
1191
|
-
|
1191
|
+
if is_polars_lazyframe(input_data):
|
1192
1192
|
return DataFormat.POLARS_LAZYFRAME
|
1193
|
-
|
1193
|
+
if is_modin_data_object(input_data):
|
1194
1194
|
return DataFormat.MODIN_OBJECT
|
1195
|
-
|
1195
|
+
if is_snowpandas_data_object(input_data):
|
1196
1196
|
return DataFormat.SNOWPANDAS_OBJECT
|
1197
|
-
|
1197
|
+
if is_pyspark_data_object(input_data):
|
1198
1198
|
return DataFormat.PYSPARK_OBJECT
|
1199
|
-
|
1199
|
+
if is_xarray_dataset(input_data):
|
1200
1200
|
return DataFormat.XARRAY_DATASET
|
1201
|
-
|
1201
|
+
if is_xarray_data_array(input_data):
|
1202
1202
|
return DataFormat.XARRAY_DATA_ARRAY
|
1203
|
-
|
1203
|
+
if is_ray_dataset(input_data):
|
1204
1204
|
return DataFormat.RAY_DATASET
|
1205
|
-
|
1205
|
+
if is_dask_object(input_data):
|
1206
1206
|
return DataFormat.DASK_OBJECT
|
1207
|
-
|
1207
|
+
if is_snowpark_data_object(input_data) or is_snowpark_row_list(input_data):
|
1208
1208
|
return DataFormat.SNOWPARK_OBJECT
|
1209
|
-
|
1209
|
+
if is_duckdb_relation(input_data):
|
1210
1210
|
return DataFormat.DUCKDB_RELATION
|
1211
|
-
|
1211
|
+
if is_dbapi_cursor(input_data):
|
1212
1212
|
return DataFormat.DBAPI_CURSOR
|
1213
|
-
|
1213
|
+
if (
|
1214
1214
|
isinstance(
|
1215
1215
|
input_data,
|
1216
1216
|
(ChainMap, UserDict, MappingProxyType),
|
@@ -1221,9 +1221,9 @@ def determine_data_format(input_data: Any) -> DataFormat:
|
|
1221
1221
|
or is_pydantic_model(input_data)
|
1222
1222
|
):
|
1223
1223
|
return DataFormat.KEY_VALUE_DICT
|
1224
|
-
|
1224
|
+
if isinstance(input_data, (ItemsView, enumerate)):
|
1225
1225
|
return DataFormat.LIST_OF_ROWS
|
1226
|
-
|
1226
|
+
if isinstance(input_data, (list, tuple, set, frozenset)):
|
1227
1227
|
if _is_list_of_scalars(input_data):
|
1228
1228
|
# -> one-dimensional data structure
|
1229
1229
|
if isinstance(input_data, tuple):
|
@@ -1231,15 +1231,14 @@ def determine_data_format(input_data: Any) -> DataFormat:
|
|
1231
1231
|
if isinstance(input_data, (set, frozenset)):
|
1232
1232
|
return DataFormat.SET_OF_VALUES
|
1233
1233
|
return DataFormat.LIST_OF_VALUES
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
return DataFormat.LIST_OF_ROWS
|
1234
|
+
# -> Multi-dimensional data structure
|
1235
|
+
# This should always contain at least one element,
|
1236
|
+
# otherwise the values type from infer_dtype would have been empty
|
1237
|
+
first_element = next(iter(input_data))
|
1238
|
+
if isinstance(first_element, dict):
|
1239
|
+
return DataFormat.LIST_OF_RECORDS
|
1240
|
+
if isinstance(first_element, (list, tuple, set, frozenset)):
|
1241
|
+
return DataFormat.LIST_OF_ROWS
|
1243
1242
|
elif isinstance(input_data, (dict, Mapping)):
|
1244
1243
|
if not input_data:
|
1245
1244
|
return DataFormat.KEY_VALUE_DICT
|
@@ -1340,7 +1339,7 @@ def convert_pandas_df_to_data_format(
|
|
1340
1339
|
DataFormat.SNOWPARK_OBJECT,
|
1341
1340
|
}:
|
1342
1341
|
return df
|
1343
|
-
|
1342
|
+
if data_format == DataFormat.NUMPY_LIST:
|
1344
1343
|
import numpy as np
|
1345
1344
|
|
1346
1345
|
# It's a 1-dimensional array, so we only return
|
@@ -1348,48 +1347,48 @@ def convert_pandas_df_to_data_format(
|
|
1348
1347
|
# Calling to_numpy() on the full DataFrame would result in:
|
1349
1348
|
# [[1], [2]] instead of [1, 2]
|
1350
1349
|
return np.ndarray(0) if df.empty else df.iloc[:, 0].to_numpy()
|
1351
|
-
|
1350
|
+
if data_format == DataFormat.NUMPY_MATRIX:
|
1352
1351
|
import numpy as np
|
1353
1352
|
|
1354
1353
|
return np.ndarray(0) if df.empty else df.to_numpy()
|
1355
|
-
|
1354
|
+
if data_format == DataFormat.PYARROW_TABLE:
|
1356
1355
|
import pyarrow as pa
|
1357
1356
|
|
1358
1357
|
return pa.Table.from_pandas(df)
|
1359
|
-
|
1358
|
+
if data_format == DataFormat.PYARROW_ARRAY:
|
1360
1359
|
import pyarrow as pa
|
1361
1360
|
|
1362
1361
|
return pa.Array.from_pandas(_pandas_df_to_series(df))
|
1363
|
-
|
1362
|
+
if data_format == DataFormat.PANDAS_SERIES:
|
1364
1363
|
return _pandas_df_to_series(df)
|
1365
|
-
|
1364
|
+
if data_format in {DataFormat.POLARS_DATAFRAME, DataFormat.POLARS_LAZYFRAME}:
|
1366
1365
|
import polars as pl # type: ignore[import-not-found]
|
1367
1366
|
|
1368
1367
|
return pl.from_pandas(df)
|
1369
|
-
|
1368
|
+
if data_format == DataFormat.POLARS_SERIES:
|
1370
1369
|
import polars as pl
|
1371
1370
|
|
1372
1371
|
return pl.from_pandas(_pandas_df_to_series(df))
|
1373
|
-
|
1372
|
+
if data_format == DataFormat.XARRAY_DATASET:
|
1374
1373
|
import xarray as xr # type: ignore[import-not-found]
|
1375
1374
|
|
1376
1375
|
return xr.Dataset.from_dataframe(df)
|
1377
|
-
|
1376
|
+
if data_format == DataFormat.XARRAY_DATA_ARRAY:
|
1378
1377
|
import xarray as xr
|
1379
1378
|
|
1380
1379
|
return xr.DataArray.from_series(_pandas_df_to_series(df))
|
1381
|
-
|
1380
|
+
if data_format == DataFormat.LIST_OF_RECORDS:
|
1382
1381
|
return _unify_missing_values(df).to_dict(orient="records")
|
1383
|
-
|
1382
|
+
if data_format == DataFormat.LIST_OF_ROWS:
|
1384
1383
|
# to_numpy converts the dataframe to a list of rows
|
1385
1384
|
return _unify_missing_values(df).to_numpy().tolist()
|
1386
|
-
|
1385
|
+
if data_format == DataFormat.COLUMN_INDEX_MAPPING:
|
1387
1386
|
return _unify_missing_values(df).to_dict(orient="dict")
|
1388
|
-
|
1387
|
+
if data_format == DataFormat.COLUMN_VALUE_MAPPING:
|
1389
1388
|
return _unify_missing_values(df).to_dict(orient="list")
|
1390
|
-
|
1389
|
+
if data_format == DataFormat.COLUMN_SERIES_MAPPING:
|
1391
1390
|
return df.to_dict(orient="series")
|
1392
|
-
|
1391
|
+
if data_format in [
|
1393
1392
|
DataFormat.LIST_OF_VALUES,
|
1394
1393
|
DataFormat.TUPLE_OF_VALUES,
|
1395
1394
|
DataFormat.SET_OF_VALUES,
|
@@ -1409,7 +1408,7 @@ def convert_pandas_df_to_data_format(
|
|
1409
1408
|
if data_format == DataFormat.SET_OF_VALUES:
|
1410
1409
|
return set(return_list)
|
1411
1410
|
return return_list
|
1412
|
-
|
1411
|
+
if data_format == DataFormat.KEY_VALUE_DICT:
|
1413
1412
|
df = _unify_missing_values(df)
|
1414
1413
|
# The key is expected to be the index -> this will return the first column
|
1415
1414
|
# as a dict with index as key.
|
streamlit/elements/arrow.py
CHANGED
@@ -563,7 +563,7 @@ class ArrowMixin:
|
|
563
563
|
if use_container_width is None:
|
564
564
|
# If use_container_width was not explicitly set by the user, we set
|
565
565
|
# it to True if width was not set explicitly, and False otherwise.
|
566
|
-
use_container_width =
|
566
|
+
use_container_width = width is None
|
567
567
|
|
568
568
|
proto.use_container_width = use_container_width
|
569
569
|
|
@@ -456,10 +456,7 @@ class PydeckMixin:
|
|
456
456
|
|
457
457
|
ctx = get_script_run_ctx()
|
458
458
|
|
459
|
-
if pydeck_obj is None
|
460
|
-
spec = json.dumps(EMPTY_MAP)
|
461
|
-
else:
|
462
|
-
spec = pydeck_obj.to_json()
|
459
|
+
spec = json.dumps(EMPTY_MAP) if pydeck_obj is None else pydeck_obj.to_json()
|
463
460
|
|
464
461
|
pydeck_proto.json = spec
|
465
462
|
pydeck_proto.use_container_width = use_container_width
|
streamlit/elements/doc_string.py
CHANGED
@@ -449,10 +449,7 @@ def _get_value(obj, var_name):
|
|
449
449
|
sig = _get_signature(name_obj) or ""
|
450
450
|
|
451
451
|
if name:
|
452
|
-
if module
|
453
|
-
obj_value = f"{module}.{name}{sig}"
|
454
|
-
else:
|
455
|
-
obj_value = f"{name}{sig}"
|
452
|
+
obj_value = f"{module}.{name}{sig}" if module else f"{name}{sig}"
|
456
453
|
|
457
454
|
if obj_value == var_name:
|
458
455
|
# No need to repeat the same info.
|
streamlit/elements/exception.py
CHANGED
@@ -232,10 +232,9 @@ def _format_syntax_error_message(exception: SyntaxError) -> str:
|
|
232
232
|
|
233
233
|
"""
|
234
234
|
if exception.text:
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
caret_indent = ""
|
235
|
+
caret_indent = (
|
236
|
+
" " * max(exception.offset - 1, 0) if exception.offset is not None else ""
|
237
|
+
)
|
239
238
|
|
240
239
|
return (
|
241
240
|
'File "%(filename)s", line %(lineno)s\n'
|
@@ -362,9 +361,8 @@ def _split_list(
|
|
362
361
|
saw_split_point = False
|
363
362
|
|
364
363
|
for item in orig_list:
|
365
|
-
if not saw_split_point:
|
366
|
-
|
367
|
-
saw_split_point = True
|
364
|
+
if not saw_split_point and split_point(item):
|
365
|
+
saw_split_point = True
|
368
366
|
|
369
367
|
if saw_split_point:
|
370
368
|
after.append(item)
|
streamlit/elements/layouts.py
CHANGED
@@ -184,7 +184,7 @@ class LayoutsMixin:
|
|
184
184
|
self,
|
185
185
|
spec: SpecType,
|
186
186
|
*,
|
187
|
-
gap: Literal["small", "medium", "large"] = "small",
|
187
|
+
gap: Literal["small", "medium", "large", "none"] = "small",
|
188
188
|
vertical_alignment: Literal["top", "center", "bottom"] = "top",
|
189
189
|
border: bool = False,
|
190
190
|
) -> list[DeltaGenerator]:
|
@@ -213,7 +213,7 @@ class LayoutsMixin:
|
|
213
213
|
Or ``[1, 2, 3]`` creates three columns where the second one is two times
|
214
214
|
the width of the first one, and the third one is three times that width.
|
215
215
|
|
216
|
-
gap : "small", "medium", or "
|
216
|
+
gap : "small", "medium", "large", or "none"
|
217
217
|
The size of the gap between the columns. The default is ``"small"``.
|
218
218
|
|
219
219
|
vertical_alignment : "top", "center", or "bottom"
|
@@ -359,11 +359,12 @@ class LayoutsMixin:
|
|
359
359
|
"small": GapSize.SMALL,
|
360
360
|
"medium": GapSize.MEDIUM,
|
361
361
|
"large": GapSize.LARGE,
|
362
|
+
"none": GapSize.NONE,
|
362
363
|
}
|
363
364
|
|
364
365
|
if isinstance(gap, str):
|
365
366
|
gap_size = gap.lower()
|
366
|
-
valid_sizes =
|
367
|
+
valid_sizes = gap_mapping.keys()
|
367
368
|
|
368
369
|
if gap_size in valid_sizes:
|
369
370
|
return gap_mapping[gap_size]
|
@@ -861,17 +861,14 @@ def _get_x_encoding(
|
|
861
861
|
# Only show a label in the x axis if the user passed a column explicitly. We
|
862
862
|
# could go either way here, but I'm keeping this to avoid breaking the existing
|
863
863
|
# behavior.
|
864
|
-
if x_from_user is None
|
865
|
-
x_title = ""
|
866
|
-
else:
|
867
|
-
x_title = x_column
|
864
|
+
x_title = "" if x_from_user is None else x_column
|
868
865
|
|
869
866
|
# User specified x-axis label takes precedence
|
870
867
|
if x_axis_label is not None:
|
871
868
|
x_title = x_axis_label
|
872
869
|
|
873
870
|
# grid lines on x axis for horizontal bar charts only
|
874
|
-
grid =
|
871
|
+
grid = chart_type == ChartType.HORIZONTAL_BAR
|
875
872
|
|
876
873
|
return alt.X(
|
877
874
|
x_field,
|
@@ -909,17 +906,14 @@ def _get_y_encoding(
|
|
909
906
|
# Only show a label in the y axis if the user passed a column explicitly. We
|
910
907
|
# could go either way here, but I'm keeping this to avoid breaking the existing
|
911
908
|
# behavior.
|
912
|
-
if y_from_user is None
|
913
|
-
y_title = ""
|
914
|
-
else:
|
915
|
-
y_title = y_column
|
909
|
+
y_title = "" if y_from_user is None else y_column
|
916
910
|
|
917
911
|
# User specified y-axis label takes precedence
|
918
912
|
if y_axis_label is not None:
|
919
913
|
y_title = y_axis_label
|
920
914
|
|
921
915
|
# grid lines on y axis for all charts except horizontal bar charts
|
922
|
-
grid =
|
916
|
+
grid = chart_type != ChartType.HORIZONTAL_BAR
|
923
917
|
|
924
918
|
return alt.Y(
|
925
919
|
field=y_field,
|
@@ -986,10 +980,11 @@ def _get_color_encoding(
|
|
986
980
|
if color_column is not None:
|
987
981
|
column_type: VegaLiteType
|
988
982
|
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
983
|
+
column_type = (
|
984
|
+
"nominal"
|
985
|
+
if color_column == _MELTED_COLOR_COLUMN_NAME
|
986
|
+
else _infer_vegalite_type(df[color_column])
|
987
|
+
)
|
993
988
|
|
994
989
|
color_enc = alt.Color(
|
995
990
|
field=color_column, legend=_COLOR_LEGEND_SETTINGS, type=column_type
|
@@ -203,10 +203,9 @@ def _pandas_style_to_css(
|
|
203
203
|
# > }
|
204
204
|
# > ...
|
205
205
|
# > ]
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
cell_selectors = style["selectors"]
|
206
|
+
cell_selectors = (
|
207
|
+
[style["selector"]] if style_type == "table_styles" else style["selectors"]
|
208
|
+
)
|
210
209
|
|
211
210
|
selectors = [
|
212
211
|
table_selector + separator + cell_selector for cell_selector in cell_selectors
|
@@ -266,9 +265,8 @@ def _use_display_values(df: DataFrame, styles: Mapping[str, Any]) -> DataFrame:
|
|
266
265
|
rows = styles["body"]
|
267
266
|
for row in rows:
|
268
267
|
for cell in row:
|
269
|
-
if "id" in cell:
|
270
|
-
|
271
|
-
|
272
|
-
new_df.iloc[r, c] = str(cell["display_value"])
|
268
|
+
if "id" in cell and (match := cell_selector_regex.match(cell["id"])):
|
269
|
+
r, c = map(int, match.groups())
|
270
|
+
new_df.iloc[r, c] = str(cell["display_value"])
|
273
271
|
|
274
272
|
return new_df
|
streamlit/elements/map.py
CHANGED
@@ -399,10 +399,7 @@ def _get_value_and_col_name(
|
|
399
399
|
else:
|
400
400
|
col_name = None
|
401
401
|
|
402
|
-
if value_or_name is None
|
403
|
-
pydeck_arg = default_value
|
404
|
-
else:
|
405
|
-
pydeck_arg = value_or_name
|
402
|
+
pydeck_arg = default_value if value_or_name is None else value_or_name
|
406
403
|
|
407
404
|
return pydeck_arg, col_name
|
408
405
|
|
@@ -462,10 +459,7 @@ def _get_viewport_details(
|
|
462
459
|
range_lat = abs(max_lat - min_lat)
|
463
460
|
|
464
461
|
if zoom is None:
|
465
|
-
|
466
|
-
longitude_distance = range_lon
|
467
|
-
else:
|
468
|
-
longitude_distance = range_lat
|
462
|
+
longitude_distance = max(range_lat, range_lon)
|
469
463
|
zoom = _get_zoom_level(longitude_distance)
|
470
464
|
|
471
465
|
return zoom, center_lat, center_lon
|
streamlit/elements/markdown.py
CHANGED
@@ -368,10 +368,7 @@ class MarkdownMixin:
|
|
368
368
|
height: 220px
|
369
369
|
|
370
370
|
"""
|
371
|
-
if icon is not None
|
372
|
-
icon_str = validate_icon_or_emoji(icon) + " "
|
373
|
-
else:
|
374
|
-
icon_str = ""
|
371
|
+
icon_str = validate_icon_or_emoji(icon) + " " if icon is not None else ""
|
375
372
|
|
376
373
|
# Escape [ and ] characters in the label to prevent breaking the directive syntax
|
377
374
|
escaped_label = label.replace("[", "\\[").replace("]", "\\]")
|