示例#1
0
    def functions(self):
        """List the AQL functions defined in this database.

        :returns: a mapping of AQL function names to its javascript code
        :rtype: dict
        :raises arango.exceptions.AQLFunctionListError: if the AQL functions
            cannot be retrieved
        """
        request = Request(method='get', endpoint='/_api/aqlfunction')

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise AQLFunctionListError(res)
            body = res.body or {}
            return {func['name']: func['code'] for func in map(dict, body)}

        return request, handler
示例#2
0
    def configure(self, sync=None, journal_size=None):
        """Configure the collection properties.

        Only *sync* and *journal_size* properties are configurable.

        :param sync: wait for the operation to sync to disk
        :type sync: bool
        :param journal_size: the journal size
        :type journal_size: int
        :returns: the new collection properties
        :rtype: dict
        :raises arango.exceptions.CollectionConfigureError: if the
            collection properties cannot be configured
        """
        data = {}
        if sync is not None:
            data['waitForSync'] = sync
        if journal_size is not None:
            data['journalSize'] = journal_size

        request = Request(method='put',
                          endpoint='/_api/collection/{}/properties'.format(
                              self._name),
                          data=data)

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise CollectionConfigureError(res)
            result = {
                'id': res.body['id'],
                'name': res.body['name'],
                'edge': res.body['type'] == 3,
                'sync': res.body['waitForSync'],
                'status': self._status(res.body['status']),
                'compact': res.body['doCompact'],
                'system': res.body['isSystem'],
                'volatile': res.body['isVolatile'],
                'journal_size': res.body['journalSize'],
                'keygen': res.body['keyOptions']['type'],
                'user_keys': res.body['keyOptions']['allowUserKeys'],
                'key_increment': res.body['keyOptions'].get('increment'),
                'key_offset': res.body['keyOptions'].get('offset')
            }
            return result

        return request, handler
示例#3
0
    def server_role(self) -> Result[str]:
        """Return the server role.

        :return: Server role. Possible values are "SINGLE" (server which is
            not in a cluster), "COORDINATOR" (cluster coordinator), "PRIMARY",
            "SECONDARY", "AGENT" (Agency server in a cluster) or "UNDEFINED".
        :rtype: str
        :raise arango.exceptions.ClusterServerRoleError: If retrieval fails.
        """
        request = Request(method="get", endpoint="/_admin/server/role")

        def response_handler(resp: Response) -> str:
            if resp.is_success:
                return str(resp.body["role"])
            raise ClusterServerRoleError(resp, request)

        return self._execute(request, response_handler)
示例#4
0
    def kill(self, query_id: str) -> Result[bool]:
        """Kill a running query.

        :param query_id: Query ID.
        :type query_id: str
        :return: True if kill request was sent successfully.
        :rtype: bool
        :raise arango.exceptions.AQLQueryKillError: If the send fails.
        """
        request = Request(method="delete", endpoint=f"/_api/query/{query_id}")

        def response_handler(resp: Response) -> bool:
            if not resp.is_success:
                raise AQLQueryKillError(resp, request)
            return True

        return self._execute(request, response_handler)
示例#5
0
    def server_role(self):
        """Return the server role.

        :return: Server role. Possible values are "SINGLE" (server which is
            not in a cluster), "COORDINATOR" (cluster coordinator), "PRIMARY",
            "SECONDARY", "AGENT" (Agency node in a cluster) or "UNDEFINED".
        :rtype: str | unicode
        :raise arango.exceptions.ClusterServerRoleError: If retrieval fails.
        """
        request = Request(method='get', endpoint='/_admin/server/role')

        def response_handler(resp):
            if resp.is_success:
                return resp.body['role']
            raise ClusterServerRoleError(resp, request)

        return self._execute(request, response_handler)
