MukeshKapoor25 commited on
Commit
851444b
·
1 Parent(s): 7611990

feat(config): Implement centralized configuration management system

Browse files

- Add comprehensive configuration management with `config.py`
- Create centralized settings loader using Pydantic and environment variables
- Migrate existing environment variable usage to new configuration system
- Add `README.md` to explain configuration management approach
- Update health check and CORS middleware to use centralized settings
- Enhance database URI builder with robust connection string generation
- Improve security by centralizing configuration and validation
- Remove hardcoded environment variable access in favor of settings object
Rationale: Standardize configuration management, improve type safety, and provide a more robust approach to handling environment-specific settings across the application.

.env CHANGED
@@ -1,15 +1,35 @@
1
- #MONGO_URI=mongodb+srv://appliedcommerce:xaqtoj-gikdaw-6giQdy@cluster0.qpc5d.mongodb.net/test??ssl=true&ssl_cert_reqs=CERT_NONE
2
-
3
  MONGO_URI=mongodb+srv://insightfy:k0KXafAbV8A8NmQK@cluster0.2shrc.mongodb.net/test??ssl=true&ssl_cert_reqs=CERT_NONE
4
 
5
  DB_NAME=book-my-service
6
 
7
  DATABASE_URI=postgresql+asyncpg://trans_owner:BookMyService7@ep-sweet-surf-a1qeduoy.ap-southeast-1.aws.neon.tech/bookmyservice?options=-csearch_path%3Dtrans
8
 
9
-
10
-
11
  CACHE_URI=redis-11382.c305.ap-south-1-1.ec2.redns.redis-cloud.com:11382
12
 
13
  #CACHE_URI=redis-11521.crce182.ap-south-1-1.ec2.redns.redis-cloud.com:11521
14
 
15
  CACHE_K=dLRZrhU1d5EP9N1CW6grUgsj7MyWIj2i
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  MONGO_URI=mongodb+srv://insightfy:k0KXafAbV8A8NmQK@cluster0.2shrc.mongodb.net/test??ssl=true&ssl_cert_reqs=CERT_NONE
2
 
3
  DB_NAME=book-my-service
4
 
5
  DATABASE_URI=postgresql+asyncpg://trans_owner:BookMyService7@ep-sweet-surf-a1qeduoy.ap-southeast-1.aws.neon.tech/bookmyservice?options=-csearch_path%3Dtrans
6
 
 
 
7
  CACHE_URI=redis-11382.c305.ap-south-1-1.ec2.redns.redis-cloud.com:11382
8
 
9
  #CACHE_URI=redis-11521.crce182.ap-south-1-1.ec2.redns.redis-cloud.com:11521
10
 
11
  CACHE_K=dLRZrhU1d5EP9N1CW6grUgsj7MyWIj2i
12
+
13
+
14
+ RAZORPAY_KEY_ID=rzp_test_2UTAol2AFSV5VN
15
+
16
+ RAZORPAY_KEY_SECRET=elb4JNjUw3eLqhVMiLFiRgki
17
+
18
+ # JWT Configuration
19
+ JWT_SECRET_KEY=2c3f5a7b9e1d4f6c8a2b5e7d9c1f3a5b7e9d2c4f6a8b0c1e3f5a7b9d1c3f5e7
20
+
21
+ JWT_ALGORITHM=HS256
22
+ JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
23
+
24
+ # Security Configuration
25
+ ALLOWED_HOSTS=localhost,127.0.0.1,bookmyservice.tech
26
+ CORS_ORIGINS=http://localhost:3000,http://127.0.0.1:3000,https://bookmyservice.tech
27
+
28
+ # Rate Limiting Configuration
29
+ RATE_LIMIT_CALLS=100
30
+ RATE_LIMIT_PERIOD=60
31
+
32
+ # Cache Key Prefixes (Optional - defaults provided)
33
+ CART_KEY_PREFIX=CA
34
+ ORDER_KEY_PREFIX=OR
35
+ APPOINTMENTS_KEY_PREFIX=AP
.gitignore CHANGED
@@ -59,3 +59,4 @@ coverage.xml
59
  *.cover
