Skip to content

Commit

Permalink
Added swagger for code documantation and configuration pytest
Browse files Browse the repository at this point in the history
  • Loading branch information
riadelimemmedov committed Feb 3, 2024
1 parent 7d2e3fa commit 9d3d10d
Show file tree
Hide file tree
Showing 15 changed files with 172 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/backend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ jobs:
- name: Run tests
run: poetry run manage.py test apps

- name: Run tests with pytest
run: poetry run pytest --cov=./ --cov-report=html

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,7 @@ poetry.toml
pyrightconfig.json

# End of https://www.toptal.com/developers/gitignore/api/python,django
note.txt

htmlcov/
.coverage
50 changes: 50 additions & 0 deletions backend/apps/users/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,53 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

from .forms import CustomUserChangeForm, CustomUserCreationForm
from .models import CustomUser

# Register your models here.


# !CustomUserAdmin
class CustomUserAdmin(UserAdmin):
add_form = CustomUserCreationForm
form = CustomUserChangeForm
model = CustomUser
list_display = (
"email",
"is_staff",
"is_active",
)
list_filter = (
"email",
"is_staff",
"is_active",
)
fieldsets = (
(None, {"fields": ("email", "password")}),
(
"Permissions",
{"fields": ("is_staff", "is_active", "groups", "user_permissions")},
),
)
add_fieldsets = (
(
None,
{
"classes": ("wide",),
"fields": (
"email",
"password1",
"password2",
"is_staff",
"is_active",
"groups",
"user_permissions",
),
},
),
)
search_fields = ("email",)
ordering = ("email",)


admin.site.register(CustomUser, CustomUserAdmin)
17 changes: 17 additions & 0 deletions backend/apps/users/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from django.contrib.auth.forms import UserChangeForm, UserCreationForm

from .models import CustomUser


# !CustomUserCreationForm
class CustomUserCreationForm(UserCreationForm):
class Meta:
model = CustomUser
fields = ("email",)


# !CustomUserChangeForm
class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ("email",)
4 changes: 4 additions & 0 deletions backend/apps/users/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,9 @@ class CustomUser(AbstractBaseUser, PermissionsMixin):

objects = CustomUserManager()

class Meta:
verbose_name = "Custom User"
verbose_name_plural = "Custom Users"

def __str__(self):
return self.email
6 changes: 6 additions & 0 deletions backend/apps/users/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.urls import path

from .views import hello_world

app_name = "users"
urlpatterns = [path("sayhello/", hello_world, name="hello_world")]
9 changes: 9 additions & 0 deletions backend/apps/users/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response

# Create your views here.


@api_view(["GET", "POST"])
def hello_world(request):
if request.method == "POST":
return Response({"message": "Got some data!", "data": request.data})
return Response({"message": "Hello, world!"})
17 changes: 17 additions & 0 deletions backend/config/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@
THIRD_PARTY_APPS = [
"django_cleanup",
"django_extensions",
"rest_framework",
"drf_spectacular",
"djmoney",
]

# !Created Apps
Expand Down Expand Up @@ -205,3 +208,17 @@
# EMAIL_HOST_USER = config("EMAIL_HOST_USER")
# EMAIL_HOST_PASSWORD = config("EMAIL_HOST_PASSWORD")
# DEFAULT_FROM_EMAIL = config("DEFAULT_FROM_EMAIL")


# !Rest Framework
REST_FRAMEWORK = {
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
}

# !SPECTACULAR_SETTINGS
SPECTACULAR_SETTINGS = {
"TITLE": "Django DRF Ecommerce",
"DESCRIPTION": "This project purpose creating ecommerce api for business company",
"VERSION": "1.0.0",
"SERVE_INCLUDE_SCHEMA": False,
}
Empty file.
Empty file.
7 changes: 7 additions & 0 deletions backend/config/tests/users/test_models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
def add_numbers(a, b):
return a + b


def test_add_numbers():
result = add_numbers(2, 3)
assert result == 5
23 changes: 13 additions & 10 deletions backend/config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from django.contrib import admin
from django.urls import include, path
from django.utils.translation import gettext_lazy as _
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerSplitView

# !Abstract
from abstract.constants import AppName
Expand All @@ -36,18 +37,20 @@
if not settings.APP_NAME or settings.APP_NAME not in [app.value for app in AppName]:
raise Exception(_("Please set app correct name same as abstract.constants.AppName"))

# For only admin
urls_admin = [
path("jet/", include("jet.urls", "jet")),
path("jet/dashboard/", include("jet.dashboard.urls", "jet-dashboard")),
]

if settings.APP_NAME == AppName.ADMIN.name:
urlpatterns += urls_admin
else:
urlpatterns += []
urlpatterns += urls_admin
urlpatterns += i18n_patterns(path("admin/", admin.site.urls))
# Only for admin
urlpatterns += [
path("jet/", include("jet.urls", "jet")),
path("jet/dashboard/", include("jet.dashboard.urls", "jet-dashboard")),
path("api/schema", SpectacularAPIView.as_view(), name="schema_api"),
path(
"api/schema/docs",
SpectacularSwaggerSplitView.as_view(url_name="schema_api"),
),
]
urlpatterns += i18n_patterns(path("admin/", admin.site.urls))
urlpatterns += [path("users/", include("apps.users.urls", namespace="users"))]


# *Settings Debug
Expand Down
38 changes: 38 additions & 0 deletions backend/schema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
openapi: 3.0.3
info:
title: Django DRF Ecommerce
version: 1.0.0
description: This project purpose creating ecommerce api for business company
paths:
/users/sayhello/:
get:
operationId: users_sayhello_retrieve
tags:
- users
security:
- cookieAuth: []
- basicAuth: []
- {}
responses:
'200':
description: No response body
post:
operationId: users_sayhello_create
tags:
- users
security:
- cookieAuth: []
- basicAuth: []
- {}
responses:
'200':
description: No response body
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
cookieAuth:
type: apiKey
in: cookie
name: sessionid
1 change: 0 additions & 1 deletion backend/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
[tool:pytest]
DJANGO_SETTINGS_MODULE = config.settings
python_files = test_*.py
addopts = --cov -x
4 changes: 4 additions & 0 deletions commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Backend
- `poetry run pytest -x`
- Format code using Black:
- `poetry run black .`
- Generate html for covering tests:
- `poetry run pytest --cov=./ --cov-report=html`
- Check code formatting is needed or not:
- `poetry run black . --check`
- Sort imports using isort with Black profile:
Expand All @@ -55,3 +57,5 @@ Backend
- `poetry run manage.py makemigrations --dry-run --verbosity 3`
- Run pre commit hooks
- `poetry run pre-commit run --all-files`
- Generate api schema
- `poetry run manage.py spectacular --file schema.yml`

0 comments on commit 9d3d10d

Please sign in to comment.