Internal#

Module contents#

class subgrounds.AsyncSubgrounds(timeout=30, headers=<factory>, global_transforms=<factory>, subgraphs=<factory>, schema_cache=PosixPath('schemas'))#

Bases: SubgroundsBase

async load(url, save_schema=False, is_subgraph=True)#

Performs introspection on the provided GraphQL API url to get the schema, stores the schema if save_schema is True and returns a generated class representing the GraphQL endpoint with all its entities.

async load_subgraph(url, save_schema=False)#

Performs introspection on the provided GraphQL API url to get the schema, stores the schema if save_schema is True and returns a generated class representing the subgraph with all its entities.

Parameters:
  • url (str) -- The url of the API

  • save_schema (bool) -- Flag indicating whether or not the schema should be cached to disk. Defaults to False.

  • cache_dir -- If save_schema == True, then subgraph schemas will be stored under cache_dir. Defaults to schemas/

Returns:

A generated class representing the subgraph and its entities

Return type:

Subgraph

async load_api(url, save_schema=False)#
Performs introspection on the provided GraphQL API url to get the

schema, stores the schema if save_schema is True and returns a generated class representing the GraphQL endpoint with all its entities.

Parameters:
  • url (str) -- The url of the API

  • save_schema (bool) -- Flag indicating whether or not the schema should be saved to disk. Defaults to False.

Returns:

A generated class representing the subgraph and its entities

Return type:

Subgraph

async execute(req, pagination_strategy=LegacyStrategy)#

Executes a DataRequest and returns a DataResponse.

Parameters:
  • req (DataRequest) -- The DataRequest object to be executed

  • pagination_strategy (Optional[Type[PaginationStrategy]]) -- A Class implementing the PaginationStrategy Protocol. If None, then automatic pagination is disabled. Defaults to LegacyStrategy.

Returns:

A DataResponse object representing the response

Return type:

DataResponse

async query_json(fpaths, pagination_strategy=LegacyStrategy)#

See query_json().

Parameters:
Returns:

The reponse data

Return type:

list[dict[str, Any]]

async query_df(fpaths, columns=None, concat=False, pagination_strategy=LegacyStrategy)#

See query_df().

Parameters:
Returns:

A pandas.DataFrame containing the reponse data.

Return type:

pandas.core.frame.DataFrame | list[pandas.core.frame.DataFrame]

async query(fpaths, unwrap=True, pagination_strategy=LegacyStrategy)#

See query().

Parameters:
Returns:

The FieldPath object(s) data

Return type:

str | int | float | bool | list | tuple | None

class subgrounds.FieldPath(subgraph: 'Subgraph', root_type: 'TypeRef.T', type_: 'TypeRef.T', path: 'list[tuple[dict[str, Any] | None, TypeMeta.FieldMeta]]')#

Bases: FieldOperatorMixin

class subgrounds.Subgraph(url: 'str', schema: 'SchemaMeta', transforms: 'list[DocumentTransform]' = [<subgrounds.transform.transforms.TypeTransform object at 0x7f6291ec6320>, <subgrounds.transform.transforms.TypeTransform object at 0x7f6291ec5570>], is_subgraph: 'bool' = True)#

Bases: object

class subgrounds.Subgrounds(timeout=30, headers=<factory>, global_transforms=<factory>, subgraphs=<factory>, schema_cache=PosixPath('schemas'))#

Bases: SubgroundsBase

load(url, save_schema=False, cache_dir=None, is_subgraph=True)#
load_subgraph(url, save_schema=False, cache_dir=None)#

Performs introspection on the provided GraphQL API url to get the schema, stores the schema if save_schema is True and returns a generated class representing the subgraph with all its entities.

Parameters:
  • API. (url The url of the) --

  • save_schema (bool) -- Flag indicating whether or not the schema should be cached to disk.

Returns:

A generated class representing the subgraph and its entities

Return type:

Subgraph

load_api(url, save_schema=False, cache_dir=None)#
Performs introspection on the provided GraphQL API url to get the

schema, stores the schema if save_schema is True and returns a generated class representing the GraphQL endpoint with all its entities.

Parameters:
  • url (str) -- The url of the API.

  • save_schema (bool) -- Flag indicating whether or not the schema should be saved to disk.

Returns:

A generated class representing the subgraph and its entities

Return type:

Subgraph

execute(req, pagination_strategy=LegacyStrategy)#

Executes a DataRequest and returns a DataResponse.

