나는 이렇게 학습한다/Framework

FastAPI _ BaseSettings 을 lru_cache 할 때, unhashable type 에러 해결방법

daco2020 2022. 10. 26. 23:30
반응형

BaseSettings을 사용한 객체를 lru_cache 할 때, TypeError: unhashable type: 에러가 발생할 때가 있다. 정리하면 다음과 같은 상황이다.

 

 

given

FastAPI 에서 lru_cache로 반환하는 BaseSettings 객체를,

 

when

다시 lru_cache를 사용하는 함수가 인수로 받을 때,

 

then

TypeError: unhashable type: 에러가 발생함.

 

 

 

e.g

class Config(BaseSettings):
    URL: str = Field(..., env="URL")

    class Config:
        env_file = "secrets/.env"
        env_file_encoding = "utf-8"

@lru_cache
def get_config() -> Config:
    return Config()

@lru_cache
def get_url(config: Config = get_config()) -> str:
    return config.URL

"""
>>> TypeError: unhashable type: 'Config'
"""

참고 : https://github.com/tiangolo/fastapi/issues/1985#issuecomment-775730974

 

 

에러 원인

lru_cache는 함수 인수를 해시하는데 get_config에서 반환된 Config 객체가 해시 가능하지 않기 때문에 get_url함수에서 오류가 발생하는 것이다.

 

 

 

 

 

해결 방법

Config 객체를 hash 하게 만들어주면 됨. class 안에 __hash__를 오버라이딩 하면 해결할 수 있다.

 

class Config(BaseSettings):
    def __hash__(self) -> int:
        return hash((type(self),) + tuple(self.__dict__.values()))

    URL: str = Field(..., env="URL")

    class Config:
        env_file = "secrets/.env"
        env_file_encoding = "utf-8"

참고 : https://github.com/pydantic/pydantic/issues/1303#issuecomment-599712964

 

 

 

반응형