Making Steem Integrated Web Application Using Flask, HTML, CSS and Beem | Learn Flask, Beem And Python | Part 1

in #utopian-io8 years ago (edited)


Whoop! Welcome to my first tutorial. After I joined Steemit, I was guided by @maverickinvictus to Utopian and I was quite fascinated by it. As said in my introduction, I am a developer and I quickly looked around Steemit to find good Steem libraries. I am going to be using Beem in this tutorial because I have found out that it way faster than Steem's official library. This tutorial will teach you about Flask, Beem and Python in general. To help you understand you all these three things we will be building a web app that will collect data from steem using Beem and then show it using Python and Flask. Now you can see how I will help you learn three things at once. Now let's just move right into the tutorial without any further talk.

Repository

https://github.com/python/cpython - Python

Other Relevant Repositories

https://github.com/holgern/beem - Beem
https://github.com/pallets/flask - Flask

Github Account

https://github.com/realSneakin

What will I learn?

In this tutorial, you will be learning about Python, Beem and Flask. By the help of this tutorial series, you will also learn how you can combine those three things to make steem integrated websites.

Requirements

To follow along with this tutorial you must have basic knowledge of Python 3.6 and these things below must be installed. Even if you don't know python I will briefly explain each part to help you understand it.

  • Python 3.6
  • Beem
  • Flask
  • A Code Editor

Difficulty

Intermediate

Tutorial Content

Python

Let's start the tutorial with me explaining three main things that we will be using this tutorial. The first thing is Python.

Python is an interpreted high-level programming language for general-purpose programming. - Wikipedia

Python is one of the easiest languages to learn among other languages such as Ruby, Javascript and HTML. For this tutorial, I am going to assume that you know the basics of Python.

Beem

Second thing that is important for this tutorial is Beem.

Beem is an unofficial python library for steem, which is created new from scratch from python-bitshares The library name is derived from a beam machine, similar to the analogy between steem and steam. Beem includes python-graphenelib. - Beem's Github Repository

Beem is a python library that we will be using to interact with Steem blockchain and collect data/information from it.

Flask

Third important thing is thing is Flask

Flask is a micro web framework written in Python. It is classified as a microframework because it does not require particular tools or libraries.

Flask is the thing that we will be using to build the website. Now I've been saying each of these things " thing" now let me clarify what these things actually are. Flask is a micro-framework, Beem is a library and Python is a language.

What are we going to create?

In this tutorial, we will be building a website that will be able to show trending, recent and hot post of any tags. It will be just a basic website and it will not have functions like upvote or comment but we will be able to see the post. Later in the series, we will be improving this website.

Creating and setting up the project

Let's just start by creating a folder. You can name that folder anything you want but I will be naming it "Steem_Website" just for quick access and easy remembrance. After creating the folder create a file named __init__.py which is going to be our main file with all the routes (you'll learn about them). After creating that file, create two folders inside there. One should be named "templates" and one should be named "static" (these names are must). We'll learn about them later. There is one more file that should be created and that is "steem". We will be using this file to interact with Steem blockchain. Now that's our basic setup. Take a look at the map below and check if all the files are correctly created.

- Steem_Website
-- static
-- templates
-- __init__.py
-- steem.py

Setting up our __init__ file and creating routes in it

Now that we have created all the necessary files, let's start typing some code. First of all, we are going to be creating a website that will show trending posts of a and that tag could be changeable. I'm going to make a route for the home first. A simple homepage should be on every site so we are going to do that first. Open the __init__.py file and then let's just create a comment first and that comment we will "Imports", you can create the comments by typing # Imports. Under the comment, we are going to be importing Flask which we can do by typing from flask import Flask. Leave a line blank and then add another comment. These comments are optional to write but I recommend to add them because it makes your code so much more readable. The next comment will be "Variables" and you know now how to add the comment so I won't repeat the process.

Under this comment, we will assign the name to the app. To do this type app = Flask(__name__) and in the code, you just typed we are assigning the "app" to our web app. Some people also call this process initialization. Then leave one line and add another comment and that comment will be "Routes" Under this comment, we will be writing our first route.

