Skip to content

Commit

Permalink
build: introduce uv and reduce project deps
Browse files Browse the repository at this point in the history
  • Loading branch information
Hicham committed Dec 9, 2024
1 parent 6f8dc18 commit b1fde82
Show file tree
Hide file tree
Showing 8 changed files with 1,973 additions and 144 deletions.
23 changes: 13 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
FROM python:3.11.4-slim-buster AS builder
ARG IMAGE_FROM="python:3.11.4-slim-buster"

FROM ${IMAGE_FROM} AS builder
WORKDIR /app

ENV VIRTUAL_ENV=/app/venv
ENV VIRTUAL_ENV=/app/.venv
RUN apt-get update -y && apt-get install -y gcc libkrb5-dev && rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install uv && uv venv $VIRTUAL_ENV && uv pip install --no-cache -r requirements.txt

FROM python:3.11.4-slim-buster AS final
COPY ./pyproject.toml .
RUN pip install uv && uv sync

FROM ${IMAGE_FROM} AS final
WORKDIR /app

ENV VIRTUAL_ENV=/app/venv \
PATH="$VIRTUAL_ENV/bin:$PATH" \
ENV VIRTUAL_ENV=/app/.venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH" \
DEBIAN_FRONTEND=noninteractive \
LC_ALL="fr_FR.utf8" \
LC_CTYPE="fr_FR.utf8"

