File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 11APP_NAME = Todo Modulith API
22APP_ENV = production
33
4- DATABASE_URL = postgresql+asyncpg://postgres:postgres@127.0.0.1:5432/todo_db
4+ POSTGRES_USER = postgres
5+ POSTGRES_PASSWORD =
6+ POSTGRES_DB = todo_db
7+ REDIS_PASSWORD =
8+
9+ DATABASE_URL =
510DATABASE_POOL_SIZE = 20
611DATABASE_MAX_OVERFLOW = 10
712DATABASE_POOL_TIMEOUT = 30
813DATABASE_POOL_RECYCLE = 3600
914
10- REDIS_URL = redis://:password@127.0.0.1:6379/0
15+ REDIS_URL =
1116
12- SECRET_KEY = your-super-secret-production-key-here
17+ SECRET_KEY =
1318
1419MAX_REQUEST_SIZE_MB = 5242880 # 5mb
1520
Original file line number Diff line number Diff line change @@ -230,8 +230,13 @@ Expected values:
230230
231231``` env
232232APP_NAME=Todo Modulith API
233- DATABASE_URL=postgresql+asyncpg://postgres:postgres@db:5432/todo_db
234- SECRET_KEY=your-super-secret-production-key-here
233+ POSTGRES_USER=postgres
234+ POSTGRES_PASSWORD=
235+ POSTGRES_DB=todo_db
236+ REDIS_PASSWORD=
237+ DATABASE_URL=
238+ REDIS_URL=
239+ SECRET_KEY=
235240ALGORITHM=HS256
236241JWT_ISSUER=todo-modulith-api
237242JWT_AUDIENCE=todo-modulith-client
@@ -242,7 +247,7 @@ REFRESH_TOKEN_EXPIRE_MINUTES=10080
242247For local development without Docker, point ` DATABASE_URL ` at your local PostgreSQL host, for example:
243248
244249``` env
245- DATABASE_URL=postgresql+asyncpg://postgres:postgres @localhost:5432/todo_db
250+ DATABASE_URL=postgresql+asyncpg://postgres@localhost:5432/todo_db
246251```
247252
248253## Local Setup
Original file line number Diff line number Diff line change @@ -11,8 +11,8 @@ services:
1111 - .env
1212 environment :
1313 APP_ENV : production
14- DATABASE_URL : postgresql+asyncpg://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgres }@db:5432/${POSTGRES_DB:-todo_db}
15- REDIS_URL : redis://:${REDIS_PASSWORD:-redis-password }@redis:6379/0
14+ DATABASE_URL : postgresql+asyncpg://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env }@db:5432/${POSTGRES_DB:-todo_db}
15+ REDIS_URL : redis://:${REDIS_PASSWORD:?Set REDIS_PASSWORD in .env }@redis:6379/0
1616 depends_on :
1717 db :
1818 condition : service_healthy
@@ -36,7 +36,7 @@ services:
3636 restart : unless-stopped
3737 environment :
3838 POSTGRES_USER : ${POSTGRES_USER:-postgres}
39- POSTGRES_PASSWORD : ${POSTGRES_PASSWORD:-postgres }
39+ POSTGRES_PASSWORD : ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env }
4040 POSTGRES_DB : ${POSTGRES_DB:-todo_db}
4141 volumes :
4242 - postgres_data:/var/lib/postgresql/data
@@ -55,7 +55,7 @@ services:
5555 " --appendonly" ,
5656 " yes" ,
5757 " --requirepass" ,
58- " ${REDIS_PASSWORD:-redis-password }" ,
58+ " ${REDIS_PASSWORD:?Set REDIS_PASSWORD in .env }" ,
5959 ]
6060 volumes :
6161 - redis_data:/data
@@ -65,7 +65,7 @@ services:
6565 " CMD" ,
6666 " redis-cli" ,
6767 " -a" ,
68- " ${REDIS_PASSWORD:-redis-password }" ,
68+ " ${REDIS_PASSWORD:?Set REDIS_PASSWORD in .env }" ,
6969 " ping" ,
7070 ]
7171 interval : 10s
Original file line number Diff line number Diff line change @@ -12,11 +12,11 @@ class Settings(BaseSettings):
1212 APP_ENV : str = Field (alias = "APP_ENV" , default = "development" )
1313 DATABASE_URL : str = Field (
1414 alias = "DATABASE_URL" ,
15- default = "postgresql+asyncpg://user:password @localhost:5432/todo_db" ,
15+ default = "postgresql+asyncpg://postgres @localhost:5432/todo_db" ,
1616 )
1717 REDIS_URL : str = Field (
1818 alias = "REDIS_URL" ,
19- default = "redis://:eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81@ 127.0.0.1:6379/0" ,
19+ default = "redis://127.0.0.1:6379/0" ,
2020 )
2121 SECRET_KEY : str = Field (alias = "SECRET_KEY" , default = DEFAULT_SECRET_KEY )
2222 ALGORITHM : str = Field (alias = "ALGORITHM" , default = "HS256" )
Original file line number Diff line number Diff line change 11from uuid import UUID
22
33from fastapi import Depends , HTTPException , Request , status
4- from fastapi .security import HTTPBearer
4+ from fastapi .security import OAuth2PasswordBearer
55from sqlalchemy .ext .asyncio import AsyncSession
66
77from src .core .database .postgres .session import get_db
88from src .modules .user .infrastructure .repositories .user_repository import (
99 SQLAlchemyUserRepository ,
1010)
1111
12- # oauth2_scheme = OAuth2PasswordBearer(
13- # tokenUrl="/api/v1/auth/login",
14- # refreshUrl="/api/v1/auth/refresh",
15- # )
16-
17- oauth2_scheme = HTTPBearer (scheme_name = "Authorization" , auto_error = False )
12+ oauth2_scheme = OAuth2PasswordBearer (
13+ tokenUrl = "/api/v1/auth/login" ,
14+ refreshUrl = "/api/v1/auth/refresh" ,
15+ auto_error = False ,
16+ )
1817
1918
2019async def get_current_user (
Original file line number Diff line number Diff line change 1- from fastapi import HTTPException , Request
1+ from fastapi import Request
22from fastapi_limiter import FastAPILimiter
3+ from fastapi_limiter .depends import RateLimiter
34
45from src .core .config .setting import get_settings
56from src .core .database .redis .client import get_redis_client
@@ -54,20 +55,5 @@ async def apply_global_rate_limit(request: Request):
5455 times = int (times_str )
5556 seconds = 60 if "minute" in period else 1
5657
57- # Get identifier for this request
58- identifier = await custom_identifier (request )
59-
60- # Check rate limit
61- is_rate_limited = await FastAPILimiter .redis .incr (
62- f"fastapi-limiter:{ identifier } :{ request .scope .get ('path' )} "
63- )
64-
65- # Set expiry on first request
66- if is_rate_limited == 1 :
67- await FastAPILimiter .redis .expire (
68- f"fastapi-limiter:{ identifier } :{ request .scope .get ('path' )} " , seconds
69- )
70-
71- # Check if rate limit exceeded
72- if is_rate_limited > times :
73- raise HTTPException (status_code = 429 , detail = "Rate limit exceeded" )
58+ limiter = RateLimiter (times = times , seconds = seconds )
59+ await limiter (request )
You can’t perform that action at this time.
0 commit comments