You are a member of the Info-Prov Team, and as such, your duty is to compose valuable cryptocurrency market insights for our customers. One important key metric is the evolution of the market capitalization of the largest coins throughout time.
Such information is available at CoinMarketCap, a popular site that offers real time data about the most popular assets in the crypto market.
See CoinMarketCap»
·
See the project»
·
How to use this repo
·
Report Bug
·
Request Feature
Table of Contents
Retrieve from CoinMarketCap API Listings Historical endpoint the top 10 coins with the largest market capitalization. For each of the retrieved coins, calculate the percentage its market capitalization represents compared to the group. For each coin, stores a document in a mongo db collection, with the following schema:
- symbol: the coin symbol
- price: coin price in USD
- market_cap: market capitalization in USD
- market_cap_pct: market capitalization percentage this coin represents out of the group of 10.
- last_updated: the timestamp associated with the data retrieved.
Further Requirements:
- Write it in python
- Set up a system that runs this process once every minute
PS: I ended up using the following endpoint: Crypto Listings Latest , which has the same structure as the historical endpoint and falls under the BASIC subscription.
Checked out the CoinMarketCap Postman collection which you can directly import into your postman account.
If you dont have a collection yet you can use the following code to create/drop a collection in a mongodb database:
-
mongo = being the URI-generated database in python flask
-
create + drop functions come from PyMongo
print("Creating coins collection...")
mongo.db.create_collection("coins")
print("Dropping coins collection...")
mongo.db.coins.drop()
Understood how to use the MarketCap Api
-
The parameters are defined based on the requirements listed above:
params = {
"sort": "market_cap",
"sort_dir": "desc",
"limit": 10
}
headers = {
"Accepts": "application/json",
"X-CMC_PRO_API_KEY": KEY
}
- Clone the repo
git clone https://github.com/vtwoptwo/coinmarketcap.git
Check out the outcome:
Make sure you have everything downloaded from the pre-requisites before continuing.
- Download MongoDB
- I created an account and downloaded the commmunity edition
- I created a mongodb:// database to test locally
- Set up a .venv env in my local folder
py -m venv .venv
.venv/Scripts/activate
- This is more of an iterative process but, you can install all your requirements at once using the following strucure for your requirements.txt
Flask==2.2.2
psycopg2==2.9.3
python-dotenv==0.21.0
pytest
pytest-cov
pymongo==3.1
requests==2.26.0
click==8.1.3
colorama==0.4.6
Flask==2.2.2
Flask-PyMongo==2.0.1
greenlet==1.1.3.post0
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.1
Werkzeug==2.2.2
pip install -r ./requirements.txt
- Make a get_data.py file and make sure you are receiving the right data:
Your response should resemble the following:
{'symbol': 'BTC', 'price': 17194.45140525171, 'market_cap': 330651019968.1309, 'market_cap_pct': 0.463055925215652, 'last_updated': '2022-12-10T18:22:00.000Z'}
{'symbol': 'ETH', 'price': 1271.2435795759775, 'market_cap': 155566991737.26785, 'market_cap_pct': 0.21786177250824543, 'last_updated': '2022-12-10T18:22:00.000Z'}
{'symbol': 'USDT', 'price': 1.0000662164008933, 'market_cap': 65712545071.71287, 'market_cap_pct': 0.09202628003201087, 'last_updated': '2022-12-10T18:22:00.000Z'}
{'symbol': 'BNB', 'price': 288.29730677866866, 'market_cap': 46118502210.35589, 'market_cap_pct': 0.0645860572655567, 'last_updated': '2022-12-10T18:22:00.000Z'}
{'symbol': 'USDC', 'price': 1.0000539139368854, 'market_cap': 42747086994.57803, 'market_cap_pct': 0.05986460262683032, 'last_updated': '2022-12-10T18:22:00.000Z'}
{'symbol': 'BUSD', 'price': 1.0001620378753022, 'market_cap': 22103565063.960773, 'market_cap_pct': 0.030954650532283898, 'last_updated': '2022-12-10T18:22:00.000Z'}
{'symbol': 'XRP', 'price': 0.38808885639422136, 'market_cap': 19557917047.384052, 'market_cap_pct': 0.027389630839609318, 'last_updated': '2022-12-10T18:22:00.000Z'}
{'symbol': 'DOGE', 'price': 0.09697167580648122, 'market_cap': 12865306344.687412, 'market_cap_pct': 0.018017051129000643, 'last_updated': '2022-12-10T18:22:00.000Z'}
{'symbol': 'ADA', 'price': 0.312804943710321, 'market_cap': 10781789464.849493, 'market_cap_pct': 0.015099216982930975, 'last_updated': '2022-12-10T18:22:00.000Z'}
{'symbol': 'MATIC', 'price': 0.9111297513428726, 'market_cap': 7958096509.406064, 'market_cap_pct': 0.01114481286788001, 'last_updated': '2022-12-10T18:22:00.000Z'}
- Make sure you are pushing the data into your collection
def call():
response = requests.get(BASE+ENDPOINT, params=params, headers=headers)
print(response)
data = response.json()
total_market_cap = 0
for coin in data["data"]:
total_market_cap += coin["quote"]["USD"]["market_cap"]
for coin in data["data"]:
symbol = coin["symbol"]
price = coin["quote"]["USD"]["price"]
market_cap = coin["quote"]["USD"]["market_cap"]
market_cap_pct = market_cap / total_market_cap
last_updated = coin["last_updated"]
document = {
"symbol": symbol,
"price": price,
"market_cap": market_cap,
"market_cap_pct": market_cap_pct,
"last_updated": last_updated
}
collection.insert_one(document)
alternatively you could also use the following:
collection.insert_many(documents)
- Note that Imade two files: one an executable and one a function to push to the mongodb collection.
-
This way I can either choose to run the process with a cron job every minute by running the get_data.py file, or create a website with a frontend which runs the api calls at the press of a button.
-
Limitations:
-
The api call should only be called every 60 seconds, as that is when the data renews at the endpoint.
-
I have never used MongoDB before this project. I recommend for people who want to try this, to read up on MongoDB and do some open source intro-exercises in order to understand some basic concepts.
-
Flask is not optimal for enterprise grade deployments: Django would be more suitable.
-
Frontend is not ideal.
I find vue.js much easier to implement and would do so if this were a larger project, but the following frontend also turned out alright.
How would you set up a system that runs this process once every minute?
I would use a Linux/Unix CLI. This way I can run the python script automatically at whichever interval I want. Check out more info here: Medium - Scheduling python scripts
Steps:
- Configure a cron file
crontab -e
***** /path/2/py /path/2/get_data.py
If I had to create dynamic dashboard I would probably use a different framework. Something fast... something like:
- Change the environment variables (I had a .env file locally), but you can use GITHUB secrets, or depending on your cloud service provider (e.g. Azure) you can globally configure environment variables for the web app.
The following files were used to prepare the document for production:
- create a .env
- config.py
- __ init __ . py
-
Go to GitHub Actions
-
Create a Build and a separate deploy workflow (You can do for both dev, prod, or test mode)
-
Use .yaml files to configure the workflow
See the open issues for a full list of proposed features (and known issues).
The idea is to create a nice and simple repo for CPP Basic Rules, information, definitions, best practices etc. Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
Don't forget to give the project a star! Thanks again!
- Fork the Project and create a feature:
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE.txt
for more information.