RUN apt-get update -y \
&& apt-get install -y cron curl gettext krb5-user locales locales-all nano nginx procps xxd \
&& rm -rf /var/lib/apt/lists/*
RUN dpkg-reconfigure locales
&& apt-get install -y cron curl gettext krb5-user locales locales-all nginx procps xxd \
&& rm -rf /var/lib/apt/lists/* \
&& dpkg-reconfigure locales

COPY --from=builder $VIRTUAL_ENV $VIRTUAL_ENV
COPY . .
Expand Down
6 changes: 2 additions & 4 deletions admin_cohort/services/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
from requests import RequestException
from rest_framework import status, HTTP_HEADER_ENCODING
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_simplejwt.authentication import AUTH_HEADER_TYPE_BYTES
from rest_framework_simplejwt.exceptions import InvalidToken

from admin_cohort.models import User
from admin_cohort.types import ServerError, LoginError, OIDCAuthTokens, JWTAuthTokens, AuthTokens
Expand Down Expand Up @@ -52,7 +50,7 @@ def refresh_token(self, **kwargs) -> dict:
if response.status_code == status.HTTP_200_OK:
return self.tokens_class(**response.json()).__dict__
elif response.status_code in (status.HTTP_400_BAD_REQUEST, status.HTTP_401_UNAUTHORIZED):
raise InvalidToken("Token is invalid or has expired")
raise InvalidTokenError("Token is invalid or has expired")
else:
response.raise_for_status()

Expand Down Expand Up @@ -346,7 +344,7 @@ def get_raw_token(header: bytes) -> Union[str, None]:
parts = header.split()
if not parts:
return None
if parts[0] not in AUTH_HEADER_TYPE_BYTES:
if parts[0] != "Bearer".encode(HTTP_HEADER_ENCODING):
return None
if len(parts) != 2:
raise AuthenticationFailed(code='bad_authorization_header',
Expand Down
11 changes: 6 additions & 5 deletions admin_cohort/tests/tests_auth.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from unittest import mock
from unittest.mock import MagicMock

from jwt import InvalidTokenError

from rest_framework import status
from rest_framework.test import APITestCase, APIRequestFactory
from rest_framework_simplejwt.exceptions import InvalidToken
from django.test import Client
from accesses.models import Access, Perimeter, Role
from admin_cohort.models import User
Expand Down Expand Up @@ -119,7 +120,7 @@ def test_authenticate_without_token(self):

@mock.patch("admin_cohort.auth.auth_class.auth_service.authenticate_http_request")
def test_authenticate_error(self, mock_authenticate_http_request: MagicMock):
mock_authenticate_http_request.side_effect = InvalidToken()
mock_authenticate_http_request.return_value = None
request = self.factory.get(path=self.protected_url, **self.headers)
request.user = self.regular_user
response = self.protected_view.as_view({'get': 'list'})(request)
Expand Down Expand Up @@ -155,7 +156,7 @@ def test_refresh_token_with_jwt_auth_mode(self, mock_refresh_token: MagicMock):
mock_refresh_token.return_value = {"access": "aaa", "refresh": "rrr"}
response = self.client.post(path=self.refresh_url,
content_type="application/json",
data={"refresh_token": "any-auth-code-will-do"},
data={"refresh_token": "any-token-will-do"},
headers={"Authorization": "Bearer any-auth",
"AuthorizationMethod": JWT_AUTH_MODE})
self.assertEqual(response.status_code, status.HTTP_200_OK)
Expand All @@ -165,14 +166,14 @@ def test_refresh_token_with_oidc_auth_mode(self, mock_refresh_token: MagicMock):
mock_refresh_token.return_value = {"access_token": "aaa", "refresh_token": "rrr"}
response = self.client.post(path=self.refresh_url,
content_type="application/json",
data={"refresh_token": "any-auth-code-will-do"},
data={"refresh_token": "any-token-will-do"},
headers={"Authorization": "Bearer any-auth",
"AuthorizationMethod": OIDC_AUTH_MODE})
self.assertEqual(response.status_code, status.HTTP_200_OK)

@mock.patch("admin_cohort.views.auth.auth_service.refresh_token")
def test_refresh_token_with_invalid_token(self, mock_refresh_token: MagicMock):
mock_refresh_token.side_effect = InvalidToken()
mock_refresh_token.side_effect = InvalidTokenError("invalid token")
response = self.client.post(path=self.refresh_url,
content_type="application/json",
data={"refresh_token": "any-auth-code-will-do"},
Expand Down
5 changes: 3 additions & 2 deletions admin_cohort/views/auth.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import logging

from jwt import InvalidTokenError

from django.contrib.auth import authenticate, login
from django.contrib.auth import views
from django.http import JsonResponse, HttpResponseRedirect
Expand All @@ -10,7 +12,6 @@
from drf_spectacular.utils import extend_schema
from requests import RequestException
from rest_framework import status, viewsets
from rest_framework_simplejwt.exceptions import InvalidToken

from admin_cohort.auth.auth_form import AuthForm
from admin_cohort.models import User
Expand Down Expand Up @@ -110,7 +111,7 @@ def post(self, request, *args, **kwargs):
try:
auth_tokens = auth_service.refresh_token(request)
return JsonResponse(data=auth_tokens, status=status.HTTP_200_OK)
except (KeyError, InvalidToken, RequestException) as e:
except (KeyError, InvalidTokenError, RequestException) as e:
return JsonResponse(data={"error": f"{e}"}, status=status.HTTP_401_UNAUTHORIZED)


Expand Down
76 changes: 76 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
[project]
name = "Cohort360-Backend"
version = "3.25.0"
authors = ["Assistance Publique - Hopitaux de Paris, Département I&D"]
description = """Supports the official **Cohort360** web app and **Portail**
Built by **Assistance Publique - Hopitaux de Paris**, _Département I&D_
"""
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"channels-redis>=4.2.1",
"channels>=4.2.0",
"daphne>=4.1.2",
"django-celery-beat>=2.7.0",
"django-cors-headers>=4.6.0",
"django-environ>=0.11.2",
"django-extensions>=3.2.3",
"django-filter>=24.3",
"django-redis>=5.4.0",
"django-safedelete>=1.4.0",
"django-websocket-redis>=0.6.0",
"django==5.0.10",
"djangorestframework>=3.15.2",
"drf-api-tracking>=1.8.4",
"drf-extensions>=0.7.1",
"drf-spectacular>=0.28.0",
"fhirpy>=2.0.15",
"gunicorn>=23.0.0",
"hdfs>=2.7.3",
"influxdb-client>=1.48.0",
"kerberos>=1.3.1",
"krb5>=0.7.0",
"psycopg[binary]>=3.2.3",
"pydantic>=2.10.3",
"pyjwt>=2.10.1",
"pytest>=8.3.4",
"python-json-logger>=2.0.7",
"redis>=5.2.1",
"requests-kerberos>=0.15.0",
"requests>=2.32.3",
]

[tool.ruff]
target-version = "py311"
lint.select = ["E", "F"]
lint.dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
lint.ignore = ["E711"]
lint.unfixable = []
lint.fixable = [
"A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ",
"EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET",
"RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"
]
line-length = 150
exclude = [
".bzr",
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".mypy_cache",
".nox",
".pants.d",
".pytype",
".ruff_cache",
".svn",
".tox",
".venv",
"__pypackages__",
"_build",
"buck-out",
"build",
"dist",
"*/migrations"
]
79 changes: 0 additions & 79 deletions requirements.txt

This file was deleted.

44 changes: 0 additions & 44 deletions ruff.toml

This file was deleted.

Loading

0 comments on commit b1fde82

Please sign in to comment.