diff --git a/swh/graphql/app.py b/swh/graphql/app.py index a4375aa..d6b19fc 100644 --- a/swh/graphql/app.py +++ b/swh/graphql/app.py @@ -1,10 +1,12 @@ from ariadne import load_schema_from_path, make_executable_schema, gql from ariadne.asgi import GraphQL from .resolvers import origin, query type_defs = gql(load_schema_from_path("swh/graphql/schema/schema.graphql")) -schema = make_executable_schema(type_defs, query, origin.origin, origin.origins) +schema = make_executable_schema( + type_defs, query, origin.origin, origin.origins, origin.visit +) app = GraphQL(schema, debug=True) diff --git a/swh/graphql/backends/archive.py b/swh/graphql/backends/archive.py index 36a89b7..4e5883a 100644 --- a/swh/graphql/backends/archive.py +++ b/swh/graphql/backends/archive.py @@ -1,12 +1,18 @@ from swh.storage import get_storage class Archive: def __init__(self): self.storage = get_storage( cls="remote", url="http://moma.internal.softwareheritage.org:5002" ) + def get_origin(self, url): + return self.storage.origin_get([url])[0] + def get_origins(self, after=None, first=50): # change page_token to base64 encode return self.storage.origin_list(page_token=after, limit=first) + + def get_origin_visits(self, origin, after=None, first=50): + return self.storage.origin_visit_get(origin, page_token=after, limit=first) diff --git a/swh/graphql/resolvers/base_connection.py b/swh/graphql/resolvers/base_connection.py index dd7dc30..6806588 100644 --- a/swh/graphql/resolvers/base_connection.py +++ b/swh/graphql/resolvers/base_connection.py @@ -1,38 +1,37 @@ """ """ # from dataclasses import dataclass # class PageInfo: # """ # dataclass # """ # class Arguments: # """ # dataclass # """ # after # Elements that come after the specified cursor # first # Returns the first n elements class BaseConnection: - - # @property - # def edges(self): - # pass + @property + def edges(self): + pass @property def nodes(self): pass @property def page_info(self): return { "hasNextPage": True, "endCursor": "", } @property def total_count(self): - return None + return 0 diff --git a/swh/graphql/resolvers/origin.py b/swh/graphql/resolvers/origin.py index 2de74f8..8bef18a 100644 --- a/swh/graphql/resolvers/origin.py +++ b/swh/graphql/resolvers/origin.py @@ -1,71 +1,76 @@ from ariadne import ObjectType from . import query from swh.graphql.backends import archive origin = ObjectType("Origin") origins = ObjectType("OriginConnection") +visit = ObjectType("Visit") + @query.field("origin") def resolve_origin(_, info, **kw): """ Top level query Get the origin matching the URL """ # return BaseNode.factory('origin').get(filters) - return archive.Archive().get_origins().results[0] + return archive.Archive().get_origin(kw["url"]) -@origin.field("url") -def origin_url(origin, info): - return origin.url +# @origin.field("url") +# def origin_url(origin, info): +# return origin.url @origin.field("id") def origin_id(origin, info): return origin.id.hex() @query.field("origins") def resolve_origins(_, info, **kw): """ Top level query Get all the origins matching the criteria """ # return BaseList.factory('origin').get(filters, state) origins = archive.Archive().get_origins( after=kw.get("after"), first=kw.get("first") ) - return origins - - -@origins.field("nodes") -def origin_nodes(origins, info, **kw): - return origins.results + # return results - -@origins.field("pageInfo") -def origin_pageinfo(origins, info, **kw): return { - "hasNextPage": bool(origins.next_page_token), - "endCursor": origins.next_page_token, + "nodes": origins.results, + "pageInfo": { + "hasNextPage": bool(origins.next_page_token), + "endCursor": origins.next_page_token, + }, } @origin.field("visits") def resolve_origin_visits(origin, info, **kw): + visits = archive.Archive().get_origin_visits( + origin.url, after=kw.get("after"), first=kw.get("first") + ) return { - "nodes": [ - { - "id": "1", - "status": "success" - }, - { - "id": "2", - "status": "success" - } - ] + "nodes": visits.results, + "pageInfo": { + "hasNextPage": bool(visits.next_page_token), + "endCursor": visits.next_page_token, + }, } + + +@visit.field("status") +def visit_status(visit, info): + return str(visit.visit) + + +@visit.field("date") +def visit_date(visit, info): + return visit.date.timestamp() diff --git a/swh/graphql/resolvers/resolvers.py b/swh/graphql/resolvers/resolvers.py new file mode 100644 index 0000000..63433e7 --- /dev/null +++ b/swh/graphql/resolvers/resolvers.py @@ -0,0 +1,40 @@ +from ariadne import ObjectType + + +def resolver_node_factory(resolver_type): + mapping = {"origin": "", "visit": ""} + return mapping[resolver_type]() + + +def resolver_list_factory(resolver_type): + mapping = { + "origins": "", + "visits": "", + } + return mapping[resolver_type]() + + +query = ObjectType("Query") + +# Nodes + + +@query.origin +def origin(): + return resolver_node_factory("origin",) + + +# Connections + + +@query.origins +def origins(): + return resolver_list_factory("origin",) + + +# @origin.visits +# def visits(): +# pass + + +# Other diff --git a/swh/graphql/schema/schema.graphql b/swh/graphql/schema/schema.graphql index 8dfa820..17a63d0 100644 --- a/swh/graphql/schema/schema.graphql +++ b/swh/graphql/schema/schema.graphql @@ -1,71 +1,68 @@ interface Node { id: ID! } -# interface SwhNode { -# swhid: String! -# } - scalar Date type PageInfo { endCursor: String hasNextPage: Boolean! } type Origin implements Node { url: String! id: ID! visits( first: Int after: String ): VisitConnection! } type OriginEdge { cursor: String! node: [Origin] } type OriginConnection { edges: [OriginEdge] nodes: [Origin] pageInfo: PageInfo! totalCount: Int } type Visit implements Node { id: ID! date: Date status: String + origin: Origin! } type VisitEdge { cursor: String! node: [Visit] } type VisitConnection { edges: [VisitEdge] nodes: [Visit] pageInfo: PageInfo! totalCount: Int } type Query { """ Get an origin with its url """ origin( url: String! ): Origin """ Get a list of origins matching the given filters """ origins( first: Int after: String ): OriginConnection! }