ai-lls-lib 1.3.2__py3-none-any.whl → 1.4.0rc2__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 CHANGED
@@ -13,7 +13,7 @@ from ai_lls_lib.core.verifier import PhoneVerifier
13
13
  from ai_lls_lib.core.processor import BulkProcessor
14
14
  from ai_lls_lib.core.cache import DynamoDBCache
15
15
 
16
- __version__ = "1.3.2"
16
+ __version__ = "1.4.0-rc.2"
17
17
  __all__ = [
18
18
  "PhoneVerification",
19
19
  "BulkJob",
@@ -180,7 +180,8 @@ def seed_products(environment: str, api_key: Optional[str], dry_run: bool):
180
180
  for p in existing_products.data:
181
181
  if (p.metadata.get("product_type") == "landline_scrubber" and
182
182
  p.metadata.get("environment") == environment and
183
- p.metadata.get("tier") == config["metadata"]["tier"]):
183
+ p.metadata.get("tier") == config["metadata"]["tier"] and
184
+ p.active): # Only use active products
184
185
  product = p
185
186
  click.echo(f"Found existing product: {product.name}")
186
187
  break
@@ -219,6 +220,53 @@ def seed_products(environment: str, api_key: Optional[str], dry_run: bool):
219
220
  click.echo(f" {price_id}")
220
221
 
221
222
 
223
+ @stripe_group.command("clean")
224
+ @click.option("--environment", type=click.Choice(["staging", "production"]), default="staging")
225
+ @click.option("--api-key", help="Stripe API key (overrides environment)")
226
+ @click.option("--force", is_flag=True, help="Skip confirmation")
227
+ def clean_products(environment: str, api_key: Optional[str], force: bool):
228
+ """Remove all Landline Scrubber products and prices."""
229
+ import stripe
230
+
231
+ # Load API key from environment if not provided
232
+ if not api_key:
233
+ api_key = get_stripe_key(environment)
234
+ if not api_key:
235
+ click.echo(f"Error: No Stripe API key found for {environment} environment", err=True)
236
+ return
237
+
238
+ stripe.api_key = api_key
239
+
240
+ if not force:
241
+ if not click.confirm(f"This will DELETE all Landline Scrubber products in {environment}. Continue?"):
242
+ return
243
+
244
+ try:
245
+ # List all products
246
+ products = stripe.Product.list(limit=100)
247
+ deleted_count = 0
248
+
249
+ for product in products.data:
250
+ if (product.metadata.get("product_type") == "landline_scrubber" and
251
+ product.metadata.get("environment") == environment):
252
+ # Archive all prices first
253
+ prices = stripe.Price.list(product=product.id, limit=100)
254
+ for price in prices.data:
255
+ if price.active:
256
+ stripe.Price.modify(price.id, active=False)
257
+ click.echo(f" Archived price: {price.id}")
258
+
259
+ # Archive the product
260
+ stripe.Product.modify(product.id, active=False)
261
+ click.echo(f"Archived product: {product.name}")
262
+ deleted_count += 1
263
+
264
+ click.echo(f"\nArchived {deleted_count} products in {environment} environment")
265
+
266
+ except stripe.error.StripeError as e:
267
+ click.echo(f"Error: {e}", err=True)
268
+
269
+
222
270
  @stripe_group.command("list")
223
271
  @click.option("--environment", type=click.Choice(["staging", "production"]), default="staging")
224
272
  @click.option("--api-key", help="Stripe API key (overrides environment)")
@@ -41,7 +41,7 @@ class Plan:
41
41
 
42
42
  def to_dict(self) -> Dict[str, Any]:
43
43
  """Convert to dictionary for JSON serialization."""