Let's just start by learning what routes are and why do we need them. Routes are a way to handle what users see when they go to a specific url. Those urls can be static and dynamic. By static urls, I mean an url that will always remain same. Dynamics are urls that change from time to time, you will better understand them later when we will use them. So the first thing that we will need to tell is that what to show a user when they go to the homepage. Instead of jumping to that, let's create a simple route that shows "Hello World" as that just the text which is very popular for the explanation. Take the look at the code below to better understand how we can create the routes.

@app.route("/")
def homepage():
  return "Hello World"

On the first line, we are assigning when to show the code we have written below and in the above example, we are assigning to show when the user is on "/". I know you'll be a bit confused by this at first but let me explain it. "/" is basically our homepage. So if our domain is utopian.io then "/" will just be the homepage of utopian.io with nothing after it. We can later also have an about us page and route for that will be "/about-us" and the normal user will see it as "utopian.io/about-us". Hope that clears up the confusion.

One the second line, we are just creating a function and that function is necessary, even though you can name it anything you want but I recommend naming it something small and meaningful.

On the third line, we are assigning what to return when a user goes to that route/url. In the above example, we are assigning that whenever a user goes to that route, return a text "Hello World". We can also return an HTML code but that is not recommended at all.

Next step is to run the flask application to do this add another comment named "Running The App" and then add the following code below it.

if __name__ == "__main__":
    app.run(debug=True)

This code will help you run the app. You might have noticed that debug is set to True. I have done this to allow me to easily see the changes. When you are going to be deploying the app, make sure that it is not set True.

Running the app

We can easily run the app from the terminal. Just proceed to the directory where __init__.py is located. Then type python3 __init__.py and the server will start to run. Flask comes with the setting to allow you to test the application on your localhost which is http://127.0.0.1:5000/. Go there and you will see your text.

Creating the homepage

I am not gonna focus on HTML & CSS in this tutorial series. I have created a designed a very normal homepage for you to follow along. To create pretty much all of our website we are going to use templates. Templates are not necessary but I totally recommend using them or else things get messy. Templates are a way to add html code to the website. To use templates first we have to import some more stuff from the flask. Where it was written from flask import Flask change it to from flask import Flask, render_template, url_for. We are going to be using render_template to well like the name suggests it renders templates and url_for is a function which we will use to get urls. I will talk about it more briefly later.

Instead of returning a normal text in route we are going to be returning a template now. So change the return statement to return render_template("home.html"). Now we have assigned to return a template but that template is not created yet so let's do that. Open the templates folder and create a new file named "home.html". Inside this file add the html code from here. We will also need to add some CSS files for the homepage. You can download the zip file from here. It has all the CSS files needed for the homepage. Extract them and copy all the folders inside it to the static folder. Just a quick note, inside the static folder we keep all of our static files like images and CSS code. Now go to the local host and see the magic. The homepage is ready. I just named this website Steem Pages because nothing else was coming to my mind.


Cool Right?

At the moment, if we click on trending button in the menu it shows an error. That's why because we haven't set up any route for "/trending" we are going to be shortly doing that.

What are we doing to be doing next?

Till now we have learned some basics of Flask and created the homepage. Now we are going to be setting up so we can see trending posts of Steemit whenever we click on trending. We are going to be using Beem to do this. First, we will use Beem to get the trending posts of all tags and then use that data in Flask.

Collecting data using Beem

First of all, we are going to be creating a new file that will have all the code for data collection. I don't like to make things messy and that's the reason I keep this code outside the __init__ file. Create a file named "steem_data", you can name it anything you want but I am just doing it for the sake of simplicity. After creating the file, let's just import Beem Discussions and Query by typing from beem.discussions import Query, Discussions_by_trending. We can use Beem Discussions and Query to find trending posts. You may have noticed that we have import discussions by trending and this is because we want the post/discussion by trending. This way the most trending post will show up first. Now leave a line and then type query = Query(limit=10) and by this, we are creating a variable query and then assigning it the Query. The limit means how much posts do we want and for this tutorial, we are just going to be showing top 10 trending posts. We can also add another parameter which is tag and then assign a specific tag of which we want trending posts but for now, we don't need that but we will surely utilize it in the future.

