Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions app/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
from app.utils.state import LifespanState

if TYPE_CHECKING:
from redis import Redis
from redis.asyncio import Redis

from app.types.factory import Factory

Expand Down Expand Up @@ -400,21 +400,21 @@ async def initialize_notification_topics(
)


def use_route_path_as_operation_ids(app: FastAPI) -> None:
def use_route_path_as_operation_id(route: APIRoute) -> str:
"""
Simplify operation IDs so that generated API clients have simpler function names.
Simplify operation ID so that generated API clients have simpler function names.

Theses names may be used by API clients to generate function names.
The operation_id will have the format "method_path", like "get_users_me".

See https://fastapi.tiangolo.com/advanced/path-operation-advanced-configuration/
"""
for route in app.routes:
if isinstance(route, APIRoute):
# The operation_id should be unique.
# It is possible to set multiple methods for the same endpoint method but it's not considered a good practice.
method = "_".join(route.methods)
route.operation_id = method.lower() + route.path.replace("/", "_")
if route.methods:
# The operation_id should be unique.
# It is possible to set multiple methods for the same endpoint method but it's not considered a good practice.
method = "_".join(route.methods)
return method.lower() + route.path.replace("/", "_")
return route.name


def init_db(
Expand Down Expand Up @@ -645,9 +645,9 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[LifespanState]:
title="Hyperion",
version=settings.HYPERION_VERSION,
lifespan=lifespan,
custom_generate_unique_id=use_route_path_as_operation_id,
)
app.include_router(api.api_router)
use_route_path_as_operation_ids(app)

