Skip to content

Commit 0a31cb5

Browse files
committed
initial commit
1 parent 578648c commit 0a31cb5

File tree

4 files changed

+186
-0
lines changed

4 files changed

+186
-0
lines changed

duneanalytics/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from .__version__ import __title__, __description__, __url__
2+
from .__version__ import __version__, __build__, __author_email__
3+
from .__version__ import __author__, __license__, __copyright__
4+
5+
from .duneanalytics import DuneAnalytics

duneanalytics/__version__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
__title__ = 'duneanalytics'
3+
__description__ = 'Unofficial library for Dune Analytics.'
4+
__url__ = 'https://github.com/itzmestar/duneanalytics'
5+
__version__ = '1.0.0'
6+
__build__ = 0x010001
7+
__author__ = 'Tarique Anwer'
8+
__author_email__ = '[email protected]'
9+
__license__ = 'Apache License 2.0'
10+
__copyright__ = 'Copyright 2021 Tarique Anwer'

duneanalytics/duneanalytics.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# -*- coding: utf-8 -*- #
2+
"""This provides the DuneAnalytics class implementation"""
3+
4+
from requests import Session
5+
6+
# --------- Constants --------- #
7+
8+
BASE_URL = "https://duneanalytics.com"
9+
GRAPH_URL = 'https://core-hsr.duneanalytics.com/v1/graphql'
10+
11+
# --------- Constants --------- #
12+
13+
14+
class DuneAnalytics:
15+
"""
16+
DuneAnalytics class to act as python client for duneanalytics.com.
17+
All requests to be made through this class.
18+
"""
19+
20+
def __init__(self, username, password):
21+
"""
22+
Initialize the object
23+
:param username: username for duneanalytics.com
24+
:param password: password for duneanalytics.com
25+
"""
26+
self.csrf = None
27+
self.auth_refresh = None
28+
self.token = None
29+
self.username = username
30+
self.password = password
31+
self.session = Session()
32+
headers = {
33+
'origin': BASE_URL,
34+
'sec-ch-ua': '" Not A;Brand";v="99", "Chromium";v="90", "Google Chrome";v="90"',
35+
'sec-ch-ua-mobile': '?0',
36+
'sec-fetch-dest': 'empty',
37+
'sec-fetch-mode': 'cors',
38+
'sec-fetch-site': 'same-site',
39+
'dnt': '1',
40+
}
41+
self.session.headers.update(headers)
42+
43+
def login(self):
44+
"""
45+
Try to login to duneanalytics.com & get the token
46+
:return:
47+
"""
48+
login_url = BASE_URL + '/auth/login'
49+
csrf_url = BASE_URL + '/api/auth/csrf'
50+
auth_url = BASE_URL + '/api/auth'
51+
52+
# fetch login page
53+
self.session.get(login_url)
54+
55+
# get csrf token
56+
self.session.post(csrf_url)
57+
self.csrf = self.session.cookies.get('csrf')
58+
59+
# try to login
60+
form_data = {
61+
'action': 'login',
62+
'username': self.username,
63+
'password': self.password,
64+
'csrf': self.csrf,
65+
'next': BASE_URL
66+
}
67+
68+
self.session.post(auth_url, data=form_data)
69+
self.auth_refresh = self.session.cookies.get('auth-refresh')
70+
71+
def fetch_auth_token(self):
72+
"""
73+
Fetch authorization token for the user
74+
:return:
75+
"""
76+
session_url = BASE_URL + '/api/auth/session'
77+
78+
response = self.session.post(session_url)
79+
if response.status_code == 200:
80+
self.token = response.json().get('token')
81+
82+
def query_result_id(self, query_id):
83+
"""
84+
Fetch the query result id for a query
85+
86+
:param query_id: provide the query_id
87+
:return:
88+
"""
89+
query_data = {"operationName": "GetResult", "variables": {"query_id": query_id},
90+
"query": "query GetResult($query_id: Int!, $parameters: [Parameter!]) "
91+
"{\n get_result(query_id: $query_id, parameters: $parameters) "
92+
"{\n job_id\n result_id\n __typename\n }\n}\n"
93+
}
94+
95+
self.session.headers.update({'authorization': f'Bearer {self.token}'})
96+
97+
response = self.session.post(GRAPH_URL, json=query_data)
98+
if response.status_code == 200:
99+
data = response.json()
100+
print(data)
101+
else:
102+
print(response.text)
103+
104+
def query_result(self, result_id):
105+
"""
106+
Fetch the result for a query
107+
:param result_id: result id of the query
108+
:return:
109+
"""
110+
query_data = {"operationName": "FindResultDataByResult",
111+
"variables": {"result_id": result_id},
112+
"query": "query FindResultDataByResult($result_id: uuid!) "
113+
"{\n query_results(where: {id: {_eq: $result_id}}) "
114+
"{\n id\n job_id\n error\n runtime\n generated_at\n columns\n __typename\n }"
115+
"\n get_result_by_result_id(args: {want_result_id: $result_id}) {\n data\n __typename\n }\n}\n"
116+
}
117+
118+
self.session.headers.update({'authorization': f'Bearer {self.token}'})
119+
120+
response = self.session.post(GRAPH_URL, json=query_data)
121+
if response.status_code == 200:
122+
data = response.json()
123+
print(data)
124+
else:
125+
print(response.text)
126+
127+
128+
129+
130+

setup.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import setuptools
2+
import os
3+
4+
here = os.path.abspath(os.path.dirname(__file__))
5+
6+
packages = ['duneanalytics']
7+
8+
requires = [
9+
'requests>=2.18.4',
10+
]
11+
12+
about = {}
13+
14+
with open(os.path.join(here, 'duneanalytics', '__version__.py'), mode='r', encoding='utf-8') as f:
15+
exec(f.read(), about)
16+
17+
with open('README.md', mode='r', encoding='utf-8') as f:
18+
readme = f.read()
19+
20+
setuptools.setup(
21+
name=about['__title__'],
22+
version=about['__version__'],
23+
description=about['__description__'],
24+
long_description=readme,
25+
long_description_content_type='text/markdown',
26+
author=about['__author__'],
27+
author_email=about['__author_email__'],
28+
url=about['__url__'],
29+
packages=packages,
30+
install_requires=requires,
31+
license=about['__license__'],
32+
classifiers=[
33+
"Programming Language :: Python :: 3",
34+
"Programming Language :: Python :: 3.6",
35+
"Programming Language :: Python :: 3.7",
36+
"Programming Language :: Python :: 3.8",
37+
"Programming Language :: Python :: 3.9",
38+
"License :: OSI Approved :: Apache Software License",
39+
"Operating System :: OS Independent",
40+
],
41+
)

0 commit comments

Comments
 (0)