示例#6
0
    def properties(self):
        """Return the properties of the query cache.

        :returns: the cache properties
        :rtype: dict
        :raises arango.exceptions.AQLCachePropertiesError: if the cache
            properties cannot be retrieved
        """
        request = Request(method='get',
                          endpoint='/_api/query-cache/properties')

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise AQLCachePropertiesError(res)
            return {'mode': res.body['mode'], 'limit': res.body['maxResults']}

        return request, handler
示例#7
0
    def ping(self):
        """Ping the next host to check if connection is established.

        :return: Response status code.
        :rtype: int
        """
        request = Request(
            method='get',
            endpoint='/_api/collection'
        )
        resp = self.send_request(request)
        if resp.status_code in {401, 403}:
            raise ServerConnectionError('bad username and/or password')
        if not resp.is_success:  # pragma: no cover
            raise ServerConnectionError(
                resp.error_message or 'bad server response')
        return resp.status_code
示例#8
0
    def fetch(self):
        """Fetch the next batch from server and update the cursor.

        :return: New batch details.
        :rtype: dict
        :raise arango.exceptions.CursorNextError: If batch retrieval fails.
        :raise arango.exceptions.CursorStateError: If cursor ID is not set.
        """
        if self._id is None:
            raise CursorStateError('cursor ID not set')
        request = Request(method='put',
                          endpoint='/_api/{}/{}'.format(self._type, self._id))
        resp = self._conn.send_request(request)

        if not resp.is_success:
            raise CursorNextError(resp, request)
        return self._update(resp.body)
示例#9
0
    def server_count(self) -> Result[int]:
        """Return the number of servers in the cluster.

        :return: Number of servers in the cluster.
        :rtype: int
        :raise arango.exceptions.ClusterServerCountError: If retrieval fails.
        """
        request = Request(method="get",
                          endpoint="/_admin/cluster/numberOfServers")

        def response_handler(resp: Response) -> int:
            if resp.is_success:
                result: int = resp.body
                return result
            raise ClusterServerCountError(resp, request)

        return self._execute(request, response_handler)
示例#10
0
    def create_service_with_file(self,
                                 mount,
                                 filename,
                                 development=None,
                                 setup=None,
                                 legacy=None):
        """Install a new service using a javascript file or zip bundle.

        :param mount: Service mount path (e.g "/_admin/aardvark").
        :type mount: str | unicode
        :param filename: Full path to the javascript file or zip bundle.
        :type filename: str | unicode
        :param development: Enable development mode.
        :type development: bool
        :param setup: Run service setup script.
        :type setup: bool
        :param legacy: Install the service in 2.8 legacy compatibility mode.
        :type legacy: bool
        :return: Service metadata.
        :rtype: dict
        :raise arango.exceptions.FoxxServiceCreateError: If install fails.
        """
        params = {'mount': mount}
        if development is not None:
            params['development'] = development
        if setup is not None:
            params['setup'] = setup
        if legacy is not None:
            params['legacy'] = legacy

        data = self._encode_file(filename)
        request = Request(
            method='post',
            endpoint='/_api/foxx',
            params=params,
            data=data,
            headers={'content-type': data.content_type}
        )

        def response_handler(resp):
            if not resp.is_success:
                raise FoxxServiceCreateError(resp, request)
            return resp.body

        return self._execute(request, response_handler)
示例#11
0
    def replace(self, document, sync=None):
        """Replace a document by its key in the edge collection.

        The ``"_key"``, ``"_from"`` and ``"_to"`` fields must be present in
        **document**. If the ``"_rev"`` field is present in **document**, its
        value is compared against the revision of the target document.

        :param document: the new document
        :type document: dict
        :param sync: wait for the operation to sync to disk
        :type sync: bool | None
        :returns: the ID, revision and key of the replaced document
        :rtype: dict
        :raises arango.exceptions.DocumentRevisionError: if the given revision
            does not match the revision of the target document
        :raises arango.exceptions.DocumentReplaceError: if the document cannot
            be replaced        """
        headers, params = {}, {}
        if sync is not None:
            params['waitForSync'] = sync

        revision = document.get('_rev')
        if revision is not None:
            headers['If-Match'] = revision

        request = Request(
            method='put',
            endpoint='/_api/gharial/{}/edge/{}/{}'.format(
                self._graph_name, self._name, document['_key']
            ),
            data=document,
            params=params,
            headers=headers
        )

        def handler(res):
            if res.status_code == 412:
                raise DocumentRevisionError(res)
            elif res.status_code not in HTTP_OK:
                raise DocumentReplaceError(res)
            edge = res.body["edge"]
            edge['_old_rev'] = edge.pop('_oldRev')
            return edge

        return request, handler
