Signed-off-by: cankush625 <cankush625@gmail.com>pull/228/head
parent
04f8c9ca12
commit
067f88f326
@ -0,0 +1,4 @@ |
||||
# Redis Host name or address |
||||
REDIS_HOST= |
||||
# Redis database port |
||||
REDIS_PORT= |
@ -0,0 +1,148 @@ |
||||
# Byte-compiled / optimized / DLL files |
||||
__pycache__/ |
||||
*.py[cod] |
||||
*$py.class |
||||
|
||||
# C extensions |
||||
*.so |
||||
|
||||
# Distribution / packaging |
||||
.Python |
||||
build/ |
||||
develop-eggs/ |
||||
dist/ |
||||
downloads/ |
||||
eggs/ |
||||
.eggs/ |
||||
lib/ |
||||
lib64/ |
||||
parts/ |
||||
sdist/ |
||||
var/ |
||||
wheels/ |
||||
share/python-wheels/ |
||||
*.egg-info/ |
||||
.installed.cfg |
||||
*.egg |
||||
MANIFEST |
||||
|
||||
# PyInstaller |
||||
# Usually these files are written by a python script from a template |
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it. |
||||
*.manifest |
||||
*.spec |
||||
|
||||
# Installer logs |
||||
pip-log.txt |
||||
pip-delete-this-directory.txt |
||||
|
||||
# Unit test / coverage reports |
||||
htmlcov/ |
||||
.tox/ |
||||
.nox/ |
||||
.coverage |
||||
.coverage.* |
||||
.cache |
||||
nosetests.xml |
||||
coverage.xml |
||||
*.cover |
||||
*.py,cover |
||||
.hypothesis/ |
||||
.pytest_cache/ |
||||
cover/ |
||||
|
||||
# Translations |
||||
*.mo |
||||
*.pot |
||||
|
||||
# Django stuff: |
||||
*.log |
||||
local_settings.py |
||||
db.sqlite3 |
||||
db.sqlite3-journal |
||||
|
||||
# Flask stuff: |
||||
instance/ |
||||
.webassets-cache |
||||
|
||||
# Scrapy stuff: |
||||
.scrapy |
||||
|
||||
# Sphinx documentation |
||||
docs/_build/ |
||||
|
||||
# PyBuilder |
||||
.pybuilder/ |
||||
target/ |
||||
|
||||
# Jupyter Notebook |
||||
.ipynb_checkpoints |
||||
|
||||
# IPython |
||||
profile_default/ |
||||
ipython_config.py |
||||
|
||||
# pyenv |
||||
# For a library or package, you might want to ignore these files since the code is |
||||
# intended to run in multiple environments; otherwise, check them in: |
||||
# .python-version |
||||
|
||||
# pipenv |
||||
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. |
||||
# However, in case of collaboration, if having platform-specific dependencies or dependencies |
||||
# having no cross-platform support, pipenv may install dependencies that don't work, or not |
||||
# install all needed dependencies. |
||||
#Pipfile.lock |
||||
|
||||
# poetry |
||||
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. |
||||
# This is especially recommended for binary packages to ensure reproducibility, and is more |
||||
# commonly ignored for libraries. |
||||
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control |
||||
#poetry.lock |
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow |
||||
__pypackages__/ |
||||
|
||||
# Celery stuff |
||||
celerybeat-schedule |
||||
celerybeat.pid |
||||
|
||||
# SageMath parsed files |
||||
*.sage.py |
||||
|
||||
# Environments |
||||
.env |
||||
.venv |
||||
env/ |
||||
venv/ |
||||
ENV/ |
||||
env.bak/ |
||||
venv.bak/ |
||||
|
||||
# Spyder project settings |
||||
.spyderproject |
||||
.spyproject |
||||
|
||||
# Rope project settings |
||||
.ropeproject |
||||
|
||||
# mkdocs documentation |
||||
/site |
||||
|
||||
# mypy |
||||
.mypy_cache/ |
||||
.dmypy.json |
||||
dmypy.json |
||||
|
||||
# Pyre type checker |
||||
.pyre/ |
||||
|
||||
# pytype static type analyzer |
||||
.pytype/ |
||||
|
||||
# Cython debug symbols |
||||
cython_debug/ |
||||
|
||||
# PyCharm |
||||
.idea/ |
@ -0,0 +1,5 @@ |
||||
FROM python:3.9.11-alpine3.14 |
||||
WORKDIR /code |
||||
COPY . /code |
||||
RUN apk add --update alpine-sdk |
||||
RUN pip install -r requirements.txt --no-cache-dir |
@ -0,0 +1,87 @@ |
||||
## Compose sample application |
||||
|
||||
### Python/Django application using a Redis database |
||||
|
||||
## Project structure: |
||||
|
||||
``` |
||||
. |
||||
├── django_redis |
||||
│ ├── config/ |
||||
│ │ └── settings.py |
||||
│ ├── database/ |
||||
│ │ ├── migrations/ |
||||
│ │ ├── admin.py |
||||
│ │ ├── apps.py |
||||
│ │ ├── models.py |
||||
│ │ ├── urls.py |
||||
│ │ └── views.py |
||||
│ ├── asgi.py |
||||
│ ├── manage.py |
||||
│ └── wsgi.py |
||||
├── .env |
||||
├── .env.example |
||||
├── .gitignore |
||||
├── docker-compose.yml |
||||
├── Dockerfile |
||||
├── README.md |
||||
└── requirements.txt |
||||
``` |
||||
|
||||
The `.env` file should have the environment variables that are specified in the `.env.example` file. |
||||
|
||||
[_docker-compose.yml_](docker-compose.yml) |
||||
|
||||
``` |
||||
services: |
||||
redis: |
||||
image: redislabs/redismod |
||||
ports: |
||||
- '6379:6379' |
||||
web: |
||||
build: . |
||||
command: python django_redis/manage.py runserver 0.0.0.0:8000 |
||||
env_file: |
||||
- .env |
||||
ports: |
||||
- '8000:8000' |
||||
volumes: |
||||
- .:/code |
||||
depends_on: |
||||
- redis |
||||
``` |
||||
|
||||
## Deploy with docker-compose |
||||
|
||||
``` |
||||
$ docker-compose up -d |
||||
[+] Running 2/2 |
||||
- Container djangoredis-redis-1 Started |
||||
- Container djangoredis-web-1 Started |
||||
``` |
||||
|
||||
## Expected result |
||||
|
||||
Listing containers must show two containers running and the port mapping as below: |
||||
``` |
||||
|
||||
$ docker ps |
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
||||
384fcfc8a3d3 djangoredis_web "python django_redis…" 2 minutes ago Up 41 seconds 0.0.0.0:8000->8000/tcp djangoredis-web-1 |
||||
9b6c3ce8d394 redislabs/redismod "redis-server --load…" 2 minutes ago Up 44 seconds 0.0.0.0:6379->6379/tcp djangoredis-redis-1 |
||||
``` |
||||
|
||||
After the application starts, navigate to `http://localhost:8000/hello-redis` in your web browser or run: |
||||
``` |
||||
$ curl localhost:8000/hello-redis |
||||
This page has been visited 5 times |
||||
``` |
||||
|
||||
## Stop and remove the containers |
||||
``` |
||||
$ docker-compose down |
||||
[+] Running 3/3 |
||||
- Container djangoredis-web-1 Removed |
||||
- Container djangoredis-redis-1 Removed |
||||
- Network djangoredis_default Removed |
||||
``` |
@ -0,0 +1,16 @@ |
||||
""" |
||||
ASGI config for config 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.0/howto/deployment/asgi/ |
||||
""" |
||||
|
||||
import os |
||||
|
||||
from django.core.asgi import get_asgi_application |
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') |
||||
|
||||
application = get_asgi_application() |
@ -0,0 +1,130 @@ |
||||
""" |
||||
Django settings for config project. |
||||
|
||||
Generated by 'django-admin startproject' using Django 4.0.3. |
||||
|
||||
For more information on this file, see |
||||
https://docs.djangoproject.com/en/4.0/topics/settings/ |
||||
|
||||
For the full list of settings and their values, see |
||||
https://docs.djangoproject.com/en/4.0/ref/settings/ |
||||
""" |
||||
import os |
||||
from pathlib import Path |
||||
|
||||
# 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 = 'django-insecure-sgq57^ub&0te!d6mt9m7-a*bf29k=e+%h=a!d1l7ceqr4qv0r5' |
||||
|
||||
# SECURITY WARNING: don't run with debug turned on in production! |
||||
DEBUG = True |
||||
|
||||
ALLOWED_HOSTS = [] |
||||
|
||||
|
||||
# Application definition |
||||
|
||||
INSTALLED_APPS = [ |
||||
'django.contrib.admin', |
||||
'django.contrib.auth', |
||||
'django.contrib.contenttypes', |
||||
'django.contrib.sessions', |
||||
'django.contrib.messages', |
||||
'django.contrib.staticfiles', |
||||
'database.apps.DatabaseConfig', |
||||
] |
||||
|
||||
MIDDLEWARE = [ |
||||
'django.middleware.security.SecurityMiddleware', |
||||
'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 = 'database.urls' |
||||
|
||||
TEMPLATES = [ |
||||
{ |
||||
'BACKEND': 'django.template.backends.django.DjangoTemplates', |
||||
'DIRS': [BASE_DIR / 'templates'] |
||||
, |
||||
'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 = 'wsgi.application' |
||||
|
||||
|
||||
# Database |
||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases |
||||
|
||||
DATABASES = { |
||||
'default': { |
||||
'ENGINE': 'django.db.backends.sqlite3', |
||||
'NAME': BASE_DIR / 'db.sqlite3', |
||||
} |
||||
} |
||||
|
||||
# Redis database configuration |
||||
|
||||
HOST = os.environ.get("REDIS_HOST") |
||||
PORT = os.environ.get("REDIS_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', |
||||
}, |
||||
] |
||||
|
||||
|
||||
# Internationalization |
||||
# https://docs.djangoproject.com/en/4.0/topics/i18n/ |
||||
|
||||
LANGUAGE_CODE = 'en-us' |
||||
|
||||
TIME_ZONE = 'UTC' |
||||
|
||||
USE_I18N = True |
||||
|
||||
USE_TZ = True |
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images) |
||||
# https://docs.djangoproject.com/en/4.0/howto/static-files/ |
||||
|
||||
STATIC_URL = 'static/' |
||||
|
||||
# Default primary key field type |
||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field |
||||
|
||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' |
@ -0,0 +1,3 @@ |
||||
from django.contrib import admin |
||||
|
||||
# Register your models here. |
@ -0,0 +1,6 @@ |
||||
from django.apps import AppConfig |
||||
|
||||
|
||||
class DatabaseConfig(AppConfig): |
||||
default_auto_field = 'django.db.models.BigAutoField' |
||||
name = 'database' |
@ -0,0 +1,3 @@ |
||||
from django.db import models |
||||
|
||||
# Create your models here. |
@ -0,0 +1,8 @@ |
||||
from django.urls import path |
||||
|
||||
from database.views import visit_counter |
||||
|
||||
|
||||
urlpatterns = [ |
||||
path('hello-redis/', visit_counter), |
||||
] |
@ -0,0 +1,17 @@ |
||||
from django.conf import settings |
||||
from django.http import HttpResponse |
||||
from redis import Redis |
||||
|
||||
def get_database_connection(host: str, port: str) -> Redis: |
||||
"""Returns Redis client""" |
||||
|
||||
return Redis(host=host, port=int(port)) |
||||
|
||||
|
||||
def visit_counter(request) -> HttpResponse: |
||||
"""Connect to redis and increase the visits count for each visit""" |
||||
|
||||
redis = get_database_connection(settings.HOST, settings.PORT) |
||||
redis.incr('views') |
||||
count = str(redis.get('views'), 'utf-8') |
||||
return HttpResponse("This page has been visited {0} times".format(count)) |
@ -0,0 +1,22 @@ |
||||
#!/usr/bin/env python |
||||
"""Django's command-line utility for administrative tasks.""" |
||||
import os |
||||
import sys |
||||
|
||||
|
||||
def main(): |
||||
"""Run administrative tasks.""" |
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') |
||||
try: |
||||
from django.core.management import execute_from_command_line |
||||
except ImportError as exc: |
||||
raise ImportError( |
||||
"Couldn't import Django. Are you sure it's installed and " |
||||
"available on your PYTHONPATH environment variable? Did you " |
||||
"forget to activate a virtual environment?" |
||||
) from exc |
||||
execute_from_command_line(sys.argv) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
main() |
@ -0,0 +1,16 @@ |
||||
""" |
||||
WSGI config for config 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.0/howto/deployment/wsgi/ |
||||
""" |
||||
|
||||
import os |
||||
|
||||
from django.core.wsgi import get_wsgi_application |
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings') |
||||
|
||||
application = get_wsgi_application() |
@ -0,0 +1,16 @@ |
||||
services: |
||||
redis: |
||||
image: redislabs/redismod |
||||
ports: |
||||
- '6379:6379' |
||||
web: |
||||
build: . |
||||
command: python django_redis/manage.py runserver 0.0.0.0:8000 |
||||
env_file: |
||||
- .env |
||||
ports: |
||||
- '8000:8000' |
||||
volumes: |
||||
- .:/code |
||||
depends_on: |
||||
- redis |
Binary file not shown.
Loading…
Reference in new issue