简体   繁体   中英

FastAPI application throws ValueError when installing Openpyxl

I wanted to use Openpyxl to manipulate Excel files in my FastAPI Application. I installed Openpyxl then my application just throws ValueError. I didn't import the module or anything, just installing it breaks my application.

The following is the error.

api_1  | INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
api_1  | INFO:     Started reloader process [1] using statreload
api_1  | Process SpawnProcess-1:
api_1  | Traceback (most recent call last):
api_1  |   File "/usr/local/lib/python3.9/multiprocessing/process.py", line 315, in _bootstrap
api_1  |     self.run()
api_1  |   File "/usr/local/lib/python3.9/multiprocessing/process.py", line 108, in run
api_1  |     self._target(*self._args, **self._kwargs)
api_1  |   File "/usr/local/lib/python3.9/site-packages/uvicorn/subprocess.py", line 61, in subprocess_started
api_1  |     target(sockets=sockets)
api_1  |   File "/usr/local/lib/python3.9/site-packages/uvicorn/server.py", line 49, in run
api_1  |     loop.run_until_complete(self.serve(sockets=sockets))
api_1  |   File "/usr/local/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
api_1  |     return future.result()
api_1  |   File "/usr/local/lib/python3.9/site-packages/uvicorn/server.py", line 56, in serve
api_1  |     config.load()
api_1  |   File "/usr/local/lib/python3.9/site-packages/uvicorn/config.py", line 308, in load
api_1  |     self.loaded_app = import_from_string(self.app)
api_1  |   File "/usr/local/lib/python3.9/site-packages/uvicorn/importer.py", line 20, in import_from_string
api_1  |     module = importlib.import_module(module_str)
api_1  |   File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module
api_1  |     return _bootstrap._gcd_import(name[level:], package, level)
api_1  |   File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
api_1  |   File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
api_1  |   File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
api_1  |   File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
api_1  |   File "<frozen importlib._bootstrap_external>", line 790, in exec_module
api_1  |   File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
api_1  |   File "./app/main.py", line 10, in <module>
api_1  |     from .users.main import setup_auth
api_1  |   File "./app/users/main.py", line 3, in <module>
api_1  |     from .routers import setup_auth_routers
api_1  |   File "./app/users/routers.py", line 10, in <module>
api_1  |     from .schemas import User_Pydantic, UserLoginIn, UserRegisterIn
api_1  |   File "./app/users/schemas.py", line 46, in <module>
api_1  |     User_Pydantic = pydantic_model_creator(User, name='User')
api_1  |   File "/usr/local/lib/python3.9/site-packages/tortoise/contrib/pydantic/creator.py", line 353, in pydantic_model_creator
api_1  |     model = get_submodel(fdesc["python_type"])
api_1  |   File "/usr/local/lib/python3.9/site-packages/tortoise/contrib/pydantic/creator.py", line 304, in get_submodel
api_1  |     pmodel = _pydantic_recursion_protector(
api_1  |   File "/usr/local/lib/python3.9/site-packages/tortoise/contrib/pydantic/creator.py", line 105, in _pydantic_recursion_protector
api_1  |     return pydantic_model_creator(
api_1  |   File "/usr/local/lib/python3.9/site-packages/tortoise/contrib/pydantic/creator.py", line 405, in pydantic_model_creator
api_1  |     model = cast(Type[PydanticModel], type(_name, (PydanticModel,), properties))
api_1  |   File "pydantic/main.py", line 287, in pydantic.main.ModelMetaclass.__new__
api_1  |   File "pydantic/fields.py", line 384, in pydantic.fields.ModelField.infer
api_1  |   File "pydantic/fields.py", line 369, in pydantic.fields.ModelField._get_field_info
api_1  |   File "pydantic/fields.py", line 158, in pydantic.fields.FieldInfo._validate
api_1  | ValueError: cannot specify both default and default_factory

From the error it seems like a Pydantic error, but I just can't fix it. Here are the models that it seems to be throwing the error.

app/resources/core_model.py

class CoreModel(Model):
    id = fields.UUIDField(pk=True)
    timestamp = fields.DatetimeField(auto_now_add=True)
    updated = fields.DatetimeField(auto_now=True)
    is_active = fields.BooleanField(default=True)

    class Meta:
        abstract = True

    class PydanticMeta:
        exclude = ('user', 'user_id', 'timestamp', 'updated', 'is_active',)

app/users/models.py

from tortoise import fields
from passlib.hash import bcrypt

from app.resources.core_model import CoreModel


class User(CoreModel):
    username = fields.CharField(50, unique=True)
    email = fields.CharField(60, unique=True)
    password_hash = fields.CharField(128)

    class PydanticMeta(CoreModel.PydanticMeta):
        exclude = (*CoreModel.PydanticMeta.exclude, 'password_hash', )

    def __str__(self):
        return self.email

    def verify_password(self, password):
        return bcrypt.verify(password, self.password_hash)

app/users/schemas.py

import re
from typing import Optional

from fastapi import HTTPException, status
from tortoise.contrib.pydantic import pydantic_model_creator
from pydantic import BaseModel, validator
from app.resources.constants import EMAIL_REGEX, PASSWORD_REGEX

from .models import User


class UserBaseIn(BaseModel):
    email: str
    password: str

    @validator('email')
    def email_validator(cls, value):
        if not value:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                                detail='Email cannot be empty')
        if not re.match(EMAIL_REGEX, value):
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                                detail="Invalid email address.")
        return value

    @validator('password')
    def password_validator(cls, value):
        if not value:
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                                detail='Password cannot be empty')
        if not re.match(PASSWORD_REGEX, value):
            raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST,
                                detail="Invalid password.")
        return value