示例#12
0
    def create_edge_definition(
        self,
        edge_collection: str,
        from_vertex_collections: Sequence[str],
        to_vertex_collections: Sequence[str],
    ) -> Result[EdgeCollection]:
        """Create a new edge definition.

        An edge definition consists of an edge collection, "from" vertex
        collection(s) and "to" vertex collection(s). Here is an example entry:

        .. code-block:: python

            {
                'edge_collection': 'edge_collection_name',
                'from_vertex_collections': ['from_vertex_collection_name'],
                'to_vertex_collections': ['to_vertex_collection_name']
            }

        :param edge_collection: Edge collection name.
        :type edge_collection: str
        :param from_vertex_collections: Names of "from" vertex collections.
        :type from_vertex_collections: [str]
        :param to_vertex_collections: Names of "to" vertex collections.
        :type to_vertex_collections: [str]
        :return: Edge collection API wrapper.
        :rtype: arango.collection.EdgeCollection
        :raise arango.exceptions.EdgeDefinitionCreateError: If create fails.
        """
        request = Request(
            method="post",
            endpoint=f"/_api/gharial/{self._name}/edge",
            data={
                "collection": edge_collection,
                "from": from_vertex_collections,
                "to": to_vertex_collections,
            },
        )

        def response_handler(resp: Response) -> EdgeCollection:
            if resp.is_success:
                return self.edge_collection(edge_collection)
            raise EdgeDefinitionCreateError(resp, request)

        return self._execute(request, response_handler)
示例#13
0
    def refresh_token(self) -> None:
        """Get a new JWT token for the current user (cannot be a superuser).

        :return: JWT token.
        :rtype: str
        """
        request = Request(
            method="post",
            endpoint="/_open/auth",
            data={
                "username": self._username,
                "password": self._password
            },
        )

        host_index = self._host_resolver.get_host_index()

        resp = self._http.send_request(
            session=self._sessions[host_index],
            method=request.method,
            url=self._url_prefixes[host_index] + request.endpoint,
            data=self.normalize_data(request.data),
        )
        resp = self.prep_response(resp)

        if not resp.is_success:
            raise JWTAuthError(resp, request)

        self._token = resp.body["jwt"]
        assert self._token is not None

        jwt_payload = jwt.decode(
            self._token,
            issuer="arangodb",
            algorithms=["HS256"],
            options={
                "require_exp": True,
                "require_iat": True,
                "verify_iat": True,
                "verify_exp": True,
                "verify_signature": False,
            },
        )
        self._token_exp = jwt_payload["exp"]
        self._auth_header = f"bearer {self._token}"
示例#14
0
    def clear_slow_queries(self):
        """Clear slow AQL queries.

        :return: True if slow queries were cleared successfully.
        :rtype: bool
        :raise arango.exceptions.AQLQueryClearError: If operation fails.
        """
        request = Request(
            method='delete',
            endpoint='/_api/query/slow'
        )

        def response_handler(resp):
            if not resp.is_success:
                raise AQLQueryClearError(resp, request)
            return True

        return self._execute(request, response_handler)
