Blogs

Ronie Martinez

May 06, 2017

Writing an AWSome Blog with Python Flask

This article shows how to create a simple Markdown-based blog site using Amazon S3, AWS Elastic beanstalk and Python Flask.

What you need

  • AWS Account (Elastic Beanstalk, S3)
  • Flask
  • Knowledge on Markdown

Sign up for an AWS account

  • Setup an AWS account. If you are new to AWS, don't worry they got a 12-month free tier. You will still need a credit card, though.
  • Login through the AWS console and go to Elastic Beanstalk console.
  • Click Create New Application link and enter your Application Name and Description.

  • Click Actions dropdown, select Create Environment and choose Web server environment in the Choose an environment tier dialog.

  • After clicking Select button, you will be sent to a configuration page. Select Python as the Platform and select Sample application as the Application code. We will change this later.

  • Go to Amazon S3 console and click Create Bucket and enter a bucket name.
  • Click on the bucket name and click Create folder and enter a folder name.

Write your Flask code

  • Start by setting up your directory structure like this:

    |- myblog
    |   |- application.py
    |   |- requirements.txt
    |   |- templates
    |   |   |- blog_entry.html
    
  • In blog_entry.html template, write the following:

    {% block post %}
        {{ markdown | safe }}
    {% endblock %}
    
  • Use this minimal code in application.py and add the S3 bucket name and folder name:

    #!/usr/bin/env python
    import boto3
    import markdown2
    from flask import Flask, render_template
    from botocore.exceptions import ClientError
    from werkzeug.exceptions import abort
    
    
    application = Flask(__name__)
    
    application.config['BUCKET_NAME'] = '<bucket_name>'
    application.config['BUCKET_FOLDER'] = '<folder_name>'
    
    
    @application.route('/blog/<post>')
    def blog(post=None):
        if post:
            try:
                s3 = boto3.resource('s3')
                object_ = s3.Object(
                    application.config['BUCKET_NAME'],
                    '{}/{}.md'.format(application.config['BUCKET_FOLDER'], post)
                )
                return render_template('blog_entry.html',
                                       markdown=markdown2.markdown(
                                           object_.get()['Body'].read(),
                                           extras=[
                                               'fenced-code-blocks'
                                           ])
                                       )
            except ClientError as e:
                print(e)
        abort(404)
    
    
    if __name__ == '__main__':
        application.debug = True
        application.run()
    
  • Add the following modules to requirements.txt.

    boto3==1.4.4
    Flask==0.12.1
    markdown2==2.3.4
    Pygments==2.2.0
    

Deploying your code

  • Using the terminal cd to your project directory and zip all the contents recursively.

    cd myblog
    zip -r myblog.zip .
    
  • In your AWS Elastic Beanstalk environment, click Upload and Deploy button, choose your myblog.zip file, enter the Version label and click Deploy

Writing your blog

  • Use any editor that you are comfortable with and start editing your markdown file.
  • Save it as <blog_filename>.md and upload it to the S3 folder you created.
  • You should be able to view your blog entry using your favorite browser. The URL format should be <Your_Beanstalk_URL>/blog/<blog_filename>

What's next?

  • Security. Security have not been tackled on this blog and it should be a major concern when deploying an web site.
  • Online editor. It is more convenient if blog entries are edited directly on your website.
  • Templates. Your website UI/UX design is a must! Try Bootstrap, etc., or design your own. Flask uses Jinja2 to work with templates.
  • Domain name. You can buy a domain name through Route 53. But you can save $$$ if you buy a domain name from namecheap and just link it to Route 53.