agentpay-python 0.1.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.
agentpay/__init__.py ADDED
@@ -0,0 +1,23 @@
1
+ """AgentPay Python SDK — AI agent ödeme altyapısı."""
2
+
3
+ from .client import AgentPayClient
4
+ from .models import (
5
+ ClientInfo,
6
+ BalanceInfo,
7
+ PaywallResponse,
8
+ SpendResult,
9
+ TopupResponse,
10
+ RegisterResponse,
11
+ ForecastResult,
12
+ )
13
+
14
+ __all__ = [
15
+ "AgentPayClient",
16
+ "ClientInfo",
17
+ "BalanceInfo",
18
+ "PaywallResponse",
19
+ "SpendResult",
20
+ "TopupResponse",
21
+ "RegisterResponse",
22
+ "ForecastResult",
23
+ ]
agentpay/client.py ADDED
@@ -0,0 +1,231 @@
1
+ """AgentPay Python SDK istemci sınıfı."""
2
+
3
+ import hashlib
4
+ import hmac
5
+ import time
6
+ from typing import Optional
7
+ from urllib.parse import urljoin
8
+
9
+ import httpx
10
+
11
+ from .models import (
12
+ BalanceInfo,
13
+ ClientInfo,
14
+ ForecastResult,
15
+ PaywallResponse,
16
+ RegisterResponse,
17
+ SpendResult,
18
+ TopupResponse,
19
+ )
20
+
21
+
22
+ class AgentPayClient:
23
+ """AgentPay API istemcisi.
24
+
25
+ Kullanım:
26
+ client = AgentPayClient(api_key="sg_...", base_url="https://api.aipp.dev")
27
+ bal = client.get_balance()
28
+ result = client.spend(amount=5.0, description="AI call #42")
29
+ """
30
+
31
+ def __init__(
32
+ self,
33
+ api_key: str,
34
+ base_url: str = "https://api.aipp.dev",
35
+ timeout: float = 30.0,
36
+ admin_token: Optional[str] = None,
37
+ ):
38
+ self.api_key = api_key
39
+ self.base_url = base_url.rstrip("/")
40
+ self.admin_token = admin_token
41
+ self._client = httpx.Client(
42
+ base_url=self.base_url,
43
+ timeout=httpx.Timeout(timeout),
44
+ headers={"X-API-Key": api_key},
45
+ )
46
+
47
+ # ────────────────────────────────
48
+ # Auth / Kayıt
49
+ # ────────────────────────────────
50
+
51
+ def register(self, idempotency_key: Optional[str] = None) -> RegisterResponse:
52
+ """Yeni API key + kredi al (auth gerekmez)."""
53
+ headers = {}
54
+ if idempotency_key:
55
+ headers["Idempotency-Key"] = idempotency_key
56
+ resp = self._client.post("/v1/auth/register", headers=headers)
57
+ resp.raise_for_status()
58
+ data = resp.json()
59
+ return RegisterResponse(
60
+ api_key=data["api_key"],
61
+ credits=data["credits"],
62
+ client_id=data["client_id"],
63
+ )
64
+
65
+ # ────────────────────────────────
66
+ # Bakiye
67
+ # ────────────────────────────────
68
+
69
+ def get_balance(self) -> BalanceInfo:
70
+ """Mevcut bakiyeyi sorgula."""
71
+ resp = self._client.get("/v1/balance")
72
+ resp.raise_for_status()
73
+ data = resp.json()
74
+ return BalanceInfo(
75
+ balance=data["balance"],
76
+ credits_used=data["credits_used"],
77
+ credits_remaining=data["credits_remaining"],
78
+ )
79
+
80
+ def forecast(
81
+ self, estimated_cost_per_call: float = 0.01
82
+ ) -> ForecastResult:
83
+ """Bakiye yetecek mi tahmini."""
84
+ bal = self.get_balance()
85
+ will_exhaust = estimated_cost_per_call > 0 and (
86
+ bal.credits_remaining / estimated_cost_per_call < 100
87
+ )
88
+ return ForecastResult(
89
+ current_balance=bal.credits_remaining,
90
+ estimated_cost_per_call=estimated_cost_per_call,
91
+ estimated_calls_remaining=(
92
+ int(bal.credits_remaining / estimated_cost_per_call)
93
+ if estimated_cost_per_call > 0
94
+ else 0
95
+ ),
96
+ will_exhaust=will_exhaust,
97
+ total_spent_all_time=bal.credits_used,
98
+ )
99
+
100
+ # ────────────────────────────────
101
+ # Harcama
102
+ # ────────────────────────────────
103
+
104
+ def spend(
105
+ self,
106
+ amount: float,
107
+ description: str = "",
108
+ idempotency_key: Optional[str] = None,
109
+ ) -> SpendResult:
110
+ """Kredi harca (idempotent)."""
111
+ payload: dict = {
112
+ "amount": amount,
113
+ "description": description or f"spend-{int(time.time())}",
114
+ }
115
+ headers = {}
116
+ if idempotency_key:
117
+ headers["Idempotency-Key"] = idempotency_key
118
+ resp = self._client.post(
119
+ "/v1/spend", json=payload, headers=headers
120
+ )
121
+ resp.raise_for_status()
122
+ data = resp.json()
123
+ return SpendResult(
124
+ success=data.get("success", True),
125
+ credits_used=data.get("credits_used", amount),
126
+ credits_remaining=data.get("credits_remaining", 0),
127
+ message=data.get("message", ""),
128
+ )
129
+
130
+ # ────────────────────────────────
131
+ # Paywall (L402)
132
+ # ────────────────────────────────
133
+
134
+ def generate_paywall(
135
+ self,
136
+ amount: float,
137
+ description: str = "",
138
+ metadata: Optional[dict] = None,
139
+ ) -> PaywallResponse:
140
+ """LN faturası oluştur — müşteri ödeyince token alır."""
141
+ payload = {
142
+ "amount": amount,
143
+ "description": description or "AgentPay paywall",
144
+ }
145
+ if metadata:
146
+ payload["metadata"] = metadata
147
+ resp = self._client.post("/v1/paywall", json=payload)
148
+ resp.raise_for_status()
149
+ data = resp.json()
150
+ return PaywallResponse(
151
+ token=data["token"],
152
+ cost=data["cost"],
153
+ invoice=data["invoice"],
154
+ paid=False,
155
+ )
156
+
157
+ def verify_paywall(self, token: str) -> PaywallResponse:
158
+ """Ödeme durumunu kontrol et."""
159
+ resp = self._client.get(f"/v1/paywall/{token}")
160
+ resp.raise_for_status()
161
+ data = resp.json()
162
+ return PaywallResponse(
163
+ token=token,
164
+ cost=data.get("cost", 0),
165
+ invoice=data.get("invoice", ""),
166
+ paid=data.get("paid", False),
167
+ )
168
+
169
+ # ────────────────────────────────
170
+ # Bakiye Yükleme
171
+ # ────────────────────────────────
172
+
173
+ def topup(self, usd_amount: float = 5.0) -> TopupResponse:
174
+ """LN faturası ile kredi yükle."""
175
+ resp = self._client.post(
176
+ "/v1/topup", json={"usd_amount": usd_amount}
177
+ )
178
+ resp.raise_for_status()
179
+ data = resp.json()
180
+ return TopupResponse(
181
+ success=data.get("success", True),
182
+ invoice=data["invoice"],
183
+ credits=data.get("credits", usd_amount * 100),
184
+ usd_amount=usd_amount,
185
+ )
186
+
187
+ # ────────────────────────────────
188
+ # Admin (admin_token gerekli)
189
+ # ────────────────────────────────
190
+
191
+ def list_clients(self) -> list[ClientInfo]:
192
+ """Tüm müşterileri listele (admin)."""
193
+ if not self.admin_token:
194
+ raise ValueError("admin_token required for list_clients")
195
+ resp = self._client.get(
196
+ "/v1/admin/clients",
197
+ headers={"Authorization": f"Bearer {self.admin_token}"},
198
+ )
199
+ resp.raise_for_status()
200
+ return [
201
+ ClientInfo(
202
+ id=c["id"],
203
+ api_key=c.get("api_key", ""),
204
+ credits_used=c.get("credits_used", 0),
205
+ is_admin=c.get("is_admin", False),
206
+ )
207
+ for c in resp.json()
208
+ ]
209
+
210
+ def get_client(self, client_id: str) -> ClientInfo:
211
+ """Müşteri detayı (admin)."""
212
+ if not self.admin_token:
213
+ raise ValueError("admin_token required for get_client")
214
+ resp = self._client.get(
215
+ f"/v1/admin/clients/{client_id}",
216
+ headers={"Authorization": f"Bearer {self.admin_token}"},
217
+ )
218
+ resp.raise_for_status()
219
+ c = resp.json()
220
+ return ClientInfo(
221
+ id=c["id"],
222
+ api_key=c.get("api_key", ""),
223
+ credits_used=c.get("credits_used", 0),
224
+ is_admin=c.get("is_admin", False),
225
+ )
226
+
227
+ def health(self) -> dict:
228
+ """API sağlık kontrolü."""
229
+ resp = self._client.get("/health")
230
+ resp.raise_for_status()
231
+ return resp.json()
agentpay/models.py ADDED
@@ -0,0 +1,64 @@
1
+ from dataclasses import dataclass, field
2
+ from typing import Optional
3
+
4
+
5
+ @dataclass
6
+ class ClientInfo:
7
+ """Müşteri bilgisi."""
8
+ id: str
9
+ api_key: str
10
+ credits_used: float = 0.0
11
+ is_admin: bool = False
12
+
13
+
14
+ @dataclass
15
+ class BalanceInfo:
16
+ """Bakiye bilgisi."""
17
+ balance: float
18
+ credits_used: float
19
+ credits_remaining: float
20
+
21
+
22
+ @dataclass
23
+ class PaywallResponse:
24
+ """L402 paywall yanıtı."""
25
+ token: str
26
+ cost: float
27
+ invoice: str # Lightning fatura
28
+ paid: bool = False
29
+
30
+
31
+ @dataclass
32
+ class SpendResult:
33
+ """Harcama sonucu."""
34
+ success: bool
35
+ credits_used: float
36
+ credits_remaining: float
37
+ message: str = ""
38
+
39
+
40
+ @dataclass
41
+ class TopupResponse:
42
+ """Bakiye yükleme yanıtı."""
43
+ success: bool
44
+ invoice: str
45
+ credits: float
46
+ usd_amount: float
47
+
48
+
49
+ @dataclass
50
+ class RegisterResponse:
51
+ """Kayıt yanıtı."""
52
+ api_key: str
53
+ credits: float
54
+ client_id: str
55
+
56
+
57
+ @dataclass
58
+ class ForecastResult:
59
+ """Bakiye tahmini."""
60
+ current_balance: float
61
+ estimated_cost_per_call: float
62
+ estimated_calls_remaining: int
63
+ will_exhaust: bool
64
+ total_spent_all_time: float = 0.0
@@ -0,0 +1,65 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentpay-python
3
+ Version: 0.1.0
4
+ Summary: AgentPay Python SDK — AI agent ödeme altyapısı
5
+ Author-email: AIPP <aippcore@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://api.aipp.dev
8
+ Project-URL: Source, https://github.com/aippdev/agentpay-python
9
+ Project-URL: Documentation, https://api.aipp.dev/docs
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
19
+ Classifier: Topic :: Internet :: WWW/HTTP
20
+ Requires-Python: >=3.9
21
+ Description-Content-Type: text/markdown
22
+ Requires-Dist: httpx>=0.25.0
23
+
24
+ # AgentPay Python SDK
25
+
26
+ AI agent'lar için Lightning Network tabanlı ödeme altyapısı.
27
+
28
+ ## Kurulum
29
+
30
+ ```bash
31
+ pip install agentpay-sdk
32
+ ```
33
+
34
+ ## Kullanım
35
+
36
+ ```python
37
+ from agentpay import AgentPayClient
38
+
39
+ # Yeni API key al (50 ücretsiz kredi ile)
40
+ client = AgentPayClient(api_key="sg_...")
41
+ bal = client.get_balance()
42
+ print(f"Bakiye: {bal.credits_remaining} kredi")
43
+
44
+ # Kredi harca (idempotent)
45
+ result = client.spend(amount=5.0, description="AI çağrısı")
46
+ print(f"Harcandı: {result.credits_used}, Kalan: {result.credits_remaining}")
47
+
48
+ # Bakiye tahmini
49
+ forecast = client.forecast(estimated_cost_per_call=0.05)
50
+ if forecast.will_exhaust:
51
+ print("Bakiye azalıyor!")
52
+ print(f"Tahmini çağrı: {forecast.estimated_calls_remaining}")
53
+
54
+ # Paywall (L402) — LN faturası ile ödeme
55
+ pw = client.generate_paywall(amount=10.0, description="Premium içerik")
56
+ print(f"Fatura: {pw.invoice}")
57
+
58
+ # Topup — kredi yükle
59
+ top = client.topup(usd_amount=5.0)
60
+ print(f"Yükleme faturası: {top.invoice}")
61
+ ```
62
+
63
+ ## API Referansı
64
+
65
+ Tüm metodlar ve modeller için: [api.aipp.dev/docs](https://api.aipp.dev/docs)
@@ -0,0 +1,7 @@
1
+ agentpay/__init__.py,sha256=iEEAvrvocGGW9BCh5oN89zbHvRA8Ftd7Rd2_FNTsIqY,434
2
+ agentpay/client.py,sha256=6-DuXhDn5JJk81dacXHNSAQimFDPkBNCryiT27kmP9g,7955
3
+ agentpay/models.py,sha256=lCvwx_NRhDNR5ywrsU4L33zSONzv9sXynvpjHMSQhjs,1140
4
+ agentpay_python-0.1.0.dist-info/METADATA,sha256=6ue-5GHLgFBT4AolE7jo7mnd00MxNVDXfiKB3shmBdk,2019
5
+ agentpay_python-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
6
+ agentpay_python-0.1.0.dist-info/top_level.txt,sha256=-ZKxHLESIWgQ31Vn1cP5LAtq7d3iqrmzjYCw6E7zrz0,9
7
+ agentpay_python-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ agentpay