Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
af9668b
Refactor SECRET_KEY, ALLOWED_HOSTS and database credentials by sourci…
callogan Jun 14, 2024
cfb96f8
Add new empty app called book and make corresponding supplements to s…
callogan Jun 16, 2024
a582405
Establish the idea of the book on model level
callogan Jun 16, 2024
f24415f
Install rest framework and make appropriate changes to existing files
callogan Jun 16, 2024
ce58a23
Create serializers for book app
callogan Jun 16, 2024
d145c86
Create the view for book app
callogan Jun 16, 2024
0859039
Create urls for book app
callogan Jun 16, 2024
f1c0d1e
Add new empty app called user and make appropriate amendments to sett…
callogan Jun 16, 2024
390e078
Constitute the concept of the user on model level
callogan Jun 16, 2024
04caf34
Create the serializer for user app
callogan Jun 16, 2024
6928f98
Create views for user app
callogan Jun 16, 2024
4867279
Create urls for user app
callogan Jun 16, 2024
3fa2b85
Apply JWT authentication
callogan Jun 16, 2024
16f5e30
Add permissions for both book and user apps
callogan Jun 16, 2024
731ca0e
Add tests to book app
callogan Jun 17, 2024
4ca40a8
Add new empty app called borrowing and make associated supplements to…
callogan Jun 17, 2024
b4ac43d
Embody the vision of the borrowing on model level
callogan Jun 17, 2024
e7bf6d6
Create serializers for borrowing app
callogan Jun 18, 2024
8ed5de2
Create the view for borrowing app
callogan Jun 21, 2024
23eccbe
Create urls for borrowing app
callogan Jun 21, 2024
61f6406
Put into effect the functionality of sending the notification about n…
callogan Jun 21, 2024
ae64559
Implement the logic of returning the book and the logic of sending th…
callogan Jun 21, 2024
f7dcb0a
Install Celery and incorporate the logic of scheduled task: sending t…
callogan Jun 25, 2024
d0dabd5
Add the validation for book inventory and the validation for returned…
callogan Jun 25, 2024
77f4b65
Add permissions for borrowing app
callogan Jun 25, 2024
82eef2c
Add tests to borrowing app
callogan Jun 25, 2024
f2479c8
Add new empty app called payment and make corresponding amendments to…
callogan Jun 25, 2024
368b0fd
Effectuate the idea of the payment on model level
callogan Jun 25, 2024
013e213
Lay the foundation of payment mechanism
callogan Jun 25, 2024
b01a953
Create serializers for payment app
callogan Jun 25, 2024
047542a
Create the view for payment app
callogan Jun 25, 2024
0b8f288
Create urls for payment app
callogan Jun 25, 2024
2543d93
Implement the functionality of sending the notification about success…
callogan Jun 25, 2024
b8b6d81
Actualize the feature of expiration time for the payment session and …
callogan Jun 25, 2024
56476b1
Incorporate the logic of scheduled task: setting expired status for t…
callogan Jun 25, 2024
0092f7f
Provide the validation for pending borrowings
callogan Jun 25, 2024
bc2b91e
Add permissions for payment app
callogan Jun 25, 2024
c574526
Add tests to payment app
callogan Jul 1, 2024
b72964e
Create the fixture with the database content
callogan Jul 2, 2024
cfb0fac
Install Django Debug Toolbar
callogan Jul 2, 2024
d56eb7a
Add docstrings to describe the purpose of specific endpoints
callogan Jul 2, 2024
b18ca1f
Implement drf-spectacular in the project
callogan Jul 2, 2024
52d796e
Dockerize the project
callogan Jul 2, 2024
340055a
Remove redundant fragments of the code in Docker-related files
callogan Jul 3, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
venv
.env
.gitignore
.github
media
.idea
12 changes: 12 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
DJANGO_SECRET_KEY=DJANGO_SECRET_KEY
ALLOWED_HOSTS=ALLOWED_HOSTS
POSTGRES_DB=POSTGRES_DB
POSTGRES_USER=POSTGRES_USER
POSTGRES_PASSWORD=POSTGRES_PASSWORD
POSTGRES_HOST=POSTGRES_HOST
POSTGRES_PORT=POSTGRES_PORT
TELEGRAM_BOT_TOKEN=TELEGRAM_BOT_TOKEN
TELEGRAM_CHAT_ID=TELEGRAM_CHAT_ID
CELERY_BROKER_URL=CELERY_BROKER_URL
CELERY_RESULT_BACKEND=CELERY_RESULT_BACKEND
STRIPE_API_KEY=STRIPE_API_KEY
28 changes: 28 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
FROM python:3.11.2-slim-buster
LABEL maintainer="callogan217@gmail.com"

