인프런 커뮤니티 질문&답변

뱅준님의 프로필 이미지
뱅준

작성한 질문수

실전! FastAPI 입문

FastAPI 오류

해결된 질문

작성

·

83

0

안녕하세요. 강의를 듣고 혼자 프로젝트 해보고있는데 왜인지 원인을 모르겠는 오류가 생겨서 여쭤봅니다.

프로젝트를 uvicorn main:app --reload 명령어로 실행하면 무수히많은 에러 스택과 함께 아래와 같은 에러가 발생하는데요.

pydantic.errors.PydanticUndefinedAnnotation: name 'Optional' is not defined

Pydantic에서 에러가 나는 것 같은데, 저는 Optional을 사용하지 않고, None으로 사용하고 있는데 있는데 왜 이러는걸까요?

답변 2

0

신동현님의 프로필 이미지
신동현
지식공유자

안녕하세요. 혹시 에러 화면 캡쳐해서 공유해주실 수 있을까요? 어느 부분에서 발생하는 에러인지 확인해야 할 것 같습니다.

뱅준님의 프로필 이미지
뱅준
질문자

Traceback (most recent call last):
  File "/miniconda3/lib/python3.12/site-packages/pydantic/type_adapter.py", line 270, in _init_core_attrs
    self._core_schema = _getattr_no_parents(self._type, '__pydantic_core_schema__')
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/type_adapter.py", line 112, in _getattr_no_parents
    raise AttributeError(attribute)
