Compare commits

..

No commits in common. "6c232b3e89df29dd2fdbfbbb57aab304a20a9d2b" and "0614f5b9632b1ef2aa8771e6b7c5ddc96dece687" have entirely different histories.

9 changed files with 124 additions and 136 deletions

33
.woodpecker.yml Normal file
View file

@ -0,0 +1,33 @@
# .woodpecker.yml
steps:
- name: build
image: docker
when:
- branch: master
event: push
commands:
- docker build --platform linux/arm64 --no-cache -t "$IMAGE" .
- echo "$REGISTRY_PASSWORD" | docker login "$REGISTRY" --password-stdin -u "$REGISTRY_USERNAME"
- docker push "$IMAGE"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
secrets: [REGISTRY, REGISTRY_USERNAME, REGISTRY_PASSWORD, IMAGE]
- name: deploy
image: docker
when:
- branch: master
event: push
commands:
- mkdir -p /root/.ssh/
- echo "$SSH_KEY" | tr -d '\r' > /root/.ssh/id_rsa
- chmod 600 /root/.ssh/id_rsa
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > /root/.ssh/config
- ssh "$REMOTE_HOST" "
cd $PROJECT_DIRECTORY;
docker-compose -f docker-compose.demo.yml down;
docker image rm "$IMAGE" || true;
docker volume rm "$VOLUME" || true;
docker pull "$IMAGE";
docker compose -f docker-compose.demo.yml up -d;
docker image prune -af;"
secrets: [SSH_KEY, REMOTE_HOST, PROJECT_DIRECTORY, IMAGE, VOLUME]

View file

@ -1,22 +0,0 @@
labels:
platform: linux/amd64
steps:
- name: build
image: docker
when:
- branch: master
event: push
commands:
- docker build -t "$REGISTRY_IMAGE_TAG" .
- echo "$FORGEJO_REGISTRY_PASSWORD" | docker login "$FORGEJO_REGISTRY_URL" --password-stdin -u "$FORGEJO_REGISTRY_USERNAME"
- docker push "$REGISTRY_IMAGE_TAG"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
secrets:
[
FORGEJO_REGISTRY_URL,
FORGEJO_REGISTRY_USERNAME,
FORGEJO_REGISTRY_PASSWORD,
REGISTRY_IMAGE_TAG,
]

View file

@ -1,31 +0,0 @@
steps:
- name: deploy
image: alpine:3.20
when:
- branch: master
event: push
commands:
- apk add openssh
- mkdir -p /root/.ssh/
- echo "$WOODPECKER_SSH_KEY" | tr -d '\r' > /root/.ssh/id_rsa
- chmod 600 /root/.ssh/id_rsa
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > /root/.ssh/config
- ssh "$SSH_HOST" '
cd "$PROJECT_DIRECTORY";
docker-compose down;
docker image rm "$REGISTRY_IMAGE_TAG" || true;
docker volume rm "$DOCKER_DB_VOLUME" || true;
docker pull "$REGISTRY_IMAGE_TAG";
docker-compose up -d;
docker image prune -af;'
secrets:
[
SSH_HOST,
PROJECT_DIRECTORY,
WOODPECKER_SSH_KEY,
REGISTRY_IMAGE_TAG,
DOCKER_DB_VOLUME,
]
depends_on:
- build

View file

@ -14,10 +14,18 @@ RUN chown root:root /tmp
RUN chmod 1777 /tmp RUN chmod 1777 /tmp
# Install packages # Install packages
RUN apt update && apt install -y graphviz libgraphviz-dev graphviz-dev wget zip chromium chromium-driver firefox-esr RUN apt clean
RUN pip3 install --upgrade pip && pip3 install --no-cache-dir -r requirements.txt RUN apt update
RUN apt install -y graphviz libgraphviz-dev graphviz-dev wget zip
RUN pip3 install --upgrade pip
RUN pip3 install --no-cache-dir -r requirements.txt
# (Firefox) Download the latest Geckodriver and install it # Install Chrome & Chromedriver
RUN apt install -y chromium chromium-driver
# Install Firefox and Geckodriver
RUN apt install -y firefox-esr
# Download the latest Geckodriver and install it
ENV GECKODRIVER_VERSION=latest ENV GECKODRIVER_VERSION=latest
RUN wget -O geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v0.35.0/geckodriver-v0.35.0-linux64.tar.gz RUN wget -O geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v0.35.0/geckodriver-v0.35.0-linux64.tar.gz
RUN tar -zxf geckodriver.tar.gz -C /usr/bin RUN tar -zxf geckodriver.tar.gz -C /usr/bin

