diff --git a/solution/services/backend/.env.template b/solution/services/backend/.env.template new file mode 100644 index 0000000..5988a69 --- /dev/null +++ b/solution/services/backend/.env.template @@ -0,0 +1,33 @@ +# Change all vars before going to production and remove all comments (!) +# Below all environment variables and default values + +DJANGO_SECRET_KEY=very_insecure_key +DJANGO_DEBUG=False +DJANGO_ALLOWED_HOSTS=localhost,127.0.0.1 +DJANGO_CSRF_TRUSTED_ORIGINS=http://localhost,http://127.0.0.1 +DJANGO_CORS_ALLOWED_ORIGINS=* +DJANGO_INTERNAL_IPS=127.0.0.1 +DJANGO_LANGUAGE_CODE=en-us +DJANGO_STATIC_URL=static/ +REDIS_URI=redis://localhost:6379 +DJANGO_DB_URI=sqlite:///db.sqlite3 +YANDEX_CLOUD_FOLDER_ID= +YANDEX_CLOUD_API_KEY= + + +# Storages + +MINIO_ENDPOINT= +MINIO_CUSTOM_ENDPOINT_URL= +MINIO_ACCESS_KEY= +MINIO_SECRET_KEY= +MINIO_USE_HTTPS=False +MINIO_MEDIA_BUCKET_NAME=adnova-media + + +# Applyable if you installing using docker compose + +DJANGO_CREATE_SUPERUSER=False +DJANGO_SUPERUSER_USERNAME= +DJANGO_SUPERUSER_EMAIL= +DJANGO_SUPERUSER_PASSWORD= diff --git a/solution/services/backend/.gitignore b/solution/services/backend/.gitignore new file mode 100644 index 0000000..657dc4c --- /dev/null +++ b/solution/services/backend/.gitignore @@ -0,0 +1,173 @@ +# 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 + +# 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 + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +uv.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 + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__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 +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# 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/ + +# PyPI configuration file +.pypirc + +# Ruff files +.ruff_cache + +# Collected static files +static diff --git a/solution/services/backend/manage.py b/solution/services/backend/manage.py new file mode 100755 index 0000000..f821d3a --- /dev/null +++ b/solution/services/backend/manage.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +"""Django's command-line utility for administrative tasks.""" + +import os +import sys + + +def main() -> None: + """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: + e = """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?""" + raise ImportError(e) from exc + execute_from_command_line(sys.argv) + + +if __name__ == "__main__": + main() diff --git a/solution/services/backend/pyproject.toml b/solution/services/backend/pyproject.toml new file mode 100644 index 0000000..9aa2df6 --- /dev/null +++ b/solution/services/backend/pyproject.toml @@ -0,0 +1,144 @@ +[project] +name = "adnova-backend" +version = "0.1.0" +readme = "README.md" +requires-python = ">=3.10,<3.12" +dependencies = [ + "celery>=5.4.0", + "colorlog>=6.9.0", + "django-cors-headers>=4.6.0", + "django-environ>=0.11.2", + "django-extensions>=3.2.3", + "django-guid>=3.5.0", + "django-health-check>=3.18.3", + "django-minio-storage>=0.5.7", + "django-ninja>=1.3.0", + "django-stubs-ext>=5.1.3", + "gunicorn>=23.0.0", + "httpx>=0.28.1", + "openai>=1.63.0", + "pillow>=11.1.0", + "psycopg2-binary>=2.9.10", + "pydantic>=2.10.5", + "pyjwt>=2.10.1", + "python-json-logger>=3.2.1", + "pytz>=2024.2", + "redis>=5.2.1", + "yandex-cloud-ml-sdk>=0.3.1", +] + +[dependency-groups] +dev = [ + "coverage>=7.6.12", + "django-debug-toolbar>=4.4.6", + "django-stubs[compatible-mypy]>=5.1.3", + "mypy>=1.15.0", + "ruff>=0.9.3", +] + +[tool.ruff] +builtins = [] +cache-dir = ".ruff_cache" +exclude = [ + ".bzr", + ".direnv", + ".eggs", + ".git", + ".git-rewrite", + ".hg", + ".mypy_cache", + ".nox", + ".pants.d", + ".pytype", + ".ruff_cache", + ".svn", + ".tox", + ".venv", + "__pypackages__", + "_build", + "buck-out", + "dist", + "migrations", + "node_modules", + "venv", +] +extend-exclude = [] +extend-include = [] +fix = false +fix-only = false +force-exclude = true +include = ["*.py", "*.pyi", "*.ipynb", "**/pyproject.toml"] +indent-width = 4 +line-length = 79 +namespace-packages = [] +output-format = "full" +preview = false +required-version = ">=0.8.4" +respect-gitignore = true +show-fixes = true +src = [".", "src"] +target-version = "py310" +unsafe-fixes = false + +[tool.ruff.analyze] +detect-string-imports = true +direction = "Dependencies" +exclude = [] +include-dependencies = {} +preview = false + +[tool.ruff.format] +docstring-code-format = true +docstring-code-line-length = 79 +exclude = [] +indent-style = "space" +line-ending = "lf" +preview = false +quote-style = "double" +skip-magic-trailing-comma = false + +[tool.ruff.lint] +allowed-confusables = ["ℹ"] +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" +exclude = ["tests.py"] +explicit-preview-rules = false +extend-fixable = [] +extend-per-file-ignores = {} +extend-safe-fixes = [] +extend-select = [] +extend-unsafe-fixes = [] +external = [] +fixable = ["ALL"] +ignore = [ + "ARG", + "D", + "ANN401", + "COM812", + "DJ001", + "DJ007", + "FBT001", + "FBT002", + "N813", + "RUF001", +] +logger-objects = [] +per-file-ignores = {} +preview = false +select = ["ALL"] +task-tags = ["TODO", "FIXME", "HACK", "WORKOUT"] +typing-modules = [] +unfixable = [] + +[tool.ruff.lint.pylint] +max-args = 6 + +[tool.mypy] +plugins = ["mypy_django_plugin.main"] +ignore_missing_imports = true +strict = false +show_error_context = false +no_implicit_optional = false + +[tool.django-stubs] +django_settings_module = "config.settings" +strict_settings = false