44
- return {
44
+ result = {
45
45
  "plan_reference": self.plan_reference,
46
46
  "plan_type": self.plan_type,
47
47
  "plan_name": self.plan_name,
@@ -52,6 +52,12 @@ class Plan:
52
52
  "percent_off": self.percent_off
53
53
  }
54
54
 
55
+ # Add variable_amount flag for VARIABLE product
56
+ if self.plan_name == "VARIABLE":
57
+ result["variable_amount"] = True
58
+
59
+ return result
60
+
55
61
  @classmethod
56
62
  def from_stripe_price(cls, price: Dict[str, Any], product: Dict[str, Any]) -> "Plan":
57
63
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ai-lls-lib
3
- Version: 1.3.2
3
+ Version: 1.4.0rc2
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
@@ -1,4 +1,4 @@
1
- ai_lls_lib/__init__.py,sha256=x0cav2ZOwvsvJ4kkxxNUxpQwIywlTtlXwRvV7P45SDY,584
1
+ ai_lls_lib/__init__.py,sha256=0poXvWj7ugCNm9UUymXIfKaFUONnODl3crlDvT2VrWU,589
2
2
  ai_lls_lib/auth/__init__.py,sha256=c6zomHSB6y9Seakf84ciGsD3XgWarIty9xty6P8fxVw,194
3
3
  ai_lls_lib/auth/context_parser.py,sha256=8I0vGbtykNLWqm8ldedxXjE-E3nqsCy113JgeyuiJoM,2222
4
4
  ai_lls_lib/cli/__init__.py,sha256=m9qjZTW1jpENwXAUeuRrlP0b66BWRcqSO28MSjvOyCs,74
@@ -7,7 +7,7 @@ ai_lls_lib/cli/aws_client.py,sha256=YcCWCpTNOW9JPLxSNLRy5-F5HPKguJJk7dPNrPqhJv0,
7
7
  ai_lls_lib/cli/commands/__init__.py,sha256=_kROrYuR_p2i110c0OvNeArfEFQbn15zR1c3pdeZOoo,28
8
8
  ai_lls_lib/cli/commands/admin.py,sha256=bNBJi2fZBP0J40JQP6HP7NYadNmI214iII1TeLhooyE,6687
9
9
  ai_lls_lib/cli/commands/cache.py,sha256=vWt0vy4L9CEgUEWUzfdehU6u43PE8vUvHx7xxg4e5tw,5680
10
- ai_lls_lib/cli/commands/stripe.py,sha256=Iccp8ZmNE18q9rvoox-Mo7dZgByEhIVP7otRklgr4uI,12707
10
+ ai_lls_lib/cli/commands/stripe.py,sha256=h2OhZEppHuFbvW2kFMIp62fr7MNt_PcaUKRwd0gWGoc,14639
11
11
  ai_lls_lib/cli/commands/test_stack.py,sha256=rNq4mhRXX7Ixo67kSoEPWlxqgXCzM9e2PR96qTAG7pE,7378
12
12
  ai_lls_lib/cli/commands/verify.py,sha256=V5ucjmjCUxqN8_AeEJWWgrmYin8BNV3h4WbZ-iX3loU,4238
13
13
  ai_lls_lib/cli/env_loader.py,sha256=YTCB6QDyknOuedPbQsW4bezB5SgHzJMGjhpSPArHFVc,3762
@@ -18,7 +18,7 @@ ai_lls_lib/core/processor.py,sha256=6752IPDQ-Mz5i_CU7aBM0UjvV7IjyZFl35LKVPkHMpc,
18
18
  ai_lls_lib/core/verifier.py,sha256=6uB_jawWoIqsNYAadTKr0lSolIWygg2gK6ykf8lrul0,2716
19
19
  ai_lls_lib/payment/__init__.py,sha256=xhUWgfLnk3syXXQItswmDXdfXUyJTXTQAA0zIUuCVII,295
20
20
  ai_lls_lib/payment/credit_manager.py,sha256=ynjweRkbdHI-A6fROUoqlazNDmXOugXsIaMco7k62S0,7147
21
- ai_lls_lib/payment/models.py,sha256=JjSmWKwpuFF85Jzmabj6y7UyolJlJlsh5CmOWRg21B8,3339
21
+ ai_lls_lib/payment/models.py,sha256=Du5sRc_cCsnyFJv0G3Rp67tLvZ68gq61Cm3QLC9jERI,3507
22
22
  ai_lls_lib/payment/stripe_manager.py,sha256=R_M4Bii9BGianL_STqvz4UU8ww8mlCByGo66V-e2C6Y,18027
23
23
  ai_lls_lib/payment/webhook_processor.py,sha256=cIZqCS98Q305SCI3-4AJ1h-IJ-l-7fMby1FFy1ckP6k,8765
24
24
  ai_lls_lib/providers/__init__.py,sha256=AEv3ARenWDwDo5PLCoszP2fQ70RgSHkrSLSUz7xHJDk,179
@@ -27,7 +27,7 @@ ai_lls_lib/providers/external.py,sha256=-Hhnlm8lQWRcWr5vG0dmD3sca2rohURrx0usOR2y
27
27
  ai_lls_lib/providers/stub.py,sha256=847Tmw522B3HQ2j38BH1sdcZQy--RdtDcXsrIrFKNBQ,1150
28
28
  ai_lls_lib/testing/__init__.py,sha256=RUxRYBzzPCPS15Umb6bUrE6rL5BQXBQf4SJM2E3ffrg,39
29
29
  ai_lls_lib/testing/fixtures.py,sha256=_n6bbr95LnQf9Dvu1qKs2HsvHEA7AAbe59B75qxE10w,3310
30
- ai_lls_lib-1.3.2.dist-info/METADATA,sha256=xXK28otz6yXx_MTWyyAxmbR1kn02dXlQY0J9I7NA36g,7248
31
- ai_lls_lib-1.3.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
32
- ai_lls_lib-1.3.2.dist-info/entry_points.txt,sha256=Pi0V_HBViEKGFbNQKatl5lhhnHHBXlxaom-5gH9gXZ0,55
33
- ai_lls_lib-1.3.2.dist-info/RECORD,,
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,,