Spaces:
Running
Running
Fabio Antonini Claude Sonnet 4.6 commited on
Commit ·
3d87cee
1
Parent(s): 977221f
fix: resolve local dev issues found during first test run
Browse files- Replace passlib with bcrypt directly (passlib 1.7 incompatible with bcrypt 4.x)
- Fix SQLite engine config: disable pool_pre_ping, add check_same_thread=False
- Import all models in __init__.py so SQLAlchemy resolves relationships
- Change dev proxy port to 8001 (port 8000 occupied by Wacom service on dev machine)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- backend/auth/password.py +4 -5
- backend/database.py +9 -5
- backend/models/__init__.py +3 -0
- frontend/vite.config.ts +1 -1
backend/auth/password.py
CHANGED
|
@@ -1,15 +1,14 @@
|
|
| 1 |
"""
|
| 2 |
GraphoLab Backend — Password hashing with bcrypt.
|
|
|
|
| 3 |
"""
|
| 4 |
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
_ctx = CryptContext(schemes=["bcrypt"], deprecated="auto")
|
| 8 |
|
| 9 |
|
| 10 |
def hash_password(plain: str) -> str:
|
| 11 |
-
return
|
| 12 |
|
| 13 |
|
| 14 |
def verify_password(plain: str, hashed: str) -> bool:
|
| 15 |
-
return
|
|
|
|
| 1 |
"""
|
| 2 |
GraphoLab Backend — Password hashing with bcrypt.
|
| 3 |
+
Uses bcrypt directly (passlib 1.7 is incompatible with bcrypt 4.x).
|
| 4 |
"""
|
| 5 |
|
| 6 |
+
import bcrypt
|
|
|
|
|
|
|
| 7 |
|
| 8 |
|
| 9 |
def hash_password(plain: str) -> str:
|
| 10 |
+
return bcrypt.hashpw(plain.encode(), bcrypt.gensalt()).decode()
|
| 11 |
|
| 12 |
|
| 13 |
def verify_password(plain: str, hashed: str) -> bool:
|
| 14 |
+
return bcrypt.checkpw(plain.encode(), hashed.encode())
|
backend/database.py
CHANGED
|
@@ -9,11 +9,15 @@ from sqlalchemy.orm import DeclarativeBase
|
|
| 9 |
|
| 10 |
from backend.config import settings
|
| 11 |
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
|
| 18 |
AsyncSessionLocal = async_sessionmaker(
|
| 19 |
bind=engine,
|
|
|
|
| 9 |
|
| 10 |
from backend.config import settings
|
| 11 |
|
| 12 |
+
# SQLite needs check_same_thread=False; pool_pre_ping is not compatible with aiosqlite
|
| 13 |
+
_is_sqlite = settings.database_url.startswith("sqlite")
|
| 14 |
+
_engine_kwargs: dict = {"echo": settings.debug}
|
| 15 |
+
if _is_sqlite:
|
| 16 |
+
_engine_kwargs["connect_args"] = {"check_same_thread": False}
|
| 17 |
+
else:
|
| 18 |
+
_engine_kwargs["pool_pre_ping"] = True
|
| 19 |
+
|
| 20 |
+
engine = create_async_engine(settings.database_url, **_engine_kwargs)
|
| 21 |
|
| 22 |
AsyncSessionLocal = async_sessionmaker(
|
| 23 |
bind=engine,
|
backend/models/__init__.py
CHANGED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Import all models so SQLAlchemy can resolve relationships regardless of import order.
|
| 2 |
+
from backend.models.user import User, Organization, Role # noqa: F401
|
| 3 |
+
from backend.models.project import Project, Document, Analysis, ProjectStatus, AnalysisType # noqa: F401
|
frontend/vite.config.ts
CHANGED
|
@@ -14,7 +14,7 @@ export default defineConfig({
|
|
| 14 |
port: 3000,
|
| 15 |
proxy: {
|
| 16 |
'/api': {
|
| 17 |
-
target: 'http://localhost:
|
| 18 |
changeOrigin: true,
|
| 19 |
rewrite: (p) => p.replace(/^\/api/, ''),
|
| 20 |
},
|
|
|
|
| 14 |
port: 3000,
|
| 15 |
proxy: {
|
| 16 |
'/api': {
|
| 17 |
+
target: 'http://localhost:8001',
|
| 18 |
changeOrigin: true,
|
| 19 |
rewrite: (p) => p.replace(/^\/api/, ''),
|
| 20 |
},
|