Part 0: Create STEEM web applications with Django and Steem-Python

in #utopian-io6 years ago (edited)

banner.png

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 steem-python are discussed. Knowledge of programming with Python is advised, as well as HTML and CSS.


Repository

https://github.com/steemit/steem-python
https://github.com/django/django

What will I learn

  • Creating a virtual environment
  • Setting up a Django project
  • Combining steem-python and Django
  • Version control and deployment

Requirements

  • Python 3.7
  • Django 2.1.5
  • steem-python 1.0.1
  • git
  • heroku
  • gunicorn
  • 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 will focus on process of starting a project from scratch and deploying it live. This tutorial will function as a framework for upcoming tutorials and will explain best practises for creating Django web apps.

Creating a virtual environment

Virtual environments are not required but are good practise. Software dependencies are saved in a special file which allows for easy deployment. pipenv will be used for this tutorial series. Assuming python3 is already installed, install pipenv as follows:

$ pip3 install pipenv

Now create a folder from which we will start working.

$ cd ~/
$ mkdir django
$ cd django

Create a new virtual environment and enter the virtual environment.

$ pipenv install django==2.1.5
$ pipenv shell

You should see parentheses around the folder name to indicate that you are in the virtual environment. You can always exit by typing $ exit.

(django) $

Setting up a Django project

Create a new project called stats.

(django) $ django-admin startproject stats .

This creates all the required files to run a Django web application. manage.py is the main file from which the server is run. The folder structure is as follows.

.
├── Pipfile
├── Pipfile.lock
├── manage.py
└── stats
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Test if everything is working by running the server from manage.py and visit the website locally at http://127.0.0.1:8000/

(django) $ python manage.py runserver

The terminal should show:

Performing system checks...

System check identified no issues (0 silenced).

You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

January 28, 2019 - 16:35:49
Django version 2.1.5, using settings 'steem.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

The unapplied migration are for setting up the database. For this tutorial no database will be required.


Screenshot 2019-01-28 17.37.37.png

Combining steem-python and Django

First install steem-python. Exit the server by pressing Ctrl + C.

(django) $ pip install steem==1.0.1

We will be creating a simple page that will display the most up to date statistics of the STEEM blockchain and updates every 3 seconds (blocktime). Django uses the concept of projects and apps to keep the code clean and reliable. A single project can contain multiple apps that can work together. Create an app called steemchain.

$ python manage.py startapp steemchain

A new directory is created for the app with its own subfolders and files.

├── Pipfile
├── Pipfile.lock
├── db.sqlite3
├── manage.py
├── stats
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── steemchain
    ├── __init__.py
    ├── admin.py
    ├── apps.py
    ├── migrations
    │   └── __init__.py
    ├── models.py
    ├── tests.py
    └── views.py

Open the project in your favourite editor and navigate to settings.py to register the app we just created.

# steem/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'steemchain.apps.SteemchainConfig', # new
]

To retrieve the data about the STEEM blockchain create a separate file services.py that takes care of interactions with the STEEM nodes.

(django) $ touch steemchain/services.py

The Blockchain class from steem-python contains the function info() that return a dict with the current blockchain statistics. Create the function blockchain_data() that makes the API call and returns the data.

# steemchain/services.py
from steem.blockchain import Blockchain


# retrieve current blockchain statistics
def blockchain_data():
    blockchain = Blockchain()
    return blockchain.info()

To display the data in the web application a view, homePageView, has to be created that calls the function we just created and parses the data to html. For this simple example a HttpReponse() will be used created in which we will manually write each html line. This response is returned to the user upon request.

# steemchain/views.py
def homePageView(request):
    data = blockchain_data()

    response = HttpResponse()
    # refresh every 3 seconds
    response.write('<meta http-equiv="refresh" content="3" />')

    # add each key, value par on a separate line
    for k, v in data.items():
        response.write(f'{k}: {v}<br>')
    return response

Now the view needs to be connected to the right url. To display the data on the homepage a link between the empty url, '', and the view has to be created. The view from views.py is imported and linked to the url '' by using the path() function.

(django) $ touch steemchain/urls.py

# steemchain/urls.py
from django.urls import path
from .views import homePageView

urlpatterns = [
    path('', homePageView, name='home')
]

The new urls.py for the app steemchain now has to be linked to the main urls.py file which then redirects to the steemchain urls.py. This is done by adding include and including steemchain.urls.

# stats/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('steemchain.urls'))
]

Now when a user visits the root url '', it will be redirected to steemchain.urls which than directs to the homePageView which pulls the data from the steem node and returns it as a HttpResponse. Test it by running the server and visiting http://127.0.0.1:8000/

(django) $ python manage.py runserver

Version control and deployment

A web application that is just running locally is not a real web application. Django allows for rapid deployment. Git and Heroku are powerful services that allow us to do just that. You will have to make separate accounts for both Git and Heroku.

