i'm trying to validate input email from request body and i have build custom field validator at model.
here is code of RegisterModel:
from pydantic import BaseModel, EmailStr, Field, field_validator
from repository.repository_user import UserRepository
from pprint import pprint
class RegisterModel(BaseModel):
name:str
email:EmailStr
password:str = Field(..., min_length=7)
@field_validator('email')
@classmethod
def email_must_unique(cls, v):
repo = UserRepository()
result = repo.find({'email': v})
pprint(result)
return result
the email_must_unique method will create new instace of UserRepository class and it will call the find method from UserRepository to find specific user based on email. actualy the email_must_unique method not finished yet to validate the email, it just get specific users, but i already facing an error.
here is code of UserRepository:
from pymongo.database import Database
from fastapi import Depends
from config.db import db_conn
class UserRepository:
def __init__(self, db: Database = Depends(db_conn)):
self.repository = db.users # users is mongo collection
def find(self, filter: dict):
result = self.repository.find_one(filter)
return result
with this code i'm facing error like this:
self.repository = db.users
^^^^^^^^
AttributeError: 'Depends' object has no attribute 'users'
i have no idea what What caused it. can you give me the solution to solve this error or maybe alternative way to validate email uniqueness ?
As mentioned in the comments by @Chiheb Nexus, Do not call the Depends
function directly. Instead, use the Annotated
dependency which is more graceful.
For example, the config/db.py
file should look like this:
# config/db.py
from typing import Annotated
from fastapi import Depends
from pymongo import MongoClient
from pymongo.database import Database
def get_db() -> Database:
client = MongoClient("mongodb://localhost:27017/")
return client.some_database
DbConn = Annotated[Database, Depends(get_db)] # <-- this is the annotated depend
You can then use it like this:
from config.db import DbConn
class UserRepository:
def __init__(self, db: DbConn): # <- FastAPI will call `DbConn`
self.repository = db.users
def find(self, filter: dict):
result = self.repository.find_one(filter)
return result
In addition, db
in the __init__
parameter is annotated via DbConn
so IDE knows its type.
Validating the uniqueness of data is a task best left to the database rather than Pydantic. In other words, you should insert data and handle unique errors, DuplicateKeyError
in pymongo.