Skip to content

Commit

Permalink
Mypy type errors fix (#324)
Browse files Browse the repository at this point in the history
* Mypy type errors fix

* Moved event_bridhe_scheduler inside fuction

* Updated imports

* Auth User moved to HtmxHttpRequest

* HttpRequest replaced with authorized HtmxHttpRequest
  • Loading branch information
Domejko authored Apr 20, 2024
1 parent 6664749 commit 746c032
Show file tree
Hide file tree
Showing 44 changed files with 184 additions and 169 deletions.
4 changes: 3 additions & 1 deletion backend/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from typing import Iterable, Any

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin

Expand Down Expand Up @@ -90,7 +92,7 @@ class EmailSendStatusAdmin(admin.ModelAdmin):
admin.site.register(EmailSendStatus, EmailSendStatusAdmin)

# admin.site.unregister(User)
fields = list(UserAdmin.fieldsets)
fields = list(UserAdmin.fieldsets) # type: ignore[arg-type]
fields[0] = (None, {"fields": ("username", "password", "logged_in_as_team", "awaiting_email_verification")})
UserAdmin.fieldsets = tuple(fields)
admin.site.register(User, UserAdmin)
Expand Down
2 changes: 1 addition & 1 deletion backend/api/base/modal.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from backend.models import QuotaLimit
from backend.models import Team
from backend.models import UserSettings
from backend.utils import quota_usage_check_under
from backend.utils.quota_limit_ops import quota_usage_check_under


# Still working on
Expand Down
3 changes: 1 addition & 2 deletions backend/api/emails/send.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import re
from dataclasses import dataclass
from typing import List, Tuple

from collections.abc import Iterator

Expand All @@ -29,7 +28,7 @@
BulkEmailErrorResponse,
BulkTemplatedEmailInput,
)
from backend.utils import quota_usage_check_under
from backend.utils.quota_limit_ops import quota_usage_check_under
from settings.helpers import send_email, send_templated_bulk_email


Expand Down
9 changes: 3 additions & 6 deletions backend/api/healthcheck/healthcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@ def ping(request: HttpRequest) -> HttpResponse:
@login_not_required
def healthcheck(request: HttpRequest) -> HttpResponse:
try:
status = connection.ensure_connection()
except OperationalError:
status = "error"

if not status: # good
connection.ensure_connection()
return HttpResponse(status=200, content="All operations are up and running!")
return HttpResponse(status=503, content="Service Unavailable")
except OperationalError:
return HttpResponse(status=503, content="Service Unavailable")
2 changes: 1 addition & 1 deletion backend/api/invoices/reminders/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from django.utils import timezone

from backend.models import Invoice, InvoiceReminder, QuotaUsage
from backend.utils import quota_usage_check_under
from backend.utils.quota_limit_ops import quota_usage_check_under
from infrastructure.aws.schedules.create_reminder import CreateReminderInputData, create_reminder_schedule

from backend.types.htmx import HtmxHttpRequest
Expand Down
6 changes: 2 additions & 4 deletions backend/api/invoices/schedule.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import json

from django.contrib import messages
from django.db.models import Q
from django.http import HttpResponse, HttpResponseForbidden, JsonResponse
Expand All @@ -11,11 +9,11 @@
from django_ratelimit.core import is_ratelimited
from mypy_boto3_iam.type_defs import GetRoleResponseTypeDef