First install Gunicorn that will be acting as the webserver.

(django) $ pipenv install gunicorn==19.9.0

Make sure that the pipfile has the following packages and lock the file.

# ./pipfile

[packages]
django = "==2.1.5"
gunicorn = "==19.9.0"
steem = "==1.0.1"
(django) $ pipenv lock

Heroku requires a procfile, create it and add the following line.

(django) $ touch Procfile


# ./procfile
web: gunicorn stats.wsgi --log-file -

Now set the ALLOWED_HOSTS in settings.py so the website can run from any ip.

# pages_project/settings.py
ALLOWED_HOSTS = ['*']

All that is left now is pushing the code to both Git and Heroku for deployment. First initialise git in the project folder. Then add all the files to be committed and add a comment. $ git status allows for an overview of which files have changed since the last commit. Create a new repository on Github and link it to the project folder. Lastly push the code.

(django) $ git init
(django) $ git add -A
(django) $ git commit -m 'initial commit'
(django) $ git remote add origin https://github.com/Juless89/django-steem-stats.git
(django) $ git push -u origin master

When using git for the first time it is recommend to set the following variables.

$ git config --global user.name "Your Name"
$ git config --global user.email "[email protected]"

Create an Heroku app and link it to the newly created git repository.

(django) $ heroku login
(django) $ heroku create
Creating app... done, ⬢ murmuring-castle-66732
https://murmuring-castle-66732.herokuapp.com/ | https://git.heroku.com/murmuring-castle-66732.git

(django) $ heroku git:remote -a murmuring-castle-66732
set git remote heroku to https://git.heroku.com/murmuring-castle-66732.git

Disable static files on Henroku and push the code.

(django) $ heroku config:set DISABLE_COLLECTSTATIC=1
(django) $ git push heroku master

Activate the Henroku app, set it to level 1. Level 1 is free to use. Then open the app to see it live.

(django) $ heroku ps:scale web=1
(django) $ heroku open

https://mysterious-beyond-70787.herokuapp.com/

Congratulations you have just created your first Django STEEM web application.


The code for this tutorial can be found on Github!

This tutorial was written by @juliank.

Sort:  

I thank you for your contribution. Here are my thoughts. Note that, my thoughts are my personal ideas on your post and they are not directly related to the review and scoring unlike the answers I gave in the questionnaire;

  • Structure

    • Your post is very good structure-wise.
  • Language

    • Usage of the first person is very sparse, so it looks professional than other, average tutorials. I appreciate your work on that!
  • Content

    • As others suggested, if steem-python library is abandoned, it would be better to follow beem.

    • Usage of virtual environments and git from start makes the project very flexible. So, instructing them in your tutorial makes your tutorial more valuable for newbies! I appreciate and thank you for that!


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, @yokunjon! Keep up the good work!

I would definitely recommend using beem over steem-python ;)

I will have a look, what makes it superior in your eyes?

If only you had done this 6-months ago!

I've got my steem (beem) + django webapp running over at https://xhaust.me -- took a bit of time to figure it out, but you can do some pretty rad stuff!

Haha sorry my bad, I did not know about this 6 months ago. Have been looking to learn more about web development with Python and I believe a good way to learn is to write tutorials. There is indeed a lot of stuff that can be done and I will be busy for a while.

I had a look at your website I like the idea. How do you verify if a user actually made a run?

There is indeed a lot of stuff that can be done and I will be busy for a while.

I'm excited to see the tutorials you put together. I'm sure I'll learn some stuff -- and it'll at least be a good refresher how to get everything working nicely. One thing I for sure need to learn about is writing good tests. I kinda just skipped that part and went straight to work and never looked back -- bad practice.

How do you verify if a user actually made a run?

Considering things are teeny tiny right now -- I haven't really worried about people lying and logging a run anyways. Most users have been logging activities by uploading a GPS file, because ultimately, they're more concerned about their training than they are about gaming the system. I've built in a couple checks to make sure that it's not a duplicate GPS file a user is uploading, and to check the start-times and speeds to see if anything is funky.

I've put some thought into:

  • switching it to require that the activity be created from GPS tracking data (like a garmin TCX or GPX or whatever).;
  • shortly, I'll be adding some information on flagging, and a button to flag -- so users can determine if they think a run is fake. Run gets flagged below a threshold? It's eliminated from the pool and the 'athlete' doesn't get a payout at the end of the week.

The site is a big W.I.P and I tend to break it a couple times each week. But it has been a lot of fun learning how to do everything.


PS. Let me know if you do a tutorial on setting up SteemKeychain and / or getting it to work with Django. I haven't looked into it yet -- but it's on my radar.

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

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!

Coin Marketplace

STEEM 0.22
TRX 0.20
JST 0.035
BTC 90550.33
ETH 3203.67
USDT 1.00
SBD 3.15