def run( main_script_path: str, command_line: Optional[str], args: List[str], flag_options: Dict[str, Any], ) -> None: """Run a script in a separate thread and start a server for the app. This starts a blocking ioloop. """ _fix_sys_path(main_script_path) _fix_matplotlib_crash() _fix_tornado_crash() _fix_sys_argv(main_script_path, args) _fix_pydeck_mapbox_api_warning() _install_config_watchers(flag_options) # Install a signal handler that will shut down the ioloop # and close all our threads _set_up_signal_handler() ioloop = tornado.ioloop.IOLoop.current() # Create and start the server. server = Server(ioloop, main_script_path, command_line) server.start(_on_server_start) # Start the ioloop. This function will not return until the # server is shut down. ioloop.start()
class ScriptCheckTest(tornado.testing.AsyncTestCase): def setUp(self) -> None: super().setUp() self._home = tempfile.mkdtemp() self._old_home = os.environ["HOME"] os.environ["HOME"] = self._home self._fd, self._path = tempfile.mkstemp() self._server = Server(self.io_loop, self._path, "test command line") def tearDown(self) -> None: self._server.stop() Server._singleton = None if event_based_file_watcher._MultiFileWatcher._singleton is not None: event_based_file_watcher._MultiFileWatcher.get_singleton().close() event_based_file_watcher._MultiFileWatcher._singleton = None os.environ["HOME"] = self._old_home os.remove(self._path) shutil.rmtree(self._home) super().tearDown() @pytest.mark.slow @tornado.testing.gen_test(timeout=30) async def test_invalid_script(self): await self._check_script_loading( "import streamlit as st\n\nst.deprecatedWrite('test')", False, "error", ) @pytest.mark.slow @tornado.testing.gen_test(timeout=30) async def test_valid_script(self): await self._check_script_loading( "import streamlit as st\n\nst.write('test')", True, "ok") @pytest.mark.slow @tornado.testing.gen_test(timeout=30) async def test_timeout_script(self): try: streamlit.server.server.SCRIPT_RUN_CHECK_TIMEOUT = 0.1 await self._check_script_loading("import time\n\ntime.sleep(5)", False, "timeout") finally: streamlit.server.server.SCRIPT_RUN_CHECK_TIMEOUT = 60 async def _check_script_loading(self, script, expected_loads, expected_msg): with os.fdopen(self._fd, "w") as tmp: tmp.write(script) ok, msg = await self._server.does_script_run_without_error() event_based_file_watcher._MultiFileWatcher.get_singleton().close() event_based_file_watcher._MultiFileWatcher._singleton = None self.assertEqual(expected_loads, ok) self.assertEqual(expected_msg, msg)
def get(**kwargs): # Hack to get the session object from Streamlit. ctx = get_report_ctx() this_session = None current_server = Server.get_current() if hasattr(current_server, '_session_infos'): # Streamlit < 0.56 session_infos = Server.get_current()._session_infos.values() else: session_infos = Server.get_current()._session_info_by_id.values() for session_info in session_infos: s = session_info.session if not hasattr( s, '_main_dg') and s._uploaded_file_mgr == ctx.uploaded_file_mgr: this_session = s if this_session is None: raise RuntimeError( "Oh noes. Couldn't get your Streamlit Session object" 'Are you doing something fancy with threads?') # Got the session object! Now let's attach some state into it. if not hasattr(this_session, '_custom_session_state'): this_session._custom_session_state = SessionState(**kwargs) return this_session._custom_session_state
def get(**kwargs): """Gets a SessionState object for the current session. Creates a new object if necessary. Parameters ---------- **kwargs : any Default values you want to add to the session state, if we're creating a new one. Example ------- >>> session_state = get(user_name='', favorite_color='black') >>> session_state.user_name '' >>> session_state.user_name = 'Mary' >>> session_state.favorite_color 'black' Since you set user_name above, next time your script runs this will be the result: >>> session_state = get(user_name='', favorite_color='black') >>> session_state.user_name 'Mary' """ # Hack to get the session object from Streamlit. ctx = ReportThread.get_report_ctx() this_session = None current_server = Server.get_current() if hasattr(current_server, '_session_infos'): # Streamlit < 0.56 session_infos = Server.get_current()._session_infos.values() else: session_infos = Server.get_current()._session_info_by_id.values() for session_info in session_infos: s = session_info.session if ( # Streamlit < 0.54.0 (hasattr(s, '_main_dg') and s._main_dg == ctx.main_dg) or # Streamlit >= 0.54.0 (not hasattr(s, '_main_dg') and s.enqueue == ctx.enqueue) or # Streamlit >= 0.65.2 (not hasattr(s, '_main_dg') and s._uploaded_file_mgr == ctx.uploaded_file_mgr) ): this_session = s if this_session is None: raise RuntimeError( "Oh noes. Couldn't get your Streamlit Session object. " 'Are you doing something fancy with threads?') # Got the session object! Now let's attach some state into it. if not hasattr(this_session, '_custom_session_state'): this_session._custom_session_state = SessionState(**kwargs) return this_session._custom_session_state
def _get_session_raw(): # Hack to get the session object from Streamlit. ctx = ReportThread.get_report_ctx() this_session = None current_server = Server.get_current() if hasattr(current_server, "_session_infos"): # Streamlit < 0.56 session_infos = Server.get_current()._session_infos.values() else: session_infos = Server.get_current()._session_info_by_id.values() for session_info in session_infos: s = session_info if ( # Streamlit < 0.54.0 (hasattr(s, "_main_dg") and s.session._main_dg == ctx.main_dg) or # Streamlit >= 0.54.0 (not hasattr(s, "_main_dg") and s.session.enqueue == ctx.enqueue) or # Streamlit >= 0.65.2 (not hasattr(s, "_main_dg") and s.session.id == ctx.session_id)): this_session = s if this_session is None: raise RuntimeError( "Oh noes. Couldn't get your Streamlit Session object" "Are you doing something fancy with threads?") return this_session
def trigger_rerun(): ctx = ReportThread.get_report_ctx() this_session = None current_server = Server.get_current() if hasattr(current_server, '_session_infos'): # Streamlit < 0.56 session_infos = Server.get_current()._session_infos.values() else: session_infos = Server.get_current()._session_info_by_id.values() for session_info in session_infos: s = session_info.session if ( # Streamlit < 0.54.0 (hasattr(s, '_main_dg') and s._main_dg == ctx.main_dg) or # Streamlit >= 0.54.0 (not hasattr(s, '_main_dg') and s._uploaded_file_mgr == ctx.uploaded_file_mgr)): this_session = s if this_session is None: raise RuntimeError( "Oh noes. Couldn't get your Streamlit Session object" 'Are you doing something fancy with threads?') this_session.request_rerun()
def get(**kwargs): ctx = ReportThread.get_report_ctx() this_session = None current_server = Server.get_current() if hasattr(current_server, '_session_infos'): # Streamlit < 0.56 session_infos = Server.get_current()._session_infos.values() else: session_infos = Server.get_current()._session_info_by_id.values() for session_info in session_infos: s = session_info.session if ( # Streamlit < 0.54.0 (hasattr(s, '_main_dg') and s._main_dg == ctx.main_dg) or # Streamlit >= 0.54.0 (not hasattr(s, '_main_dg') and s.enqueue == ctx.enqueue) or # Streamlit >= 0.65.2 (not hasattr(s, '_main_dg') and s._uploaded_file_mgr == ctx.uploaded_file_mgr)): this_session = s if this_session is None: raise RuntimeError("Could not get session object.") if not hasattr(this_session, '_custom_session_state'): this_session._custom_session_state = SessionState(**kwargs) return this_session._custom_session_state
def get_app(self): # Create a Server, and patch its _on_stopped function # to no-op. This prevents it from shutting down the # ioloop when it stops. self.server = Server(self.io_loop, "/not/a/script.py", "test command line") self.server._on_stopped = mock.MagicMock() # type: ignore[assignment] app = self.server._create_app() return app
def setUp(self) -> None: super().setUp() self._home = tempfile.mkdtemp() self._old_home = os.environ["HOME"] os.environ["HOME"] = self._home self._fd, self._path = tempfile.mkstemp() self._server = Server(self.io_loop, self._path, "test command line")
def get(**kwargs): """ Get a SessionState object for the current session. Create a new object if necessary. Parameters: **kwargs : Default values you want to add to the session state Returns: this_session._custom_session_state: Current SessionState Example ------- >>> session_state = get(user_name='', favorite_color='black') >>> session_state.user_name '' >>> session_state.user_name = 'Mary' >>> session_state.favorite_color 'black' Since you set user_name above, next time your script runs this will be the result: >>> session_state = get(user_name='', favorite_color='black') >>> session_state.user_name 'Mary' """ # Hack to get the session object from Streamlit. ctx = report_thread.get_report_ctx() this_session = None current_server = Server.get_current() if hasattr(current_server, '_session_infos'): # noqa: WPS421 session_infos = current_server._session_infos.values() else: current_server = Server.get_current() session_info_id = current_server._session_info_by_id session_infos = session_info_id.values() for session_info in session_infos: s = session_info.session check = (s._uploaded_file_mgr == ctx.uploaded_file_mgr) if (not hasattr(s, '_main_dg') and check): # noqa: WPS421 this_session = s if not hasattr(this_session, '_custom_session_state'): # noqa: WPS421 new_state = SessionState(**kwargs) this_session._custom_session_state = new_state return this_session._custom_session_state
def get_host(): # Hack to get the session object from Streamlit. current_server = Server.get_current() if hasattr(current_server, '_session_infos'): # Streamlit < 0.56 session_infos = Server.get_current()._session_infos.values() else: session_infos = Server.get_current()._session_info_by_id.values() # Multiple Session Objects? for session_info in session_infos: headers = session_info.ws.request.headers return headers['Host']
def get(**kwargs): """Gets a SessionState object for the current session. Creates a new object if necessary. Parameters ---------- **kwargs : any Default values you want to add to the session state, if we're creating a new one. Example ------- >>> session_state = get(user_name='', favorite_color='black') >>> session_state.user_name '' >>> session_state.user_name = 'Mary' >>> session_state.favorite_color 'black' Since you set user_name above, next time your script runs this will be the result: >>> session_state = get(user_name='', favorite_color='black') >>> session_state.user_name 'Mary' """ session_id = ReportThread.get_report_ctx().session_id id = Server.get_current()._get_session_info(session_id) return get_session(session_id, **kwargs)
def _get_session_object(): # Hack to get the session object from Streamlit. ctx = ReportThread.get_report_ctx() this_session = None session_infos = Server.get_current()._session_infos.values() for session_info in session_infos: s = session_info.session if ( # Streamlit < 0.54.0 (hasattr(s, '_main_dg') and s._main_dg == ctx.main_dg) or # Streamlit >= 0.54.0 (not hasattr(s, '_main_dg') and s.enqueue == ctx.enqueue) or # Streamlit >= 0.65.2 (not hasattr(s, '_main_dg') and s._uploaded_file_mgr == ctx.uploaded_file_mgr)): this_session = s if this_session is None: raise RuntimeError( "Oh noes. Couldn't get your Streamlit Session object" 'Are you doing something fancy with threads?') return this_session
def page_first(): st.title("This is my first page") # ... session_state = get(remote_ip='', favorite_color='black') sessions = Server.get_current()._session_info_by_id session_id_key = list(sessions.keys())[0] session = sessions[session_id_key] # Default IP ip = '123.59.195.125' access_token = '32954095c41f7b' handler = ipinfo.getHandler(access_token) ip_address = ip details = handler.getDetails(ip_address) st.write(details.all) street = st.sidebar.text_input("Street", '1') city = st.sidebar.text_input("City", details.city) province = st.sidebar.text_input("Province", details.region) country = st.sidebar.text_input("Country", details.country_name) lat = float(details.latitude) lon = float(details.longitude) st.write('lat: ' + str(lat)) st.write('lon: ' + str(lon)) map_data = pd.DataFrame({'lat': [lat], 'lon': [lon]}) # st.map(map_data) st.map(map_data, zoom=12)
def _get_session(): session_id = get_report_ctx().session_id session_info = Server.get_current()._get_session_info(session_id) if session_info is None: raise RuntimeError("Couldn't get your Streamlit Session object.") return session_info.session
def trigger_rerun(): """ mechanism in place to force resets and update widget states """ session_infos = Server.get_current()._session_info_by_id.values() for session_info in session_infos: this_session = session_info.session this_session.request_rerun()
def get_session_id(): import streamlit.report_thread as ReportThread from streamlit.server.server import Server session_id = get_report_ctx().session_id session_info = Server.get_current()._get_session_info(session_id) if session_info is None: raise RuntimeError("Couldn't get your Streamlit Session object.") return session_info.session.id
def sync(): session_id = ReportThread.get_report_ctx().session_id session_info = Server.get_current()._get_session_info(session_id) if session_info is None: raise RuntimeError('Could not get Streamlit session object.') this_session = session_info.session this_session.request_rerun()
def get_this_session_info() -> Optional[SessionInfo]: current_server = Server.get_current() # The original implementation of SessionState (https://gist.github.com/tvst/036da038ab3e999a64497f42de966a92) has a problem # noqa: E501 # as referred to in https://gist.github.com/tvst/036da038ab3e999a64497f42de966a92#gistcomment-3484515, # noqa: E501 # then fixed here. # This code only works with streamlit>=0.65, https://gist.github.com/tvst/036da038ab3e999a64497f42de966a92#gistcomment-3418729 # noqa: E501 session_id = get_session_id() session_info = current_server._get_session_info(session_id) return session_info
def _get_report_session() -> ReportSession: try: session_id: str = get_report_ctx().session_id except AttributeError: raise RuntimeError("Couldn't start Streamlit application.") session_info = Server.get_current()._get_session_info(session_id) if session_info is None: raise RuntimeError("Couldn't get your Streamlit Session object.") return session_info.session
def get_server_event_loop() -> asyncio.AbstractEventLoop: current_server = Server.get_current() ioloop = current_server._ioloop # `ioloop` is expected to be of type `BaseAsyncIOLoop`, # which has the `asyncio_loop` attribute. if not isinstance(ioloop, BaseAsyncIOLoop): raise Exception( "Unexpectedly failed to access the asyncio event loop.") return ioloop.asyncio_loop
def get_global_relay() -> MediaRelay: server = Server.get_current() if hasattr(server, _SERVER_GLOBAL_RELAY_ATTR_NAME_): return getattr(server, _SERVER_GLOBAL_RELAY_ATTR_NAME_) else: loop = get_server_event_loop() with loop_context(loop): relay = MediaRelay() setattr(server, _SERVER_GLOBAL_RELAY_ATTR_NAME_, relay) return relay
def run(script_path, command_line, args): """Run a script in a separate thread and start a server for the app. This starts a blocking ioloop. Parameters ---------- script_path : str command_line : str args : [str] """ _fix_sys_path(script_path) _fix_matplotlib_crash() _fix_tornado_crash() _fix_sys_argv(script_path, args) _fix_pydeck_mapbox_api_warning() # Install a signal handler that will shut down the ioloop # and close all our threads _set_up_signal_handler() ioloop = tornado.ioloop.IOLoop.current() # Create and start the server. server = Server(ioloop, script_path, command_line) server.start(_on_server_start) # (Must come after start(), because this starts a new thread and start() # may call sys.exit() which doesn't kill other threads. server.add_preheated_report_session() # Start the ioloop. This function will not return until the # server is shut down. ioloop.start()
def get_session(): """ Enable the persistance of variable values across different streamlit pages. This code is from: https://gist.github.com/Ghasel/0aba4869ba6fdc8d49132e6974e2e662 """ session_id = get_report_ctx().session_id session_info = Server.get_current()._get_session_info(session_id) if session_info is None: raise RuntimeError("Couldn't get your Streamlit Session object.") return session_info.session
def get_base_url(): '''Return the base URL of the page. Usually connections are http://localhost:8501. But the port can change or it can be a remote connection. And so, its useful to get the base URL for use with links on various pages. ''' session_id = get_report_ctx().session_id session_info = Server.get_current()._get_session_info(session_id) if session_info: return f'http://{session_info.ws.request.host}/' return 'http://localhost:8501/'
def get_session_headers(timeout=5): # script execution may start before a websocket connection is established, this operation will block execution until # a connection is made, and the corresponding information is populated under session_info ctx = get_report_ctx() session_info = Server.get_current()._session_info_by_id[ctx.session_id] increment = .05 max_retries = timeout / increment i = 0 while session_info.ws is None and i < max_retries: i += 1 time.sleep(increment) if session_info.ws is None: return None return session_info.ws.request.headers['Accept-Language']
def get_user_id(): ctx = ReportThread.get_report_ctx() session_infos = Server.get_current()._session_info_by_id.values() # print(dir(session_infos[0])) for session_info in session_infos: # print("Session info session dir:") # print(dir(session_info.session)) if session_info.session.id == ctx.session_id: user_id = session_info.session.id # print("Current: " + str(session_info.session.id)) else: # print(session_info.session.id) pass return user_id
async def update_fn(): server = Server.get_current() sessions = list(server._session_info_by_id.values()) url = "localhost:8080" if "LIGHTNING_APP_STATE_URL" in os.environ else f"localhost:{APP_SERVER_PORT}" ws_url = f"ws://{url}/api/v1/ws" last_updated = time.time() async with websockets.connect(ws_url) as websocket: while True: _ = await websocket.recv() while (time.time() - last_updated) < 1: time.sleep(0.1) for session in sessions: session = session.session session.request_rerun(session._client_state) last_updated = time.time()
def _get_widget_states(): ctx = ReportThread.get_report_ctx() session = None session_infos = Server.get_current()._session_info_by_id.values() for session_info in session_infos: if session_info.session.enqueue == ctx.enqueue: session = session_info.session if session is None: raise RuntimeError( "Oh noes. Couldn't get your Streamlit Session object" "Are you doing something fancy with threads?") return session._widget_states
def get_main_session_by_id(session_id): """This returns the session state based on the ID provided This is relying on Streamlit internals and is not a public API. Args: session_id ([type]): The session id string Returns: [type]: session state associated with session or None """ # pylint: disable=protected-access session = Server.get_current()._session_info_by_id.get(session_id, None) if session: return session.session.session_state return None