1- """This module is meant to contain the DeFiLlama class"""
1+ """This module is meant to contain the DeFiLlama class
2+
3+ DeFiLLama API Docs: https://defillama.com/docs/api
4+ """
25
3- # Global imports
46import datetime
5- from string import Template
6- from typing import Union , List , Dict
7+
8+ from pycaw .defillama import helpers
9+ from pycaw .messari import dataloader
10+ from pycaw .messari import utils
711
812import pandas as pd
13+ from typing import Union , List , Dict
914
10- from messari .dataloader import DataLoader
11- # Local imports
12- from messari .utils import validate_input , get_taxonomy_dict , time_filter_df
13- from .helpers import format_df
1415
1516##########################
1617# URL Endpoints
1718##########################
18- DL_PROTOCOLS_URL = "https://api.llama.fi/protocols"
19- DL_GLOBAL_TVL_URL = "https://api.llama.fi/charts/"
20- DL_CURRENT_PROTOCOL_TVL_URL = Template ("https://api.llama.fi/tvl/$slug" )
21- DL_CHAIN_TVL_URL = Template ("https://api.llama.fi/charts/$chain" )
22- DL_GET_PROTOCOL_TVL_URL = Template ("https://api.llama.fi/protocol/$slug" )
2319
2420
25- class DeFiLlama (DataLoader ):
26- """This class is a wrapper around the DeFi Llama API
27- """
21+ class DeFiLlama (dataloader .DataLoader ):
22+ """This class is a wrapper around the DeFi Llama API"""
2823
29- def __init__ (self ):
30- messari_to_dl_dict = get_taxonomy_dict ("messari_to_dl.json" )
31- DataLoader .__init__ (self , api_dict = None , taxonomy_dict = messari_to_dl_dict )
24+ api_urls : Dict [str , str ]
3225
33- def get_protocol_tvl_timeseries (self , asset_slugs : Union [str , List ],
34- start_date : Union [str , datetime .datetime ] = None ,
35- end_date : Union [str , datetime .datetime ] = None ) -> pd .DataFrame :
26+ def __init__ (self ):
27+ messari_to_dl_dict = utils .get_taxonomy_dict ("messari_to_dl.json" )
28+ dataloader .DataLoader .__init__ (
29+ self , api_dict = None , taxonomy_dict = messari_to_dl_dict
30+ )
31+
32+ @property
33+ def api_urls (self ) -> Dict [str , str ]:
34+ _endpoint_preamble : str = "https://api.llama.fi"
35+ urls = dict (
36+ # List all protocols on defillama along with their tvl
37+ protocols = "/" .join ([_endpoint_preamble , "protocols" ]),
38+ # Get historical TVL of a protocol and breakdowns by token and chain
39+ get_protocol_tvl = "/" .join ([_endpoint_preamble , "protocol" , "{_slug}" ]),
40+ # Get historical TVL on DeFi on all chains
41+ global_tvl = "/" .join ([_endpoint_preamble , "charts" ]),
42+ # Get historical TVL of a chain
43+ chain_tvl = "/" .join ([_endpoint_preamble , "charts" , "{_chain}" ]),
44+ # Get current TVL of a protocol
45+ current_protocol_tvl = "/" .join ([_endpoint_preamble , "tvl" , "{_slug}" ]),
46+ # Get current TVL of all chains
47+ all_chains_tvl = "/" .join ([_endpoint_preamble , "chains" ]),
48+ )
49+ return urls
50+ # TODO test: Check that the urls aren't broken now.
51+
52+ def get_protocol_tvl_timeseries (
53+ self ,
54+ asset_slugs : Union [str , List ],
55+ start_date : Union [str , datetime .datetime ] = None ,
56+ end_date : Union [str , datetime .datetime ] = None ,
57+ ) -> pd .DataFrame :
3658 """Returns times TVL of a protocol with token amounts as a pandas DataFrame.
3759 Returned DataFrame is indexed by df[protocol][chain][asset].
3860
@@ -59,7 +81,7 @@ def get_protocol_tvl_timeseries(self, asset_slugs: Union[str, List],
5981
6082 slug_df_list : List = []
6183 for slug in slugs :
62- endpoint_url = DL_GET_PROTOCOL_TVL_URL . substitute ( slug = slug )
84+ endpoint_url = self . api_urls [ "get_protocol_tvl" ]. format ( _slug = slug )
6385 protocol = self .get_response (endpoint_url )
6486
6587 ###########################
@@ -95,13 +117,15 @@ def get_protocol_tvl_timeseries(self, asset_slugs: Union[str, List],
95117 chain_tvl_tokens_usd_df = pd .DataFrame (chain_tvl_tokens_usd )
96118
97119 # fix indexes
98- chain_tvl_df = format_df (chain_tvl_df )
99- chain_tvl_tokens_df = format_df (chain_tvl_tokens_df )
100- chain_tvl_tokens_usd_df = format_df (chain_tvl_tokens_usd_df )
120+ chain_tvl_df = helpers . format_df (chain_tvl_df )
121+ chain_tvl_tokens_df = helpers . format_df (chain_tvl_tokens_df )
122+ chain_tvl_tokens_usd_df = helpers . format_df (chain_tvl_tokens_usd_df )
101123 chain_tvl_tokens_usd_df = chain_tvl_tokens_usd_df .add_suffix ("_usd" )
102124
103125 # concat tokens and tokensInUsd
104- joint_tokens_df = pd .concat ([chain_tvl_tokens_df , chain_tvl_tokens_usd_df ], axis = 1 )
126+ joint_tokens_df = pd .concat (
127+ [chain_tvl_tokens_df , chain_tvl_tokens_usd_df ], axis = 1
128+ )
105129 # Join total chain TVL w/ token TVL
106130 chain_df = chain_tvl_df .join (joint_tokens_df )
107131 chain_df_list .append (chain_df )
@@ -119,7 +143,7 @@ def get_protocol_tvl_timeseries(self, asset_slugs: Union[str, List],
119143 token [key ] = value
120144 token .pop ("tokens" , None )
121145 tokens_df = pd .DataFrame (tokens )
122- tokens_df = format_df (tokens_df )
146+ tokens_df = helpers . format_df (tokens_df )
123147
124148 ## tokens in USD
125149 tokens_usd = protocol ["tokensInUsd" ]
@@ -128,13 +152,13 @@ def get_protocol_tvl_timeseries(self, asset_slugs: Union[str, List],
128152 token [key ] = value
129153 token .pop ("tokens" , None )
130154 tokens_usd_df = pd .DataFrame (tokens_usd )
131- tokens_usd_df = format_df (tokens_usd_df )
155+ tokens_usd_df = helpers . format_df (tokens_usd_df )
132156 tokens_usd_df = tokens_usd_df .add_suffix ("_usd" )
133157
134158 # Get total tvl across chains
135159 tvl = protocol ["tvl" ]
136160 total_tvl_df = pd .DataFrame (tvl )
137- total_tvl_df = format_df (total_tvl_df )
161+ total_tvl_df = helpers . format_df (total_tvl_df )
138162
139163 # Working
140164 joint_tokens_df = pd .concat ([tokens_df , tokens_usd_df ], axis = 1 )
@@ -150,11 +174,16 @@ def get_protocol_tvl_timeseries(self, asset_slugs: Union[str, List],
150174 total_slugs_df = pd .concat (slug_df_list , keys = slugs , axis = 1 )
151175 total_slugs_df .sort_index (inplace = True )
152176
153- total_slugs_df = time_filter_df (total_slugs_df , start_date = start_date , end_date = end_date )
177+ total_slugs_df = utils .time_filter_df (
178+ total_slugs_df , start_date = start_date , end_date = end_date
179+ )
154180 return total_slugs_df
155181
156- def get_global_tvl_timeseries (self , start_date : Union [str , datetime .datetime ] = None ,
157- end_date : Union [str , datetime .datetime ] = None ) -> pd .DataFrame :
182+ def get_global_tvl_timeseries (
183+ self ,
184+ start_date : Union [str , datetime .datetime ] = None ,
185+ end_date : Union [str , datetime .datetime ] = None ,
186+ ) -> pd .DataFrame :
158187 """Returns timeseries TVL from total of all Defi Llama supported protocols
159188
160189 Parameters
@@ -170,15 +199,20 @@ def get_global_tvl_timeseries(self, start_date: Union[str, datetime.datetime] =
170199 DataFrame
171200 DataFrame containing timeseries tvl data for every protocol
172201 """
173- global_tvl = self .get_response (DL_GLOBAL_TVL_URL )
202+ global_tvl = self .get_response (self . api_urls [ "global_tvl" ] )
174203 global_tvl_df = pd .DataFrame (global_tvl )
175- global_tvl_df = format_df (global_tvl_df )
176- global_tvl_df = time_filter_df (global_tvl_df , start_date = start_date , end_date = end_date )
204+ global_tvl_df = helpers .format_df (global_tvl_df )
205+ global_tvl_df = utils .time_filter_df (
206+ global_tvl_df , start_date = start_date , end_date = end_date
207+ )
177208 return global_tvl_df
178209
179- def get_chain_tvl_timeseries (self , chains_in : Union [str , List ],
180- start_date : Union [str , datetime .datetime ] = None ,
181- end_date : Union [str , datetime .datetime ] = None ) -> pd .DataFrame :
210+ def get_chain_tvl_timeseries (
211+ self ,
212+ chains_in : Union [str , List ],
213+ start_date : Union [str , datetime .datetime ] = None ,
214+ end_date : Union [str , datetime .datetime ] = None ,
215+ ) -> pd .DataFrame :
182216 """Retrive timeseries TVL for a given chain
183217
184218 Parameters
@@ -197,20 +231,22 @@ def get_chain_tvl_timeseries(self, chains_in: Union[str, List],
197231 DataFrame
198232 DataFrame containing timeseries tvl data for each chain
199233 """
200- chains = validate_input (chains_in )
234+ chains = utils . validate_input (chains_in )
201235
202236 chain_df_list = []
203237 for chain in chains :
204- endpoint_url = DL_CHAIN_TVL_URL . substitute ( chain = chain )
238+ endpoint_url = self . api_urls [ "chain_tvl" ]. format ( _chain = chain )
205239 response = self .get_response (endpoint_url )
206240 chain_df = pd .DataFrame (response )
207- chain_df = format_df (chain_df )
241+ chain_df = helpers . format_df (chain_df )
208242 chain_df_list .append (chain_df )
209243
210244 # Join DataFrames from each chain & return
211245 chains_df = pd .concat (chain_df_list , axis = 1 )
212246 chains_df .columns = chains
213- chains_df = time_filter_df (chains_df , start_date = start_date , end_date = end_date )
247+ chains_df = utils .time_filter_df (
248+ chains_df , start_date = start_date , end_date = end_date
249+ )
214250 return chains_df
215251
216252 def get_current_tvl (self , asset_slugs : Union [str , List ]) -> Dict :
@@ -226,11 +262,11 @@ def get_current_tvl(self, asset_slugs: Union[str, List]) -> Dict:
226262 DataFrame
227263 Pandas Series for tvl indexed by each slug {slug: tvl, ...}
228264 """
229- slugs = validate_input (asset_slugs )
265+ slugs = utils . validate_input (asset_slugs )
230266
231267 tvl_dict = {}
232268 for slug in slugs :
233- endpoint_url = DL_CURRENT_PROTOCOL_TVL_URL . substitute ( slug = slug )
269+ endpoint_url = self . api_urls [ "current_protocol_tvl" ]. format ( _slug = slug )
234270 tvl = self .get_response (endpoint_url )
235271 if isinstance (tvl , float ):
236272 tvl_dict [slug ] = tvl
@@ -250,7 +286,7 @@ def get_protocols(self) -> pd.DataFrame:
250286 DataFrame
251287 DataFrame with one column per DeFi Llama supported protocol
252288 """
253- protocols = self .get_response (DL_PROTOCOLS_URL )
289+ protocols = self .get_response (self . api_urls [ "protocols" ] )
254290
255291 protocol_dict = {}
256292 for protocol in protocols :
0 commit comments