Skip to content

Commit 5e55e69

Browse files
Initial workings of Bokeh Chart
1 parent 2466625 commit 5e55e69

24 files changed

+21775
-144
lines changed

.gitignore

Lines changed: 56 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,162 +1,74 @@
1+
########################################################################
2+
# Python - https://github.com/github/gitignore/blob/master/Python.gitignore
3+
########################################################################
14
# Byte-compiled / optimized / DLL files
25
__pycache__/
36
*.py[cod]
47
*$py.class
58

6-
# C extensions
7-
*.so
8-
99
# Distribution / packaging
10-
.Python
1110
build/
12-
develop-eggs/
1311
dist/
14-
downloads/
1512
eggs/
1613
.eggs/
17-
lib/
18-
lib64/
19-
parts/
20-
sdist/
21-
var/
22-
wheels/
23-
share/python-wheels/
2414
*.egg-info/
25-
.installed.cfg
2615
*.egg
27-
MANIFEST
28-
29-
# PyInstaller
30-
# Usually these files are written by a python script from a template
31-
# before PyInstaller builds the exe, so as to inject date/other infos into it.
32-
*.manifest
33-
*.spec
3416

35-
# Installer logs
36-
pip-log.txt
37-
pip-delete-this-directory.txt
17+
# Python venv
18+
venv
3819

3920
# Unit test / coverage reports
40-
htmlcov/
41-
.tox/
42-
.nox/
4321
.coverage
44-
.coverage.*
45-
.cache
46-
nosetests.xml
47-
coverage.xml
48-
*.cover
49-
*.py,cover
50-
.hypothesis/
22+
.coverage\.*
5123
.pytest_cache/
52-
cover/
53-
54-
# Translations
55-
*.mo
56-
*.pot
57-
58-
# Django stuff:
59-
*.log
60-
local_settings.py
61-
db.sqlite3
62-
db.sqlite3-journal
63-
64-
# Flask stuff:
65-
instance/
66-
.webassets-cache
67-
68-
# Scrapy stuff:
69-
.scrapy
70-
71-
# Sphinx documentation
72-
docs/_build/
73-
74-
# PyBuilder
75-
.pybuilder/
76-
target/
77-
78-
# Jupyter Notebook
79-
.ipynb_checkpoints
80-
81-
# IPython
82-
profile_default/
83-
ipython_config.py
84-
85-
# pyenv
86-
# For a library or package, you might want to ignore these files since the code is
87-
# intended to run in multiple environments; otherwise, check them in:
88-
# .python-version
89-
90-
# pipenv
91-
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92-
# However, in case of collaboration, if having platform-specific dependencies or dependencies
93-
# having no cross-platform support, pipenv may install dependencies that don't work, or not
94-
# install all needed dependencies.
95-
#Pipfile.lock
96-
97-
# poetry
98-
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99-
# This is especially recommended for binary packages to ensure reproducibility, and is more
100-
# commonly ignored for libraries.
101-
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102-
#poetry.lock
103-
104-
# pdm
105-
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106-
#pdm.lock
107-
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108-
# in version control.
109-
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
110-
.pdm.toml
111-
.pdm-python
112-
.pdm-build/
113-
114-
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115-
__pypackages__/
116-
117-
# Celery stuff
118-
celerybeat-schedule
119-
celerybeat.pid
120-
121-
# SageMath parsed files
122-
*.sage.py
123-
124-
# Environments
125-
.env
126-
.venv
127-
env/
128-
venv/
129-
ENV/
130-
env.bak/
131-
venv.bak/
132-
133-
# Spyder project settings
134-
.spyderproject
135-
.spyproject
136-
137-
# Rope project settings
138-
.ropeproject
139-
140-
# mkdocs documentation
141-
/site
142-
143-
# mypy
14424
.mypy_cache/
145-
.dmypy.json
146-
dmypy.json
147-
148-
# Pyre type checker
149-
.pyre/
150-
151-
# pytype static type analyzer
152-
.pytype/
153-
154-
# Cython debug symbols
155-
cython_debug/
156-
157-
# PyCharm
158-
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
159-
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
160-
# and can be added to the global gitignore or merged into this file. For a more nuclear
161-
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
162-
#.idea/
25+
test-reports
26+
27+
# Test fixtures
28+
cffi_bin
29+
30+
# Pyenv Stuff
31+
.python-version
32+
33+
########################################################################
34+
# OSX - https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
35+
########################################################################
36+
.DS_Store
37+
.DocumentRevisions-V100
38+
.fseventsd
39+
.Spotlight-V100
40+
.TemporaryItems
41+
.Trashes
42+
.VolumeIcon.icns
43+
.com.apple.timemachine.donotpresent
44+
45+
########################################################################
46+
# node - https://github.com/github/gitignore/blob/master/Node.gitignore
47+
########################################################################
48+
# Logs
49+
npm-debug.log*
50+
yarn-debug.log*
51+
yarn-error.log*
52+
53+
# Dependency directories
54+
node_modules/
55+
56+
# Coverage directory used by tools like istanbul
57+
coverage/
58+
59+
# Lockfiles
60+
template/**/yarn.lock
61+
template/**/package-lock.json
62+
template-reactless/**/yarn.lock
63+
template-reactless/**/package-lock.json
64+
65+
########################################################################
66+
# JetBrains
67+
########################################################################
68+
.idea
69+
70+
########################################################################
71+
# VSCode
72+
########################################################################
73+
.vscode/
74+
buildcontext/

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
recursive-include streamlit_bokeh/frontend/build *

