Skip to content

KatyaLubyankina/NewsFeed

Repository files navigation

NewsFeed with FastApi

This project allows users to view and create news posts with pictures and comments. See detailed OpenAPI documentation of NewsFeed project without starting the project.

Features:

  • FastAPI (Python 3.10) - framework for API
  • OAuth2 - for authentication with JSON Web Token
  • PostgreSQL - database with indexes for post and user id to improve the speed of operations
  • pgAdmin for management
  • SQLite - database for tests
  • SqlAlchemy - for ORM
  • MinIO - for S3 storage
  • Pytest - for tests (Reusable Pytest fixtures and new test database for each test)
  • Docker Compose - for running application (containers for application and MinIO storage with volumes)
  • Uvicorn - for ASGI web server
  • CI/CD pipeline: Github action for pytest and docker image build before pull request in master
  • Poetry - for packaging and dependency management
  • Fastapi-pagination - for pagination in endpoint for getting all posts
  • Python-dotenv - for reading configuration variables and secret data
  • Loguru - for logging errors
  • Pre-commit - black, flake8 and isort formate code before each commit

Getting started

Clone github repository

git clone https://github.com/KatyaLubyankina/NewsFeed.git

Change directory to NewsFeed

cd NewsFeed

Start Docker Desktop and run this command to start project in docker containers

docker compose up --build

You can change secret data (secret keys for encryption and s3 storage) in src/secrets folder. The API documentation will be at http://localhost/docs. API endpoints will be available at http://localhost/. MinIO object storage - http://localhost:9000 - use minioadmin as login and password. You can change these values with 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment variables (use .env_vars file).

Testing

This project comes with Pytest and a few Pytest fixtures for new user, login, post and comment. Tests are located in /tests directory and the fixtures are available in tests/conftest.py. To run all tests use:

pytest

To check coverage use:

pytest --cov

Examples:

Some examples of API endpoints.

Create new user

Request to create new user

curl -X 'POST' \
  'http://localhost/user' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "username": "test",
  "email": "test@gmail.com",
  "password": "test",
  "avatar_url": ""
}'

Response:

{
  "username": "test",
  "email": "test@gmail.com"
}

Create new post

Authentication is required for this endpoint. Request:

curl -X 'POST' \
  'http://localhost/post' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
  "image_url": "test url",
  "caption": "test caption",
  "creator_id": 1
}'

Response:

{
  "id": 1,
  "image_url": "test url",
  "caption": "test caption",
  "timestamp": "2023-06-29T11:02:39.927456",
  "user": {
    "username": "test"
  },
  "comments": []
}

Create new comment

Authentication is required for this endpoint. Request:

curl -X 'POST' \
  'http://localhost/comment' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QiLCJleHAiOjE2ODgwMjY2NDF9.0BlUSHzdzR4lOdghXxuwxijc1E1aZQYJ_lOOUFWbNwY' \
  -H 'Content-Type: application/json' \
  -d '{
  "username": "test",
  "text": "test comment",
  "post_id": 1
}'

Response:

{
  "text": "test comment",
  "username": "test",
  "post_id": 1,
  "id": 1,
  "timestamp": "2023-06-29T11:04:21.418987"
}

Get all posts

Request:

curl -X 'GET' \
  'http://localhost/post/all' \
  -H 'accept: application/json'

Response:

[
  {
    "id": 1,
    "image_url": "test url",
    "caption": "test caption",
    "timestamp": "2023-06-29T11:02:39.927456",
    "user": {
      "username": "test"
    },
    "comments": [
      {
        "text": "test comment",
        "username": "test",
        "timestamp": "2023-06-29T11:04:21.418987"
      }
    ]
  }
]

Get all comment for post

Request:

curl -X 'GET' \
  'http://localhost/comment/all/1' \
  -H 'accept: application/json'

Response:

[
  {
    "text": "test comment",
    "username": "test",
    "post_id": 1,
    "id": 1,
    "timestamp": "2023-06-29T11:04:21.418987"
  }
]

Delete post

Authenticated user can delete post only if user created this post. Request:

curl -X 'GET' \
  'http://localhost/post/delete/1' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InRlc3QiLCJleHAiOjE2ODgwMjY2NDF9.0BlUSHzdzR4lOdghXxuwxijc1E1aZQYJ_lOOUFWbNwY'

Response:

"ok"