growflowbilling-client 1.2.0__tar.gz

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.
Files changed (33) hide show
  1. growflowbilling_client-1.2.0/.gitignore +66 -0
  2. growflowbilling_client-1.2.0/LICENSE +21 -0
  3. growflowbilling_client-1.2.0/PKG-INFO +247 -0
  4. growflowbilling_client-1.2.0/PUBLISHING.md +73 -0
  5. growflowbilling_client-1.2.0/README.md +216 -0
  6. growflowbilling_client-1.2.0/pyproject.toml +62 -0
  7. growflowbilling_client-1.2.0/src/growflow_billing/__init__.py +83 -0
  8. growflowbilling_client-1.2.0/src/growflow_billing/client.py +261 -0
  9. growflowbilling_client-1.2.0/src/growflow_billing/config.py +36 -0
  10. growflowbilling_client-1.2.0/src/growflow_billing/endpoints/__init__.py +17 -0
  11. growflowbilling_client-1.2.0/src/growflow_billing/endpoints/admin_products.py +221 -0
  12. growflowbilling_client-1.2.0/src/growflow_billing/endpoints/checkout.py +114 -0
  13. growflowbilling_client-1.2.0/src/growflow_billing/endpoints/invoices.py +125 -0
  14. growflowbilling_client-1.2.0/src/growflow_billing/endpoints/plans.py +48 -0
  15. growflowbilling_client-1.2.0/src/growflow_billing/endpoints/products.py +138 -0
  16. growflowbilling_client-1.2.0/src/growflow_billing/endpoints/subscribers.py +130 -0
  17. growflowbilling_client-1.2.0/src/growflow_billing/endpoints/subscriptions.py +187 -0
  18. growflowbilling_client-1.2.0/src/growflow_billing/exceptions.py +59 -0
  19. growflowbilling_client-1.2.0/src/growflow_billing/models/__init__.py +24 -0
  20. growflowbilling_client-1.2.0/src/growflow_billing/models/admin_product.py +66 -0
  21. growflowbilling_client-1.2.0/src/growflow_billing/models/checkout.py +52 -0
  22. growflowbilling_client-1.2.0/src/growflow_billing/models/invoice.py +80 -0
  23. growflowbilling_client-1.2.0/src/growflow_billing/models/plan.py +83 -0
  24. growflowbilling_client-1.2.0/src/growflow_billing/models/product.py +73 -0
  25. growflowbilling_client-1.2.0/src/growflow_billing/models/subscriber.py +50 -0
  26. growflowbilling_client-1.2.0/src/growflow_billing/models/subscription.py +84 -0
  27. growflowbilling_client-1.2.0/src/growflow_billing/utils/__init__.py +10 -0
  28. growflowbilling_client-1.2.0/src/growflow_billing/utils/helpers.py +110 -0
  29. growflowbilling_client-1.2.0/src/growflow_billing/utils/retry.py +80 -0
  30. growflowbilling_client-1.2.0/src/growflow_billing/webhooks.py +337 -0
  31. growflowbilling_client-1.2.0/tests/__init__.py +1 -0
  32. growflowbilling_client-1.2.0/tests/conftest.py +32 -0
  33. growflowbilling_client-1.2.0/tests/test_client.py +1225 -0
