We have a Python package, which uses asyncio, to connect to our GraphQL API. (It’s a code-gen SDK, using ariadne-codegen.)
Running this locally in browser, via streamlit run app.py. Version 1.33.0. (Will eventually be deployed on Streamlit Cloud when it’s working.)
I’ve been trying various approaches to call the client package, and generally it works with async/await.
But I’m finding an issue where if I submit multiple forms on the same page, the second submit gives the error below.
The most reliable method, so far, is calling my top-level async function with:
loop = asyncio.new_event_loop()
loop.run_until_complete(main())
Just calling with asyncio.run(main()) didn’t work as well.
It reliably happens when I submit one form (such as clear_data_form), and then click the submit button in another form on same page (data_content_form).
Would splitting our one-page app into multiple pages help this situation, so there’s only one form per page?
Any help would be much appreciated!
Error:
RuntimeError: <asyncio.locks.Event object at 0x7f37f4d302e0 [unset]> is bound to a different event loop
Traceback:
File "/home/kirk/.local/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 584, in _run_script
exec(code, module.__dict__)
File "/mnt/c/projects/Graphlit/graphlit-samples-kirk/python/streamlit-extract-website-topics/app.py", line 90, in <module>
loop.run_until_complete(main())
File "/usr/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
return future.result()
File "/mnt/c/projects/Graphlit/graphlit-samples-kirk/python/streamlit-extract-website-topics/app.py", line 55, in main
await feed.handle_feed(uri)
File "/mnt/c/projects/Graphlit/graphlit-samples-kirk/python/streamlit-extract-website-topics/components/feed.py", line 10, in handle_feed
error_message = await client.create_workflow()
File "/mnt/c/projects/Graphlit/graphlit-samples-kirk/python/streamlit-extract-website-topics/other/client.py", line 64, in create_workflow
response = await graphlit.client.create_workflow(input)
File "/home/kirk/.local/lib/python3.10/site-packages/graphlit_api/client.py", line 1102, in create_workflow
response = await self.execute(
File "/home/kirk/.local/lib/python3.10/site-packages/graphlit_api/async_base_client.py", line 114, in execute
return await self._execute_json(
File "/home/kirk/.local/lib/python3.10/site-packages/graphlit_api/async_base_client.py", line 294, in _execute_json
return await self.http_client.post(
File "/usr/local/lib/python3.10/dist-packages/httpx/_client.py", line 1892, in post
return await self.request(
File "/usr/local/lib/python3.10/dist-packages/httpx/_client.py", line 1574, in request
return await self.send(request, auth=auth, follow_redirects=follow_redirects)
File "/usr/local/lib/python3.10/dist-packages/httpx/_client.py", line 1661, in send
response = await self._send_handling_auth(
File "/usr/local/lib/python3.10/dist-packages/httpx/_client.py", line 1689, in _send_handling_auth
response = await self._send_handling_redirects(
File "/usr/local/lib/python3.10/dist-packages/httpx/_client.py", line 1726, in _send_handling_redirects
response = await self._send_single_request(request)
File "/usr/local/lib/python3.10/dist-packages/httpx/_client.py", line 1763, in _send_single_request
response = await transport.handle_async_request(request)
File "/usr/local/lib/python3.10/dist-packages/httpx/_transports/default.py", line 373, in handle_async_request
resp = await self._pool.handle_async_request(req)
File "/usr/local/lib/python3.10/dist-packages/httpcore/_async/connection_pool.py", line 216, in handle_async_request
raise exc from None
File "/usr/local/lib/python3.10/dist-packages/httpcore/_async/connection_pool.py", line 196, in handle_async_request
response = await connection.handle_async_request(
File "/usr/local/lib/python3.10/dist-packages/httpcore/_async/connection.py", line 101, in handle_async_request
return await self._connection.handle_async_request(request)
File "/usr/local/lib/python3.10/dist-packages/httpcore/_async/http11.py", line 143, in handle_async_request
raise exc
File "/usr/local/lib/python3.10/dist-packages/httpcore/_async/http11.py", line 113, in handle_async_request
) = await self._receive_response_headers(**kwargs)
File "/usr/local/lib/python3.10/dist-packages/httpcore/_async/http11.py", line 186, in _receive_response_headers
event = await self._receive_event(timeout=timeout)
File "/usr/local/lib/python3.10/dist-packages/httpcore/_async/http11.py", line 224, in _receive_event
data = await self._network_stream.read(
File "/usr/local/lib/python3.10/dist-packages/httpcore/_backends/anyio.py", line 35, in read
return await self._stream.receive(max_bytes=max_bytes)
File "/usr/local/lib/python3.10/dist-packages/anyio/streams/tls.py", line 205, in receive
data = await self._call_sslobject_method(self._ssl_object.read, max_bytes)
File "/usr/local/lib/python3.10/dist-packages/anyio/streams/tls.py", line 147, in _call_sslobject_method
data = await self.transport_stream.receive()
File "/usr/local/lib/python3.10/dist-packages/anyio/_backends/_asyncio.py", line 1133, in receive
await self._protocol.read_event.wait()
File "/usr/lib/python3.10/asyncio/locks.py", line 211, in wait
fut = self._get_loop().create_future()
File "/usr/lib/python3.10/asyncio/mixins.py", line 30, in _get_loop
raise RuntimeError(f'{self!r} is bound to a different event loop')
Here’s the code for my async function, and anywhere it shows ‘await’, it’s calling another async function.
async def main():
st.image("https://graphlitplatform.blob.core.windows.net/samples/graphlit-logo.svg", width=128)
st.title("Graphlit Platform")
st.markdown("Summarize any PDF, DOCX, or PPTX file. Summary generated with the [Anthropic](https://www.anthropic.com) Claude 3 Haiku LLM.")
if st.session_state['token'] is None:
st.info("💡 To get started, generate a token in the side panel to connect to your Graphlit project.")
with st.form("data_content_form"):
selected_pdf = st.selectbox("Select a PDF:", options=list(pdfs.keys()))
document_uri = st.text_input("Or enter your own URL to a file (i.e. PDF, DOCX, PPTX):", key='pdf_uri')
uri = document_uri if document_uri else pdfs[selected_pdf]
submit_content = st.form_submit_button("Submit")
if submit_content and uri and st.session_state['token']:
await upload.handle_upload(uri)
with st.form("summarize_data_form"):
if st.session_state['content_done'] == True:
await summarize.handle_summarize()
with st.form("clear_data_form"):
st.markdown("If you run into any problems, or exceeded your Free Tier project quota, you can delete all your contents to start over. Be aware, this deletes *all* the contents in your project.")
submit_reset = st.form_submit_button("Reset project")
if submit_reset:
if st.session_state['token']:
with st.spinner('Deleting contents... Please wait.'):
await client.delete_all_contents()
sidebar.create_sidebar("""
### Demo Instructions
- [Sign up for Graphlit](https://docs.graphlit.dev/getting-started/signup) 🆓
- **Step 1:** Generate Graphlit project token.
- **Step 2:** Select a PDF, or fill in your own document URL.
- **Step 3:** Click to generate summary of file using [Anthropic](https://www.anthropic.com) Claude 3 Haiku LLM.
""")
if __name__ == "__main__":
loop = asyncio.new_event_loop()
loop.run_until_complete(main())