Changeset View
Changeset View
Standalone View
Standalone View
swh/graphql/resolvers/resolvers.py
Show All 10 Lines | |||||
# and in the following priority order | # and in the following priority order | ||||
# - In this module using a decorator (eg: @visit_status.field("snapshot")) | # - In this module using a decorator (eg: @visit_status.field("snapshot")) | ||||
# Every object (type) is expected to resolve this way as they can accept arguments | # Every object (type) is expected to resolve this way as they can accept arguments | ||||
# eg: origin.visits takes arguments to paginate | # eg: origin.visits takes arguments to paginate | ||||
# - As a property in the Node object (eg: resolvers.visit.BaseVisitNode.id) | # - As a property in the Node object (eg: resolvers.visit.BaseVisitNode.id) | ||||
# Every scalar is expected to resolve this way | # Every scalar is expected to resolve this way | ||||
# - As an attribute/item in the object/dict returned by a backend (eg: Origin.url) | # - As an attribute/item in the object/dict returned by a backend (eg: Origin.url) | ||||
import datetime | |||||
from typing import Optional, Union | from typing import Optional, Union | ||||
from ariadne import ObjectType, UnionType | from ariadne import ObjectType, UnionType | ||||
from graphql.type import GraphQLResolveInfo | from graphql.type import GraphQLResolveInfo | ||||
from swh.graphql import resolvers as rs | from swh.graphql import resolvers as rs | ||||
from swh.graphql.utils import utils | from swh.graphql.utils import utils | ||||
from swh.model.model import TimestampWithTimezone | |||||
from .resolver_factory import ConnectionObjectFactory, NodeObjectFactory | from .resolver_factory import ConnectionObjectFactory, NodeObjectFactory | ||||
query: ObjectType = ObjectType("Query") | query: ObjectType = ObjectType("Query") | ||||
origin: ObjectType = ObjectType("Origin") | origin: ObjectType = ObjectType("Origin") | ||||
visit: ObjectType = ObjectType("Visit") | visit: ObjectType = ObjectType("Visit") | ||||
visit_status: ObjectType = ObjectType("VisitStatus") | visit_status: ObjectType = ObjectType("VisitStatus") | ||||
snapshot: ObjectType = ObjectType("Snapshot") | snapshot: ObjectType = ObjectType("Snapshot") | ||||
snapshot_branch: ObjectType = ObjectType("Branch") | snapshot_branch: ObjectType = ObjectType("Branch") | ||||
revision: ObjectType = ObjectType("Revision") | revision: ObjectType = ObjectType("Revision") | ||||
release: ObjectType = ObjectType("Release") | release: ObjectType = ObjectType("Release") | ||||
directory: ObjectType = ObjectType("Directory") | directory: ObjectType = ObjectType("Directory") | ||||
directory_entry: ObjectType = ObjectType("DirectoryEntry") | directory_entry: ObjectType = ObjectType("DirectoryEntry") | ||||
search_result: ObjectType = ObjectType("SearchResult") | search_result: ObjectType = ObjectType("SearchResult") | ||||
binary_string: ObjectType = ObjectType("BinaryString") | binary_string: ObjectType = ObjectType("BinaryString") | ||||
date: ObjectType = ObjectType("Date") | |||||
branch_target: UnionType = UnionType("BranchTarget") | branch_target: UnionType = UnionType("BranchTarget") | ||||
release_target: UnionType = UnionType("ReleaseTarget") | release_target: UnionType = UnionType("ReleaseTarget") | ||||
directory_entry_target: UnionType = UnionType("DirectoryEntryTarget") | directory_entry_target: UnionType = UnionType("DirectoryEntryTarget") | ||||
search_result_target: UnionType = UnionType("SearchResultTarget") | search_result_target: UnionType = UnionType("SearchResultTarget") | ||||
# Node resolvers | # Node resolvers | ||||
# A node resolver will return either an instance of a BaseNode subclass or None | # A node resolver will return either an instance of a BaseNode subclass or None | ||||
▲ Show 20 Lines • Show All 258 Lines • ▼ Show 20 Lines | |||||
@binary_string.field("text") | @binary_string.field("text") | ||||
def binary_string_text_resolver(obj: bytes, *args, **kw) -> str: | def binary_string_text_resolver(obj: bytes, *args, **kw) -> str: | ||||
return obj.decode(utils.ENCODING, "replace") | return obj.decode(utils.ENCODING, "replace") | ||||
@binary_string.field("base64") | @binary_string.field("base64") | ||||
def binary_string_base64_resolver(obj: bytes, *args, **kw) -> str: | def binary_string_base64_resolver(obj: bytes, *args, **kw) -> str: | ||||
return utils.get_b64_string(obj) | return utils.get_b64_string(obj) | ||||
@date.field("date") | |||||
def date_info_date_resolver( | |||||
obj: Optional[Union[datetime.datetime, TimestampWithTimezone]], | |||||
*args: GraphQLResolveInfo, | |||||
**kw, | |||||
) -> Optional[Union[datetime.datetime, TimestampWithTimezone]]: | |||||
if obj is not None: | |||||
# This will be serialised as a DateTime Scalar | |||||
return obj | |||||
return None | |||||
jayeshv: @vlorentz changed this to use a timestamp instead of seconds and microseconds. What do you… | |||||
Not Done Inline ActionsUsing floats loses precision for very high or low timestamps; but I guess that's fine vlorentz: Using floats loses precision for very high or low timestamps; but I guess that's fine | |||||
@date.field("timestamp") | |||||
def date_info_micro_seconds_resolver( | |||||
obj: Optional[TimestampWithTimezone], *args: GraphQLResolveInfo, **kw | |||||
) -> Optional[float]: | |||||
if obj is not None: | |||||
return obj.timestamp.seconds + (obj.timestamp.microseconds / (10**6)) | |||||
return None | |||||
@date.field("offset") | |||||
def date_info_offset_resolver( | |||||
obj: Optional[TimestampWithTimezone], *args: GraphQLResolveInfo, **kw | |||||
) -> Optional[bytes]: | |||||
if obj is not None: | |||||
return obj.offset_bytes | |||||
return None |
@vlorentz changed this to use a timestamp instead of seconds and microseconds. What do you think?