AttributeError: __pydantic_core_schema__

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 864, in _resolve_forward_ref
    obj = _typing_extra.eval_type_backport(obj, globalns=self._types_namespace)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_typing_extra.py", line 279, in eval_type_backport
    return _eval_type_backport(value, globalns, localns, type_params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_typing_extra.py", line 303, in _eval_type_backport
    return _eval_type(value, globalns, localns, type_params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_typing_extra.py", line 332, in _eval_type
    return typing._eval_type(  # type: ignore
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/typing.py", line 414, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/typing.py", line 924, in _evaluate
    eval(self.__forward_code__, globalns, localns),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 1, in <module>
NameError: name 'Optional' is not defined

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/miniconda3/lib/python3.12/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/miniconda3/lib/python3.12/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/miniconda3/lib/python3.12/site-packages/uvicorn/_subprocess.py", line 80, in subprocess_started
    target(sockets=sockets)
  File "/miniconda3/lib/python3.12/site-packages/uvicorn/server.py", line 65, in run
    return asyncio.run(self.serve(sockets=sockets))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/asyncio/runners.py", line 194, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "uvloop/loop.pyx", line 1517, in uvloop.loop.Loop.run_until_complete
  File "/miniconda3/lib/python3.12/site-packages/uvicorn/server.py", line 69, in serve
    await self._serve(sockets)
  File "/miniconda3/lib/python3.12/site-packages/uvicorn/server.py", line 76, in _serve
    config.load()
  File "/miniconda3/lib/python3.12/site-packages/uvicorn/config.py", line 434, in load
    self.loaded_app = import_from_string(self.app)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/uvicorn/importer.py", line 19, in import_from_string
    module = importlib.import_module(module_str)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/importlib/__init__.py", line 90, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 995, in exec_module
  File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
  File "/Desktop/dev/labserver/src/main.py", line 10, in <module>
    from api.agent import router as agent_router
  File "/Desktop/dev/labserver/src/api/agent.py", line 226, in <module>
    @router.post("/polling")
     ^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/routing.py", line 994, in decorator
    self.add_api_route(
  File "/miniconda3/lib/python3.12/site-packages/fastapi/routing.py", line 933, in add_api_route
    route = route_class(
            ^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/routing.py", line 554, in __init__
    self.dependant = get_dependant(path=self.path_format, call=self.endpoint)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/dependencies/utils.py", line 284, in get_dependant
    sub_dependant = get_param_sub_dependant(
                    ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/dependencies/utils.py", line 118, in get_param_sub_dependant
    return get_sub_dependant(
           ^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/dependencies/utils.py", line 154, in get_sub_dependant
    sub_dependant = get_dependant(
                    ^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/dependencies/utils.py", line 284, in get_dependant
    sub_dependant = get_param_sub_dependant(
                    ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/dependencies/utils.py", line 118, in get_param_sub_dependant
    return get_sub_dependant(
           ^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/dependencies/utils.py", line 154, in get_sub_dependant
    sub_dependant = get_dependant(
                    ^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/dependencies/utils.py", line 277, in get_dependant
    param_details = analyze_param(
                    ^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/dependencies/utils.py", line 480, in analyze_param
    field = create_model_field(
            ^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/fastapi/utils.py", line 96, in create_model_field
    return ModelField(**kwargs)  # type: ignore[arg-type]
           ^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 6, in __init__
  File "/miniconda3/lib/python3.12/site-packages/fastapi/_compat.py", line 110, in __post_init__
    self._type_adapter: TypeAdapter[Any] = TypeAdapter(
                                           ^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/type_adapter.py", line 257, in __init__
    self._init_core_attrs(rebuild_mocks=False)
  File "/miniconda3/lib/python3.12/site-packages/pydantic/type_adapter.py", line 135, in wrapped
    return func(self, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/type_adapter.py", line 277, in _init_core_attrs
    self._core_schema = _get_schema(self._type, config_wrapper, parent_depth=self._parent_depth)
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/type_adapter.py", line 95, in _get_schema
    schema = gen.generate_schema(type_)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 655, in generate_schema
    schema = self._generate_schema_inner(obj)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 908, in _generate_schema_inner
    return self._annotated_schema(obj)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 2024, in _annotated_schema
    source_type, *annotations = self._get_args_resolving_forward_refs(
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 886, in _get_args_resolving_forward_refs
    args = tuple([self._resolve_forward_ref(a) if isinstance(a, ForwardRef) else a for a in args])
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/miniconda3/lib/python3.12/site-packages/pydantic/_internal/_generate_schema.py", line 866, in _resolve_forward_ref
    raise PydanticUndefinedAnnotation.from_name_error(e) from e
pydantic.errors.PydanticUndefinedAnnotation: name 'Optional' is not defined

For further information visit https://errors.pydantic.dev/2.9/u/undefined-annotation

None 쓰는 부분을 다 Optional로 변경해도 똑같이 오류가 나네요 ㅠ

신동현님의 프로필 이미지
신동현
지식공유자

최신 Pydantic 버전(2.9.x)을 쓰고 계신 것 같은데요. 라이브러리 버전 때문에 발생하는 문제인 것 같습니다. Pydantic 버전을 2.8대로 낮추고 다시 시도해보시겠어요?

뱅준님의 프로필 이미지
뱅준
질문자

get_db를 get_db()로 가져와서 생긴 문제였습니다 ㅠ 겨우 해결했네요 감사합니다.

신동현님의 프로필 이미지
신동현
지식공유자

해결하셨다니 다행입니다!

0

안녕하세요, 인프런 AI 인턴입니다.

뱅준님께서 제공하신 FastAPI 프로젝트 실행 시 발생하는 pydantic.errors.PydanticUndefinedAnnotation: name 'Optional' is not defined 오류에 대해 설명드리겠습니다. 이 오류는 FastAPI와 Pydantic에서 타입 힌팅을 사용할 때 발생할 수 있으며, 일반적으로 Optional 타입 선언 시 from typing import Optional을 제대로 임포트하지 않았을 때 주로 발생합니다.

뱅준님은 Optional을 사용하지 않고 있다고 말씀하셨지만, 프로젝트의 코드 어딘가에 이미 제대로 임포트되지 않았거나 불필요한 부분이 있을 수 있기 때문에 이를 한번 확인해보시는 것이 좋습니다. 또한, None을 기본 값으로 사용하는 변수에 Optional 키워드를 명시하지 않았을 경우, Pydantic이 이를 몰라 발생하는 문제일 수 있습니다.

문제를 해결할 수 있는 몇 가지 방법을 제안드립니다:

  1. 타입 임포트 확인: from typing import Optional이 코드 맨 위에 제대로 임포트 되어있는지 확인합니다. 그럼에도 불구하고 문제가 있다면, 명시적으로 타입을 선언해주는 것이 좋습니다.

  2. 타입 명확화: None을 사용하고 있지만 문제가 발생한다면, 타입 힌팅을 명확하게 Optional로 해보세요. 예를 들어:

   from typing import Optional

   def example_function(param: Optional[int] = None):
       ...
  1. 코드 전체 확인: 프로젝트 내 다른 곳에서 Optional을 사용하고 있음에도 임포트가 누락된 경우가 없는지 전체 코드를 꼼꼼히 살펴보세요.

이와 유사한 문제를 다룬 기존의 질문 중 하나가 있는데, 아래에 링크를 드리니 참고해보시면 좋을 것 같습니다:

다시 한번 코드를 점검하시고, 위의 해결책을 따라해보신 후에도 문제가 지속된다면 구체적인 코드 스니펫이나 기타 오류 메시지를 추가로 공유해주시면 더욱 도움을 드릴 수 있을 것 같습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

뱅준님의 프로필 이미지
뱅준

작성한 질문수

질문하기