from backend.decorators import feature_flag_check, quota_usage_check
from backend.decorators import feature_flag_check
from backend.models import Invoice, AuditLog, APIKey, InvoiceOnetimeSchedule, InvoiceURL, QuotaUsage
from backend.types.emails import SingleEmailInput
from backend.types.htmx import HtmxHttpRequest
from backend.utils import quota_usage_check_under
from backend.utils.quota_limit_ops import quota_usage_check_under
from infrastructure.aws.handler import get_iam_client
from infrastructure.aws.schedules.create_schedule import (
create_onetime_schedule,
Expand Down
2 changes: 1 addition & 1 deletion backend/api/quotas/requests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from backend.decorators import superuser_only
from backend.models import QuotaIncreaseRequest, QuotaLimit, QuotaUsage, QuotaOverrides
from backend.utils import quota_usage_check_under
from backend.utils.quota_limit_ops import quota_usage_check_under


def submit_request(request: HttpRequest, slug) -> HttpResponse:
Expand Down
4 changes: 3 additions & 1 deletion backend/api/receipts/delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
from django.shortcuts import render, redirect
from django.urls import resolve, Resolver404, reverse
from django.views.decorators.http import require_http_methods

from backend.models import Receipt
from backend.types.htmx import HtmxHttpRequest


@require_http_methods(["DELETE"])
@login_required
def receipt_delete(request: HttpRequest, id: int):
def receipt_delete(request: HtmxHttpRequest, id: int):
try:
receipt = Receipt.objects.get(id=id)
except Receipt.DoesNotExist:
Expand Down
6 changes: 3 additions & 3 deletions backend/api/receipts/fetch.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from django.db.models import Q
from django.http import HttpRequest
from django.shortcuts import render, redirect

from backend.models import Receipt
from backend.models import Receipt, User
from backend.types.htmx import HtmxHttpRequest


def fetch_all_receipts(request: HttpRequest):
def fetch_all_receipts(request: HtmxHttpRequest):
context = {}
if not request.htmx:
return redirect("receipts dashboard")
Expand Down
7 changes: 5 additions & 2 deletions backend/api/settings/change_name.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from django.contrib import messages
from django.http import HttpRequest, HttpResponse
from django.contrib.auth.models import AnonymousUser
from django.http import HttpResponse
from django.shortcuts import render
from django.views.decorators.http import require_http_methods

from backend.types.htmx import HtmxHttpRequest


@require_http_methods(["POST"])
def change_account_name(request: HttpRequest):
def change_account_name(request: HtmxHttpRequest):
if not request.htmx:
return HttpResponse("Invalid Request", status=405)

Expand Down
4 changes: 2 additions & 2 deletions backend/api/teams/kick.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@


def kick_user(request: HttpRequest, user_id):
user: User = User.objects.filter(id=user_id).first()
user: User | None = User.objects.filter(id=user_id).first()
confirmation_text = request.POST.get("confirmation_text")
if not user:
messages.error(request, "User not found")
Expand All @@ -16,7 +16,7 @@ def kick_user(request: HttpRequest, user_id):
messages.error(request, "Invalid confirmation")
return redirect("user settings teams")

team: Team = user.teams_joined.first()
team: Team | None = user.teams_joined.first()
if not team:
messages.error(request, "User is not apart of your team")
return redirect("user settings teams")
Expand Down
23 changes: 12 additions & 11 deletions backend/api/teams/leave.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
from django.contrib import messages
from django.http import HttpRequest, HttpResponse
from django.http import HttpResponse
from django.shortcuts import render

from backend.models import *
from backend.types.htmx import HtmxHttpRequest


def return_error_notif(request: HttpRequest, message: str):
def return_error_notif(request: HtmxHttpRequest, message: str):
messages.error(request, message)
resp = render(request, "partials/messages_list.html", status=200)
resp["HX-Trigger-After-Swap"] = "leave_team_error"
return resp


def leave_team_confirmed(request: HttpRequest, team_id):
team: Team = Team.objects.filter(id=team_id).first()
def leave_team_confirmed(request: HtmxHttpRequest, team_id):
team: Team | None = Team.objects.filter(id=team_id).first()

if not team:
return return_error_notif(request, "Team not found")

if team.leader == request.user: # may be changed in the future. If no members allow delete
return return_error_notif(request, "You cannot leave your own team")

if not request.user.teams_joined.filter(id=team_id).exists():
if request.user.teams_joined.filter(id=team_id).exists():
team.members.remove(request.user)
messages.success(request, f"You have successfully left the team {team.name}")
response = HttpResponse(status=200)
response["HX-Refresh"] = "true"
return response
else:
return return_error_notif(request, "You are not a member of this team")

team.members.remove(request.user)
messages.success(request, f"You have successfully left the team {team.name}")
response = HttpResponse(status=200)
response["HX-Refresh"] = "true"
return response
12 changes: 8 additions & 4 deletions backend/api/teams/switch_team.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
from django.contrib import messages
from django.http import HttpRequest, HttpResponse
from django.contrib.auth.models import AnonymousUser
from django.http import HttpResponse
from django.shortcuts import render

from backend.models import Team
from backend.types.htmx import HtmxHttpRequest


def switch_team(request: HttpRequest, team_id):
def switch_team(request: HtmxHttpRequest, team_id):
if not team_id:
if not request.user.logged_in_as_team:
messages.error(request, "You are not logged into an organization")

request.user.logged_in_as_team = None
request.user.save()
messages.success(request, "You are now logged into your personal account")
response = HttpResponse(status=200)
response["HX-Refresh"] = "true"
return response

team: Team = Team.objects.filter(id=team_id).first()
team: Team | None = Team.objects.filter(id=team_id).first()

if not team:
messages.error(request, "Team not found")
Expand All @@ -33,13 +36,14 @@ def switch_team(request: HttpRequest, team_id):
messages.success(request, f"Now signing in for {team.name}")
request.user.logged_in_as_team = team
request.user.save()

response = HttpResponse(status=200)
response["HX-Refresh"] = "true"
return response
# return render(request, "components/+logged_in_for.html")


def get_dropdown(request: HttpRequest):
def get_dropdown(request: HtmxHttpRequest):
if not request.htmx:
return HttpResponse("Invalid Request", status=405)

Expand Down
6 changes: 3 additions & 3 deletions backend/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def get_item(name: str, url_name: Optional[str] = None, icon: Optional[str] = No
"icon": icon,
}

def generate_breadcrumbs(*breadcrumb_list: str) -> List[Dict[str, Any]]:
def generate_breadcrumbs(*breadcrumb_list: str) -> List[dict[Any, Any] | None]:
"""
Generate a list of breadcrumb items based on the provided list of breadcrumb names.
Expand All @@ -64,7 +64,7 @@ def generate_breadcrumbs(*breadcrumb_list: str) -> List[Dict[str, Any]]:
"""
return [all_items.get(breadcrumb) for breadcrumb in breadcrumb_list]

current_url_name: str = request.resolver_match.url_name
current_url_name: str | Any = request.resolver_match.url_name # type: ignore[union-attr]

all_items: Dict[str, dict] = {
"dashboard": get_item("Dashboard", "dashboard", "house"),
Expand All @@ -78,7 +78,7 @@ def generate_breadcrumbs(*breadcrumb_list: str) -> List[Dict[str, Any]]:
"clients create": get_item("Create", "clients create"),
}

all_breadcrumbs: Dict[str, list] = {
all_breadcrumbs: Dict[str | None, list] = {
"dashboard": generate_breadcrumbs("dashboard"),
"user settings teams": generate_breadcrumbs("dashboard", "user settings teams"),
"receipts dashboard": generate_breadcrumbs("dashboard", "receipts dashboard"),
Expand Down
2 changes: 1 addition & 1 deletion backend/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from django.urls import reverse

from backend.models import QuotaLimit
from backend.utils import get_feature_status
from backend.utils.feature_flags import get_feature_status


def not_authenticated(view_func):
Expand Down
2 changes: 1 addition & 1 deletion backend/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def get_queryset(self):


class User(AbstractUser):
objects = CustomUserManager()
objects = CustomUserManager() # type: ignore

logged_in_as_team = models.ForeignKey("Team", on_delete=models.SET_NULL, null=True, blank=True)
awaiting_email_verification = models.BooleanField(default=True)
Expand Down
2 changes: 1 addition & 1 deletion backend/templatetags/feature_enabled.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from django import template

from backend.utils import get_feature_status
from backend.utils.feature_flags import get_feature_status

register = template.Library()

Expand Down
2 changes: 1 addition & 1 deletion backend/types/emails.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from dataclasses import dataclass
from typing import Literal, Optional, List, TypedDict, Dict
from typing import Literal, TypedDict

from mypy_boto3_sesv2.type_defs import SendEmailResponseTypeDef, SendBulkEmailResponseTypeDef, BulkEmailEntryResultTypeDef

Expand Down
8 changes: 8 additions & 0 deletions backend/types/htmx.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
from django.contrib.auth.models import AnonymousUser
from django.http import HttpRequest
from django_htmx.middleware import HtmxDetails

from backend.models import User


class HtmxHttpRequest(HttpRequest):
htmx: HtmxDetails
user: User


class UnauthorizedHttpRequest(HttpRequest):
user: AnonymousUser
Empty file added backend/utils/__init__.py
Empty file.
29 changes: 29 additions & 0 deletions backend/utils/feature_flags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from backend.models import FeatureFlags
from django.core.cache import cache
from django.core.cache.backends.redis import RedisCacheClient

cache: RedisCacheClient = cache


def get_feature_status(feature, should_use_cache=True):
if should_use_cache:
key = f"myfinances:feature_flag:{feature}"
cached_value = cache.get(key)
if cached_value:
return cached_value

value = FeatureFlags.objects.filter(name=feature).first()
if value:
if should_use_cache:
cache.set(key, value.value, timeout=300)
return value.value
else:
return False


def set_cache(key, value, timeout=300):
cache.set(key, value, timeout=timeout)


def get_cache(key):
return cache.get(key)
16 changes: 16 additions & 0 deletions backend/utils/http_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from django.http import HttpResponseRedirect


def redirect_to_last_visited(request, fallback_url="dashboard"):
"""
Redirects user to the last visited URL stored in session.
If no previous URL is found, redirects to the fallback URL.
:param request: HttpRequest object
:param fallback_url: URL to redirect to if no previous URL found
:return: HttpResponseRedirect object
"""
try:
last_visited_url = request.session.get("last_visited", fallback_url)
return HttpResponseRedirect(last_visited_url)
except KeyError:
return HttpResponseRedirect(fallback_url)
Loading

0 comments on commit 746c032

Please sign in to comment.