Removing unused dependencies

This commit is contained in:
James Ketr 2025-06-18 12:49:41 -07:00
parent 168fe8cc8e
commit f53ff967cb
50 changed files with 124 additions and 755 deletions

View File

@ -1,16 +1,7 @@
from __future__ import annotations from __future__ import annotations
import traceback import traceback
from pydantic import BaseModel, Field
from typing import ( from typing import (
Literal,
get_args,
List,
AsyncGenerator,
TYPE_CHECKING,
Optional,
ClassVar,
Any,
TypeAlias, TypeAlias,
Dict, Dict,
Tuple, Tuple,

View File

@ -5,51 +5,41 @@ from typing import (
get_args, get_args,
List, List,
AsyncGenerator, AsyncGenerator,
TYPE_CHECKING,
Optional, Optional,
ClassVar, ClassVar,
Any, Any,
TypeAlias,
Dict,
Tuple,
) )
import json
import time import time
import inspect
import re import re
from abc import ABC from abc import ABC
import asyncio
from datetime import datetime, UTC from datetime import datetime, UTC
from prometheus_client import Counter, Summary, CollectorRegistry # type: ignore from prometheus_client import Counter, Summary, CollectorRegistry # type: ignore
import numpy as np # type: ignore import numpy as np # type: ignore
import json_extractor as json_extractor import json_extractor as json_extractor
from pydantic import BaseModel, Field, model_validator # type: ignore from pydantic import BaseModel, Field, model_validator # type: ignore
from uuid import uuid4 from uuid import uuid4
from typing import List, Optional, Generator, ClassVar, Any, Dict, TYPE_CHECKING, Literal from typing import List, Optional, ClassVar, Any, Literal
from datetime import datetime, date, UTC from datetime import datetime, UTC
from typing_extensions import Annotated, Union
import numpy as np # type: ignore import numpy as np # type: ignore
from uuid import uuid4 from uuid import uuid4
from prometheus_client import CollectorRegistry, Counter # type: ignore from prometheus_client import CollectorRegistry, Counter # type: ignore
import traceback
import os import os
import json
import re import re
from pathlib import Path from pathlib import Path
from rag import start_file_watcher, ChromaDBFileWatcher from rag import start_file_watcher, ChromaDBFileWatcher
import defines import defines
from logger import logger from logger import logger
from models import (Tunables, CandidateQuestion, ChatMessageUser, ChatMessage, RagEntry, ChatMessageMetaData, ApiStatusType, Candidate, ChatContextType) from models import (Tunables, ChatMessageUser, ChatMessage, RagEntry, ChatMessageMetaData, ApiStatusType, Candidate, ChatContextType)
import utils.llm_proxy as llm_manager import utils.llm_proxy as llm_manager
from database.manager import RedisDatabase from database.manager import RedisDatabase
from models import ChromaDBGetResponse from models import ChromaDBGetResponse
from utils.metrics import Metrics from utils.metrics import Metrics
from models import ( ApiActivityType, ApiMessage, ChatMessageError, ChatMessageRagSearch, ChatMessageStatus, ChatMessageStreaming, LLMMessage, ChatQuery, ChatMessage, ChatOptions, ChatMessageUser, Tunables, ApiMessageType, ChatSenderType, ApiStatusType, ChatMessageMetaData, Candidate) from models import ( ApiActivityType, ApiMessage, ChatMessageError, ChatMessageRagSearch, ChatMessageStatus, ChatMessageStreaming, LLMMessage, ChatMessage, ChatOptions, ChatMessageUser, Tunables, ApiStatusType, ChatMessageMetaData, Candidate)
from logger import logger from logger import logger
import defines import defines
from .registry import agent_registry from .registry import agent_registry
@ -64,7 +54,6 @@ class CandidateEntity(Candidate):
async def cleanup(self): async def cleanup(self):
"""Cleanup resources associated with this entity""" """Cleanup resources associated with this entity"""
pass
# Internal instance members # Internal instance members
CandidateEntity__agents: List[Agent] = [] CandidateEntity__agents: List[Agent] = []

View File

@ -1,13 +1,11 @@
from __future__ import annotations from __future__ import annotations
from typing import Literal, AsyncGenerator, ClassVar, Optional, Any from typing import Literal, AsyncGenerator, ClassVar, Optional, Any
from datetime import datetime
import inspect
from .base import Agent, agent_registry from .base import Agent, agent_registry
from logger import logger from logger import logger
from .registry import agent_registry from .registry import agent_registry
from models import ( ApiMessage, ChatMessageError, ChatMessageStatus, ChatMessageStreaming, ChatQuery, ChatMessage, Tunables, ApiStatusType, ChatMessageUser, Candidate) from models import ( ApiMessage, Tunables, ApiStatusType)
system_message = f""" system_message = f"""

View File

@ -1,13 +1,10 @@
from __future__ import annotations from __future__ import annotations
from typing import Literal, AsyncGenerator, ClassVar, Optional, Any from typing import Literal, ClassVar
from datetime import datetime from datetime import datetime
import inspect
from .base import Agent, agent_registry from .base import Agent, agent_registry
from logger import logger
from .registry import agent_registry from .registry import agent_registry
from models import ( ChatQuery, ChatMessage, Tunables, ApiStatusType)
system_message = f""" system_message = f"""
Launched on {datetime.now().isoformat()}. Launched on {datetime.now().isoformat()}.

View File

@ -1,6 +1,4 @@
from __future__ import annotations from __future__ import annotations
from datetime import UTC, datetime
from pydantic import model_validator, Field, BaseModel
from typing import ( from typing import (
Dict, Dict,
Literal, Literal,
@ -12,25 +10,17 @@ from typing import (
Optional Optional
# override # override
) # NOTE: You must import Optional for late binding to work ) # NOTE: You must import Optional for late binding to work
import inspect
import random import random
import re
import json
import asyncio
import time import time
import asyncio
import time import time
import os import os
import hashlib
from .base import Agent, agent_registry, LLMMessage from .base import Agent, agent_registry
from models import ActivityType, ApiActivityType, Candidate, ChatMessage, ChatMessageError, ChatMessageMetaData, ApiMessageType, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatOptions, ChatSenderType, ApiStatusType, Tunables from models import ApiActivityType, ChatMessage, ChatMessageError, ChatMessageStatus, ChatMessageStreaming, ApiStatusType, Tunables
import helpers.model_cast as model_cast
from logger import logger from logger import logger
import defines import defines
import backstory_traceback as traceback import backstory_traceback as traceback
from image_generator.image_model_cache import ImageModelCache
from image_generator.profile_image import generate_image, ImageRequest from image_generator.profile_image import generate_image, ImageRequest
seed = int(time.time()) seed = int(time.time())

View File

@ -1,5 +1,4 @@
from __future__ import annotations from __future__ import annotations
from datetime import UTC, datetime
from pydantic import model_validator, Field, BaseModel # type: ignore from pydantic import model_validator, Field, BaseModel # type: ignore
from typing import ( from typing import (
Dict, Dict,
@ -13,20 +12,17 @@ from typing import (
Optional Optional
# override # override
) # NOTE: You must import Optional for late binding to work ) # NOTE: You must import Optional for late binding to work
import inspect
import random import random
import re import re
import json import json
import asyncio
import time import time
import asyncio
import time import time
import os import os
import random import random
from names_dataset import NameDataset, NameWrapper # type: ignore from names_dataset import NameDataset, NameWrapper # type: ignore
from .base import Agent, agent_registry, LLMMessage from .base import Agent, agent_registry
from models import ApiActivityType, Candidate, ChatMessage, ChatMessageError, ChatMessageMetaData, ApiMessageType, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatOptions, ChatSenderType, ApiStatusType, Tunables from models import ApiActivityType, ChatMessage, ChatMessageError, ApiMessageType, ChatMessageStatus, ChatMessageStreaming, ApiStatusType, Tunables
from logger import logger from logger import logger
import defines import defines
import backstory_traceback as traceback import backstory_traceback as traceback

View File

@ -10,18 +10,12 @@ from typing import (
Optional Optional
# override # override
) # NOTE: You must import Optional for late binding to work ) # NOTE: You must import Optional for late binding to work
import inspect
import re
import json import json
import traceback
import asyncio
import time
import asyncio
import numpy as np # type: ignore import numpy as np # type: ignore
from logger import logger from logger import logger
from .base import Agent, agent_registry from .base import Agent, agent_registry
from models import (ApiActivityType, ApiMessage, ApiStatusType, Candidate, ChatMessage, ChatMessageError, ChatMessageResume, ChatMessageStatus, JobRequirements, JobRequirementsMessage, SkillAssessment, SkillStrength, Tunables) from models import (ApiActivityType, ApiMessage, ApiStatusType, ChatMessage, ChatMessageError, ChatMessageResume, ChatMessageStatus, SkillAssessment, SkillStrength)
class GenerateResume(Agent): class GenerateResume(Agent):
agent_type: Literal["generate_resume"] = "generate_resume" # type: ignore agent_type: Literal["generate_resume"] = "generate_resume" # type: ignore

View File

@ -11,17 +11,12 @@ from typing import (
# override # override
) # NOTE: You must import Optional for late binding to work ) # NOTE: You must import Optional for late binding to work
import inspect import inspect
import re
import json import json
import asyncio
import time
import asyncio
import numpy as np # type: ignore import numpy as np # type: ignore
from .base import Agent, agent_registry, LLMMessage from .base import Agent, agent_registry
from models import ApiActivityType, ApiMessage, Candidate, ChatMessage, ChatMessageError, ChatMessageMetaData, ApiMessageType, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatOptions, ChatSenderType, ApiStatusType, Job, JobRequirements, JobRequirementsMessage, Tunables from models import ApiActivityType, ApiMessage, ChatMessage, ChatMessageError, ChatMessageStatus, ChatMessageStreaming, ApiStatusType, Job, JobRequirements, JobRequirementsMessage, Tunables
from logger import logger from logger import logger
import defines
import backstory_traceback as traceback import backstory_traceback as traceback
class JobRequirementsAgent(Agent): class JobRequirementsAgent(Agent):

View File

@ -1,13 +1,11 @@
from __future__ import annotations from __future__ import annotations
from typing import Literal, AsyncGenerator, ClassVar, Optional, Any, List from typing import Literal, AsyncGenerator, ClassVar, Optional, Any
from datetime import datetime, UTC
import inspect
from .base import Agent, agent_registry from .base import Agent, agent_registry
from logger import logger from logger import logger
from .registry import agent_registry from .registry import agent_registry
from models import ( ApiMessage, ChatMessage, ChromaDBGetResponse, ApiStatusType, ChatMessage, ChatMessageError, ChatMessageRagSearch, ChatMessageStatus, ChatMessageStreaming, ChatOptions, ApiMessageType, ChatSenderType, ApiStatusType, ChatMessageMetaData, Candidate, Tunables ) from models import ( ApiMessage, ApiStatusType, ChatMessageError, ChatMessageRagSearch, ApiStatusType, Tunables )
class Chat(Agent): class Chat(Agent):
""" """

View File

@ -10,20 +10,13 @@ from typing import (
Optional Optional
# override # override
) # NOTE: You must import Optional for late binding to work ) # NOTE: You must import Optional for late binding to work
import inspect
import re
import json import json
import asyncio
import time
import asyncio
import numpy as np # type: ignore import numpy as np # type: ignore
from .base import Agent, agent_registry, LLMMessage from .base import Agent, agent_registry
from models import (ApiMessage, Candidate, ChatMessage, ChatMessageError, ChatMessageMetaData, ApiMessageType, ChatMessageRagSearch, from models import (ApiMessage, ChatMessage, ChatMessageError, ChatMessageRagSearch, ChatMessageSkillAssessment, ApiStatusType, EvidenceDetail,
ChatMessageSkillAssessment, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatOptions, SkillAssessment, Tunables)
ChatSenderType, ApiStatusType, EvidenceDetail, SkillAssessment, Tunables)
from logger import logger from logger import logger
import defines
import backstory_traceback as traceback import backstory_traceback as traceback
class SkillMatchAgent(Agent): class SkillMatchAgent(Agent):

View File

@ -1,275 +0,0 @@
# auth_utils.py
"""
Secure Authentication Utilities
Provides password hashing, verification, and security features
"""
import traceback
import bcrypt
import secrets
import logging
from datetime import datetime, timezone, timedelta
from typing import Dict, Any, Optional, Tuple
from pydantic import BaseModel
logger = logging.getLogger(__name__)
class PasswordSecurity:
"""Handles password hashing and verification using bcrypt"""
@staticmethod
def hash_password(password: str) -> Tuple[str, str]:
"""
Hash a password with a random salt using bcrypt
Args:
password: Plain text password
Returns:
Tuple of (password_hash, salt) both as strings
"""
# Generate a random salt
salt = bcrypt.gensalt()
# Hash the password
password_hash = bcrypt.hashpw(password.encode('utf-8'), salt)
return password_hash.decode('utf-8'), salt.decode('utf-8')
@staticmethod
def verify_password(password: str, password_hash: str) -> bool:
"""
Verify a password against its hash
Args:
password: Plain text password to verify
password_hash: Stored password hash
Returns:
True if password matches, False otherwise
"""
try:
return bcrypt.checkpw(
password.encode('utf-8'),
password_hash.encode('utf-8')
)
except Exception as e:
logger.error(f"Password verification error: {e}")
return False
@staticmethod
def generate_secure_token(length: int = 32) -> str:
"""Generate a cryptographically secure random token"""
return secrets.token_urlsafe(length)
class AuthenticationRecord(BaseModel):
"""Authentication record for storing user credentials"""
user_id: str
password_hash: str
salt: str
refresh_tokens: list = []
reset_password_token: Optional[str] = None
reset_password_expiry: Optional[datetime] = None
last_password_change: datetime
mfa_enabled: bool = False
mfa_method: Optional[str] = None
mfa_secret: Optional[str] = None
login_attempts: int = 0
locked_until: Optional[datetime] = None
class Config:
json_encoders = {
datetime: lambda v: v.isoformat() if v else None
}
class SecurityConfig:
"""Security configuration constants"""
MAX_LOGIN_ATTEMPTS = 5
ACCOUNT_LOCKOUT_DURATION_MINUTES = 15
PASSWORD_MIN_LENGTH = 8
TOKEN_EXPIRY_HOURS = 24
REFRESH_TOKEN_EXPIRY_DAYS = 30
class AuthenticationManager:
"""Manages authentication operations with security features"""
def __init__(self, database):
self.database = database
self.password_security = PasswordSecurity()
async def create_user_authentication(self, user_id: str, password: str) -> AuthenticationRecord:
"""
Create authentication record for a new user
Args:
user_id: Unique user identifier
password: Plain text password
Returns:
AuthenticationRecord object
"""
if len(password) < SecurityConfig.PASSWORD_MIN_LENGTH:
raise ValueError(f"Password must be at least {SecurityConfig.PASSWORD_MIN_LENGTH} characters long")
# Hash the password
password_hash, salt = self.password_security.hash_password(password)
# Create authentication record
auth_record = AuthenticationRecord(
user_id=user_id,
password_hash=password_hash,
salt=salt,
last_password_change=datetime.now(timezone.utc),
login_attempts=0
)
# Store in database
await self.database.set_authentication(user_id, auth_record.model_dump())
logger.info(f"🔐 Created authentication record for user {user_id}")
return auth_record
async def verify_user_credentials(self, login: str, password: str) -> Tuple[bool, Optional[Dict[str, Any]], Optional[str]]:
"""
Verify user credentials with security checks
Args:
login: Email or username
password: Plain text password
Returns:
Tuple of (is_valid, user_data, error_message)
"""
try:
# Get user data
user_data = await self.database.get_user(login)
if not user_data:
logger.warning(f"⚠️ Login attempt with non-existent user: {login}")
return False, None, "Invalid credentials"
# Get authentication record
auth_record = await self.database.get_authentication(user_data["id"])
if not auth_record:
logger.error(f"❌ No authentication record found for user {user_data['id']}")
return False, None, "Authentication record not found"
auth_data = AuthenticationRecord.model_validate(auth_record)
# Check if account is locked
if auth_data.locked_until and auth_data.locked_until > datetime.now(timezone.utc):
time_until_unlock = auth_data.locked_until - datetime.now(timezone.utc)
# Convert time_until_unlock to minutes:seconds format
total_seconds = time_until_unlock.total_seconds()
minutes = int(total_seconds // 60)
seconds = int(total_seconds % 60)
time_until_unlock_str = f"{minutes}m {seconds}s"
logger.warning(f"🔒 Account is locked for user {login} for another {time_until_unlock_str}.")
return False, None, f"Account is temporarily locked due to too many failed attempts. Retry after {time_until_unlock_str}"
# Verify password
if not self.password_security.verify_password(password, auth_data.password_hash):
# Increment failed attempts
auth_data.login_attempts += 1
# Lock account if too many attempts
if auth_data.login_attempts >= SecurityConfig.MAX_LOGIN_ATTEMPTS:
auth_data.locked_until = datetime.now(timezone.utc) + timedelta(
minutes=SecurityConfig.ACCOUNT_LOCKOUT_DURATION_MINUTES
)
logger.warning(f"🔒 Account locked for user {login} after {auth_data.login_attempts} failed attempts")
# Update authentication record
await self.database.set_authentication(user_data["id"], auth_data.model_dump())
logger.warning(f"⚠️ Invalid password for user {login} (attempt {auth_data.login_attempts})")
return False, None, "Invalid credentials"
# Reset failed attempts on successful login
if auth_data.login_attempts > 0:
auth_data.login_attempts = 0
auth_data.locked_until = None
await self.database.set_authentication(user_data["id"], auth_data.model_dump())
logger.info(f"✅ Successful authentication for user {login}")
return True, user_data, None
except Exception as e:
logger.error(traceback.format_exc())
logger.error(f"❌ Authentication error for user {login}: {e}")
return False, None, "Authentication failed"
async def check_user_exists(self, email: str, username: str | None = None) -> Tuple[bool, Optional[str]]:
"""
Check if a user already exists with the given email or username
Args:
email: Email address to check
username: Username to check (optional)
Returns:
Tuple of (exists, conflict_field)
"""
try:
# Check email
existing_user = await self.database.get_user(email)
if existing_user:
return True, "email"
# Check username if provided
if username:
existing_user = await self.database.get_user(username)
if existing_user:
return True, "username"
return False, None
except Exception as e:
logger.error(f"❌ Error checking user existence: {e}")
# In case of error, assume user doesn't exist to avoid blocking creation
return False, None
async def update_last_login(self, user_id: str):
"""Update user's last login timestamp"""
try:
user_data = await self.database.get_user_by_id(user_id)
if user_data:
user_data["lastLogin"] = datetime.now(timezone.utc).isoformat()
await self.database.set_user_by_id(user_id, user_data)
except Exception as e:
logger.error(f"❌ Error updating last login for user {user_id}: {e}")
# Utility functions for common operations
def validate_password_strength(password: str) -> Tuple[bool, list]:
"""
Validate password strength
Args:
password: Password to validate
Returns:
Tuple of (is_valid, list_of_issues)
"""
issues = []
if len(password) < SecurityConfig.PASSWORD_MIN_LENGTH:
issues.append(f"Password must be at least {SecurityConfig.PASSWORD_MIN_LENGTH} characters long")
if not any(c.isupper() for c in password):
issues.append("Password must contain at least one uppercase letter")
if not any(c.islower() for c in password):
issues.append("Password must contain at least one lowercase letter")
if not any(c.isdigit() for c in password):
issues.append("Password must contain at least one digit")
# Check for special characters
special_chars = "!@#$%^&*()_+-=[]{}|;:,.<>?"
if not any(c in special_chars for c in password):
issues.append("Password must contain at least one special character")
return len(issues) == 0, issues
def sanitize_login_input(login: str) -> str:
"""Sanitize login input (email or username)"""
return login.strip().lower() if login else ""

View File

@ -1,17 +1,14 @@
from pydantic import BaseModel, ConfigDict, Field
from redis.asyncio import (Redis, ConnectionPool) from redis.asyncio import (Redis, ConnectionPool)
from typing import Any, Optional, Dict, List, Optional, TypeGuard, Union from typing import Optional, Optional
import json import json
import logging import logging
import os import os
from datetime import datetime, timezone, UTC, timedelta from datetime import datetime, UTC
import asyncio import asyncio
from models import ( from models import (
# User models # User models
Candidate, Employer, BaseUser, EvidenceDetail, Guest, Authentication, AuthResponse, SkillAssessment, Candidate, Employer, BaseUser, EvidenceDetail, Guest, Authentication, AuthResponse, SkillAssessment,
) )
import backstory_traceback as traceback
from .constants import KEY_PREFIXES
from .core import RedisDatabase from .core import RedisDatabase
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@ -1,7 +1,5 @@
from datetime import UTC, datetime, timedelta, timezone
import logging import logging
import json from typing import Optional, Any, Dict
from typing import List, Optional, Any, Dict, TYPE_CHECKING, Self
from .protocols import DatabaseProtocol from .protocols import DatabaseProtocol

View File

@ -1,10 +1,9 @@
import logging import logging
from typing import Any, Dict, TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from .protocols import DatabaseProtocol pass
from ..constants import KEY_PREFIXES
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@ -1,11 +1,10 @@
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
import json import json
import logging import logging
from typing import Any, Dict, TYPE_CHECKING, List, Optional from typing import Any, Dict, List, Optional
from .protocols import DatabaseProtocol from .protocols import DatabaseProtocol
from ..constants import KEY_PREFIXES
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@ -1,7 +1,6 @@
from datetime import UTC, datetime
import json import json
import logging import logging
from typing import Any, Dict, TYPE_CHECKING, Optional from typing import Any, Dict, TYPE_CHECKING
from .protocols import DatabaseProtocol from .protocols import DatabaseProtocol
@ -9,7 +8,7 @@ from ..constants import KEY_PREFIXES
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
if TYPE_CHECKING: if TYPE_CHECKING:
from ..core import RedisDatabase pass
class BaseMixin(DatabaseProtocol): class BaseMixin(DatabaseProtocol):
"""Base mixin with core Redis operations and utilities""" """Base mixin with core Redis operations and utilities"""

View File

@ -1,6 +1,6 @@
from datetime import datetime, UTC, timedelta from datetime import datetime, UTC, timedelta
import logging import logging
from typing import Any, Dict, TYPE_CHECKING, List, Optional from typing import Any, Dict, List, Optional
from .protocols import DatabaseProtocol from .protocols import DatabaseProtocol

View File

@ -1,6 +1,6 @@
from datetime import UTC, datetime from datetime import UTC, datetime
import logging import logging
from typing import Any, Dict, TYPE_CHECKING, List, Optional from typing import Any, Dict, List, Optional
from .protocols import DatabaseProtocol from .protocols import DatabaseProtocol
from ..constants import KEY_PREFIXES from ..constants import KEY_PREFIXES

View File

@ -1,6 +1,6 @@
from datetime import datetime, UTC, timedelta from datetime import datetime, UTC
import logging import logging
from typing import Any, Dict, TYPE_CHECKING, List, Optional from typing import Any, Dict, List, Optional
from .protocols import DatabaseProtocol from .protocols import DatabaseProtocol

View File

@ -3,7 +3,7 @@ from typing import Any, Dict, List, Optional, Protocol, TYPE_CHECKING
from redis.asyncio import Redis from redis.asyncio import Redis
if TYPE_CHECKING: if TYPE_CHECKING:
from database.core import RedisDatabase pass
from models import SkillAssessment from models import SkillAssessment

View File

@ -1,6 +1,6 @@
from datetime import UTC, datetime from datetime import UTC, datetime
import logging import logging
from typing import Any, Dict, TYPE_CHECKING, List, Optional from typing import Any, Dict, List, Optional
from .protocols import DatabaseProtocol from .protocols import DatabaseProtocol
from ..constants import KEY_PREFIXES from ..constants import KEY_PREFIXES

View File

@ -1,11 +1,10 @@
import json import json
import logging import logging
from typing import Any, Dict, TYPE_CHECKING, Optional from typing import Optional
from models import SkillAssessment from models import SkillAssessment
from .protocols import DatabaseProtocol from .protocols import DatabaseProtocol
from ..constants import KEY_PREFIXES
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@ -1,7 +1,7 @@
from datetime import UTC, datetime, timedelta, timezone from datetime import UTC, datetime, timedelta, timezone
import logging import logging
import json import json
from typing import List, Optional, Any, Dict, TYPE_CHECKING, Self from typing import List, Optional, Any, Dict, Self
from .protocols import DatabaseProtocol from .protocols import DatabaseProtocol

View File

@ -1,4 +1,4 @@
from fastapi import FastAPI, HTTPException, Depends, Query, Path, Body, status, APIRouter, Request, BackgroundTasks from fastapi import Request
from database.manager import RedisDatabase from database.manager import RedisDatabase
import hashlib import hashlib
from logger import logger from logger import logger

View File

@ -1,9 +1,7 @@
from __future__ import annotations
import asyncio import asyncio
from uuid import uuid4
import weakref import weakref
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import Dict, Optional, Any from typing import Dict, Optional
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from pydantic import BaseModel, Field # type: ignore from pydantic import BaseModel, Field # type: ignore
@ -46,7 +44,7 @@ class EntityManager(BaseModel):
self._prometheus_collector = prometheus_collector self._prometheus_collector = prometheus_collector
self._database = database self._database = database
async def get_entity(self, candidate: Candidate) -> CandidateEntity: async def get_entity(self, candidate: "Candidate") -> CandidateEntity:
"""Get or create CandidateEntity with proper reference tracking""" """Get or create CandidateEntity with proper reference tracking"""
# Check if entity exists and is still valid # Check if entity exists and is still valid

View File

@ -8,7 +8,7 @@ import sys
from datetime import datetime from datetime import datetime
from models import ( from models import (
UserStatus, UserType, SkillLevel, EmploymentType, UserStatus, UserType, SkillLevel, EmploymentType,
Candidate, Employer, Location, Skill, AIModelType Candidate, Employer, Location, Skill
) )

View File

@ -458,7 +458,6 @@ def is_field_optional(field_info: Any, field_type: Any, debug: bool = False) ->
except: except:
if debug: if debug:
print(f" └─ is_required() failed") print(f" └─ is_required() failed")
pass
# Check the 'required' attribute (Pydantic v1 style) # Check the 'required' attribute (Pydantic v1 style)
if hasattr(field_info, 'required'): if hasattr(field_info, 'required'):

View File

@ -1,4 +1,4 @@
from pydantic import BaseModel, Field from pydantic import BaseModel
import json import json
from typing import Any, List, Set from typing import Any, List, Set

View File

@ -1,22 +1,13 @@
from __future__ import annotations from __future__ import annotations
from datetime import UTC, datetime from pydantic import BaseModel
from pydantic import BaseModel, Field from typing import Any, AsyncGenerator
from typing import Dict, Literal, Any, AsyncGenerator, Optional
import inspect
import random
import re
import json
import traceback import traceback
import asyncio import asyncio
import time import time
import os import os
import gc
import tempfile
import uuid import uuid
import torch
import asyncio import asyncio
import time import time
import json
from typing import AsyncGenerator from typing import AsyncGenerator
from threading import Thread from threading import Thread
import queue import queue
@ -24,7 +15,7 @@ import uuid
from .image_model_cache import ImageModelCache from .image_model_cache import ImageModelCache
from models import ApiActivityType, ApiStatusType, Candidate, ChatMessage, ChatMessageError, ChatMessageMetaData, ChatMessageStatus, ChatMessageUser, ChatOptions, ChatSenderType from models import ApiActivityType, ApiStatusType, ChatMessage, ChatMessageError, ChatMessageStatus
from logger import logger from logger import logger
from image_generator.image_model_cache import ImageModelCache from image_generator.image_model_cache import ImageModelCache

View File

@ -1,81 +1,37 @@
import hashlib from fastapi import FastAPI, Depends, APIRouter, Request
import time
import traceback
from fastapi import FastAPI, HTTPException, Depends, Query, Path, Body, status, APIRouter, Request, BackgroundTasks, File, UploadFile, Form
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi.exceptions import RequestValidationError from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse, StreamingResponse, FileResponse from fastapi.responses import JSONResponse, FileResponse
from fastapi.staticfiles import StaticFiles
from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY from starlette.status import HTTP_422_UNPROCESSABLE_ENTITY
from functools import wraps from typing import Optional
from typing import Callable, Any, Optional
from utils.rate_limiter import RateLimiter, RateLimitResult
import schedule
import os import os
import shutil
from enum import Enum
import uuid
import defines import defines
import pathlib
from markitdown import MarkItDown, StreamInfo
import io
import uvicorn import uvicorn
from typing import List, Optional, Dict, Any from datetime import datetime
from datetime import datetime, timedelta, UTC
import uuid
import jwt
import os
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
import redis.asyncio as redis
import re import re
import asyncio
import signal import signal
import json import json
import uuid
import logging
from datetime import datetime, timezone, timedelta
from typing import Dict, Any, Optional
from pydantic import BaseModel, EmailStr, field_validator, ValidationError
# Prometheus # Prometheus
from prometheus_client import Summary
from prometheus_fastapi_instrumentator import Instrumentator from prometheus_fastapi_instrumentator import Instrumentator
from prometheus_client import CollectorRegistry, Counter from prometheus_client import CollectorRegistry
import secrets
import os
import backstory_traceback import backstory_traceback
from background_tasks import BackgroundTaskManager
# ============================= # =============================
# Import custom modules # Import custom modules
# ============================= # =============================
from auth_utils import (
AuthenticationManager,
validate_password_strength,
sanitize_login_input,
SecurityConfig
)
import helpers.model_cast as model_cast
import defines
from logger import logger from logger import logger
from database.manager import RedisDatabase, redis_manager, DatabaseManager
import entities
from email_service import VerificationEmailRateLimiter, email_service
from device_manager import DeviceManager
import agents
from entities.entity_manager import entity_manager from entities.entity_manager import entity_manager
from database.manager import redis_manager, DatabaseManager
from background_tasks import BackgroundTaskManager
# ============================= # =============================
# Import utilities # Import utilities
# ============================= # =============================
from utils.dependencies import get_database, set_db_manager from utils.dependencies import get_database, set_db_manager
from utils.responses import create_success_response, create_error_response
from utils.helpers import filter_and_paginate
# ============================= # =============================
# Import route modules # Import route modules
@ -93,35 +49,6 @@ from routes import (
users, users,
) )
# =============================
# Import Pydantic models
# =============================
from models import (
# API
MOCK_UUID, ApiActivityType, ChatMessageError, ChatMessageResume, ChatMessageSkillAssessment, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, DocumentMessage, DocumentOptions, Job, JobRequirements, JobRequirementsMessage, LoginRequest, CreateCandidateRequest, CreateEmployerRequest,
# User models
Candidate, Employer, BaseUserWithType, BaseUser, Guest, Authentication, AuthResponse, CandidateAI,
# Job models
JobApplication, ApplicationStatus,
# Chat models
ChatSession, ChatMessage, ChatContext, ChatQuery, ApiStatusType, ChatSenderType, ApiMessageType, ChatContextType,
ChatMessageRagSearch,
# Document models
Document, DocumentType, DocumentListResponse, DocumentUpdateRequest, DocumentContentResponse,
# Supporting models
Location, MFARequest, MFAData, MFARequestResponse, MFAVerifyRequest, RagContentMetadata, RagContentResponse, ResendVerificationRequest, Resume, ResumeMessage, Skill, SkillAssessment, SystemInfo, UserType, WorkExperience, Education,
# Email
EmailVerificationRequest
)
# Initialize FastAPI app
# ============================ # ============================
# Startup Event # Startup Event
# ============================ # ============================

View File

@ -1,14 +1,11 @@
from typing import List, Dict, Optional, Any, Union, Literal, TypeVar, Generic, Annotated from typing import List, Dict, Optional, Any, Union, Literal, TypeVar, Annotated
from pydantic import BaseModel, Field, EmailStr, HttpUrl, model_validator, field_validator, ConfigDict from pydantic import BaseModel, Field, EmailStr, HttpUrl, model_validator, field_validator, ConfigDict
from pydantic.types import constr, conint from datetime import datetime, UTC
from datetime import datetime, date, UTC
from enum import Enum from enum import Enum
import uuid import uuid
from auth_utils import ( from utils.auth_utils import (
AuthenticationManager,
validate_password_strength, validate_password_strength,
sanitize_login_input, sanitize_login_input,
SecurityConfig
) )
import defines import defines
@ -823,7 +820,6 @@ class GuestConversionRequest(BaseModel):
@field_validator('password') @field_validator('password')
def validate_password_strength(cls, v): def validate_password_strength(cls, v):
# Import here to avoid circular imports # Import here to avoid circular imports
from auth_utils import validate_password_strength
is_valid, issues = validate_password_strength(v) is_valid, issues = validate_password_strength(v)
if not is_valid: if not is_valid:
raise ValueError('; '.join(issues)) raise ValueError('; '.join(issues))

View File

@ -1,10 +1,9 @@
from __future__ import annotations from __future__ import annotations
from typing import List, Dict, Any, Optional, TypedDict, Tuple from typing import List, Dict, Any, Optional, TypedDict
from markdown_it import MarkdownIt from markdown_it import MarkdownIt
from markdown_it.tree import SyntaxTreeNode from markdown_it.tree import SyntaxTreeNode
import traceback import traceback
import logging import logging
import json
import defines import defines

View File

@ -1,10 +1,9 @@
from __future__ import annotations from __future__ import annotations
from pydantic import BaseModel, field_serializer, field_validator, model_validator, Field # type: ignore from pydantic import BaseModel, field_serializer, field_validator, model_validator, Field # type: ignore
from typing import List, Optional, Dict, Any, Union from typing import List, Optional, Dict, Any
import os import os
import glob import glob
from pathlib import Path from pathlib import Path
import time
import hashlib import hashlib
import asyncio import asyncio
import logging import logging

View File

@ -2,16 +2,11 @@
Chat routes Chat routes
""" """
import json import json
import jwt from datetime import datetime, timezone, UTC
import secrets
import uuid
from datetime import datetime, timedelta, timezone, UTC
from typing import (Optional, List, Dict, Any)
from fastapi import ( from fastapi import (
APIRouter, HTTPException, Depends, Body, Request, BackgroundTasks, APIRouter, HTTPException, Depends, Body, Request, HTTPException,
FastAPI, HTTPException, Depends, Query, Path, Body, status, Depends, Query, Path, Body, APIRouter, Request
APIRouter, Request, BackgroundTasks, File, UploadFile, Form
) )
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse

View File

@ -7,13 +7,12 @@ import secrets
import uuid import uuid
import os import os
from datetime import datetime, timedelta, timezone, UTC from datetime import datetime, timedelta, timezone, UTC
from typing import Any, Dict, Optional from typing import Any, Dict
from fastapi import APIRouter, HTTPException, Depends, Body, Request, BackgroundTasks from fastapi import APIRouter, Depends, Body, Request, BackgroundTasks
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from pydantic import BaseModel, EmailStr, ValidationError, field_validator from pydantic import BaseModel, EmailStr, ValidationError, field_validator
from auth_utils import AuthenticationManager, SecurityConfig
import backstory_traceback as backstory_traceback import backstory_traceback as backstory_traceback
from utils.rate_limiter import RateLimiter from utils.rate_limiter import RateLimiter
from database.manager import RedisDatabase, redis_manager from database.manager import RedisDatabase, redis_manager
@ -21,23 +20,19 @@ from device_manager import DeviceManager
from email_service import VerificationEmailRateLimiter, email_service from email_service import VerificationEmailRateLimiter, email_service
from logger import logger from logger import logger
from models import ( from models import (
LoginRequest, CreateCandidateRequest, CreateEmployerRequest, LoginRequest, CreateCandidateRequest, Candidate,
Candidate, Employer, Guest, AuthResponse, Employer, Guest, AuthResponse, MFARequest,
MFARequest, MFAData, MFAVerifyRequest, MFAData, MFAVerifyRequest, ResendVerificationRequest,
EmailVerificationRequest, ResendVerificationRequest,
MFARequestResponse, MFARequestResponse MFARequestResponse, MFARequestResponse
) )
from utils.dependencies import ( from utils.dependencies import (
get_current_admin, get_database, get_current_user, get_current_user_or_guest, get_current_admin, get_database, get_current_user, create_access_token
create_access_token, verify_token_with_blacklist
) )
from utils.responses import create_success_response, create_error_response from utils.responses import create_success_response, create_error_response
from utils.rate_limiter import get_rate_limiter from utils.rate_limiter import get_rate_limiter
from auth_utils import ( from utils.auth_utils import (
AuthenticationManager, AuthenticationManager, SecurityConfig,
validate_password_strength, validate_password_strength,
sanitize_login_input,
SecurityConfig
) )
# Create router for authentication endpoints # Create router for authentication endpoints

View File

@ -5,43 +5,38 @@ import json
import pathlib import pathlib
import re import re
import shutil import shutil
import jwt
import secrets import secrets
import uuid import uuid
import os import os
from datetime import datetime, timedelta, timezone, UTC from datetime import datetime, timezone, UTC
from typing import Any, Dict, List, Optional from typing import Any, Dict, List, Optional
from fastapi import APIRouter, File, Form, HTTPException, Depends, Body, Path, Query, Request, BackgroundTasks, UploadFile from fastapi import APIRouter, File, Form, Depends, Body, Path, Query, BackgroundTasks, UploadFile
from fastapi.responses import FileResponse, JSONResponse, StreamingResponse from fastapi.responses import FileResponse, JSONResponse, StreamingResponse
from pydantic import BaseModel, ValidationError from pydantic import ValidationError
from auth_utils import AuthenticationManager, SecurityConfig
import backstory_traceback as backstory_traceback import backstory_traceback as backstory_traceback
from agents.generate_resume import GenerateResume from agents.generate_resume import GenerateResume
import agents.base as agents import agents.base as agents
from utils.rate_limiter import RateLimiter, rate_limited from utils.rate_limiter import rate_limited
from utils.helpers import filter_and_paginate, get_document_type_from_filename, get_skill_cache_key, get_requirements_list from utils.helpers import filter_and_paginate, get_document_type_from_filename, get_skill_cache_key, get_requirements_list
from database.manager import RedisDatabase, redis_manager from database.manager import RedisDatabase
from device_manager import DeviceManager from email_service import email_service
from email_service import VerificationEmailRateLimiter, email_service
from logger import logger from logger import logger
from models import ( from models import (
MOCK_UUID, ApiActivityType, ApiMessageType, ApiStatusType, CandidateAI, ChatContextType, ChatMessageError, ChatMessageRagSearch, ChatMessageResume, ChatMessageSkillAssessment, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatSession, Document, DocumentContentResponse, DocumentListResponse, DocumentMessage, DocumentOptions, DocumentType, DocumentUpdateRequest, Job, JobRequirements, LoginRequest, CreateCandidateRequest, CreateEmployerRequest, MOCK_UUID, ApiActivityType, ApiMessageType, ApiStatusType, CandidateAI, ChatContextType, ChatMessageError, ChatMessageRagSearch, ChatMessageResume, ChatMessageSkillAssessment, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatSession, Document, DocumentContentResponse, DocumentListResponse, DocumentMessage, DocumentOptions, DocumentType, DocumentUpdateRequest, Job, JobRequirements, CreateCandidateRequest, Candidate, RAGDocumentRequest,
Candidate, Employer, Guest, AuthResponse, RagContentMetadata, RagContentResponse, SkillAssessment, UserType
MFARequest, MFAData, MFAVerifyRequest,
EmailVerificationRequest, RAGDocumentRequest, RagContentMetadata, RagContentResponse, ResendVerificationRequest,
MFARequestResponse, MFARequestResponse, SkillAssessment, UserType
) )
from utils.dependencies import ( from utils.dependencies import (
get_current_admin, get_database, get_current_user, get_current_user_or_guest, get_current_admin, get_database, get_current_user, get_current_user_or_guest,
create_access_token, verify_token_with_blacklist, prometheus_collector prometheus_collector
) )
from utils.rate_limiter import rate_limited from utils.rate_limiter import rate_limited
from utils.responses import create_paginated_response, create_success_response, create_error_response from utils.responses import create_paginated_response, create_success_response, create_error_response
import utils.llm_proxy as llm_manager import utils.llm_proxy as llm_manager
import entities.entity_manager as entities import entities.entity_manager as entities
import defines import defines
from utils.auth_utils import AuthenticationManager
# Create router for authentication endpoints # Create router for authentication endpoints
router = APIRouter(prefix="/candidates", tags=["candidates"]) router = APIRouter(prefix="/candidates", tags=["candidates"])

View File

@ -2,29 +2,21 @@
Chat routes Chat routes
""" """
import json import json
import jwt
import secrets
import uuid import uuid
from datetime import datetime, timedelta, timezone, UTC from datetime import datetime, UTC
from typing import (Optional, List, Dict, Any) from typing import (Dict, Any)
from fastapi import ( from fastapi import (
APIRouter, HTTPException, Depends, Body, Request, BackgroundTasks, APIRouter, Depends, Body, Depends, Query, Path,
FastAPI, HTTPException, Depends, Query, Path, Body, status, Body, APIRouter
APIRouter, Request, BackgroundTasks, File, UploadFile, Form
) )
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from pydantic import ValidationError
from auth_utils import AuthenticationManager, SecurityConfig from database.manager import RedisDatabase
from database.manager import RedisDatabase, redis_manager
from device_manager import DeviceManager
from email_service import email_service
from logger import logger from logger import logger
from utils.dependencies import ( from utils.dependencies import (
get_database, get_current_user, get_current_user_or_guest, get_database, get_current_user, get_current_user_or_guest
create_access_token, verify_token_with_blacklist
) )
from utils.responses import ( from utils.responses import (
create_success_response, create_error_response, create_paginated_response create_success_response, create_error_response, create_paginated_response

View File

@ -4,36 +4,15 @@ Debugging Endpoints
import json import json
from datetime import datetime, UTC from datetime import datetime, UTC
from fastapi import APIRouter, Depends, Body, Path from fastapi import APIRouter, Depends, Path
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from pydantic import BaseModel, EmailStr, ValidationError, field_validator
from auth_utils import AuthenticationManager, SecurityConfig from database.manager import RedisDatabase
import backstory_traceback as backstory_traceback
from utils.rate_limiter import RateLimiter
from database.manager import RedisDatabase, redis_manager
from device_manager import DeviceManager
from email_service import VerificationEmailRateLimiter, email_service
from logger import logger from logger import logger
from models import (
LoginRequest, CreateCandidateRequest, CreateEmployerRequest,
Candidate, Employer, Guest, AuthResponse,
MFARequest, MFAData, MFAVerifyRequest,
EmailVerificationRequest, ResendVerificationRequest,
MFARequestResponse, MFARequestResponse
)
from utils.dependencies import ( from utils.dependencies import (
get_current_admin, get_database, get_current_user, get_current_user_or_guest, get_current_admin, get_database
create_access_token, verify_token_with_blacklist
) )
from utils.responses import create_success_response, create_error_response from utils.responses import create_success_response, create_error_response
from utils.rate_limiter import get_rate_limiter
from auth_utils import (
AuthenticationManager,
validate_password_strength,
sanitize_login_input,
SecurityConfig
)
# Create router for authentication endpoints # Create router for authentication endpoints
router = APIRouter(prefix="/auth", tags=["authentication"]) router = APIRouter(prefix="/auth", tags=["authentication"])

View File

@ -1,43 +1,24 @@
""" """
Employer Routes Employer Routes
""" """
import asyncio
import io
import json
import pathlib
import re
import shutil
import jwt
import secrets import secrets
import uuid import uuid
import os from datetime import datetime, timezone
from datetime import datetime, timedelta, timezone, UTC
from typing import Any, Dict, List, Optional
from fastapi import APIRouter, File, Form, HTTPException, Depends, Body, Path, Query, Request, BackgroundTasks, UploadFile from fastapi import APIRouter, Depends, BackgroundTasks
from fastapi.responses import FileResponse, JSONResponse, StreamingResponse from fastapi.responses import JSONResponse
from markitdown import MarkItDown, StreamInfo
from pydantic import BaseModel, ValidationError
from auth_utils import AuthenticationManager from database.manager import RedisDatabase
from utils.helpers import create_job_from_content, filter_and_paginate, get_document_type_from_filename, get_skill_cache_key, get_requirements_list
from database.manager import RedisDatabase, redis_manager
from logger import logger from logger import logger
from models import ( from models import (
MOCK_UUID, ApiActivityType, ApiMessageType, ApiStatusType, CandidateAI, ChatContextType, ChatMessage, ChatMessageError, ChatMessageRagSearch, ChatMessageResume, ChatMessageSkillAssessment, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatSession, Document, DocumentContentResponse, DocumentListResponse, DocumentMessage, DocumentOptions, DocumentType, DocumentUpdateRequest, Job, JobRequirements, JobRequirementsMessage, LoginRequest, CreateCandidateRequest, CreateEmployerRequest, CreateEmployerRequest
Candidate, Employer, Guest, AuthResponse,
MFARequest, MFAData, MFAVerifyRequest,
EmailVerificationRequest, RAGDocumentRequest, RagContentMetadata, RagContentResponse, ResendVerificationRequest,
MFARequestResponse, MFARequestResponse, Resume, ResumeMessage, SkillAssessment, UserType
) )
from utils.dependencies import ( from utils.dependencies import (
get_current_admin, get_database, get_current_user, get_current_user_or_guest, get_database
create_access_token, verify_token_with_blacklist, prometheus_collector
) )
from utils.responses import create_paginated_response, create_success_response, create_error_response from utils.responses import create_success_response, create_error_response
import utils.llm_proxy as llm_manager
import entities.entity_manager as entities
from email_service import email_service from email_service import email_service
from utils.auth_utils import AuthenticationManager
# Create router for job endpoints # Create router for job endpoints
router = APIRouter(prefix="/employers", tags=["employers"]) router = APIRouter(prefix="/employers", tags=["employers"])

View File

@ -6,35 +6,25 @@ import io
import json import json
import pathlib import pathlib
import re import re
import shutil
import jwt
import secrets
import uuid import uuid
import os from datetime import datetime, UTC
from datetime import datetime, timedelta, timezone, UTC from typing import Any, Dict, Optional
from typing import Any, Dict, List, Optional
from fastapi import APIRouter, File, Form, HTTPException, Depends, Body, Path, Query, Request, BackgroundTasks, UploadFile from fastapi import APIRouter, File, Depends, Body, Path, Query, UploadFile
from fastapi.responses import FileResponse, JSONResponse, StreamingResponse from fastapi.responses import JSONResponse, StreamingResponse
from markitdown import MarkItDown, StreamInfo from markitdown import MarkItDown, StreamInfo
import backstory_traceback as backstory_traceback import backstory_traceback as backstory_traceback
import defines import defines
from agents.generate_resume import GenerateResume
from agents.base import CandidateEntity from agents.base import CandidateEntity
from utils.helpers import create_job_from_content, filter_and_paginate, get_document_type_from_filename, get_skill_cache_key, get_requirements_list from utils.helpers import create_job_from_content, filter_and_paginate, get_document_type_from_filename
from database.manager import RedisDatabase, redis_manager from database.manager import RedisDatabase
from logger import logger from logger import logger
from models import ( from models import (
MOCK_UUID, ApiActivityType, ApiMessageType, ApiStatusType, CandidateAI, ChatContextType, ChatMessage, ChatMessageError, ChatMessageRagSearch, ChatMessageResume, ChatMessageSkillAssessment, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatSession, Document, DocumentContentResponse, DocumentListResponse, DocumentMessage, DocumentOptions, DocumentType, DocumentUpdateRequest, Job, JobRequirements, JobRequirementsMessage, LoginRequest, CreateCandidateRequest, CreateEmployerRequest, MOCK_UUID, ApiActivityType, ApiStatusType, ChatContextType, ChatMessage, ChatMessageError, ChatMessageStatus, DocumentType, Job, JobRequirementsMessage, Candidate, Employer
Candidate, Employer, Guest, AuthResponse,
MFARequest, MFAData, MFAVerifyRequest,
EmailVerificationRequest, RAGDocumentRequest, RagContentMetadata, RagContentResponse, ResendVerificationRequest,
MFARequestResponse, MFARequestResponse, Resume, ResumeMessage, SkillAssessment, UserType
) )
from utils.dependencies import ( from utils.dependencies import (
get_current_admin, get_database, get_current_user, get_current_user_or_guest, get_current_admin, get_database, get_current_user
create_access_token, verify_token_with_blacklist, prometheus_collector
) )
from utils.responses import create_paginated_response, create_success_response, create_error_response from utils.responses import create_paginated_response, create_success_response, create_error_response
import utils.llm_proxy as llm_manager import utils.llm_proxy as llm_manager

View File

@ -2,38 +2,22 @@
Resume Routes Resume Routes
""" """
import json import json
import pathlib from datetime import datetime, UTC
import re from typing import List
import shutil
import jwt
import secrets
import uuid
import os
from datetime import datetime, timedelta, timezone, UTC
from typing import Any, Dict, List, Optional
from fastapi import APIRouter, File, Form, HTTPException, Depends, Body, Path, Query, Request, BackgroundTasks, UploadFile from fastapi import APIRouter, HTTPException, Depends, Body, Path, Query
from fastapi.responses import FileResponse, JSONResponse, StreamingResponse from fastapi.responses import StreamingResponse
from pydantic import BaseModel, ValidationError
import backstory_traceback as backstory_traceback import backstory_traceback as backstory_traceback
from utils.helpers import filter_and_paginate, get_document_type_from_filename, get_skill_cache_key, get_requirements_list from database.manager import RedisDatabase
from database.manager import RedisDatabase, redis_manager
from logger import logger from logger import logger
from models import ( from models import (
MOCK_UUID, ApiActivityType, ApiMessageType, ApiStatusType, CandidateAI, ChatContextType, ChatMessageError, ChatMessageRagSearch, ChatMessageResume, ChatMessageSkillAssessment, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatSession, Document, DocumentContentResponse, DocumentListResponse, DocumentMessage, DocumentOptions, DocumentType, DocumentUpdateRequest, Job, JobRequirements, LoginRequest, CreateCandidateRequest, CreateEmployerRequest, MOCK_UUID, ChatMessageError, Job, Candidate, Resume, ResumeMessage
Candidate, Employer, Guest, AuthResponse,
MFARequest, MFAData, MFAVerifyRequest,
EmailVerificationRequest, RAGDocumentRequest, RagContentMetadata, RagContentResponse, ResendVerificationRequest,
MFARequestResponse, MFARequestResponse, Resume, ResumeMessage, SkillAssessment, UserType
) )
from utils.dependencies import ( from utils.dependencies import (
get_current_admin, get_database, get_current_user, get_current_user_or_guest, get_database, get_current_user
create_access_token, verify_token_with_blacklist, prometheus_collector
) )
from utils.responses import create_paginated_response, create_success_response, create_error_response from utils.responses import create_success_response
import utils.llm_proxy as llm_manager
from utils.rate_limiter import get_rate_limiter
# Create router for authentication endpoints # Create router for authentication endpoints
router = APIRouter(prefix="/resumes", tags=["resumes"]) router = APIRouter(prefix="/resumes", tags=["resumes"])

View File

@ -1,39 +1,11 @@
""" """
Health/system routes Health/system routes
""" """
import json
from datetime import datetime, UTC
from fastapi import APIRouter, Depends, Body, HTTPException, Path, Request from fastapi import APIRouter, Depends, HTTPException, Request
from fastapi.responses import JSONResponse
from pydantic import BaseModel, EmailStr, ValidationError, field_validator
from auth_utils import AuthenticationManager, SecurityConfig from database.manager import redis_manager, Redis
import backstory_traceback as backstory_traceback from utils.responses import create_success_response
from utils.rate_limiter import RateLimiter
from database.manager import RedisDatabase, redis_manager, Redis
from device_manager import DeviceManager
from email_service import VerificationEmailRateLimiter, email_service
from logger import logger
from models import (
LoginRequest, CreateCandidateRequest, CreateEmployerRequest,
Candidate, Employer, Guest, AuthResponse,
MFARequest, MFAData, MFAVerifyRequest,
EmailVerificationRequest, ResendVerificationRequest,
MFARequestResponse, MFARequestResponse
)
from utils.dependencies import (
get_current_admin, get_database, get_current_user, get_current_user_or_guest,
create_access_token, verify_token_with_blacklist
)
from utils.responses import create_success_response, create_error_response
from utils.rate_limiter import get_rate_limiter
from auth_utils import (
AuthenticationManager,
validate_password_strength,
sanitize_login_input,
SecurityConfig
)
# Create router for authentication endpoints # Create router for authentication endpoints
router = APIRouter(prefix="/system", tags=["system"]) router = APIRouter(prefix="/system", tags=["system"])

View File

@ -1,38 +1,19 @@
""" """
Job Routes Job Routes
""" """
import io
import json
import pathlib
import re
import shutil
import jwt
import secrets
import uuid
import os
from datetime import datetime, timedelta, timezone, UTC
from typing import Any, Dict, List, Optional
from fastapi import APIRouter, File, Form, HTTPException, Depends, Body, Path, Query, Request, BackgroundTasks, UploadFile from fastapi import APIRouter, Depends, Path
from fastapi.responses import FileResponse, JSONResponse, StreamingResponse from fastapi.responses import JSONResponse
from database.manager import RedisDatabase, redis_manager from database.manager import RedisDatabase
from device_manager import DeviceManager
from email_service import VerificationEmailRateLimiter, email_service
from logger import logger from logger import logger
from models import ( from models import (
MOCK_UUID, ApiActivityType, ApiMessageType, ApiStatusType, BaseUserWithType, CandidateAI, ChatContextType, ChatMessageError, ChatMessageRagSearch, ChatMessageResume, ChatMessageSkillAssessment, ChatMessageStatus, ChatMessageStreaming, ChatMessageUser, ChatSession, Document, DocumentContentResponse, DocumentListResponse, DocumentMessage, DocumentOptions, DocumentType, DocumentUpdateRequest, Job, JobRequirements, LoginRequest, CreateCandidateRequest, CreateEmployerRequest, BaseUserWithType
Candidate, Employer, Guest, AuthResponse,
MFARequest, MFAData, MFAVerifyRequest,
EmailVerificationRequest, RAGDocumentRequest, RagContentMetadata, RagContentResponse, ResendVerificationRequest,
MFARequestResponse, MFARequestResponse, Resume, ResumeMessage, SkillAssessment, UserType
) )
from utils.dependencies import ( from utils.dependencies import (
get_current_admin, get_database, get_current_user, get_current_user_or_guest, get_database
create_access_token, verify_token_with_blacklist, prometheus_collector
) )
from utils.rate_limiter import get_rate_limiter from utils.responses import create_success_response, create_error_response
from utils.responses import create_paginated_response, create_success_response, create_error_response
# Create router for job endpoints # Create router for job endpoints
router = APIRouter(prefix="/users", tags=["users"]) router = APIRouter(prefix="/users", tags=["users"])

View File

@ -1,11 +1,10 @@
import os import os
from pydantic import BaseModel, Field, model_validator from pydantic import BaseModel
from typing import List, Optional, Generator, ClassVar, Any, Dict from typing import List, Optional, Any, Dict
from datetime import datetime from datetime import datetime
from typing import ( from typing import (
Any, Any,
) )
from typing_extensions import Annotated
from bs4 import BeautifulSoup from bs4 import BeautifulSoup

View File

@ -1,54 +1,3 @@
""" """
Utils package - Utility functions and dependencies Utils package - Utility functions and dependencies
""" """
# Import commonly used utilities for easy access
from .dependencies import (
get_database,
get_current_user,
get_current_user_or_guest,
get_current_admin,
create_access_token,
verify_token_with_blacklist
)
from .responses import (
create_success_response,
create_error_response,
create_paginated_response
)
from .helpers import (
filter_and_paginate,
stream_agent_response,
get_candidate_files_dir,
get_document_type_from_filename,
get_skill_cache_key
)
from .rate_limiter import (
get_rate_limiter
)
__all__ = [
# Dependencies
"get_database",
"get_current_user",
"get_current_user_or_guest",
"get_current_admin",
"get_rate_limiter",
"create_access_token",
"verify_token_with_blacklist",
# Responses
"create_success_response",
"create_error_response",
"create_paginated_response",
# Helpers
"filter_and_paginate",
"stream_agent_response",
"get_candidate_files_dir",
"get_document_type_from_filename",
"get_skill_cache_key"
]

View File

@ -3,7 +3,7 @@
Secure Authentication Utilities Secure Authentication Utilities
Provides password hashing, verification, and security features Provides password hashing, verification, and security features
""" """
from __future__ import annotations
import traceback import traceback
import bcrypt import bcrypt
import secrets import secrets

View File

@ -4,7 +4,7 @@ Shared dependencies for FastAPI routes
from __future__ import annotations from __future__ import annotations
import jwt import jwt
import os import os
from datetime import datetime, timedelta, timezone, UTC from datetime import datetime, timedelta, UTC
from typing import Optional from typing import Optional
from fastapi import HTTPException, Depends from fastapi import HTTPException, Depends

View File

@ -4,7 +4,6 @@ Helper functions shared across routes
import asyncio import asyncio
import hashlib import hashlib
import json import json
import os
import pathlib import pathlib
from datetime import datetime, UTC from datetime import datetime, UTC
from typing import Any, Dict, List, Optional, Tuple from typing import Any, Dict, List, Optional, Tuple
@ -108,7 +107,6 @@ async def stream_agent_response(chat_agent, user_message, chat_session_data=None
final_message = None final_message = None
import utils.llm_proxy as llm_manager import utils.llm_proxy as llm_manager
import agents
async for generated_message in chat_agent.generate( async for generated_message in chat_agent.generate(
llm=llm_manager.get_llm(), llm=llm_manager.get_llm(),
@ -203,7 +201,7 @@ def get_skill_cache_key(candidate_id: str, skill: str) -> str:
async def reformat_as_markdown(database, candidate_entity, content: str): async def reformat_as_markdown(database, candidate_entity, content: str):
"""Reformat content as markdown using AI agent""" """Reformat content as markdown using AI agent"""
from models import ChatContextType, MOCK_UUID, ApiStatusType, ChatMessageError, ChatMessageStatus, ApiActivityType, ChatMessage from models import ChatContextType, MOCK_UUID, ChatMessageError, ChatMessageStatus, ApiActivityType, ChatMessage
import utils.llm_proxy as llm_manager import utils.llm_proxy as llm_manager
chat_agent = candidate_entity.get_or_create_agent(agent_type=ChatContextType.JOB_REQUIREMENTS) chat_agent = candidate_entity.get_or_create_agent(agent_type=ChatContextType.JOB_REQUIREMENTS)

View File

@ -3,7 +3,6 @@ from typing import Dict, List, Any, AsyncGenerator, Optional, Union
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from enum import Enum from enum import Enum
import asyncio import asyncio
import json
from dataclasses import dataclass from dataclasses import dataclass
import os import os
import defines import defines
@ -145,7 +144,6 @@ class BaseLLMAdapter(ABC):
**kwargs **kwargs
) -> Union[ChatResponse, AsyncGenerator[ChatResponse, None]]: ) -> Union[ChatResponse, AsyncGenerator[ChatResponse, None]]:
"""Send chat messages and get response""" """Send chat messages and get response"""
pass
@abstractmethod @abstractmethod
async def generate( async def generate(
@ -156,7 +154,6 @@ class BaseLLMAdapter(ABC):
**kwargs **kwargs
) -> Union[ChatResponse, AsyncGenerator[ChatResponse, None]]: ) -> Union[ChatResponse, AsyncGenerator[ChatResponse, None]]:
"""Generate text from prompt""" """Generate text from prompt"""
pass
@abstractmethod @abstractmethod
async def embeddings( async def embeddings(
@ -166,12 +163,10 @@ class BaseLLMAdapter(ABC):
**kwargs **kwargs
) -> EmbeddingResponse: ) -> EmbeddingResponse:
"""Generate embeddings for input text(s)""" """Generate embeddings for input text(s)"""
pass
@abstractmethod @abstractmethod
async def list_models(self) -> List[str]: async def list_models(self) -> List[str]:
"""List available models""" """List available models"""
pass
class OllamaAdapter(BaseLLMAdapter): class OllamaAdapter(BaseLLMAdapter):
"""Adapter for Ollama with enhanced statistics""" """Adapter for Ollama with enhanced statistics"""

View File

@ -3,10 +3,8 @@ Rate limiting utilities for guest and authenticated users
""" """
from __future__ import annotations from __future__ import annotations
from functools import wraps from functools import wraps
import json
import time
from datetime import datetime, timedelta, UTC from datetime import datetime, timedelta, UTC
from typing import Callable, Dict, Optional, Tuple, Any from typing import Callable, Dict, Optional, Any
from fastapi import Depends, HTTPException, Request from fastapi import Depends, HTTPException, Request
from pydantic import BaseModel # type: ignore from pydantic import BaseModel # type: ignore
from database.manager import RedisDatabase from database.manager import RedisDatabase