ai-lls-lib 1.4.0rc2__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.
- ai_lls_lib/__init__.py +1 -1
- ai_lls_lib/auth/__init__.py +4 -4
- ai_lls_lib/auth/context_parser.py +68 -68
- ai_lls_lib/cli/__init__.py +3 -3
- ai_lls_lib/cli/__main__.py +30 -30
- ai_lls_lib/cli/aws_client.py +115 -115
- ai_lls_lib/cli/commands/__init__.py +3 -3
- ai_lls_lib/cli/commands/admin.py +174 -174
- ai_lls_lib/cli/commands/cache.py +142 -142
- ai_lls_lib/cli/commands/stripe.py +377 -377
- ai_lls_lib/cli/commands/test_stack.py +216 -216
- ai_lls_lib/cli/commands/verify.py +111 -111
- ai_lls_lib/cli/env_loader.py +122 -122
- ai_lls_lib/core/__init__.py +3 -3
- ai_lls_lib/core/cache.py +106 -106
- ai_lls_lib/core/models.py +77 -77
- ai_lls_lib/core/processor.py +295 -295
- ai_lls_lib/core/verifier.py +84 -84
- ai_lls_lib/payment/__init__.py +13 -13
- ai_lls_lib/payment/credit_manager.py +186 -193
- ai_lls_lib/payment/models.py +102 -102
- ai_lls_lib/payment/stripe_manager.py +487 -487
- ai_lls_lib/payment/webhook_processor.py +215 -215
- ai_lls_lib/providers/__init__.py +7 -7
- ai_lls_lib/providers/base.py +28 -28
- ai_lls_lib/providers/external.py +87 -87
- ai_lls_lib/providers/stub.py +48 -48
- ai_lls_lib/testing/__init__.py +3 -3
- ai_lls_lib/testing/fixtures.py +104 -104
- {ai_lls_lib-1.4.0rc2.dist-info → ai_lls_lib-1.4.0rc4.dist-info}/METADATA +1 -1
- ai_lls_lib-1.4.0rc4.dist-info/RECORD +33 -0
- ai_lls_lib-1.4.0rc2.dist-info/RECORD +0 -33
- {ai_lls_lib-1.4.0rc2.dist-info → ai_lls_lib-1.4.0rc4.dist-info}/WHEEL +0 -0
- {ai_lls_lib-1.4.0rc2.dist-info → ai_lls_lib-1.4.0rc4.dist-info}/entry_points.txt +0 -0
ai_lls_lib/providers/external.py
CHANGED
@@ -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()
|
ai_lls_lib/providers/stub.py
CHANGED
@@ -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
|
ai_lls_lib/testing/__init__.py
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
"""
|
2
|
-
Testing utilities and fixtures
|
3
|
-
"""
|
1
|
+
"""
|
2
|
+
Testing utilities and fixtures
|
3
|
+
"""
|
ai_lls_lib/testing/fixtures.py
CHANGED
@@ -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
|
@@ -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=0poXvWj7ugCNm9UUymXIfKaFUONnODl3crlDvT2VrWU,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=ynjweRkbdHI-A6fROUoqlazNDmXOugXsIaMco7k62S0,7147
|
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.0rc2.dist-info/METADATA,sha256=htsgnIQ-MJ32O71Vn-isPhmoru6EaTPmOP3sMII7M3o,7251
|
31
|
-
ai_lls_lib-1.4.0rc2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
32
|
-
ai_lls_lib-1.4.0rc2.dist-info/entry_points.txt,sha256=Pi0V_HBViEKGFbNQKatl5lhhnHHBXlxaom-5gH9gXZ0,55
|
33
|
-
ai_lls_lib-1.4.0rc2.dist-info/RECORD,,
|
File without changes
|
File without changes
|