Synthetic Fields#
One of Subgrounds' unique features is the ability to define schema-based (i.e.: pre-querying) transformations using SyntheticFields
.
SyntheticFields
can be created using Python arithmetic operators on relative FieldPath
(i.e.: FieldPaths
starting from an entity and not the root Query
object) and must be added to the entity which they enhance. Once added to an entity, SyntheticFields
can be queried just like regular GraphQL fields.
The example below demonstrates how to create a simple SyntheticField
to calculate the swap price of Swap
events stored on the Sushiswap subgraph:
Click for Interactive Documentation
Clicking this button will enable editing and execution of the code-blocks on this page. Learn more here.
from subgrounds import Subgrounds
sg = Subgrounds()
sushiswap = sg.load_subgraph(
"https://api.thegraph.com/subgraphs/name/sushiswap/exchange")
swap = sushiswap.Swap # short hand for ease-of-use
# Define a synthetic field named price1 (the swap price of token1,
# in terms of token0) on Swap entities
swap.price1 = (
abs(swap.amount0Out - swap.amount0In)
/ abs(swap.amount1Out - swap.amount1In)
)
# Build query to get the last 10 swaps of the WETH-USDC pair on Sushiswap
weth_usdc = sushiswap.Query.pair(id="0x397ff1542f962076d0bfe58ea045ffa2d347aca0")
last_10_swaps = weth_usdc.swaps(
orderBy=swap.timestamp,
orderDirection="desc",
first=10
)
# Query swap prices using the `SyntheticField` price1 as if they were regular fields
sg.query_df([
last_10_swaps.timestamp,
last_10_swaps.price1 # synthetic fields get used the same!
])
SyntheticFields
can also be created using the constructor, allowing for much more complex transformations.
from datetime import datetime
from subgrounds import SyntheticField
# Create a SyntheticField on the Swap entity called `datetime`, which will format
# the timestamp field into something more human readable
swap.datetime = SyntheticField(
f=lambda timestamp: str(datetime.fromtimestamp(timestamp)),
type_=SyntheticField.STRING,
deps=swap.timestamp,
)
last_10_swaps = sushiswap.Query.swaps(
orderBy=swap.timestamp,
orderDirection="desc",
first=10,
)
sg.query_df([
last_10_swaps.datetime,
last_10_swaps.pair.token0.symbol,
last_10_swaps.pair.token1.symbol,
])
Helpers#
Since there are several common instances SyntheticFields
we see in the wild, we've added some helper constructors for ease of use.
SyntheticField.datetime_of_timestamp
#
This helper constructor makes it easy to convert timestamps
into datetime
objects.
swap.datetime = SyntheticField.datetime_of_timestamp(swap.timestamp)
swap.datetime = SyntheticField(
f=lambda timestamp: str(datetime.fromtimestamp(timestamp)),
type_=SyntheticField.STRING,
deps=swap.timestamp,
)