chargebee / chargebee-python Goto Github PK
View Code? Open in Web Editor NEWPython library for the Chargebee API.
Home Page: https://apidocs.chargebee.com/docs/api?lang=python
License: MIT License
Python library for the Chargebee API.
Home Page: https://apidocs.chargebee.com/docs/api?lang=python
License: MIT License
Could you add trove classifiers to setup.py to clarify which versions of python are supported?
At present caniusepython3
nags about this package since it doesn't have any python 3 classifiers in it's setup.py.
Getting a mixed spaces and tabs error :
E File "/home/rof/.virtualenv/lib/python3.4/site-packages/chargebee/request.py", line 10
E if isinstance(v, (list)):
E ^
E TabError: inconsistent use of tabs and spaces in indentation
There is no unbilled_charge
object in the result of a subscription as documented API Docs in the subscription section:
chargebee.configure("test_fYhuOPJEARUIDWVKgHhOnbAiPmpCBicuV","selfdecode-test")
result = chargebee.Subscription.create_for_customer("8avVGOkx8U1MX", {
"plan_id" : "free",
"addons" : [{
"id" : "cbdemo_conciergesupport"
}]
})
subscription = result.subscription
customer = result.customer
card = result.card
invoice = result.invoice
unbilled_charge = result.unbilled_charge
There is only a unbilled_charges
object in the result and it contains the unbilled charge for a subscription
When a field on an object is assigned, the value is not persisted down to the values
dict on the object. I suspect this is probably due to the fact that setattr
is being used to populate the fields on initialization, so it's not able to be overloaded.
Unfortunately, this makes using the object basically useless, since they can't really be updated given the currently available methods.
Example:
subscription = chargebee.Subscription.retrieve('subscriptionId')
assert subscription.plan_id == 'oldPlanId' # this passes
subscription.plan_id = 'newPlanId'
serializedSub = json.loads(str(subscription))
assert serializedSub['plan_id'] == 'newPlanId # this fails
It would be nice to provide a way for the attributes of the object to be "serialized" into a dict that can be passed to the update
call of a chargebee model, or implement some sort of update
that can be called on the object itself, rather than passing in the id and update params.
Python version: 3.9
Library version: 2.10.0
Code:
result = chargebee.Subscription.cancel(subscription_id)
Canceling subscription raise error:
‘chargebee.api_error.APIError: This API operation is not enabled for this site. Please contact [email protected] to get this enabled’.
But the same operation works fine with cURL for our website.
It is possible to have the number of objects (Subscriptions, Coupons, Invoices, Customers, etc.) with filters ?
Do you have any plan to support async requests.?
You probably shouldn't distribute the tests package as no one expects to get a package by that name when they pip install chargebee
. Just exclude it:
find_packages(exclude=["tests"])
Currently the only way to retrieve a list of subscriptions related to a single customer is through chargebee.Subscription.list({"customer_id[is]": "<customer-id>"})
. This returns a ListResult
response which includes duplicative customer information for each item in the list result. This ultimately makes parsing the response into something like a dataclass
more difficult than it should be.
It would be more convenient to have Customer.retrieve({"id[is]": "<customer_id>"})
return subscriptions along with the customer information in the following format:
{
"customer": {
"id": "<id>",
...
"subscriptions": [
{ <subscription-one> },
{ <subscription-two> },
...
]
{
I'd love to know if there is a way to include additional info from the Customer.retrieve
method; however, documentation states that this call only returns the Customer
and (an optional) Card
objects.
Can't find anything on how this environment variable needs to be setup. But for some reason it's allowed to not pass in a environment for the new hosted checkout function:
@staticmethod
def checkout_new(params, env=None, headers=None):
return request.send('post', request.uri_path("hosted_pages","checkout_new"), params, env, headers)
request.send
also allows empty envs:
def send(method, url, params=None, env=None, headers=None):
if params is None:
params = {}
env = env or ChargeBee.default_env
If we look at what ChargeBee.default_env
is, we see that it's None
:
class ChargeBee(object):
default_env = None
I think either the Chargebee class default_env should be set, or http_request.request
should not break on a env that's not set:
def request(method, url, env, params=None, headers=None):
if not env:
raise Exception('No environment configured.')
That being said, perhaps I didn't set up something correctly? Where can I find docs about this?
release of 2.17.0 appears to have broken imports
$ poetry run pip install chargebee==2.17.0 -U
Collecting chargebee==2.17.0
Downloading chargebee-2.17.0.tar.gz (141 kB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 141.9/141.9 kB 2.6 MB/s eta 0:00:00
Preparing metadata (setup.py) ... done
Requirement already satisfied: requests in ./.venv/lib/python3.10/site-packages (from chargebee==2.17.0) (2.28.1)
Requirement already satisfied: charset-normalizer<3,>=2 in ./.venv/lib/python3.10/site-packages (from requests->chargebee==2.17.0) (2.1.0)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in ./.venv/lib/python3.10/site-packages (from requests->chargebee==2.17.0) (1.26.11)
Requirement already satisfied: certifi>=2017.4.17 in ./.venv/lib/python3.10/site-packages (from requests->chargebee==2.17.0) (2022.6.15)
Requirement already satisfied: idna<4,>=2.5 in ./.venv/lib/python3.10/site-packages (from requests->chargebee==2.17.0) (3.3)
Building wheels for collected packages: chargebee
p Building wheel for chargebee (setup.py) ... done
Created wheel for chargebee: filename=chargebee-2.17.0-py3-none-any.whl size=168044 sha256=d9f58a2f164b1a2497a3e1caaf9c822c88ba923be664285d41d58da626c77852
Stored in directory: /home/tholub/.cache/pip/wheels/ff/1c/70/0ae76d8ba65b08c2351acdb3f0942da8fd391155f4e9b11d16
Successfully built chargebee
Installing collected packages: chargebee
Attempting uninstall: chargebee
Found existing installation: chargebee 2.16.0
Uninstalling chargebee-2.16.0:
Successfully uninstalled chargebee-2.16.0
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
flask-subscription 0.1.0 requires chargebee==2.16.0, but you have chargebee 2.17.0 which is incompatible.
Successfully installed chargebee-2.17.0
[notice] A new release of pip available: 22.1.2 -> 22.2.1
[notice] To update, run: pip install --upgrade pip
tholub@pop-os:~/git/mobius-2/flask_subscription migrate.registry (fb9412b)$ poetry run python
Python 3.10.4 (main, May 19 2022, 15:17:01) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from chargebee import Content
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'Content' from 'chargebee' (/home/tholub/git/mobius-2/flask_subscription/.venv/lib/python3.10/site-packages/chargebee/__init__.py)
This failed import is issued here
Getting CERTIFICATE_VERIFY_FAILED on all API calls suddenly.
It seems Chargebee updated their SSL certificate but not the ca-certs.crt
used for SSL validation and its now failing.
Make any API call using Python SDK
Should not fail on certificate verification
No response
macOS
Python 3.11.7
2.35.0
No response
http.request() raises UnicodeEncodeError if 'params' contains unicode data (for example a customer's name etc.)
Hi there :)
I would like to send a payload as JSON to Chargebee API but it only works in URL encoded format, not in JSON format.
I need to send JSON from the requests Python package without the Chargebee wrapper.
Any idea?
$ curl https://***********-test.chargebee.com/api/v2/payment_sources/create_card \
> -u **************************************:\
> -d customer_id="cbdemo_douglas" \
> -d card[number]="378282246310005" \
> -d card[cvv]="100" \
> -d card[expiry_year]=2022 \
> -d card[expiry_month]=12
{
"payment_source": {
"id": "pm_BTcLSfTGD1TtShje",
"updated_at": 1662057402,
"resource_version": 1662057402861,
...
}
}
}
$ curl https://***********-test.chargebee.com/api/v2/payment_sources/create_card \
> -u **************************************:\
> -H 'content-type: application/json' \
> -H 'accept: application/json' \
> -d '{
> "customer_id":"cbdemo_douglas",
> "card":{
> "number":"378282246310005",
> "cvv":"100",
> "expiry_year":"2022",
> "expiry_month":"12"
> }
> }'
{"message":"customer_id : cannot be blank","type":"invalid_request","api_error_code":"invalid_request","param":"customer_id","error_code":"param_required","error_msg":"cannot be blank","error_param":"customer_id","http_status_code":400}
The 'usage' model does not seem to be available in 2,8.3 version.
$ pip show chargebee
Name: chargebee
Version: 2.8.3
Summary: Python wrapper for the ChargeBee Subscription Billing API
Home-page: https://apidocs.chargebee.com/docs/api?lang=python
Author: ChargeBee
Author-email: [email protected]
License: UNKNOWN
Location: /home/jcyriac/.local/lib/python3.8/site-packages
Requires:
Required-by:
SUB_ID = 'xxxxxxxxxxxxxxxxxxxx'
entries = chargebee.Usage.list({
"subscription_id[is]" : SUB_ID
})
output ->
Traceback (most recent call last):
File "list_usage.py", line 12, in <module>
entries = chargebee.Usage.list({
AttributeError: module 'chargebee' has no attribute 'Usage'
Hello,
Is there an official Chargebee stubs library to support Python typing ?
If not, is that planned any time soon ?
As a critical library that handles payments related topics, Chargebee may greatly benefit from stubs that will help developers to avoid typing mistakes.
It will also keep code documentation as up to date as possible.
Regards,
Cannot directly access Item and ItemPrice object, e.g. when I type these:
/// IDE gives error: "Cannot find reference 'Item' in '__init__.py' "
chargebee.Item
/// IDE gives error: "Cannot find reference 'ItemPrice' in '__init__.py' "
chargebee.ItemPrice
Also cannot access Item and ItemPrice from Webhook event content, e.g.:
content = chargebee.Content(result)
/// This gives error: "name 'Item' is not defined"
content.item
/// This gives error: "name 'ItemPrice' is not defined"
content.item_price
If I install from the pip package, it does not include the SSL directory and CRL.
Once I'd placed the file in the package folder, everything worked OK.
Can you add it to the pip package?
Hi, I see the lib uses urllib. Would you be open to a switch to requests (https://github.com/request/request)?
Besides the nice api, if chargebee-python used requests it could benefit from other nice libraries like:
Thoughts?
Currently, can't use this library with Python 3. What is the best way to proceed? Issue a pull request with the changes?
RefactoringTool: Refactored djenv/lib/python3.4/site-packages/chargebee/http.py
--- djenv/lib/python3.4/site-packages/chargebee/http.py (original)
+++ djenv/lib/python3.4/site-packages/chargebee/http.py (refactored)
@@ -54,7 +54,7 @@
def process_response(url,response, http_code):
try:
resp_json = compat.json.loads(response)
- except Exception, ex:
+ except Exception as ex:
raise Exception("Response not in JSON format. Probably not a chargebee error. \n URL is " + url + "\n Content is \n" + response)
if http_code < 200 or http_code > 299:
handle_api_resp_error(url,http_code, resp_json)
RefactoringTool: Files that need to be modified:
RefactoringTool: djenv/lib/python3.4/site-packages/chargebee/http.py
except Exception, ex
should be except Exception as ex
I would like to be able to set a timeout for requests being sent to chargebee. I am happy to make a pull request to enable this behaviour. I can see two ways to go here:
Add a timeout to the Environment
class in environment.py
so that it can be set during chargebee.configure
.
Add a keyword parameter to methods that use request.send
and request.send_list_request
which will get eventually passed to the connection object. This means that the timeout can be configurable per api call.
Are either of these options acceptable? Again, I am happy to submit a pull request if the project is happy to proceed with this feature request.
Accessing eg. my_customer.values
is a reasonable way of serialising a model object for eg. caching locally in memcache or redis.
But after retrieving from the cache, deserialising could be easier. Objects without nested subtypes are available via chargebee.Card.construct(values)
. But currently to get a Customer model instance back from a cache result (.values
object), you need to jump through hoops:
my_customer = chargebee.Customer.construct(values,
# need to pass in the subtypes to be deserialized properly
# I got these from chargebee/result.py
sub_types={
'billing_address' : chargebee.Customer.BillingAddress,
'contacts' : chargebee.Customer.Contact,
'payment_method' : chargebee.Customer.PaymentMethod
}
)
Simple-ish solution could be to override construct()
in models with subtypes, and move the hardcoded stuff from result.py into the model.
More complex would be for .construct()
or a metaclass could find the sub-types?
When I tried to retrieve and event_id in which content there are characters with written accent like 'Québec':
"event_type": "subscription_renewed",
"object": "event",
"content": {
...
"billing_address": {
"city": "Québec",
...
},
},
It throws the following error.
File "/srv/amigoserver/amigoserver/django/amigoserver/payments/views.py" in post
37. or not chargebee_utils.event_exists(event.get('id'))):
File "/srv/amigoserver/amigoserver/django/amigoserver/payments/chargebee_utils.py" in event_exists
219. chargebee.Event.retrieve(event_id)
File "/usr/local/lib/python2.7/dist-packages/chargebee/models/event.py" in retrieve
40. return request.send('get', request.uri_path("events",id), None, env, headers)
File "/usr/local/lib/python2.7/dist-packages/chargebee/request.py" in send
29. response = http_request.request(method, url, env, ser_params, headers)
File "/usr/local/lib/python2.7/dist-packages/chargebee/http_request.py" in request
71. method=request_args['method'], status_code=response.status_code, text=response.text
Exception Type: UnicodeEncodeError at /payments/cb_webhooks
Exception Value: 'ascii' codec can't encode character u'\xe9' in position 2129: ordinal not in range(128)
I made this call inside a Django application which give the following hint about the error:
I will really appreciate if someone can help me to solve this issue.
I have a case where I need to work with two different Chargebee account in the same SaaS application.
If I’m not mistaken, the Chargebee configuration is currently “global”. I currently workaround this issue by updating the configuration before each call with the proper credentials but I suspect I’ll run into race-condition issues at scale.
I know some 3rd-party librairies allow to configure multiple client instances, would it be applicable for this library? Do you have any other suggestions?
APIError.__init__()
takes two params (apart from self):
https://github.com/chargebee/chargebee-python/blob/master/chargebee/api_error.py#L3
However, on models/event.py line 20, it's passed only a string message.
https://github.com/chargebee/chargebee-python/blob/master/chargebee/models/event.py#L20
This throws a TypeError saying '__init__()
takes 3 arguments (2 given)'
Example:
>>> import chargebee
>>> data = 'non-json-data'
>>> chargebee.Event.deserialize(data)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/kunal/work/kunal/python/chargebee/local/lib/python2.7/site-packages/chargebee/models/event.py", line 20, in deserialize
raise APIError("Invalid webhook object to deserialize")
TypeError: __init__() takes exactly 3 arguments (2 given)
It would be good to add the retry on failure for timeouts https://findwork.dev/blog/advanced-usage-python-requests-timeouts-retries-hooks/
Currently in an interactive shell/debugger/traceback you don't get a very good representation of the model instances:
eg. <chargebee.models.customer.Customer at 0x7ff7f9fb0e48>
Would be helpful to make it reference the Chargebee IDs by implementing Model.__repr__()
eg. <Customer: ZEw32jZRMQ0bB21A9t>
Implementation idea:
Model.fields[0]
is the key to use for representing the instance.id
(or entity_id
/cn_id
/txn_id
/etc), or could be by simply re-ordering the fields
listAddressModelMixin
class which implements __repr__()
by merging a few fields together (eg. return " ".join([self.city or '', self.zip or '', self.country or ''])
)Importing v2.6.1 on Python 2.7 with deprecation warnings enabled raises an ImportWarning:
henrik@debian:~$ python -Wall -c "import chargebee"
/local/lib/python2.7/site-packages/chargebee/compat.py:40: ImportWarning: Not importing directory '/local/lib/python2.7/site-packages/chargebee/ssl': missing __init__.py
import ssl
This library doesn't put SNI when it connects to perform API requests. Doing so however is good practice.
Note that there were some releases of docker desktop for mac recently that shipped with a transparant proxy in it, that only was able to forward connections using SNI, breaking this code. This has been fixed now on the docker side. (see also docker/for-mac#5568)
A fix is waiting for you at #38 .
Following the docs, I am supposed to be able to retrieve invoices, subscriptions, transcations... for example: https://apidocs.chargebee.com/docs/api/exports#export_invoices
However, when I try to do that, I get:
result = chargebee.Export.invoices({
AttributeError: type object 'Export' has no attribute 'invoices'
Looking at https://github.com/chargebee/chargebee-python/blob/master/chargebee/models/export.py that seems true.
Is the doc ahead of the client? Or am I missing something here?
Getting an ugly html blob back for 503 Bad Gateways which is on chargebee side, and then the error saying Probably not a chargbee error, feels like you are lieing to your customers. Please fix
https://github.com/chargebee/chargebee-python/blob/master/chargebee/http_request.py#L84
except Exception as ex:
raise Exception("Response not in JSON format. Probably not a chargebee error. \n URL is " + url + "\n Content is \n" + response)
if http_code < 200 or http_code > 299:
handle_api_resp_error(url,http_code, resp_json)
```
checkout_one_time_for_item is missing on HostedPage
In the documentation on https://www.chargebee.com/docs/2.0/ga-inapp-checkout.html it's is described how to enable GA for the Checkout Portal:
You need to 'Pass the enableGATracking parameter as true when initializing the Chargebee instance.':
var chargebeeInstance = Chargebee.init({ site: "your-chargebee-subdomain", enableGATracking: true });
But how can I do this using the Python SDK? The method chargebee.configure() only allows me to set site and api_key.
Thanks,
Mark
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.