davebshow / gremlinclient

A Python client for TP3 Gremlin Server for Tornado, Trollius, or Asyncio
MIT License
28 stars 6 forks source link

Example returns 400 #13

Open richburdon opened 8 years ago

richburdon commented 8 years ago

The example script on the home page returns

tornado.httpclient.HTTPError: HTTP 400: Bad Request

With the following on the server:

titan_1 | 185142 [gremlin-server-worker-1] WARN org.apache.tinkerpop.gremlin.server.handler.HttpGremlinEndpointHandler - Invalid request - responding with 400 Bad Request and no gremlin script supplied

Against Titan (https://github.com/elubow/titan-gremlin/blob/master/Dockerfile)

Which depends on TinkerPop 3.0.1-incubating

Is this server supported?

davebshow commented 8 years ago

It sounds like you are using the Gremlin Server with the REST interface configuration, but gremlinclient uses the default WebSocket connection. You can try using: https://github.com/davebshow/titan-gremlin, or download Titan and use the default config params. Let me know if that helps. Thanks!

richburdon commented 8 years ago

David, got it thanks.

I'm using Docker, hence https://hub.docker.com/r/davebshow/titan-websockets

I assume that's the image from https://github.com/davebshow/titan-gremlin/blob/master/Dockerfile

Follow-up Q: is it not possible to have Titan handle both WS and REST traffic: I'm generally going to call it via WS (from your lib), but would like also to be able to use the console (and/or curl) to test my scripts.

Thanks.

leifurhauks commented 8 years ago

@richburdon for your follow-up question, from the tinkerpop3 docs:

Gremlin Server provides for a single REST endpoint - a Gremlin evaluator - which allows the submission of a Gremlin script as a request. For each request, it returns a response containing the serialized results of that script. To enable this endpoint, Gremlin Server needs to be configured with the HttpChannelizer, which replaces the default WebSocketChannelizer, in the configuration file

While that would seem to suggest that that you have to pick one or the other, I think you could just run multiple instances of gremlin-server against the same titan instance, as long as you bind them to different ports (or hostnames).

pluradj commented 8 years ago

@richburdon Titan Server is based off of Gremlin Server. This JIRA is open to support both WS and REST simultaneously but has not been started https://issues.apache.org/jira/browse/TINKERPOP-915

davebshow commented 8 years ago

Ah yes @richburdon, the titan-websockets image is what I was referring to. Thanks for the input @leifurhauks and @pluradj. Unless there are any objections, I am going to go ahead and close this issue.

richburdon commented 8 years ago

Dave, sorry one more question (I'm still working through this and not familiar with tornado -- and unsure why it's required to make a websocket request -- e.g., rather than https://pypi.python.org/pypi/websockets; I assume to handle multiple (many) requests without blocking on active sockets?)

In your example:

@gen.coroutine def go(): resp = yield submit(SERVER_URL, '1 + 1') while True: msg = yield resp.read() if msg is None: break

IOLoop.current().loop.run_sync(go)

How can I pass a script to go? And how can I get the result from run_sync?

I now have Marko's variant code working, which uses your lib, but again I have the same issue:

v.g().toList()

doesn't returns None.

Thanks again -- I know I'm missing something very basic, but the docs don't help very much.

davebshow commented 8 years ago

We use Tornado because it is Python 2/3 compatible. I think the websockets library you linked to is Python 3 only.

To answer your question, to return something from a Tornado coroutine with Python 2.7, you can use: raise gen.Return(value) as specified here: http://www.tornadoweb.org/en/stable/gen.html#tornado.gen.Return

To pass args to the go coroutine, I would maybe use a lambda...something like this (untested):

@gen.coroutine
def go(script):
    ...
    raise gen.Return(output)

output = IOLoop.current().loop.run_sync(lambda: go("1 + 1"))
davebshow commented 8 years ago

Btw @richburdon no worries! I love questions and I am happy that you are using gremlinclient!

richburdon commented 8 years ago

Fantastic -- thanks (it wasn't obvious to a non Tornado user, perhaps update the docs?)

So, nearly there. Last part (since your very gracious last message ;).

I have the gremlin-python.py file now happily generated from Marko's Groovy source (with a couple of fixes). As you know this uses your gremlinclient lib and the submit method does the gen.Return(output) as you suggest; I was expecting to do something like this:

g = PythonGraphTraversalSource(SERVER_URL, 'g') g.addV().tx().commit() # no method for commit() in the generated source. print g.V().toList()

Have you used the generated lang variant above?

Is it another simple mistake I'm making, or perhaps something missing from the generated source.

Thanks again. Feels like I'm nearly there now...

davebshow commented 8 years ago

I'm not 100% sure what you are asking...

I haven't used the Marko's generated code at all, so I'm not sure what the issue is. I'm also not sure about the Gremlin you wrote...maybe it is fine, but I'm not sure if g.addV().tx().commit() will work as is even if the generated code is complete.

richburdon commented 8 years ago

OK Thanks Dave. I'll follow-up with Marko and/or try to extend the generated lib. I'll let you know if I can move this forward.

Separately, do you think the comprehensive language variant would be a useful adjunct to your package, or a separate project (I'm happy to either send you a pull request, or create a new repo for this).