app.add_middleware(
CORSMiddleware,
Expand Down Expand Up @@ -702,7 +702,7 @@ async def logging_middleware(
# We test the ip address with the redis limiter
process = True
if redis_client and settings.ENABLE_RATE_LIMITER: # If redis is configured
process, log = limiter(
process, log = await limiter(
redis_client,
ip_address,
settings.REDIS_LIMIT,
Expand Down
22 changes: 11 additions & 11 deletions app/core/checkout/payment_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,10 +166,10 @@ async def init_checkout(
payer: HelloAssoApiV5ModelsCartsCheckoutPayer | None = None
if payer_user is not None:
payer = HelloAssoApiV5ModelsCartsCheckoutPayer(
first_name=payer_user.firstname, # ty:ignore[unknown-argument]
last_name=payer_user.name, # ty:ignore[unknown-argument]
first_name=payer_user.firstname,
last_name=payer_user.name,
email=payer_user.email,
date_of_birth=datetime.combine( # ty:ignore[unknown-argument]
date_of_birth=datetime.combine(
payer_user.birthday,
datetime.min.time(),
tzinfo=UTC,
Expand All @@ -182,19 +182,19 @@ async def init_checkout(
secret = security.generate_token(nbytes=12)

init_checkout_body = HelloAssoApiV5ModelsCartsInitCheckoutBody(
total_amount=checkout_amount, # ty:ignore[unknown-argument]
initial_amount=checkout_amount, # ty:ignore[unknown-argument]
item_name=checkout_name, # ty:ignore[unknown-argument]
back_url=redirection_uri, # ty:ignore[unknown-argument]
error_url=redirection_uri, # ty:ignore[unknown-argument]
return_url=redirection_uri, # ty:ignore[unknown-argument]
contains_donation=False, # ty:ignore[unknown-argument]
total_amount=checkout_amount,
initial_amount=checkout_amount,
item_name=checkout_name,
back_url=redirection_uri,
error_url=redirection_uri,
return_url=redirection_uri,
contains_donation=False,
payer=payer,
metadata=schemas_checkout.HelloAssoCheckoutMetadata(
secret=secret,
hyperion_checkout_id=str(checkout_model_id),
).model_dump(),
) # ty:ignore[missing-argument] # See https://github.com/astral-sh/ty/issues/1438
)

response: HelloAssoApiV5ModelsCartsInitCheckoutResponse
with ApiClient(configuration) as api_client:
Expand Down
3 changes: 2 additions & 1 deletion app/core/permissions/endpoints_permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.permissions import cruds_permissions, schemas_permissions
from app.core.permissions.factory_permissions import CorePermissionsFactory
from app.dependencies import (
get_db,
is_user,
Expand All @@ -29,7 +30,7 @@
root="permissions",
tag="Permissions",
router=router,
factory=None,
factory=CorePermissionsFactory(),
)

hyperion_security_logger = logging.getLogger("hyperion.security")
Expand Down
31 changes: 31 additions & 0 deletions app/core/permissions/factory_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.groups.groups_type import GroupType
from app.core.permissions import cruds_permissions, schemas_permissions
from app.core.utils.config import Settings
from app.module import permissions_list
from app.types.factory import Factory


class CorePermissionsFactory(Factory):
depends_on = []

@classmethod
async def run(cls, db: AsyncSession, settings: Settings) -> None:
for permission in permissions_list:
await cruds_permissions.create_group_permission(
permission=schemas_permissions.CoreGroupPermission(
permission_name=permission,
group_id=GroupType.admin.value,
),
db=db,
)
await db.commit()

@classmethod
async def should_run(cls, db: AsyncSession):
permissions = await cruds_permissions.get_permissions(
permissions_list,
db,
)
return len(permissions) == 0
6 changes: 3 additions & 3 deletions app/core/utils/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ class School(BaseModel):
# On registration, user whose email match these regex will be automatically assigned to the corresponding account type
# Use simple quotes to avoid escaping the regex
# Ex: `student_email_regex: '^[\w\-.]*@domain.fr$'`
student_email_regex: Pattern
staff_email_regex: Pattern | None = None
former_student_email_regex: Pattern | None = None
student_email_regex: Pattern[str]
staff_email_regex: Pattern[str] | None = None
former_student_email_regex: Pattern[str] | None = None

# If event should be confirmed by a moderator before being added to the calendar
require_event_confirmation: bool = True
Expand Down
6 changes: 3 additions & 3 deletions app/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ async def get_users(db: AsyncSession = Depends(get_db)):
from uuid import UUID

import calypsso
import redis
import redis.asyncio as redis
import starlette
import starlette.datastructures
from fastapi import BackgroundTasks, Depends, FastAPI, HTTPException, Request
Expand Down Expand Up @@ -101,7 +101,7 @@ async def init_state(

SessionLocal = init_SessionLocal(engine)

redis_client = init_redis_client(
redis_client = await init_redis_client(
settings=settings,
hyperion_error_logger=hyperion_error_logger,
)
Expand Down Expand Up @@ -145,7 +145,7 @@ async def disconnect_state(
This methode should be called as a dependency as tests may need to run additional steps
"""

disconnect_redis_client(GLOBAL_STATE["redis_client"])
await disconnect_redis_client(GLOBAL_STATE["redis_client"])
await disconnect_scheduler(GLOBAL_STATE["scheduler"])
await disconnect_websocket_connection_manager(GLOBAL_STATE["ws_manager"])

Expand Down
20 changes: 10 additions & 10 deletions app/modules/amap/endpoints_amap.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from datetime import UTC, datetime

from fastapi import Depends, HTTPException, Response
from redis import Redis
from redis.asyncio import Redis
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.groups.groups_type import AccountType
Expand Down Expand Up @@ -532,12 +532,12 @@ async def add_order_to_delievery(
raise HTTPException(status_code=400, detail="You can't order nothing")

redis_key = "amap_" + order.user_id
if not isinstance(redis_client, Redis) or locker_get(
if not isinstance(redis_client, Redis) or await locker_get(
redis_client=redis_client,
key=redis_key,
):
raise HTTPException(status_code=429, detail="Too fast !")
locker_set(redis_client=redis_client, key=redis_key, lock=True)
await locker_set(redis_client=redis_client, key=redis_key, lock=True)

try:
await cruds_amap.add_order_to_delivery(
Expand Down Expand Up @@ -600,7 +600,7 @@ async def add_order_to_delievery(
delivery_name=orderret.delivery.name,
)
finally:
locker_set(redis_client=redis_client, key=redis_key, lock=False)
await locker_set(redis_client=redis_client, key=redis_key, lock=False)


@module.router.patch(
Expand Down Expand Up @@ -694,12 +694,12 @@ async def edit_order_from_delivery(
raise HTTPException(status_code=404, detail="No cash found")

redis_key = "amap_" + previous_order.user_id
if not isinstance(redis_client, Redis) or locker_get(
if not isinstance(redis_client, Redis) or await locker_get(
redis_client=redis_client,
key=redis_key,
):
raise HTTPException(status_code=429, detail="Too fast !")
locker_set(redis_client=redis_client, key=redis_key, lock=True)
await locker_set(redis_client=redis_client, key=redis_key, lock=True)

try:
await cruds_amap.edit_order_with_products(
Expand Down Expand Up @@ -727,7 +727,7 @@ async def edit_order_from_delivery(
)

finally:
locker_set(redis_client=redis_client, key=redis_key, lock=False)
await locker_set(redis_client=redis_client, key=redis_key, lock=False)


@module.router.delete(
Expand Down Expand Up @@ -778,12 +778,12 @@ async def remove_order(

redis_key = "amap_" + order.user_id

if not isinstance(redis_client, Redis) or locker_get(
if not isinstance(redis_client, Redis) or await locker_get(
redis_client=redis_client,
key=redis_key,
):
raise HTTPException(status_code=429, detail="Too fast !")
locker_set(redis_client=redis_client, key=redis_key, lock=True)
await locker_set(redis_client=redis_client, key=redis_key, lock=True)

try:
await cruds_amap.remove_order(
Expand All @@ -801,7 +801,7 @@ async def remove_order(
return Response(status_code=204)

finally:
locker_set(redis_client=redis_client, key=redis_key, lock=False)
await locker_set(redis_client=redis_client, key=redis_key, lock=False)


@module.router.post(
Expand Down
16 changes: 8 additions & 8 deletions app/modules/cdr/utils_cdr.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ def build_data_rows(
users: list[models_users.CoreUser],
users_purchases: dict[str, list[models_cdr.Purchase]],
users_answers: dict[str, list[models_cdr.CustomData]],
product_structure: dict,
product_structure: dict, # ty:ignore[missing-type-argument]
col_idx: int,
):
data_rows = []
Expand Down Expand Up @@ -413,17 +413,17 @@ def build_data_rows(
def write_fixed_headers(
worksheet: xlsxwriter.Workbook.worksheet_class,
fixed_columns: list[str],
formats: dict,
formats: dict, # ty:ignore[missing-type-argument]
):
for col, title in enumerate(fixed_columns):
worksheet.merge_range(0, col, 2, col, title, formats["header"]["base"])


def write_product_headers(
worksheet: xlsxwriter.Workbook.worksheet_class,
product_structure: dict,
product_structure: dict, # ty:ignore[missing-type-argument]
fixed_columns: list[str],
formats: dict,
formats: dict, # ty:ignore[missing-type-argument]
max_lens: list[int],
):
product_end_cols = [
Expand Down Expand Up @@ -542,10 +542,10 @@ def write_product_headers(

def write_data_rows(
worksheet: xlsxwriter.Workbook.worksheet_class,
data_rows: list,
data_rows: list, # ty:ignore[missing-type-argument]
product_end_cols: list[int],
variant_end_cols: list[int],
formats: dict,
formats: dict, # ty:ignore[missing-type-argument]
max_lens: list[int],
start_row: int = 3,
):
Expand Down Expand Up @@ -600,9 +600,9 @@ def write_to_excel(
worksheet_name: str,
fixed_columns: list[str],
product_structure,
data_rows: list,
data_rows: list, # ty:ignore[missing-type-argument]
col_idx: int,
formats: dict,
formats: dict, # ty:ignore[missing-type-argument]
):
worksheet = workbook.add_worksheet(worksheet_name)
max_lens = [len(c) for c in fixed_columns] + [0] * (col_idx - len(fixed_columns))
Expand Down
14 changes: 7 additions & 7 deletions app/modules/raffle/endpoints_raffle.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from fastapi import Depends, HTTPException
from fastapi.responses import FileResponse
from redis import Redis
from redis.asyncio import Redis
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.groups import cruds_groups
Expand Down Expand Up @@ -522,13 +522,13 @@ async def buy_ticket(

redis_key = "raffle_" + user.id

if not isinstance(redis_client, Redis) or locker_get(
if not isinstance(redis_client, Redis) or await locker_get(
redis_client=redis_client,
key=redis_key,
):
raise HTTPException(status_code=429, detail="Too fast !")

locker_set(redis_client=redis_client, key=redis_key, lock=True)
await locker_set(redis_client=redis_client, key=redis_key, lock=True)

try:
new_amount = balance.balance - pack_ticket.price
Expand All @@ -550,7 +550,7 @@ async def buy_ticket(
return tickets

finally:
locker_set(redis_client=redis_client, key=redis_key, lock=False)
await locker_set(redis_client=redis_client, key=redis_key, lock=False)


@module.router.get(
Expand Down Expand Up @@ -1002,12 +1002,12 @@ async def edit_cash_by_id(

redis_key = "raffle_" + user_id

if not isinstance(redis_client, Redis) or locker_get(
if not isinstance(redis_client, Redis) or await locker_get(
redis_client=redis_client,
key=redis_key,
):
raise HTTPException(status_code=403, detail="Too fast !")
locker_set(redis_client=redis_client, key=redis_key, lock=True)
await locker_set(redis_client=redis_client, key=redis_key, lock=True)

try:
await cruds_raffle.edit_cash(
Expand All @@ -1016,7 +1016,7 @@ async def edit_cash_by_id(
db=db,
)
finally:
locker_set(redis_client=redis_client, key=redis_key, lock=False)
await locker_set(redis_client=redis_client, key=redis_key, lock=False)


@module.router.post(
Expand Down
Loading
Loading