Last active
April 4, 2023 02:53
-
-
Save jakerockland/6939284e2f7fc693d63010b206ac94e6 to your computer and use it in GitHub Desktop.
Art Blocks Token Holders Subgraph Script
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
######################################################################################## | |
## This script provides an easy way to aggregate the token holders of Art Blocks | |
## projects. | |
## | |
## In this current example only project "0", Chromie Squiggles [1], is being queried for | |
## but you can readily change `project: "0"` to the project number of your choosing | |
## in the GraphQL query below. | |
## | |
## You can also remove `, project: "0"` from the query entirely, to pull data | |
## for all Art Blocks token holders. | |
## | |
## This data is pulled from the Art Blocks subgraph [2] and required Python 3 | |
## and (optionally, but preferably) virtualenv [3]. | |
## | |
## High level instructions to use this script: | |
## 1. Download this file from Github Gist, or copy and paste the contents into a | |
## new file named `ArtBlocksTokenHolders.py`. If you download the file, make | |
## sure to rename it to `ArtBlocksTokenHolders.py`. | |
## 2. Ensure that you have Python 3 and virtualenv [3] installed on your system, | |
## you can test this by running `python3 --version` and `virtualenv --version` | |
## from your terminal and ensuring a valid version string is output. | |
## 3. Ensure that you can navigate to the `ArtBlocksTokenHolders.py` file you | |
## downloaded/created via your terminal. | |
## 4. Make any modifications to the script (to query for a different project, | |
## for example) and save. | |
## 5. Run the script by running the commands in the instructions below from your | |
## terminal after having navigated to the directory containing your script | |
## (ex. by using the `cd` command in your terminal). | |
## 6. You should now have a `ArtBlocksTokenHolders.csv` file in the same | |
## directory that you ran the script in, which you can open with your favorite | |
## text editor or spreadsheet editor. | |
## | |
## To run this script do the following (after modifying as desired): | |
## `$ virtualenv -p python3 --no-site-packages ./venv` | |
## `$ source ./venv/bin/activate` | |
## `$ pip install requests` | |
## `$ python ArtBlocksTokenHolders.py` | |
## | |
## [1] https://artblocks.io/project/0 | |
## [2] https://thegraph.com/explorer/subgraph/artblocks/art-blocks | |
## [3] https://pypi.org/project/virtualenv/ | |
######################################################################################## | |
from __future__ import print_function | |
import os | |
import requests | |
from requests.exceptions import HTTPError | |
import csv | |
import time | |
RESULTS_CSV = 'ArtBlocksTokenHolders.csv' | |
SUBGRAPH_ENDPOINT = 'https://api.thegraph.com/subgraphs/name/artblocks/art-blocks' | |
SUBGRAPH_QUERY= """ | |
{{ | |
tokens(first: {entries}, where: {{ id_gt: "{lastID}", project: "0" }}) {{ | |
id | |
owner{{ | |
id | |
}} | |
project {{ | |
id | |
}} | |
}} | |
}} | |
""" | |
def getTokens(session, entries, lastID): | |
print(f'Retrieving next {entries} after item {lastID}.') | |
subgraphQuery = SUBGRAPH_QUERY.format(entries=entries, lastID=lastID) | |
try: | |
response = session.post(SUBGRAPH_ENDPOINT, json={'query': subgraphQuery}) | |
response.raise_for_status() | |
return response.json() | |
except HTTPError as http_err: | |
print(f'HTTP error occurred: {http_err}') | |
return None | |
except Exception as err: | |
print(f'Other error occurred: {err}') | |
return None | |
def main(): | |
session = requests.Session() | |
ownerToProjectsMap = dict() | |
entries = 1000 | |
response = getTokens(session, entries, '') | |
while response: | |
tokens = response["data"]["tokens"] | |
if not tokens: | |
break | |
for token in tokens: | |
owner = token["owner"]["id"] | |
projectID = token["project"]["id"] | |
projects = ownerToProjectsMap.get(owner) | |
if projects is None: | |
projects = set() | |
projects.add(projectID) | |
ownerToProjectsMap[owner] = projects | |
time.sleep(1) | |
lastID = tokens[-1]["id"] | |
response = getTokens(session, entries, lastID) | |
with open(RESULTS_CSV, 'w') as f: | |
fieldnames = ['Owner', 'Projects', 'Total Projects Count'] | |
writer = csv.DictWriter(f, quoting=csv.QUOTE_ALL, fieldnames=fieldnames) | |
writer.writeheader() | |
for owner, projects in ownerToProjectsMap.items(): | |
writer.writerow({ | |
'Owner': owner, | |
'Projects': sorted(projects), | |
'Total Projects Count': len(projects) | |
}) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
nice! i added command line arguments for convenience