示例#15
0
    def vertex_collections(self) -> Result[List[str]]:
        """Return vertex collections in the graph that are not orphaned.

        :return: Names of vertex collections that are not orphaned.
        :rtype: [str]
        :raise arango.exceptions.VertexCollectionListError: If retrieval fails.
        """
        request = Request(
            method="get",
            endpoint=f"/_api/gharial/{self._name}/vertex",
        )

        def response_handler(resp: Response) -> List[str]:
            if not resp.is_success:
                raise VertexCollectionListError(resp, request)
            return sorted(set(resp.body["collections"]))

        return self._execute(request, response_handler)
示例#16
0
    def server_id(self) -> Result[str]:
        """Return this server's ID.

        :return: Server ID.
        :rtype: str
        :raise arango.exceptions.ReplicationServerIDError: If retrieval fails.
        """
        request = Request(
            method="get",
            endpoint="/_api/replication/server-id",
        )

        def response_handler(resp: Response) -> str:
            if resp.is_success:
                return str(resp.body["serverId"])
            raise ReplicationServerIDError(resp, request)

        return self._execute(request, response_handler)
示例#17
0
    def stop_applier(self) -> Result[Json]:
        """Stop the replication applier.

        :return: Applier state and details.
        :rtype: dict
        :raise arango.exceptions.ReplicationApplierStopError: If operation fails.
        """
        request = Request(
            method="put",
            endpoint="/_api/replication/applier-stop",
        )

        def response_handler(resp: Response) -> Json:
            if resp.is_success:
                return format_replication_applier_state(resp.body)
            raise ReplicationApplierStopError(resp, request)

        return self._execute(request, response_handler)
示例#18
0
    def applier_state(self) -> Result[Json]:
        """Return the state of the replication applier

        :return: Applier state and details.
        :rtype: dict
        :raise arango.exceptions.ReplicationApplierStateError: If retrieval fails.
        """
        request = Request(
            method="get",
            endpoint="/_api/replication/applier-state",
        )

        def response_handler(resp: Response) -> Json:
            if resp.is_success:
                return format_replication_applier_state(resp.body)
            raise ReplicationApplierStateError(resp, request)

        return self._execute(request, response_handler)
示例#19
0
    def logger_first_tick(self) -> Result[str]:
        """Return the first available tick value from the server.

        :return: First tick value.
        :rtype: str
        :raise arango.exceptions.ReplicationLoggerFirstTickError: If retrieval fails.
        """
        request = Request(
            method="get",
            endpoint="/_api/replication/logger-first-tick",
        )

        def response_handler(resp: Response) -> str:
            if resp.is_success:
                return str(resp.body["firstTick"])
            raise ReplicationLoggerFirstTickError(resp, request)

        return self._execute(request, response_handler)
示例#20
0
    def vertex_collections(self):
        """Return the vertex collections of the graph.

        :returns: the names of the vertex collections
        :rtype: list
        :raises arango.exceptions.VertexCollectionListError: if the list of
            vertex collections cannot be retrieved
        """
        request = Request(method='get',
                          endpoint='/_api/gharial/{}/vertex'.format(
                              self._name))

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise VertexCollectionListError(res)
            return res.body['collections']

        return request, handler
示例#21
0
    def clear(self):
        """Clear the query cache.

        :return: True if query cache was cleared successfully.
        :rtype: bool
        :raise arango.exceptions.AQLCacheClearError: If operation fails.
        """
        request = Request(
            method='delete',
            endpoint='/_api/query-cache'
        )

        def response_handler(resp):
            if not resp.is_success:
                raise AQLCacheClearError(resp, request)
            return True

        return self._execute(request, response_handler)
示例#22
0
    def entries(self):
        """Return the query cache entries.

        :return: Query cache entries.
        :rtype: list
        :raise AQLCacheEntriesError: If retrieval fails.
        """
        request = Request(
            method='get',
            endpoint='/_api/query-cache/entries'
        )

        def response_handler(resp):
            if not resp.is_success:
                raise AQLCacheEntriesError(resp, request)
            return resp.body

        return self._execute(request, response_handler)