Now we are going to be creating a function that will return as a list of all the posts and their details and for that, we are going to be using the below code.

# Imports
from beem.discussions import Query, Discussions_by_trending
from beem.account import Account


# Variables
query = Query(limit=10)

# Functions
def trending():
    posts = []
    for post in Discussions_by_trending(query):
        if "image" in post.json_metadata:
            picture = post.json_metadata["image"]
            acc = Account(post["author"])
            rep = acc.rep
            posts += [{
                "title": post["title"],
                "content": post.body[:500],
                "author": post["author"],
                "author_rep": rep,
                "image": picture[0],
                "permalink": post["permlink"]
            }]
        else:
            acc = Account(post["author"])
            rep = acc.rep
            posts += [{
                "title": post["title"],
                "content": post.body[:500],
                "author": post["author"],
                "author_rep": rep,
                "permalink": post["permlink"]
            }]
    return posts

This is some basic Python stuff but let me try to explain it to you. We have created a function named "trending" and then inside it, we have created an empty list named posts. This list will store all the data from the posts. Now we are running a for loop for what to do with each post in the discussion. I ran an if statement because some posts have images while others don't so if a post has "image" inside of the posts json metadata (this is where images are present) only then we need to add the image to our list. We then created a variable known as "picture" and this variable will be used to handle pictures. I also wanted to know the user's reputation but reputation isn't available in the post so I found a way around it by getting the name of the author of the post and then getting information about the author. I created "rep" variable and it will only include rep of the account so I can use it. Now we are going to be storing all the information inside "posts" variable.

+= in Python means to add more information on top of previous information, just basic Python. First of all, we are adding the title and the title will be post's title so you know how that came from. The content is going to be the post's body. The same way the author is going to be the author of the post. The "author_rep" is going to be the reputation of the author and remember that we stored it in the variable called "rep". The image is going to be the first image of the post so we can use it as the thumbnail. Permalink link is going to be the "permlink" of the post, we will use it later and I will show you how. Everything is the same happening under the else statement the only difference is that there is no image. At the end it this function will return a list with all the information.

Using the data collected by Beem in Trending

Now that we have a function that can provide us top 10 trending posts and it's data, we can start using it in our website. First thing should be to create another route under the last one and this one will be for "/trending". You can use the code below to do that but I have already explained how you can do that so you should first try to make it for yourself. The name of the file will be "trending.html".

@app.route("/trending")
def trending():
  return render_template("trending.html")

Before we create "trending.html" I want to create a layout and this is because all the trending, hot and recent pages are going to be almost the same except the posts are going to be different. So instead of writing the same html again and again, we are going to be making a layout. You'll understand this better once we do this. Create a file called layout.html. Inside this file we are going to adding the image like on homepage because I want it on the trending page as well and a small footer. Copy the code from here and add it to the layout.html file. You may have noticed that the code has {% block body %} and {% endblock %} these are variables in Flask. We can use them to add html code and that's what we are going to do now because we have created the layout.

Before we create the trending.html file we have to do one more thing. That is to import the trending function that we created earlier to the init.py file so we can use it on the website. In Flask, we can have to pass the things through the route to be able to be used in the html code. If your file name is steem_data.py then you can just import it by typing from steem_data import trending and this will import the trending function from that file. This only works if both files are in the same directory. Under the place where comments have been written create a variable "posts_trending" and assign it the the function trending that we imported. We can't do this inside the route because if we do there Python will think we are assigning the route function and because of that it will go in an infinite loop and the application will not work. Under the trending route, create a variable called "trending_posts" and then assign it the "posts_trending" variable that we created. Now after the "trending.html" file add comma ( , ) and then create a variable there with the name posts and assign it trending_posts. Now the trending route will look like below.

@app.route("/trending")
def trending():
    trending_posts = trending
    return render_template("trending.html", posts=trending_posts)

Now create the trending.html file and instead of writing the usual html, we are going to start by typing {% extends 'layout.html' %} and what this will do is that it will let flask know that we are going to be extending the layout.html file. Then we are are going to be opening the body variable that we created in the layout file by typing {% block body %} and then close it by typing {% endblock %}. In the middle of those copy and paste this code.

