Skip to content

Instantly share code, notes, and snippets.

@syrusakbary
Created June 25, 2025 09:50
Show Gist options
  • Save syrusakbary/229d90362e00caf56dc77b91e3ded28a to your computer and use it in GitHub Desktop.
Save syrusakbary/229d90362e00caf56dc77b91e3ded28a to your computer and use it in GitHub Desktop.
from typing import Optional, Union
from graphql.language import DocumentNode, Location, OperationType, Source, Token, parse
from graphql.language.ast import Node
class GraphQLDocument:
source: Source
locations: list[Location]
tokens: list[Token]
def __init__(
self,
source: Union[Source, str],
document: Optional[DocumentNode] = None,
locations: Optional[list[Location]] = None,
tokens: Optional[list[Token]] = None,
):
if isinstance(source, str):
source = Source(source)
if document is None:
document = parse(source)
self.source = source
self.document = document
self.prefix = ""
self.locations = locations or []
self.tokens = tokens or []
def use_source(self) -> str:
return "source"
def use_location(self, loc: Location) -> str:
if loc not in self.locations:
self.locations.append(loc)
self.use_token(loc.start_token)
self.use_token(loc.end_token)
location_index = len(self.locations) - 1
else:
location_index = self.locations.index(loc)
return f"locations[{location_index}]"
def use_token(self, token: Token) -> str:
if token not in self.tokens:
self.tokens.append(token)
token_index = len(self.tokens) - 1
else:
token_index = self.tokens.index(token)
return f"tokens[{token_index}]"
def to_code(self) -> str:
ident = ",\n "
# Important, this must go before tokens and locations, so those are computed properly
document_repr = self.ast_to_code(self.document)
return f"""
from graphql.language import Source, TokenKind
from graphql.language.ast import *
def get_document():
source = Source({self.source.body!r})
tokens = [
{ident.join([self.token_to_code(token) for token in self.tokens])}
]
locations = [
{ident.join([self.loc_to_code(loc) for loc in self.locations])}
]
document = {document_repr}
return source, tokens, locations, document
"""
@staticmethod
def from_code(code: str) -> "GraphQLDocument":
out = {}
exec(code, out)
get_document = out["get_document"]
source, tokens, locations, document = get_document()
return GraphQLDocument(source=source, document=document, locations=locations, tokens=tokens)
# return GraphQLDocument(source = out['source'], locations = out['locations'], tokens = out['tokens'])
def __eq__(self, other: "GraphQLDocument") -> bool:
return (
self.source == other.source
and self.locations == other.locations
and self.tokens == other.tokens
)
def token_to_code(self, token: Token) -> str:
"""
Converts a token into a python code representation of the token.
"""
# prev = self.use_token(token.prev) if token.prev else repr(None)
return "{}Token({}{}, {}, {}, {}, {}, value={})".format(
self.prefix,
self.prefix,
token.kind,
token.start,
token.end,
token.line,
token.column,
repr(token.value),
)
def loc_to_code(self, loc: Location) -> str:
"""
Converts a location into a python code representation of the location.
"""
return "{}Location({}, {}, {})".format(
self.prefix,
self.use_token(loc.start_token),
self.use_token(loc.end_token),
self.use_source(),
)
def ast_to_code(
self,
ast: Union[Node, Location, list[Node], OperationType, int, str, float, bool],
indent: int = 0,
) -> str:
"""
Converts an ast into a python code representation of the AST.
"""
code = []
def append(line):
return code.append((" " * indent) + line)
if isinstance(ast, Node):
append(f"{self.prefix}{ast.__class__.__name__}(")
indent += 1
for i, k in enumerate(ast.keys, 1):
v = getattr(ast, k)
append(
"{}={},".format(
k,
self.ast_to_code(v, indent),
)
)
indent -= 1
append(")")
elif isinstance(ast, Location):
append(self.use_location(ast))
elif isinstance(ast, list):
if ast:
append("[")
indent += 1
for i, it in enumerate(ast, 1):
is_last = i == len(ast)
append(self.ast_to_code(it, indent) + ("," if not is_last else ""))
indent -= 1
append("]")
else:
append("[]")
elif ast is None or isinstance(ast, (int, str, float, bool)):
append(repr(ast))
elif isinstance(ast, OperationType):
append(f"{self.prefix}OperationType.{ast.name}")
else:
raise Exception(f"Unknown ast type: {type(ast)}")
return "\n".join(code).strip()
from graphql.language import Source, ast, parse
from .ast import GraphQLDocument
def test_source():
source = Source("query { a { b } }")
document = GraphQLDocument(source)
start_token1 = ast.Token(ast.TokenKind.NAME, 1, 1, 1, 1)
start_token2 = ast.Token(ast.TokenKind.NAME, 2, 2, 2, 2)
start_token3 = ast.Token(ast.TokenKind.NAME, 3, 3, 3, 3)
start_token4 = ast.Token(ast.TokenKind.NAME, 4, 4, 4, 4)
start_token5 = ast.Token(ast.TokenKind.NAME, 5, 5, 5, 5)
location_12 = ast.Location(start_token1, start_token2, source)
location_13 = ast.Location(start_token1, start_token3, source)
location_23 = ast.Location(start_token2, start_token3, source)
location_34 = ast.Location(start_token3, start_token4, source)
location_15 = ast.Location(start_token1, start_token5, source)
location_var: str = document.use_location(location_12)
assert location_var == "locations[0]"
assert len(document.locations) == 1
assert document.locations[0] == location_12
assert len(document.tokens) == 2
assert document.tokens[0] == start_token1
assert document.tokens[1] == start_token2
location_var: str = document.use_location(location_13)
assert len(document.locations) == 2
assert location_var == "locations[1]"
assert document.locations[1] == location_13
assert len(document.tokens) == 3
assert document.tokens[1] == start_token2
assert document.tokens[2] == start_token3
location_var: str = document.use_location(location_23)
assert len(document.locations) == 3
assert location_var == "locations[2]"
assert document.locations[2] == location_23
assert len(document.tokens) == 3
assert document.tokens[0] == start_token1
assert document.tokens[1] == start_token2
assert document.tokens[2] == start_token3
# Repeated location
location_var: str = document.use_location(location_23)
assert len(document.locations) == 3
assert location_var == "locations[2]"
assert document.locations[2] == location_23
assert len(document.tokens) == 3
assert document.tokens[0] == start_token1
assert document.tokens[1] == start_token2
assert document.tokens[2] == start_token3
location_var: str = document.use_location(location_34)
assert len(document.locations) == 4
assert location_var == "locations[3]"
assert document.locations[3] == location_34
assert len(document.tokens) == 4
assert document.tokens[0] == start_token1
assert document.tokens[1] == start_token2
assert document.tokens[2] == start_token3
assert document.tokens[3] == start_token4
location_var: str = document.use_location(location_15)
assert len(document.locations) == 5
assert location_var == "locations[4]"
assert document.locations[4] == location_15
assert len(document.tokens) == 5
assert document.tokens[0] == start_token1
assert document.tokens[1] == start_token2
assert document.tokens[2] == start_token3
assert document.tokens[3] == start_token4
assert document.tokens[4] == start_token5
def test_source_to_code():
source = Source("query { a { b } }")
document = GraphQLDocument(source)
code = document.to_code()
document2 = GraphQLDocument.from_code(code)
assert document.source == document2.source
assert document.locations == document2.locations
assert document.tokens == document2.tokens
assert document.document == document2.document
assert document == document2
def test_long_query_benchmark(benchmark):
document = GraphQLDocument(LONG_QUERY)
doc_code = document.to_code()
def get_document():
document.from_code(doc_code)
# assert document == document2
benchmark(get_document)
def test_long_query_benchmark_parse(benchmark):
def parse_document():
parse(LONG_QUERY)
benchmark(parse_document)
LONG_QUERY = """
query ownerQuery(
$owner: String!
$timeRange: TimeRangeInput
$appIds: [ID]
$appId: ID!
$tabOverview: Boolean!
$tabPkgs: Boolean!
$tabApps: Boolean!
$tabTeam: Boolean!
$tabSettings: Boolean!
$tabUsage: Boolean!
$tabSetGen: Boolean!
$tabSetCollabs: Boolean!
$tabAccToken: Boolean!
$tabBilling: Boolean!
) {
viewer {
globalName
...LayoutWrapper_data
...DashboardActivityViewer_data
...dashboardNamespaceIntentCardsFragment
...namespacesCommandDialog
id
}
owner: getGlobalObject(slug: $owner) {
__typename
... on User {
globalName
...dashboardUserNavigationHeaderOwner
...dashboardUserFragment
}
... on Namespace {
globalName
isAdmin: viewerHasRole(role: ADMIN)
isEditor: viewerHasRole(role: EDITOR)
...dashboardNamespaceNavigationHeaderOwner
...dashboardNamespaceFragment
}
... on Node {
__isNode: __typename
id
}
}
ownerUsage: getGlobalObject(slug: $owner) {
__typename
...UsageAppRateLimiterCalloutFragment
... on Node {
__isNode: __typename
id
}
}
...AppSelectorFragment_2CQkps @include(if: $tabUsage)
}
fragment AccessTokenSettings_viewer on User {
id
apiTokens {
edges {
node {
id
identifier
createdAt
lastUsedAt
revokedAt
}
}
}
}
fragment Account_SettingsAccount on User {
id
username
fullName
bio
avatar
email
isEmailValidated
githubUrl
twitterUrl
websiteUrl
location
packages {
edges {
node {
id
name
namespace
packageName
icon
}
}
}
}
fragment AppActivityCard_data on DeployApp {
id
activeVersion {
...AppRowCard_deployAppVersion
id
}
}
fragment AppActivityItem_data on ActivityEvent {
...DashboardActivityItemHeader_data
id
body {
text
ranges {
entity {
__typename
... on DeployApp {
id
...AppActivityCard_data
}
id
}
}
}
}
fragment AppRowCard_deployAppVersion on DeployAppVersion {
favicon
sourcePackage {
icon
name
packageName
owner {
__typename
globalName
... on Node {
__isNode: __typename
id
}
}
id
}
clientName
isActive
app {
name
owner {
__typename
globalName
... on Node {
__isNode: __typename
id
}
}
url
id
}
publishedBy {
avatar
fullName
username
id
}
url
screenshot
}
fragment AppSelectorFragment_2CQkps on Query {
selectedApp: node(id: $appId) {
__typename
... on DeployApp {
activeVersion {
app {
id
name
}
screenshot
id
}
}
id
}
search(query: "", first: 15, apps: {owner: $owner}) {
edges {
node {
__typename
... on DeployApp {
activeVersion {
app {
id
name
}
screenshot
id
}
}
... on Node {
__isNode: __typename
id
}
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
}
fragment AppVersionActivityCard_data on DeployAppVersion {
id
...AppRowCard_deployAppVersion
}
fragment AppVersionActivityItem_data on ActivityEvent {
...DashboardActivityItemHeader_data
id
body {
text
ranges {
entity {
__typename
... on DeployAppVersion {
id
...AppVersionActivityCard_data
}
id
}
}
}
}
fragment AuthenticatedNavbarUserAvatar_data on User {
username
avatar
}
fragment BillingPage_viewer on User {
id
username
email
isEmailValidated
isPro
billing {
paymentMethods {
__typename
... on CardPaymentMethod {
id
brand
country
expMonth
expYear
funding
last4
}
... on Node {
__isNode: __typename
id
}
}
payments {
amount
currency
status
id
}
}
}
fragment BlogPostActivityCard_data on BlogPost {
id
slug
title
tags {
id
name
}
coverImageUrl
}
fragment BlogPostActivityItem_data on ActivityEvent {
...DashboardActivityItemHeader_data
id
body {
text
ranges {
entity {
__typename
... on BlogPost {
id
...BlogPostActivityCard_data
}
id
}
}
}
}
fragment CollabRow_NamespaceCollaborator on NamespaceCollaborator {
id
createdAt
role
user {
userId: id
username
fullName
avatar
id
}
}
fragment CollabRow_NamespaceCollaboratorInvite on NamespaceCollaboratorInvite {
id
createdAt
role
user {
userId: id
username
fullName
avatar
id
}
}
fragment CollaboratorsInvits_NamespacesSettingsNamespace on Namespace {
id
nspPendingInvites: pendingInvites(first: 10) {
totalCount
edges {
node {
nodeType: __typename
id
...CollabRow_NamespaceCollaboratorInvite
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
}
fragment Collaborators_NamespacesSettingsNamespace on Namespace {
id
nspCollaborators: collaborators(first: 10) {
totalCount
edges {
node {
nodeType: __typename
id
...CollabRow_NamespaceCollaborator
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
}
fragment DashboardActivityItemHeader_data on ActivityEvent {
body {
...RenderRanges_data
}
id
actorIcon
createdAt
}
fragment DashboardActivityItem_data on ActivityEvent {
...DashboardActivityItemHeader_data
...PackageVersionActivityItem_data
...PackageActivityItem_data
...AppActivityItem_data
...AppVersionActivityItem_data
...BlogPostActivityItem_data
body {
text
ranges {
packageEntity: entity {
__typename
... on Package {
id
}
id
}
packageVersionEntity: entity {
__typename
... on PackageVersion {
id
}
id
}
blogPostEntity: entity {
__typename
... on BlogPost {
id
}
id
}
appEntity: entity {
__typename
... on DeployApp {
id
}
id
}
appVersionEntity: entity {
__typename
... on DeployAppVersion {
id
}
id
}
}
}
}
fragment DashboardActivityViewer_data on User {
registerIntent
firstName
username
}
fragment HeaderFragment on User {
globalName
...AuthenticatedNavbarUserAvatar_data
...NotificationMenu_fragment_User
}
fragment Intercom_viewer on User {
id
username
avatar
email
dateJoined
fullName
}
fragment LayoutWrapper_data on User {
id
fullName
email
avatar
...Intercom_viewer
...HeaderFragment
}
fragment NamespacesSettings_general on Namespace {
id
name
avatar
displayName
description
githubHandle
twitterHandle
websiteUrl
packages {
totalCount
edges {
node {
id
name
namespace
packageName
icon
}
}
}
}
fragment NotificationItemInvitCollabNsp_UserNotificationKindIncomingNamespaceInvite on UserNotification {
id
icon
seenState
createdAt
kind {
__typename
... on UserNotificationKindIncomingNamespaceInvite {
namespaceInvite {
id
createdAt
declinedBy {
globalName
avatar
id
}
approvedBy {
globalName
avatar
id
}
requestedBy {
globalName
avatar
id
}
namespace {
globalId
globalName
displayName
avatar
id
}
}
}
}
}
fragment NotificationItemInvitCollabPkg_UserNotificationKindIncomingPackageInvite on UserNotification {
id
icon
seenState
createdAt
kind {
__typename
... on UserNotificationKindIncomingPackageInvite {
packageInvite {
id
createdAt
declinedBy {
globalName
avatar
id
}
approvedBy {
globalName
avatar
id
}
requestedBy {
globalName
avatar
id
}
package {
owner {
__typename
globalName
... on Node {
__isNode: __typename
id
}
}
packageName
icon
id
}
}
}
}
}
fragment NotificationItemReqTransfertPkg_UserNotificationKindIncomingPackageInvite on UserNotification {
id
icon
seenState
createdAt
kind {
__typename
... on UserNotificationKindIncomingPackageTransfer {
packageTransferRequest {
id
createdAt
declinedBy {
globalName
avatar
id
}
approvedBy {
globalName
avatar
id
}
requestedBy {
globalName
avatar
id
}
package {
owner {
__typename
globalName
... on Node {
__isNode: __typename
id
}
}
packageName
icon
id
}
}
}
}
}
fragment NotificationItemValidateEmail_UserNotificationKindValidateEmail on UserNotification {
id
icon
seenState
createdAt
kind {
__typename
... on UserNotificationKindValidateEmail {
user {
id
username
fullName
avatar
isEmailValidated
}
}
}
}
fragment NotificationMenuItem_UserNotification on UserNotification {
id
body {
...RenderRanges_data
text
ranges {
entity {
__typename
...RenderRangesEntity
... on User {
id
avatar
}
id
}
offset
length
}
}
icon
seenState
createdAt
...NotificationItemInvitCollabNsp_UserNotificationKindIncomingNamespaceInvite
...NotificationItemInvitCollabPkg_UserNotificationKindIncomingPackageInvite
...NotificationItemReqTransfertPkg_UserNotificationKindIncomingPackageInvite
...NotificationItemValidateEmail_UserNotificationKindValidateEmail
kind {
__typename
... on UserNotificationKindIncomingPackageTransfer {
__typename
}
... on UserNotificationKindIncomingPackageInvite {
__typename
}
... on UserNotificationKindIncomingNamespaceInvite {
__typename
}
... on UserNotificationKindValidateEmail {
__typename
}
}
}
fragment NotificationMenu_fragment_User on User {
id
notifications(first: 4) {
hasPendingNotifications
edges {
node {
id
...NotificationMenuItem_UserNotification
seenState
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
}
fragment PackageActivityCard_data on Package {
id
lastVersion {
...PackageCard_data
id
}
}
fragment PackageActivityItem_data on ActivityEvent {
...DashboardActivityItemHeader_data
id
body {
text
ranges {
entity {
__typename
... on Package {
id
...PackageActivityCard_data
}
id
}
}
}
}
fragment PackageCard_data on PackageVersion {
typeResult: __typename
description
package {
id
icon
packageName
likersCount
viewerHasLiked
showDeployButton
owner {
__typename
globalName
... on Node {
__isNode: __typename
id
}
}
collaborators {
totalCount
edges {
node {
id
user {
avatar
username
fullName
id
}
}
}
}
}
}
fragment PackageVersionActivityCard_data on PackageVersion {
id
...PackageCard_data
}
fragment PackageVersionActivityItem_data on ActivityEvent {
...DashboardActivityItemHeader_data
id
body {
text
ranges {
entity {
__typename
... on PackageVersion {
id
...PackageVersionActivityCard_data
}
id
}
}
}
}
fragment RenderRangesEntity on Node {
__isNode: __typename
__typename
id
... on User {
username
}
... on Package {
id
name
likersCount
downloadsCount
packageName
owner {
__typename
globalName
... on Node {
__isNode: __typename
id
}
}
watchersCount
viewerHasLiked
viewerIsWatching
}
... on PackageVersion {
id
version
package {
id
icon
name
packageName
owner {
__typename
globalName
... on Node {
__isNode: __typename
id
}
}
likersCount
downloadsCount
watchersCount
viewerHasLiked
viewerIsWatching
}
}
... on Namespace {
globalName
}
... on BlogPost {
slug
}
... on DeployApp {
name
owner {
__typename
globalName
... on Node {
__isNode: __typename
id
}
}
}
}
fragment RenderRanges_data on EventBody {
text
ranges {
entity {
__typename
...RenderRangesEntity
id
}
offset
length
}
}
fragment UsageAppRateLimiterCalloutFragment on Owner {
__isOwner: __typename
__typename
... on User {
limitState
probationStartedAt
currentUsage {
cpuTime {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
noRequests {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
ingress {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
egress {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
}
}
... on Namespace {
limitState
probationStartedAt
currentUsage {
cpuTime {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
noRequests {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
ingress {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
egress {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
}
}
}
fragment dashboardNamespaceAppsFragment on Namespace {
apps(first: 5, sortBy: NEWEST) {
totalCount
edges {
node {
id
activeVersion {
...AppRowCard_deployAppVersion
id
}
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
id
}
fragment dashboardNamespaceFragment on Namespace {
isAdmin: viewerHasRole(role: ADMIN)
...dashboardNamespaceHeaderFragment
...dashboardNamespaceNavigationFragment
...dashboardNamespaceOverviewFragment @include(if: $tabOverview)
...dashboardNamespaceAppsFragment @include(if: $tabApps)
...dashboardNamespacePackagesFragment @include(if: $tabPkgs)
...dashboardNamespaceTeamFragment @include(if: $tabTeam)
...dashboardNamespaceSettingsFragment @include(if: $tabSettings)
...dashboardNamespaceUsageFragment_1LoqyQ @include(if: $tabUsage)
...dashboardNamespaceInvitationsFragment
}
fragment dashboardNamespaceHeaderFragment on Namespace {
globalName
avatar
displayName
description
twitterHandle
githubHandle
websiteUrl
collaborators {
totalCount
edges {
node {
user {
id
avatar
username
}
id
}
}
}
}
fragment dashboardNamespaceIntentCardsFragment on User {
...dashboardNamespaceOverviewIntentCardsFragment
}
fragment dashboardNamespaceInvitationsFragment on Namespace {
globalName
avatar
viewerIsInvited
viewerInvitation {
id
requestedBy {
id
fullName
username
}
}
}
fragment dashboardNamespaceNavigationFragment on Namespace {
globalName
isAdmin: viewerHasRole(role: ADMIN)
}
fragment dashboardNamespaceNavigationHeaderOwner on Namespace {
globalName
avatar
}
fragment dashboardNamespaceOverviewActivityFragment on Namespace {
activity: publicActivity(first: 6) {
edges {
node {
id
...DashboardActivityItem_data
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
id
}
fragment dashboardNamespaceOverviewAppsFragment on Namespace {
globalName
newestApps: apps(first: 5, sortBy: NEWEST) {
totalCount
edges {
node {
activeVersion {
id
...AppRowCard_deployAppVersion
}
id
}
}
}
}
fragment dashboardNamespaceOverviewFragment on Namespace {
...dashboardNamespaceOverviewActivityFragment
...dashboardNamespaceOverviewAppsFragment
...dashboardNamespaceOverviewPackagesFragment
}
fragment dashboardNamespaceOverviewIntentCardsFragment on User {
isViewer
registerIntent
activeApps: apps(sortBy: MOST_ACTIVE) {
totalCount
}
}
fragment dashboardNamespaceOverviewPackagesFragment on Namespace {
globalName
popularPackages: packages(first: 5) {
totalCount
edges {
node {
id
lastVersion {
...PackageCard_data
id
}
}
}
}
}
fragment dashboardNamespacePackagesFragment on Namespace {
pkgVersions: packageVersions(first: 10) {
totalCount
edges {
node {
id
...PackageCard_data
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
id
}
fragment dashboardNamespaceSettingsFragment on Namespace {
globalName
avatar
displayName
...dashboardNamespaceSettingsNavigation
...NamespacesSettings_general @include(if: $tabSetGen)
...Collaborators_NamespacesSettingsNamespace @include(if: $tabSetCollabs)
...CollaboratorsInvits_NamespacesSettingsNamespace @include(if: $tabSetCollabs)
}
fragment dashboardNamespaceSettingsNavigation on Namespace {
globalName
}
fragment dashboardNamespaceTeamFragment on Namespace {
id
nspTeam: collaborators(first: 10) {
totalCount
edges {
node {
nodeType: __typename
id
...CollabRow_NamespaceCollaborator
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
}
fragment dashboardNamespaceUsageFragment_1LoqyQ on Namespace {
globalName
avatar
networkIngress: usageMetrics(timeRange: $timeRange, variant: network_ingress, appIds: $appIds, grouping: BY_DAY) {
value
unit
timestamp
}
networkEgress: usageMetrics(timeRange: $timeRange, variant: network_egress, appIds: $appIds, grouping: BY_DAY) {
value
unit
timestamp
}
cpuTime: usageMetrics(timeRange: $timeRange, variant: cpu_time, appIds: $appIds, grouping: BY_DAY) {
value
unit
timestamp
}
noRequests: usageMetrics(timeRange: $timeRange, variant: no_of_requests, appIds: $appIds, grouping: BY_DAY) {
value
unit
timestamp
}
noFailedRequests: usageMetrics(timeRange: $timeRange, variant: no_of_failed_requests, appIds: $appIds, grouping: BY_DAY) {
value
unit
timestamp
}
currentUsage(appIds: $appIds, timeRange: $timeRange) {
since
cpuTime {
used
usedPercent
max
unit
charge {
amount
currency
}
}
noRequests {
used
usedPercent
max
unit
charge {
amount
currency
}
}
ingress {
used
usedPercent
max
unit
charge {
amount
currency
}
}
egress {
used
usedPercent
max
unit
charge {
amount
currency
}
}
buildMinutes {
used
usedPercent
max
unit
charge {
amount
currency
}
}
appCount {
used
usedPercent
max
unit
charge {
amount
currency
}
}
}
id
}
fragment dashboardUserAppsFragment on User {
apps(first: 5, sortBy: NEWEST) {
totalCount
edges {
node {
id
activeVersion {
...AppRowCard_deployAppVersion
id
}
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
id
}
fragment dashboardUserFragment on User {
isViewer
canSeeApps: viewerCan(action: DEPLOY_APP)
...dashboardUserHeaderFragment
...dashboardUserNavigationFragment
...dashboardUserOverviewFragment @include(if: $tabOverview)
...dashboardUserAppsFragment @include(if: $tabApps)
...dashboardUserPackagesFragment @include(if: $tabPkgs)
...dashboardUserSettingsFragment @include(if: $tabSettings)
...dashboardUserUsageFragment_1LoqyQ @include(if: $tabUsage)
}
fragment dashboardUserHeaderFragment on User {
globalName
avatar
firstName
lastName
bio
fullName
githubUrl
twitterUrl
websiteUrl
}
fragment dashboardUserNavigationFragment on User {
globalName
isViewer
}
fragment dashboardUserNavigationHeaderOwner on User {
globalName
avatar
}
fragment dashboardUserOverviewActivityFragment on User {
activity: publicActivity(first: 6) {
edges {
node {
id
...DashboardActivityItem_data
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
id
}
fragment dashboardUserOverviewAppsFragment on User {
globalName
newestApps: apps(first: 5, sortBy: NEWEST) {
totalCount
edges {
node {
activeVersion {
id
...AppRowCard_deployAppVersion
}
id
}
}
}
}
fragment dashboardUserOverviewFragment on User {
isViewer
registerIntent
activeApps: apps(sortBy: MOST_ACTIVE) {
totalCount
}
...dashboardUserOverviewActivityFragment
...dashboardUserOverviewAppsFragment
...dashboardUserOverviewPackagesFragment
}
fragment dashboardUserOverviewPackagesFragment on User {
isViewer
globalName
popularPackages: packages(first: 5) {
totalCount
edges {
node {
id
lastVersion {
...PackageCard_data
id
}
}
}
}
}
fragment dashboardUserPackagesFragment on User {
isViewer
pkgVersions: packageVersions(first: 10) {
totalCount
edges {
node {
id
...PackageCard_data
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
id
}
fragment dashboardUserSettingsFragment on User {
globalName
avatar
...dashboardUserSettingsNavigation
...Account_SettingsAccount @include(if: $tabSetGen)
...AccessTokenSettings_viewer @include(if: $tabAccToken)
...BillingPage_viewer @include(if: $tabBilling)
}
fragment dashboardUserSettingsNavigation on User {
globalName
}
fragment dashboardUserUsageFragment_1LoqyQ on User {
globalName
avatar
networkIngress: usageMetrics(timeRange: $timeRange, variant: network_ingress, appIds: $appIds, grouping: BY_DAY) {
value
unit
timestamp
}
networkEgress: usageMetrics(timeRange: $timeRange, variant: network_egress, appIds: $appIds, grouping: BY_DAY) {
value
unit
timestamp
}
cpuTime: usageMetrics(timeRange: $timeRange, variant: cpu_time, appIds: $appIds, grouping: BY_DAY) {
value
unit
timestamp
}
noRequests: usageMetrics(timeRange: $timeRange, variant: no_of_requests, appIds: $appIds, grouping: BY_DAY) {
value
unit
timestamp
}
noFailedRequests: usageMetrics(timeRange: $timeRange, variant: no_of_failed_requests, appIds: $appIds, grouping: BY_DAY) {
value
unit
timestamp
}
currentUsage(appIds: $appIds, timeRange: $timeRange) {
cpuTime {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
noRequests {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
ingress {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
egress {
nearingLimits
used
usedPercent
max
unit
charge {
amount
currency
}
}
buildMinutes {
used
usedPercent
max
unit
charge {
amount
currency
}
}
appCount {
used
usedPercent
max
unit
charge {
amount
currency
}
}
}
id
}
fragment namespacesCommandDialog on User {
globalName
fullName
avatar
isPro
namespaces(first: 10) {
edges {
node {
id
avatar
displayName
globalName
description
isPro
__typename
}
cursor
}
pageInfo {
endCursor
hasNextPage
}
}
id
}
"""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment