[
https://issues.apache.org/jira/browse/TINKERPOP-2752?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17556938#comment-17556938
]
Steve Kieffer commented on TINKERPOP-2752:
------------------------------------------
Would you be willing to provide support for better control over the
dependencies?
The {{AiohttpTransport}} class is the only thing in {{gremlinpython}} that
requires {{aiohttp}} or {{nest_asyncio}} (and all their recursive
requirements), so if you're using an alternative transport, you wind up having
to install a lot of packages you may not need.
To move {{aiohttp}} into {{extras_require}} now could break existing
installations; however, with a little modification to {{setup.py}}, we could
have an "opt out" at installation time via an environment variable, like so:
{code}
export GREMLINPYTHON_NO_AIOHTTP=1
pip install --no-binary gremlinpython gremlinpython
{code}
The following code in {{setup.py}} should do it:
{code:python}
install_requires = [
'nest_asyncio',
'aiohttp>=3.8.0,<=3.8.1',
'aenum>=1.4.5,<4.0.0',
'isodate>=0.6.0,<1.0.0'
]
no_aiohttp = bool(os.getenv("GREMLINPYTHON_NO_AIOHTTP"))
if no_aiohttp:
install_requires = [
req for req in install_requires if not (
req.startswith('nest_asyncio') or
req.startswith('aiohttp')
)
]
{code}
I've seen this approach used, for example, by the {{aiohttp}} library itself,
to decline installation of certain extension modules.
See:
https://github.com/aio-libs/aiohttp/blob/f922c1985d74509366f68152ddd940f121fc40e5/setup.py#L11
> `AiohttpTransport` malfunctions in an eventlet monkey patched app
> -----------------------------------------------------------------
>
> Key: TINKERPOP-2752
> URL: https://issues.apache.org/jira/browse/TINKERPOP-2752
> Project: TinkerPop
> Issue Type: Bug
> Components: python
> Affects Versions: 3.6.0, 3.5.2
> Environment: python 3.8, running both natively on macOS, and within a
> Docker container hosted on macOS
> Reporter: Steve Kieffer
> Priority: Blocker
>
> I'm running an eventlet-based Flask web app, that starts out with a call to
> {code:python}
> eventlet.monkey_patch()
> {code}
> and has view functions that use gremlin-python to connect to a gremlin server.
> I've found that if the browser issues several requests in rapid succession,
> it can provoke the
> {code:python}
> RuntimeError: Cannot run the event loop while another loop is running
> {code}
> error. Passing
> {code:python}
> call_from_event_loop=True
> {code}
> when constructing the {{DriverRemoteConnection}} just leads to a different
> type of error, because the problem is transient, not consistent.
> I've developed a minimal example that demonstrates the issue, and can share a
> link to that if it would be helpful.
> *Possible solution:*
> How about supplying another transport, besides the {{AiohttpTransport}}
> class, which uses the {{websocket-client}} python package, instead of
> {{aiohttp}}?
> I've made one which is very rudimentary but, in testing so far, works fine
> and solves this issue:
> {code:python}
> from gremlin_python.driver.transport import AbstractBaseTransport
> import websocket
> class WebsocketTransport(AbstractBaseTransport):
> def __init__(self, **kwargs):
> self.ws = websocket.WebSocket(**kwargs)
> def connect(self, url, headers=None):
> headers = headers or []
> self.ws.connect(url, header=headers)
> def write(self, message):
> self.ws.send_binary(message)
> def read(self):
> return self.ws.recv()
> def close(self):
> self.ws.close()
> @property
> def closed(self):
> return not self.ws.connected
> def transport_factory():
> return WebsocketTransport()
> {code}
> Happy to open this as a PR, if it seems like a good idea.
--
This message was sent by Atlassian Jira
(v8.20.7#820007)