{% for post in trending_posts %}
<section class="section blog-area">
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-md-12">
                <div class="blog-posts">
                    <div class="single-post">
                        {% if post["image"] %}
                        <div class="image-wrapper"><img src="{{ post['image'] }}" height="500px" width="800px" alt="Blog Image"></div>
                        {% endif %}
                        <div class="icons">
                            <div class="left-area">
                            </div>
                        </div>
                        <p class="date"><em>By {{ post["author"] }}</em></p>
                        <h3 class="title"><a href="#"><b class="light-color">{{ post["title"] }}</b></a></h3>
                        <a class="btn read-more-btn" href="#"><b>Read The Post</b></a>
                    </div>(html comment removed:  single-post )
                </div>(html comment removed:  blog-posts )
            </div>(html comment removed:  col-lg-4 )
        </div>(html comment removed:  row )
    </div>(html comment removed:  container )
</section>(html comment removed:  section )
{% endfor %}

In Flask, whenever we have to use Python in html then we use double curly brackets like used in the above code. We first started a for loop in which we were looping through each post and then placing it's data in the correct place using some html & css. I haven't added content/post's body as I want user to see it once he/she clicks on read the post.

Final Product

After all this efforts, we were able to create a website that pulls the information from the steem blockchain and then shows it on the website. There are somethings missing like we haven't created recent and hot section and we can't read the full post at the moment but we will do these all things in next tutorial. We will keep improving our website as the time moves on.

Utopian Funding

How posts shows on the website at the moment.

All the code/files used in this tutorial are present here

Github Repository

How to check out this application by yourself

If you want to see live how this application works uptill now then clone the github repository and then just run then __init__ file by typing python3 __init__.py and it will start the local server, now go to http://127.0.0.1:5000/ to check out the website. Thanks for reading my tutorial!

Sort:  

Saving this to come back later.

Cool tutorial.

Want to come work on a project?

Thanks @idikuci!
Sure, I can work on a project

you on discord or somewhere else we can chat?

Yes, I am on Discord
Sneakin#8476

Hey @sneakin
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Thank you for your contribution.

  • Put some comments on your code, plus the explanation you've already made.

Good tutorial, thanks for your good work!

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? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Thanks for the review! : )

While this is way over my head I applaud that you are using Utopian-io as one of the condensers of Steem as well as submitting relevant material.

It is a great way of putting your knowledge to use.

I wish you luck Sneakin and if you have any questions please feel free to message me anytime.

Thanks for the upvote and comment. I really appreciate your help. Thanks!

Hi @sneakin, I'm @checky ! While checking the mentions made in this post I found out that @app.route doesn't exist on Steem. Maybe you made a typo ?

If you found this comment useful, consider upvoting it to help keep this bot running. You can see a list of all available commands by replying with !help.

Congratulations! This post has been upvoted from the communal account, @minnowsupport, by Sneakin from the Minnow Support Project. It's a witness project run by aggroed, ausbitbank, teamsteem, theprophet0, someguy123, neoxian, followbtcnews, and netuoso. The goal is to help Steemit grow by supporting Minnows. Please find us at the Peace, Abundance, and Liberty Network (PALnet) Discord Channel. It's a completely public and open space to all members of the Steemit community who voluntarily choose to be there.

If you would like to delegate to the Minnow Support Project you can do so by clicking on the following links: 50SP, 100SP, 250SP, 500SP, 1000SP, 5000SP.
Be sure to leave at least 50SP undelegated on your account.

Amazing Tutorial @sneakin all things are well explained So, helpful tutorial for me waiting for your next article

Thanks for reading!
The next one will be out in a day or two : )

Congratulations @sneakin! You have completed the following achievement on Steemit and have been rewarded with new badge(s) :

Award for the number of upvotes

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:
SteemitBoard World Cup Contest - The results, the winners and the prizes

Do you like SteemitBoard's project? Then Vote for its witness and get one more award!

Nice, I am going to give this a try.

Coin Marketplace

STEEM 0.04
TRX 0.31
JST 0.087
BTC 58512.26
ETH 1565.93
USDT 1.00
SBD 0.38