mirror of
https://github.com/ae-utbm/sith.git
synced 2025-03-10 07:17:11 +00:00
Integrate automatic redis startup with the project
This commit is contained in:
parent
6841d96455
commit
ba6e2a6402
@ -8,4 +8,10 @@ SECRET_KEY=(4sjxvhz@m5$0a$j0_pqicnc$s!vbve)z+&++m%g%bjhlz4+g2
|
||||
DATABASE_URL=sqlite:///db.sqlite3
|
||||
#DATABASE_URL=postgres://user:password@127.0.0.1:5432/sith
|
||||
|
||||
CACHE_URL=redis://127.0.0.1:6379/0
|
||||
REDIS_PORT=7963
|
||||
CACHE_URL=redis://127.0.0.1:${REDIS_PORT}/0
|
||||
|
||||
# Used to select which other services to run alongside
|
||||
# runserver and pytest
|
||||
PROCFILE_RUNSERVER=Procfile.dev
|
||||
PROCFILE_PYTEST=Procfile.pytest
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -22,3 +22,9 @@ node_modules/
|
||||
# compiled documentation
|
||||
site/
|
||||
.env
|
||||
|
||||
### Redis ###
|
||||
|
||||
# Ignore redis binary dump (dump.rdb) files
|
||||
|
||||
*.rdb
|
||||
|
2
Procfile.dev
Normal file
2
Procfile.dev
Normal file
@ -0,0 +1,2 @@
|
||||
bundler: npm run serve
|
||||
redis: redis-server --port $REDIS_PORT
|
1
Procfile.pytest
Normal file
1
Procfile.pytest
Normal file
@ -0,0 +1 @@
|
||||
redis: redis-server --port $REDIS_PORT
|
14
manage.py
14
manage.py
@ -13,13 +13,25 @@
|
||||
# OR WITHIN THE LOCAL FILE "LICENSE"
|
||||
#
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from django.utils.autoreload import DJANGO_AUTORELOAD_ENV
|
||||
|
||||
from processes.composer import start_composer, stop_composer
|
||||
from sith.environ import env
|
||||
|
||||
if __name__ == "__main__":
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sith.settings")
|
||||
|
||||
from django.core.management import execute_from_command_line
|
||||
|
||||
if (
|
||||
os.environ.get(DJANGO_AUTORELOAD_ENV) is None
|
||||
and (procfile := env.str("PROCFILE_RUNSERVER", None)) is not None
|
||||
):
|
||||
start_composer(procfile)
|
||||
|
||||
execute_from_command_line(sys.argv)
|
||||
|
||||
stop_composer()
|
||||
|
26
processes/composer.py
Normal file
26
processes/composer.py
Normal file
@ -0,0 +1,26 @@
|
||||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
import psutil
|
||||
|
||||
COMPOSER_PID = "COMPOSER_PID"
|
||||
|
||||
|
||||
def start_composer(procfile: str):
|
||||
"""Starts the composer and stores the PID as an environment variable
|
||||
This allows for running smoothly with the django reloader
|
||||
"""
|
||||
process = subprocess.Popen(
|
||||
[sys.executable, "-m", "honcho", "-f", procfile, "start"],
|
||||
)
|
||||
os.environ[COMPOSER_PID] = str(process.pid)
|
||||
|
||||
|
||||
def stop_composer():
|
||||
"""Stops the composer if it was started before"""
|
||||
if (pid := os.environ.get(COMPOSER_PID, None)) is not None:
|
||||
process = psutil.Process(int(pid))
|
||||
process.send_signal(signal.SIGTERM)
|
||||
process.wait()
|
@ -48,6 +48,7 @@ dependencies = [
|
||||
"environs[django]<15.0.0,>=14.1.0",
|
||||
"requests>=2.32.3",
|
||||
"honcho>=2.0.0",
|
||||
"psutil>=7.0.0",
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
@ -125,6 +126,9 @@ ignore = [
|
||||
[tool.ruff.lint.pydocstyle]
|
||||
convention = "google"
|
||||
|
||||
[project.entry-points.pytest11]
|
||||
sith = "sith.pytest"
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
DJANGO_SETTINGS_MODULE = "sith.settings"
|
||||
python_files = ["tests.py", "test_*.py", "*_tests.py"]
|
||||
|
4
sith/environ.py
Normal file
4
sith/environ.py
Normal file
@ -0,0 +1,4 @@
|
||||
from environs import Env
|
||||
|
||||
env = Env()
|
||||
_ = env.read_env()
|
23
sith/pytest.py
Normal file
23
sith/pytest.py
Normal file
@ -0,0 +1,23 @@
|
||||
import pytest
|
||||
|
||||
from processes.composer import start_composer, stop_composer
|
||||
|
||||
from .environ import env
|
||||
|
||||
# pytest-django uses the load_initial_conftest hook
|
||||
# it's the first hook loaded by pytest and can only
|
||||
# be defined in a proper pytest plugin
|
||||
# To use the composer before pytest-django loads
|
||||
# we need to define this hook and thus create a proper
|
||||
# pytest plugin. We can't just use conftest.py
|
||||
|
||||
|
||||
@pytest.hookimpl(tryfirst=True)
|
||||
def pytest_load_initial_conftests(early_config, parser, args):
|
||||
"""Hook that loads the composer before the pytest-django plugin"""
|
||||
if (procfile := env.str("PROCFILE_PYTEST", None)) is not None:
|
||||
start_composer(procfile)
|
||||
|
||||
|
||||
def pytest_unconfigure(config):
|
||||
stop_composer()
|
@ -42,14 +42,11 @@ from pathlib import Path
|
||||
import sentry_sdk
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from environs import Env
|
||||
from sentry_sdk.integrations.django import DjangoIntegration
|
||||
|
||||
from .environ import env
|
||||
from .honeypot import custom_honeypot_error
|
||||
|
||||
env = Env()
|
||||
env.read_env()
|
||||
|
||||
BASE_DIR = Path(__file__).parent.parent.resolve()
|
||||
|
||||
# Quick-start development settings - unsuitable for production
|
||||
|
@ -1,13 +1,6 @@
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.staticfiles.management.commands.runserver import (
|
||||
Command as Runserver,
|
||||
)
|
||||
from django.utils.autoreload import DJANGO_AUTORELOAD_ENV
|
||||
|
||||
from staticfiles.processors import OpenApi
|
||||
|
||||
@ -16,19 +9,5 @@ class Command(Runserver):
|
||||
"""Light wrapper around default runserver that integrates javascirpt auto bundling."""
|
||||
|
||||
def run(self, **options):
|
||||
# OpenApi generation needs to be before the bundler
|
||||
OpenApi.compile()
|
||||
# Run all other web processes but only if debug mode is enabled
|
||||
# Also protects from re-launching the server if django reloads it
|
||||
if os.environ.get(DJANGO_AUTORELOAD_ENV) is None:
|
||||
logging.getLogger("django").info("Running complementary processes")
|
||||
with subprocess.Popen(
|
||||
[sys.executable, "-m", "honcho", "start"],
|
||||
env={
|
||||
**os.environ,
|
||||
**{"BUNDLER_MODE": "serve" if settings.DEBUG else "compile"},
|
||||
},
|
||||
):
|
||||
super().run(**options)
|
||||
return
|
||||
super().run(**options)
|
||||
|
17
uv.lock
generated
17
uv.lock
generated
@ -1104,6 +1104,21 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/6a/fd08d94654f7e67c52ca30523a178b3f8ccc4237fce4be90d39c938a831a/prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e", size = 386595 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psutil"
|
||||
version = "7.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/2a/80/336820c1ad9286a4ded7e845b2eccfcb27851ab8ac6abece774a6ff4d3de/psutil-7.0.0.tar.gz", hash = "sha256:7be9c3eba38beccb6495ea33afd982a44074b78f28c434a1f51cc07fd315c456", size = 497003 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/e6/2d26234410f8b8abdbf891c9da62bee396583f713fb9f3325a4760875d22/psutil-7.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:101d71dc322e3cffd7cea0650b09b3d08b8e7c4109dd6809fe452dfd00e58b25", size = 238051 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/8b/30f930733afe425e3cbfc0e1468a30a18942350c1a8816acfade80c005c4/psutil-7.0.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:39db632f6bb862eeccf56660871433e111b6ea58f2caea825571951d4b6aa3da", size = 239535 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/ed/d362e84620dd22876b55389248e522338ed1bf134a5edd3b8231d7207f6d/psutil-7.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fcee592b4c6f146991ca55919ea3d1f8926497a713ed7faaf8225e174581e91", size = 275004 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/b9/b0eb3f3cbcb734d930fdf839431606844a825b23eaf9a6ab371edac8162c/psutil-7.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b1388a4f6875d7e2aff5c4ca1cc16c545ed41dd8bb596cefea80111db353a34", size = 277986 },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/a2/709e0fe2f093556c17fbafda93ac032257242cabcc7ff3369e2cb76a97aa/psutil-7.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5f098451abc2828f7dc6b58d44b532b22f2088f4999a937557b603ce72b1993", size = 279544 },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/e6/eecf58810b9d12e6427369784efe814a1eec0f492084ce8eb8f4d89d6d61/psutil-7.0.0-cp37-abi3-win32.whl", hash = "sha256:ba3fcef7523064a6c9da440fc4d6bd07da93ac726b5733c29027d7dc95b39d99", size = 241053 },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/1b/6921afe68c74868b4c9fa424dad3be35b095e16687989ebbb50ce4fceb7c/psutil-7.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:4cf3d4eb1aa9b348dec30105c55cd9b7d4629285735a102beb4441e38db90553", size = 244885 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "psycopg"
|
||||
version = "3.2.3"
|
||||
@ -1520,6 +1535,7 @@ dependencies = [
|
||||
{ name = "mistune" },
|
||||
{ name = "phonenumbers" },
|
||||
{ name = "pillow" },
|
||||
{ name = "psutil" },
|
||||
{ name = "pydantic-extra-types" },
|
||||
{ name = "python-dateutil" },
|
||||
{ name = "redis", extra = ["hiredis"] },
|
||||
@ -1581,6 +1597,7 @@ requires-dist = [
|
||||
{ name = "mistune", specifier = ">=3.0.2,<4.0.0" },
|
||||
{ name = "phonenumbers", specifier = ">=8.13.52,<9.0.0" },
|
||||
{ name = "pillow", specifier = ">=11.0.0,<12.0.0" },
|
||||
{ name = "psutil", specifier = ">=7.0.0" },
|
||||
{ name = "pydantic-extra-types", specifier = ">=2.10.1,<3.0.0" },
|
||||
{ name = "python-dateutil", specifier = ">=2.9.0.post0,<3.0.0.0" },
|
||||
{ name = "redis", extras = ["hiredis"], specifier = ">=5.2.0,<6.0.0" },
|
||||
|
Loading…
x
Reference in New Issue
Block a user