Parameters:
  • req (DataRequest) -- The DataRequest object to be executed.

  • pagination_strategy (Optional[Type[PaginationStrategy]]) -- A Class implementing the PaginationStrategy Protocol. If None, then automatic pagination is disabled. Defaults to LegacyStrategy.

Returns:

A DataResponse object representing the response

Return type:

DataResponse

execute_iter(req, pagination_strategy=LegacyStrategy)#

Same as execute, except that an iterator is returned which will iterate the data pages.

Parameters:
  • req (DataRequest) -- The DataRequest object to be executed

  • pagination_strategy (Optional[Type[PaginationStrategy]]) -- A Class implementing the PaginationStrategy Protocol. If None, then automatic pagination is disabled. Defaults to LegacyStrategy.

Returns:

An iterator over the DocumentResponse pages.

Return type:

Iterator[DocumentResponse]

⚠️ DOES NOT apply global transforms across multiple documents or their pages.

Since we yield each page as we get it, it's not possible to accurately perform the transforms since we don't collect the pages. This means transforms expecting multiple documents or pages of documents will be inaccurate.

query_json(fpaths, pagination_strategy=LegacyStrategy)#
Equivalent to

Subgrounds.execute(Subgrounds.mk_request(fpaths), pagination_strategy).

Parameters:
Returns:

The reponse data

Return type:

list[dict[str, Any]]

query_json_iter(fpaths, pagination_strategy=LegacyStrategy)#

Same as query_json returns an iterator over the response data pages.

Parameters:
Returns:

The reponse data

Return type:

list[dict[str, Any]]

query_df(fpaths, columns=None, concat=False, pagination_strategy=LegacyStrategy)#

Same as Subgrounds.query() but formats the response data into a Pandas DataFrame. If the response data cannot be flattened to a single query (e.g.: when querying multiple list fields that return different entities), then multiple dataframes are returned

fpaths is a list of FieldPath objects that indicate which data must be queried.

columns is an optional argument used to rename the dataframes(s) columns. The length of columns must be the same as the number of columns of all returned dataframes.

concat indicates whether or not the resulting dataframes should be concatenated together. The dataframes must have the same number of columns, as well as the same column names and types (the names can be set using the columns argument).

Parameters:
Returns:

A pandas.DataFrame containing the reponse data.

Return type:

pandas.core.frame.DataFrame | list[pandas.core.frame.DataFrame]

Example:

>>> from subgrounds import Subgrounds
>>> sg = Subgrounds()
>>> univ3 = sg.load_subgraph(
...    'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3')

# Define price SyntheticField
>>> univ3.Swap.price = abs(univ3.Swap.amount0) / abs(univ3.Swap.amount1)

# Query last 10 swaps from the ETH/USDC pool
>>> eth_usdc = univ3.Query.swaps(
...     orderBy=univ3.Swap.timestamp,
...     orderDirection='desc',
...     first=10,
...     where=[
...         univ3.Swap.pool == '0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8'
...     ]
... )
>>> sg.query_df([
...     eth_usdc.timestamp,
...     eth_usdc.price
... ])
  swaps_timestamp  swaps_price
0       1643213811  2618.886394
1       1643213792  2618.814281
2       1643213792  2617.500494
3       1643213763  2615.458495
4       1643213763  2615.876574
5       1643213739  2615.352390
6       1643213678  2615.205713
7       1643213370  2614.115746
8       1643213210  2613.077301
9       1643213196  2610.686563
query_df_iter(fpaths, pagination_strategy=LegacyStrategy)#

Same as query_df except returns an iterator over the response data pages

Parameters:
Returns:

An iterator over the response data pages, each as a pandas.DataFrame.

Return type:

Iterator[pandas.core.frame.DataFrame | list[pandas.core.frame.DataFrame]]

query(fpaths, unwrap=True, pagination_strategy=LegacyStrategy)#

Executes one or multiple FieldPath objects immediately and returns the data (as a tuple if multiple FieldPath objects are provided).

Parameters:
Returns:

The FieldPath object(s) data

Return type:

str | int | float | bool | list | tuple | None

Example:

>>> from subgrounds import Subgrounds
>>> sg = Subgrounds()
>>> univ3 = sg.load_subgraph(
...  'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3')

# Define price SyntheticField
>>> univ3.Swap.price = abs(univ3.Swap.amount0) / abs(univ3.Swap.amount1)

