Integrate Graphistry into Streamlit.
The following snippet works but is not ideal :
g = graphistry.bind(source="src", destination="dst", node="dst").nodes(edges).edges(edges)
plot = g.settings(url_params={'play': 1000, 'bg': '%230a0a0a'}).plot()
iframe = '<iframe src="' + plot + '", height="800", width="100%"></iframe>'
st.markdown(iframe, unsafe_allow_html=True)
Test if custom components or iframe support works with Graphistry.
Thanks!
For our side: We're happy to try to add some custom logic to our def plot(..): ... method to detect we're in a streamlit environment and emit code differently, just need guidance.
The general expected behavior for our users is:
.plot() : Best-effort inline rendering for whatever notebook environment is being used
.plot(render=False): get a URL string
Also: Currently heavy GPU-accelerated cross-filtering happens inside our embedded visuals, and while we're working towards easier in/out of streaming concrete data + symbolic logic, those will be releasing in waves in Q3 & Q4, so recommend just getting out basic GPU plots for now based on an initial dataframe upload. (Which happens via whatever is bound by the time of the g.plot() call.)
Also for now, if you make that:
.plot(render=False)
then it won't pop up a new window. : )
Hi any update on this? Looks like we're missing the current on-prem edition release window, and would love to get in for the next one!
Hi @lmeyerov !
The Streamlit team is currently developing "Custom Components" as a way to extend Streamlit with our own use cases. At a high level it's an endpoint for exposing HTML/CSS/JS code inside a sandboxed iframe using arguments passed from the Python end user side. I'm positive it will interact very well with graphistry-js.
The following is still beta work in progress, but the lifecycle looks like the following :
plot(...)/bind(...)/settings(...) on the end user Python side st.graphistry(dataset=,color=....) on your Python library dev side, ReactDOM.render(<Graphistry dataset=...,>) If all the arguments in the settings + bind phase are the same as those in the <Graphistry> tag then implementation should be a no brainer.
The feature is currently being beta-tested so the API is still changing a small bit, but if you have some time and a little bit of JS or React experience I honestly think it'd be great if you joined the closed beta and tried to integrate on your side :) I don't think it'd take more than a day but I didn't really go into all of the arguments that are used in Graphistry... If you are interested don't hesitate to DM @randyzwitch !
In any case I think we should wait for the release of Custom Components (which is expected for H1 2020, I don't have an exact timeframe though) to be more precise on the custom logic you would need to define.
Thanks @andfanilo ! The Custom Components looks exciting!
class Graphistry:
...
def plot(self):
iframe_url = self.get_iframe_url()
try:
if is_in_streamlit():
return st.iframe(iframe_url)
I'm mostly unsure of the recommended thing to put in for (a) is_in_streamlit() for detection and (b) what to do for the return for our iframe
Ex: the below would seem to work, albeit without automatic integration (manual g.plot(mode='streamlit') and with unsafe_allow_html=True:
def plot(self, ...., mode=None):
if mode == 'streamlit':
url = self.get_iframe_url()
html = '<iframe src="' + plot + '", height="800", width="100%"></iframe>'
return st.markdown(iframe, unsafe_allow_html=True)
It'd be better if we could autodetect streamlit and not do unsafe_allow_html, but afaict the above would work..
-- Python uploader: receive dataframe (e.g., 1GB of Arrow) and some optional settings, return live server session info (generic ID, embeddable url, ...). Also accessible via REST API underneath.
-- Viewer API 1: Server REST API: for a session ID, authenticate (JWT) -> live control of filters, clustering, etc.
-- Viewer API 2: Browser JS APIs (REST, JS, React): Load a server session view into a browser window and control local + server state.
Longer-term, it might be easier for us to connect streamlit to our Server REST APIs vs forcing a roundtrip through the JS client. Ex: if a streamlit UI control like a slider moves, tell the graphistry server directly. OTOH, streamlit our <> React client might be easier coding, and work for everything except changes in the dataframe (where we shouldn't roundtrip 1GB of data through the browser!)
:+1: Great that you look forward to Custom Components
Streamlit doesn't provide an out of the box st.iframe for now, so the way @EmmiBevensee does it is the most reasonable dirty way of doing it though you don't get JS support. Let me consult the eng team to see if there's a way to detect we're in a Streamlit environment without relying on hitting the Streamlit Tornado server API / detecting if Streamlit is loaded in pkg_resources.
Yup this looks good to me, will keep you updated when it's out
@lmeyerov If you're interested in working with us in the Custom Components Beta, please send me an email at [email protected]. We'd love to have you as one of our launch examples, feels like it shouldn't be much work to get this going :+1:
Hi @lmeyerov ,
For the short-term solution is_in_streamlit(), you can try this gist.
Also just st.iframe should be sufficient, no need for the return.
Hi @andfanilo , great, will try to get this into our next release. Thanks!
@andfanilo Quick update: Had some f500 customer work where we'll be evaluating streamlit for a fit, so this will be going up in priority next week. (Will also reexamine in the open as part of ProjectDomino.org , where folks have already began experimenting for upcoming public tier for covid misinfo awareness.)
cc @randyzwitch
Thanks for the update @lmeyerov
Streamlit doesn't provide an out of the box st.iframe for now,
So actually st.iframe (and st.html`) should come with the release of Custom Components, which eases half of your shorter term solution. I don't have an official timeframe for the release but hopefully pretty soon.
Hi @andfanilo @randyzwitch , some learnings so far:
-- unsafe markdown html indeed gets us quite far! not great to tell F500 + gov folks to do anything unsafe, but great for starters! been an improvement over Viola etc so far
-- the upcoming iframe option sounds right in line. will there be a way to mark iframe attribute allow="fullscreen" so users can pop in and out of fullscreen without losing their session?
-- based on some customer work + projectdomino.org use, we're carving out a sequence of tutorials (minimal, basic dashboard, self-contained docker, integrated docker)
-- the new st custom ui api stuff sounds relevant for Q4 stuff for taking this to the next level :) the model we'll be hoping for is the st frontend can send UI control commands to us (and vice-versa), and the st backend can send dataframe updates to the graphistry backend (and vice versa?)

Hey @lmeyerov, glad you’ve made some progress! The “correct” way to do this comes out tomorrow in v0.63.0, so the “unsafe” part will no longer be necessary.
The documentation will show tomorrow how to use React and/or TypeScript. Happy to answer any questions as they come up (or refer you to an engineer that knows what they are doing with J.S. :) )
Cool!
My sense is we'll "eventually" get to doing React stuff on our side (Q4?), but for now + bulk of our end-users interested in streamlit for dashboarding, React loses a lot of the appeal of the current model. (We already have a react component, but even when we get that re-wrapped for streamlit, our streamlit users will still likely rather not touch JS, e.g., imagine a bank fraud team or some data scientist.)
The end-user never touches JS, they write Python. The component architecture deals with bi-directional communication between Python and JS
Ah gotcha, that's good to hear. My guess is we'll probably still get more mileage by focusing on the python -> python layers first, which are largely already there :)
Current progress on proving out a customer streamlit/rapids/graphistry dashboard:
Frontend: Will be curious if v2 supports safely or we'll still need the backdoor:
-- currently doing allow=fullscreen for iframe
-- currently doing custom css for 100% width of the iframe
-- we haven't figured out 100% height
Backend:
-- Unclear how to prevent form input updating until the form's 'submit' button is clicked (if button:... pattern didn't quite work)
-- Multiple dashboarding without multiple servers: Stuck - See https://discuss.streamlit.io/t/multiple-apps-on-same-server/4216
-- We're learning what's needed for caching
-- docker + docker-compose was pretty easy
-- next up is caddy jwt auth bastion integration
In q4, or if this keeps going well, in q3, will want to connection streamlit dynamic df data to our backend dynamic df, so no need to refresh the iframe, just server<>server APache Arrow deltas. will be very cool if we pull it off :)
Now that it's Tuesday...
https://docs.streamlit.io/en/stable/develop_streamlit_components.html#create-a-static-component
components.html and components.iframe can be used in place of st.markdown, which gives you the same basic functionality, but sandboxed into an iframe put into the Streamlit app. This will allow you the same functionality, but keeps other widgets from modifying your widget, and similarly your widget won't be able to modify someone elses.
Thanks -- I'll file tickets as the new API, as I was fearing, does not support ^^^^^ functionality, so we'll stick with markdown
Hi @randyzwitch just a quick heads up, as we've been bogged down in some internal + customer stuff:
-- with the st queryurl + fullscreen stuff landing, looks like we're about there for v1 from st side!
-- we hit issues on using caddy reverse proxy <> st for showing how to bundle together in a production setting (bastion / auth server), hopefully eow or next for that as on some customer paths
folks have been perking up on this, and 2+ projects already planning for it, so we're excited
Great, looking forward to checking it out. Once it's released, we'd be happy to add it to our Components gallery:
Most helpful comment
Hi @randyzwitch just a quick heads up, as we've been bogged down in some internal + customer stuff:
-- with the st queryurl + fullscreen stuff landing, looks like we're about there for v1 from st side!
-- we hit issues on using caddy reverse proxy <> st for showing how to bundle together in a production setting (bastion / auth server), hopefully eow or next for that as on some customer paths
folks have been perking up on this, and 2+ projects already planning for it, so we're excited