def __init__(self, uri, headers, verified): self.uri = uri self.verified = verified parts = urlsplit(uri) scheme = parts.scheme host = parts.hostname port = parts.port if scheme == "http": from urllib3 import HTTPConnectionPool self._http = HTTPConnectionPool("%s:%d" % (host, port)) elif scheme == "https": from urllib3 import HTTPSConnectionPool if verified: from certifi import where self._http = HTTPSConnectionPool("%s:%d" % (host, port), cert_reqs="CERT_REQUIRED", ca_certs=where()) else: self._http = HTTPSConnectionPool("%s:%d" % (host, port)) else: raise ValueError("Unsupported scheme %r" % scheme) self.path = parts.path if "auth" in headers: user, password = headers.pop("auth") headers["Authorization"] = 'Basic ' + b64encode( (ustr(user) + u":" + ustr(password)).encode("utf-8")).decode("ascii") self.headers = headers
def sync(self): ref = self.ref # Some of the transactional URIs do not support empty statement # lists in versions earlier than 2.3. Which doesn't really matter # as it's a waste sending anything anyway. if ref in (self.autocommit_ref, self.begin_ref, self.transaction_ref) and not self._statements: return 0 count = 0 try: response = self.post(ref, {"statements": self._statements}, expected=(OK, CREATED)) if response.status == 201: location_path = urlsplit(response.headers["Location"]).path self.transaction_ref = "".join(location_path.rpartition("transaction")[1:]) self.commit_ref = "%s/commit" % self.transaction_ref self.ref = self.transaction_ref content = json_loads(response.data.decode("utf-8")) errors = content["errors"] if errors: from py2neo.database import GraphError raise GraphError.hydrate(errors[0]) for i, result_loader in enumerate(self._result_loaders): try: count += result_loader.load(content["results"][i]) except IndexError: result_loader.fail() return count finally: self._statements[:] = () self._result_loaders[:] = ()
def begin(self): r = self._post("/db/data/transaction") if r.status == 201: location_path = urlsplit(r.headers["Location"]).path tx = location_path.rpartition("/")[-1] self.transactions.add(tx) return tx else: raise RuntimeError("Can't begin a new transaction")
def get_connection_data(uri=None, **settings): """ Generate a dictionary of connection data for an optional URI plus additional connection settings. :param uri: :param settings: :return: """ data = { "host": None, "password": None, "port": None, "scheme": None, "secure": None, "verified": None, "user": None, "user_agent": None, } # apply uri uri = coalesce(uri, NEO4J_URI) if uri is not None: parsed = urlsplit(uri) if parsed.scheme is not None: data["scheme"] = parsed.scheme if data["scheme"] in ["https"]: data["secure"] = True elif data["scheme"] in ["http"]: data["secure"] = False data["user"] = coalesce(parsed.username, data["user"]) data["password"] = coalesce(parsed.password, data["password"]) data["host"] = coalesce(parsed.hostname, data["host"]) data["port"] = coalesce(parsed.port, data["port"]) # apply auth (this can override `uri`) if "auth" in settings and settings["auth"] is not None: data["user"], data["password"] = settings["auth"] elif NEO4J_AUTH is not None: data["user"], _, data["password"] = NEO4J_AUTH.partition(":") # apply components (these can override `uri` and `auth`) data["user_agent"] = coalesce(settings.get("user_agent"), NEO4J_USER_AGENT, data["user_agent"]) data["secure"] = coalesce(settings.get("secure"), data["secure"], NEO4J_SECURE) data["verified"] = coalesce(settings.get("verified"), data["verified"], NEO4J_VERIFIED) data["scheme"] = coalesce(settings.get("scheme"), data["scheme"]) data["user"] = coalesce(settings.get("user"), data["user"]) data["password"] = coalesce(settings.get("password"), data["password"]) data["host"] = coalesce(settings.get("host"), data["host"]) data["port"] = coalesce(settings.get("port"), data["port"]) # apply correct scheme for security if data["secure"] is True and data["scheme"] == "http": data["scheme"] = "https" if data["secure"] is False and data["scheme"] == "https": data["scheme"] = "http" # apply default port for scheme if data["scheme"] and not data["port"]: if data["scheme"] == "http": data["port"] = DEFAULT_HTTP_PORT elif data["scheme"] == "https": data["port"] = DEFAULT_HTTPS_PORT elif data["scheme"] in ["bolt", "bolt+routing"]: data["port"] = DEFAULT_BOLT_PORT # apply other defaults if not data["user_agent"]: data["user_agent"] = http_user_agent() if data["scheme"] in [ "http", "https" ] else bolt_user_agent() if data["secure"] is None: data["secure"] = DEFAULT_SECURE if data["verified"] is None: data["verified"] = DEFAULT_VERIFIED if not data["scheme"]: data["scheme"] = DEFAULT_SCHEME if data["scheme"] == "http": data["secure"] = False data["verified"] = False if data["scheme"] == "https": data["secure"] = True data["verified"] = True if not data["user"]: data["user"] = DEFAULT_USER if not data["password"]: data["password"] = DEFAULT_PASSWORD if not data["host"]: data["host"] = DEFAULT_HOST if not data["port"]: data["port"] = DEFAULT_BOLT_PORT # apply composites data["auth"] = (data["user"], data["password"]) data["uri"] = "%s://%s:%s" % (data["scheme"], data["host"], data["port"]) h = hashlib_new("md5") for key in sorted(data): h.update(bstr(data[key])) data["hash"] = h.hexdigest() return data