60
  .hypothesis/
61
  .pytest_cache/
 
 
59
  *.cover
60
  .hypothesis/
61
  .pytest_cache/
62
+ .env
app/api/health.py CHANGED
@@ -8,6 +8,7 @@ import logging
8
  from datetime import datetime
9
 
10
  from app.nosql import check_mongodb_health, check_redis_health
 
11
 
12
  logger = logging.getLogger(__name__)
13
  router = APIRouter()
@@ -121,7 +122,7 @@ async def detailed_status() -> Dict[str, Any]:
121
  "service": {
122
  "name": "merchant-api",
123
  "version": "1.0.0",
124
- "environment": os.getenv("ENVIRONMENT", "unknown"),
125
  "uptime_seconds": psutil.Process().create_time()
126
  },
127
  "databases": {
@@ -148,7 +149,7 @@ async def detailed_status() -> Dict[str, Any]:
148
  "service": {
149
  "name": "merchant-api",
150
  "version": "1.0.0",
151
- "environment": os.getenv("ENVIRONMENT", "unknown")
152
  },
153
  "databases": {
154
  "mongodb": {
 
8
  from datetime import datetime
9
 
10
  from app.nosql import check_mongodb_health, check_redis_health
11
+ from app.config.config import settings
12
 
13
  logger = logging.getLogger(__name__)
14
  router = APIRouter()
 
122
  "service": {
123
  "name": "merchant-api",
124
  "version": "1.0.0",
125
+ "environment": settings.ENVIRONMENT,
126
  "uptime_seconds": psutil.Process().create_time()
127
  },
128
  "databases": {
 
149
  "service": {
150
  "name": "merchant-api",
151
  "version": "1.0.0",
152
+ "environment": settings.ENVIRONMENT
153
  },
154
  "databases": {
155
  "mongodb": {
app/app.py CHANGED
@@ -34,11 +34,12 @@ app = FastAPI(
34
  # max_request_size=10 * 1024 * 1024 # 10MB limit
35
  # )
36
 
37
- # CORS configuration - FIXED: Use specific domains in production
38
- allowed_origins = os.getenv("ALLOWED_ORIGINS", "http://localhost:3000,http://localhost:8000").split(",")
 
39
  app.add_middleware(
40
  CORSMiddleware,
41
- allow_origins=allowed_origins, # Use environment variable for allowed origins
42
  allow_credentials=True,
43
  allow_methods=["GET", "POST", "PUT", "DELETE"], # Specific methods only
44
  allow_headers=["Content-Type", "Authorization", "X-CSRF-Token"], # Specific headers only
 
34
  # max_request_size=10 * 1024 * 1024 # 10MB limit
35
  # )
36
 
37
+ # CORS configuration using centralized settings
38
+ from app.config.config import settings
39
+
40
  app.add_middleware(
41
  CORSMiddleware,
42
+ allow_origins=settings.CORS_ORIGINS, # Use centralized configuration
43
  allow_credentials=True,
44
  allow_methods=["GET", "POST", "PUT", "DELETE"], # Specific methods only
45
  allow_headers=["Content-Type", "Authorization", "X-CSRF-Token"], # Specific headers only
app/config/README.md ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Configuration Management
2
+
3
+ This directory contains the centralized configuration management for the MHS service, following the same pattern as the AMS service.
4
+
5
+ ## Files
6
+
7
+ - `config.py` - Main configuration file with centralized settings
8
+ - `security_config.py` - Security-specific configuration
9
+ - `nlp_config.py` - NLP-specific configuration
10
+
11
+ ## Usage
12
+
13
+ ### Basic Usage
14
+
15
+ ```python
16
+ from app.config.config import settings
17
+
18
+ # Database settings
19
+ mongo_uri = settings.MONGO_URI
20
+ db_name = settings.DB_NAME
21
+
22
+ # Cache settings
23
+ cache_uri = settings.CACHE_URI
24
+ cache_key = settings.CACHE_K
25
+
26
+ # JWT settings
27
+ jwt_secret = settings.JWT_SECRET_KEY
28
+ jwt_algorithm = settings.JWT_ALGORITHM
29
+
30
+ # Generate cache keys
31
+ cart_key = settings.get_cache_key("cart", user_id, "items")
32
+ order_key = settings.get_cache_key("order", order_id)
33
+ ```
34
+
35
+ ### Configuration Validation
36
+
37
+ ```python
38
+ from app.config.config import validate_configuration
39
+
40
+ # Validate configuration on startup
41
+ try:
42
+ validate_configuration()
43
+ print("✅ Configuration is valid")
44
+ except ValueError as e:
45
+ print(f"❌ Configuration error: {e}")
46
+ ```
47
+
48
+ ### Environment Variables
49
+
50
+ All configuration is loaded from environment variables with sensible defaults. Key variables include:
51
+
52
+ - `MONGO_URI` - MongoDB connection string
53
+ - `DATABASE_URI` - PostgreSQL connection string
54
+ - `CACHE_URI` - Redis connection string
55
+ - `CACHE_K` - Redis password
56
+ - `JWT_SECRET_KEY` - JWT signing secret
57
+ - `RAZORPAY_KEY_ID` - Payment gateway key
58
+ - `RAZORPAY_KEY_SECRET` - Payment gateway secret
59
+ - `CORS_ORIGINS` - Allowed CORS origins
60
+ - `ALLOWED_HOSTS` - Allowed hosts
61
+
62
+ ## Migration from Direct os.getenv()
63
+
64
+ Instead of:
65
+ ```python
66
+ import os
67
+ mongo_uri = os.getenv("MONGO_URI")
68
+ ```
69
+
70
+ Use:
71
+ ```python
72
+ from app.config.config import settings
73
+ mongo_uri = settings.MONGO_URI
74
+ ```
75
+
76
+ This provides:
77
+ - Type safety
78
+ - Default values
79
+ - Validation
80
+ - Centralized configuration
81
+ - Better error handling
app/config/config.py ADDED
@@ -0,0 +1,202 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from typing import Optional, Dict
3
+ from urllib.parse import quote_plus
4
+ from dotenv import load_dotenv
5
+
6
+ # Load environment variables early so URI builder sees them
7
+ load_dotenv()
8
+
9
+
10
+ def build_database_uri(env: Dict[str, str] = os.environ) -> str:
11
+ """
12
+ Assemble a SQLAlchemy/asyncpg URI from separate env vars.
13
+ Supports:
14
+ - URL-encoding for user/password
15
+ - Default schema via ?options=-csearch_path=<schema>
16
+ - sslmode=require (e.g., Neon)
17
+ Honors DATABASE_URI if set (escape hatch/override).
18
+ """
19
+
20
+ # If already provided as a single secret, honor it and return immediately.
21
+ env = env or os.environ
22
+ direct_uri = env.get("DATABASE_URI") or env.get("DATABASE_URL")
23
+ if direct_uri:
24
+ return direct_uri
25
+
26
+ protocol = env.get("DB_PROTOCOL") or "postgresql+asyncpg"
27
+ user = env.get("DB_USER")
28
+ password = env.get("DB_PASSWORD")
29
+ host = env.get("DB_HOST") or "localhost"
30
+ port = env.get("DB_PORT") or "5432"
31
+ dbname = env.get("DB_NAME")
32
+
33
+ missing = [k for k, v in {"DB_USER": user, "DB_PASSWORD": password, "DB_NAME": dbname}.items() if not v]
34
+ if missing:
35
+ raise ValueError(f"Missing required environment variables: {', '.join(missing)}")
36
+
37
+ # Optional extras
38
+ schema = env.get("DB_SCHEMA") # e.g., "trans"
39
+ # sslmode is not supported in asyncpg URI; SSL must be set programmatically if needed
40
+
41
+ # Build query params if schema provided
42
+ q = f"?options=-csearch_path={schema}" if schema else ""
43
+
44
+ # URL-encode credentials so special characters don't break the URI
45
+ user_enc = quote_plus(user)
46
+ password_enc = quote_plus(password)
47
+
48
+ return f"{protocol}://{user_enc}:{password_enc}@{host}:{port}/{dbname}{q}"
49
+
50
+
51
+ # Single source of truth exported both ways for compatibility
52
+ DATABASE_URI: str = build_database_uri()
53
+ DATABASE_URL: str = DATABASE_URI
54
+
55
+
56
+ class Settings:
57
+ """Application configuration settings"""
58
+
59
+ # Database settings
60
+ DATABASE_URL: str = DATABASE_URL
61
+ MONGO_URI: str = os.getenv("MONGO_URI", "")
62
+ DB_NAME: str = os.getenv("DB_NAME", "book-my-service")
63
+
64
+ # Redis/Cache settings
65
+ CACHE_URI: str = os.getenv("CACHE_URI", "redis://localhost:6379")
66
+ CACHE_K: str = os.getenv("CACHE_K", "")
67
+
68
+ # Cache key prefixes (configurable via environment variables)
69
+ CART_KEY_PREFIX: str = os.getenv("CART_KEY_PREFIX", "cart")
70
+ ORDER_KEY_PREFIX: str = os.getenv("ORDER_KEY_PREFIX", "order")
71
+ APPOINTMENTS_KEY_PREFIX: str = os.getenv("APPOINTMENTS_KEY_PREFIX", "appointments")
72
+
73
+ # Payment settings
74
+ RAZORPAY_KEY_ID: str = os.getenv("RAZORPAY_KEY_ID", "")
75
+ RAZORPAY_KEY_SECRET: str = os.getenv("RAZORPAY_KEY_SECRET", "")
76
+
77
+ # JWT settings
78
+ # Prefer MHS-specific envs; gracefully fall back to UMS-compatible names
79
+ JWT_SECRET_KEY: str = os.getenv("JWT_SECRET_KEY") or os.getenv("SECRET_KEY")
80
+ JWT_ALGORITHM: str = os.getenv("JWT_ALGORITHM") or os.getenv("ALGORITHM", "HS256")
81
+ JWT_ACCESS_TOKEN_EXPIRE_MINUTES: int = int(
82
+ os.getenv("JWT_ACCESS_TOKEN_EXPIRE_MINUTES", os.getenv("ACCESS_TOKEN_EXPIRE_MINUTES", "30"))
83
+ )
84
+
85
+ # Security settings
86
+ # Include Hugging Face Spaces by default to avoid 400s behind their proxy.
87
+ # Override via ALLOWED_HOSTS env var in production as needed.
88
+ ALLOWED_HOSTS: list = os.getenv(
89
+ "ALLOWED_HOSTS",
90
+ "localhost,127.0.0.1,*.hf.space,bmsmhs-bookmyservice-mhs.hf.space"
91
+ ).split(",")
92
+ CORS_ORIGINS: list = os.getenv(
93
+ "CORS_ORIGINS",
94
+ "http://localhost:3000,http://127.0.0.1:3000"
95
+ ).split(",")
96
+
97
+ # Rate limiting
98
+ RATE_LIMIT_CALLS: int = int(os.getenv("RATE_LIMIT_CALLS", "100"))
99
+ RATE_LIMIT_PERIOD: int = int(os.getenv("RATE_LIMIT_PERIOD", "60"))
100
+
101
+ # NLP Configuration
102
+ SPACY_MODEL: str = os.getenv("SPACY_MODEL", "en_core_web_sm")
103
+ SENTENCE_TRANSFORMER_MODEL: str = os.getenv("SENTENCE_TRANSFORMER_MODEL", "all-MiniLM-L6-v2")
104
+ ENABLE_ADVANCED_NLP: bool = os.getenv("ENABLE_ADVANCED_NLP", "true").lower() == "true"
105
+ ENABLE_SEMANTIC_MATCHING: bool = os.getenv("ENABLE_SEMANTIC_MATCHING", "true").lower() == "true"
106
+ ENABLE_CONTEXT_PROCESSING: bool = os.getenv("ENABLE_CONTEXT_PROCESSING", "true").lower() == "true"
107
+ ENABLE_INTENT_CLASSIFICATION: bool = os.getenv("ENABLE_INTENT_CLASSIFICATION", "true").lower() == "true"
108
+ SEMANTIC_SIMILARITY_THRESHOLD: float = float(os.getenv("SEMANTIC_SIMILARITY_THRESHOLD", "0.6"))
109
+
110
+ # Performance settings
111
+ ASYNC_PROCESSOR_MAX_WORKERS: int = int(os.getenv("ASYNC_PROCESSOR_MAX_WORKERS", "4"))
112
+ CACHE_DURATION_SECONDS: int = int(os.getenv("CACHE_DURATION_SECONDS", "3600"))
113
+
114
+ # Business settings
115
+ DEFAULT_SEARCH_RADIUS_METERS: int = int(os.getenv("DEFAULT_SEARCH_RADIUS_METERS", "5000"))
116
+ MAX_ENTITY_MATCHES: int = int(os.getenv("MAX_ENTITY_MATCHES", "10"))
117
+ MAX_SEMANTIC_MATCHES: int = int(os.getenv("MAX_SEMANTIC_MATCHES", "5"))
118
+
119
+ # Security settings
120
+ MAX_REQUEST_SIZE: int = int(os.getenv("MAX_REQUEST_SIZE", "10485760")) # 10MB
121
+ MAX_STRING_LENGTH: int = int(os.getenv("MAX_STRING_LENGTH", "1000"))
122
+ MAX_LIST_ITEMS: int = int(os.getenv("MAX_LIST_ITEMS", "100"))
123
+ RATE_LIMIT_REQUESTS_PER_MINUTE: int = int(os.getenv("RATE_LIMIT_RPM", "60"))
124
+ RATE_LIMIT_BURST: int = int(os.getenv("RATE_LIMIT_BURST", "10"))
125
+
126
+ # Logging settings
127
+ LOG_SANITIZATION_ENABLED: bool = os.getenv("LOG_SANITIZATION_ENABLED", "true").lower() == "true"
128
+ MAX_LOG_VALUE_LENGTH: int = int(os.getenv("MAX_LOG_VALUE_LENGTH", "500"))
129
+ NLP_LOG_LEVEL: str = os.getenv("NLP_LOG_LEVEL", "INFO")
130
+ ENABLE_PERFORMANCE_LOGGING: bool = os.getenv("ENABLE_PERFORMANCE_LOGGING", "true").lower() == "true"
131
+
132
+ # Environment
133
+ ENVIRONMENT: str = os.getenv("ENVIRONMENT", "development")
134
+
135
+ @classmethod
136
+ def get_cache_key(cls, key_type: str, *args) -> str:
137
+ """
138
+ Generate cache keys using configurable prefixes
139
+
140
+ Args:
141
+ key_type: Type of cache key (cart, order, appointments)
142
+ *args: Additional arguments to include in the key
143
+
144
+ Returns:
145
+ str: Formatted cache key
146
+ """
147
+ if key_type == "cart":
148
+ return f"{cls.CART_KEY_PREFIX}:{':'.join(map(str, args))}"
149
+ elif key_type == "order":
150
+ return f"{cls.ORDER_KEY_PREFIX}:{':'.join(map(str, args))}"
151
+ elif key_type == "appointments":
152
+ return f"{cls.APPOINTMENTS_KEY_PREFIX}:{':'.join(map(str, args))}"
153
+ else:
154
+ raise ValueError(f"Unknown cache key type: {key_type}")
155
+
156
+ @classmethod
157
+ def validate_required_settings(cls) -> Dict[str, bool]:
158
+ """
159
+ Validate that required settings are present
160
+
161
+ Returns:
162
+ Dict with validation results
163
+ """
164
+ validations = {
165
+ "mongo_uri": bool(cls.MONGO_URI),
166
+ "db_name": bool(cls.DB_NAME),
167
+ "cache_uri": bool(cls.CACHE_URI),
168
+ "cache_key": bool(cls.CACHE_K),
169
+ "jwt_secret": bool(cls.JWT_SECRET_KEY)
170
+ }
171
+
172
+ return validations
173
+
174
+ @classmethod
175
+ def get_missing_settings(cls) -> list:
176
+ """
177
+ Get list of missing required settings
178
+
179
+ Returns:
180
+ List of missing setting names
181
+ """
182
+ validations = cls.validate_required_settings()
183
+ return [setting for setting, is_valid in validations.items() if not is_valid]
184
+
185
+
186
+ # Global settings instance
187
+ settings = Settings()
188
+
189
+
190
+ def validate_configuration():
191
+ """
192
+ Validate configuration on startup
193
+
194
+ Raises:
195
+ ValueError: If required configuration is missing
196
+ """
197
+ missing = settings.get_missing_settings()
198
+ if missing:
199
+ raise ValueError(f"Missing required configuration: {', '.join(missing)}")
200
+
201
+ print("✅ Configuration validation passed")
202
+ return True
app/config/nlp_config.py CHANGED
@@ -8,29 +8,32 @@ from typing import Dict, Any
8
  class NLPConfig:
9
  """Configuration class for NLP pipeline settings"""
10
 
 
 
 
11
  # Model settings
12
- SPACY_MODEL = os.getenv("SPACY_MODEL", "en_core_web_sm")
13
- SENTENCE_TRANSFORMER_MODEL = os.getenv("SENTENCE_TRANSFORMER_MODEL", "all-MiniLM-L6-v2")
14
 
15
  # Performance settings
16
- ASYNC_PROCESSOR_MAX_WORKERS = int(os.getenv("ASYNC_PROCESSOR_MAX_WORKERS", "4"))
17
- CACHE_DURATION_SECONDS = int(os.getenv("CACHE_DURATION_SECONDS", "3600")) # 1 hour
18
- SEMANTIC_SIMILARITY_THRESHOLD = float(os.getenv("SEMANTIC_SIMILARITY_THRESHOLD", "0.6"))
19
 
20
  # Feature flags
21
- ENABLE_ADVANCED_NLP = os.getenv("ENABLE_ADVANCED_NLP", "true").lower() == "true"
22
- ENABLE_SEMANTIC_MATCHING = os.getenv("ENABLE_SEMANTIC_MATCHING", "true").lower() == "true"
23
- ENABLE_CONTEXT_PROCESSING = os.getenv("ENABLE_CONTEXT_PROCESSING", "true").lower() == "true"
24
- ENABLE_INTENT_CLASSIFICATION = os.getenv("ENABLE_INTENT_CLASSIFICATION", "true").lower() == "true"
25
 
26
  # Logging settings
27
- NLP_LOG_LEVEL = os.getenv("NLP_LOG_LEVEL", "INFO")
28
- ENABLE_PERFORMANCE_LOGGING = os.getenv("ENABLE_PERFORMANCE_LOGGING", "true").lower() == "true"
29
 
30
- # Business-specific settings
31
- DEFAULT_SEARCH_RADIUS_METERS = int(os.getenv("DEFAULT_SEARCH_RADIUS_METERS", "5000"))
32
- MAX_ENTITY_MATCHES = int(os.getenv("MAX_ENTITY_MATCHES", "10"))
33
- MAX_SEMANTIC_MATCHES = int(os.getenv("MAX_SEMANTIC_MATCHES", "5"))
34
 
35
  # Service category mappings
36
  SERVICE_CATEGORY_MAPPINGS = {
 
8
  class NLPConfig:
9
  """Configuration class for NLP pipeline settings"""
10
 
11
+ # Import from centralized config
12
+ from app.config.config import settings
13
+
14
  # Model settings
15
+ SPACY_MODEL = settings.SPACY_MODEL
16
+ SENTENCE_TRANSFORMER_MODEL = settings.SENTENCE_TRANSFORMER_MODEL
17
 
18
  # Performance settings
19
+ ASYNC_PROCESSOR_MAX_WORKERS = settings.ASYNC_PROCESSOR_MAX_WORKERS
20
+ CACHE_DURATION_SECONDS = settings.CACHE_DURATION_SECONDS
21
+ SEMANTIC_SIMILARITY_THRESHOLD = settings.SEMANTIC_SIMILARITY_THRESHOLD
22
 
23
  # Feature flags
24
+ ENABLE_ADVANCED_NLP = settings.ENABLE_ADVANCED_NLP
25
+ ENABLE_SEMANTIC_MATCHING = settings.ENABLE_SEMANTIC_MATCHING
26
+ ENABLE_CONTEXT_PROCESSING = settings.ENABLE_CONTEXT_PROCESSING
27
+ ENABLE_INTENT_CLASSIFICATION = settings.ENABLE_INTENT_CLASSIFICATION
28
 
29
  # Logging settings
30
+ NLP_LOG_LEVEL = settings.NLP_LOG_LEVEL
31
+ ENABLE_PERFORMANCE_LOGGING = settings.ENABLE_PERFORMANCE_LOGGING
32
 
33
+ # Business-specific settings - Use centralized config
34
+ DEFAULT_SEARCH_RADIUS_METERS = settings.DEFAULT_SEARCH_RADIUS_METERS
35
+ MAX_ENTITY_MATCHES = settings.MAX_ENTITY_MATCHES
36
+ MAX_SEMANTIC_MATCHES = settings.MAX_SEMANTIC_MATCHES
37
 
38
  # Service category mappings
39
  SERVICE_CATEGORY_MAPPINGS = {
app/config/security_config.py CHANGED
@@ -8,17 +8,18 @@ from typing import List, Dict, Any
8
  class SecurityConfig:
9
  """Security configuration class"""
10
 
11
- # Input validation settings
12
- MAX_REQUEST_SIZE = int(os.getenv("MAX_REQUEST_SIZE", "10485760")) # 10MB
13
- MAX_STRING_LENGTH = int(os.getenv("MAX_STRING_LENGTH", "1000"))
14
- MAX_LIST_ITEMS = int(os.getenv("MAX_LIST_ITEMS", "100"))
15
 
16
  # Rate limiting settings
17
- RATE_LIMIT_REQUESTS_PER_MINUTE = int(os.getenv("RATE_LIMIT_RPM", "60"))
18
- RATE_LIMIT_BURST = int(os.getenv("RATE_LIMIT_BURST", "10"))
19
 
20
- # CORS settings
21
- ALLOWED_ORIGINS = os.getenv("ALLOWED_ORIGINS", "http://localhost:3000").split(",")
 
22
  ALLOWED_METHODS = ["GET", "POST", "PUT", "DELETE"]
23
  ALLOWED_HEADERS = ["Content-Type", "Authorization", "X-CSRF-Token"]
24
 
@@ -70,8 +71,8 @@ class SecurityConfig:
70
  }
71
 
72
  # Logging configuration
73
- LOG_SANITIZATION_ENABLED = os.getenv("LOG_SANITIZATION_ENABLED", "true").lower() == "true"
74
- MAX_LOG_VALUE_LENGTH = int(os.getenv("MAX_LOG_VALUE_LENGTH", "500"))
75
 
76
  @classmethod
77
  def get_rate_limit(cls, endpoint: str) -> int:
 
8
  class SecurityConfig:
9
  """Security configuration class"""
10
 
11
+ # Input validation settings - Use centralized config
12
+ MAX_REQUEST_SIZE = settings.MAX_REQUEST_SIZE
13
+ MAX_STRING_LENGTH = settings.MAX_STRING_LENGTH
14
+ MAX_LIST_ITEMS = settings.MAX_LIST_ITEMS
15
 
16
  # Rate limiting settings
17
+ RATE_LIMIT_REQUESTS_PER_MINUTE = settings.RATE_LIMIT_REQUESTS_PER_MINUTE
18
+ RATE_LIMIT_BURST = settings.RATE_LIMIT_BURST
19
 
20
+ # CORS settings - Import from centralized config
21
+ from app.config.config import settings
22
+ ALLOWED_ORIGINS = settings.CORS_ORIGINS
23
  ALLOWED_METHODS = ["GET", "POST", "PUT", "DELETE"]
24
  ALLOWED_HEADERS = ["Content-Type", "Authorization", "X-CSRF-Token"]
25
 
 
71
  }
72
 
73
  # Logging configuration
74
+ LOG_SANITIZATION_ENABLED = settings.LOG_SANITIZATION_ENABLED
75
+ MAX_LOG_VALUE_LENGTH = settings.MAX_LOG_VALUE_LENGTH
76
 
77
  @classmethod
78
  def get_rate_limit(cls, endpoint: str) -> int:
app/nosql.py CHANGED
@@ -5,6 +5,7 @@ from redis.exceptions import RedisError
5
  from dotenv import load_dotenv
6
  import logging
7
  from datetime import datetime
 
8
 
9
  # Configure logging
10
  logging.basicConfig(
@@ -16,20 +17,20 @@ logger = logging.getLogger(__name__)
16
  # Load environment variables from .env file (fallback)
17
  load_dotenv()
18
 
19
- # MongoDB configuration with fallback to environment variables
20
- MONGO_URI = os.getenv('MONGO_URI')
21
- DB_NAME = os.getenv('DB_NAME', 'book-my-service')
22
-
23
- # Redis configuration with fallback to environment variables
24
- CACHE_URI = os.getenv('CACHE_URI')
25
- CACHE_K = os.getenv('CACHE_K')
26
 
27
- # Validate that we have the required configuration
28
- if not MONGO_URI or not DB_NAME:
29
- raise ValueError("MongoDB configuration is missing. Please check your environment variables.")
30
 
31
- if not CACHE_URI or not CACHE_K:
32
- raise ValueError("Redis configuration is missing. Please check your environment variables.")
 
33
 
34
  # Parse Redis host and port safely
35
  try:
 
5
  from dotenv import load_dotenv
6
  import logging
7
  from datetime import datetime
8
+ from app.config.config import settings, validate_configuration
9
 
10
  # Configure logging
11
  logging.basicConfig(
 
17
  # Load environment variables from .env file (fallback)
18
  load_dotenv()
19
 
20
+ # Validate configuration on import
21
+ try:
22
+ validate_configuration()
23
+ except ValueError as e:
24
+ logger.error(f"Configuration validation failed: {e}")
25
+ raise
 
26
 
27
+ # MongoDB configuration using settings
28
+ MONGO_URI = settings.MONGO_URI
29
+ DB_NAME = settings.DB_NAME
30
 
31
+ # Redis configuration using settings
32
+ CACHE_URI = settings.CACHE_URI
33
+ CACHE_K = settings.CACHE_K
34
 
35
  # Parse Redis host and port safely
36
  try: