Skip to content

Ziang-Lu/Flask-Blog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

80 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Flask Blog

This repo contains Flask-Blog project, which is a basic blogging application.


Tech Stack (Implementation Notes)

We separate user_service and post_service out as a Flask-based web services:

  • user_service is responsible for all the logics and information related to users, and talks to PostgreSQL directly.

    • The user following system is also implemented in user_service, and presented in the main Flask-Blog app.

    Defined resources:

    • UserList

      Route: /users

      Method Description Request Form Schema Response Status Code
      GET Returns the user with a specified username or email Query:
      username: string
      email: string
      200 on success, 400 on no username or email privided, 404 on user not found
      POST Adds a user with the given name, email and password username: string
      email: string
      password: string
      201 on success, 400 on invalid data provided
    • UserItem

      Route: /users/<int:id>

      Method Description Request Form Schema Response Status Code
      GET Returns the user with the specified ID 200 on success
      PUT Updates the user with the specified ID username: string
      email: string
      image_filename: string
      200 on success, 400 on invalid data provided
    • UserAuth

      Route: /user-auth/

      Method Description Request Form Schema Response Status Code
      GET Handles user authentication Query:
      email: string
      JSON:
      password: string
      200 on success, 404 on user not found, 401 on authentication failed
    • UserFollow

      Route: /user-follow/<int:follower_id>/<followed_username>

      Method Description Request Form Schema Response Status Code
      POST Lets the given follower follow the user with the given username 201 on success, 404 on followee not found, 400 on invalid data provided
      DELETE Lets the given follower unfollow the user with the given username 204 on success, 404 on followee not found, 400 on invalid data provided
  • post_service is responsible for all the logics and information related to user posts, and talks to PostgreSQL directly.

    Defined resources:

    • PostList

      Route: /posts

      Method Description Request Form Schema Response Status Code
      GET Returns all posts (optionally with some filters) Query
      user: string
      author: string
      200 on success
      POST Adds a new post user_id: int
      title: string
      content: string
      201 on success
    • PostItem

      Route: /posts/<int:id>

      Method Description Request Form Schema Response Status Code
      GET Returns the post with the specified ID 200 on success, 404 on post not found
      POST Updates the post with the specified ID title: string
      content: string
      200 on success
      DELETE Deletes the post with the specified ID 204 on success
    • PostLike

      Route: /posts/<int:post_id>/likes

      Method Description Request Form Schema Response Status Code
      POST Likes the given post 201 on success, 404 on post not found
    • PostComment

      Route: posts/<int:post_id>/comments

      Method Description Request Form Schema Response Status Code
      POST Comments on the given post user_id: int
      text: string
      201 on success, 404 on post not found
  • Marshmallow/Flask-Marshmallow is used for schema definition & deserialization (including validation) / serialization.

  • Since these web services are backed by PostgreSQL database, Flask-SQLAlchemy module is used for ORM-related tasks.

The communication between the main Flask-Blog app and the web services is through RESTful API, via JSON.


In this way, the original Flask-Blog app now becomes a "skeleton" or a "gateway", which talks to user_service and post_service, uses the fetched data to render HTML templates.


Additional Features

  • As a presentation of the user following system, a logged-in user is able to choose to show only the posts authored by himself and the followed users.

  • Asynchronous tasks:

    Some actions in the app takes long time to run, which blocks the server to handle the request.

    Thus, Celery is used as an asynchronous task queue (with Redis as the broker (message queue)) to handle those long-running tasks, like sending email to users.


Local Development

Environment Setup

$ pipenv --python=3.7
$ pipenv shell

# Install all the packages specified in Pipfile
$ pipenv install

Normal development...


Run the Dockerized Application

For "Dockerized", check out https://github.com/Ziang-Lu/Flask-Blog/blob/master/Deployment%20Options.md#dockerization-linux-server--web-server-in-docker-container--python-web-app-wsgi-server-in-docker-container for details


If the dependencies ever changed:

# Update requirements.txt from Pipenv.lock
$ pipenv lock -r > requirements.txt

# Since flask_app, user_service, and post_service almost depend on the same Python dependencies, when putting them into separate Docker images:
# - We created a base image, which contains all the needed Python dependencies
# - Let separate images inherit from this base image, so that the Python dependencies are downloaded once in the base image, and can be reused among all the separate images.

# Build, tag, and push the base image, on which other images are dependent of
$ ./docker_base_exec.sh

To run the Dockerized application, every time some changes are made to the codes:

# Build and tag the service images
$ ./docker_services_exec.sh

# Use docker-compose to orchestrate the services (containers)
$ docker-compose up

After running the application:

$ docker-compose down -v  # Also remove the volumes

License

This repo is distributed under the MIT license.