Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Develop #1

Open
wants to merge 62 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
d9c141a
Initialized Django project
Naz-iv Dec 11, 2023
9ce30ee
updated .gitignore
Naz-iv Dec 11, 2023
6e45295
added flake8 rules for project
Naz-iv Dec 11, 2023
c23bf1a
initial commit for requirements.txt
Naz-iv Dec 11, 2023
a86fbe7
implemented dflight-servce models
Naz-iv Dec 11, 2023
b049e5b
implemented custom user model
Naz-iv Dec 11, 2023
beaa245
added user serizliers
Naz-iv Dec 11, 2023
5dd5688
added user views
Naz-iv Dec 11, 2023
0b5f85d
updated urls for project with routesa and JWT
Naz-iv Dec 11, 2023
a361003
updated models.py on_delete settings and related names for Route fields
Naz-iv Dec 11, 2023
f415b8f
fixed naming in URLs router
Naz-iv Dec 11, 2023
bbdd831
implemented basic serializers.py
Naz-iv Dec 11, 2023
3ceb944
implemented basic viewsets for all models
Naz-iv Dec 11, 2023
0f27987
run migrations for models
Naz-iv Dec 11, 2023
41801bb
minot corrections to serializer (added fields in Meta), urls (updated…
Naz-iv Dec 11, 2023
4ec5235
updated admin panel
Naz-iv Dec 11, 2023
2e33721
minor corrections to models
Naz-iv Dec 11, 2023
3275e19
realized serializers for list and details view
Naz-iv Dec 11, 2023
77a3b91
realized view for all models
Naz-iv Dec 11, 2023
b4ca3f6
updated migrations after chnaging models
Naz-iv Dec 11, 2023
5c71ec6
updated ordering for models
Naz-iv Dec 11, 2023
bb57255
renamed URL from ticket to tickets
Naz-iv Dec 11, 2023
a7df86a
implemented complex logic serrializers class retrival
Naz-iv Dec 11, 2023
c31ae98
updated serializers.py
Naz-iv Dec 11, 2023
571d52f
changed models Meta classes
Naz-iv Dec 11, 2023
979264f
changed models Meta classes
Naz-iv Dec 11, 2023
3742d01
changed models Meta classes
Naz-iv Dec 11, 2023
acbed26
updated serializers
Naz-iv Dec 11, 2023
8989a3e
optimized queries for viewsets
Naz-iv Dec 11, 2023
2e6670a
customized order serializer
Naz-iv Dec 11, 2023
d8cc0e4
added default and custom pagination
Naz-iv Dec 11, 2023
4a7443b
added default and custom pagination
Naz-iv Dec 11, 2023
47554df
added custom permission
Naz-iv Dec 11, 2023
0f15e62
updated viewsets permission classes
Naz-iv Dec 11, 2023
15afa40
loaded database with instances and prepared fixture
Naz-iv Dec 11, 2023
8b73fb4
run migrations to recreate db
Naz-iv Dec 11, 2023
de80c0e
updated route serializer to improve route instance creation process
Naz-iv Dec 11, 2023
f350525
changed access token lifetime for easier development process
Naz-iv Dec 11, 2023
f8a762f
updated db fixture
Naz-iv Dec 12, 2023
2719b27
added swagger to project for documentation purpose
Naz-iv Dec 12, 2023
a6acb08
improved formatting of models
Naz-iv Dec 12, 2023
6acd632
created tests for serializers, viewsets, endpoints and models
Naz-iv Dec 12, 2023
a779746
re-formatted serializer files
Naz-iv Dec 12, 2023
5b64490
extended schema for viewsets to improve documentation
Naz-iv Dec 12, 2023
90e993a
corrected impports
Naz-iv Dec 12, 2023
aeaba7b
added docker settings
Naz-iv Dec 12, 2023
5207b8f
changed setting to use postgres SQL
Naz-iv Dec 12, 2023
f741a6e
added wait for db command to project
Naz-iv Dec 12, 2023
41ff375
fixed setting file to solve OSErro 500
Naz-iv Dec 12, 2023
0176dfa
finalized project
Naz-iv Dec 12, 2023
80c32e3
updated debug setting in setting.py
Naz-iv Dec 12, 2023
a7d97fd
added media files for README.MD
Naz-iv Dec 12, 2023
d02acfa
updated README.MD, dockerignore and flight serializer
Naz-iv Dec 12, 2023
d8bc7af
updated links in README.MD
Naz-iv Dec 12, 2023
517e74f
updated links in README.MD
Naz-iv Dec 12, 2023
42681e0
fixing issue with img in README.md
Naz-iv Dec 12, 2023
419f3f1
fixing issue with img in README.md
Naz-iv Dec 12, 2023
db37880
fixing issue with img in README.md
Naz-iv Dec 12, 2023
ddec005
fixing issue with img in README.md
Naz-iv Dec 12, 2023
b2445b7
updated README.MD
Naz-iv Dec 12, 2023
0f489c8
updated README.MD
Naz-iv Dec 12, 2023
68fe7e4
Update access token lifetime.py
Naz-iv Dec 13, 2023
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
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
venv
.env
.idea
static
10 changes: 10 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[flake8]
inline-quotes = "
ignore = E203, E266, W503, N807, N818, F401
max-line-length = 79
max-complexity = 18
select = B,C,E,F,W,T4,B9,Q0,N8,VNE
exclude =
**migrations
venv
tests
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,4 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.idea/
26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
FROM python:3.9.18-alpine3.18
LABEL maintainer="[email protected]"

ENV PYTHONUNBUFFERED 1

WORKDIR app/

COPY requirements.txt requirements.txt

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 chmod -R 755 /vol/web/

RUN apk add --no-cache bash

USER django-user
114 changes: 113 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,113 @@
# airport_api_service
# Airport-API-Service

Welcome to the Airport Service API! Best solution for managing flight orders, routes, planes, tickets ordering and more. Airport Service API suites both developers integrating airport management infrastructure or airline company in need of efficient system to handle reservations and flights .

___

## Airport Service DB Structure

![Airport Service DB Structure](media/readme_images/img.png)

## Features


* ___Tickets Ordering ___: Users can easily order tickets for their desired flights.
* ___Flight Management___: Administrators can add new flights to the system and manage existing ones.
* ___Authentication and Permissions___: The API is secured with JWT authentication using the Django Rest Framework (DRF).
* ___Filtering and Pagination___: The API supports filtering of flight, airports, airplanes and crew. Even more, pagination is implemented to efficiently manage large sets of data.
* ___API Documentation___: The API documentation is automatically generated using DRF Spectacular. It provides a clear overview of available endpoints, request parameters, response formats, and authentication requirements.
* ___User Order Management___: Users can only view and manage their own orders. The API enforces this restriction in order to ensure privacy and security of data.
* ___Preloaded data for better first time experience___: API is presented with preloaded data. It will allow you to test all functionality of API.
___

## Prerequisites
Following prerequisites need to be installed on your system:

* ___Docker___: You can download and install Docker from the official website: https://www.docker.com/.
* ___ModHeader___: You can download and install ModHeader from the official website: https://modheader.com/.


## How to use

### Easy and quick way

Follow the link [Airport Service API](https://airport-service-api-v9qf.onrender.com)

### More complex but full of fun way

#### Working with git repository

To set up the Airport Service API, follow these steps:

1. Clone the repository:
```
git clone https://github.com/Naz-iv/airport_api_service.git
```
2. Navigate to Project Directory: Change into the project directory using the following command:
```
cd airport_api_service
```
3. Build and Run Docker Container: Use Docker Compose to build the API's Docker container and start the API server:
```
docker-compose build
docker-compose up
```

#### Working with Docker Hub

To set up the Airport Service API, follow these steps:

1. Pull image from Docker Hub:
```
docker pull nivankiv/airport_api_service-app:latest
```
2. Run Docker Container:
```
docker-compose up
```

##### When Git API project or Docker Hub image is ready for user:

You need to generate access token. Do to: ``127.0.0.1:8000/api/users/token``

To use servie as admin enter following credentials:
- login: ``[email protected]``
- password: ``1qazcde3``

To use servie as user enter following credentials:
- login: ``[email protected]``
- password: ``1qazcde3``

After logging in with provided credentials you will receive two tokens: access token and refresh token.
Add new request headed and enter information:

Name: ``Authorization``

Value: ``Bearer_space_*your_access_token*``

Access token example. ``Bearer dmwkejeowk.ewkjeoqdowkjefowfejwefjwef.efhnwefowhefojw``

![ModHeader interface](media/readme_images/img_1.png)

Go to ``127.0.0.1:8000/api/flight_service/`` and discover all hidden gems


## Conclusion

Thank you for using the Airport Service API!

## Screenshots

![API main](media/readme_images/img_2.png)
![Crew List](media/readme_images/img_3.png)
![Airport List](media/readme_images/img_4.png)
![Order List](media/readme_images/img_5.png)
![Airplane Types List](media/readme_images/img_6.png)
![Airplane List](media/readme_images/img_7.png)
![Flight List](media/readme_images/img_8.png)
![Ticket List](media/readme_images/img_9.png)
![Route List](media/readme_images/img_10.png)
![Order Details](media/readme_images/img_11.png)
![Flight Details](media/readme_images/img_12.png)
![Ticket Details](media/readme_images/img_13.png)
![Route Details](media/readme_images/img_14.png)
Empty file added core/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions core/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
ASGI config for core project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")

application = get_asgi_application()
170 changes: 170 additions & 0 deletions core/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import os
from datetime import timedelta
from pathlib import Path
from dotenv import load_dotenv

load_dotenv()

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ["SECRET_KEY"]

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ["DEBUG"]

ALLOWED_HOSTS = []

INTERNAL_IPS = [
"127.0.0.1",
]

# Application definition

INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"drf_spectacular",
"debug_toolbar",
"flight_service",
"user",
]

MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"debug_toolbar.middleware.DebugToolbarMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "core.urls"

TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]