@@ -0,0 +1,66 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual Environment
24
+ venv/
25
+ ENV/
26
+ env/
27
+ .venv
28
+
29
+ # Environment
30
+ .env
31
+ .env.local
32
+ .env.*.local
33
+
34
+ # IDEs
35
+ .vscode/
36
+ .idea/
37
+ *.swp
38
+ *.swo
39
+ *~
40
+ .DS_Store
41
+
42
+ # Testing
43
+ .pytest_cache/
44
+ .coverage
45
+ htmlcov/
46
+ *.cover
47
+
48
+ # Database
49
+ *.db
50
+
51
+ # Logs
52
+ *.log
53
+
54
+ # Alembic
55
+ # Uncommit migrations/versions/ in production
56
+
57
+ # Node (for admin dashboard)
58
+ node_modules/
59
+ .pnpm-store/
60
+ dist/
61
+ build/
62
+
63
+ # Exception: keep admin-dashboard src/lib
64
+ !platform/admin-dashboard/src/lib/
65
+
66
+ full-version/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 GrowFlow
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,247 @@
1
+ Metadata-Version: 2.4
2
+ Name: growflowbilling-client
3
+ Version: 1.2.0
4
+ Summary: Python client for GrowFlow Billing API - subscription management, checkout, invoices
5
+ Project-URL: Homepage, https://github.com/giuliogarofalo/growflow-billing
6
+ Project-URL: Documentation, https://docs.growflow.studio/billing-client
7
+ Project-URL: Repository, https://github.com/giuliogarofalo/growflow-billing
8
+ Author-email: GrowFlow <dev@growflow.studio>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: billing,payments,saas,stripe,subscriptions
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: httpx>=0.25.0
23
+ Requires-Dist: pydantic[email]>=2.0.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
26
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
27
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
28
+ Requires-Dist: respx>=0.20.0; extra == 'dev'
29
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # GrowFlow Billing Client
33
+
34
+ Python client for [GrowFlow Billing API](https://billing.growflow.studio) - subscription management, checkout sessions, invoices, and more.
35
+
36
+ > **Documentation**: See [growflow-billing-docs](https://github.com/growflow/growflow-billing-docs) for complete API documentation and examples.
37
+ >
38
+ > **Node.js**: Looking for the Node.js/TypeScript client? See [@growflow/billing-client](https://github.com/growflow/growflow-billing-client-node).
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ pip install growflow-billing-client
44
+ ```
45
+
46
+ Or install from source:
47
+
48
+ ```bash
49
+ pip install git+https://github.com/growflow/growflow-billing-client.git
50
+ ```
51
+
52
+ ## Quick Start
53
+
54
+ ```python
55
+ import asyncio
56
+ from growflow_billing import GrowFlowBillingClient
57
+
58
+ async def main():
59
+ async with GrowFlowBillingClient(api_key="sk_live_xxx") as client:
60
+ # Get available plans
61
+ plans = await client.get_plans()
62
+ for plan in plans:
63
+ print(f"{plan.name}: {plan.price_monthly} {plan.currency}/month")
64
+
65
+ # Create a checkout session
66
+ session = await client.create_checkout_session(
67
+ customer_external_id="customer_123",
68
+ plan_slug="pro",
69
+ billing_cycle="monthly",
70
+ success_url="https://yourapp.com/billing?status=success",
71
+ cancel_url="https://yourapp.com/billing?status=canceled",
72
+ )
73
+ print(f"Checkout URL: {session.checkout_url}")
74
+
75
+ asyncio.run(main())
76
+ ```
77
+
78
+ ## Features
79
+
80
+ - **Plans**: List available subscription plans
81
+ - **Subscribers**: Create and manage subscribers
82
+ - **Subscriptions**: Get subscription status, cancel, change plans
83
+ - **Checkout**: Create Stripe checkout sessions
84
+ - **Portal**: Create Stripe customer portal sessions
85
+ - **Invoices**: List invoice history with PDF downloads
86
+ - **Products**: List and purchase add-on products
87
+
88
+ ## API Reference
89
+
90
+ ### Client Initialization
91
+
92
+ ```python
93
+ from growflow_billing import GrowFlowBillingClient
94
+
95
+ client = GrowFlowBillingClient(
96
+ api_key="sk_live_xxx", # Required
97
+ base_url="https://billing.growflow.studio/api/v1", # Optional
98
+ timeout=30.0, # Optional (seconds)
99
+ max_retries=3, # Optional
100
+ )
101
+ ```
102
+
103
+ ### Plans
104
+
105
+ ```python
106
+ # List all active plans
107
+ plans = await client.get_plans()
108
+
109
+ # Access plan properties
110
+ for plan in plans:
111
+ print(plan.slug) # e.g., "pro"
112
+ print(plan.name) # e.g., "Pro Plan"
113
+ print(plan.price_monthly) # e.g., Decimal("349.00")
114
+ print(plan.price_yearly) # e.g., Decimal("3490.00")
115
+ print(plan.limits) # e.g., {"conversations": 5000, "stores": 3}
116
+ print(plan.features) # e.g., ["premium_support", "api_access"]
117
+ print(plan.trial_days) # e.g., 14
118
+ ```
119
+
120
+ ### Subscribers
121
+
122
+ ```python
123
+ # Create a new subscriber
124
+ subscriber = await client.create_subscriber(
125
+ external_id="store_123", # Your internal ID
126
+ email="owner@store.com",
127
+ name="My Store",
128
+ company_name="Store Inc.", # Optional
129
+ vat_number="IT12345678901", # Optional
130
+ )
131
+
132
+ # Get subscriber by external ID
133
+ subscriber = await client.get_subscriber(external_id="store_123")
134
+ ```
135
+
136
+ ### Subscriptions
137
+
138
+ ```python
139
+ # Get active subscription
140
+ subscription = await client.get_subscription(external_id="store_123")
141
+
142
+ if subscription:
143
+ print(subscription.status) # "active", "trialing", "past_due", etc.
144
+ print(subscription.plan_slug) # "pro"
145
+ print(subscription.billing_cycle) # "monthly" or "yearly"
146
+ print(subscription.current_period_end) # datetime
147
+ print(subscription.is_trialing) # bool
148
+ print(subscription.trial_days_remaining) # int or None
149
+
150
+ # Cancel subscription
151
+ await client.cancel_subscription(
152
+ subscription_id="sub_xxx",
153
+ at_period_end=True, # Cancel at end of billing period
154
+ )
155
+
156
+ # Change plan
157
+ await client.change_plan(
158
+ subscription_id="sub_xxx",
159
+ new_plan_slug="enterprise",
160
+ prorate=True,
161
+ )
162
+ ```
163
+
164
+ ### Checkout Sessions
165
+
166
+ ```python
167
+ # Create checkout session for new subscription
168
+ session = await client.create_checkout_session(
169
+ customer_external_id="store_123",
170
+ plan_slug="pro",
171
+ billing_cycle="monthly", # or "yearly"
172
+ success_url="https://yourapp.com/billing?status=success",
173
+ cancel_url="https://yourapp.com/billing?status=canceled",
174
+ coupon_code="WELCOME20", # Optional discount code
175
+ )
176
+
177
+ # Redirect user to Stripe checkout
178
+ redirect_url = session.checkout_url
179
+ ```
180
+
181
+ ### Customer Portal
182
+
183
+ ```python
184
+ # Create portal session for subscription management
185
+ portal = await client.create_portal_session(
186
+ customer_external_id="store_123",
187
+ return_url="https://yourapp.com/billing",
188
+ )
189
+
190
+ # Redirect user to Stripe portal
191
+ redirect_url = portal.portal_url
192
+ ```
193
+
194
+ ### Invoices
195
+
196
+ ```python
197
+ # List invoices
198
+ invoices = await client.get_invoices(
199
+ external_id="store_123",
200
+ limit=20,
201
+ )
202
+
203
+ for invoice in invoices:
204
+ print(invoice.number) # "INV-0001"
205
+ print(invoice.status) # "paid", "open", "void"
206
+ print(invoice.amount_paid) # 34900 (cents)
207
+ print(invoice.currency) # "eur"
208
+ print(invoice.invoice_pdf) # URL to PDF
209
+ print(invoice.hosted_invoice_url) # Stripe hosted page
210
+ ```
211
+
212
+ ## Error Handling
213
+
214
+ ```python
215
+ from growflow_billing import (
216
+ GrowFlowBillingError,
217
+ AuthenticationError,
218
+ NotFoundError,
219
+ ConflictError,
220
+ ValidationError,
221
+ RateLimitError,
222
+ )
223
+
224
+ try:
225
+ plans = await client.get_plans()
226
+ except AuthenticationError:
227
+ print("Invalid API key")
228
+ except NotFoundError as e:
229
+ print(f"Resource not found: {e.message}")
230
+ except RateLimitError:
231
+ print("Rate limit exceeded, try again later")
232
+ except GrowFlowBillingError as e:
233
+ print(f"API error: {e.message} (status: {e.status_code})")
234
+ ```
235
+
236
+ ## Configuration
237
+
238
+ Environment variables:
239
+
240
+ ```bash
241
+ GROWFLOW_BILLING_API_KEY=sk_live_xxx
242
+ GROWFLOW_BILLING_URL=https://billing.growflow.studio/api/v1
243
+ ```
244
+
245
+ ## License
246
+
247
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -0,0 +1,73 @@
1
+ # Publishing growflowbilling-client (Python SDK)
2
+
3
+ ## Overview
4
+
5
+ The Python SDK is published to PyPI as `growflowbilling-client`.
6
+ Publishing is automated via GitHub Actions on push to `main` when files in `sdk/python/` change.
7
+
8
+ **Note**: The distribution name is `growflowbilling-client` but the Python import path remains `growflow_billing`:
9
+
10
+ ```python
11
+ from growflow_billing import GrowFlowBillingClient
12
+ ```
13
+
14
+ ## How It Works
15
+
16
+ 1. **Version detection**: CI compares `pyproject.toml` version against the published PyPI version
17
+ 2. **If version changed**: lint, type-check, test, build, publish to PyPI, create git tag
18
+ 3. **If version unchanged**: CI skips publishing
19
+
20
+ ## Publishing a New Version
21
+
22
+ ```bash
23
+ cd sdk/python
24
+
25
+ # 1. Make your changes
26
+ # 2. Bump version in pyproject.toml
27
+ # version = "1.3.0"
28
+
29
+ # 3. Commit and push
30
+ git add pyproject.toml
31
+ git commit -m "chore(sdk): bump python SDK to vX.Y.Z"
32
+ git push origin main
33
+ ```
34
+
35
+ CI will automatically:
36
+ - Run `ruff` linting and `mypy` type checking
37
+ - Run `pytest`
38
+ - Build with `python -m build`
39
+ - Publish to PyPI via OIDC Trusted Publisher (no tokens needed)
40
+ - Create a git tag `growflowbilling-python-sdk-vX.Y.Z`
41
+
42
+ ## PyPI Trusted Publisher (OIDC)
43
+
44
+ Publishing uses PyPI's Trusted Publisher mechanism — no API tokens required.
45
+
46
+ **Setup (one-time, already done):**
47
+ 1. PyPI → Manage → Publishing → Add trusted publisher for `growflowbilling-client`
48
+ - Owner: `giuliogarofalo`, Repo: `growflow-billing`, Workflow: `publish-python-sdk.yml`, Environment: `pypi`
49
+ 2. GitHub → `growflow-billing` repo → Settings → Environments → Create `pypi` environment
50
+
51
+ ## Local Development
52
+
53
+ ```bash
54
+ cd sdk/python
55
+ pip install -e ".[dev]"
56
+ ruff check src/ # Linting
57
+ mypy src/ # Type checking
58
+ pytest # Tests
59
+ python -m build # Build sdist + wheel
60
+ ```
61
+
62
+ ## Consumer Usage
63
+
64
+ ```bash
65
+ pip install growflowbilling-client
66
+ ```
67
+
68
+ ```python
69
+ from growflow_billing import GrowFlowBillingClient
70
+
71
+ async with GrowFlowBillingClient(api_key="sk_...") as client:
72
+ plans = await client.get_plans()
73
+ ```
@@ -0,0 +1,216 @@
1
+ # GrowFlow Billing Client
2
+
3
+ Python client for [GrowFlow Billing API](https://billing.growflow.studio) - subscription management, checkout sessions, invoices, and more.
4
+
5
+ > **Documentation**: See [growflow-billing-docs](https://github.com/growflow/growflow-billing-docs) for complete API documentation and examples.
6
+ >
7
+ > **Node.js**: Looking for the Node.js/TypeScript client? See [@growflow/billing-client](https://github.com/growflow/growflow-billing-client-node).
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pip install growflow-billing-client
13
+ ```
14
+
15
+ Or install from source:
16
+
17
+ ```bash
18
+ pip install git+https://github.com/growflow/growflow-billing-client.git
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ```python
24
+ import asyncio
25
+ from growflow_billing import GrowFlowBillingClient
26
+
27
+ async def main():
28
+ async with GrowFlowBillingClient(api_key="sk_live_xxx") as client:
29
+ # Get available plans
30
+ plans = await client.get_plans()
31
+ for plan in plans:
32
+ print(f"{plan.name}: {plan.price_monthly} {plan.currency}/month")
33
+
34
+ # Create a checkout session
35
+ session = await client.create_checkout_session(
36
+ customer_external_id="customer_123",
37
+ plan_slug="pro",
38
+ billing_cycle="monthly",
39
+ success_url="https://yourapp.com/billing?status=success",
40
+ cancel_url="https://yourapp.com/billing?status=canceled",
41
+ )
42
+ print(f"Checkout URL: {session.checkout_url}")
43
+
44
+ asyncio.run(main())
45
+ ```
46
+
47
+ ## Features
48
+
49
+ - **Plans**: List available subscription plans
50
+ - **Subscribers**: Create and manage subscribers
51
+ - **Subscriptions**: Get subscription status, cancel, change plans
52
+ - **Checkout**: Create Stripe checkout sessions
53
+ - **Portal**: Create Stripe customer portal sessions
54
+ - **Invoices**: List invoice history with PDF downloads
55
+ - **Products**: List and purchase add-on products
56
+
57
+ ## API Reference
58
+
59
+ ### Client Initialization
60
+
61
+ ```python
62
+ from growflow_billing import GrowFlowBillingClient
63
+
64
+ client = GrowFlowBillingClient(
65
+ api_key="sk_live_xxx", # Required
66
+ base_url="https://billing.growflow.studio/api/v1", # Optional
67
+ timeout=30.0, # Optional (seconds)
68
+ max_retries=3, # Optional
69
+ )
70
+ ```
71
+
72
+ ### Plans
73
+
74
+ ```python
75
+ # List all active plans
76
+ plans = await client.get_plans()
77
+
78
+ # Access plan properties
79
+ for plan in plans:
80
+ print(plan.slug) # e.g., "pro"
81
+ print(plan.name) # e.g., "Pro Plan"
82
+ print(plan.price_monthly) # e.g., Decimal("349.00")
83
+ print(plan.price_yearly) # e.g., Decimal("3490.00")
84
+ print(plan.limits) # e.g., {"conversations": 5000, "stores": 3}
85
+ print(plan.features) # e.g., ["premium_support", "api_access"]
86
+ print(plan.trial_days) # e.g., 14
87
+ ```
88
+
89
+ ### Subscribers
90
+
91
+ ```python
92
+ # Create a new subscriber
93
+ subscriber = await client.create_subscriber(
94
+ external_id="store_123", # Your internal ID
95
+ email="owner@store.com",
96
+ name="My Store",
97
+ company_name="Store Inc.", # Optional
98
+ vat_number="IT12345678901", # Optional
99
+ )
100
+
101
+ # Get subscriber by external ID
102
+ subscriber = await client.get_subscriber(external_id="store_123")
103
+ ```
104
+
105
+ ### Subscriptions
106
+
107
+ ```python
108
+ # Get active subscription
109
+ subscription = await client.get_subscription(external_id="store_123")
110
+
111
+ if subscription:
112
+ print(subscription.status) # "active", "trialing", "past_due", etc.
113
+ print(subscription.plan_slug) # "pro"
114
+ print(subscription.billing_cycle) # "monthly" or "yearly"
115
+ print(subscription.current_period_end) # datetime
116
+ print(subscription.is_trialing) # bool
117
+ print(subscription.trial_days_remaining) # int or None
118
+
119
+ # Cancel subscription
120
+ await client.cancel_subscription(
121
+ subscription_id="sub_xxx",
122
+ at_period_end=True, # Cancel at end of billing period
123
+ )
124
+
125
+ # Change plan
126
+ await client.change_plan(
127
+ subscription_id="sub_xxx",
128
+ new_plan_slug="enterprise",
129
+ prorate=True,
130
+ )
131
+ ```
132
+
133
+ ### Checkout Sessions
134
+
135
+ ```python
136
+ # Create checkout session for new subscription
137
+ session = await client.create_checkout_session(
138
+ customer_external_id="store_123",
139
+ plan_slug="pro",
140
+ billing_cycle="monthly", # or "yearly"
141
+ success_url="https://yourapp.com/billing?status=success",
142
+ cancel_url="https://yourapp.com/billing?status=canceled",
143
+ coupon_code="WELCOME20", # Optional discount code
144
+ )
145
+
146
+ # Redirect user to Stripe checkout
147
+ redirect_url = session.checkout_url
148
+ ```
149
+
150
+ ### Customer Portal
151
+
152
+ ```python
153
+ # Create portal session for subscription management
154
+ portal = await client.create_portal_session(
155
+ customer_external_id="store_123",
156
+ return_url="https://yourapp.com/billing",
157
+ )
158
+
159
+ # Redirect user to Stripe portal
160
+ redirect_url = portal.portal_url
161
+ ```
162
+
163
+ ### Invoices
164
+
165
+ ```python
166
+ # List invoices
167
+ invoices = await client.get_invoices(
168
+ external_id="store_123",
169
+ limit=20,
170
+ )
171
+
172
+ for invoice in invoices:
173
+ print(invoice.number) # "INV-0001"
174
+ print(invoice.status) # "paid", "open", "void"
175
+ print(invoice.amount_paid) # 34900 (cents)
176
+ print(invoice.currency) # "eur"
177
+ print(invoice.invoice_pdf) # URL to PDF
178
+ print(invoice.hosted_invoice_url) # Stripe hosted page
179
+ ```
180
+
181
+ ## Error Handling
182
+
183
+ ```python
184
+ from growflow_billing import (
185
+ GrowFlowBillingError,
186
+ AuthenticationError,
187
+ NotFoundError,
188
+ ConflictError,
189
+ ValidationError,
190
+ RateLimitError,
191
+ )
192
+
193
+ try:
194
+ plans = await client.get_plans()
195
+ except AuthenticationError:
196
+ print("Invalid API key")
197
+ except NotFoundError as e:
198
+ print(f"Resource not found: {e.message}")
199
+ except RateLimitError:
200
+ print("Rate limit exceeded, try again later")
201
+ except GrowFlowBillingError as e:
202
+ print(f"API error: {e.message} (status: {e.status_code})")
203
+ ```
204
+
205
+ ## Configuration
206
+
207
+ Environment variables:
208
+
209
+ ```bash
210
+ GROWFLOW_BILLING_API_KEY=sk_live_xxx
211
+ GROWFLOW_BILLING_URL=https://billing.growflow.studio/api/v1
212
+ ```
213
+
214
+ ## License
215
+
216
+ MIT License - see [LICENSE](LICENSE) for details.
@@ -0,0 +1,62 @@
1
+ [project]
2
+ name = "growflowbilling-client"
3
+ version = "1.2.0"
4
+ description = "Python client for GrowFlow Billing API - subscription management, checkout, invoices"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ license = {text = "MIT"}
8
+ authors = [
9
+ {name = "GrowFlow", email = "dev@growflow.studio"}
10
+ ]
11
+ keywords = ["billing", "subscriptions", "stripe", "payments", "saas"]
12
+ classifiers = [
13
+ "Development Status :: 4 - Beta",
14
+ "Intended Audience :: Developers",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Topic :: Software Development :: Libraries :: Python Modules",
21
+ "Typing :: Typed",
22
+ ]
23
+ dependencies = [
24
+ "httpx>=0.25.0",
25
+ "pydantic[email]>=2.0.0",
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ dev = [
30
+ "pytest>=7.0.0",
31
+ "pytest-asyncio>=0.21.0",
32
+ "respx>=0.20.0",
33
+ "ruff>=0.1.0",
34
+ "mypy>=1.0.0",
35
+ ]
36
+
37
+ [project.urls]
38
+ Homepage = "https://github.com/giuliogarofalo/growflow-billing"
39
+ Documentation = "https://docs.growflow.studio/billing-client"
40
+ Repository = "https://github.com/giuliogarofalo/growflow-billing"
41
+
42
+ [build-system]
43
+ requires = ["hatchling"]
44
+ build-backend = "hatchling.build"
45
+
46
+ [tool.hatch.build.targets.wheel]
47
+ packages = ["src/growflow_billing"]
48
+
49
+ [tool.ruff]
50
+ line-length = 100
51
+ target-version = "py310"
52
+
53
+ [tool.ruff.lint]
54
+ select = ["E", "F", "I", "N", "W", "UP"]
55
+
56
+ [tool.mypy]
57
+ python_version = "3.10"
58
+ strict = true
59
+
60
+ [tool.pytest.ini_options]
61
+ asyncio_mode = "auto"
62
+ testpaths = ["tests"]