ENV PYTHONUNBUFFERED 1

WORKDIR app/

COPY requirements.txt requirements.txt
RUN pip install debugpy

RUN apt-get update \
&& apt-get -y install libpq-dev gcc

RUN pip install -r requirements.txt

COPY . .

RUN mkdir -p /vol/web/media

RUN adduser \
--disabled-password \
--no-create-home \
django-user

RUN chown -R django-user:django-user /vol/
RUN chown -R 755 /vol/web/

USER django-user
155 changes: 155 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,156 @@
# Library Service API

Library Service API is overarching web application programming interface aimed to provide
a diverse features and operations for managing the library. Its main goal is to make functioning
of the library more efficient by applying automation means.

All the API features are grouped by the following services (as stacks of homogenous functionalities).

## Book Service

Book Service is intended for managing book stock at the library, including creation of books and making
various operations with them. Nonetheless, only admin can create, update or delete books. Ordinary users
have an access to a list of all books as well as to single book details without the possibility
to make operations with them.

## User Service

Users can register providing an email and a password. After going through authentication procedure users
can view and update their profile information.

## Borrowing Service

Borrowing Service operates the borrowing of books by users and provides all the necessary actions related
to that functionality.

* Create new borrowing: borrowing the book results in making the record in the ledger about borrowing
creation and corresponding changes of the inventory.
* Get borrowing collection - glean a list of borrowings based on 2 criteria:
- user ID (for admin only);
- "is_active" status for the borrowing (either the book is returned or not).
* Get certain borrowing: retrieve detailed information about specified borrowing information.
* Return the book: assign the value for "actual return date" of borrowed book. Simultaneously the payment
for the borrowing is being created.

## Notification Service (Telegram chat)

Notification Service is in charge of sending notifications associated with library operations using
Telegram chat.

* Keep library administrators informed about creation of new borrowing.
* Issue the alert on overdue borrowings.
* Notify administrators about successful payments.

## Payment Service (Stripe API integration)

Payment Service provides payment processing for borrowings in reliable and secure way using
Stripe payment gateway.

* Perform payments for borrowings: deliver full-fledged financial infrastructure to users
for making payments.
* Checking payment processing status: verify that the payment has been processed successfully
or inform about payment cancellation.
* Ensures the control of expiration time for the payments session and for the payment.

## Installation

Clone this repository:

```bash
git clone https://github.com/callogan/library-service-api
cd library-service-api
```

* The main branch is considered as the most sustainable branch, therefore it is recommended to work from it.

* If you intend to run the application locally, follow the next steps:

1. Create the virtual environment:

```bash
python -m venv venv
```

2. Activate the virtual environment:

On Windows:

```bash
venv\Scripts\activate
```

On macOS and Linux:

```bash
source venv/bin/activate
```

3. Install dependencies:

```bash
pip install -r requirements.txt
```

4. Copy this file ".env.sample" and rename it to ".env", then fill in the actual values for your local environment.

STRIPE_API_KEY (as secret key) is available here: https://sripe.com/. You can get Telegram Bot Token
here: https://t.me/BotFather.