WSGI_APPLICATION = "core.wsgi.application"


# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases

DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"HOST": os.environ["POSTGRES_HOST"],
"NAME": os.environ["POSTGRES_DB"],
"USER": os.environ["POSTGRES_USER"],
"PASSWORD": os.environ["POSTGRES_PASSWORD"],
"PORT": os.environ["POSTGRES_PORT"]
}
}


# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation."
"UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation."
"MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation."
"CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation."
"NumericPasswordValidator",
},
]

AUTH_USER_MODEL = "user.User"

# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/

LANGUAGE_CODE = "en-us"

TIME_ZONE = "UTC"

USE_I18N = True

USE_TZ = False


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/

STATIC_URL = "static/"

MEDIA_URL = "/media/"
MEDIA_ROOT = "/vol/web/media"

# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

REST_FRAMEWORK = {
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
"DEFAULT_THROTTLE_CLASSES": [
"rest_framework.throttling.AnonRateThrottle",
"rest_framework.throttling.UserRateThrottle",
],
"DEFAULT_THROTTLE_RATES": {"anon": "10/day", "user": "30/day"},
"DEFAULT_AUTHENTICATION_CLASSES": (
"rest_framework_simplejwt.authentication.JWTAuthentication",
),
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
"PAGE_SIZE": 4
}