# Construct FieldPath to get price of last swap on ETH/USDC pool
>>> eth_usdc_last = univ3.Query.swaps(
...     orderBy=univ3.Swap.timestamp,
...     orderDirection='desc',
...     first=1,
...     where=[
...         univ3.Swap.pool == '0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8'
...     ]
... ).price

# Query last price FieldPath
>>> sg.query(eth_usdc_last)
2628.975030015892
query_iter(fpaths, unwrap=True, pagination_strategy=LegacyStrategy)#

Same as query except an iterator over the resonse data pages is returned.

Parameters:
  • fpath -- One or more FieldPath object(s) to query.

  • unwrap (bool) -- Flag indicating whether or not, in the case where the returned data is a list of one element, the element itself should be returned instead of the list. Defaults to True.

  • pagination_strategy (Optional[Type[PaginationStrategy]]) -- A Class implementing the PaginationStrategy Protocol. If None, then automatic pagination is disabled. Defaults to LegacyStrategy.

Returns:

An iterator over the FieldPath object(s)' data pages

Return type:

Iterator[str | int | float | bool | list[Any] | tuple | None]

class subgrounds.SyntheticField(f: 'Callable', type_: 'TypeRef.T', deps: 'list[FieldPath | SyntheticField] | FieldPath | SyntheticField', default: 'Any' = None)#

Bases: FieldOperatorMixin

STRING: ClassVar[TypeRef.Named] = Named(name_='String', kind='SCALAR')#
INT: ClassVar[TypeRef.Named] = Named(name_='Int', kind='SCALAR')#
FLOAT: ClassVar[TypeRef.Named] = Named(name_='Float', kind='SCALAR')#
BOOL: ClassVar[TypeRef.Named] = Named(name_='Boolean', kind='SCALAR')#
static default_of_type(type_)#
classmethod constant(value)#

Returns a constant SyntheticField with value value. Useful for injecting additional static data to a schema or merging entities.

Parameters:

value (str | int | float | bool) -- The constant field's value

Returns:

The constant SyntheticField

Return type:

SyntheticField

Example:

>>> from subgrounds import Subgrounds, SyntheticField
>>> sg = Subgrounds()
>>> univ3 = sg.load_subgraph(
...     "https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3"
... )

# Create constant SyntheticFields
>>> univ3.Mint.tx_type = SyntheticField.constant('MINT')
>>> univ3.Burn.tx_type = SyntheticField.constant('BURN')

# Last 10 mints and burns
>>> mints = univ3.Query.mints(
...     first=10,
...     orderBy=univ3.Mint.timestamp,
...     orderDirection='desc'
... )
>>> burns = univ3.Query.burns(
...     first=10,
...     orderBy=univ3.Burn.timestamp,
...     orderDirection='desc'
... )

# Query mints and burns. Notice that we merge the two entity tables by
# setting `concat=True` and overwriting the column names (columns must
# match the `FieldPaths`)
>>> df = sg.query_df(
...     [
...         mints.transaction.id,
...         mints.timestamp,
...         mints.tx_type,
...         mints.origin,
...         mints.amountUSD,
...         burns.transaction.id,
...         burns.timestamp,
...         burns.tx_type,
...         burns.origin,
...         burns.amountUSD,
...     ],
...     columns=['tx_hash', 'timestamp', 'tx_type', 'origin', 'amount_USD'],
...     concat=True
..  )

# Sort the DataFrame (output is truncated)
>>> df.sort_values(by=['timestamp'], ascending=False)
 tx_hash   timestamp    tx_type  origin     amount_USD
0xcbe1...  1656016553    MINT  0x3435....  7.879784e+03
0xddda...  1656016284    MINT  0xc747....  5.110840e+04
0xa767...  1656016284    BURN  0xd40d....  2.804573e+05
0xc132...  1656015853    MINT  0xc747....  5.122569e+04
0x1444...  1656015773    MINT  0xd11a....  8.897983e+03
0x3315...  1656015693    MINT  0xb7dd....  0.000000e+00
0xcc71...  1656015278    BURN  0xa7c4....  1.254942e+06
0x7bbf...  1656015111    MINT  0xac56....  3.432075e+04
0xea21...  1656014785    BURN  0x0709....  2.059106e+04
0x3bd3...  1656014120    MINT  0x5099....  2.517578e+03
0x1ea5...  1656014018    BURN  0x5099....  0.000000e+00
0xb9d3...  1656013998    MINT  0x22df....  8.365750e+04
0xc5e3...  1656013946    BURN  0xac56....  3.363809e+04
0x7c73...  1656013913    MINT  0x4ce6....  4.837287e+04
0x95cf...  1656013728    BURN  0x4ce6....  5.110010e+04
0x76dd...  1656013599    MINT  0x234a....  5.363896e+03
0x47e5...  1656013580    BURN  0xaf0f....  0.000000e+00
0xe20e...  1656013455    BURN  0xaf0f....  0.000000e+00
0xac3e...  1656013237    BURN  0x665d....  2.254100e+05
0x01c3...  1656013034    BURN  0x0084....  0.000000e+00
classmethod datetime_of_timestamp(timestamp)#

