timber-common 0.2.3__tar.gz → 0.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {timber_common-0.2.3 → timber_common-0.2.4}/PKG-INFO +1 -1
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/security/oauth_service.py +51 -12
- {timber_common-0.2.3 → timber_common-0.2.4}/pyproject.toml +1 -1
- {timber_common-0.2.3 → timber_common-0.2.4}/CHANGELOG.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/LICENSE +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/README.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/config/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/config/model_loader.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/engine/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/engine/config_executor.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/engine/operation_registry.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/init.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/models/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/models/base.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/models/configs/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/models/core/__init.__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/models/core/tag.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/models/core/user.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/models/factory.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/models/mixins.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/models/registry.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_fetcher/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_fetcher/alphavantage.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_fetcher/base.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_fetcher/curated_data.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_fetcher/polygon.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_fetcher/stock.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_fetcher/yfinance.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_processor/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_processor/portfolio_metrics.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_processor/returns.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_processor/risk_metrics.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_processor/standardization.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_processor/technical_indicators.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/db_service.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/encryption/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/encryption/field_encryption.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/gdpr/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/gdpr/deletion.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/inventory/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/inventory/available_capabilities.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/inventory/cached_capabilities.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/inventory/loader.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/persistence/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/persistence/base.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/persistence/cache.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/persistence/instances.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/persistence/manager.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/persistence/notification.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/persistence/research.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/persistence/session.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/persistence/tracker.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/security/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/vector/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/vector/auto_ingestion.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/services/vector/tag_embedding.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/utils/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/utils/config.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/utils/db_utils.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/utils/helpers.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/utils/time_helpers.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/common/utils/validators.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/data/models/00_association_tables.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/data/models/cache_models.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/data/models/narrative_models.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/data/models/notification_models.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/data/models/oauth_models.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/data/models/portfolio_models.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/data/models/stock_research_models.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/data/models/user_preferences_models.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/data/models/vector_db_models.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/DOCUMENTATION_INDEX.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/DOCUMENTATION_SUMMARY.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/PROGRESS_UPDATE.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/TIMBER_SESSION_API_REFERENCE.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/01_model_design_patterns.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/02_service_architecture.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/03_data_fetching_strategies.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/04_caching_strategies.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/05_error_handling.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/06_performance_optimization.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/07_security_best_practices.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/design_guides/01_system_architecture.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/design_guides/02_config_driven_models.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/design_guides/03_persistence_layer.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/design_guides/04_vector_integration.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/design_guides/05_multi_app_support.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/how_to/01_getting_started.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/how_to/02_creating_models.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/how_to/03_using_services.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/how_to/04_financial_data_fetching.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/how_to/05_encryption_and_security.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/how_to/06_vector_search.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/how_to/07_gdpr_compliance.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/documentation/how_to/08_testing_guide.md +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/modules/__init__.py +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/modules/config/custom_analysis.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/modules/config/investing_operations_config.yaml +0 -0
- {timber_common-0.2.3 → timber_common-0.2.4}/modules/investing_operations.py +0 -0
|
@@ -45,7 +45,7 @@ def _patch_oauth2_client_methods():
|
|
|
45
45
|
|
|
46
46
|
# Check if method already exists
|
|
47
47
|
if hasattr(OAuth2Client, 'check_endpoint_auth_method'):
|
|
48
|
-
logger.
|
|
48
|
+
logger.debug("OAuth2Client already has check_endpoint_auth_method")
|
|
49
49
|
return
|
|
50
50
|
|
|
51
51
|
import secrets
|
|
@@ -65,12 +65,12 @@ def _patch_oauth2_client_methods():
|
|
|
65
65
|
# If client has a configured method, use it strictly
|
|
66
66
|
if hasattr(self, 'token_endpoint_auth_method') and self.token_endpoint_auth_method:
|
|
67
67
|
result = method == self.token_endpoint_auth_method
|
|
68
|
-
logger.
|
|
68
|
+
logger.debug(f"Client {self.client_id}: checking {method} against configured {self.token_endpoint_auth_method} = {result}")
|
|
69
69
|
return result
|
|
70
70
|
|
|
71
71
|
# Otherwise allow common methods
|
|
72
72
|
result = method in ['client_secret_post', 'client_secret_basic', 'none']
|
|
73
|
-
logger.
|
|
73
|
+
logger.debug(f"Client {self.client_id}: {method} allowed by default = {result}")
|
|
74
74
|
return result
|
|
75
75
|
|
|
76
76
|
return False
|
|
@@ -81,9 +81,25 @@ def _patch_oauth2_client_methods():
|
|
|
81
81
|
|
|
82
82
|
def check_client_secret(self, client_secret):
|
|
83
83
|
"""Validate client secret using constant-time comparison"""
|
|
84
|
+
logger.debug(f"check_client_secret called for client {self.client_id}")
|
|
85
|
+
logger.debug(f"Has client_secret attribute: {hasattr(self, 'client_secret')}")
|
|
86
|
+
|
|
84
87
|
if not self.has_client_secret():
|
|
88
|
+
logger.warning(f"Client {self.client_id} has no secret configured")
|
|
85
89
|
return False
|
|
86
|
-
|
|
90
|
+
|
|
91
|
+
stored_secret = self.client_secret
|
|
92
|
+
provided_secret = client_secret
|
|
93
|
+
|
|
94
|
+
logger.debug(f"Stored secret length: {len(stored_secret)}")
|
|
95
|
+
logger.debug(f"Provided secret length: {len(provided_secret)}")
|
|
96
|
+
logger.debug(f"Stored secret (first 10 chars): {stored_secret[:10]}...")
|
|
97
|
+
logger.debug(f"Provided secret (first 10 chars): {provided_secret[:10]}...")
|
|
98
|
+
|
|
99
|
+
result = secrets.compare_digest(stored_secret, provided_secret)
|
|
100
|
+
logger.debug(f"Secret comparison result: {result}")
|
|
101
|
+
|
|
102
|
+
return result
|
|
87
103
|
|
|
88
104
|
def get_client_id(self):
|
|
89
105
|
"""Return the client_id"""
|
|
@@ -344,15 +360,22 @@ class ModularAuthorizationServer(AuthorizationServer):
|
|
|
344
360
|
|
|
345
361
|
def query_client(self, client_id: str):
|
|
346
362
|
"""Implements the mandatory client query for Authlib."""
|
|
363
|
+
logger.debug(f"query_client called with client_id: {client_id}")
|
|
364
|
+
|
|
347
365
|
OAuth2Client = _get_model('OAuth2Client')
|
|
348
366
|
if not OAuth2Client:
|
|
367
|
+
logger.error("OAuth2Client model not found in registry")
|
|
349
368
|
return None
|
|
350
369
|
|
|
351
370
|
with db_service.session_scope() as session:
|
|
352
371
|
client = session.query(OAuth2Client).filter_by(client_id=client_id).first()
|
|
353
372
|
if client:
|
|
354
373
|
session.expunge(client)
|
|
355
|
-
logger.
|
|
374
|
+
logger.debug(f"Found client: {client_id}")
|
|
375
|
+
logger.debug(f"Client name: {getattr(client, 'client_name', 'N/A')}")
|
|
376
|
+
logger.debug(f"Client has secret: {bool(getattr(client, 'client_secret', None))}")
|
|
377
|
+
logger.debug(f"Client auth method: {getattr(client, 'token_endpoint_auth_method', 'N/A')}")
|
|
378
|
+
logger.debug(f"Client is_active: {getattr(client, 'is_active', 'N/A')}")
|
|
356
379
|
else:
|
|
357
380
|
logger.warning(f"Client not found: {client_id}")
|
|
358
381
|
return client
|
|
@@ -394,6 +417,22 @@ class ModularAuthorizationServer(AuthorizationServer):
|
|
|
394
417
|
This is required by Authlib but was not implemented, causing NotImplementedError.
|
|
395
418
|
"""
|
|
396
419
|
return status_code, payload, headers
|
|
420
|
+
|
|
421
|
+
def send_signal(self, name, *args, **kwargs):
|
|
422
|
+
"""
|
|
423
|
+
Send a signal/event notification.
|
|
424
|
+
|
|
425
|
+
Authlib uses this for hooks like 'after_authenticate_client'.
|
|
426
|
+
We don't need to do anything with signals for basic OAuth,
|
|
427
|
+
but the method must exist to avoid NotImplementedError.
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
name: Signal name (e.g., 'after_authenticate_client')
|
|
431
|
+
*args, **kwargs: Signal-specific arguments
|
|
432
|
+
"""
|
|
433
|
+
logger.debug(f"Signal sent: {name}")
|
|
434
|
+
# Signals are optional - we don't need to do anything
|
|
435
|
+
pass
|
|
397
436
|
|
|
398
437
|
def create_oauth2_request(self, request):
|
|
399
438
|
"""
|
|
@@ -579,35 +618,35 @@ class MyPasswordGrant(grants.ResourceOwnerPasswordCredentialsGrant):
|
|
|
579
618
|
try:
|
|
580
619
|
with db_service.session_scope() as session:
|
|
581
620
|
# Find user by email
|
|
582
|
-
logger.
|
|
621
|
+
logger.debug(f"Querying for user with email: {username}")
|
|
583
622
|
user = session.query(User).filter_by(email=username).first()
|
|
584
623
|
|
|
585
624
|
if not user:
|
|
586
625
|
logger.warning(f"Password grant: User not found: {username}")
|
|
587
626
|
# List available users for debugging
|
|
588
627
|
all_users = session.query(User).all()
|
|
589
|
-
logger.
|
|
628
|
+
logger.debug(f"Available users in database: {[u.email for u in all_users[:5]]}")
|
|
590
629
|
return None
|
|
591
630
|
|
|
592
|
-
logger.
|
|
631
|
+
logger.debug(f"User found: {user.email}, ID: {user.id}")
|
|
593
632
|
|
|
594
633
|
# Check if user is active
|
|
595
634
|
is_active = getattr(user, 'is_active', True)
|
|
596
|
-
logger.
|
|
635
|
+
logger.debug(f"User is_active: {is_active}")
|
|
597
636
|
|
|
598
637
|
if not is_active:
|
|
599
638
|
logger.warning(f"Password grant: User not active: {username}")
|
|
600
639
|
return None
|
|
601
640
|
|
|
602
641
|
# Verify password
|
|
603
|
-
logger.
|
|
642
|
+
logger.debug(f"Checking password for user: {username}")
|
|
604
643
|
|
|
605
644
|
if not hasattr(user, 'check_password'):
|
|
606
645
|
logger.error(f"User model has no check_password method!")
|
|
607
646
|
return None
|
|
608
647
|
|
|
609
648
|
password_valid = user.check_password(password)
|
|
610
|
-
logger.
|
|
649
|
+
logger.debug(f"Password validation result: {password_valid}")
|
|
611
650
|
|
|
612
651
|
if not password_valid:
|
|
613
652
|
logger.warning(f"Password grant: Invalid password for user: {username}")
|
|
@@ -615,7 +654,7 @@ class MyPasswordGrant(grants.ResourceOwnerPasswordCredentialsGrant):
|
|
|
615
654
|
|
|
616
655
|
# Update last login
|
|
617
656
|
if hasattr(user, 'update_last_login'):
|
|
618
|
-
logger.
|
|
657
|
+
logger.debug(f"Updating last login for user: {username}")
|
|
619
658
|
user.update_last_login()
|
|
620
659
|
session.flush()
|
|
621
660
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "timber-common"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.4"
|
|
4
4
|
description = "Configuration-driven persistence library with automatic encryption, caching, vector search, and GDPR compliance for Python applications"
|
|
5
5
|
authors = ["Pumulo Sikaneta <pumulo@gmail.com>"]
|
|
6
6
|
maintainers = ["Pumulo Sikaneta <pumulo@gmail.com>"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_processor/portfolio_metrics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_processor/standardization.py
RENAMED
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/common/services/data_processor/technical_indicators.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/common/services/inventory/available_capabilities.py
RENAMED
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/common/services/inventory/cached_capabilities.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/01_model_design_patterns.md
RENAMED
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/02_service_architecture.md
RENAMED
|
File without changes
|
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/04_caching_strategies.md
RENAMED
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/best_practices/05_error_handling.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/design_guides/01_system_architecture.md
RENAMED
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/design_guides/02_config_driven_models.md
RENAMED
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/design_guides/03_persistence_layer.md
RENAMED
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/design_guides/04_vector_integration.md
RENAMED
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/design_guides/05_multi_app_support.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/how_to/04_financial_data_fetching.md
RENAMED
|
File without changes
|
{timber_common-0.2.3 → timber_common-0.2.4}/documentation/how_to/05_encryption_and_security.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|