class UserRegisterIn(UserBaseIn):
    username: Optional[str] = None
    pass


class UserLoginIn(UserBaseIn):
    pass


User_Pydantic = pydantic_model_creator(User, name='User')
UserIn_Pydantic = pydantic_model_creator(User, name='UserIn', exclude_readonly=True)

And the fact that my application breaks soon as installing Openpyxl makes me think it's not really a pydantic problem.

Environment

Docker - 20.10.2
Python - 3.9.2
FastAPI - 0.63.0
Openpyxl - 3.0.6
Tortoise ORM - 0.16.21

Any suggestions will help.
Thank you in advance.

I've tried debugging this a bit. Based on the traceback I simplified the code and was able to reproduce the exception.

from tortoise import fields
from tortoise.models import Model
from passlib.hash import bcrypt


class CoreModel(Model):
    id = fields.UUIDField(pk=True)
    timestamp = fields.DatetimeField(auto_now_add=True)
    updated = fields.DatetimeField(auto_now=True)
    is_active = fields.BooleanField(default=True)

    class Meta:
        abstract = True

    class PydanticMeta:
        exclude = ('user', 'user_id', 'timestamp', 'updated', 'is_active',)


class User(CoreModel):
    username = fields.CharField(50, unique=True)
    email = fields.CharField(60, unique=True)
    password_hash = fields.CharField(128)

    class PydanticMeta(CoreModel.PydanticMeta):
        exclude = (*CoreModel.PydanticMeta.exclude, 'password_hash', )

    def __str__(self):
        return self.email

    def verify_password(self, password):
        return bcrypt.verify(password, self.password_hash)
        

from tortoise.contrib.pydantic import pydantic_model_creator

User_Pydantic = pydantic_model_creator(User, name='User')

Knowing nothing about the underlying library I just looked at anything that might execute and it looks like PyDanticMeta.exclude maps the fieldnames somewhere but two of the fields have different names than in the tuple: user and user_id . The problem seems to be with the user_id ; id is possible. At a guess I think this is related to some magic in the ORM.

I am facing same error but, This isn't pydantic or fastapi errror

its just tortoise-orm error

replace fields.UUIDField with fields.IntField and see if this works

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM