├── .gitignore
├── CHANGELOG.md
├── LICENCE
├── README.md
├── pycoingecko
├── __init__.py
├── api.py
├── utils.py
└── version.py
├── setup.py
└── tests
└── test_api.py
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | *.egg-info/
24 | .installed.cfg
25 | *.egg
26 | MANIFEST
27 |
28 | # PyInstaller
29 | # Usually these files are written by a python script from a template
30 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
31 | *.manifest
32 | *.spec
33 |
34 | # Installer logs
35 | pip-log.txt
36 | pip-delete-this-directory.txt
37 |
38 | # Unit test / coverage reports
39 | htmlcov/
40 | .tox/
41 | .coverage
42 | .coverage.*
43 | .cache
44 | nosetests.xml
45 | coverage.xml
46 | *.cover
47 | .hypothesis/
48 | .pytest_cache/
49 |
50 | # Translations
51 | *.mo
52 | *.pot
53 |
54 | # Django stuff:
55 | *.log
56 | local_settings.py
57 | db.sqlite3
58 |
59 | # Flask stuff:
60 | instance/
61 | .webassets-cache
62 |
63 | # Scrapy stuff:
64 | .scrapy
65 |
66 | # Sphinx documentation
67 | docs/_build/
68 |
69 | # PyBuilder
70 | target/
71 |
72 | # Jupyter Notebook
73 | .ipynb_checkpoints
74 |
75 | # IPython
76 | profile_default/
77 | ipython_config.py
78 |
79 | # pyenv
80 | .python-version
81 |
82 | # celery beat schedule file
83 | celerybeat-schedule
84 |
85 | # SageMath parsed files
86 | *.sage.py
87 |
88 | # Environments
89 | .env
90 | .venv
91 | env/
92 | venv/
93 | ENV/
94 | env.bak/
95 | venv.bak/
96 |
97 | # Spyder project settings
98 | .spyderproject
99 | .spyproject
100 |
101 | # Rope project settings
102 | .ropeproject
103 |
104 | # mkdocs documentation
105 | /site
106 |
107 | # mypy
108 | .mypy_cache/
109 | .dmypy.json
110 | dmypy.json
111 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | 3.2.0 / 2024-11-13
3 | ==================
4 |
5 | * support both public (with or without demo_api_key) and pro (with pro api key) api in requests
6 | * added new methods in coins, asset_platforms, exchanges, nfts, global
7 |
8 | 3.1.0 / 2022-10-26
9 | ==================
10 |
11 | * added nfts (beta) endpoints (/nfts/list, /nfts/{id}, /nfts/{asset_platform_id}/contract/{contract_address})
12 | * updated tests
13 |
14 | 3.0.0 / 2022-09-01
15 | ==================
16 |
17 | * removed deprecated endpoints (status_updates, finance and events):
18 | * /coins/{id}/status_updates -> cg.get_coin_status_updates_by_id()
19 | * /exchanges/{id}/status_updates -> cg.get_exchanges_status_updates_by_id()
20 | * /finance_platforms -> cg.get_finance_platforms()
21 | * /finance_products -> cg.get_finance_products()
22 | * /status_updates -> cg.get_status_updates()
23 | * /events -> cg.get_events()
24 | * /events/countries -> cg.get_events_countries()
25 | * /events/types -> cg.get_events_types()
26 | * removed deprecated api_base_url param from CoinGeckoAPI init
27 |
28 | 2.3.0 / 2022-08-30
29 | ==================
30 |
31 | * added /search endpoint
32 | * added CoinGecko Pro API support using api_key param in CoinGeckoAPI init (required in PRO version API calls)
33 | * added ability to modify how many retries to do in requests session using param retries in CoinGeckoAPI init (default: retries=5)
34 | * fixed session to mount retry adapter on https instead of http
35 | * fixed params passed in get_coin_market_chart_range_from_contract_address_by_id for /coins/{id}/contract/{contract_address}/market_chart/range endpoint
36 |
37 | 2.2.0 / 2021-06-17
38 | ==================
39 |
40 | * added /indexes/{market_id}/{id} and /companies/public_treasury/{coin_id} endpoints
41 |
42 | 2.1.0 / 2021-06-03
43 | ==================
44 |
45 | * added asset_platforms (/asset_platforms) and categories (/coins/categories/list, coins/categories) endpoints
46 |
47 | 2.0.0 / 2021-04-23
48 | ==================
49 |
50 | * allow Python Lists and Booleans for any endpoint parameter (list converted to comma-separated string & bool converted to lower case string)
51 | * removed /indexes/{id} endpoint (Get market index by id) -> cg.get_indexes_by_id()
52 | * improved request exceptions handling (Fixed unbound local exception on GET request failure)
53 |
54 | 1.4.1 / 2021-03-30
55 | ==================
56 |
57 | * fixed __api_url_params issue for optional parametes of few endpoints (such as /coins/{id}/market_chart)
58 |
59 | 1.4.0 / 2020-10-03
60 | ==================
61 |
62 | * added new endpoints (/coins/{id}/ohlc, /search/trending, /global/decentralized_finance_defi)
63 | * updated tests
64 |
65 | 1.3.0 / 2020-07-12
66 | ==================
67 |
68 | * allow optional arguments for **ALL** endopoints
69 |
70 | 1.2.0 / 2019-12-13
71 | ==================
72 |
73 | * added indexes endpoints (/indexes, /indexes/{id}, /indexes/list)
74 |
75 | 1.1.0 / 2019-12-06
76 | ==================
77 |
78 | * added derivatives endpoints (/derivatives, /derivatives/exchanges, /derivatives/exchanges/{id}, /derivatives/exchanges/list)
79 |
80 | 1.0.0 / 2019-11-17
81 | ==================
82 |
83 | * updated tests
84 | * included more contract endpoints
85 | * included /coins/{id}/market_chart/range endpoint
86 | * basic methods for finance endpoints with tests
87 | * updated error handling
88 | * added check for json format in __request; coingecko returns a html string when something goes wrong in the request, which results in an error when json.loads is called on the html string.
89 |
90 | 0.4.0 / 2019-08-20
91 | ==================
92 |
93 | * included /exchanges/{id}/volume_chart endpoint
94 |
95 | 0.3.0 / 2019-05-31
96 | ==================
97 |
98 | * exceptions include API error message
99 | * fix get_coin_market_chart_by_id test
100 | * Use a list or tuple for multiple-valued arguments
101 | * convert every list arg to comma-separated string
102 |
103 | 0.2.0 / 2019-05-17
104 | ==================
105 |
106 | * Fixed arguments for get_token_price
107 | * Added get_token_price function
108 |
109 | 0.1.6 / 2019-02-02
110 | ==================
111 |
112 | * README incude examples
113 | * included /exchanges/list endpoint
114 |
115 | 0.1.0 / 2019-01-02
116 | ==================
117 |
118 | * added /coins/{id}/tickers endpoint
119 | * included events endpoints
120 | * included status_updates endpoints
121 | * updated exchanges endpoints
122 | * updated coins endpoints
123 | * included simple endpoints
124 |
125 | 0.0.2 / 2018-11-20
126 | ==================
127 |
128 | * use requests session to include retries
129 | * fixed bug when querying exchanges and added more unit tests
130 | * first unit tests for coingecko wrappers
131 | * initial commit
132 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Christoforou Emmanouil
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CoinGecko API wrapper
2 | [](https://pypi.python.org/pypi/pycoingecko/)
3 | 
4 |
5 | Python3 wrapper around the [CoinGecko](https://www.coingecko.com/) API (V3) 🦎
Supports both Public and Pro API:
6 | * [Public API v3.0.1](https://docs.coingecko.com/v3.0.1/reference/introduction)
7 | * [Pro API v3.1.1](https://docs.coingecko.com/v3.1.1/reference/introduction)
8 |
9 | ### Installation
10 | PyPI
11 | ```bash
12 | pip install -U pycoingecko
13 | ```
14 | or from source
15 | ```bash
16 | git clone https://github.com/man-c/pycoingecko.git
17 | cd pycoingecko
18 | python3 setup.py install
19 | ```
20 |
21 | ### Usage
22 |
23 | For free **Public API**:
24 |
25 | * without any demo api key (x-cg-demo-api-key):
26 | ```python
27 | from pycoingecko import CoinGeckoAPI
28 | cg = CoinGeckoAPI()
29 | ```
30 | * 🔑 with a demo api key:
31 | ```python
32 | from pycoingecko import CoinGeckoAPI
33 | cg = CoinGeckoAPI(demo_api_key='YOUR_DEMO_API_KEY')
34 | ```
35 |
36 | For **Pro API**:
37 | * 🔑 with a pro api key:
38 | ```python
39 | from pycoingecko import CoinGeckoAPI
40 | cg = CoinGeckoAPI(api_key='YOUR_PRO_API_KEY')
41 | ```
42 |
43 | ### Examples
44 | The required parameters for each endpoint are defined as required (mandatory) parameters for the corresponding functions.\
45 | **Any optional parameters** can be passed using same names, as defined in CoinGecko API doc (https://www.coingecko.com/en/api/documentation).
46 |
47 | For any parameter:
48 | - ***Lists** are supported as input for multiple-valued comma-separated parameters\
49 | (e.g. see /simple/price usage examples).*
50 | - ***Booleans** are supported as input for boolean type parameters; they can be `str` ('true', 'false'') or `bool` (`True`, `False`)\
51 | (e.g. see /simple/price usage examples).*
52 |
53 | Usage examples:
54 | ```python
55 | # /simple/price endpoint with the required parameters
56 | >>> cg.get_price(ids='bitcoin', vs_currencies='usd')
57 | {'bitcoin': {'usd': 3462.04}}
58 |
59 | >>> cg.get_price(ids='bitcoin,litecoin,ethereum', vs_currencies='usd')
60 | # OR (lists can be used for multiple-valued arguments)
61 | >>> cg.get_price(ids=['bitcoin', 'litecoin', 'ethereum'], vs_currencies='usd')
62 | {'bitcoin': {'usd': 3461.27}, 'ethereum': {'usd': 106.92}, 'litecoin': {'usd': 32.72}}
63 |
64 | >>> cg.get_price(ids='bitcoin,litecoin,ethereum', vs_currencies='usd,eur')
65 | # OR (lists can be used for multiple-valued arguments)
66 | >>> cg.get_price(ids=['bitcoin', 'litecoin', 'ethereum'], vs_currencies=['usd', 'eur'])
67 | {'bitcoin': {'usd': 3459.39, 'eur': 3019.33}, 'ethereum': {'usd': 106.91, 'eur': 93.31}, 'litecoin': {'usd': 32.72, 'eur': 28.56}}
68 |
69 | # optional parameters can be passed as defined in the API doc (https://www.coingecko.com/api/docs/v3)
70 | >>> cg.get_price(ids='bitcoin', vs_currencies='usd', include_market_cap='true', include_24hr_vol='true', include_24hr_change='true', include_last_updated_at='true')
71 | {'bitcoin': {'usd': 3458.74, 'usd_market_cap': 60574330199.29028, 'usd_24h_vol': 4182664683.6247883, 'usd_24h_change': 1.2295378479069035, 'last_updated_at': 1549071865}}
72 | # OR (also booleans can be used for boolean type arguments)
73 | >>> cg.get_price(ids='bitcoin', vs_currencies='usd', include_market_cap=True, include_24hr_vol=True, include_24hr_change=True, include_last_updated_at=True)
74 | {'bitcoin': {'usd': 3458.74, 'usd_market_cap': 60574330199.29028, 'usd_24h_vol': 4182664683.6247883, 'usd_24h_change': 1.2295378479069035, 'last_updated_at': 1549071865}}
75 | ```
76 |
77 | ### API documentation
78 | https://www.coingecko.com/en/api/documentation
79 |
80 | ### 📡 Endpoints included
81 | > :warning: **Endpoints documentation**: To make sure that you are using properly each endpoint you should check the [API documentation](https://www.coingecko.com/en/api/documentation). Return behaviour and parameters of the endpoints, such as *pagination*, might have changed.
Any **optional parameters** defined in CoinGecko API doc can be passed as function parameters using same parameters names with the API *(see Examples above)*.
82 | ping
83 |
84 |
85 | * **/ping**
86 |
87 | _Check API server status_
88 | ```python
89 | cg.ping()
90 | ```
91 |
92 |
93 | key
94 |
95 |
96 | * [Pro API] 💼 **/key**
97 |
98 | _Monitor your account's API usage, including rate limits, monthly total credits, remaining credits, and more_
99 | ```python
100 | cg.key()
101 | ```
102 |
103 |
104 | simple
105 |
106 |
107 | * **/simple/price**
108 |
109 | _Get the current price of any cryptocurrencies in any other supported currencies that you need_
110 | ```python
111 | cg.get_price()
112 | ```
113 | * **/simple/token_price/{id}**
114 |
115 | _Get current price of tokens (using contract addresses) for a given platform in any other currency that you need_
116 | ```python
117 | cg.get_token_price()
118 | ```
119 | * **/simple/supported_vs_currencies**
120 |
121 | _Get list of supported_vs_currencies_
122 | ```python
123 | cg.get_supported_vs_currencies()
124 | ```
125 |
126 |
127 | coins
128 |
129 |
130 | * **/coins/list**
131 |
132 | _List all supported coins id, name and symbol (no pagination required)_
133 | ```python
134 | cg.get_coins_list()
135 | ```
136 |
137 | * [Pro API] 💼 **/coins/top_gainers_losers**
138 |
139 | _Query the top 30 coins with largest price gain and loss by a specific time duration_
140 | ```python
141 | cg.get_coin_top_gainers_losers()
142 | ```
143 |
144 | * [Pro API] 💼 **/coins/list/new**
145 |
146 | _Query the latest 200 coins that recently listed on CoinGecko_
147 | ```python
148 | cg.get_coins_list_new()
149 | ```
150 |
151 | * **/coins/markets**
152 |
153 | _List all supported coins price, market cap, volume, and market related data_
154 | ```python
155 | cg.get_coins_markets()
156 | ```
157 | * **/coins/{id}**
158 |
159 | _Get current data (name, price, market, ... including exchange tickers) for a coin_
160 | ```python
161 | cg.get_coin_by_id()
162 | ```
163 | * **/coins/{id}/tickers**
164 |
165 | _Get coin tickers (paginated to 100 items)_
166 | ```python
167 | cg.get_coin_ticker_by_id()
168 | ```
169 | * **/coins/{id}/history**
170 |
171 | _Get historical data (name, price, market, stats) at a given date for a coin_
172 | ```python
173 | cg.get_coin_history_by_id()
174 | ```
175 | * **/coins/{id}/market_chart**
176 |
177 | _Get historical market data include price, market cap, and 24h volume (granularity auto)_
178 | ```python
179 | cg.get_coin_market_chart_by_id()
180 | ```
181 | * **/coins/{id}/market_chart/range**
182 |
183 | _Get historical market data include price, market cap, and 24h volume within a range of timestamp (granularity auto)_
184 | ```python
185 | cg.get_coin_market_chart_range_by_id()
186 | ```
187 |
188 | [//]: # (* **/coins/{id}/status_updates** (Get status updates for a given coin (beta)))
189 |
190 | [//]: # ( ```python)
191 |
192 | [//]: # ( cg.get_coin_status_updates_by_id())
193 |
194 | [//]: # ( ```)
195 | * **/coins/{id}/ohlc**
196 |
197 | _Get the OHLC chart (Open, High, Low, Close) of a coin based on particular coin id_
198 | ```python
199 | cg.get_coin_ohlc_by_id()
200 | ```
201 |
202 | * [Pro API] 💼 **/coins/{id}/ohlc/range**
203 |
204 | _Get the OHLC chart (Open, High, Low, Close) of a coin within a range of timestamp based on particular coin id_
205 | ```python
206 | cg.get_coin_ohlc_by_id_range()
207 | ```
208 |
209 | * [Pro API] 👑 **/coins/{id}/circulating_supply_chart**
210 |
211 | _Query historical circulating supply of a coin by number of days away from now based on provided coin id_
212 | ```python
213 | cg.get_coin_circulating_supply_chart()
214 | ```
215 |
216 | * [Pro API] 👑 **/coins/{id}/circulating_supply_chart/range**
217 |
218 | _Query historical circulating supply of a coin, within a range of timestamp based on the provided coin id_
219 | ```python
220 | cg.get_coin_circulating_supply_chart_range()
221 | ```
222 |
223 | * [Pro API] 👑 **/coins/{id}/total_supply_chart**
224 |
225 | _Query historical total supply of a coin by number of days away from now based on provided coin id_
226 | ```python
227 | cg.get_coin_total_supply_chart()
228 | ```
229 |
230 | * [Pro API] 👑 **/coins/{id}/total_supply_chart/range**
231 |
232 | _Query historical total supply of a coin, within a range of timestamp based on the provided coin id_
233 | ```python
234 | cg.get_coin_total_supply_chart_range()
235 | ```
236 |
237 |
238 |
239 |
240 | contract
241 |
242 |
243 | * **/coins/{id}/contract/{contract_address}**
244 |
245 | _Get coin info from contract address_
246 | ```python
247 | cg.get_coin_info_from_contract_address_by_id()
248 | ```
249 | * **/coins/{id}/contract/{contract_address}/market_chart/**
250 |
251 | _Get historical market data include price, market cap, and 24h volume (granularity auto) from a contract address_
252 | ```python
253 | cg.get_coin_market_chart_from_contract_address_by_id()
254 | ```
255 | * **/coins/{id}/contract/{contract_address}/market_chart/range**
256 |
257 | _Get historical market data include price, market cap, and 24h volume within a range of timestamp (granularity auto) from a contract address_
258 | ```python
259 | cg.get_coin_market_chart_range_from_contract_address_by_id()
260 | ```
261 |
262 |
263 | asset_platforms
264 |
265 |
266 | * **/asset_platforms**
267 |
268 | _List all asset platforms (Blockchain networks)_
269 | ```python
270 | cg.get_asset_platforms()
271 | ```
272 |
273 | * [Pro API] 👑 **/token_lists/{asset_platform_id}/all.json**
274 |
275 | _Get full list of tokens of a blockchain network (asset platform) that is supported by Ethereum token list standard_
276 | ```python
277 | cg.get_asset_platform_by_id()
278 | ```
279 |
280 |
281 |
282 | categories
283 |
284 |
285 | * **/coins/categories/list**
286 |
287 | _List all categories_
288 | ```python
289 | cg.get_coins_categories_list()
290 | ```
291 | * **coins/categories**
292 |
293 | _List all categories with market data_
294 | ```python
295 | cg.get_coins_categories()
296 | ```
297 |
298 |
299 | exchanges
300 |
301 |
302 | * **/exchanges**
303 |
304 | _List all exchanges_
305 | ```python
306 | cg.get_exchanges_list()
307 | ```
308 | * **/exchanges/list**
309 |
310 | _List all supported markets id and name (no pagination required)_
311 | ```python
312 | cg.get_exchanges_id_name_list()
313 | ```
314 | * **/exchanges/{id}**
315 |
316 | _Get exchange volume in BTC and top 100 tickers only_
317 | ```python
318 | cg.get_exchanges_by_id()
319 | ```
320 | * **/exchanges/{id}/tickers**
321 |
322 | _Get exchange tickers (paginated, 100 tickers per page)_
323 | ```python
324 | cg.get_exchanges_tickers_by_id()
325 | ```
326 |
327 | [//]: # (* **/exchanges/{id}/status_updates** (Get status updates for a given exchange (beta)))
328 |
329 | [//]: # ( ```python)
330 |
331 | [//]: # ( cg.get_exchanges_status_updates_by_id())
332 |
333 | [//]: # ( ```)
334 | * **/exchanges/{id}/volume_chart**
335 |
336 | _Get volume_chart data for a given exchange_
337 | ```python
338 | cg.get_exchanges_volume_chart_by_id()
339 | ```
340 |
341 | * [Pro API] 💼 **/exchanges/{id}/volume_chart/range**
342 |
343 | _Query the historical volume chart data in BTC by specifying date range in UNIX based on exchange’s id_
344 | ```python
345 | cg.get_exchanges_volume_chart_by_id_within_time_range()
346 | ```
347 |
348 |
349 |
350 | [//]: # (finance
)
351 |
352 | [//]: # ()
353 |
354 | [//]: # ()
355 | [//]: # (* **/finance_platforms** (List all finance platforms))
356 |
357 | [//]: # ( ```python)
358 |
359 | [//]: # ( cg.get_finance_platforms())
360 |
361 | [//]: # ( ```)
362 |
363 | [//]: # (* **/finance_products** (List all finance products))
364 |
365 | [//]: # ( ```python)
366 |
367 | [//]: # ( cg.get_finance_products())
368 |
369 | [//]: # ( ```)
370 |
371 | [//]: # (
)
372 |
373 | indexes
374 |
375 |
376 | * **/indexes**
377 |
378 | _List all market indexes_
379 | ```python
380 | cg.get_indexes()
381 | ```
382 | * **/indexes/{market_id}/{id}**
383 |
384 | _Get market index by market id and index id_
385 | ```python
386 | cg.get_indexes_by_market_id_and_index_id()
387 | ```
388 | * **/indexes/list**
389 |
390 | _List market indexes id and name_
391 | ```python
392 | cg.get_indexes_list()
393 | ```
394 |
395 |
396 | derivatives
397 |
398 |
399 | * **/derivatives**
400 |
401 | _List all derivative tickers_
402 | ```python
403 | cg.get_derivatives()
404 | ```
405 | * **/derivatives/exchanges**
406 |
407 | _List all derivative exchanges_
408 | ```python
409 | cg.get_derivatives_exchanges()
410 | ```
411 | * **/derivatives/exchanges/{id}**
412 |
413 | _Show derivative exchange data_
414 | ```python
415 | cg.get_derivatives_exchanges_by_id()
416 | ```
417 | * **/derivatives/exchanges/list**
418 |
419 | _List all derivative exchanges name and identifier_
420 | ```python
421 | cg.get_derivatives_exchanges_list()
422 | ```
423 |
424 |
425 | nfts (beta)
426 |
427 |
428 | * **/nfts/list**
429 |
430 | _List all supported NFT ids, paginated by 100 items per page, paginated to 100 items_
431 | ```python
432 | cg.get_nfts_list()
433 | ```
434 | * **/nfts/{id}**
435 |
436 | _Get current data (name, price_floor, volume_24h ...) for an NFT collection. native_currency (string) is only a representative of the currency_
437 | ```python
438 | cg.get_nfts_by_id()
439 | ```
440 | * **/nfts/{asset_platform_id}/contract/{contract_address}**
441 |
442 | _Get current data (name, price_floor, volume_24h ...) for an NFT collection. native_currency (string) is only a representative of the currency_
443 | ```python
444 | cg.get_nfts_collection_by_asset_platform_id_and_contract_address()
445 | ```
446 |
447 | * [Pro API] 💼 **/nfts/markets**
448 |
449 | _Query all the supported NFT collections with floor price, market cap, volume and market related data on CoinGecko_
450 | ```python
451 | cg.get_nfts_markets()
452 | ```
453 |
454 | * [Pro API] 💼 **/nfts/{id}/market_chart**
455 |
456 | _Query historical market data of a NFT collection, including floor price, market cap, and 24h volume, by number of days away from now_
457 | ```python
458 | cg.get_nfts_market_chart_by_id()
459 | ```
460 |
461 | * [Pro API] 💼 **/nfts/{asset_platform_id}/contract/{contract_address}/market_chart**
462 |
463 | _Query historical market data of a NFT collection, including floor price, market cap, and 24h volume, by number of days away from now based on the provided contract address_
464 | ```python
465 | cg.get_ntfs_market_chart_by_asset_platform_id_and_contract_address()
466 | ```
467 |
468 | * [Pro API] 💼 **/nfts/{id}/tickers**
469 |
470 | _Query the latest floor price and 24h volume of a NFT collection, on each NFT marketplace, e.g. OpenSea and LooksRare_
471 | ```python
472 | cg.get_nfts_tickers_by_id()
473 | ```
474 |
475 |
476 |
477 | [//]: # (status_updates
)
478 |
479 | [//]: # ()
480 |
481 | [//]: # ()
482 | [//]: # (* **/status_updates** (List all status_updates with data (description, category, created_at, user, user_title and pin)))
483 |
484 | [//]: # ( ```python)
485 |
486 | [//]: # ( cg.get_status_updates())
487 |
488 | [//]: # ( ```)
489 |
490 | [//]: # (
)
491 |
492 | [//]: # (events
)
493 |
494 | [//]: # ()
495 |
496 | [//]: # ()
497 | [//]: # (* **/events** (Get events, paginated by 100))
498 |
499 | [//]: # ( ```python)
500 |
501 | [//]: # ( cg.get_events())
502 |
503 | [//]: # ( ```)
504 |
505 | [//]: # (* **/events/countries** (Get list of event countries))
506 |
507 | [//]: # ( ```python)
508 |
509 | [//]: # ( cg.get_events_countries())
510 |
511 | [//]: # ( ```)
512 |
513 | [//]: # (* **/events/types** (Get list of events types))
514 |
515 | [//]: # ( ```python)
516 |
517 | [//]: # ( cg.get_events_types())
518 |
519 | [//]: # ( ```)
520 |
521 | [//]: # (
)
522 |
523 | exchange_rates
524 |
525 |
526 | * **/exchange_rates**
527 |
528 | _Get BTC-to-Currency exchange rates_
529 | ```python
530 | cg.get_exchange_rates()
531 | ```
532 |
533 |
534 | search
535 |
536 |
537 | * **/search**
538 |
539 | _Search for coins, categories and markets on CoinGecko_
540 | ```python
541 | cg.search()
542 | ```
543 |
544 |
545 | trending
546 |
547 |
548 | * **/search/trending**
549 |
550 | _Get trending search coins (Top-7) on CoinGecko in the last 24 hours_
551 | ```python
552 | cg.get_search_trending()
553 | ```
554 |
555 |
556 | global
557 |
558 |
559 | * **/global**
560 |
561 | _Get cryptocurrency global data_
562 | ```python
563 | cg.get_global()
564 | ```
565 | * **/global/decentralized_finance_defi**
566 |
567 | _Get cryptocurrency global decentralized finance(defi) data_
568 | ```python
569 | cg.get_global_decentralized_finance_defi()
570 | ```
571 |
572 | * [Pro API] 💼 **/global/market_cap_chart**
573 |
574 | _Query historical global market cap and volume data by number of days away from now)_
575 | ```python
576 | cg.get_global_market_cap_chart()
577 | ```
578 |
579 |
580 |
581 | companies (beta)
582 |
583 |
584 | * **/companies/public_treasury/{coin_id}**
585 |
586 | _Query public companies’ bitcoin or ethereum holdings_
587 | ```python
588 | cg.get_companies_public_treasury_by_coin_id()
589 | ```
590 |
591 |
592 | ### Test
593 |
594 | #### Installation
595 | Install required packages for testing using:
596 | ```bash
597 | pip install pytest responses
598 | ```
599 |
600 | #### Usage
601 |
602 | Run unit tests with:
603 |
604 | ```
605 | # after installing pytest and responses using pip3
606 | pytest tests
607 | ```
608 |
609 | ## License
610 | [MIT](https://choosealicense.com/licenses/mit/)
611 |
--------------------------------------------------------------------------------
/pycoingecko/__init__.py:
--------------------------------------------------------------------------------
1 | from .api import CoinGeckoAPI
2 | from .version import __version__
3 |
--------------------------------------------------------------------------------
/pycoingecko/api.py:
--------------------------------------------------------------------------------
1 | import json
2 | import requests
3 |
4 | from requests.adapters import HTTPAdapter
5 | from requests.packages.urllib3.util.retry import Retry
6 |
7 | from .utils import func_args_preprocessing
8 |
9 |
10 | class CoinGeckoAPI:
11 | __API_URL_BASE = 'https://api.coingecko.com/api/v3/'
12 | __PRO_API_URL_BASE = 'https://pro-api.coingecko.com/api/v3/'
13 |
14 | def __init__(self, api_key: str = '', retries=5, demo_api_key: str = ''):
15 |
16 | self.extra_params = None
17 | # self.headers = None
18 | if api_key:
19 | self.api_base_url = self.__PRO_API_URL_BASE
20 | self.extra_params = {'x_cg_pro_api_key': api_key}
21 | # self.headers = {"accept": "application/json",
22 | # "x-cg-pro-api-key": api_key}
23 | else:
24 | self.api_base_url = self.__API_URL_BASE
25 | if demo_api_key:
26 | self.extra_params = {'x_cg_demo_api_key': demo_api_key}
27 | # self.headers = {"accept": "application/json",
28 | # "x-cg-demo-api-key": demo_api_key}
29 |
30 | self.request_timeout = 120
31 |
32 | self.session = requests.Session()
33 | retries = Retry(total=retries, backoff_factor=0.5, status_forcelist=[502, 503, 504])
34 | self.session.mount('https://', HTTPAdapter(max_retries=retries))
35 |
36 | # self.session.headers = self.headers
37 |
38 | def __request(self, url, params):
39 | # if using pro or demo version of CoinGecko with api key, inject key in every call
40 | if self.extra_params is not None:
41 | params.update(self.extra_params)
42 |
43 | try:
44 | response = self.session.get(url, params=params, timeout=self.request_timeout)
45 | except requests.exceptions.RequestException:
46 | raise
47 |
48 | try:
49 | response.raise_for_status()
50 | # self._headers = response.headers
51 | content = json.loads(response.content.decode('utf-8'))
52 | return content
53 | except Exception as e:
54 | # check if json (with error message) is returned
55 | try:
56 | content = json.loads(response.content.decode('utf-8'))
57 | raise ValueError(content)
58 | # if no json
59 | except json.decoder.JSONDecodeError:
60 | pass
61 |
62 | raise
63 |
64 | # def __api_url_params(self, api_url, params, api_url_has_params=False):
65 | # # if using pro version of CoinGecko, inject key in every call
66 | # if self.api_key:
67 | # params['x_cg_pro_api_key'] = self.api_key
68 | #
69 | # if params:
70 | # # if api_url contains already params and there is already a '?' avoid
71 | # # adding second '?' (api_url += '&' if '?' in api_url else '?'); causes
72 | # # issues with request parametes (usually for endpoints with required
73 | # # arguments passed as parameters)
74 | # api_url += '&' if api_url_has_params else '?'
75 | # for key, value in params.items():
76 | # if type(value) == bool:
77 | # value = str(value).lower()
78 | #
79 | # api_url += "{0}={1}&".format(key, value)
80 | # api_url = api_url[:-1]
81 | # return api_url
82 |
83 | # ---------- PING ----------#
84 | def ping(self, **kwargs):
85 | """Check API server status"""
86 |
87 | api_url = '{0}ping'.format(self.api_base_url)
88 | # api_url = self.__api_url_params(api_url, kwargs)
89 |
90 | return self.__request(api_url, kwargs)
91 |
92 | # ---------- KEY ----------#
93 | def key(self, **kwargs):
94 | """Monitor your account's API usage, including rate limits, monthly total credits, remaining credits, and more"""
95 |
96 | api_url = '{0}key'.format(self.api_base_url)
97 | # api_url = self.__api_url_params(api_url, kwargs)
98 |
99 | return self.__request(api_url, kwargs)
100 |
101 | # ---------- SIMPLE ----------#
102 | @func_args_preprocessing
103 | def get_price(self, ids, vs_currencies, **kwargs):
104 | """Get the current price of any cryptocurrencies in any other supported currencies that you need"""
105 |
106 | ids = ids.replace(' ', '')
107 | kwargs['ids'] = ids
108 | vs_currencies = vs_currencies.replace(' ', '')
109 | kwargs['vs_currencies'] = vs_currencies
110 |
111 | api_url = '{0}simple/price'.format(self.api_base_url)
112 | # api_url = self.__api_url_params(api_url, kwargs)
113 |
114 | return self.__request(api_url, kwargs)
115 |
116 | @func_args_preprocessing
117 | def get_token_price(self, id, contract_addresses, vs_currencies, **kwargs):
118 | """Get the current price of any tokens on this coin (ETH only at this stage as per api docs) in any other supported currencies that you need"""
119 |
120 | contract_addresses = contract_addresses.replace(' ', '')
121 | kwargs['contract_addresses'] = contract_addresses
122 | vs_currencies = vs_currencies.replace(' ', '')
123 | kwargs['vs_currencies'] = vs_currencies
124 |
125 | api_url = '{0}simple/token_price/{1}'.format(self.api_base_url, id)
126 | # api_url = self.__api_url_params(api_url, kwargs)
127 | return self.__request(api_url, kwargs)
128 |
129 | @func_args_preprocessing
130 | def get_supported_vs_currencies(self, **kwargs):
131 | """Get list of supported_vs_currencies"""
132 |
133 | api_url = '{0}simple/supported_vs_currencies'.format(self.api_base_url)
134 | # api_url = self.__api_url_params(api_url, kwargs)
135 |
136 | return self.__request(api_url, kwargs)
137 |
138 | # ---------- COINS ----------#
139 | @func_args_preprocessing
140 | def get_coins(self, **kwargs):
141 | """List all coins with data (name, price, market, developer, community, etc)"""
142 |
143 | api_url = '{0}coins'.format(self.api_base_url)
144 | # ['order', 'per_page', 'page', 'localization']
145 | # api_url = self.__api_url_params(api_url, kwargs)
146 |
147 | return self.__request(api_url, kwargs)
148 |
149 | @func_args_preprocessing
150 | def get_coin_top_gainers_losers(self, vs_currency, **kwargs):
151 | """Get top gainers and losers"""
152 |
153 | kwargs['vs_currency'] = vs_currency
154 |
155 | api_url = '{0}coins/top_gainers_losers'.format(self.api_base_url)
156 |
157 | return self.__request(api_url, kwargs)
158 |
159 | @func_args_preprocessing
160 | def get_coins_list_new(self, **kwargs):
161 | """This endpoint allows you to query the latest 200 coins that recently listed on CoinGecko"""
162 |
163 | api_url = '{0}coins/list/new'.format(self.api_base_url)
164 | # api_url = self.__api_url_params(api_url, kwargs)
165 |
166 | return self.__request(api_url, kwargs)
167 |
168 | @func_args_preprocessing
169 | def get_coins_list(self, **kwargs):
170 | """List all supported coins id, name and symbol (no pagination required)"""
171 |
172 | api_url = '{0}coins/list'.format(self.api_base_url)
173 | # api_url = self.__api_url_params(api_url, kwargs)
174 |
175 | return self.__request(api_url, kwargs)
176 |
177 | @func_args_preprocessing
178 | def get_coins_markets(self, vs_currency, **kwargs):
179 | """List all supported coins price, market cap, volume, and market related data"""
180 |
181 | kwargs['vs_currency'] = vs_currency
182 |
183 | api_url = '{0}coins/markets'.format(self.api_base_url)
184 | # api_url = self.__api_url_params(api_url, kwargs)
185 |
186 | return self.__request(api_url, kwargs)
187 |
188 | @func_args_preprocessing
189 | def get_coin_by_id(self, id, **kwargs):
190 | """Get current data (name, price, market, ... including exchange tickers) for a coin"""
191 |
192 | api_url = '{0}coins/{1}/'.format(self.api_base_url, id)
193 | # api_url = self.__api_url_params(api_url, kwargs)
194 |
195 | return self.__request(api_url, kwargs)
196 |
197 | @func_args_preprocessing
198 | def get_coin_ticker_by_id(self, id, **kwargs):
199 | """Get coin tickers (paginated to 100 items)"""
200 |
201 | api_url = '{0}coins/{1}/tickers'.format(self.api_base_url, id)
202 | # api_url = self.__api_url_params(api_url, kwargs)
203 |
204 | return self.__request(api_url, kwargs)
205 |
206 | @func_args_preprocessing
207 | def get_coin_history_by_id(self, id, date, **kwargs):
208 | """Get historical data (name, price, market, stats) at a given date for a coin"""
209 |
210 | kwargs['date'] = date
211 |
212 | api_url = '{0}coins/{1}/history'.format(self.api_base_url, id)
213 | # api_url = self.__api_url_params(api_url, kwargs)
214 |
215 | return self.__request(api_url, kwargs)
216 |
217 | @func_args_preprocessing
218 | def get_coin_market_chart_by_id(self, id, vs_currency, days, **kwargs):
219 | """Get historical market data include price, market cap, and 24h volume (granularity auto)"""
220 |
221 | # api_url = '{0}coins/{1}/market_chart?vs_currency={2}&days={3}'.format(self.api_base_url, id, vs_currency, days)
222 | # api_url = self.__api_url_params(api_url, kwargs, api_url_has_params=True)
223 | api_url = '{0}coins/{1}/market_chart'.format(self.api_base_url, id, vs_currency, days)
224 | kwargs['vs_currency'] = vs_currency
225 | kwargs['days'] = days
226 |
227 | return self.__request(api_url, kwargs)
228 |
229 | @func_args_preprocessing
230 | def get_coin_market_chart_range_by_id(self, id, vs_currency, from_timestamp, to_timestamp, **kwargs):
231 | """Get historical market data include price, market cap, and 24h volume within a range of timestamp (granularity auto)"""
232 |
233 | # api_url = '{0}coins/{1}/market_chart/range?vs_currency={2}&from={3}&to={4}'.format(self.api_base_url, id,
234 | # vs_currency, from_timestamp,
235 | # to_timestamp)
236 | # api_url = self.__api_url_params(api_url, kwargs, api_url_has_params=True)
237 | api_url = '{0}coins/{1}/market_chart/range'.format(self.api_base_url, id)
238 | kwargs['vs_currency'] = vs_currency
239 | kwargs['from'] = from_timestamp
240 | kwargs['to'] = to_timestamp
241 |
242 | return self.__request(api_url, kwargs)
243 |
244 | # @func_args_preprocessing
245 | # def get_coin_status_updates_by_id(self, id, **kwargs):
246 | # """Get status updates for a given coin"""
247 | #
248 | # api_url = '{0}coins/{1}/status_updates'.format(self.api_base_url, id)
249 | # api_url = self.__api_url_params(api_url, kwargs)
250 | #
251 | # return self.__request(api_url)
252 |
253 | @func_args_preprocessing
254 | def get_coin_ohlc_by_id(self, id, vs_currency, days, **kwargs):
255 | """Get coin's OHLC"""
256 |
257 | # api_url = '{0}coins/{1}/ohlc?vs_currency={2}&days={3}'.format(self.api_base_url, id, vs_currency, days)
258 | # api_url = self.__api_url_params(api_url, kwargs, api_url_has_params=True)
259 | api_url = '{0}coins/{1}/ohlc'.format(self.api_base_url, id)
260 | kwargs['vs_currency'] = vs_currency
261 | kwargs['days'] = days
262 |
263 | return self.__request(api_url, kwargs)
264 |
265 | @func_args_preprocessing
266 | def get_coin_ohlc_by_id_range(self, id, vs_currency, from_timestamp, to_timestamp, interval, **kwargs):
267 | """Get coin's OHLC within a range of timestamp"""
268 |
269 | kwargs['vs_currency'] = vs_currency
270 | kwargs['from'] = from_timestamp
271 | kwargs['to'] = to_timestamp
272 | kwargs['interval'] = interval
273 |
274 | api_url = '{0}coins/{1}/ohlc/range'.format(self.api_base_url, id)
275 | # api_url = self.__api_url_params(api_url, kwargs)
276 |
277 | return self.__request(api_url, kwargs)
278 |
279 | @func_args_preprocessing
280 | def get_coin_circulating_supply_chart(self, id, days, **kwargs):
281 | """Get coin's circulating supply chart"""
282 |
283 | kwargs['days'] = days
284 |
285 | api_url = '{0}coins/{1}/circulating_supply_chart'.format(self.api_base_url, id)
286 | # api_url = self.__api_url_params(api_url, kwargs)
287 |
288 | return self.__request(api_url, kwargs)
289 |
290 | @func_args_preprocessing
291 | def get_coin_circulating_supply_chart_range(self, id, from_timestamp, to_timestamp, **kwargs):
292 | """Get coin's circulating supply chart within a range of timestamp"""
293 |
294 | kwargs['from'] = from_timestamp
295 | kwargs['to'] = to_timestamp
296 |
297 | api_url = '{0}coins/{1}/circulating_supply_chart/range'.format(self.api_base_url, id)
298 | # api_url = self.__api_url_params(api_url, kwargs)
299 |
300 | return self.__request(api_url, kwargs)
301 |
302 | @func_args_preprocessing
303 | def get_coin_total_supply_chart(self, id, days, **kwargs):
304 | """Get coin's total supply chart"""
305 |
306 | kwargs['days'] = days
307 |
308 | api_url = '{0}coins/{1}/total_supply_chart'.format(self.api_base_url, id)
309 | # api_url = self.__api_url_params(api_url, kwargs)
310 |
311 | return self.__request(api_url, kwargs)
312 |
313 | @func_args_preprocessing
314 | def get_coin_total_supply_chart_range(self, id, from_timestamp, to_timestamp, **kwargs):
315 | """Get coin's total supply chart within a range of timestamp"""
316 |
317 | kwargs['from'] = from_timestamp
318 | kwargs['to'] = to_timestamp
319 |
320 | api_url = '{0}coins/{1}/total_supply_chart/range'.format(self.api_base_url, id)
321 | # api_url = self.__api_url_params(api_url, kwargs)
322 |
323 | return self.__request(api_url, kwargs)
324 |
325 | # ---------- Contract ----------#
326 | @func_args_preprocessing
327 | def get_coin_info_from_contract_address_by_id(self, id, contract_address, **kwargs):
328 | """Get coin info from contract address"""
329 |
330 | api_url = '{0}coins/{1}/contract/{2}'.format(self.api_base_url, id, contract_address)
331 | # api_url = self.__api_url_params(api_url, kwargs)
332 |
333 | return self.__request(api_url, kwargs)
334 |
335 | @func_args_preprocessing
336 | def get_coin_market_chart_from_contract_address_by_id(self, id, contract_address, vs_currency, days, **kwargs):
337 | """Get historical market data include price, market cap, and 24h volume (granularity auto) from a contract address"""
338 |
339 | # api_url = '{0}coins/{1}/contract/{2}/market_chart/?vs_currency={3}&days={4}'.format(self.api_base_url, id,
340 | # contract_address,
341 | # vs_currency, days)
342 | # api_url = self.__api_url_params(api_url, kwargs, api_url_has_params=True)
343 | api_url = '{0}coins/{1}/contract/{2}/market_chart'.format(self.api_base_url, id, contract_address)
344 | kwargs['vs_currency'] = vs_currency
345 | kwargs['days'] = days
346 |
347 | return self.__request(api_url, kwargs)
348 |
349 | @func_args_preprocessing
350 | def get_coin_market_chart_range_from_contract_address_by_id(self, id, contract_address, vs_currency, from_timestamp,
351 | to_timestamp, **kwargs):
352 | """Get historical market data include price, market cap, and 24h volume within a range of timestamp (granularity auto) from a contract address"""
353 |
354 | # api_url = '{0}coins/{1}/contract/{2}/market_chart/range?vs_currency={3}&from={4}&to={5}'.format(
355 | # self.api_base_url, id, contract_address, vs_currency, from_timestamp, to_timestamp)
356 | # api_url = self.__api_url_params(api_url, kwargs, api_url_has_params=True)
357 | api_url = '{0}coins/{1}/contract/{2}/market_chart/range'.format(self.api_base_url, id, contract_address)
358 | kwargs['vs_currency'] = vs_currency
359 | kwargs['from'] = from_timestamp
360 | kwargs['to'] = to_timestamp
361 |
362 | return self.__request(api_url, kwargs)
363 |
364 | # ---------- ASSET PLATFORMS ----------#
365 | @func_args_preprocessing
366 | def get_asset_platforms(self, **kwargs):
367 | """List all asset platforms (Blockchain networks)"""
368 |
369 | api_url = '{0}asset_platforms'.format(self.api_base_url)
370 | # api_url = self.__api_url_params(api_url, kwargs)
371 |
372 | return self.__request(api_url, kwargs)
373 |
374 | @func_args_preprocessing
375 | def get_asset_platform_by_id(self, asset_platform_id, **kwargs):
376 | """ List all asset platforms (Blockchain networks) by platform id """
377 |
378 | api_url = '{0}token_lists/{1}/all.json'.format(self.api_base_url, asset_platform_id)
379 | # api_url = self.__api_url_params(api_url, kwargs)
380 |
381 | return self.__request(api_url, kwargs)
382 |
383 | # ---------- CATEGORIES ----------#
384 | @func_args_preprocessing
385 | def get_coins_categories_list(self, **kwargs):
386 | """List all categories"""
387 |
388 | api_url = '{0}coins/categories/list'.format(self.api_base_url)
389 | # api_url = self.__api_url_params(api_url, kwargs)
390 |
391 | return self.__request(api_url, kwargs)
392 |
393 | @func_args_preprocessing
394 | def get_coins_categories(self, **kwargs):
395 | """List all categories with market data"""
396 |
397 | api_url = '{0}coins/categories'.format(self.api_base_url)
398 | # api_url = self.__api_url_params(api_url, kwargs)
399 |
400 | return self.__request(api_url, kwargs)
401 |
402 | # ---------- EXCHANGES ----------#
403 | @func_args_preprocessing
404 | def get_exchanges_list(self, **kwargs):
405 | """List all exchanges"""
406 |
407 | api_url = '{0}exchanges'.format(self.api_base_url)
408 | # api_url = self.__api_url_params(api_url, kwargs)
409 |
410 | return self.__request(api_url, kwargs)
411 |
412 | @func_args_preprocessing
413 | def get_exchanges_id_name_list(self, **kwargs):
414 | """List all supported markets id and name (no pagination required)"""
415 |
416 | api_url = '{0}exchanges/list'.format(self.api_base_url)
417 | # api_url = self.__api_url_params(api_url, kwargs)
418 |
419 | return self.__request(api_url, kwargs)
420 |
421 | @func_args_preprocessing
422 | def get_exchanges_by_id(self, id, **kwargs):
423 | """Get exchange volume in BTC and tickers"""
424 |
425 | api_url = '{0}exchanges/{1}'.format(self.api_base_url, id)
426 | # api_url = self.__api_url_params(api_url, kwargs)
427 |
428 | return self.__request(api_url, kwargs)
429 |
430 | @func_args_preprocessing
431 | def get_exchanges_tickers_by_id(self, id, **kwargs):
432 | """Get exchange tickers (paginated, 100 tickers per page)"""
433 |
434 | api_url = '{0}exchanges/{1}/tickers'.format(self.api_base_url, id)
435 | # api_url = self.__api_url_params(api_url, kwargs)
436 |
437 | return self.__request(api_url, kwargs)
438 |
439 | # @func_args_preprocessing
440 | # def get_exchanges_status_updates_by_id(self, id, **kwargs):
441 | # """Get status updates for a given exchange"""
442 | #
443 | # api_url = '{0}exchanges/{1}/status_updates'.format(self.api_base_url, id)
444 | # api_url = self.__api_url_params(api_url, kwargs)
445 | #
446 | # return self.__request(api_url)
447 |
448 | @func_args_preprocessing
449 | def get_exchanges_volume_chart_by_id(self, id, days, **kwargs):
450 | """Get volume chart data for a given exchange"""
451 |
452 | kwargs['days'] = days
453 |
454 | api_url = '{0}exchanges/{1}/volume_chart'.format(self.api_base_url, id)
455 | # api_url = self.__api_url_params(api_url, kwargs)
456 |
457 | return self.__request(api_url, kwargs)
458 |
459 | @func_args_preprocessing
460 | def get_exchanges_volume_chart_by_id_within_time_range(self, id, from_timestamp, to_timestamp, **kwargs):
461 | """Get volume chart data for a given exchange within a time range"""
462 |
463 | kwargs['from'] = from_timestamp
464 | kwargs['to'] = to_timestamp
465 |
466 | api_url = '{0}exchanges/{1}/volume_chart/range'.format(self.api_base_url, id)
467 | # api_url = self.__api_url_params(api_url, kwargs)
468 |
469 | return self.__request(api_url, kwargs)
470 |
471 | # # ---------- FINANCE ----------#
472 | # @func_args_preprocessing
473 | # def get_finance_platforms(self, **kwargs):
474 | # """Get cryptocurrency finance platforms data"""
475 | #
476 | # api_url = '{0}finance_platforms'.format(self.api_base_url)
477 | # api_url = self.__api_url_params(api_url, kwargs)
478 | #
479 | # return self.__request(api_url)
480 | #
481 | # @func_args_preprocessing
482 | # def get_finance_products(self, **kwargs):
483 | # """Get cryptocurrency finance products data"""
484 | #
485 | # api_url = '{0}finance_products'.format(self.api_base_url)
486 | # api_url = self.__api_url_params(api_url, kwargs)
487 | #
488 | # return self.__request(api_url)
489 |
490 | # ---------- INDEXES ----------#
491 | @func_args_preprocessing
492 | def get_indexes(self, **kwargs):
493 | """List all market indexes"""
494 |
495 | api_url = '{0}indexes'.format(self.api_base_url)
496 | # api_url = self.__api_url_params(api_url, kwargs)
497 |
498 | return self.__request(api_url, kwargs)
499 |
500 | # @func_args_preprocessing
501 | # def get_indexes_by_id(self, id, **kwargs):
502 | # """Get market index by id"""
503 | #
504 | # api_url = '{0}indexes/{1}'.format(self.api_base_url, id)
505 | # api_url = self.__api_url_params(api_url, kwargs)
506 | #
507 | # return self.__request(api_url)
508 |
509 | @func_args_preprocessing
510 | def get_indexes_by_market_id_and_index_id(self, market_id, id, **kwargs):
511 | """Get market index by market id and index id"""
512 |
513 | api_url = '{0}indexes/{1}/{2}'.format(self.api_base_url, market_id, id)
514 | # api_url = self.__api_url_params(api_url, kwargs)
515 |
516 | return self.__request(api_url, kwargs)
517 |
518 | @func_args_preprocessing
519 | def get_indexes_list(self, **kwargs):
520 | """List market indexes id and name"""
521 |
522 | api_url = '{0}indexes/list'.format(self.api_base_url)
523 | # api_url = self.__api_url_params(api_url, kwargs)
524 |
525 | return self.__request(api_url, kwargs)
526 |
527 | # ---------- DERIVATIVES ----------#
528 | @func_args_preprocessing
529 | def get_derivatives(self, **kwargs):
530 | """List all derivative tickers"""
531 |
532 | api_url = '{0}derivatives'.format(self.api_base_url)
533 | # api_url = self.__api_url_params(api_url, kwargs)
534 |
535 | return self.__request(api_url, kwargs)
536 |
537 | @func_args_preprocessing
538 | def get_derivatives_exchanges(self, **kwargs):
539 | """List all derivative tickers"""
540 |
541 | api_url = '{0}derivatives/exchanges'.format(self.api_base_url)
542 | # api_url = self.__api_url_params(api_url, kwargs)
543 |
544 | return self.__request(api_url, kwargs)
545 |
546 | @func_args_preprocessing
547 | def get_derivatives_exchanges_by_id(self, id, **kwargs):
548 | """List all derivative tickers"""
549 |
550 | api_url = '{0}derivatives/exchanges/{1}'.format(self.api_base_url, id)
551 | # api_url = self.__api_url_params(api_url, kwargs)
552 |
553 | return self.__request(api_url, kwargs)
554 |
555 | @func_args_preprocessing
556 | def get_derivatives_exchanges_list(self, **kwargs):
557 | """List all derivative tickers"""
558 |
559 | api_url = '{0}derivatives/exchanges/list'.format(self.api_base_url)
560 | # api_url = self.__api_url_params(api_url, kwargs)
561 |
562 | return self.__request(api_url, kwargs)
563 |
564 | # ---------- NFTS (BETA) ----------#
565 | @func_args_preprocessing
566 | def get_nfts_list(self, **kwargs):
567 | """List all supported NFT ids, paginated by 100 items per page, paginated to 100 items"""
568 |
569 | api_url = '{0}nfts/list'.format(self.api_base_url)
570 | # api_url = self.__api_url_params(api_url, kwargs)
571 |
572 | return self.__request(api_url, kwargs)
573 |
574 | @func_args_preprocessing
575 | def get_nfts_by_id(self, id, **kwargs):
576 | """Get current data (name, price_floor, volume_24h ...) for an NFT collection. native_currency (string) is only a representative of the currency"""
577 |
578 | api_url = '{0}nfts/{1}'.format(self.api_base_url, id)
579 | # api_url = self.__api_url_params(api_url, kwargs)
580 |
581 | return self.__request(api_url, kwargs)
582 |
583 | @func_args_preprocessing
584 | def get_nfts_by_asset_platform_id_and_contract_address(self, asset_platform_id, contract_address, **kwargs):
585 | """Get current data (name, price_floor, volume_24h ...) for an NFT collection. native_currency (string) is only a representative of the currency"""
586 |
587 | api_url = '{0}nfts/{1}/contract/{2}'.format(self.api_base_url, asset_platform_id, contract_address)
588 | # api_url = self.__api_url_params(api_url, kwargs)
589 |
590 | return self.__request(api_url, kwargs)
591 |
592 | @func_args_preprocessing
593 | def get_nfts_markets(self, **kwargs):
594 | """This endpoint allows you to query all the supported NFT collections with floor price, market cap, volume and market related data on CoinGecko"""
595 |
596 | api_url = '{0}nfts/markets'.format(self.api_base_url)
597 | # api_url = self.__api_url_params(api_url, kwargs)
598 |
599 | return self.__request(api_url, kwargs)
600 |
601 | @func_args_preprocessing
602 | def get_nfts_market_chart_by_id(self, id, days, **kwargs):
603 | """This endpoint allows you query historical market data of a NFT collection, including floor price, market cap, and 24h volume, by number of days away from now"""
604 |
605 | kwargs['days'] = days
606 |
607 | api_url = '{0}nfts/{1}/market_chart'.format(self.api_base_url, id)
608 | # api_url = self.__api_url_params(api_url, kwargs)
609 |
610 | return self.__request(api_url, kwargs)
611 |
612 | @func_args_preprocessing
613 | def get_ntfs_market_chart_by_asset_platform_id_and_contract_address(self, asset_platform_id, contract_address, days, **kwargs):
614 | """This endpoint allows you query historical market data of a NFT collection, including floor price, market cap, and 24h volume, by number of days away from now based on the provided contract address"""
615 |
616 | kwargs['days'] = days
617 |
618 | api_url = '{0}nfts/{1}/contract/{2}/market_chart'.format(self.api_base_url, asset_platform_id, contract_address)
619 | # api_url = self.__api_url_params(api_url, kwargs)
620 |
621 | return self.__request(api_url, kwargs)
622 |
623 | @func_args_preprocessing
624 | def get_nfts_tickers_by_id(self, id, **kwargs):
625 | """This endpoint allows you to query the latest floor price and 24h volume of a NFT collection, on each NFT marketplace, e.g. OpenSea and LooksRare"""
626 |
627 | api_url = '{0}nfts/{1}/tickers'.format(self.api_base_url, id)
628 | # api_url = self.__api_url_params(api_url, kwargs)
629 |
630 | return self.__request(api_url, kwargs)
631 |
632 | # # ---------- STATUS UPDATES ----------#
633 | # @func_args_preprocessing
634 | # def get_status_updates(self, **kwargs):
635 | # """List all status_updates with data (description, category, created_at, user, user_title and pin)"""
636 | #
637 | # api_url = '{0}status_updates'.format(self.api_base_url)
638 | # api_url = self.__api_url_params(api_url, kwargs)
639 | #
640 | # return self.__request(api_url)
641 |
642 | # # ---------- EVENTS ----------#
643 | # @func_args_preprocessing
644 | # def get_events(self, **kwargs):
645 | # """Get events, paginated by 100"""
646 | #
647 | # api_url = '{0}events'.format(self.api_base_url)
648 | # api_url = self.__api_url_params(api_url, kwargs)
649 | #
650 | # return self.__request(api_url)
651 | #
652 | # @func_args_preprocessing
653 | # def get_events_countries(self, **kwargs):
654 | # """Get list of event countries"""
655 | #
656 | # api_url = '{0}events/countries'.format(self.api_base_url)
657 | # api_url = self.__api_url_params(api_url, kwargs)
658 | #
659 | # return self.__request(api_url)
660 | #
661 | # @func_args_preprocessing
662 | # def get_events_types(self, **kwargs):
663 | # """Get list of event types"""
664 | #
665 | # api_url = '{0}events/types'.format(self.api_base_url)
666 | # api_url = self.__api_url_params(api_url, kwargs)
667 | #
668 | # return self.__request(api_url)
669 |
670 | # ---------- EXCHANGE-RATES ----------#
671 | @func_args_preprocessing
672 | def get_exchange_rates(self, **kwargs):
673 | """Get BTC-to-Currency exchange rates"""
674 |
675 | api_url = '{0}exchange_rates'.format(self.api_base_url)
676 | # api_url = self.__api_url_params(api_url, kwargs)
677 |
678 | return self.__request(api_url, kwargs)
679 |
680 | # ---------- SEARCH ----------#
681 | @func_args_preprocessing
682 | def search(self, query, **kwargs):
683 | """Search for coins, categories and markets on CoinGecko"""
684 |
685 | # api_url = '{0}search?query={1}'.format(self.api_base_url, query)
686 | # api_url = self.__api_url_params(api_url, kwargs, api_url_has_params=True)
687 | api_url = '{0}search'.format(self.api_base_url)
688 | kwargs['query'] = query
689 |
690 | return self.__request(api_url, kwargs)
691 |
692 | # ---------- TRENDING ----------#
693 | @func_args_preprocessing
694 | def get_search_trending(self, **kwargs):
695 | """Get top 7 trending coin searches"""
696 |
697 | api_url = '{0}search/trending'.format(self.api_base_url)
698 | # api_url = self.__api_url_params(api_url, kwargs)
699 |
700 | return self.__request(api_url, kwargs)
701 |
702 | # ---------- GLOBAL ----------#
703 | @func_args_preprocessing
704 | def get_global(self, **kwargs):
705 | """Get cryptocurrency global data"""
706 |
707 | api_url = '{0}global'.format(self.api_base_url)
708 | # api_url = self.__api_url_params(api_url, kwargs)
709 |
710 | return self.__request(api_url, kwargs)['data']
711 |
712 | @func_args_preprocessing
713 | def get_global_decentralized_finance_defi(self, **kwargs):
714 | """Get cryptocurrency global decentralized finance(defi) data"""
715 |
716 | api_url = '{0}global/decentralized_finance_defi'.format(self.api_base_url)
717 | # api_url = self.__api_url_params(api_url, kwargs)
718 |
719 | return self.__request(api_url, kwargs)['data']
720 |
721 | @func_args_preprocessing
722 | def get_global_market_cap_chart(self, days, **kwargs):
723 | """Get cryptocurrency global market cap chart data"""
724 |
725 | kwargs['days'] = days
726 |
727 | api_url = '{0}global/market_cap_chart'.format(self.api_base_url)
728 | # api_url = self.__api_url_params(api_url, kwargs)
729 |
730 | return self.__request(api_url, kwargs)
731 |
732 | # ---------- COMPANIES ----------#
733 | @func_args_preprocessing
734 | def get_companies_public_treasury_by_coin_id(self, coin_id, **kwargs):
735 | """Get public companies data"""
736 |
737 | api_url = '{0}companies/public_treasury/{1}'.format(self.api_base_url, coin_id)
738 | # api_url = self.__api_url_params(api_url, kwargs)
739 |
740 | return self.__request(api_url, kwargs)
741 |
--------------------------------------------------------------------------------
/pycoingecko/utils.py:
--------------------------------------------------------------------------------
1 | from functools import wraps
2 |
3 |
4 | def func_args_preprocessing(func):
5 | """Return function that converts list input arguments to comma-separated strings"""
6 |
7 | @wraps(func)
8 | def input_args(*args, **kwargs):
9 |
10 | # check in **kwargs for lists and booleans
11 | for v in kwargs:
12 | kwargs[v] = arg_preprocessing(kwargs[v])
13 | # check in *args for lists and booleans
14 | args = [arg_preprocessing(v) for v in args]
15 |
16 | return func(*args, **kwargs)
17 |
18 | return input_args
19 |
20 |
21 | def arg_preprocessing(arg_v):
22 | """Return the values of an argument after preprocessing"""
23 |
24 | # check if arg is list and convert it to comma-separated string
25 | if isinstance(arg_v, list):
26 | arg_v = ','.join(arg_v)
27 | # check if arg is boolean and convert it to string
28 | elif isinstance(arg_v, bool):
29 | arg_v = str(arg_v).lower()
30 |
31 | return arg_v
32 |
33 |
34 | def get_comma_separated_values(values):
35 | """Return the values as a comma-separated string"""
36 |
37 | # Make sure values is a list or tuple
38 | if not isinstance(values, list) and not isinstance(values, tuple):
39 | values = [values]
40 |
41 | return ','.join(values)
42 |
43 |
--------------------------------------------------------------------------------
/pycoingecko/version.py:
--------------------------------------------------------------------------------
1 | __version__ = '3.2.0'
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | # from distutils.core import setup
2 | import setuptools
3 |
4 | version = {}
5 | exec(open('./pycoingecko/version.py').read(), version)
6 | # print(version['__version__'])
7 |
8 | setuptools.setup(
9 | name='pycoingecko',
10 | version=version['__version__'],
11 | packages=['pycoingecko', ],
12 | license='MIT',
13 | description='Python wrapper around the CoinGecko API',
14 | long_description=open('README.md').read(),
15 | long_description_content_type="text/markdown",
16 | author='Christoforou Manolis',
17 | author_email='emchristoforou@gmail.com',
18 | install_requires=['requests'],
19 | url='https://github.com/man-c/pycoingecko',
20 | classifiers=[
21 | "Programming Language :: Python :: 3",
22 | "Programming Language :: Python :: 2",
23 | "License :: OSI Approved :: MIT License",
24 | "Operating System :: OS Independent",
25 | ],
26 | )
27 |
--------------------------------------------------------------------------------
/tests/test_api.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | import requests.exceptions
3 | import responses
4 | import unittest
5 | import unittest.mock as mock
6 |
7 | from pycoingecko import CoinGeckoAPI
8 | from requests.exceptions import HTTPError
9 |
10 |
11 | class TestWrapper(unittest.TestCase):
12 |
13 | @responses.activate
14 | def test_connection_error(self):
15 | with pytest.raises(requests.exceptions.ConnectionError):
16 | CoinGeckoAPI().ping()
17 |
18 | @responses.activate
19 | def test_failed_ping(self):
20 | # Arrange
21 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/ping',
22 | status = 404)
23 | exception = HTTPError("HTTP Error")
24 |
25 | # Act Assert
26 | with pytest.raises(HTTPError) as HE:
27 | CoinGeckoAPI().ping()
28 |
29 | @responses.activate
30 | def test_ping(self):
31 | # Arrange
32 | ping_json = { 'gecko_says':'(V3) To the Moon!' }
33 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/ping',
34 | json = ping_json, status = 200)
35 |
36 | # Act
37 | response = CoinGeckoAPI().ping()
38 |
39 | ## Assert
40 | assert response == ping_json
41 |
42 |
43 | #---------- SIMPLE ----------#
44 |
45 | #---------- /simple/price ----------#
46 | @responses.activate
47 | def test_get_price(self):
48 | # Arrange
49 | coins_json_sample = {"bitcoin": {"usd": 7984.89}}
50 |
51 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd',
52 | json = coins_json_sample, status = 200)
53 |
54 | # Act
55 | response = CoinGeckoAPI().get_price('bitcoin', 'usd')
56 |
57 | ## Assert
58 | assert response == coins_json_sample
59 |
60 | @responses.activate
61 | def test_failed_get_price(self):
62 | # Arrange
63 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd',
64 | status = 404)
65 | exception = HTTPError("HTTP Error")
66 |
67 | # Act Assert
68 | with pytest.raises(HTTPError) as HE:
69 | CoinGeckoAPI().get_price('bitcoin', 'usd')
70 |
71 | #---------- /simple/token_price/{id} ----------#
72 | @responses.activate
73 | def test_get_token_price(self):
74 | # Arrange
75 | coins_json_sample = {'0xB8c77482e45F1F44dE1745F52C74426C631bDD52': {'bnb': 1.0, 'bnb_market_cap': 144443301.0, 'bnb_24h_vol': 17983938.686249834, 'last_updated_at': 1558704332}}
76 |
77 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/simple/token_price/ethereum?include_market_cap=true&include_24hr_vol=true&include_last_updated_at=true&contract_addresses=0xB8c77482e45F1F44dE1745F52C74426C631bDD52&vs_currencies=bnb',
78 | json = coins_json_sample, status = 200)
79 |
80 | # Act
81 | response = CoinGeckoAPI().get_token_price('ethereum', '0xB8c77482e45F1F44dE1745F52C74426C631bDD52', 'bnb', include_market_cap='true', include_24hr_vol='true', include_last_updated_at='true')
82 |
83 | ## Assert
84 | assert response == coins_json_sample
85 |
86 | @responses.activate
87 | def test_failed_get_token_price(self):
88 | # Arrange
89 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/simple/token_price/ethereum?include_market_cap=true&include_24hr_vol=true&include_last_updated_at=true&contract_addresses=0xB8c77482e45F1F44dE1745F52C74426C631bDD52&vs_currencies=bnb',
90 | status = 404)
91 | exception = HTTPError("HTTP Error")
92 |
93 | # Act Assert
94 | with pytest.raises(HTTPError) as HE:
95 | CoinGeckoAPI().get_token_price('ethereum', '0xB8c77482e45F1F44dE1745F52C74426C631bDD52', 'bnb', include_market_cap='true', include_24hr_vol='true', include_last_updated_at='true')
96 |
97 | #---------- /simple/supported_vs_currencies ----------#
98 | @responses.activate
99 | def test_get_supported_vs_currencies(self):
100 | # Arrange
101 | coins_json_sample = ['btc', 'eth', 'ltc', 'bch', 'bnb', 'eos', 'xrp', 'xlm', 'usd', 'aed', 'ars', 'aud', 'bdt', 'bhd', 'bmd', 'brl', 'cad', 'chf', 'clp', 'cny', 'czk', 'dkk', 'eur', 'gbp', 'hkd', 'huf', 'idr', 'ils', 'inr', 'jpy', 'krw', 'kwd', 'lkr', 'mmk', 'mxn', 'myr', 'nok', 'nzd', 'php', 'pkr', 'pln', 'rub', 'sar', 'sek', 'sgd', 'thb', 'try', 'twd', 'uah', 'vef', 'vnd', 'zar', 'xdr', 'xag', 'xau']
102 |
103 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/simple/supported_vs_currencies',
104 | json = coins_json_sample, status = 200)
105 |
106 | # Act
107 | response = CoinGeckoAPI().get_supported_vs_currencies()
108 |
109 | ## Assert
110 | assert response == coins_json_sample
111 |
112 | @responses.activate
113 | def test_failed_get_supported_vs_currencies(self):
114 | # Arrange
115 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/simple/supported_vs_currencies',
116 | status = 404)
117 | exception = HTTPError("HTTP Error")
118 |
119 | # Act Assert
120 | with pytest.raises(HTTPError) as HE:
121 | CoinGeckoAPI().get_supported_vs_currencies()
122 |
123 |
124 | #---------- /simple/supported_vs_currencies ----------#
125 | @responses.activate
126 | def test_get_supported_vs_currencies(self):
127 | # Arrange
128 | coins_json_sample = ['btc', 'eth', 'ltc', 'bch', 'bnb', 'eos', 'xrp', 'xlm', 'usd', 'aed', 'ars', 'aud', 'bdt', 'bhd', 'bmd', 'brl', 'cad', 'chf', 'clp', 'cny', 'czk', 'dkk', 'eur', 'gbp', 'hkd', 'huf', 'idr', 'ils', 'inr', 'jpy', 'krw', 'kwd', 'lkr', 'mmk', 'mxn', 'myr', 'nok', 'nzd', 'php', 'pkr', 'pln', 'rub', 'sar', 'sek', 'sgd', 'thb', 'try', 'twd', 'uah', 'vef', 'vnd', 'zar', 'xdr', 'xag', 'xau']
129 |
130 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/simple/supported_vs_currencies',
131 | json = coins_json_sample, status = 200)
132 |
133 | # Act
134 | response = CoinGeckoAPI().get_supported_vs_currencies()
135 |
136 | ## Assert
137 | assert response == coins_json_sample
138 |
139 | @responses.activate
140 | def test_failed_get_supported_vs_currencies(self):
141 | # Arrange
142 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/simple/supported_vs_currencies',
143 | status = 404)
144 | exception = HTTPError("HTTP Error")
145 |
146 | # Act Assert
147 | with pytest.raises(HTTPError) as HE:
148 | CoinGeckoAPI().get_supported_vs_currencies()
149 |
150 |
151 | #---------- COINS ----------#
152 |
153 | #---------- /price/coins ----------#
154 | @responses.activate
155 | def test_failed_get_coins(self):
156 | # Arrange
157 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins',
158 | status = 404)
159 | exception = HTTPError("HTTP Error")
160 |
161 | # Act Assert
162 | with pytest.raises(HTTPError) as HE:
163 | CoinGeckoAPI().get_coins()
164 |
165 | @responses.activate
166 | def test_get_coins(self):
167 | # Arrange
168 | coins_json_sample = [ { "id": "bitcoin", "symbol": "btc", "name": "Bitcoin", "localization": { "en": "Bitcoin", "es": "Bitcoin", "de": "Bitcoin", "nl": "Bitcoin", "pt": "Bitcoin", "fr": "Bitcoin", "it": "Bitcoin", "hu": "Bitcoin", "ro": "Bitcoin", "sv": "Bitcoin", "pl": "Bitcoin", "id": "Bitcoin", "zh": "Bitcoin", "zh-tw": "Bitcoin", "ja": "Bitcoin", "ko": "Bitcoin", "ru": "Bitcoin", "ar": "Bitcoin", "th": "Bitcoin", "vi": "Bitcoin", "tr": "Bitcoin" }, "image": { "thumb": "https://assets.coingecko.com/coins/images/1/thumb/bitcoin.png?1510040391", "small": "https://assets.coingecko.com/coins/images/1/small/bitcoin.png?1510040391", "large": "https://assets.coingecko.com/coins/images/1/large/bitcoin.png?1510040391" } } ]
169 |
170 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins',
171 | json = coins_json_sample, status = 200)
172 |
173 | # Act
174 | response = CoinGeckoAPI().get_coins()
175 |
176 | ## Assert
177 | assert response == coins_json_sample
178 |
179 |
180 | #---------- /price/coins/list ----------#
181 | @responses.activate
182 | def test_failed_get_coins_list(self):
183 | # Arrange
184 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/list',
185 | status = 404)
186 | exception = HTTPError("HTTP Error")
187 |
188 | # Act
189 | with pytest.raises(HTTPError) as HE:
190 | CoinGeckoAPI().get_coins_list()
191 |
192 | @responses.activate
193 | def test_get_coins_list(self):
194 | # Arrange
195 | coins_json_sample = [ { "id": "bitcoin", "symbol": "btc", "name": "Bitcoin" }, { "id": "litecoin", "symbol": "ltc", "name": "Litecoin" }, { "id": "auroracoin", "symbol": "aur", "name": "Auroracoin" }, { "id": "peercoin", "symbol": "ppc", "name": "Peercoin" }, { "id": "dogecoin", "symbol": "doge", "name": "Dogecoin" }, { "id": "nxt", "symbol": "nxt", "name": "NXT" }, { "id": "omni", "symbol": "omni", "name": "Omni (Mastercoin)" } ]
196 |
197 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/list',
198 | json = coins_json_sample, status = 200)
199 |
200 | # Act
201 | response = CoinGeckoAPI().get_coins_list()
202 |
203 | ## Assert
204 | assert response == coins_json_sample
205 |
206 |
207 | #---------- /price/coins/markets ----------#
208 | @responses.activate
209 | def test_failed_get_coins_markets(self):
210 | # Arrange
211 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd',
212 | status = 404)
213 | exception = HTTPError("HTTP Error")
214 |
215 | # Act Assert
216 | with pytest.raises(HTTPError) as HE:
217 | CoinGeckoAPI().get_coins_markets('usd')
218 |
219 | @responses.activate
220 | def test_get_coins_markets(self):
221 | # Arrange
222 | markets_json_sample = [ { "id": "bitcoin", "symbol": "btc", "name": "Bitcoin", "image": "https://assets.coingecko.com/coins/images/1/large/bitcoin.png?1510040391", "current_price": 7015.11823787848, "market_cap": 120934444800.105, "market_cap_rank": 1, "total_volume": 6121170828.21792, "high_24h": 7054.21193531031, "low_24h": 6668.29100755648, "price_change_24h": "299.72373285508", "price_change_percentage_24h": "4.46323343521924", "market_cap_change_24h": "5197755386.983", "market_cap_change_percentage_24h": "4.4910178555649", "circulating_supply": "17236100.0", "ath": 19665.3949272416, "ath_change_percentage": -64.2200698307594, "ath_date": "2017-12-16T00:00:00.000Z", "roi": 0, "last_updated": "2018-08-28T12:12:53.390Z" } ]
223 |
224 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd',
225 | json = markets_json_sample, status = 200)
226 |
227 | # Act
228 | response = CoinGeckoAPI().get_coins_markets('usd')
229 |
230 | ## Assert
231 | assert response == markets_json_sample
232 |
233 |
234 | #---------- /price/coins/{id} ----------#
235 | @responses.activate
236 | def test_failed_get_coin_by_id(self):
237 | # Arrange
238 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/bitcoin/',
239 | status = 404)
240 | exception = HTTPError("HTTP Error")
241 |
242 | # Act Assert
243 | with pytest.raises(HTTPError) as HE:
244 | CoinGeckoAPI().get_coin_by_id('bitcoin')
245 |
246 |
247 | @responses.activate
248 | def test_get_coin_by_id(self):
249 | # Arrange
250 | bitcoin_json_sample = { "id": "bitcoin", "symbol": "btc", "name": "Bitcoin", "categories": [ "Cryptocurrency" ], "localization": { "en": "Bitcoin", "es": "Bitcoin", "de": "Bitcoin", "nl": "Bitcoin", "pt": "Bitcoin", "fr": "Bitcoin", "it": "Bitcoin", "hu": "Bitcoin", "ro": "Bitcoin", "sv": "Bitcoin", "pl": "Bitcoin", "id": "Bitcoin", "zh": "比特币", "zh-tw": "比特幣", "ja": "ビットコイン", "ko": "비트코인", "ru": "биткоина", "ar": "بيتكوين", "th": "บิตคอยน์", "vi": "Bitcoin", "tr": "Bitcoin"}}
251 |
252 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/bitcoin/',
253 | json = bitcoin_json_sample, status = 200)
254 |
255 | # Act
256 | response = CoinGeckoAPI().get_coin_by_id('bitcoin')
257 |
258 | ## Assert
259 | assert response == bitcoin_json_sample
260 |
261 |
262 | #---------- /price/coins/{id}/tickers ----------#
263 | @responses.activate
264 | def test_failed_get_coin_ticker_by_id(self):
265 | # Arrange
266 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/bitcoin/tickers',
267 | status = 404)
268 | exception = HTTPError("HTTP Error")
269 |
270 | # Act Assert
271 | with pytest.raises(HTTPError) as HE:
272 | CoinGeckoAPI().get_coin_ticker_by_id('bitcoin')
273 |
274 |
275 | @responses.activate
276 | def test_get_get_coin_ticker_by_id(self):
277 | # Arrange
278 | bitcoin_json_sample = {'name': 'Bitcoin', 'tickers': [{'base': 'BTC', 'target': 'USDT', 'market': {'name': 'BW.com', 'identifier': 'bw', 'has_trading_incentive': False}, 'last': 7963.0, ' volume': 93428.7568, 'converted_last': {'btc': 0.99993976, 'eth': 31.711347, 'usd': 7979.23}, 'converted_volume': {'btc': 93423, 'eth': 2962752, 'usd': 745489919}, ' bid_ask_spread_percentage': 0.111969, 'timestamp': '2019-05-24T11:20:14+00:00', 'is_anomaly': False, 'is_stale': False, 'trade_url': 'https://www.bw.com/trade/btc_us dt', 'coin_id': 'bitcoin'}]}
279 |
280 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/bitcoin/tickers',
281 | json = bitcoin_json_sample, status = 200)
282 |
283 | # Act
284 | response = CoinGeckoAPI().get_coin_ticker_by_id('bitcoin')
285 |
286 | ## Assert
287 | assert response == bitcoin_json_sample
288 |
289 |
290 | #---------- /price/coins/{id}/history ----------#
291 | @responses.activate
292 | def test_failed_get_coin_history_by_id(self):
293 | # Arrange
294 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/bitcoin/history?date=27-08-2018',
295 | status = 404)
296 | exception = HTTPError("HTTP Error")
297 |
298 | # Act Assert
299 | with pytest.raises(HTTPError) as HE:
300 | CoinGeckoAPI().get_coin_history_by_id('bitcoin', '27-08-2018')
301 |
302 |
303 | @responses.activate
304 | def test_get_coin_history_by_id(self):
305 | # Arrange
306 | history_json_sample = { "id": "bitcoin", "symbol": "btc", "name": "Bitcoin", "localization": { "en": "Bitcoin", "es": "Bitcoin", "de": "Bitcoin", "nl": "Bitcoin", "pt": "Bitcoin", "fr": "Bitcoin", "it": "Bitcoin", "hu": "Bitcoin", "ro": "Bitcoin", "sv": "Bitcoin", "pl": "Bitcoin", "id": "Bitcoin", "zh": "比特币", "zh-tw": "比特幣", "ja": "ビットコイン", "ko": "비트코인", "ru": "биткоина", "ar": "بيتكوين", "th": "บิตคอยน์", "vi": "Bitcoin", "tr": "Bitcoin" } }
307 |
308 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/bitcoin/history?date=27-08-2018',
309 | json = history_json_sample, status = 200)
310 |
311 | # Act
312 | response = CoinGeckoAPI().get_coin_history_by_id('bitcoin', '27-08-2018')
313 |
314 | ## Assert
315 | assert response == history_json_sample
316 |
317 |
318 | #---------- /price/coins/{id}/market_chart ----------#
319 | @responses.activate
320 | def test_failed_get_coin_market_chart_by_id(self):
321 | # Arrange
322 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/bitcoin/market_chart?vs_currency=usd&days=1',
323 | status = 404)
324 | exception = HTTPError("HTTP Error")
325 |
326 | # Act Assert
327 | with pytest.raises(HTTPError) as HE:
328 | CoinGeckoAPI().get_coin_market_chart_by_id('bitcoin', 'usd', 1)
329 |
330 |
331 | @responses.activate
332 | def test_get_coin_market_chart_by_id(self):
333 | # Arrange
334 | json_response = { "prices": [ [ 1535373899623, 6756.942910425894 ], [ 1535374183927, 6696.894541693875 ], [ 1535374496401, 6689.990513793263 ], [ 1535374779118, 6668.291007556478 ], [ 1535375102688, 6703.7499879964 ], [ 1535375384209, 6706.898948451269 ] ] }
335 |
336 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/bitcoin/market_chart?vs_currency=usd&days=1',
337 | json = json_response, status = 200)
338 |
339 | # Act
340 | response = CoinGeckoAPI().get_coin_market_chart_by_id('bitcoin', 'usd', 1)
341 |
342 | ## Assert
343 | assert response == json_response
344 |
345 |
346 | #---------- /price/coins/{id}/status_updates ----------#
347 | # @responses.activate
348 | # def test_failed_get_coin_status_updates_by_id(self):
349 | # # Arrange
350 | # responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/litecoin/status_updates',
351 | # status = 404)
352 | # exception = HTTPError("HTTP Error")
353 | #
354 | # # Act Assert
355 | # with pytest.raises(HTTPError) as HE:
356 | # CoinGeckoAPI().get_coin_status_updates_by_id('litecoin')
357 | #
358 | #
359 | # @responses.activate
360 | # def test_get_coin_status_updates_by_id(self):
361 | # # Arrange
362 | # json_response = [ {'description': 'Travala.com Partners with Litecoin Foundation to Champion Crypto Payments. \r\n#TravelWithLitecoin www.travala.com/litecoin\r\n\r\nRead the full announcement here: bit.ly/2LumY3b', 'category': 'general', 'created_at': '2019-05-14T13:56:43.282Z', 'user': 'Keith Yong', 'user_title': 'Operations Director', 'pin': False, 'project': {'type': 'Coin', 'id': 'litecoin', 'name': 'Litecoin', 'symbol': 'ltc', 'image': {'thumb': 'https://assets.coingecko.com/coins/images/2/thumb/litecoin.png?1547033580', 'small': 'https://assets.coingecko.com/coins/images/2/small/litecoin.png?1547033580', 'large': 'https://assets.coingecko.com/coins/images/2/large/litecoin.png?1547033580'}}} ]
363 | #
364 | # responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/litecoin/status_updates',
365 | # json = json_response, status = 200)
366 | #
367 | # # Act
368 | # response = CoinGeckoAPI().get_coin_status_updates_by_id('litecoin')
369 | #
370 | # ## Assert
371 | # assert response == json_response
372 |
373 |
374 | #---------- /price/coins/{id}/contract/{contract_address} ----------#
375 | @responses.activate
376 | def test_failed_get_coin_info_from_contract_address_by_id(self):
377 | # Arrange
378 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/ethereum/contract/0x0D8775F648430679A709E98d2b0Cb6250d2887EF',
379 | status = 404)
380 | exception = HTTPError("HTTP Error")
381 |
382 | # Act Assert
383 | with pytest.raises(HTTPError) as HE:
384 | CoinGeckoAPI().get_coin_info_from_contract_address_by_id(id='ethereum',contract_address='0x0D8775F648430679A709E98d2b0Cb6250d2887EF')
385 |
386 |
387 | @responses.activate
388 | def test_get_coin_info_from_contract_address_by_id(self):
389 | # Arrange
390 | json_response = {'id': '0x', 'symbol': 'zrx', 'name': '0x', 'block_time_in_minutes': 0, 'categories': ['Protocol'], 'localization': {'en': '0x', 'es': '0x', 'de': '0x', 'nl': '0x', 'pt': '0x', 'fr': '0x', 'it': '0x', 'hu': '0x', 'ro': '0x', 'sv': '0x', 'pl': '0x', 'id': '0x', 'zh': '0x协议', 'zh-tw': '0x協議', 'ja': 'ロエックス', 'ko': '제로엑스', 'ru': '0x', 'ar': '0x', 'th': '0x', 'vi': '0x', 'tr': '0x'}}
391 |
392 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/coins/ethereum/contract/0x0D8775F648430679A709E98d2b0Cb6250d2887EF',
393 | json = json_response, status = 200)
394 |
395 | # Act
396 | response = CoinGeckoAPI().get_coin_info_from_contract_address_by_id(id='ethereum',contract_address='0x0D8775F648430679A709E98d2b0Cb6250d2887EF')
397 |
398 | ## Assert
399 | assert response == json_response
400 |
401 |
402 | #---------- EXCHANGES ----------#
403 |
404 |
405 | #---------- /exchanges ----------#
406 | @responses.activate
407 | def test_failed_get_exchanges_list(self):
408 | # Arrange
409 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/exchanges',
410 | status = 404)
411 | exception = HTTPError("HTTP Error")
412 |
413 | # Act Assert
414 | with pytest.raises(HTTPError) as HE:
415 | CoinGeckoAPI().get_exchanges_list()
416 |
417 |
418 | @responses.activate
419 | def test_get_exchanges_list(self):
420 | # Arrange
421 | json_response = [ { "id": "bitforex", "name": "Bitforex", "description": "", "url": "https://www.bitforex.com/", "image": "https://assets.coingecko.com/markets/images/214/small/bitforex.jpg?1533199114", "has_trading_incentive": "true", "trade_volume_24h_btc": 680266.637119918 }, { "id": "binance", "name": "Binance", "description": "Binance is a China-based cryptocurrency exchange that lists most of the Chinese coins. It is a popular exchange for its huge number of Initial Coin Offering (ICO) listings and low fees.", "url": "https://www.binance.com/", "image": "https://assets.coingecko.com/markets/images/52/small/binance.jpg?1519353250", "has_trading_incentive": "false", "trade_volume_24h_btc": 189744.350072168 } ]
422 |
423 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/exchanges',
424 | json = json_response, status = 200)
425 |
426 | # Act
427 | response = CoinGeckoAPI().get_exchanges_list()
428 |
429 | ## Assert
430 | assert response == json_response
431 |
432 |
433 | #---------- /exchanges/list ----------#
434 | @responses.activate
435 | def test_failed_get_exchanges_id_name_list(self):
436 | # Arrange
437 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/exchanges/list',
438 | status = 404)
439 | exception = HTTPError("HTTP Error")
440 |
441 | # Act Assert
442 | with pytest.raises(HTTPError) as HE:
443 | CoinGeckoAPI().get_exchanges_id_name_list()
444 |
445 |
446 | @responses.activate
447 | def test_get_exchanges_id_name_list(self):
448 | # Arrange
449 | json_response = [{'id': 'abcc', 'name': 'ABCC'}, {'id': 'acx', 'name': 'ACX'}, {'id': 'airswap', 'name': 'AirSwap'}]
450 |
451 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/exchanges/list',
452 | json = json_response, status = 200)
453 |
454 | # Act
455 | response = CoinGeckoAPI().get_exchanges_id_name_list()
456 |
457 | ## Assert
458 | assert response == json_response
459 |
460 |
461 |
462 | #---------- /exchanges/{id} ----------#
463 | @responses.activate
464 | def test_failed_get_exchanges_by_id(self):
465 | # Arrange
466 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/exchanges/bitforex',
467 | status = 404)
468 | exception = HTTPError("HTTP Error")
469 |
470 | # Act Assert
471 | with pytest.raises(HTTPError) as HE:
472 | CoinGeckoAPI().get_exchanges_by_id('bitforex')
473 |
474 |
475 | @responses.activate
476 | def test_get_exchanges_by_id(self):
477 | # Arrange
478 | json_response = { "name": "Bitforex", "has_trading_incentive": "true", "trade_volume_24h_btc": 680266.637119918, "tickers": [ { "base": "BTC", "target": "USDT", "market": { "name": "Bitforex", "identifier": "bitforex", "has_trading_incentive": "true" }, "last": 7039.55, "converted_last": { "btc": "1.001711841446200081963480716", "eth": "24.4986463149997536428213651518458101194944", "usd": "7043.71831205846008527901735024184383795812" }, "volume": 447378.73, "converted_volume": { "btc": "448144.5713519911718500979009072226084", "eth": "10960173.27267390510353832059421689917189597190216256", "usd": "3151209752.222085727501972469271259554059845134991788" }, "timestamp": "2018-08-28T12:46:25.719Z", "is_anomaly": "false" } ] }
479 |
480 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/exchanges/bitforex',
481 | json = json_response, status = 200)
482 |
483 | # Act
484 | response = CoinGeckoAPI().get_exchanges_by_id('bitforex')
485 |
486 | ## Assert
487 | assert response == json_response
488 |
489 |
490 | #---------- EXCHANGE RATES ----------#
491 |
492 | #---------- /exchange_rates ----------#
493 | @responses.activate
494 | def test_failed_get_exchange_rates(self):
495 | # Arrange
496 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/exchange_rates',
497 | status = 404)
498 | exception = HTTPError("HTTP Error")
499 |
500 | # Act Assert
501 | with pytest.raises(HTTPError) as HE:
502 | CoinGeckoAPI().get_exchange_rates()
503 |
504 |
505 | @responses.activate
506 | def test_get_exchange_rates(self):
507 | # Arrange
508 | json_response = { "rates": { "btc": { "name": "Bitcoin", "unit": "Ƀ", "value": 0, "type": "crypto" }, "eth": { "name": "Ether", "unit": "Ξ", "value": 24.451, "type": "crypto" }, "usd": { "name": "US Dollar", "unit": "$", "value": 7040.152, "type": "fiat" } } }
509 |
510 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/exchange_rates',
511 | json = json_response, status = 200)
512 |
513 | # Act
514 | response = CoinGeckoAPI().get_exchange_rates()
515 |
516 | ## Assert
517 | assert response == json_response
518 |
519 | #---------- TRENDING ----------#
520 |
521 | #---------- /search/trending ----------#
522 | @responses.activate
523 | def test_failed_search_get_trending(self):
524 | # Arrange
525 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/search/trending',
526 | status = 404)
527 | exception = HTTPError("HTTP Error")
528 |
529 | # Act Assert
530 | with pytest.raises(HTTPError) as HE:
531 | CoinGeckoAPI().get_search_trending()
532 |
533 |
534 | @responses.activate
535 | def test_get_search_trending(self):
536 | # Arrange
537 | json_response = { "coins": [{"item": {"id":"iris-network", "name":"IRISnet", "symbol":"IRIS", "market_cap_rank":159, "thumb":"/coins/images/5135/thumb/IRIS.png", "score":0}}, {"item": {"id":"hegic", "name":"Hegic", "symbol":"HEGIC", "market_cap_rank":386, "thumb":"/coins/images/12454/thumb/Hegic.png", "score":1}}, {"item": {"id":"moonswap", "name":"MoonSwap", "symbol":"MOON", "market_cap_rank":373, "thumb":"/coins/images/12441/thumb/moon.jpg", "score":2}}, {"item": {"id":"yfv-finance", "name":"YFValue", "symbol":"YFV", "market_cap_rank":179, "thumb":"/coins/images/12198/thumb/yfv.jpg", "score":3}}, {"item": {"id":"yffi-finance", "name":"yffi finance", "symbol":"YFFI", "market_cap_rank":531, "thumb":"/coins/images/11940/thumb/yffi-finance.jpg", "score":4}}, {"item": {"id":"relevant", "name":"Relevant", "symbol":"REL", "market_cap_rank":915, "thumb":"/coins/images/11586/thumb/Relevant.png", "score":5}}, {"item": {"id":"sake-token", "name":"SakeToken", "symbol":"SAKE", "market_cap_rank":503, "thumb":"/coins/images/12428/thumb/sake.png", "score":6}}], "exchanges": [] }
538 |
539 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/search/trending',
540 | json = json_response, status = 200)
541 |
542 | # Act
543 | response = CoinGeckoAPI().get_search_trending()
544 |
545 | ## Assert
546 | assert response == json_response
547 |
548 | #---------- GLOBAL ----------#
549 |
550 | #---------- /global ----------#
551 | @responses.activate
552 | def test_failed_get_global(self):
553 | # Arrange
554 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/global',
555 | status = 404)
556 | exception = HTTPError("HTTP Error")
557 |
558 | # Act Assert
559 | with pytest.raises(HTTPError) as HE:
560 | CoinGeckoAPI().get_global()
561 |
562 |
563 | @responses.activate
564 | def test_get_global(self):
565 | # Arrange
566 | json_response = { "data": { "active_cryptocurrencies": 2517, "upcoming_icos": 360, "ongoing_icos": 423, "ended_icos": 2037, "markets": 197 } }
567 |
568 | responses.add(responses.GET, 'https://api.coingecko.com/api/v3/global',
569 | json = json_response, status = 200)
570 |
571 | # Act
572 | response = CoinGeckoAPI().get_global()
573 |
574 | ## Assert
575 | expected_response = { "active_cryptocurrencies": 2517, "upcoming_icos": 360, "ongoing_icos": 423, "ended_icos": 2037, "markets": 197 }
576 | assert response == expected_response
577 |
578 |
579 |
580 | # #---------- FINANCE ----------#
581 | #
582 | # #---------- /finance_platforms ----------#
583 | #
584 | # @responses.activate
585 | # def test_failed_get_finance_platforms(self):
586 | # # Arrange
587 | # responses.add(responses.GET, 'https://api.coingecko.com/api/v3/finance_platforms',
588 | # status = 404)
589 | # exception = HTTPError("HTTP Error")
590 | #
591 | # # Act Assert
592 | # with pytest.raises(HTTPError) as HE:
593 | # CoinGeckoAPI().get_finance_platforms()
594 | #
595 | # @responses.activate
596 | # def test_get_finance_platforms(self):
597 | # # Arrange
598 | # json_response = [{"name": "Binance Lending", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Celsius Network", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Compound Finance", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "dYdX", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Nexo", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Staked US", "facts": "", "category": "", "centralized": False, "website_url": "https://staked.us/"}, {"name": "Cobo", "facts": "", "category": "", "centralized": False, "website_url": "https://cobo.com/"}, {"name": "Crypto.com", "facts": "", "category": "", "centralized": True, "website_url": "https://crypto.com/en/"}]
599 | #
600 | # responses.add(responses.GET, 'https://api.coingecko.com/api/v3/finance_platforms',
601 | # json = json_response, status = 200)
602 | #
603 | # # Act
604 | # response = CoinGeckoAPI().get_finance_platforms()
605 | #
606 | # ## Assert
607 | # expected_response = [{"name": "Binance Lending", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Celsius Network", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Compound Finance", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "dYdX", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Nexo", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Staked US", "facts": "", "category": "", "centralized": False, "website_url": "https://staked.us/"}, {"name": "Cobo", "facts": "", "category": "", "centralized": False, "website_url": "https://cobo.com/"}, {"name": "Crypto.com", "facts": "", "category": "", "centralized": True, "website_url": "https://crypto.com/en/"}]
608 | # assert response == expected_response
609 | #
610 | # #---------- /finance_products ----------#
611 | #
612 | # @responses.activate
613 | # def test_failed_get_finance_products(self):
614 | # # Arrange
615 | # responses.add(responses.GET, 'https://api.coingecko.com/api/v3/finance_products',
616 | # status = 404)
617 | # exception = HTTPError("HTTP Error")
618 | #
619 | # # Act Assert
620 | # with pytest.raises(HTTPError) as HE:
621 | # CoinGeckoAPI().get_finance_products()
622 | #
623 | # @responses.activate
624 | # def test_get_finance_products(self):
625 | # # Arrange
626 | # json_response = [{"name": "Binance Lending", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Celsius Network", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Compound Finance", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "dYdX", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Nexo", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Staked US", "facts": "", "category": "", "centralized": False, "website_url": "https://staked.us/"}, {"name": "Cobo", "facts": "", "category": "", "centralized": False, "website_url": "https://cobo.com/"}, {"name": "Crypto.com", "facts": "", "category": "", "centralized": True, "website_url": "https://crypto.com/en/"}]
627 | #
628 | # responses.add(responses.GET, 'https://api.coingecko.com/api/v3/finance_platforms',
629 | # json = json_response, status = 200)
630 | #
631 | # # Act
632 | # response = CoinGeckoAPI().get_finance_platforms()
633 | #
634 | # ## Assert
635 | # expected_response = [{"name": "Binance Lending", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Celsius Network", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Compound Finance", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "dYdX", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Nexo", "facts": "", "category": "", "centralized": False, "website_url": ""}, {"name": "Staked US", "facts": "", "category": "", "centralized": False, "website_url": "https://staked.us/"}, {"name": "Cobo", "facts": "", "category": "", "centralized": False, "website_url": "https://cobo.com/"}, {"name": "Crypto.com", "facts": "", "category": "", "centralized": True, "website_url": "https://crypto.com/en/"}]
636 | # assert response == expected_response
637 |
--------------------------------------------------------------------------------