Skip to content
This repository was archived by the owner on Feb 6, 2025. It is now read-only.

Commit 4a0fe10

Browse files
pmantica1obi1kenobi
andcommitted
Add a function that computes the fingerprint of a schema (#737)
* Intermediate commit * Add a function that computes a schema fingerprint * Nits * Fix copyright line * Address comments * Add more tests * Assert that schema does not contain extensions and add more tests * Remove assertion * Update graphql_compiler/schema/__init__.py Co-Authored-By: Predrag Gruevski <[email protected]> * Specify that the fingerprint is a hexadecimal string Co-Authored-By: Predrag Gruevski <[email protected]> * Nit Co-Authored-By: Predrag Gruevski <[email protected]> * Address nits * Address comments * Address comments Co-authored-by: Predrag Gruevski <[email protected]>
1 parent 8a4d829 commit 4a0fe10

File tree

2 files changed

+671
-0
lines changed

2 files changed

+671
-0
lines changed

graphql_compiler/schema/__init__.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from collections import OrderedDict
33
from datetime import date, datetime
44
from decimal import Decimal
5+
from hashlib import sha256
56
from itertools import chain
67

78
import arrow
@@ -16,7 +17,10 @@
1617
GraphQLNonNull,
1718
GraphQLObjectType,
1819
GraphQLScalarType,
20+
GraphQLSchema,
1921
GraphQLString,
22+
lexicographic_sort_schema,
23+
print_schema,
2024
)
2125
from graphql.type.directives import specified_directives
2226
import six
@@ -447,3 +451,30 @@ def check_for_nondefault_directive_names(directives):
447451
raise AssertionError(
448452
u"Unsupported directives found: {}".format(nondefault_directives_found)
449453
)
454+
455+
456+
def compute_schema_fingerprint(schema: GraphQLSchema) -> str:
457+
"""Compute a fingerprint compactly representing the data in the given schema.
458+
459+
The fingerprint is not sensitive to things like type or field order. This function is guaranteed
460+
to be robust enough that if two GraphQLSchema have the same fingerprint, then they also
461+
represent the same schema.
462+
463+
Because of internal implementation changes, different versions of this library *may* produce
464+
different fingerprints for the same schema. Since cross-version fingerprint stability
465+
is an *explicit non-goal* here, changing a schema's fingerprint will not be considered
466+
a breaking change.
467+
468+
The fingerprint is computed on a best-effort basis and has some known issues at the moment.
469+
Please see the discussion in the pull request below for more details.
470+
https://github.com/kensho-technologies/graphql-compiler/pull/737
471+
472+
Args:
473+
schema: the schema for which to compute a fingerprint.
474+
475+
Returns:
476+
a hexadecimal string fingerprint compactly representing the data in the schema.
477+
"""
478+
lexicographically_sorted_schema = lexicographic_sort_schema(schema)
479+
text = print_schema(lexicographically_sorted_schema)
480+
return sha256(text.encode("utf-8")).hexdigest()

0 commit comments

Comments
 (0)