dominusnode 1.0.0__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.
dominusnode/types.py ADDED
@@ -0,0 +1,521 @@
1
+ """Dominus Node SDK type definitions.
2
+
3
+ Uses TypedDict for JSON-compatible response types. These match the shapes
4
+ returned by the Dominus Node REST API.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Any, List, Optional
10
+ from dataclasses import dataclass, field
11
+
12
+
13
+ # ──────────────────────────────────────────────────────────────────────
14
+ # Auth
15
+ # ──────────────────────────────────────────────────────────────────────
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class User:
20
+ id: str
21
+ email: str
22
+ created_at: str
23
+ is_admin: bool = False
24
+
25
+
26
+ @dataclass(frozen=True, repr=False)
27
+ class LoginResult:
28
+ """Result from login or register. May require MFA."""
29
+
30
+ user: Optional[User] = None
31
+ token: Optional[str] = None
32
+ refresh_token: Optional[str] = None
33
+ mfa_required: bool = False
34
+ mfa_challenge_token: Optional[str] = None
35
+
36
+ def __repr__(self) -> str:
37
+ return f"LoginResult(user={self.user!r}, mfa_required={self.mfa_required}, token={'[REDACTED]' if self.token else None}, refresh_token={'[REDACTED]' if self.refresh_token else None})"
38
+
39
+
40
+ @dataclass(frozen=True)
41
+ class MfaStatus:
42
+ enabled: bool
43
+ backup_codes_remaining: int = 0
44
+
45
+
46
+ @dataclass(frozen=True, repr=False)
47
+ class MfaSetup:
48
+ secret: str
49
+ otpauth_uri: str
50
+ backup_codes: List[str] = field(default_factory=list)
51
+
52
+ def __repr__(self) -> str:
53
+ return f"MfaSetup(secret='[REDACTED]', otpauth_uri='[REDACTED]', backup_codes=[{len(self.backup_codes)} codes])"
54
+
55
+
56
+ # ──────────────────────────────────────────────────────────────────────
57
+ # API Keys
58
+ # ──────────────────────────────────────────────────────────────────────
59
+
60
+
61
+ @dataclass(frozen=True)
62
+ class ApiKey:
63
+ id: str
64
+ prefix: str
65
+ label: str
66
+ created_at: str
67
+ revoked_at: Optional[str] = None
68
+
69
+
70
+ @dataclass(frozen=True, repr=False)
71
+ class CreatedApiKey:
72
+ """Returned only on creation -- includes the raw key (shown once)."""
73
+
74
+ key: str
75
+ id: str
76
+ prefix: str
77
+ label: str
78
+ created_at: str
79
+
80
+ def __repr__(self) -> str:
81
+ return f"CreatedApiKey(id={self.id!r}, prefix={self.prefix!r}, label={self.label!r}, key='[REDACTED]')"
82
+
83
+
84
+ # ──────────────────────────────────────────────────────────────────────
85
+ # Wallet
86
+ # ──────────────────────────────────────────────────────────────────────
87
+
88
+
89
+ @dataclass(frozen=True)
90
+ class Wallet:
91
+ balance_cents: int
92
+ balance_usd: float
93
+ currency: str
94
+ last_topped_up: Optional[str] = None
95
+
96
+
97
+ @dataclass(frozen=True)
98
+ class WalletTransaction:
99
+ id: str
100
+ type: str
101
+ amount_cents: int
102
+ amount_usd: float
103
+ description: str
104
+ payment_provider: Optional[str] = None
105
+ created_at: str = ""
106
+
107
+
108
+ @dataclass(frozen=True)
109
+ class WalletForecast:
110
+ daily_avg_cents: int
111
+ days_remaining: Optional[float]
112
+ trend: str # "up" | "down" | "stable"
113
+ trend_pct: int
114
+
115
+
116
+ @dataclass(frozen=True)
117
+ class StripeCheckout:
118
+ session_id: str
119
+ url: str
120
+
121
+
122
+ @dataclass(frozen=True)
123
+ class CryptoInvoice:
124
+ invoice_id: str
125
+ invoice_url: str
126
+ pay_currency: str
127
+ price_amount: float
128
+
129
+
130
+ @dataclass(frozen=True)
131
+ class PaypalOrder:
132
+ order_id: str
133
+ approval_url: str
134
+ amount_cents: int
135
+
136
+
137
+ # ──────────────────────────────────────────────────────────────────────
138
+ # Usage
139
+ # ──────────────────────────────────────────────────────────────────────
140
+
141
+
142
+ @dataclass(frozen=True)
143
+ class UsageSummary:
144
+ total_bytes: int
145
+ total_cost_cents: int
146
+ request_count: int
147
+ total_gb: float
148
+ total_cost_usd: float
149
+
150
+
151
+ @dataclass(frozen=True)
152
+ class UsageRecord:
153
+ id: str
154
+ session_id: str
155
+ bytes_in: int
156
+ bytes_out: int
157
+ total_bytes: int
158
+ cost_cents: int
159
+ proxy_type: str
160
+ target_host: str
161
+ created_at: str
162
+
163
+
164
+ @dataclass(frozen=True)
165
+ class UsagePagination:
166
+ limit: int
167
+ offset: int
168
+ total: int
169
+
170
+
171
+ @dataclass(frozen=True)
172
+ class UsagePeriod:
173
+ since: str
174
+ until: str
175
+
176
+
177
+ @dataclass(frozen=True)
178
+ class UsageResponse:
179
+ summary: UsageSummary
180
+ records: List[UsageRecord]
181
+ pagination: UsagePagination
182
+ period: UsagePeriod
183
+
184
+
185
+ @dataclass(frozen=True)
186
+ class DailyUsage:
187
+ date: str
188
+ total_bytes: int
189
+ total_gb: float
190
+ total_cost_cents: int
191
+ total_cost_usd: float
192
+ request_count: int
193
+
194
+
195
+ @dataclass(frozen=True)
196
+ class TopHost:
197
+ target_host: str
198
+ total_bytes: int
199
+ total_gb: float
200
+ request_count: int
201
+
202
+
203
+ # ──────────────────────────────────────────────────────────────────────
204
+ # Plans
205
+ # ──────────────────────────────────────────────────────────────────────
206
+
207
+
208
+ @dataclass(frozen=True)
209
+ class Plan:
210
+ id: str
211
+ name: str
212
+ price_per_gb_cents: int
213
+ price_per_gb_usd: float
214
+ monthly_bandwidth_bytes: int
215
+ monthly_bandwidth_gb: Optional[float]
216
+ is_default: bool
217
+
218
+
219
+ @dataclass(frozen=True)
220
+ class UserPlanUsage:
221
+ monthly_usage_bytes: int
222
+ monthly_usage_gb: float
223
+ limit_bytes: int
224
+ limit_gb: Optional[float]
225
+ percent_used: Optional[float]
226
+
227
+
228
+ @dataclass(frozen=True)
229
+ class UserPlanInfo:
230
+ plan: Plan
231
+ usage: UserPlanUsage
232
+
233
+
234
+ # ──────────────────────────────────────────────────────────────────────
235
+ # Sessions
236
+ # ──────────────────────────────────────────────────────────────────────
237
+
238
+
239
+ @dataclass(frozen=True)
240
+ class ActiveSession:
241
+ id: str
242
+ started_at: str
243
+ status: str
244
+
245
+
246
+ # ──────────────────────────────────────────────────────────────────────
247
+ # Proxy
248
+ # ──────────────────────────────────────────────────────────────────────
249
+
250
+
251
+ @dataclass(frozen=True)
252
+ class ProxyUrlOptions:
253
+ """Options for building a proxy URL."""
254
+
255
+ country: Optional[str] = None
256
+ state: Optional[str] = None
257
+ city: Optional[str] = None
258
+ asn: Optional[int] = None # ASN targeting (API parity with Node.js/C++/Rust)
259
+ session_id: Optional[str] = None
260
+ protocol: str = "http" # "http" or "socks5"
261
+
262
+
263
+ @dataclass(frozen=True)
264
+ class ProxyHealth:
265
+ status: str
266
+ active_sessions: int
267
+ uptime_seconds: int
268
+
269
+
270
+ @dataclass(frozen=True)
271
+ class ProviderStat:
272
+ name: str
273
+ state: str
274
+ consecutive_failures: int
275
+ total_requests: int
276
+ total_errors: int
277
+ avg_latency_ms: float
278
+ fallback_only: bool
279
+
280
+
281
+ @dataclass(frozen=True)
282
+ class ProxyEndpoints:
283
+ http: str
284
+ socks5: str
285
+
286
+
287
+ @dataclass(frozen=True)
288
+ class ProxyStatus:
289
+ status: str
290
+ active_sessions: int
291
+ user_active_sessions: int
292
+ avg_latency_ms: float
293
+ providers: List[ProviderStat]
294
+ endpoints: ProxyEndpoints
295
+ supported_countries: List[str]
296
+ uptime_seconds: int
297
+
298
+
299
+ @dataclass(frozen=True)
300
+ class GeoTargeting:
301
+ state_support: bool
302
+ city_support: bool
303
+ asn_support: bool
304
+ us_states: List[Any] = field(default_factory=list)
305
+ major_us_cities: List[Any] = field(default_factory=list)
306
+
307
+
308
+ @dataclass(frozen=True)
309
+ class ProxyEndpointConfig:
310
+ host: str
311
+ port: int
312
+
313
+
314
+ @dataclass(frozen=True)
315
+ class ProxyConfig:
316
+ http_proxy: ProxyEndpointConfig
317
+ socks5_proxy: ProxyEndpointConfig
318
+ supported_countries: List[str]
319
+ blocked_countries: List[str]
320
+ max_rotation_interval_minutes: int
321
+ min_rotation_interval_minutes: int
322
+ geo_targeting: GeoTargeting
323
+
324
+
325
+ # ──────────────────────────────────────────────────────────────────────
326
+ # Admin
327
+ # ──────────────────────────────────────────────────────────────────────
328
+
329
+
330
+ @dataclass(frozen=True)
331
+ class AdminUser:
332
+ id: str
333
+ email: str
334
+ status: str
335
+ plan_id: str
336
+ balance_cents: int
337
+ created_at: str
338
+ is_admin: bool
339
+
340
+
341
+ @dataclass(frozen=True)
342
+ class AdminUserDetail:
343
+ id: str
344
+ email: str
345
+ status: str
346
+ plan_id: str
347
+ balance_cents: int
348
+ created_at: str
349
+ is_admin: bool
350
+ api_key_count: int
351
+ total_usage_bytes: int
352
+ total_spent_cents: int
353
+ last_active: Optional[str]
354
+
355
+
356
+ @dataclass(frozen=True)
357
+ class Pagination:
358
+ page: int
359
+ limit: int
360
+ total: int
361
+ total_pages: int
362
+
363
+
364
+ @dataclass(frozen=True)
365
+ class AdminUsersResponse:
366
+ users: List[AdminUser]
367
+ pagination: Pagination
368
+
369
+
370
+ @dataclass(frozen=True)
371
+ class RevenueStats:
372
+ total_revenue_cents: int
373
+ total_revenue_usd: float
374
+ total_transactions: int
375
+ avg_transaction_cents: int
376
+ avg_transaction_usd: float
377
+ top_up_count: int
378
+ unique_paying_users: int
379
+ period: UsagePeriod
380
+
381
+
382
+ @dataclass(frozen=True)
383
+ class DailyRevenue:
384
+ date: str
385
+ revenue_cents: int
386
+ revenue_usd: float
387
+ transaction_count: int
388
+
389
+
390
+ @dataclass(frozen=True)
391
+ class SystemStats:
392
+ total_users: int
393
+ active_users: int
394
+ suspended_users: int
395
+ total_api_keys: int
396
+ active_api_keys: int
397
+ total_sessions: int
398
+ active_sessions: int
399
+
400
+
401
+ # ──────────────────────────────────────────────────────────────────────
402
+ # Slots & Waitlist
403
+ # ──────────────────────────────────────────────────────────────────────
404
+
405
+
406
+ @dataclass(frozen=True)
407
+ class SlotsInfo:
408
+ total: int
409
+ used: int
410
+ remaining: int
411
+ unlimited: bool
412
+
413
+
414
+ @dataclass(frozen=True)
415
+ class WaitlistJoinResult:
416
+ message: str
417
+
418
+
419
+ @dataclass(frozen=True)
420
+ class WaitlistCount:
421
+ pending: int
422
+
423
+
424
+ # ──────────────────────────────────────────────────────────────────────
425
+ # Agentic Wallets
426
+ # ──────────────────────────────────────────────────────────────────────
427
+
428
+
429
+ @dataclass(frozen=True)
430
+ class AgenticWallet:
431
+ id: str
432
+ label: str
433
+ balance_cents: int
434
+ spending_limit_cents: int
435
+ status: str
436
+ created_at: str = ""
437
+ daily_limit_cents: Optional[int] = None
438
+ allowed_domains: Optional[List[str]] = None
439
+
440
+
441
+ @dataclass(frozen=True)
442
+ class AgenticWalletTransaction:
443
+ id: str
444
+ wallet_id: str
445
+ type: str
446
+ amount_cents: int
447
+ description: str
448
+ session_id: Optional[str] = None
449
+ created_at: str = ""
450
+
451
+
452
+ # ──────────────────────────────────────────────────────────────────────
453
+ # Teams
454
+ # ──────────────────────────────────────────────────────────────────────
455
+
456
+
457
+ @dataclass(frozen=True)
458
+ class Team:
459
+ id: str
460
+ name: str
461
+ owner_id: str
462
+ max_members: int
463
+ status: str
464
+ balance_cents: int
465
+ created_at: str = ""
466
+
467
+
468
+ @dataclass(frozen=True)
469
+ class TeamMember:
470
+ id: str
471
+ team_id: str
472
+ user_id: str
473
+ email: str
474
+ role: str
475
+ joined_at: str = ""
476
+
477
+
478
+ @dataclass(frozen=True)
479
+ class TeamInvite:
480
+ id: str
481
+ team_id: str
482
+ email: str
483
+ role: str
484
+ token: str = ""
485
+ expires_at: str = ""
486
+ created_at: str = ""
487
+
488
+
489
+ @dataclass(frozen=True)
490
+ class TeamTransaction:
491
+ id: str
492
+ team_id: str
493
+ type: str
494
+ amount_cents: int
495
+ description: str
496
+ created_at: str = ""
497
+
498
+
499
+ @dataclass(frozen=True)
500
+ class TeamKey:
501
+ id: str
502
+ key_prefix: str
503
+ label: str
504
+ created_at: str = ""
505
+
506
+
507
+ @dataclass(frozen=True, repr=False)
508
+ class TeamKeyCreateResponse:
509
+ """Returned only on creation -- includes the raw key (shown once)."""
510
+ id: str
511
+ key: str
512
+ key_prefix: str
513
+ label: str
514
+
515
+ def __repr__(self) -> str:
516
+ return f"TeamKeyCreateResponse(id={self.id!r}, key_prefix={self.key_prefix!r}, label={self.label!r}, key='[REDACTED]')"
517
+
518
+
519
+ @dataclass(frozen=True)
520
+ class TeamDeleteResponse:
521
+ refunded_cents: int