Returns a SyntheticField that will transform the FieldPath timestamp into a human-readable ISO8601 string.

Parameters:

timestamp (subgrounds.subgraph.fieldpath.FieldPath | subgrounds.subgraph.fieldpath.SyntheticField) -- A FieldPath representing a Unix timestamp field.

Returns:

An ISO8601 datetime string SyntheticField.

Return type:

Self

Example:

>>> from subgrounds import Subgrounds, SyntheticField
>>> sg = Subgrounds()
>>> univ3 = sg.load_subgraph(
...     "https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3"
... )

# Create datetime SyntheticField
>>> univ3.Swap.datetime = SyntheticField.datetime_of_timestamp(
...     univ3.Swap.timestamp
... )

# Query 100 swaps
>>> sg.query_df([
...     univ3.Query.swaps.timestamp,
...     univ3.Query.swaps.datetime,
... ])
    swaps_timestamp       swaps_datetime
0        1625105710  2021-06-30 22:15:10
1        1629253724  2021-08-17 22:28:44
2        1647333277  2022-03-15 04:34:37
3        1630801974  2021-09-04 20:32:54
4        1653240241  2022-05-22 13:24:01
..              ...                  ...
95       1646128326  2022-03-01 04:52:06
96       1646128326  2022-03-01 04:52:06
97       1626416555  2021-07-16 02:22:35
98       1626416555  2021-07-16 02:22:35
99       1625837291  2021-07-09 09:28:11
classmethod map(dict, type_, fpath, default=None)#

Returns a SyntheticField that will map the values of fpath using the key value pairs in dict. If a value is not in the dictionary, then default will be used instead.

Parameters:
Returns:

A map SyntheticField

Return type:

Self

Example:

>>> from subgrounds import Subgrounds, SyntheticField
>>> sg = Subgrounds()
>>> univ3 = sg.load_subgraph(
...     'https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3'
... )

# Hand-crafted mapping of pool addresses to symbol
>>> pooladdr_symbol_map = {
...     '0x5777d92f208679db4b9778590fa3cab3ac9e2168': 'DAI/USDC-001',
...     '0x6c6bc977e13df9b0de53b251522280bb72383700': 'DAI/USDC-005',
...     '0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8': 'USDC/ETH-030',
...     '0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640': 'USDC/ETH-005',
... }

# Create map SyntheticField using our dictionary with 'UNKNOWN' as the
# default value
>>> univ3.Pool.symbol = SyntheticField.map(
...     pooladdr_symbol_map,
...     SyntheticField.STRING,
...     univ3.Pool.id,
...     'UNKNOWN'
... )

# Query top 10 pools by TVL
>>> pools = univ3.Query.pools(
...     first=10,
...     orderBy=univ3.Pool.totalValueLockedUSD,
...     orderDirection='desc'
... )
>>> sg.query_df([
...     pools.id,
...     pools.symbol
... ])
                                     pools_id  pools_symbol
0  0xa850478adaace4c08fc61de44d8cf3b64f359bec       UNKNOWN
1  0x5777d92f208679db4b9778590fa3cab3ac9e2168  DAI/USDC-001
2  0x6c6bc977e13df9b0de53b251522280bb72383700  DAI/USDC-005
3  0x8ad599c3a0ff1de082011efddc58f1908eb6e6d8  USDC/ETH-030
4  0x88e6a0c2ddd26feeb64f039a2c41296fcb3f5640  USDC/ETH-005
5  0x3416cf6c708da44db2624d63ea0aaef7113527c6       UNKNOWN
6  0xcbcdf9626bc03e24f779434178a73a0b4bad62ed       UNKNOWN
7  0xc63b0708e2f7e69cb8a1df0e1389a98c35a76d52       UNKNOWN
8  0x4585fe77225b41b697c938b018e2ac67ac5a20c0       UNKNOWN
9  0x4e68ccd3e89f51c3074ca5072bbac773960dfa36       UNKNOWN