Commit 851ebfff authored by David Michael Brown's avatar David Michael Brown Committed by GitHub
Browse files

Merge pull request #5 from davebshow/async_dsl

Async dsl
parents 33567e96 da3e96b5
from aiogremlin.driver.cluster import Cluster
from aiogremlin.remote.driver_remote_connection import DriverRemoteConnection
from aiogremlin.gremlin_python.structure.graph import Graph
from aiogremlin.structure.graph import Graph
__version__ = "3.2.4"
import aiohttp
from aiogremlin.gremlin_python.driver import transport
from gremlin_python.driver import transport
class AiohttpTransport(transport.AbstractBaseTransport):
......
"""Client for the Tinkerpop 3 Gremlin Server."""
from aiogremlin import exception
from aiogremlin.gremlin_python.driver import request
from aiogremlin.gremlin_python.process import traversal
from gremlin_python.driver import request
from gremlin_python.process import traversal
class Client:
......@@ -58,8 +59,8 @@ class Client:
**coroutine** Submit a script and bindings to the Gremlin Server.
:param message: Can be an instance of
`Message<aiogremlin.gremlin_python.request.RequestMessage>` or
`Bytecode<aiogremlin.gremlin_python.process.traversal.Bytecode>`
`Message<gremlin_python.request.RequestMessage>` or
`Bytecode<gremlin_python.process.traversal.Bytecode>`
or a `str` representing a raw Gremlin script
:param dict bindings: Optional bindings used with raw Grelmin
:returns: :py:class:`ResultSet<aiogremlin.driver.resultset.ResultSet>`
......
......@@ -12,7 +12,7 @@ import yaml
from aiogremlin import exception
from aiogremlin import driver
from aiogremlin.gremlin_python.driver import serializer
from gremlin_python.driver import serializer
def my_import(name):
......@@ -52,7 +52,7 @@ class Cluster:
'min_conns': 1,
'max_times_acquired': 16,
'max_inflight': 64,
'message_serializer': 'aiogremlin.gremlin_python.driver.serializer.GraphSONMessageSerializer',
'message_serializer': 'gremlin_python.driver.serializer.GraphSONMessageSerializer',
'provider': 'aiogremlin.driver.provider.TinkerGraph'
}
......
......@@ -15,7 +15,7 @@ except ImportError:
from aiogremlin.driver import provider, resultset
from aiogremlin.driver.protocol import GremlinServerWSProtocol
from aiogremlin.driver.aiohttp.transport import AiohttpTransport
from aiogremlin.gremlin_python.driver import serializer
from gremlin_python.driver import serializer
logger = logging.getLogger(__name__)
......@@ -28,9 +28,9 @@ class Connection:
:py:meth:`Connection.open<aiogremlin.connection.Connection.open>`.
:param str url: url for host Gremlin Server
:param aiogremlin.gremlin_python.driver.transport.AbstractBaseTransport transport:
:param gremlin_python.driver.transport.AbstractBaseTransport transport:
Transport implementation
:param aiogremlin.gremlin_python.driver.protocol.AbstractBaseProtocol protocol:
:param gremlin_python.driver.protocol.AbstractBaseProtocol protocol:
Protocol implementation
:param asyncio.BaseEventLoop loop:
:param str username: Username for database auth
......@@ -74,7 +74,7 @@ class Connection:
:param str url: url for host Gremlin Server
:param asyncio.BaseEventLoop loop:
:param aiogremlin.gremlin_python.driver.protocol.AbstractBaseProtocol protocol:
:param gremlin_python.driver.protocol.AbstractBaseProtocol protocol:
Protocol implementation
:param func transport_factory: Factory function for transports
:param ssl.SSLContext ssl_context:
......@@ -125,7 +125,7 @@ class Connection:
"""
Submit a script and bindings to the Gremlin Server
:param `RequestMessage<aiogremlin.gremlin_python.driver.request.RequestMessage>` message:
:param `RequestMessage<gremlin_python.driver.request.RequestMessage>` message:
:returns: :py:class:`ResultSet<aiogremlin.driver.resultset.ResultSet>`
object
"""
......
......@@ -9,7 +9,7 @@ try:
except ImportError:
import json
from aiogremlin.gremlin_python.driver import protocol, request, serializer
from gremlin_python.driver import protocol, request, serializer
__author__ = 'David M. Brown (davebshow@gmail.com)'
......
'''
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
'''
'''THIS FILE HAS BEEN MODIFIED BY DAVID M. BROWN TO SUPPORT PEP 492'''
__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
from aiogremlin.gremlin_python.statics import *
from aiogremlin.gremlin_python.process.graph_traversal import __
from aiogremlin.gremlin_python.process.strategies import *
from aiogremlin.gremlin_python.process.traversal import Binding, Cardinality
'''
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
'''
__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
"""
import abc
import base64
import collections
import uuid
try:
import ujson as json
except ImportError:
import json
__author__ = 'David M. Brown (davebshow@gmail.com)'
class AbstractBaseProtocol(metaclass=abc.ABCMeta):
@abc.abstractmethod
def connection_made(self, transport):
self._transport = transport
@abc.abstractmethod
def data_received(self, message):
pass
@abc.abstractmethod
def write(self, request_id, request_message):
pass
'''
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
'''
'''THIS FILE HAS BEEN MODIFIED BY DAVID M. BROWN TO SUPPORT PEP 492'''
import abc
import collections
from aiogremlin.gremlin_python.driver import request
from aiogremlin.gremlin_python.process import traversal
__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
class RemoteConnection(metaclass=abc.ABCMeta):
def __init__(self, url, traversal_source):
self._url = url
self._traversal_source = traversal_source
@property
def url(self):
return self._url
@property
def traversal_source(self):
return self._traversal_source
@abc.abstractmethod
def submit(self, bytecode):
pass
def __repr__(self):
return "remoteconnection[" + self._url + "," + self._traversal_source + "]"
class RemoteTraversal(traversal.Traversal):
def __init__(self, traversers, side_effects):
super(RemoteTraversal, self).__init__(None, None, None)
self.traversers = traversers
self._side_effects = side_effects
@property
def side_effects(self):
return self._side_effects
@side_effects.setter
def side_effects(self, val):
self._side_effects = val
class RemoteStrategy(traversal.TraversalStrategy):
def __init__(self, remote_connection):
self.remote_connection = remote_connection
async def apply(self, traversal):
if traversal.traversers is None:
remote_traversal = await self.remote_connection.submit(
traversal.bytecode)
traversal.remote_results = remote_traversal
traversal.side_effects = remote_traversal.side_effects
traversal.traversers = remote_traversal.traversers
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
"""
import collections
__author__ = 'David M. Brown (davebshow@gmail.com)'
RequestMessage = collections.namedtuple(
'RequestMessage', ['processor', 'op', 'args'])
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
"""
'''THIS FILE HAS BEEN MODIFIED BY DAVID M. BROWN TO SUPPORT PEP 492'''
try:
import ujson as json
except ImportError:
import json
from aiogremlin.gremlin_python.structure.io import graphson
__author__ = 'David M. Brown (davebshow@gmail.com)'
class Processor:
"""Base class for OpProcessor serialization system."""
def __init__(self, writer):
self._graphson_writer = writer
def get_op_args(self, op, args):
op_method = getattr(self, op, None)
if not op_method:
raise Exception("Processor does not support op: {}".format(op))
return op_method(args)
class Standard(Processor):
def authentication(self, args):
return args
def eval(self, args):
return args
class Traversal(Processor):
def authentication(self, args):
return args
def bytecode(self, args):
gremlin = args['gremlin']
args['gremlin'] = self._graphson_writer.toDict(gremlin)
aliases = args.get('aliases', '')
if not aliases:
aliases = {'g': 'g'}
args['aliases'] = aliases
return args
def close(self, args):
return self.keys(args)
def gather(self, args):
side_effect = args['sideEffect']
args['sideEffect'] = {'@type': 'g:UUID', '@value': side_effect}
aliases = args.get('aliases', '')
if not aliases:
aliases = {'g': 'g'}
args['aliases'] = aliases
return args
def keys(self, args):
side_effect = args['sideEffect']
args['sideEffect'] = {'@type': 'g:UUID', '@value': side_effect}
return args
class GraphSONMessageSerializer:
"""Message serializer for GraphSON"""
def __init__(self, reader=None, writer=None):
if not reader:
reader = graphson.GraphSONReader()
self._graphson_reader = reader
if not writer:
writer = graphson.GraphSONWriter()
self.standard = Standard(writer)
self.traversal = Traversal(writer)
def get_processor(self, processor):
processor = getattr(self, processor, None)
if not processor:
raise Exception("Unknown processor")
return processor
def serialize_message(self, request_id, request_message):
processor = request_message.processor
op = request_message.op
args = request_message.args
if not processor:
processor_obj = self.get_processor('standard')
else:
processor_obj = self.get_processor(processor)
args = processor_obj.get_op_args(op, args)
message = self.build_message(request_id, processor, op, args)
return message
def build_message(self, request_id, processor, op, args):
message = {
'requestId': {'@type': 'g:UUID', '@value': request_id},
'processor': processor,
'op': op,
'args': args
}
return self.finalize_message(message, b"\x21",
b"application/vnd.gremlin-v2.0+json")
def finalize_message(self, message, mime_len, mime_type):
message = json.dumps(message)
message = b''.join([mime_len, mime_type, message.encode('utf-8')])
return message
def deserialize_message(self, message):
return self._graphson_reader.toObject(message)
"""
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
"""
import abc
__author__ = 'David M. Brown (davebshow@gmail.com)'
class AbstractBaseTransport(metaclass=abc.ABCMeta):
@abc.abstractmethod
def connect(self, url, *, ssl_context=None):
pass
@abc.abstractmethod
def write(self, message):
pass
@abc.abstractmethod
def read(self):
pass
@abc.abstractmethod
def close(self):
pass
@abc.abstractproperty
def closed(self):
pass
'''
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
'''
__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
'''
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
'''
'''THIS FILE HAS BEEN MODIFIED BY DAVID M. BROWN TO SUPPORT PEP 492'''
import sys
from aiogremlin.gremlin_python.process.traversal import Traversal
from aiogremlin.gremlin_python.process.traversal import TraversalStrategies
from aiogremlin.gremlin_python.process.strategies import VertexProgramStrategy
from .traversal import Bytecode
from aiogremlin.gremlin_python.driver.remote_connection import RemoteStrategy
from aiogremlin.gremlin_python import statics
from aiogremlin.gremlin_python.statics import long
class GraphTraversalSource(object):
def __init__(self, graph, traversal_strategies, bytecode=None):
self.graph = graph
self.traversal_strategies = traversal_strategies
if bytecode is None:
bytecode = Bytecode()
self.bytecode = bytecode
def __repr__(self):
return "graphtraversalsource[" + str(self.graph) + "]"
def withBulk(self, *args):
source = GraphTraversalSource(self.graph, TraversalStrategies(self.traversal_strategies), Bytecode(self.bytecode))
source.bytecode.add_source("withBulk", *args)
return source
def withPath(self, *args):
source = GraphTraversalSource(self.graph, TraversalStrategies(self.traversal_strategies), Bytecode(self.bytecode))
source.bytecode.add_source("withPath", *args)
return source
def withSack(self, *args):
source = GraphTraversalSource(self.graph, TraversalStrategies(self.traversal_strategies), Bytecode(self.bytecode))
source.bytecode.add_source("withSack", *args)
return source
def withSideEffect(self, *args):
source = GraphTraversalSource(self.graph, TraversalStrategies(self.traversal_strategies), Bytecode(self.bytecode))
source.bytecode.add_source("withSideEffect", *args)
return source
def withStrategies(self, *args):
source = GraphTraversalSource(self.graph, TraversalStrategies(self.traversal_strategies), Bytecode(self.bytecode))
source.bytecode.add_source("withStrategies", *args)
return source
def withoutStrategies(self, *args):
source = GraphTraversalSource(self.graph, TraversalStrategies(self.traversal_strategies), Bytecode(self.bytecode))
source.bytecode.add_source("withoutStrategies", *args)
return source
def withRemote(self, remote_connection):
source = GraphTraversalSource(self.graph, TraversalStrategies(self.traversal_strategies), Bytecode(self.bytecode))
source.traversal_strategies.add_strategies([RemoteStrategy(remote_connection)])
return source
def withComputer(self,graph_computer=None, workers=None, result=None, persist=None, vertices=None, edges=None, configuration=None):
return self.withStrategies(VertexProgramStrategy(graph_computer,workers,result,persist,vertices,edges,configuration))
def E(self, *args):
traversal = GraphTraversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
traversal.bytecode.add_step("E", *args)
return traversal
def V(self, *args):
traversal = GraphTraversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
traversal.bytecode.add_step("V", *args)
return traversal
def addV(self, *args):
traversal = GraphTraversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
traversal.bytecode.add_step("addV", *args)
return traversal
def inject(self, *args):
traversal = GraphTraversal(self.graph, self.traversal_strategies, Bytecode(self.bytecode))
traversal.bytecode.add_step("inject", *args)
return traversal
class GraphTraversal(Traversal):
def __init__(self, graph, traversal_strategies, bytecode):
Traversal.__init__(self, graph, traversal_strategies, bytecode)
def __getitem__(self, index):
if isinstance(index, int):
return self.range(long(index), long(index + 1))
elif isinstance(index, slice):
return self.range(long(0) if index.start is None else long(index.start), long(sys.maxsize) if index.stop is None else long(index.stop))
else:
raise TypeError("Index must be int or slice")
def __getattr__(self, key):
return self.values(key)
def V(self, *args):
self.bytecode.add_step("V", *args)
return self
def addE(self, *args):
self.bytecode.add_step("addE", *args)
return self
def addInE(self, *args):
self.bytecode.add_step("addInE", *args)
return self
def addOutE(self, *args):