|
| 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 | + |
0 commit comments