weco 0.2.28__py3-none-any.whl → 0.3.1__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.
weco/credits.py ADDED
@@ -0,0 +1,172 @@
1
+ """Credit management commands for the Weco CLI."""
2
+
3
+ import webbrowser
4
+ import requests
5
+ from rich.console import Console
6
+ from rich.table import Table
7
+ from . import __base_url__
8
+ from .api import handle_api_error
9
+ from .auth import load_weco_api_key, handle_authentication
10
+
11
+
12
+ def handle_credits_command(args, console: Console) -> None:
13
+ """Handle the credits command and its subcommands."""
14
+ # Ensure user is authenticated
15
+ weco_api_key = load_weco_api_key()
16
+ if not weco_api_key:
17
+ console.print("[bold yellow]Authentication Required[/]")
18
+ console.print("You need to be logged in to manage credits.")
19
+ weco_api_key, _ = handle_authentication(console)
20
+ if not weco_api_key:
21
+ console.print("[bold red]Authentication failed. Please run 'weco' to log in.[/]")
22
+ return
23
+
24
+ auth_headers = {"Authorization": f"Bearer {weco_api_key}"}
25
+
26
+ if args.credits_command == "balance" or args.credits_command is None:
27
+ check_balance(console, auth_headers)
28
+ elif args.credits_command == "topup":
29
+ topup_credits(console, auth_headers, args.amount)
30
+ elif args.credits_command == "autotopup":
31
+ configure_autotopup(console, auth_headers, args)
32
+ else:
33
+ console.print(f"[bold red]Unknown credits command: {args.credits_command}[/]")
34
+
35
+
36
+ def check_balance(console: Console, auth_headers: dict) -> None:
37
+ """Check and display the current credit balance."""
38
+ try:
39
+ response = requests.get(f"{__base_url__}/billing/balance", headers=auth_headers, timeout=10)
40
+ response.raise_for_status()
41
+ data = response.json()
42
+
43
+ balance = data.get("balance_credits", 0)
44
+
45
+ # Create a nice table display
46
+ table = Table(title="Weco Credit Balance", show_header=True, header_style="bold cyan")
47
+ table.add_column("Balance", style="green", justify="right")
48
+ table.add_column("Status", justify="left")
49
+
50
+ status = "✅ Good" if balance > 10 else "⚠️ Low" if balance > 0 else "❌ Empty"
51
+ table.add_row(f"{balance:.2f} credits", status)
52
+
53
+ console.print(table)
54
+
55
+ if balance < 10:
56
+ console.print("\n[yellow]💡 Tip: You're running low on credits. Run 'weco credits topup' to add more.[/]")
57
+
58
+ except requests.exceptions.HTTPError as e:
59
+ if e.response.status_code == 401:
60
+ console.print("[bold red]Authentication failed. Please log in again with 'weco'.[/]")
61
+ else:
62
+ console.print(f"[bold red]Error checking balance: {e}[/]")
63
+ except Exception as e:
64
+ console.print(f"[bold red]Unexpected error: {e}[/]")
65
+
66
+
67
+ def topup_credits(console: Console, auth_headers: dict, amount: float) -> None:
68
+ """Initiate a credit top-up via Stripe."""
69
+ try:
70
+ console.print(f"[cyan]Preparing to purchase {amount:.2f} credits...[/]")
71
+
72
+ response = requests.post(
73
+ f"{__base_url__}/billing/topup/checkout", headers=auth_headers, json={"amount": amount}, timeout=10
74
+ )
75
+ response.raise_for_status()
76
+ data = response.json()
77
+
78
+ checkout_url = data.get("checkout_url")
79
+ if checkout_url:
80
+ console.print("\n[bold green]✅ Checkout session created![/]")
81
+ console.print(f"Total: {amount:.2f} credits")
82
+ console.print("\n[yellow]Opening checkout page in your browser...[/]")
83
+
84
+ # Try to open the browser
85
+ try:
86
+ if webbrowser.open(checkout_url):
87
+ console.print("[green]Browser opened successfully![/]")
88
+ else:
89
+ console.print(f"[yellow]Please open this URL manually:[/]\n{checkout_url}")
90
+ except Exception:
91
+ console.print(f"[yellow]Please open this URL in your browser:[/]\n{checkout_url}")
92
+
93
+ console.print("\n[dim]Complete the payment in your browser. Your credits will be added automatically.[/]")
94
+ else:
95
+ console.print("[bold red]Error: No checkout URL received.[/]")
96
+
97
+ except requests.exceptions.HTTPError as e:
98
+ response = getattr(e, "response", None)
99
+
100
+ if response is not None and response.status_code == 401:
101
+ console.print("[bold red]Authentication failed. Please log in again with 'weco'.[/]")
102
+ else:
103
+ console.print("[bold red]Error creating checkout session[/]")
104
+ handle_api_error(e, console)
105
+ except Exception as e:
106
+ console.print(f"[bold red]Unexpected error: {e}[/]")
107
+
108
+
109
+ def configure_autotopup(console: Console, auth_headers: dict, args) -> None:
110
+ """Configure automatic top-up settings."""
111
+ try:
112
+ # Handle conflicting flags
113
+ if args.enable and args.disable:
114
+ console.print("[bold red]Error: Cannot use both --enable and --disable flags.[/]")
115
+ return
116
+
117
+ # If neither flag is set, show current settings
118
+ if not args.enable and not args.disable:
119
+ # Get current auto top-up settings from API
120
+ response = requests.get(f"{__base_url__}/billing/auto-topup", headers=auth_headers, timeout=10)
121
+ response.raise_for_status()
122
+ settings_data = response.json()
123
+
124
+ # Also check if user has a payment method
125
+ balance_response = requests.get(f"{__base_url__}/billing/balance", headers=auth_headers, timeout=10)
126
+ balance_response.raise_for_status()
127
+ balance_data = balance_response.json()
128
+
129
+ has_payment_method = bool(balance_data.get("stripe_customer_id"))
130
+
131
+ console.print("[cyan]Current Auto Top-Up Settings:[/]")
132
+
133
+ if settings_data.get("enabled"):
134
+ if has_payment_method:
135
+ console.print("Status: [green]✅ Enabled[/]")
136
+ else:
137
+ console.print("Status: [yellow]⚠️ Enabled but no payment method saved[/]")
138
+ else:
139
+ console.print("Status: [red]❌ Disabled[/]")
140
+
141
+ console.print(f"Threshold: {settings_data.get('threshold_credits', 4.0)} credits")
142
+ console.print(f"Top-up Amount: {settings_data.get('topup_amount_credits', 50.0)} credits")
143
+
144
+ if not has_payment_method:
145
+ console.print("\n[yellow]💡 Note: Auto top-up requires a saved payment method.[/]")
146
+ console.print("Complete a manual top-up first to save your payment details.")
147
+
148
+ console.print("\nUse --enable or --disable to change settings.")
149
+ return
150
+
151
+ # Configure auto top-up
152
+ settings = {"enabled": args.enable, "threshold_credits": args.threshold, "topup_amount_credits": args.amount}
153
+
154
+ response = requests.post(f"{__base_url__}/billing/auto-topup", headers=auth_headers, json=settings, timeout=10)
155
+ response.raise_for_status()
156
+
157
+ if args.enable:
158
+ console.print("[bold green]✅ Auto top-up enabled![/]")
159
+ console.print(f"When your balance falls below {args.threshold} credits,")
160
+ console.print(f"we'll automatically add {args.amount} credits to your account.")
161
+ console.print("\n[yellow]Note: Requires a saved payment method.[/]")
162
+ else:
163
+ console.print("[bold green]✅ Auto top-up disabled![/]")
164
+ console.print("You'll need to manually top up your credits when running low.")
165
+
166
+ except requests.exceptions.HTTPError as e:
167
+ if e.response.status_code == 401:
168
+ console.print("[bold red]Authentication failed. Please log in again with 'weco'.[/]")
169
+ else:
170
+ console.print(f"[bold red]Error configuring auto top-up: {e}[/]")
171
+ except Exception as e:
172
+ console.print(f"[bold red]Unexpected error: {e}[/]")