Skip to content

Commit

Permalink
Upgrade streamlit as a dev dep to 1.12.0 and fix imports (#1005)
Browse files Browse the repository at this point in the history
* Upgrade streamlit as a dev dep to 1.12.0 and fix imports

* Update CHANGELOG.md

* Fix to use packaging.version for version comparison

* Fix import

* Fix import

* Add a test matrix item

* Fix initialization of SessionInfo in a test
  • Loading branch information
whitphx authored Aug 15, 2022
1 parent 296aeb5 commit 29c2435
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 42 deletions.
7 changes: 5 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@ jobs:
streamlit-version: 1.0.0
- python-version: 3.9
streamlit-version: 1.4.0
# Test with streamlit <1.6.0 and >=1.6.0. See https://github.com/whitphx/streamlit-webrtc/issues/709
# Test with streamlit >=1.6.0. See https://github.com/whitphx/streamlit-webrtc/issues/709
- python-version: 3.9
streamlit-version: 1.6.0
# Test with streamlit <1.8.0 and >=1.8.0. See https://github.com/whitphx/streamlit-webrtc/issues/759
# Test with streamlit >=1.8.0. See https://github.com/whitphx/streamlit-webrtc/issues/759
- python-version: 3.9
streamlit-version: 1.8.0
# Test with streamlit >=1.12.0. See https://github.com/whitphx/streamlit-webrtc/issues/1004
- python-version: 3.9
streamlit-version: 1.12.0

steps:
- uses: actions/checkout@v3
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

### Fix
- Escape-hatch to access the running Streamlit server object for the new web server design with streamlit>=1.12.0, #1005.

## [0.42.0] - 2022-07-02

### Fix
Expand Down
28 changes: 12 additions & 16 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ python = ">=3.7,<3.11"
streamlit = ">=0.84.1"
aiortc = "^1.1.2"
typing_extensions = { version = ">=3.7.4,<5.0.0", python = "<3.8" }
packaging = ">=20.0"

[tool.poetry.dev-dependencies]
black = "^21.12b0"
Expand Down
9 changes: 7 additions & 2 deletions streamlit_webrtc/eventloop.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@
import contextlib
from typing import Union

from streamlit.server.server import Server
from tornado.platform.asyncio import BaseAsyncIOLoop

from .server import _is_modern_architecture, get_current_server


def get_server_event_loop() -> asyncio.AbstractEventLoop:
current_server = Server.get_current()
current_server = get_current_server()

if _is_modern_architecture():
return current_server._eventloop

ioloop = current_server._ioloop

# `ioloop` is expected to be of type `BaseAsyncIOLoop`,
Expand Down
4 changes: 2 additions & 2 deletions streamlit_webrtc/relay.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from aiortc.contrib.media import MediaRelay
from streamlit.server.server import Server

from .eventloop import get_server_event_loop, loop_context
from .server import get_current_server

_SERVER_GLOBAL_RELAY_ATTR_NAME_ = "streamlit-webrtc-global-relay"


def get_global_relay() -> MediaRelay:
server = Server.get_current()
server = get_current_server()

if hasattr(server, _SERVER_GLOBAL_RELAY_ATTR_NAME_):
return getattr(server, _SERVER_GLOBAL_RELAY_ATTR_NAME_)
Expand Down
67 changes: 67 additions & 0 deletions streamlit_webrtc/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import logging

import streamlit as st
from packaging import version

logger = logging.getLogger(__name__)

_server = None

VERSION_1_12_0 = version.parse("1.12.0")


def _is_modern_architecture() -> bool:
"""Returns if the imported streamlit package version is >=1.12.0.
It is because since that version, streamlit has changed its internal architecture
making `web` and `runtime` submodules to which some files have been moved
decoupling the web server-related files and the core runtime,
e.g. https://github.com/streamlit/streamlit/pull/4956.
During this a huge refactoring, `Server._singleton` and
its accessor `Server.get_current()` have been removed
(https://github.com/streamlit/streamlit/pull/4966)
that we have been using as a server-wide global object,
so we have to change the way to access it.
"""
return version.parse(st.__version__) >= VERSION_1_12_0


def get_current_server():
global _server
if _server:
return _server

if _is_modern_architecture():
logger.debug(
"The running Streamlit version is gte 1.12.0. "
"Try to get the server instance"
)

import gc

from streamlit.web.server.server import Server

servers = [obj for obj in gc.get_objects() if isinstance(obj, Server)]

if len(servers) == 0:
raise RuntimeError("Unexpectedly no server exists")
if len(servers) > 1:
logger.warning(
"Unexpectedly multiple server instances exist. Use the first one."
)

_server = servers[0]
else:
logger.debug(
"The running Streamlit version is less than 1.12.0. "
"Call Server.get_current()"
)
try:
from streamlit.web.server.server import Server
except ModuleNotFoundError:
# streamlit < 1.12.0
from streamlit.server.server import Server

_server = Server.get_current()

return _server
28 changes: 18 additions & 10 deletions streamlit_webrtc/session_info.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
from typing import Optional

from streamlit.server.server import SessionInfo
try:
from streamlit.web.server.server import SessionInfo
except ModuleNotFoundError:
# streamlit < 1.12.0
from streamlit.server.server import SessionInfo # type: ignore

try:
from streamlit.scriptrunner import get_script_run_ctx
from streamlit.runtime.scriptrunner import get_script_run_ctx
except ModuleNotFoundError:
# streamlit < 1.8
# streamlit < 1.12.0
try:
from streamlit.script_run_context import get_script_run_ctx # type: ignore
from streamlit.scriptrunner import get_script_run_ctx # type: ignore
except ModuleNotFoundError:
# streamlit < 1.4
from streamlit.report_thread import ( # type: ignore
get_report_ctx as get_script_run_ctx,
)
# streamlit < 1.8
try:
from streamlit.script_run_context import get_script_run_ctx # type: ignore
except ModuleNotFoundError:
# streamlit < 1.4
from streamlit.report_thread import ( # type: ignore
get_report_ctx as get_script_run_ctx,
)

from streamlit.server.server import Server
from .server import get_current_server

# Ref: https://gist.github.com/tvst/036da038ab3e999a64497f42de966a92

Expand All @@ -28,7 +36,7 @@ def get_session_id() -> str:


def get_this_session_info() -> Optional[SessionInfo]:
current_server = Server.get_current()
current_server = get_current_server()

# 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
Expand Down
16 changes: 10 additions & 6 deletions streamlit_webrtc/shutdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
from typing import Callable, Union

try:
from streamlit.app_session import AppSession, AppSessionState
from streamlit.runtime.app_session import AppSession, AppSessionState
except ModuleNotFoundError:
# streamlit < 1.4
from streamlit.report_session import ( # type: ignore
ReportSession as AppSession,
ReportSessionState as AppSessionState,
)
# streamlit < 1.12.0
try:
from streamlit.app_session import AppSession, AppSessionState # type: ignore
except ModuleNotFoundError:
# streamlit < 1.4
from streamlit.report_session import ( # type: ignore
ReportSession as AppSession,
ReportSessionState as AppSessionState,
)

from .session_info import get_this_session_info

Expand Down
10 changes: 6 additions & 4 deletions tests/session_info_test.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from unittest.mock import Mock

from streamlit.server.server import SessionInfo

from streamlit_webrtc.session_info import get_script_run_count
from streamlit_webrtc.server import _is_modern_architecture
from streamlit_webrtc.session_info import SessionInfo, get_script_run_count


def test_get_script_run_count():
session_info = SessionInfo(ws=Mock(), session=Mock())
if _is_modern_architecture():
session_info = SessionInfo(client=Mock(), session=Mock())
else:
session_info = SessionInfo(ws=Mock(), session=Mock())
assert get_script_run_count(session_info) == 0

0 comments on commit 29c2435

Please sign in to comment.