[ 
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)

Reply via email to