ImportError: cannot import name '__author__' from 'bcrypt._bcrypt' (/.venv/lib/python3.13/site-packages/bcrypt/_bcrypt.cpython-313-darwin.so)
ImportError: cannot import name 'author' from 'bcrypt._bcrypt' (/.venv/lib/python3.13/site-packages/bcrypt/_bcrypt.cpython-313-darwin.so)
Please provide instructions for reproducing from a clean environment.
import bcrypt
import re
import secrets
class PasswordUtility:
@staticmethod
def hash_password(password: str) -> bytes:
return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt(12))
@staticmethod
def check_password(plain_text_password: str, hashed_password: bytes) -> bool:
return bcrypt.checkpw(plain_text_password.encode('utf-8'), hashed_password)
@staticmethod
def validate_password(password: str) -> tuple[bool, str]:
"""
Validates the password against common rules.
Returns (True, "Valid") if password is OK,
otherwise returns (False, "Reason why it failed").
"""
if len(password) < 8:
return False, "Password must be at least 8 characters long."
if not re.search(r"[A-Z]", password):
return False, "Password must contain at least one uppercase letter."
if not re.search(r"[a-z]", password):
return False, "Password must contain at least one lowercase letter."
if not re.search(r"[0-9]", password):
return False, "Password must contain at least one digit."
if not re.search(r"[\W_]", password): # Special chars including underscore
return False, "Password must contain at least one special character."
return True, "Password is valid."
@staticmethod
def create_otp_code(digits: int = 6) -> int:
if not isinstance(digits, int) or digits < 1 or digits > 20:
raise ValueError("Digits must be an integer between 1 and 20")
return int(''.join(secrets.choice('123456789') for _ in range(digits)))
venv/lib/python3.10/site-packages/bcrypt/__init__.py", line 13, in <module> from ._bcrypt import ( ImportError: cannot import name '__author__' from 'bcrypt._bcrypt'
`
requirements.txt
alembic==1.16.5 annotated-types==0.7.0 anyio==4.9.0 Authlib==1.6.1 certifi==2025.7.14 cffi==1.17.1 click==8.2.1 cryptography==45.0.6 dnspython==2.7.0 ecdsa==0.19.1 email_validator==2.2.0 exceptiongroup==1.3.0 fastapi==0.116.1 fastapi-cli==0.0.8 fastapi-cloud-cli==0.1.4 greenlet==3.2.3 h11==0.16.0 httpcore==1.0.9 httptools==0.6.4 httpx==0.28.1 idna==3.10 itsdangerous==2.2.0 Jinja2==3.1.6 Mako==1.3.10 markdown-it-py==3.0.0 MarkupSafe==3.0.2 mdurl==0.1.2 psycopg2-binary==2.9.10 py-bcrypt==0.4 pyasn1==0.6.1 pycparser==2.22 pydantic==2.11.7 pydantic-settings==2.10.1 pydantic_core==2.33.2 Pygments==2.19.2 python-dotenv==1.1.1 python-jose==3.5.0 python-multipart==0.0.20 PyYAML==6.0.2 rich==14.1.0 rich-toolkit==0.14.8 rignore==0.6.4 rsa==4.9.1 sentry-sdk==2.33.2 shellingham==1.5.4 six==1.17.0 sniffio==1.3.1 SQLAlchemy==2.0.41 sqlmodel==0.0.24 starlette==0.47.2 tomli==2.2.1 typer==0.16.0 typing-inspection==0.4.1 typing_extensions==4.14.1 urllib3==2.5.0 uvicorn==0.35.0 uvloop==0.21.0 watchfiles==1.1.0 websockets==15.0.1
`
it is fixed after installing like this:
pip install git+https://github.com/pyca/bcrypt.git#egg=bcrypt