Part 4: Adding live STEEM/SBD tickers
This tutorial is part of a series where different aspects of quickly creating and deploying STEEM web applications by using the Django framework as well as Beem are discussed. Knowledge of programming with Python is advised, as well as HTML and CSS, Javascript and Bootstrap.
Repository
https://github.com/django/django
What will I learn
- Fetching STEEM and SBD ticker prices
- Create an APIview and path
- Parse the prices into a html
- Automatically updating the ticker prices
- Pitfalls with regards to scaling
Requirements
- Python 3.7
- Django 2.1.5
- Beem 0.20.17
- Gunicorn 19.9.0
- Git
- Heroku
- Pipenv
Difficulty
- basic
Tutorial
Preface
Django allows for quick development of web applications and since it uses Python as it's main programming language it also allows for easy combition with the steem-python library to develop STEEM web applications. This part is a continuation on Part 2 and continues with the code: Github. In this tutorial a live STEEM/SBD ticker will be added to the blog page.
Setup
Download the base files via Github and branch to commit e3b2d6f86b3191f9ca448ddcac43ab41f2bdc7cd
to follow along side the tutorial. Install the virtual environment from the Lockfile
, enter the virtual environment and install the django rest-framework
that will be used for this tutorial.
$ cd ~/
$ git clone https://github.com/Juless89/django-steem-blog.git
$ cd django-steem-blog
$ git checkout e3b2d6f86b3191f9ca448ddcac43ab41f2bdc7cd
$ pipenv install
$ pipenv shell
(django-steem_blog) $ pip install djangorestframework==3.9.1
Register the rest_framework inside settings.py.
INSTALLED_APPS = [
.
.
'rest_framework', # new
}
Run the server, it should look as following:
(django-steem_blog) $ python manage.py runserver
Fetching STEEM and SBD ticker prices
Ticker prices can either be fetched directly from a specific exchange or another option is to use the weighted average of all exchanges via a service like coinmarketcap.com. This website hosts an API that can be accessed for current ticker prices.
To display the ticker prices on the webpage an Ajax call can be made to the API directly and process the data requested. A cleaner solution would be to make this call inside a python function to process the data and only return the required data via an APIview
to Ajax to parse to html. The file services.py
is used to house any additional python functions.
# posts/services.py
# Get request for coinmarketcap, returns a string of the current price
def get_market_price(token):
api_url = 'https://api.coinmarketcap.com/v1/ticker/{}/'.format(token)
response = requests.get(api_url)
if response.status_code == 200:
return json.loads(response.content.decode('utf-8'))[0]['price_usd']
else:
return None
This function requests the data for a specific ticker from coinmarketcap.com and returns only the price_usd
data variable. When the response fails None
is returned.
Create an APIview and path
The django rest_framework is build to handle everything with regard to RESTful API
. For this tutorial the same could be accomplished by returning the data from get_market_price
in a Jsonrepsonse
. It is good practise to use the framework as it allows for many additional features like user authentication when this is required.
Import the APIView
and response from the framework, create a new APIView TickerData
and overwrite the get
method. Also import get_market_price
from services.py
.
# posts/view.py
from .services import get_market_price
from rest_framework.views import APIView
from rest_framework.response import Response
# APIview for coinmarketcap STEEM and SBD ticker prices.
class TickerData(APIView):
# Unused user authentication classes
authentication_classes = []
permission_classes = []
# Retrieve STEEM and SBD market prices, return a dict
def get(self, request, format=None):
data = {
"STEEM": '{:.3f}'.format(float(get_market_price('steem'))),
"SBD": '{:.3f}'.format(float(get_market_price('steem-dollars'))),
}
return Response(data)
Register the path 'api/ticker/data/'
where the api can be accessed inside urls.py
.
# pages/urls.py
from .views import TickerData
urlpatters = [
.
path('api/ticker/data/', TickerData.as_view()),
.
]
Access the path directly to see if everything is working. http://127.0.0.1:8000/api/ticker/data/
Parse the prices into a html
In order to fetch and parse the data into the html Ajax is required. This code needs to be inserted into album.html
between <script></script>
tags. The ticker prices will be displayed in the header so place the <scripts></scripts>
tags below <header></header>
Additionally a div
tag has to be created with an id so that is can be referenced to. Add a new div tag inside the container that is in the header. Behind the the <a></a>
tag. Set its id
to ticker
and the class
to navbar-brand
.
# templates/album.html
<div id="ticker" class="navbar-brand"></div>
<header>
<div class="collapse bg-dark" id="navbarHeader">
</div>
<div class="navbar navbar-dark bg-dark shadow-sm">
<div class="container d-flex justify-content-between">
<a href="#" class="navbar-brand d-flex align-items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mr-2" focusable="false" aria-hidden="true"><path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"></path><circle cx="12" cy="13" r="4"></circle></svg>
<strong>Blog</strong>
</a>
<div id="ticker" class="navbar-brand"></div>
</div>
</div>
</header>
To perform a Ajax GET request use the following code structure. The endpoint
is the path to the APIView
. When the request is successful a data
object is returned. Which can be accessed by adding a .
and the name of the requested variable. In this case data.STEEM
and data.SBD
. A string is created by concatenating the variables with text strings. $('#ticker').html(string);
inserts the created string into the div tag with id=ticker
.
# templates/album.html
var endpoint = '/api/ticker/data'
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
var string = 'STEEM $' + data.STEEM + ' SBD $' + data.SBD
$('#ticker').html(string);
},
error: function(error_data){
console.log(error_data)
}
})
Loading the webpage should now display the STEEM and SBD price tickers in the top right corner. http://127.0.0.1:8000
Automatically updating the ticker prices
At the moment when the page is loaded the ticker prices are pulled from coinmarketcap's API and displayed on the webpage. Automatically refreshing the prices can be achieved with several changes to the script.
Create a function from the Ajax call get_ticker
and then set an interval for this function setInterval("get_ticker();",5000)
. The time is in milliseconds so 1000 equals 1 second.
# templates/album.html
function get_ticker()
{
$.ajax({
method: "GET",
url: endpoint,
success: function(data){
var string = 'STEEM $' + data.STEEM + ' SBD $' + data.SBD
$('#ticker').html(string);
},
error: function(error_data){
console.log(error_data)
}
})
}
setInterval("get_ticker();",5000);
However, the code does not process until the first interval is met. To load the function initially on page load add the following line $(document).ready(get_ticker);
# templates/album.html
// Load on page load, then load every 5000/1000 seconds.
$(document).ready(get_ticker);
setInterval("get_ticker();",5000);
Pitfalls with regards to scaling
Currently every time the ticker prices are reloaded an API call from the server to coinmarketcap is made. Most public APIs have a limit to how often they can be called from a unique IP address. Imagine a refresh time of 5 seconds and 100 users active on the webpage. This would mean that on average 100 calls would be made per second. For scaling it would be better to create a separate service that uploads the ticker prices into a database every x seconds and then an APIView that loads the data from the database instead.
Curriculum
- Part 0: Create STEEM web applications with Django and Steem-Python
- Part 1: Using the URL to dynamically pull data via the Steem API and parse to html
- Part 2: Using A Bootstrap Template To Parse STEEM Posts Via Beem API
- Part 3: Combing Charts.js And Django Rest Framework
The code for this tutorial can be found on Github!
This tutorial was written by @juliank.
Thank you for your contribution @steempytutorials.
After analyzing your tutorial we suggest the following:
Put more comments in the sections of your code, for example, the ajax call has no comments to help the reader understand what is developed.
This tutorial is a bit basic, in the next tutorial bring something more innovative.
Looking forward to your upcoming tutorials.
Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.
To view those questions and the relevant answers related to your post, click here.
Need help? Chat with us on Discord.
[utopian-moderator]
Thank you for your review, @portugalcoin! Keep up the good work!
Hi @steempytutorials!
Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server
Congratulations @steempytutorials! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click here to view your Board
If you no longer want to receive notifications, reply to this comment with the word
STOP
To support your work, I also upvoted your post!
Hey, @steempytutorials!
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!