示例#23
0
    def random(self):
        """Return a random document from the collection.

        :returns: a random document
        :rtype: dict
        :raises arango.exceptions.DocumentGetError: if the document cannot
            be fetched from the collection
        """
        request = Request(method='put',
                          endpoint='/_api/simple/any',
                          data={'collection': self._name})

        def handler(res):
            if res.status_code not in HTTP_OK:
                raise DocumentGetError(res)
            return res.body['document']

        return request, handler
示例#24
0
    def server_id(self):
        """Return this server's ID.

        :return: Server ID.
        :rtype: str
        :raise arango.exceptions.ReplicationServerIDError: If retrieval fails.
        """
        request = Request(
            method='get',
            endpoint='/_api/replication/server-id',
        )

        def response_handler(resp):
            if resp.is_success:
                return resp.body['serverId']
            raise ReplicationServerIDError(resp, request)

        return self._execute(request, response_handler)
示例#25
0
    def delete_job(self, job_id):
        """Delete a Pregel job.

        :param job_id: Pregel job ID.
        :type job_id: int
        :return: True if Pregel job was deleted successfully.
        :rtype: bool
        :raise arango.exceptions.PregelJobDeleteError: If delete fails.
        """
        request = Request(method='delete',
                          endpoint='/_api/control_pregel/{}'.format(job_id))

        def response_handler(resp):
            if resp.is_success:
                return True
            raise PregelJobDeleteError(resp, request)

        return self._execute(request, response_handler)
示例#26
0
    def slow_queries(self):
        """Return a list of all slow AQL queries.

        :return: Slow AQL queries.
        :rtype: [dict]
        :raise arango.exceptions.AQLQueryListError: If retrieval fails.
        """
        request = Request(
            method='get',
            endpoint='/_api/query/slow'
        )

        def response_handler(resp):
            if not resp.is_success:
                raise AQLQueryListError(resp, request)
            return [format_aql_query(q) for q in resp.body]

        return self._execute(request, response_handler)
示例#27
0
    def kill(self, query_id):
        """Kill a running query.

        :param query_id: Query ID.
        :type query_id: str | unicode
        :return: True if kill request was sent successfully.
        :rtype: bool
        :raise arango.exceptions.AQLQueryKillError: If the send fails.
        """
        request = Request(method='delete',
                          endpoint='/_api/query/{}'.format(query_id))

        def response_handler(resp):
            if not resp.is_success:
                raise AQLQueryKillError(resp, request)
            return True

        return self._execute(request, response_handler)
示例#28
0
    def tracking(self):
        """Return AQL query tracking properties.

        :return: AQL query tracking properties.
        :rtype: dict
        :raise arango.exceptions.AQLQueryTrackingGetError: If retrieval fails.
        """
        request = Request(
            method='get',
            endpoint='/_api/query/properties'
        )

        def response_handler(resp):
            if not resp.is_success:
                raise AQLQueryTrackingGetError(resp, request)
            return format_aql_tracking(resp.body)

        return self._execute(request, response_handler)
示例#29
0
    def vertex_collections(self):
        """Return vertex collections in the graph that are not orphaned.

        :return: Names of vertex collections that are not orphaned.
        :rtype: [str | unicode]
        :raise arango.exceptions.VertexCollectionListError: If retrieval fails.
        """
        request = Request(
            method='get',
            endpoint='/_api/gharial/{}/vertex'.format(self._name),
        )

        def response_handler(resp):
            if not resp.is_success:
                raise VertexCollectionListError(resp, request)
            return sorted(set(resp.body['collections']))

        return self._execute(request, response_handler)
示例#30
0
    def properties(self):
        """Return the query cache properties.

        :return: Query cache properties.
        :rtype: dict
        :raise arango.exceptions.AQLCachePropertiesError: If retrieval fails.
        """
        request = Request(
            method='get',
            endpoint='/_api/query-cache/properties'
        )

        def response_handler(resp):
            if not resp.is_success:
                raise AQLCachePropertiesError(resp, request)
            return format_aql_cache(resp.body)

        return self._execute(request, response_handler)