setup.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from pathlib import Path
2+
3+
import setuptools
4+
5+
this_directory = Path(__file__).parent
6+
long_description = (this_directory / "README.md").read_text()
7+
8+
setuptools.setup(
9+
name="streamlit-bokeh-chart",
10+
version="3.6.1",
11+
author="Streamlit",
12+
author_email="streamlitcommunity@snowflake.com",
13+
description="Streamlit component that allows you to render Bokeh charts",
14+
long_description=long_description,
15+
long_description_content_type="text/markdown",
16+
url="",
17+
packages=setuptools.find_packages(),
18+
include_package_data=True,
19+
classifiers=[],
20+
python_requires=">=3.10",
21+
install_requires=[
22+
# By definition, a Custom Component depends on Streamlit.
23+
# If your component has other Python dependencies, list
24+
# them here.
25+
"streamlit >= 0.63",
26+
"bokeh == 3.6.1",
27+
],
28+
extras_require={
29+
"devel": [
30+
"wheel",
31+
"pytest==7.4.0",
32+
"playwright==1.48.0",
33+
"requests==2.31.0",
34+
"pytest-playwright-snapshot==1.0",
35+
"pytest-rerunfailures==12.0",
36+
]
37+
}
38+
)

streamlit_bokeh/__init__.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import os
2+
import streamlit.components.v1 as components
3+
4+
# Create a _RELEASE constant. We'll set this to False while we're developing
5+
# the component, and True when we're ready to package and distribute it.
6+
# (This is, of course, optional - there are innumerable ways to manage your
7+
# release process.)
8+
_DEV = os.environ.get("DEV", False)
9+
_RELEASE = not _DEV
10+
11+
# Declare a Streamlit component. `declare_component` returns a function
12+
# that is used to create instances of the component. We're naming this
13+
# function "_component_func", with an underscore prefix, because we don't want
14+
# to expose it directly to users. Instead, we will create a custom wrapper
15+
# function, below, that will serve as our component's public API.
16+
17+
# It's worth noting that this call to `declare_component` is the
18+
# *only thing* you need to do to create the binding between Streamlit and
19+
# your component frontend. Everything else we do in this file is simply a
20+
# best practice.
21+
22+
if not _RELEASE:
23+
_component_func = components.declare_component(
24+
# We give the component a simple, descriptive name ("streamlit_bokeh"
25+
# does not fit this bill, so please choose something better for your
26+
# own component :)
27+
"streamlit_bokeh",
28+
# Pass `url` here to tell Streamlit that the component will be served
29+
# by the local dev server that you run via `npm run start`.
30+
# (This is useful while your component is in development.)
31+
url="http://localhost:3001",
32+
)
33+
else:
34+
# When we're distributing a production version of the component, we'll
35+
# replace the `url` param with `path`, and point it to the component's
36+
# build directory:
37+
parent_dir = os.path.dirname(os.path.abspath(__file__))
38+
build_dir = os.path.join(parent_dir, "frontend/build")
39+
_component_func = components.declare_component("streamlit_bokeh", path=build_dir)
40+
41+
42+
import importlib.metadata
43+
from typing import TYPE_CHECKING
44+
import bokeh
45+
from bokeh.embed import json_item
46+
import json
47+
48+
if TYPE_CHECKING:
49+
from bokeh.plotting.figure import Figure
50+
51+
ST_BOKEH_VERSION = importlib.metadata.version("streamlit_bokeh")
52+
53+
def streamlit_bokeh(figure: "Figure", use_container_width=True, theme: str = "streamlit", key=None):
54+
"""Create a new instance of "streamlit_bokeh".
55+
56+
Parameters
57+
----------
58+
figure: bokeh.plotting.figure.Figure
59+
A Bokeh figure to plot.
60+
use_container_width : bool
61+
Whether to override the figure's native width with the width of
62+
the parent container. If ``use_container_width`` is ``False``,
63+
Streamlit sets the width of the chart to fit its contents
64+
according to the plotting library, up to the width of the parent
65+
container. If ``use_container_width`` is ``True`` (default), Streamlit
66+
sets the width of the figure to match the width of the parent container.
67+
key: str or None
68+
An optional key that uniquely identifies this component. If this is
69+
None, and the component's arguments are changed, the component will
70+
be re-mounted in the Streamlit frontend and lose its current state.
71+
72+
Example
73+
-------
74+
>>> from streamlit_bokeh import streamlit_bokeh
75+
>>> from bokeh.plotting import figure
76+
>>>
77+
>>> x = [1, 2, 3, 4, 5]
78+
>>> y = [6, 7, 2, 4, 5]
79+
>>>
80+
>>> p = figure(title="simple line example", x_axis_label="x", y_axis_label="y")
81+
>>> p.line(x, y, legend_label="Trend", line_width=2)
82+
>>>
83+
>>> streamlit_bokeh(p, use_container_width=True)
84+
85+
"""
86+
87+
if bokeh.__version__ != ST_BOKEH_VERSION:
88+
# TODO(ken): Update Error message
89+
raise Exception(
90+
f"Streamlit only supports Bokeh version {ST_BOKEH_VERSION}, "
91+
f"but you have version {bokeh.__version__} installed. Please "
92+
f"run `pip install --force-reinstall --no-deps bokeh=="
93+
f"{ST_BOKEH_VERSION}` to install the correct version."
94+
)
95+
96+
# Call through to our private component function. Arguments we pass here
97+
# will be sent to the frontend, where they'll be available in an "args"
98+
# dictionary.
99+
component_value = _component_func(
100+
figure=json.dumps(json_item(figure)),
101+
use_container_width=use_container_width,
102+
bokeh_theme=theme,
103+
key=key)
104+
105+
# We could modify the value returned from the component if we wanted.
106+
# There's no need to do this in our simple example - but it's an option.
107+
return component_value

streamlit_bokeh/frontend/.env

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Run the component's dev server on :3001
2+
# (The Streamlit dev server already runs on :3000)
3+
PORT=3001
4+
5+
# Don't automatically open the web browser on `npm run start`.
6+
BROWSER=none
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"endOfLine": "lf",
3+
"semi": false,
4+
"trailingComma": "es5"
5+
}

0 commit comments

Comments
 (0)