Package: coingecko-py
coingecko_pyAn Advanced API Client For The Coingecko APIThe base api client class and its documentation are automatically generated withswagger-codegenfrom the OpenAPI specification availablehereon the coingecko website.The documentation for the api client can be foundhere.This ensures that all endpoints and their corresponding parameters are100%correct. Furthermore,
the "Client Updated" badge you see at the top of this README is a live check that the spec used to
generate the client code matches the latest version of the spec available on the coingecko website.
This badge is updated once a day as a part of the CICD pipeline.Additionally, the base api client has been extended to provide additional functionality likeAbstracting away complexities associated with server side rate limiting when sending many api requests.Page range queries (bounded and unbounded).OutlineInstallationUsageAPI ReferenceAdvanced Features - Mitigate Rate LimitingAdvanced Features - Page Range QueriesClient ConfigurationSummaryDevelopment and TestingLicenseInstallationThis package is currently only available throughPyPI. You can install
it by runningpipinstallcoingecko_pyUsageThis package exposes a single class calledCoingeckoApi. To import and
initialize this class, do the followingfromcoingecko_pyimportCoingeckoApicg=CoingeckoApi()Check out theAPI Referencefor more details on how
to use this object.Advanced FeaturesThis section includes usage examples for advanced features that have been added to the
base api client.Advanced Features - Mitigate Rate LimitingNote: This functionality is available forallendpoints available on the base client.Imagine you wanted to get price data for the last year on the top 1000 market cap coins.First, we get the data for the top 1000 market cap coins. Each page returns 100 results and pages are already sorted by market cap.# np.ravel flattens a list of listsimportnumpyasnpcoins=np.ravel([cg.coins_markets_get('usd',page=i)foriinrange(1,11)])Next, we iterate overcoinsand use each coin id to query for it's price data.ndays=365prices=dict()forcincoins:cid=c['id']prices[cid]=cg.coins_id_market_chart_get(cid,'usd',ndays)['prices']The issue here is that the coingecko api performs server side rate limiting. If you are using the free tier, it's about 50 api calls per second. Paid tiers have higher limits, but there is still a limit.Since the above code block would be sending 1000 api requests synchronously, it is likely to fail at some point if you have a decent internet connection. In order to get around this, you would have to add error detection and call management logic. If you are writing a complex app with many api calls, this can be really annoying.Thecoingecko_pyclient introduces a mechanism to queue api calls and execute a series of queued calls while performingclient side exponential backoff retries. Seeherefor an explanation of this strategy.This allows you to write code without worrying about rate limiting! Here is a block of code that is equivalent to the above code block that won't error out due to rate limiting.ndays=365forcincoins:cid=c['id']cg.coins_id_market_chart_get(cid,'usd',ndays,qid=cid)prices=cg.execute_queued()prices={k:v['prices']fork,vinprices.items()}The key differences here areThe inclusion of theqidkeyword argument in the api call signature.qidstands for queue id.Wheneverqidis present as a keyword argument in an api call, the client will queue the call instead of executing it.qidcan be used as a lookup key for the result of this api call once it is executed.The line containing the api call (cg.coins_id_market_chart_get(...)) does not return anything.Wheneverqidis not a kwarg, an api call behaves exactly the same as the base api client.Wheneverqidis a kwarg, an api call returns nothing, as it was queued.The functionexecute_queuedmust be invoked in order to execute all queued calls.It internally deals with rate limiting.It's return value is a dictionary where the keys are theqidvalues from queued calls and the values are the data parsed from responses of the corresponding api calls.Ifexecute_queuedis successful, the internal call queue is cleared.So if you calledexecute_queuedon line 1 then again on line 2, the second call would return an empty dictionary.These two blocks of code both produce a dictionarypriceswith the same exact structure (assuming the first code block doesn't error out because of rate limiting).prices={'bitcoin':{'prices':[[1610236800000,40296.5290038294],[1610323200000,38397.895985418174],[1610409600000,35669.90668663349],...]},'ethereum':{'prices':[[1610236800000,1282.979575527323],[1610323200000,1267.7310031512136],[1610409600000,1092.9143378806064],...]},...}This approach to API design was loosely inspired by [dask's][https://docs.dask.org/en/stable/] approach to lazy execution of a sequence of operations on dataframes.Advanced Features - Page Range QueriesNote: This functionality is available forallendpoints the base client that support paging.The coingecko api has a number of endpoints that support pagination. Pagination is a common api feature where you can request a specific page of data from an api. This is often necessary as some data objects are too large to return in a single api response. If you want all the data for a particular api call you are executing, you must request data from all pages.Here is an example that uses the client to query for a single page of datacg.coins_id_tickers_get('bitcoin',page=2,per_page=50)Page range queries allow you to request a range of pages in asingleclient call. The
api client supportsboundedandunboundedpage range queries.Boundedqueries request pages over a fully defined range[page_start, page_end].Unboundedqueries only require the specification ofpage_startand will return
data from all available pages frompage_startonwards.For the code blocks below, let's assume we magically know there are 100 data pages for thecoins_id_tickers_getendpoint for the given set of parameters. In reality, if you wanted
to determine the number of data pages for a client call, you would need to make the call,
inspect the HTTP headers, perform a calculation to determine the total number of pages,
then loop over the page range and make a request per each page.Here is an example of doing pagination manually using the base api client functionalitydata=[]foriinrange(1,101):res=cg.coins_id_tickers_get('bitcoin',page=i)data.append(res)Here is an example of doing aboundedpage range query with the extended client.cg.coins_id_tickers_get('bitcoin',qid="data",page_start=1,page_end=100)data=cg.execute_queued()['data']Here is an example of doing anunboundedpage range query with the extended client.cg.coins_id_tickers_get('bitcoin',qid="data",page_start=1)data=cg.execute_queued()['data']All code blocks will produce equivalent output. The return value of a page range query is a list of response data from each individual api call. Sodata[0]contains the result for page 1,data[49]contains the result for page 50.It's important to note thatqidmust be included as a keyword argument for page range queries.
Thus, page range queries will also automatically deal with rate limiting as detailed in therate limitingsection.Client ConfigurationThe extended client supports multiple configuration options which impact its behavior.KwargDefaultDescriptionexp_limit8Max exponent (2exp_limit) for exponential backoff retriesprogress_interval10Min percentage interval at which to log progress of queued api callslog_levellogging.INFOpythonlogginglog level for client log messagesThe API client doesn't print any messages, but has logs at the following levels.10 (logging.DEBUG) will provide logs about internal state of client.20 (logging.INFO) progress logs and other useful info exists at this level.30 (logging.WARNING) useful warnings. I don't recommend any level higher than this.
Seeherefor more info on log levels.Here's an example of how to configure the client with non-default values.cg=CoingeckoApi(log_level=10,exp_limit=6,progress_interval=5)SummaryA quick summary of the functionality offered by this packageIt's base api client is automatically generated, ensuring correctness.It's functionality is described in theAPI Reference.It's extra features are accessible in the following wayscg.execute_queuedis the only public method added to the client. It takes no input arguments and returns a dictionary that mapsqidvalues to the corresponding queued api call.You can queue api calls by include the keyword argumentqidin a client call. When you include the kwargqidthe function call does not return anything (as it was queued for later execution).Queued calls benefit from the clients internal strategy for mitigating server side rate limiting.Page range queries allow you to request a range of data pages in a single client call.Ifpage_startandpage_endare both defined, it will return all data pages in range.Ifpage_startis defined andpage_endis not, it will return all data pages frompage_startonwards.Page range queries must be queued (includeqidin their call signature).Development and TestingThis package is packaged withpoetryIf you have poetry installed, you can perform the following steps to set up the development environment.gitclonehttps://github.com/brycemorrow4564/coingecko_py.gitcdcoingecko_py
poetryshellpoetryupdatepoetryinstallIf you want to run the tests (within the dev environment), do the followingpoetryruntestLicenseMIT