SPECTACULAR_SETTINGS = {
"TITLE": "Airport Service API",
"DESCRIPTION": "Order flight tickets and check flights",
"VERSION": "1.0.0",
"SERVE_INCLUDE_SCHEMA": False,
"SWAGGER_UI_SETTINGS": {
"deepLinking": True,
"defaultModelRendering": "model",
"defaultModelsExpandDepth": 2,
"defaultModelExpandDepth": 2,
},
}

SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(minutes=50),
"REFRESH_TOKEN_LIFETIME": timedelta(days=1),
"ROTATE_REFRESH_TOKENS": False,
}
21 changes: 21 additions & 0 deletions core/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView, SpectacularRedocView

from core import settings

urlpatterns = [
path("admin/", admin.site.urls),
path("api/user/", include("user.urls", namespace="user")),
path(
"api/flight_service/",
include("flight_service.urls", namespace="flight-service"),
),

path("__debug__/", include("debug_toolbar.urls")),

path("api/schema/", SpectacularAPIView.as_view(), name="schema"),
path("api/schema/swagger/", SpectacularSwaggerView.as_view(url_name="schema"), name="swagger"),
path("api/schema/redoc/", SpectacularRedocView.as_view(url_name="schema"), name="redoc"),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
16 changes: 16 additions & 0 deletions core/wsgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
WSGI config for core project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "core.settings")

application = get_wsgi_application()
Loading