View file

@ -1,6 +1,6 @@
## DRF-Template ## DRF-Template
![Build Status](https://woodpecker.06222001.xyz/api/badges/2/status.svg) ![Build Status](https://woodpecker.06222001.xyz/api/badges/1/status.svg)
![Demo Page Status](https://stats.06222001.xyz/api/badge/119/status) ![Demo Page Status](https://stats.06222001.xyz/api/badge/119/status)
This is a Django template that I personally use for my projects. This covers the following This is a Django template that I personally use for my projects. This covers the following
@ -27,7 +27,7 @@ When using `docker-compose.dev.yml`, the entire project directory is mounted ont
### Deployment ### Deployment
A sample `docker-compose.yml` is provided which I use in hosting the demo. DEBUG should be set to False when deploying as to not expose the URLs fro Celery Flower and the Django Silk Profiler. The local Inbucket container is not present so make sure to specify an external SMTP server to process emails properly. A sample `docker-compose.demo.yml` is provided which I use in hosting the demo. DEBUG should be set to False when deploying as to not expose the URLs fro Celery Flower and the Django Silk Profiler. The local Inbucket container is not present so make sure to specify an external SMTP server to process emails properly.
### URLs ### URLs

View file

@ -6,12 +6,12 @@ info:
paths: paths:
/api/v1/accounts/jwt/create/: /api/v1/accounts/jwt/create/:
post: post:
operationId: accounts_jwt_create_create operationId: api_v1_accounts_jwt_create_create
description: |- description: |-
Takes a set of user credentials and returns an access and refresh JSON web Takes a set of user credentials and returns an access and refresh JSON web
token pair to prove the authentication of those credentials. token pair to prove the authentication of those credentials.
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -33,12 +33,12 @@ paths:
description: '' description: ''
/api/v1/accounts/jwt/refresh/: /api/v1/accounts/jwt/refresh/:
post: post:
operationId: accounts_jwt_refresh_create operationId: api_v1_accounts_jwt_refresh_create
description: |- description: |-
Takes a refresh type JSON web token and returns an access type JSON web Takes a refresh type JSON web token and returns an access type JSON web
token if the refresh token is valid. token if the refresh token is valid.
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -60,12 +60,12 @@ paths:
description: '' description: ''
/api/v1/accounts/jwt/verify/: /api/v1/accounts/jwt/verify/:
post: post:
operationId: accounts_jwt_verify_create operationId: api_v1_accounts_jwt_verify_create
description: |- description: |-
Takes a token and indicates if it is valid. This view provides no Takes a token and indicates if it is valid. This view provides no
information about a token's fitness for a particular use. information about a token's fitness for a particular use.
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -87,9 +87,9 @@ paths:
description: '' description: ''
/api/v1/accounts/users/: /api/v1/accounts/users/:
get: get:
operationId: accounts_users_list operationId: api_v1_accounts_users_list
tags: tags:
- accounts - api
security: security:
- jwtAuth: [] - jwtAuth: []
responses: responses:
@ -102,9 +102,9 @@ paths:
$ref: '#/components/schemas/CustomUser' $ref: '#/components/schemas/CustomUser'
description: '' description: ''
post: post:
operationId: accounts_users_create operationId: api_v1_accounts_users_create
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -129,7 +129,7 @@ paths:
description: '' description: ''
/api/v1/accounts/users/{id}/: /api/v1/accounts/users/{id}/:
get: get:
operationId: accounts_users_retrieve operationId: api_v1_accounts_users_retrieve
parameters: parameters:
- in: path - in: path
name: id name: id
@ -138,7 +138,7 @@ paths:
description: A unique integer value identifying this user. description: A unique integer value identifying this user.
required: true required: true
tags: tags:
- accounts - api
security: security:
- jwtAuth: [] - jwtAuth: []
- {} - {}
@ -150,7 +150,7 @@ paths:
$ref: '#/components/schemas/CustomUser' $ref: '#/components/schemas/CustomUser'
description: '' description: ''
put: put:
operationId: accounts_users_update operationId: api_v1_accounts_users_update
parameters: parameters:
- in: path - in: path
name: id name: id
@ -159,7 +159,7 @@ paths:
description: A unique integer value identifying this user. description: A unique integer value identifying this user.
required: true required: true
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -183,7 +183,7 @@ paths:
$ref: '#/components/schemas/CustomUser' $ref: '#/components/schemas/CustomUser'
description: '' description: ''
patch: patch:
operationId: accounts_users_partial_update operationId: api_v1_accounts_users_partial_update
parameters: parameters:
- in: path - in: path
name: id name: id
@ -192,7 +192,7 @@ paths:
description: A unique integer value identifying this user. description: A unique integer value identifying this user.
required: true required: true
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -215,7 +215,7 @@ paths:
$ref: '#/components/schemas/CustomUser' $ref: '#/components/schemas/CustomUser'
description: '' description: ''
delete: delete:
operationId: accounts_users_destroy operationId: api_v1_accounts_users_destroy
parameters: parameters:
- in: path - in: path
name: id name: id
@ -224,7 +224,7 @@ paths:
description: A unique integer value identifying this user. description: A unique integer value identifying this user.
required: true required: true
tags: tags:
- accounts - api
security: security:
- jwtAuth: [] - jwtAuth: []
responses: responses:
@ -232,9 +232,9 @@ paths:
description: No response body description: No response body
/api/v1/accounts/users/activation/: /api/v1/accounts/users/activation/:
post: post:
operationId: accounts_users_activation_create operationId: api_v1_accounts_users_activation_create
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -259,9 +259,9 @@ paths:
description: '' description: ''
/api/v1/accounts/users/me/: /api/v1/accounts/users/me/:
get: get:
operationId: accounts_users_me_retrieve operationId: api_v1_accounts_users_me_retrieve
tags: tags:
- accounts - api
security: security:
- jwtAuth: [] - jwtAuth: []
- {} - {}
@ -273,9 +273,9 @@ paths:
$ref: '#/components/schemas/CustomUser' $ref: '#/components/schemas/CustomUser'
description: '' description: ''
put: put:
operationId: accounts_users_me_update operationId: api_v1_accounts_users_me_update
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -299,9 +299,9 @@ paths:
$ref: '#/components/schemas/CustomUser' $ref: '#/components/schemas/CustomUser'
description: '' description: ''
patch: patch:
operationId: accounts_users_me_partial_update operationId: api_v1_accounts_users_me_partial_update
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -324,9 +324,9 @@ paths:
$ref: '#/components/schemas/CustomUser' $ref: '#/components/schemas/CustomUser'
description: '' description: ''
delete: delete:
operationId: accounts_users_me_destroy operationId: api_v1_accounts_users_me_destroy
tags: tags:
- accounts - api
security: security:
- jwtAuth: [] - jwtAuth: []
responses: responses:
@ -334,9 +334,9 @@ paths:
description: No response body description: No response body
/api/v1/accounts/users/resend_activation/: /api/v1/accounts/users/resend_activation/:
post: post:
operationId: accounts_users_resend_activation_create operationId: api_v1_accounts_users_resend_activation_create
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -361,9 +361,9 @@ paths:
description: '' description: ''
/api/v1/accounts/users/reset_password/: /api/v1/accounts/users/reset_password/:
post: post:
operationId: accounts_users_reset_password_create operationId: api_v1_accounts_users_reset_password_create
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -388,9 +388,9 @@ paths:
description: '' description: ''
/api/v1/accounts/users/reset_password_confirm/: /api/v1/accounts/users/reset_password_confirm/:
post: post:
operationId: accounts_users_reset_password_confirm_create operationId: api_v1_accounts_users_reset_password_confirm_create
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -415,9 +415,9 @@ paths:
description: '' description: ''
/api/v1/accounts/users/reset_username/: /api/v1/accounts/users/reset_username/:
post: post:
operationId: accounts_users_reset_username_create operationId: api_v1_accounts_users_reset_username_create
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -441,9 +441,9 @@ paths:
description: '' description: ''
/api/v1/accounts/users/reset_username_confirm/: /api/v1/accounts/users/reset_username_confirm/:
post: post:
operationId: accounts_users_reset_username_confirm_create operationId: api_v1_accounts_users_reset_username_confirm_create
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -467,9 +467,9 @@ paths:
description: '' description: ''
/api/v1/accounts/users/set_password/: /api/v1/accounts/users/set_password/:
post: post:
operationId: accounts_users_set_password_create operationId: api_v1_accounts_users_set_password_create
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -493,9 +493,9 @@ paths:
description: '' description: ''
/api/v1/accounts/users/set_username/: /api/v1/accounts/users/set_username/:
post: post:
operationId: accounts_users_set_username_create operationId: api_v1_accounts_users_set_username_create
tags: tags:
- accounts - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -519,9 +519,9 @@ paths:
description: '' description: ''
/api/v1/billing/: /api/v1/billing/:
get: get:
operationId: billing_retrieve operationId: api_v1_billing_retrieve
tags: tags:
- billing - api
security: security:
- jwtAuth: [] - jwtAuth: []
responses: responses:
@ -529,9 +529,9 @@ paths:
description: No response body description: No response body
/api/v1/notifications/: /api/v1/notifications/:
get: get:
operationId: notifications_list operationId: api_v1_notifications_list
tags: tags:
- notifications - api
security: security:
- jwtAuth: [] - jwtAuth: []
- {} - {}
@ -546,7 +546,7 @@ paths:
description: '' description: ''
/api/v1/notifications/{id}/: /api/v1/notifications/{id}/:
get: get:
operationId: notifications_retrieve operationId: api_v1_notifications_retrieve
parameters: parameters:
- in: path - in: path
name: id name: id
@ -555,7 +555,7 @@ paths:
description: A unique integer value identifying this notification. description: A unique integer value identifying this notification.
required: true required: true
tags: tags:
- notifications - api
security: security:
- jwtAuth: [] - jwtAuth: []
- {} - {}
@ -567,7 +567,7 @@ paths:
$ref: '#/components/schemas/Notification' $ref: '#/components/schemas/Notification'
description: '' description: ''
patch: patch:
operationId: notifications_partial_update operationId: api_v1_notifications_partial_update
parameters: parameters:
- in: path - in: path
name: id name: id
@ -576,7 +576,7 @@ paths:
description: A unique integer value identifying this notification. description: A unique integer value identifying this notification.
required: true required: true
tags: tags:
- notifications - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -599,7 +599,7 @@ paths:
$ref: '#/components/schemas/Notification' $ref: '#/components/schemas/Notification'
description: '' description: ''
delete: delete:
operationId: notifications_destroy operationId: api_v1_notifications_destroy
parameters: parameters:
- in: path - in: path
name: id name: id
@ -608,7 +608,7 @@ paths:
description: A unique integer value identifying this notification. description: A unique integer value identifying this notification.
required: true required: true
tags: tags:
- notifications - api
security: security:
- jwtAuth: [] - jwtAuth: []
- {} - {}
@ -617,9 +617,9 @@ paths:
description: No response body description: No response body
/api/v1/stripe/checkout_session/: /api/v1/stripe/checkout_session/:
post: post:
operationId: stripe_checkout_session_create operationId: api_v1_stripe_checkout_session_create
tags: tags:
- stripe - api
requestBody: requestBody:
content: content:
application/json: application/json:
@ -639,9 +639,9 @@ paths:
description: No response body description: No response body
/api/v1/stripe/webhook/: /api/v1/stripe/webhook/:
post: post:
operationId: stripe_webhook_create operationId: api_v1_stripe_webhook_create
tags: tags:
- stripe - api
security: security:
- jwtAuth: [] - jwtAuth: []
- {} - {}
@ -650,9 +650,9 @@ paths:
description: No response body description: No response body
/api/v1/subscriptions/plans/: /api/v1/subscriptions/plans/:
get: get:
operationId: subscriptions_plans_list operationId: api_v1_subscriptions_plans_list
tags: tags:
- subscriptions - api
security: security:
- jwtAuth: [] - jwtAuth: []
- {} - {}
@ -667,7 +667,7 @@ paths:
description: '' description: ''
/api/v1/subscriptions/plans/{id}/: /api/v1/subscriptions/plans/{id}/:
get: get:
operationId: subscriptions_plans_retrieve operationId: api_v1_subscriptions_plans_retrieve
parameters: parameters:
- in: path - in: path
name: id name: id
@ -676,7 +676,7 @@ paths:
description: A unique integer value identifying this subscription plan. description: A unique integer value identifying this subscription plan.
required: true required: true
tags: tags:
- subscriptions - api
security: security:
- jwtAuth: [] - jwtAuth: []
- {} - {}
@ -689,9 +689,9 @@ paths:
description: '' description: ''
/api/v1/subscriptions/self/: /api/v1/subscriptions/self/:
get: get:
operationId: subscriptions_self_list operationId: api_v1_subscriptions_self_list
tags: tags:
- subscriptions - api
security: security:
- jwtAuth: [] - jwtAuth: []
responses: responses:
@ -705,7 +705,7 @@ paths:
description: '' description: ''
/api/v1/subscriptions/self/{id}/: /api/v1/subscriptions/self/{id}/:
get: get:
operationId: subscriptions_self_retrieve operationId: api_v1_subscriptions_self_retrieve
parameters: parameters:
- in: path - in: path
name: id name: id
@ -714,7 +714,7 @@ paths:
description: A unique integer value identifying this user subscription. description: A unique integer value identifying this user subscription.
required: true required: true
tags: tags:
- subscriptions - api
security: security:
- jwtAuth: [] - jwtAuth: []
responses: responses:
@ -726,9 +726,9 @@ paths:
description: '' description: ''
/api/v1/subscriptions/user_group/: /api/v1/subscriptions/user_group/:
get: get:
operationId: subscriptions_user_group_list operationId: api_v1_subscriptions_user_group_list
tags: tags:
- subscriptions - api
security: security:
- jwtAuth: [] - jwtAuth: []
responses: responses:
@ -742,7 +742,7 @@ paths:
description: '' description: ''
/api/v1/subscriptions/user_group/{id}/: /api/v1/subscriptions/user_group/{id}/:
get: get:
operationId: subscriptions_user_group_retrieve operationId: api_v1_subscriptions_user_group_retrieve
parameters: parameters:
- in: path - in: path
name: id name: id
@ -751,7 +751,7 @@ paths:
description: A unique integer value identifying this user subscription. description: A unique integer value identifying this user subscription.
required: true required: true
tags: tags:
- subscriptions - api
security: security:
- jwtAuth: [] - jwtAuth: []
responses: responses:

View file

@ -23,8 +23,7 @@ def sample_selenium_task():
@shared_task(autoretry_for=(Exception,), retry_kwargs={'max_retries': 3, 'countdown': 5}) @shared_task(autoretry_for=(Exception,), retry_kwargs={'max_retries': 3, 'countdown': 5})
def simple_google_search(): def simple_google_search():
driver = setup_webdriver(driver_type="firefox", driver = setup_webdriver(use_proxy=False, use_saved_session=False)
use_proxy=False, use_saved_session=False)
driver.get(f"https://google.com/") driver.get(f"https://google.com/")
google_search(driver, search_term="cat blog posts") google_search(driver, search_term="cat blog posts")

View file

@ -1,8 +1,10 @@
version: "3.9"
services: services:
# Django Backend # Django Backend
django: django:
env_file: .env env_file: .env
image: git.06222001.xyz/keannu125/drf_template:latest image: keannu125/drf-template:latest
ports: ports:
- "${BACKEND_PORT}:8000" - "${BACKEND_PORT}:8000"
environment: environment:
@ -10,18 +12,16 @@ services:
- RUN_TYPE=web - RUN_TYPE=web
depends_on: depends_on:
- postgres - postgres
- pgbouncer
# Django Celery Worker # Django Celery Worker
celery: celery:
env_file: .env env_file: .env
environment: environment:
- RUN_TYPE=worker - RUN_TYPE=worker
image: git.06222001.xyz/keannu125/drf_template:latest image: keannu125/drf-template:latest
depends_on: depends_on:
- django - django
- postgres - postgres
- pgbouncer
- redis - redis
# Run multiple worker instances # Run multiple worker instances
scale: 4 scale: 4
@ -31,12 +31,11 @@ services:
env_file: .env env_file: .env
environment: environment:
- RUN_TYPE=beat - RUN_TYPE=beat
image: git.06222001.xyz/keannu125/drf_template:latest image: keannu125/drf-template:latest
depends_on: depends_on:
- celery - celery
- django - django
- postgres - postgres
- pgbouncer
- redis - redis
# SQL Database # SQL Database
@ -48,7 +47,7 @@ services:
- POSTGRES_USER=${DB_USERNAME} - POSTGRES_USER=${DB_USERNAME}
- POSTGRES_PASSWORD=${DB_PASSWORD} - POSTGRES_PASSWORD=${DB_PASSWORD}
volumes: volumes:
- db_data:/var/lib/postgresql/data - db-data:/var/lib/postgresql/data
command: postgres -c max_connections=200 command: postgres -c max_connections=200
# DB Bouncer # DB Bouncer
@ -77,4 +76,4 @@ services:
command: listen --forward-to django:8000/api/v1/stripe/webhook/ command: listen --forward-to django:8000/api/v1/stripe/webhook/
volumes: volumes:
db_data: db-data:

View file

@ -1,3 +1,5 @@
version: "3.9"
services: services:
# Django Backend # Django Backend
django: django: