ai-lls-lib 1.4.0rc3__py3-none-any.whl → 1.4.0rc4__py3-none-any.whl

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.
Files changed (34) hide show
  1. ai_lls_lib/__init__.py +1 -1
  2. ai_lls_lib/auth/__init__.py +4 -4
  3. ai_lls_lib/auth/context_parser.py +68 -68
  4. ai_lls_lib/cli/__init__.py +3 -3
  5. ai_lls_lib/cli/__main__.py +30 -30
  6. ai_lls_lib/cli/aws_client.py +115 -115
  7. ai_lls_lib/cli/commands/__init__.py +3 -3
  8. ai_lls_lib/cli/commands/admin.py +174 -174
  9. ai_lls_lib/cli/commands/cache.py +142 -142
  10. ai_lls_lib/cli/commands/stripe.py +377 -377
  11. ai_lls_lib/cli/commands/test_stack.py +216 -216
  12. ai_lls_lib/cli/commands/verify.py +111 -111
  13. ai_lls_lib/cli/env_loader.py +122 -122
  14. ai_lls_lib/core/__init__.py +3 -3
  15. ai_lls_lib/core/cache.py +106 -106
  16. ai_lls_lib/core/models.py +77 -77
  17. ai_lls_lib/core/processor.py +295 -295
  18. ai_lls_lib/core/verifier.py +84 -84
  19. ai_lls_lib/payment/__init__.py +13 -13
  20. ai_lls_lib/payment/credit_manager.py +186 -186
  21. ai_lls_lib/payment/models.py +102 -102
  22. ai_lls_lib/payment/stripe_manager.py +487 -487
  23. ai_lls_lib/payment/webhook_processor.py +215 -215
  24. ai_lls_lib/providers/__init__.py +7 -7
  25. ai_lls_lib/providers/base.py +28 -28
  26. ai_lls_lib/providers/external.py +87 -87
  27. ai_lls_lib/providers/stub.py +48 -48
  28. ai_lls_lib/testing/__init__.py +3 -3
  29. ai_lls_lib/testing/fixtures.py +104 -104
  30. {ai_lls_lib-1.4.0rc3.dist-info → ai_lls_lib-1.4.0rc4.dist-info}/METADATA +1 -1
  31. ai_lls_lib-1.4.0rc4.dist-info/RECORD +33 -0
  32. ai_lls_lib-1.4.0rc3.dist-info/RECORD +0 -33
  33. {ai_lls_lib-1.4.0rc3.dist-info → ai_lls_lib-1.4.0rc4.dist-info}/WHEEL +0 -0
  34. {ai_lls_lib-1.4.0rc3.dist-info → ai_lls_lib-1.4.0rc4.dist-info}/entry_points.txt +0 -0
@@ -1,87 +1,87 @@
1
- """
2
- External API provider for production phone verification
3
- """
4
- import os
5
- from typing import Tuple, Optional
6
- import httpx
7
- from aws_lambda_powertools import Logger
8
- from ..core.models import LineType
9
-
10
- logger = Logger()
11
-
12
-
13
- class ExternalAPIProvider:
14
- """
15
- Production provider that calls external verification APIs.
16
- """
17
-
18
- def __init__(
19
- self,
20
- phone_api_key: Optional[str] = None,
21
- dnc_api_key: Optional[str] = None,
22
- timeout: float = 10.0
23
- ):
24
- """
25
- Initialize external API provider.
26
-
27
- Args:
28
- phone_api_key: API key for phone line type verification
29
- dnc_api_key: API key for DNC list checking
30
- timeout: HTTP request timeout in seconds
31
- """
32
- self.phone_api_key = phone_api_key or os.environ.get("PHONE_VERIFY_API_KEY", "")
33
- self.dnc_api_key = dnc_api_key or os.environ.get("DNC_API_KEY", "")
34
- self.http_client = httpx.Client(timeout=timeout)
35
-
36
- def verify_phone(self, phone: str) -> Tuple[LineType, bool]:
37
- """
38
- Verify phone using external APIs.
39
-
40
- Args:
41
- phone: E.164 formatted phone number
42
-
43
- Returns:
44
- Tuple of (line_type, is_on_dnc_list)
45
-
46
- Raises:
47
- httpx.HTTPError: For API communication errors
48
- ValueError: For invalid responses
49
- """
50
- line_type = self._check_line_type(phone)
51
- is_dnc = self._check_dnc(phone)
52
- return line_type, is_dnc
53
-
54
- def _check_line_type(self, phone: str) -> LineType:
55
- """
56
- Check line type via external API.
57
-
58
- TODO: Implement actual API call
59
- - Use self.phone_api_key for authentication
60
- - Parse API response
61
- - Map to LineType enum
62
- """
63
- logger.info(f"External line type check for {phone[:6]}***")
64
-
65
- # Placeholder implementation
66
- # In production, this would make an actual API call
67
- raise NotImplementedError("External line type API not yet configured")
68
-
69
- def _check_dnc(self, phone: str) -> bool:
70
- """
71
- Check DNC status via external API.
72
-
73
- TODO: Implement actual API call
74
- - Use self.dnc_api_key for authentication
75
- - Parse API response
76
- - Return boolean status
77
- """
78
- logger.info(f"External DNC check for {phone[:6]}***")
79
-
80
- # Placeholder implementation
81
- # In production, this would make an actual API call
82
- raise NotImplementedError("External DNC API not yet configured")
83
-
84
- def __del__(self):
85
- """Cleanup HTTP client"""
86
- if hasattr(self, 'http_client'):
87
- self.http_client.close()
1
+ """
2
+ External API provider for production phone verification
3
+ """
4
+ import os
5
+ from typing import Tuple, Optional
6
+ import httpx
7
+ from aws_lambda_powertools import Logger
8
+ from ..core.models import LineType
9
+
10
+ logger = Logger()
11
+
12
+
13
+ class ExternalAPIProvider:
14
+ """
15
+ Production provider that calls external verification APIs.
16
+ """
17
+
18
+ def __init__(
19
+ self,
20
+ phone_api_key: Optional[str] = None,
21
+ dnc_api_key: Optional[str] = None,
22
+ timeout: float = 10.0
23
+ ):
24
+ """
25
+ Initialize external API provider.
26
+
27
+ Args:
28
+ phone_api_key: API key for phone line type verification
29
+ dnc_api_key: API key for DNC list checking
30
+ timeout: HTTP request timeout in seconds
31
+ """
32
+ self.phone_api_key = phone_api_key or os.environ.get("PHONE_VERIFY_API_KEY", "")
33
+ self.dnc_api_key = dnc_api_key or os.environ.get("DNC_API_KEY", "")
34
+ self.http_client = httpx.Client(timeout=timeout)
35
+
36
+ def verify_phone(self, phone: str) -> Tuple[LineType, bool]:
37
+ """
38
+ Verify phone using external APIs.
39
+
40
+ Args:
41
+ phone: E.164 formatted phone number
42
+
43
+ Returns:
44
+ Tuple of (line_type, is_on_dnc_list)
45
+
46
+ Raises:
47
+ httpx.HTTPError: For API communication errors
48
+ ValueError: For invalid responses
49
+ """
50
+ line_type = self._check_line_type(phone)
51
+ is_dnc = self._check_dnc(phone)
52
+ return line_type, is_dnc
53
+
54
+ def _check_line_type(self, phone: str) -> LineType:
55
+ """
56
+ Check line type via external API.
57
+
58
+ TODO: Implement actual API call
59
+ - Use self.phone_api_key for authentication
60
+ - Parse API response
61
+ - Map to LineType enum
62
+ """
63
+ logger.info(f"External line type check for {phone[:6]}***")
64
+
65
+ # Placeholder implementation
66
+ # In production, this would make an actual API call
67
+ raise NotImplementedError("External line type API not yet configured")
68
+
69
+ def _check_dnc(self, phone: str) -> bool:
70
+ """
71
+ Check DNC status via external API.
72
+
73
+ TODO: Implement actual API call
74
+ - Use self.dnc_api_key for authentication
75
+ - Parse API response
76
+ - Return boolean status
77
+ """
78
+ logger.info(f"External DNC check for {phone[:6]}***")
79
+
80
+ # Placeholder implementation
81
+ # In production, this would make an actual API call
82
+ raise NotImplementedError("External DNC API not yet configured")
83
+
84
+ def __del__(self):
85
+ """Cleanup HTTP client"""
86
+ if hasattr(self, 'http_client'):
87
+ self.http_client.close()
@@ -1,48 +1,48 @@
1
- """
2
- Stub provider for development and testing
3
- """
4
- from typing import Tuple
5
- from aws_lambda_powertools import Logger
6
- from ..core.models import LineType
7
-
8
- logger = Logger()
9
-
10
-
11
- class StubProvider:
12
- """
13
- Stub implementation for development and testing.
14
- Uses deterministic rules based on phone number digits.
15
- """
16
-
17
- def verify_phone(self, phone: str) -> Tuple[LineType, bool]:
18
- """
19
- Verify using stub logic based on last digit.
20
-
21
- Line type:
22
- - Ends in 2 or 0: LANDLINE
23
- - Otherwise: MOBILE
24
-
25
- DNC status:
26
- - Ends in 1 or 0: on DNC list
27
- - Otherwise: not on DNC
28
-
29
- Args:
30
- phone: E.164 formatted phone number
31
-
32
- Returns:
33
- Tuple of (line_type, is_on_dnc_list)
34
- """
35
- logger.info(f"Stub verification for {phone[:6]}***")
36
-
37
- last_digit = phone[-1] if phone else '5'
38
-
39
- # Determine line type
40
- if last_digit in ['2', '0']:
41
- line_type = LineType.LANDLINE
42
- else:
43
- line_type = LineType.MOBILE
44
-
45
- # Determine DNC status
46
- is_dnc = last_digit in ['1', '0']
47
-
48
- return line_type, is_dnc
1
+ """
2
+ Stub provider for development and testing
3
+ """
4
+ from typing import Tuple
5
+ from aws_lambda_powertools import Logger
6
+ from ..core.models import LineType
7
+
8
+ logger = Logger()
9
+
10
+
11
+ class StubProvider:
12
+ """
13
+ Stub implementation for development and testing.
14
+ Uses deterministic rules based on phone number digits.
15
+ """
16
+
17
+ def verify_phone(self, phone: str) -> Tuple[LineType, bool]:
18
+ """
19
+ Verify using stub logic based on last digit.
20
+
21
+ Line type:
22
+ - Ends in 2 or 0: LANDLINE
23
+ - Otherwise: MOBILE
24
+
25
+ DNC status:
26
+ - Ends in 1 or 0: on DNC list
27
+ - Otherwise: not on DNC
28
+
29
+ Args:
30
+ phone: E.164 formatted phone number
31
+
32
+ Returns:
33
+ Tuple of (line_type, is_on_dnc_list)
34
+ """
35
+ logger.info(f"Stub verification for {phone[:6]}***")
36
+
37
+ last_digit = phone[-1] if phone else '5'
38
+
39
+ # Determine line type
40
+ if last_digit in ['2', '0']:
41
+ line_type = LineType.LANDLINE
42
+ else:
43
+ line_type = LineType.MOBILE
44
+
45
+ # Determine DNC status
46
+ is_dnc = last_digit in ['1', '0']
47
+
48
+ return line_type, is_dnc
@@ -1,3 +1,3 @@
1
- """
2
- Testing utilities and fixtures
3
- """
1
+ """
2
+ Testing utilities and fixtures
3
+ """
@@ -1,104 +1,104 @@
1
- """
2
- Test fixtures and utilities for ai-lls-lib
3
- """
4
- from datetime import datetime, timedelta, timezone
5
- from typing import List, Dict, Any
6
- from ai_lls_lib.core.models import PhoneVerification, LineType, VerificationSource
7
-
8
- # Sample phone numbers for testing
9
- # Using 201-555-01XX format which is designated for testing
10
- TEST_PHONES = {
11
- "valid_mobile": "+12015550153", # Ends in 3 - mobile, not on DNC
12
- "valid_landline": "+12015550152", # Ends in 2 - landline, not on DNC
13
- "dnc_mobile": "+12015550151", # Ends in 1 - mobile, on DNC
14
- "dnc_landline": "+12015550150", # Ends in 0 - landline, on DNC
15
- "invalid": "not-a-phone",
16
- "missing_country": "2015550123",
17
- "international": "+442071234567",
18
- }
19
-
20
- def create_test_verification(
21
- phone: str = TEST_PHONES["valid_mobile"],
22
- line_type: LineType = LineType.MOBILE,
23
- dnc: bool = False,
24
- cached: bool = False,
25
- source: VerificationSource = VerificationSource.API
26
- ) -> PhoneVerification:
27
- """Create a test PhoneVerification object"""
28
- return PhoneVerification(
29
- phone_number=phone,
30
- line_type=line_type,
31
- dnc=dnc,
32
- cached=cached,
33
- verified_at=datetime.now(timezone.utc),
34
- source=source
35
- )
36
-
37
- def create_test_csv_content(phones: List[str] = None) -> str:
38
- """Create CSV content for testing bulk processing"""
39
- if phones is None:
40
- phones = [
41
- TEST_PHONES["valid_mobile"],
42
- TEST_PHONES["valid_landline"],
43
- TEST_PHONES["dnc_mobile"],
44
- ]
45
-
46
- lines = ["name,phone,email"]
47
- for i, phone in enumerate(phones):
48
- lines.append(f"Test User {i},{phone},test{i}@example.com")
49
-
50
- return "\n".join(lines)
51
-
52
- def create_dynamodb_item(phone: str, line_type: LineType = LineType.MOBILE, dnc: bool = False) -> Dict[str, Any]:
53
- """Create a DynamoDB item for testing"""
54
- ttl = int((datetime.now(timezone.utc) + timedelta(days=30)).timestamp())
55
-
56
- return {
57
- "phone_number": phone,
58
- "line_type": line_type.value, # Store as string in DynamoDB
59
- "dnc": dnc,
60
- "cached": True,
61
- "verified_at": datetime.now(timezone.utc).isoformat(),
62
- "source": VerificationSource.CACHE.value, # Store as string in DynamoDB
63
- "ttl": ttl
64
- }
65
-
66
- def create_sqs_message(file_id: str, bucket: str, key: str, user_id: str) -> Dict[str, Any]:
67
- """Create an SQS message for bulk processing"""
68
- return {
69
- "file_id": file_id,
70
- "bucket": bucket,
71
- "key": key,
72
- "user_id": user_id,
73
- "created_at": datetime.now(timezone.utc).isoformat()
74
- }
75
-
76
- def create_api_gateway_event(
77
- phone: str = None,
78
- user_id: str = "test-user",
79
- method: str = "GET",
80
- path: str = "/verify"
81
- ) -> Dict[str, Any]:
82
- """Create an API Gateway event for Lambda testing"""
83
- event = {
84
- "httpMethod": method,
85
- "path": path,
86
- "headers": {
87
- "Authorization": "Bearer test-token"
88
- },
89
- "requestContext": {
90
- "authorizer": {
91
- "lambda": {
92
- "principal_id": user_id,
93
- "claims": {
94
- "email": f"{user_id}@example.com"
95
- }
96
- }
97
- }
98
- }
99
- }
100
-
101
- if phone:
102
- event["queryStringParameters"] = {"p": phone}
103
-
104
- return event
1
+ """
2
+ Test fixtures and utilities for ai-lls-lib
3
+ """
4
+ from datetime import datetime, timedelta, timezone
5
+ from typing import List, Dict, Any
6
+ from ai_lls_lib.core.models import PhoneVerification, LineType, VerificationSource
7
+
8
+ # Sample phone numbers for testing
9
+ # Using 201-555-01XX format which is designated for testing
10
+ TEST_PHONES = {
11
+ "valid_mobile": "+12015550153", # Ends in 3 - mobile, not on DNC
12
+ "valid_landline": "+12015550152", # Ends in 2 - landline, not on DNC
13
+ "dnc_mobile": "+12015550151", # Ends in 1 - mobile, on DNC
14
+ "dnc_landline": "+12015550150", # Ends in 0 - landline, on DNC
15
+ "invalid": "not-a-phone",
16
+ "missing_country": "2015550123",
17
+ "international": "+442071234567",
18
+ }
19
+
20
+ def create_test_verification(
21
+ phone: str = TEST_PHONES["valid_mobile"],
22
+ line_type: LineType = LineType.MOBILE,
23
+ dnc: bool = False,
24
+ cached: bool = False,
25
+ source: VerificationSource = VerificationSource.API
26
+ ) -> PhoneVerification:
27
+ """Create a test PhoneVerification object"""
28
+ return PhoneVerification(
29
+ phone_number=phone,
30
+ line_type=line_type,
31
+ dnc=dnc,
32
+ cached=cached,
33
+ verified_at=datetime.now(timezone.utc),
34
+ source=source
35
+ )
36
+
37
+ def create_test_csv_content(phones: List[str] = None) -> str:
38
+ """Create CSV content for testing bulk processing"""
39
+ if phones is None:
40
+ phones = [
41
+ TEST_PHONES["valid_mobile"],
42
+ TEST_PHONES["valid_landline"],
43
+ TEST_PHONES["dnc_mobile"],
44
+ ]
45
+
46
+ lines = ["name,phone,email"]
47
+ for i, phone in enumerate(phones):
48
+ lines.append(f"Test User {i},{phone},test{i}@example.com")
49
+
50
+ return "\n".join(lines)
51
+
52
+ def create_dynamodb_item(phone: str, line_type: LineType = LineType.MOBILE, dnc: bool = False) -> Dict[str, Any]:
53
+ """Create a DynamoDB item for testing"""
54
+ ttl = int((datetime.now(timezone.utc) + timedelta(days=30)).timestamp())
55
+
56
+ return {
57
+ "phone_number": phone,
58
+ "line_type": line_type.value, # Store as string in DynamoDB
59
+ "dnc": dnc,
60
+ "cached": True,
61
+ "verified_at": datetime.now(timezone.utc).isoformat(),
62
+ "source": VerificationSource.CACHE.value, # Store as string in DynamoDB
63
+ "ttl": ttl
64
+ }
65
+
66
+ def create_sqs_message(file_id: str, bucket: str, key: str, user_id: str) -> Dict[str, Any]:
67
+ """Create an SQS message for bulk processing"""
68
+ return {
69
+ "file_id": file_id,
70
+ "bucket": bucket,
71
+ "key": key,
72
+ "user_id": user_id,
73
+ "created_at": datetime.now(timezone.utc).isoformat()
74
+ }
75
+
76
+ def create_api_gateway_event(
77
+ phone: str = None,
78
+ user_id: str = "test-user",
79
+ method: str = "GET",
80
+ path: str = "/verify"
81
+ ) -> Dict[str, Any]:
82
+ """Create an API Gateway event for Lambda testing"""
83
+ event = {
84
+ "httpMethod": method,
85
+ "path": path,
86
+ "headers": {
87
+ "Authorization": "Bearer test-token"
88
+ },
89
+ "requestContext": {
90
+ "authorizer": {
91
+ "lambda": {
92
+ "principal_id": user_id,
93
+ "claims": {
94
+ "email": f"{user_id}@example.com"
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+
101
+ if phone:
102
+ event["queryStringParameters"] = {"p": phone}
103
+
104
+ return event
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ai-lls-lib
3
- Version: 1.4.0rc3
3
+ Version: 1.4.0rc4
4
4
  Summary: Landline Scrubber core library - phone verification and DNC checking
5
5
  Author: LandlineScrubber Team
6
6
  Requires-Python: >=3.12,<4.0
@@ -0,0 +1,33 @@
1
+ ai_lls_lib/__init__.py,sha256=mPH9z5syhmUHZkQz-dsk1KWKeq52_SWyYWd7VkiZzo0,589
2
+ ai_lls_lib/auth/__init__.py,sha256=ZjwlfTvYUo9A9BaLinaXW2elxYectScmu0XtKAppSFs,198
3
+ ai_lls_lib/auth/context_parser.py,sha256=AWyGWejrFR0jJ7fMhajdA1ABo656Qlvs2YAzz-IfTrs,2290
4
+ ai_lls_lib/cli/__init__.py,sha256=HyjnIBGlrbTlHQ82n_UppjtJbZl4_7QsnAgRqNlXKMU,77
5
+ ai_lls_lib/cli/__main__.py,sha256=wsSjkPdrkqqmcxYZr-_CWmOd1YQAN4fo3cey-P4BQxI,746
6
+ ai_lls_lib/cli/aws_client.py,sha256=lqihYQQtpx8Xb5HcVTbexl1pZdlYYdozPLDEGcen27Q,4067
7
+ ai_lls_lib/cli/commands/__init__.py,sha256=yi0bdkZSPIXY33apvJRcuK410-Ta0-_-n31MQYuL_aU,31
8
+ ai_lls_lib/cli/commands/admin.py,sha256=JlFljbblVWJkJ2z2FIM6P0fy3Pmc0VqG62Y3POtvRFw,6861
9
+ ai_lls_lib/cli/commands/cache.py,sha256=1Vm3m5vXJkRagNmQXpT8_YEsQEv92veJUFwA_v9FPb0,5822
10
+ ai_lls_lib/cli/commands/stripe.py,sha256=5Exkxst9xf3KRynfIlQRw5NJavWol9DYrHCMKRPzGpA,15016
11
+ ai_lls_lib/cli/commands/test_stack.py,sha256=FK6ITOek7j4e0QiSNTv_taLghNnR8d_kWG02cl0A3rY,7594
12
+ ai_lls_lib/cli/commands/verify.py,sha256=a63KSXd0XfJq2LFEt3RrGmQ7SXK40pQhS-oaPo8SCdo,4349
13
+ ai_lls_lib/cli/env_loader.py,sha256=zqCIZvySqXQMxbOW45k6qevrsKbk8X14OU7EDr1jx8Q,3884
14
+ ai_lls_lib/core/__init__.py,sha256=ATh5sGhhB9g5Sd2H0kRqoCA0hxqe6UWonlPq2Wnl_i8,39
15
+ ai_lls_lib/core/cache.py,sha256=4HSVaRvv_wueLV30fVbTk_KWZmXjR2mBrGl7UNT_5kQ,3817
16
+ ai_lls_lib/core/models.py,sha256=jzvc-SlP-nLgvkom9hj-TwKHxBePbEfC9xL_Tt1Uh4Y,2458
17
+ ai_lls_lib/core/processor.py,sha256=8PI_j1ZMOD1hru3PyV5QMmMx7Em8X0ivq8prMXwait4,10269
18
+ ai_lls_lib/core/verifier.py,sha256=dM5DkVudc29Evsd-QSkX9cQEM8EeUJQlCYxImDIJ7Uc,2800
19
+ ai_lls_lib/payment/__init__.py,sha256=uQwWZ2tw-cxS06hbWiKu8ubxzzYCmxeKBQQU7m_mRX4,308
20
+ ai_lls_lib/payment/credit_manager.py,sha256=DH_t8AMx74vexegoTD3UkFNA1XuomIQWOZu9VoJMO3E,7340
21
+ ai_lls_lib/payment/models.py,sha256=LxGop5e1hhUmBCpnzJwU-dDQSLHy6uM6gSFYYo2V_FI,3609
22
+ ai_lls_lib/payment/stripe_manager.py,sha256=mu1bbGewCZDUye734wKq7JCTT_2MSyF8K-FjTmD5R5U,18514
23
+ ai_lls_lib/payment/webhook_processor.py,sha256=bAf8oUBzvCsb1stzKZ-cjZs02T-RJl-MeVnZmnnj5UM,8980
24
+ ai_lls_lib/providers/__init__.py,sha256=xDh9KY3pgDef59CqQlAR215bawxdEY2OP-BRRT9ru_c,186
25
+ ai_lls_lib/providers/base.py,sha256=WSnSkHtRvwpX8QtGINjO-EWsZL0augp5E8M1DPwpf00,709
26
+ ai_lls_lib/providers/external.py,sha256=T8P_XtLNCXZBB0DzK4fradNBoiapIbpQ09Ai4DihpMM,2710
27
+ ai_lls_lib/providers/stub.py,sha256=n8WCcuqcv62DnIO-WPhuold-AC3yrxjQAboJ4CO2n6U,1198
28
+ ai_lls_lib/testing/__init__.py,sha256=NytBz7T0YtNLDArRYHsczaeopIQmmBeV21-XXUprdeY,42
29
+ ai_lls_lib/testing/fixtures.py,sha256=OC1huorIqUndePoUTfgoU-aDvsWAFJqmQ6fGDjH9E14,3414
30
+ ai_lls_lib-1.4.0rc4.dist-info/METADATA,sha256=qhAt5YJFzoVZAXxrxcUzxtIzIsMEcwmnyScnxB8plkg,7251
31
+ ai_lls_lib-1.4.0rc4.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
32
+ ai_lls_lib-1.4.0rc4.dist-info/entry_points.txt,sha256=Pi0V_HBViEKGFbNQKatl5lhhnHHBXlxaom-5gH9gXZ0,55
33
+ ai_lls_lib-1.4.0rc4.dist-info/RECORD,,
@@ -1,33 +0,0 @@
1
- ai_lls_lib/__init__.py,sha256=UP9ZiqSs3cEXqNunHbIuzjmrDyGv7nNa_Vx3zdB4xew,589
2
- ai_lls_lib/auth/__init__.py,sha256=c6zomHSB6y9Seakf84ciGsD3XgWarIty9xty6P8fxVw,194
3
- ai_lls_lib/auth/context_parser.py,sha256=8I0vGbtykNLWqm8ldedxXjE-E3nqsCy113JgeyuiJoM,2222
4
- ai_lls_lib/cli/__init__.py,sha256=m9qjZTW1jpENwXAUeuRrlP0b66BWRcqSO28MSjvOyCs,74
5
- ai_lls_lib/cli/__main__.py,sha256=8tUdq4GJwzIiTC1pvCsTkwmq8iNujdFTbI45_wm3d7A,716
6
- ai_lls_lib/cli/aws_client.py,sha256=YcCWCpTNOW9JPLxSNLRy5-F5HPKguJJk7dPNrPqhJv0,3952
7
- ai_lls_lib/cli/commands/__init__.py,sha256=_kROrYuR_p2i110c0OvNeArfEFQbn15zR1c3pdeZOoo,28
8
- ai_lls_lib/cli/commands/admin.py,sha256=bNBJi2fZBP0J40JQP6HP7NYadNmI214iII1TeLhooyE,6687
9
- ai_lls_lib/cli/commands/cache.py,sha256=vWt0vy4L9CEgUEWUzfdehU6u43PE8vUvHx7xxg4e5tw,5680
10
- ai_lls_lib/cli/commands/stripe.py,sha256=h2OhZEppHuFbvW2kFMIp62fr7MNt_PcaUKRwd0gWGoc,14639
11
- ai_lls_lib/cli/commands/test_stack.py,sha256=rNq4mhRXX7Ixo67kSoEPWlxqgXCzM9e2PR96qTAG7pE,7378
12
- ai_lls_lib/cli/commands/verify.py,sha256=V5ucjmjCUxqN8_AeEJWWgrmYin8BNV3h4WbZ-iX3loU,4238
13
- ai_lls_lib/cli/env_loader.py,sha256=YTCB6QDyknOuedPbQsW4bezB5SgHzJMGjhpSPArHFVc,3762
14
- ai_lls_lib/core/__init__.py,sha256=QUaeQHIyvknkgMxIbfXRo1a5jSQpiJkB84dId5ubuEk,36
15
- ai_lls_lib/core/cache.py,sha256=MubgyAF3y7BBF9am39Ni98NgikZ9UBZUG-KtbE3XWX4,3711
16
- ai_lls_lib/core/models.py,sha256=ABRYaeMCWahQh4WdbkCxt3AO0-EvPWZwlL-JITQSnEM,2381
17
- ai_lls_lib/core/processor.py,sha256=6752IPDQ-Mz5i_CU7aBM0UjvV7IjyZFl35LKVPkHMpc,9974
18
- ai_lls_lib/core/verifier.py,sha256=6uB_jawWoIqsNYAadTKr0lSolIWygg2gK6ykf8lrul0,2716
19
- ai_lls_lib/payment/__init__.py,sha256=xhUWgfLnk3syXXQItswmDXdfXUyJTXTQAA0zIUuCVII,295
20
- ai_lls_lib/payment/credit_manager.py,sha256=gQABSr8Lgy_IqNwQ5Dg-Ep-_7P7Q9Atx77RGMgmW0V8,7154
21
- ai_lls_lib/payment/models.py,sha256=Du5sRc_cCsnyFJv0G3Rp67tLvZ68gq61Cm3QLC9jERI,3507
22
- ai_lls_lib/payment/stripe_manager.py,sha256=R_M4Bii9BGianL_STqvz4UU8ww8mlCByGo66V-e2C6Y,18027
23
- ai_lls_lib/payment/webhook_processor.py,sha256=cIZqCS98Q305SCI3-4AJ1h-IJ-l-7fMby1FFy1ckP6k,8765
24
- ai_lls_lib/providers/__init__.py,sha256=AEv3ARenWDwDo5PLCoszP2fQ70RgSHkrSLSUz7xHJDk,179
25
- ai_lls_lib/providers/base.py,sha256=344XYOg7bxDQMWJ6Lle8U7NOHpabnCp0XYbZpeWpPAk,681
26
- ai_lls_lib/providers/external.py,sha256=-Hhnlm8lQWRcWr5vG0dmD3sca2rohURrx0usOR2y1MM,2623
27
- ai_lls_lib/providers/stub.py,sha256=847Tmw522B3HQ2j38BH1sdcZQy--RdtDcXsrIrFKNBQ,1150
28
- ai_lls_lib/testing/__init__.py,sha256=RUxRYBzzPCPS15Umb6bUrE6rL5BQXBQf4SJM2E3ffrg,39
29
- ai_lls_lib/testing/fixtures.py,sha256=_n6bbr95LnQf9Dvu1qKs2HsvHEA7AAbe59B75qxE10w,3310
30
- ai_lls_lib-1.4.0rc3.dist-info/METADATA,sha256=LP2Jz8xjGUZZU3-6IaefvMUfRJalzjLsXviMElbV8D0,7251
31
- ai_lls_lib-1.4.0rc3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
32
- ai_lls_lib-1.4.0rc3.dist-info/entry_points.txt,sha256=Pi0V_HBViEKGFbNQKatl5lhhnHHBXlxaom-5gH9gXZ0,55
33
- ai_lls_lib-1.4.0rc3.dist-info/RECORD,,