我正在尝试在Google App Engine上使用py2neo设置后端。当在应用程序引擎上的开发人员上推送时,它工作得很好,但是,不幸的是,当我在本地主机上使用它时,它不起作用。

首先,我已经在python中设置了HOME环境变量(由于这个技巧,我的代码可以在我的dev上运行),但是它不能解决localhost问题。

然后,我遵循了该建议"ImportError: No module named _ssl" with dev_appserver.py from Google App Engine
它可以防止一个异常,但另一个异常会在之后出现。

这是我的回溯

    ft1.1: Traceback (most recent call last):
  File "/Users/Arnaud/Documents/project/app/test/neo4j/test_graph_handler.py", line 13, in test_get_direct_neighbours
    selection = self.graph_handler.get_direct_neighbours("8")
  File "/Users/Arnaud/Documents/project/app/neo4j/graph_handler.py", line 20, in get_direct_neighbours
    labels(l) AS `relationship`" % self.protect(ean))
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/database/__init__.py", line 694, in run
    return self.begin(autocommit=True).run(statement, parameters, **kwparameters)
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/database/__init__.py", line 370, in begin
    return self.transaction_class(self, autocommit)
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/database/__init__.py", line 1212, in __init__
    self.session = driver.session()
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/packages/neo4j/v1/session.py", line 126, in session
    connection = connect(self.address, self.ssl_context, **self.config)
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/packages/neo4j/v1/bolt.py", line 444, in connect
    if not store.match_or_trust(host, der_encoded_server_certificate):
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/packages/neo4j/v1/bolt.py", line 397, in match_or_trust
    f_out = os_open(self.path, O_CREAT | O_APPEND | O_WRONLY, 0o600)  # TODO: Windows
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/tools/devappserver2/python/stubs.py", line 73, in fake_open
    raise OSError(errno.EROFS, 'Read-only file system', filename)
OSError: [Errno 30] Read-only file system: '/Users/Arnaud/.neo4j/known_hosts'


由于一切都在沙盒环境中进行,并且有假用户,异常是正常的,但在开发人员中不会发生。

这是/Users/Arnaud/Documents/project/app/neo4j/graph_handler.py:20

 13     def get_direct_neighbours(self, ean):
 14         selection = self.graph.run("\
 15                 MATCH\
 16                 (:Product {ean: '%s'})-->(l)<--(n:Product)\
 17                 RETURN\
 18                 n.ean AS `ean`,\
 19                 n.name AS `name`,\
 20                 labels(l) AS `relationship`" % self.protect(ean))
 21         return selection


因此,为了理解为什么它对开发人员有效,我尝试定位沙箱和开发人员执行开始不同的地方。就在这里
/Users/Arnaud/Documents/project/app/libs/py2neo/packages/neo4j/v1/bolt.py:427

427     if ssl_context and SSL_AVAILABLE:
428         host, port = host_port
429         if __debug__: log_info("~~ [SECURE] %s", host)
430         try:
431             s = ssl_context.wrap_socket(s, server_hostname=host if HAS_SNI else None)
432         except SSLError as cause:
433             error = ProtocolError("Cannot establish secure connection; %s" % cause.args[1])
434             error.__cause__ = cause
435             raise error
436         else:
437             # Check that the server provides a certificate
438             der_encoded_server_certificate = s.getpeercert(binary_form=True)
439             if der_encoded_server_certificate is None:
440                 raise ProtocolError("When using a secure socket, the server should always provide a certificate")
441             trust = config.get("trust", TRUST_DEFAULT)
442             if trust == TRUST_ON_FIRST_USE:
443                 store = PersonalCertificateStore()
444                 if not store.match_or_trust(host, der_encoded_server_certificate):
445                     raise ProtocolError("Server certificate does not match known certificate for %r; check "
446                                         "details in file %r" % (host, KNOWN_HOSTS))
447     else:
448         der_encoded_server_certificate = None


因为在开发人员中,在本地主机上时,ssl_compat.py中的ssl加载失败,因此成功,因此代码进入if语句中,并在444行失败

要了解我强迫SSL_AVAILABLE为虚假,但是即使如此,我也遇到了一些关于App Engine套接字的问题,这些问题无法识别为套接字

ft1.1: Traceback (most recent call last):
  File "/Users/Arnaud/Documents/project/app/test/neo4j/test_graph_handler.py", line 13, in test_get_direct_neighbours
    selection = self.graph_handler.get_direct_neighbours("8")
  File "/Users/Arnaud/Documents/project/app/neo4j/graph_handler.py", line 20, in get_direct_neighbours
    labels(l) AS `relationship`" % self.protect(ean))
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/database/__init__.py", line 694, in run
    return self.begin(autocommit=True).run(statement, parameters, **kwparameters)
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/database/__init__.py", line 370, in begin
    return self.transaction_class(self, autocommit)
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/database/__init__.py", line 1212, in __init__
    self.session = driver.session()
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/packages/neo4j/v1/session.py", line 126, in session
    connection = connect(self.address, self.ssl_context, **self.config)
  File "/Users/Arnaud/Documents/project/app/libs/py2neo/packages/neo4j/v1/bolt.py", line 460, in connect
    ready_to_read, _, _ = select((s,), (), (), 0)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/remote_socket/_remote_socket.py", line 483, in select
    _SetState(request, _GetSocket(value), POLLIN)
  File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/api/remote_socket/_remote_socket.py", line 425, in _GetSocket
    raise ValueError('select only supported on socket objects.')
ValueError: select only supported on socket objects.


如果有人遇到过同样的问题,那么我将对此感兴趣,因为在进行任何测试之前必须先推动开发人员。

编辑:
对于那些想知道的人,因为我还没有收到奈杰尔的答复,而且我需要一些快速的解决方案,所以我创建了自己的类来发送和接收密码请求,它与应用程序引擎兼容,并且将其放在了要点:https://gist.github.com/ArnaudParan/e26f291ba8b3c08e5b762d549667c7d6这是实验性的,如果您要求完整的节点,则可能不起作用,但如果有帮助,我会发布

最佳答案

第一个回溯可能表明py2neo软件包可能与GAE's sandbox restrictions不兼容。特别是,它显示了尝试以写入模式(/Users/Arnaud/.neo4j/known_hosts)打开os_open(self.path, O_CREAT | O_APPEND | O_WRONLY, 0o600)文件的尝试,这是不允许的。检查是否可以将py2neo配置为不这样做。

沙箱对套接字也有限制,请参见Limitations and restrictions

关于python - 将py2neo v3与Google App Engine一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38830407/

10-17 00:36