5. Apply the migrations:

```bash
python manage.py migrate
```

6. In order to run the development server, use the following command:

```bash
python manage.py runserver
```

* You might as well run the application via the Docker. For this purpose make certain the Docker is installed
on your computer and follow the next steps:
1. Fill the actual data for ".env" file (as was mentioned above).
2. Build the Docker image and start the containers for the application and the database:
```bash
docker-compose up --build
```

Access the application in your web browser at http://localhost:8000.

## Project Fixture

- This project includes the fixture that is used for demonstration purpose. The fixture contains basic dataset
representing various project entities.
- The fixture named `library_service_db_data.json` is located in the root directory.
- In order to load the fixture data into the application, use the following command:

```bash
python manage.py loaddata library_service_db_data.json
```

## Technologies

* [Django REST Framework](https://www.django-rest-framework.org/) This is toolbox for designing Web APIs, providing
features such as serialization, authentication, API views and viewsets to streamline the development of RESTful services
in Django applications.
* [Celery](https://docs.celeryq.dev/en/stable/) This is the system to operate task queue with focus on real-time
processing and option to schedule tasks.
* [Redis](https://redis.io/) This is a source available, im-memory storage, used as distributed, in-memory key-value
database, cache and message broker.
* [Docker](https://www.docker.com/) This is open source containerization platform that enables developers to package
applications into containers, simplifying the process of building, running, managing and distributing applications
throughout different execution environments.
* [PostgreSQL](https://www.postgresql.org/) This is a powerful, open source object-relational database management
system.
* [Swagger](https://swagger.io/) This is open source suite of tools to generate API documentation.

## Demo

![ER Diagram](demo/entity-relationship-diagram.png)
![API Endpoints part 1](demo/swagger-all-endpoints-1.png)
![API Endpoints part 2](demo/swagger-all-endpoints-2.png)

## Copyright

Copyright (c) 2024 Ruslan Kazmiryk
Empty file added book/__init__.py
Empty file.
12 changes: 12 additions & 0 deletions book/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.contrib import admin

from book.models import Book


@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
list_display = (
"id", "title", "author", "cover", "inventory", "daily_fee"
)
list_filter = ("author", )
search_fields = ("title", )
6 changes: 6 additions & 0 deletions book/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class BookConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "book"
47 changes: 47 additions & 0 deletions book/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Generated by Django 5.0.6 on 2024-06-16 13:35

import django.core.validators
from django.db import migrations, models


class Migration(migrations.Migration):
initial = True

dependencies = []

operations = [
migrations.CreateModel(
name="Book",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("title", models.CharField(max_length=255)),
("author", models.CharField(max_length=255)),
(
"cover",
models.CharField(
choices=[("H", "HARD"), ("S", "SOFT")], max_length=1
),
),
("inventory", models.PositiveIntegerField()),
(
"daily_fee",
models.DecimalField(
decimal_places=2,
max_digits=5,
validators=[django.core.validators.MinValueValidator(0)],
),
),
],
options={
"ordering": ("title",),
},
),
]
Empty file added book/migrations/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions book/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.core.validators import MinValueValidator
from django.db import models


class Book(models.Model):
COVER_CHOICES = [("H", "HARD"), ("S", "SOFT")]

title = models.CharField(max_length=255)
author = models.CharField(max_length=255)
cover = models.CharField(max_length=1, choices=COVER_CHOICES)
inventory = models.PositiveIntegerField()
daily_fee = models.DecimalField(
max_digits=5, decimal_places=2, validators=[MinValueValidator(0)]
)

class Meta:
ordering = ("title",)

def __str__(self):
return self.title

15 changes: 15 additions & 0 deletions book/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from rest_framework import serializers

from book.models import Book


class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ("id", "title", "author", "cover", "inventory", "daily_fee")


class BookListSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ("id", "title", "author", "daily_fee")
Empty file added book/tests/__init__.py
Empty file.
Loading