import streamlit as st
from PIL import Image
import pandas as pd
import base64
import matplotlib.pyplot as plt
from bs4 import BeautifulSoup
import requests
import json
import time
st.set_page_config(layout='wide')
# title
image = Image.open('logo.jpg')
st.image(image, width=500)
st.title('Crypto Price App')
st.markdown("""
This app retrieves crypto prices for top 100 crypto from CoinMarketCap.
""")
# page layout
col1 = st.sidebar
col2, col3 = st.beta_columns((2, 1))
# sidebar + main panel
col1.header('Input Options')
# Sidebar - currency price unit
currency_price_unit = col1.selectbox('Select currency for price', ('USD', 'BTC', 'ETH'))
# web scraping
@st.cache
def load_data():
cmc = requests.get('https://coinmarketcap.com')
soup = BeautifulSoup(cmc.content, 'html.parser')
data = soup.find('script', id='__NEXT_DATA__', type='application/json')
coins = {}
coin_data = json.loads(data.contents[0])
listings = coin_data['props']['initialState']['cryptocurrency']['listingLatest']['data']
for i in listings:
coins[str(i['id'])] = i['slug']
coin_name = []
coin_symbol = []
market_cap = []
percent_change_1h = []
percent_change_24h = []
percent_change_7d = []
price = []
volume_24h = []
for i in listings:
coin_name.append(i['slug'])
coin_symbol.append(i['symbol'])
price.append(i['quote'][currency_price_unit]['price'])
percent_change_1h.append(i['quote'][currency_price_unit]['percent_change_1h'])
percent_change_24h.append(i['quote'][currency_price_unit]['percent_change_7d'])
percent_change_7d.append(i['quote'][currency_price_unit]['percent_change_7d'])
market_cap.append(i['quote'][currency_price_unit]['market_cap'])
volume_24h.append(i['quote'][currency_price_unit]['volume_24h'])
df = pd.DataFrame(columns=['coin_name', 'coin_symbol', 'market_cap', 'percent_change_1h', 'percent_change_24h',
'percent_change_7d', 'price', 'volume_24h'])
df['coin_name'] = coin_name
df['coin_symbol'] = coin_symbol
df['price'] = price
df['percent_change_1h'] = percent_change_1h
df['percent_change_24h'] = percent_change_24h
df['percent_change_7d'] = percent_change_7d
df['market_cap'] = market_cap
df['volume_24h'] = volume_24h
return df
df = load_data()
# sidebar - crypto selections
sorted_coin = sorted(df['coin_symbol'])
selected_coin = col1.multiselect('Cryptocurrency', sorted_coin, sorted_coin)
df_selected_coin = df[(df['coin_symbol'].isin(selected_coin))]
## sidebar - number of coins to display
num_coin = col1.slider('Display Top N coins', 1, 100, 100)
df_coins = df_selected_coin[:num_coin]
## sidebar - percent change timeframe
percent_timeframe = col1.selectbox('Percent change time frame',
['7d', '24h', '1h'])
percent_dict = {'7d': 'percent_change_7d', '24h': 'percent_change_24h', '1h': 'percent_change_1h'}
selected_present_timeframe = percent_dict[percent_timeframe]
## Sidebar - sorting values
sort_values = col1.selectbox('Sort values?', ['Yes', 'No'])
col2.subheader('Price data of selected crypto')
col2.write(
'Data dimension: ' + str(df_selected_coin.shape[0]) + ' rows and ' + str(df_selected_coin.shape[1]) + ' columns.')
col2.dataframe(df_coins)
# download csv data
def filedownload(df):
csv = df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode()
href = f'<a href="data:file/csv;base64,{b64}" download="crypto.csv">Download CSV File</a>'
return href
col2.markdown(filedownload(df_selected_coin), unsafe_allow_html=True)
# preparing data for bar plot of % price change
col2.subheader('Table of % Price change')
df_change = pd.concat(
[df_coins.coin_symbol, df_coins.percent_change_1h, df_coins.percent_change_24h, df_coins.percent_change_7d], axis=1)
df_change = df_change.set_index('coin_symbol')
df_change['positive_percent_change_1h'] = df_change['percent_change_1h'] > 0
df_change['positive_percent_change_24h'] = df_change['percent_change_24h'] > 0
df_change['positive_percent_change_7d'] = df_change['percent_change_7d'] > 0
col2.dataframe(df_change)
# Conditional creation of Bar plot (time frame)
col3.subheader('Bar plot of % Price Change')
if percent_timeframe == '7d':
if sort_values == 'Yes':
df_change = df_change.sort_values(by=['percent_change_7d'])
col3.write('*7 days period*')
plt.figure(figsize=(5, 25))
plt.subplots_adjust(top=1, bottom=0)
df_change['percent_change_7d'].plot(kind='barh',
color=df_change.positive_percent_change_7d.map({True: 'g', False: 'r'}))
col3.pyplot(plt)
elif percent_timeframe == '24h':
if sort_values == 'Yes':
df_change = df_change.sort_values(by=['percent_change_24h'])
col3.write('*24 hour period*')
plt.figure(figsize=(5, 25))
plt.subplots_adjust(top=1, bottom=0)
df_change['percent_change_24h'].plot(kind='barh',
color=df_change.positive_percent_change_24h.map({True: 'g', False: 'r'}))
col3.pyplot(plt)
else:
if sort_values == 'Yes':
df_change = df_change.sort_values(by=['percent_change_1h'])
col3.write('*1 hour period*')
plt.figure(figsize=(5, 25))
plt.subplots_adjust(top=1, bottom=0)
df_change['percent_change_1h'].plot(kind='barh',
color=df_change.positive_percent_change_1h.map({True: 'g', False: 'r'}))
col3.pyplot(plt)
File "C:\Users\samue\anaconda3\lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 556, in _run_script
exec(code, module.__dict__)File "C:\Users\samue\PycharmProjects\crypto_price_app\main.py", line 81, in <module>
df = load_data()File "C:\Users\samue\anaconda3\lib\site-packages\streamlit\runtime\legacy_caching\caching.py", line 618, in wrapped_func
return get_or_create_cached_value()File "C:\Users\samue\anaconda3\lib\site-packages\streamlit\runtime\legacy_caching\caching.py", line 602, in get_or_create_cached_value
return_value = non_optional_func(*args, **kwargs)File "C:\Users\samue\PycharmProjects\crypto_price_app\main.py", line 45, in load_data
listings = coin_data['props']['initialState']['cryptocurrency']['listingLatest']['data']