easypost / easypost-python Goto Github PK
View Code? Open in Web Editor NEWEasyPost Shipping API Client Library for Python
Home Page: https://easypost.com/docs/api
License: MIT License
EasyPost Shipping API Client Library for Python
Home Page: https://easypost.com/docs/api
License: MIT License
When creating a report, the start and end dates are ignored. The created report uses the current date instead. This is not a problem with the API since other client libraries seem to work fine.
I think the problem is related to this line:
easypost-python/easypost/__init__.py
Line 966 in 3115008
Things appear to work properly when wrapped_params
is changed to params
like this:
response, api_key = requestor.request('post', url, params, False)
Just started using this library (have a support ticket open with this too). New account + has billing enabled. Tried creating new API keys as well. This simple script is failing:
import easypost
key = '........MY_API_KEY........'
easypost.api_key = key
address_data = {
'street1':'341 9th Avenue',
'city':'New York',
'state':'NY',
'zip':'10199',
'country':'US',
'company':'Test Warehouse 1 2',
'verify':[
'delivery'
]
}
address = easypost.Address.create(address_data)
Traceback is:
Traceback (most recent call last):
File "C:\Users\Cole\Desktop\test.py", line 19, in <module>
address = easypost.Address.create(address_data)
File "C:\Users\Cole\AppData\Local\Programs\Python\Python36-32\lib\site-packages\easypost\__init__.py", line 639, in create
response, api_key = requestor.request('post', url, wrapped_params)
File "C:\Users\Cole\AppData\Local\Programs\Python\Python36-32\lib\site-packages\easypost\__init__.py", line 260, in request
response = self.interpret_response(http_body, http_status)
File "C:\Users\Cole\AppData\Local\Programs\Python\Python36-32\lib\site-packages\easypost\__init__.py", line 321, in interpret_response
self.handle_api_error(http_status, http_body, response)
File "C:\Users\Cole\AppData\Local\Programs\Python\Python36-32\lib\site-packages\easypost\__init__.py", line 383, in handle_api_error
raise Error(error.get('message', ''), http_status, http_body)
easypost.Error: This api key is no longer active. Please use a different api key or reactivate this key.
When writing tests around the easypost API, it would be helpful to be able to catch exceptions based on their subclasses instead of having a megaexception class and having to parse the message string.
Here's a snippet from our code base:
except easypost.Error as e:
# Is it a connection problem?
if u'error communicating with EasyPost' in e.message:
log.exception(e)
rate = fallback_rate
else:
raise
This is slightly terrifying because our business logic has to depend on parsing error message strings, which could change across versions of your python bindings. We work around this with a unit test that literally reads the easypost code for the version and error message strings, but subclassed exceptions would be a nicer pattern.
Seems like when there's a field api_key
in a carrier type this isn't behaving as intended with this client library.
Example below is Australia Post but this appears to happen for any carrier with api_key among the fields (e.g. Parcel, Fastway, etc.)
result with cURL:
curl -X GET https://api.easypost.com/v2/carrier_types -u PRODUCTION_API_KEY:
{
"object": "CarrierType",
"type": "AustraliaPostAccount",
"readable": "Australia Post",
"logo": null,
"fields": {
"credentials": {
"account_number": {
"visibility": "visible",
"label": "Australia Post Account Number"
},
"api_key": {
"visibility": "masked",
"label": "Australia Post API Key"
},
"api_secret": {
"visibility": "password",
"label": "Australia Post Secret Key"
},
"print_as_you_go": {
"visibility": "checkbox",
"label": "Print as you go"
}
}
}
},
result with python client library:
import easypost
easypost.api_key = 'api_key_here'
carrier_types = easypost.CarrierAccount.types()
print carrier_types
<EasyPostObject CarrierType at 0x11007abd0> JSON: {
"fields": {
"credentials": {
"account_number": {
"label": "Australia Post Account Number",
"visibility": "visible"
},
"api_secret": {
"label": "Australia Post Secret Key",
"visibility": "password"
},
"print_as_you_go": {
"label": "Print as you go",
"visibility": "checkbox"
}
}
},
"logo": null,
"object": "CarrierType",
"readable": "Australia Post",
"type": "AustraliaPostAccount"
},
Note in the Python case the absence of api_key
import easypost
easypost.api_key = "<YOUR_TEST/PRODUCTION_API_KEY>"
shipment = easypost.Shipment.retrieve("shp_...")
shipment.buy(rate="rate_...")
Goes to this URL with these params:
/shipments/shp_.../buy
{'rate': 'rate_...'}
and returns this error:
Error: A valid rate must be supplied in order to purchase a shipment. Please verify the rate exists and that the rate is associated with the shipment being purchased.
Using shipment.lowest_rate() works but only because it's returning the entire rate object as a param.
import easypost
easypost.api_key = "<YOUR_TEST/PRODUCTION_API_KEY>"
shipment = easypost.Shipment.retrieve("shp_...")
shipment.buy(rate=shipment.lowest_rate(), insurance=249.99)
/shipments/shp_.../buy
{'rate': <Rate Rate at 0x110f2f310> JSON: {
"api_key": "API_KEY",
"carrier": "USPS",
"carrier_account_id": "ca_...",
"created_at": "2016-02-19T06:06:59Z",
"currency": "USD",
"delivery_date": null,
etc....
So it seems theres a problem with the API not accepting just the rate_id, or the documentation is wrong.
Hello,
when I use the example orders.py I am getting an error in the browser after the label has been generated. Anyone else have this?
Only 3.6.0 is currently available, not 3.6.1.
https://pypi.python.org/pypi/easypost
Only up to 3.6.3 available here:
https://pypi.org/project/easypost/
Enter a host to ping:
When use
import easypost
import urllib3
urllib3.disable_warnings()
easypost.api_key = 'API_KEY'
address = easypost.Address.create(
company="EasyPost",
street1="118 2nd St",
street2="4th Fl",
city="San Francisco",
state="CA",
zip="94105",
phone="415-456-7890"
)
verified_address = address.verify()
print(verified_address)
Getting ping message, what's solution ?
As the title states, how do you purchase a batch of shipments where the shipments do not yet have a rate saved?
We'll have to commit to re-record periodically, but I think this is probably a reasonable tradeoff.
Right now if you provide multiple parameters, such as verify_strict zip4 and verify delivery, the python client will error with "Error: The parameters passed to create an Address were missing or invalid."
We should support having multiple verifications in the client, as the API supports this use case.
Adding the ability to install from pip would greatly increase the ease at which EasyPost can be added to projects and maintained in the future.
The depreciated version of the python api could be installed in pip, why has this been dropped from the current version?
Using this as my to address:
"to_address": {
"city": "Toronto",
"company": null,
"country": "CA",
"email": null,
"name": "R\xf5ger Hos\xe8in",
"phone": "5555555555",
"state": "ON",
"street1": "636 King Street West",
"street2": "",
"zip": "M5V1M7"
}
I get the following error returned to me:
"messages": [
{
"api_key": "WFvVSAc8vIBZbtzgGn6f7Q",
"carrier": "Purolator",
"message": "XML request is malformed.",
"type": "rate_error"
}
]
If I force the name to be a string, it works just fine except that the unicode characters don't translate over to Easypost, it shows as that string above.
Any ideas?
I want to pull multiple shipment ids from a database and request a scan form, but I receive an error when attempting the request when the array of objects containing the shipment ids is assigned to variable:
shipments = [{'id': 'shp_504...'}, {'id': 'shp_6e0...'}]
import json
manifest = json.dumps(shipments)
scan_form = easypost.ScanForm.create(shipments=manifest)
I only receive the error: Error: We're sorry, something went wrong. If the problem persists please contact Support.
Support cannot explain and suggested I submit this issue.
Call:
batch_api_obj = self.easypost.Batch.retrieve(shipping_api_batch_uuid)
batch_api_obj.label(file_format='pdf')
Returning "AttributeError: 'NoneType' object has no attribute 'items'"
Traceback (most recent call last):
File ".../shipping_processor.py", line 504, in batch_generate_label
batch_api_obj.label(file_format='pdf')
File "/thewinegallery/src/thewinegalleryvenv/lib/python3.4/site-packages/easypost/init.py", line 810, in label
self.refresh_from(response, api_key)
File "/thewinegallery/src/thewinegalleryvenv/lib/python3.4/site-packages/easypost/init.py", line 452, in refresh_from
for k, v in sorted(six.iteritems(values)):
File "/thewinegallery/src/thewinegalleryvenv/lib/python3.4/site-packages/six.py", line 581, in iteritems
return iter(d.items(**kw))
AttributeError: 'NoneType' object has no attribute 'items'
I'm attempting to schedule a pickup for a batch with a test API key, and getting a "location is a mandatory field" error, however as far as i can tell "location" is not a field at all on a pickup. The pickup object creates fine, error occurs when attempting to call pickupObj.buy(carrier='Purolator', service='PurolatorPickup')
.
pickup object looks like this (some info replaced with "XXX"):
<Pickup b'Pickup' at 0x7f8ec3d59400> JSON: { "address": { "carrier_facility": null, "city": "Canmore", "company": null, "country": "CA", "created_at": "2017-05-20T23:34:35Z", "email": null, "federal_tax_id": null, "id": "adr_de8a3d4703be4da5917ec9394adf88fe", "mode": "test", "name": "XXX", "object": "Address", "phone": "XXX", "residential": null, "state": "AB", "state_tax_id": null, "street1": "XXX", "street2": null, "updated_at": "2017-05-20T23:34:35Z", "verifications": {}, "zip": "XXX" }, "carrier_accounts": [], "confirmation": null, "created_at": "2017-05-23T01:08:41Z", "id": "pickup_b903680e49774671a36ddcb3ab28a8f0", "instructions": null, "is_account_address": true, "max_datetime": "2017-05-23T23:00:00Z", "messages": [], "min_datetime": "2017-05-23T14:00:00Z", "mode": "test", "object": "Pickup", "pickup_rates": [ { "carrier": "Purolator", "created_at": "2017-05-23T01:08:41Z", "currency": "CAD", "id": "pickuprate_52ca9de05d2a4359a75a907044b20043", "mode": "test", "object": "PickupRate", "pickup_id": "pickup_b903680e49774671a36ddcb3ab28a8f0", "rate": "0.00", "service": "PurolatorPickup", "updated_at": "2017-05-23T01:08:41Z" } ], "reference": null, "status": "unknown", "updated_at": "2017-05-23T01:08:41Z" }
easypost version is 3.6.0
python version 3.4.3
Hi,
I'm using this package to integrate project I'm working on with EasyPost, and during testing this integration I've encountered an issue:
from decimal import Decimal
full_weight = Decimal("20.7")
# here comes the code I'm using to create shipment
final_shipment = create_shipment(weight=full_weight, **args)
assert final_shipment.weight == full_weight
And I get fail on this line:
AssertionError: assert Decimal('21') == Decimal('20.7')
Does this mean that you are rounding up values? Or you don't accept weight?
Unclosed file in version.py
:
/venv3/lib/python3.6/site-packages/easypost/version.py:4: ResourceWarning: unclosed file <_io.BufferedReader name='/venv3/lib/python3.6/site-packages/easypost/../VERSION'>
VERSION = pkg_resources.resource_stream('easypost', '../VERSION').read().decode('utf-8').strip()
To reproduce add PYTHONWARNINGS=always
to environment variables.
The example in your docs doesn't work and without any change, our production systems started failing. .
The error is specifically happening in this call somewhere upstream easypost.Shipment.create()
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
File "/usr/local/lib/python3.7/site-packages/easypost/__init__.py", line 600, in create
return convert_to_easypost_object(response, api_key)
File "/usr/local/lib/python3.7/site-packages/easypost/__init__.py", line 150, in convert_to_easypost_object
return cls.construct_from(response, api_key, parent, name)
File "/usr/local/lib/python3.7/site-packages/easypost/__init__.py", line 464, in construct_from
instance.refresh_from(values, api_key)
File "/usr/local/lib/python3.7/site-packages/easypost/__init__.py", line 476, in refresh_from
self.__dict__[k] = convert_to_easypost_object(v, api_key, self, k)
File "/usr/local/lib/python3.7/site-packages/easypost/__init__.py", line 150, in convert_to_easypost_object
return cls.construct_from(response, api_key, parent, name)
File "/usr/local/lib/python3.7/site-packages/easypost/__init__.py", line 464, in construct_from
instance.refresh_from(values, api_key)
File "/usr/local/lib/python3.7/site-packages/easypost/__init__.py", line 471, in refresh_from
if k == 'id' and self.id != v:
File "/usr/local/lib/python3.7/site-packages/easypost/__init__.py", line 434, in __getattr__
raise AttributeError("%r object has no attribute %r" % (type(self).__name__, k))
AttributeError: 'Tracker' object has no attribute 'id'
This is the python call
... verify=["delivery"],
... name = "Dr. Steve Brule",
... street1 = "179 N Harbor Dr",
... street2 = "",
... city = "Redondo Beach",
... state = "CA",
... zip = "90277",
... country = "US",
... phone = "310-808-5243"
... )
>>> from_address = easypost.Address.create(
... verify=["delivery"],
... name = "EasyPost",
... street1 = "118 2nd Street",
... street2 = "4th Floor",
... city = "San Francisco",
... state = "CA",
... zip = "94105",
... country = "US",
... phone = "415-456-7890"
... )
>>> parcel = easypost.Parcel.create(
... predefined_package = "Parcel",
... weight = 21.2
... )
>>> shipment = easypost.Shipment.create(
... to_address = to_address,
... from_address = from_address,
... parcel = parcel,)```
Attempting to check if a shipment has a selected rate results in this error:
Traceback (most recent call last):
File "sales_report.py", line 32, in <module>
if 'selected_rate' in shipment:
File "/usr/local/lib/python2.7/site-packages/easypost/__init__.py", line 405, in __getitem__
return self.__dict__[k]
KeyError: 0
I'm not entirely sure why that is (and my time to look into this issue has run out for today, so I just caught the exception instead) but this should probably be supported behavior. Here's the code that triggers the bug, it happens when I retrieve a shipment that was created but postage hasn't been purchased for:
import easypost
easypost.api_key = 'my_key_text'
shipment = easypost.Shipment.retrieve(order['easypost_shipment_id'])
if 'selected_rate' in shipment:
order['ship_date'] = shipment['selected_rate']['created_at']
to preface the tracking numbers. Any UPS tracking number that starts with 105... is typically a tracking number for a pallet of things rather than a box. Below is the error i receive along with the code i used to create it.
tracker = easypost.Tracker.create(
tracking_code="1058233044",
carrier="UPS"
)
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
tracker = easypost.Tracker.create(
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/easypost-4.1.0-py3.8.egg/easypost/__init__.py", line 599, in create
response, api_key = requestor.request('post', url, wrapped_params)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/easypost-4.1.0-py3.8.egg/easypost/__init__.py", line 267, in request
response = self.interpret_response(http_body, http_status)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/easypost-4.1.0-py3.8.egg/easypost/__init__.py", line 328, in interpret_response
self.handle_api_error(http_status, http_body, response)
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/easypost-4.1.0-py3.8.egg/easypost/__init__.py", line 392, in handle_api_error
raise Error(error.get('message', ''), http_status, http_body)
easypost.Error: The tracking number does not belong to the carrier you specified. Please confirm that both the carrier and tracking number are correct.
i can confirm that the tracking number does belong to UPS. Please let me know if there is any way that we are able to force check the API to use a particular shipping carrier.
I'm looking to have a single fedex shipment contain multiple packages, with a single master tracking code and shipping labels that indicate they're part of a multiple package shipment.
I see a bit of conflicting documentation about this. Here I see that easypost supports multi-package shipments: https://www.easypost.com/can-i-add-multiple-packages-to-a-fedex-shipment.
Here in the docs, https://www.easypost.com/docs/api#shipment-object, I see "The dimensions and weight of the package", which seems to imply that only a single parcel is supported.
So does easypost support this? How would I go about implementing that with this client library?
Thanks!
sr/local/lib/python2.7/dist-packages/requests/packages/urllib3/connectionpool.py:730: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html (This warning will only appear once by default.)
InsecureRequestWarning)
Traceback (most recent call last):
File "ups_address_validation.py", line 12, in
phone = "415-456-7890"
File "/usr/local/lib/python2.7/dist-packages/easypost/init.py", line 482, in create
response, api_key = requestor.request('post', url, wrapped_params)
File "/usr/local/lib/python2.7/dist-packages/easypost/init.py", line 207, in request
response = self.interpret_response(http_body, http_status)
File "/usr/local/lib/python2.7/dist-packages/easypost/init.py", line 255, in interpret_response
self.handle_api_error(http_status, http_body, response)
File "/usr/local/lib/python2.7/dist-packages/easypost/init.py", line 308, in handle_api_error
raise Error(error, http_status, http_body)
easypost.Error: Unauthorized (401)
Please guide us, to run this lib.
Hi, I have been given some v1 APIs from eastpost staff. Will everything blow up if I use this SDK for v1 API?
This will need some additional investigation; but it appears that when creating a custom item with a description that is longer than the max field length (~250 characters), the Python CL is returning an unhelpful Wrong parameter type
error. In reality, it should be returning a message stating the max field length was exceeded or something along those lines. This info should be getting returned from the API but may not be getting exposed via this library.
Wrong parameter type
error is occurringA typical error response should look something like:
{"error":{"code":"PARAMETER.INVALID_TYPE","message":"Wrong parameter type.","errors":[{"field":"weight","message":"must be a float"}]}}
1 test is failing in webhooks - the assertion that a newly-created webhook object will always be returned in the .all() fetch for webhooks. This seems to be because the EasyPost API no longer guarantees synchronous creation of new webhook objects. That is to say, a newly-created webhook is not immediately queryable. This breaks a build test for the Python library. Propose removing that assertion, since it isn't possible to alter the test to suit this non-deterministic case.
Currently attempting to create a shipment using the one call buy example. The API will return an error message of easypost.Error: Missing required data to get rates.
with no details.
I've attempted a few things with no luck.
Current call:
shipment = easypost.Shipment.create(
carrier_accounts={"0": "ca_5dbee8b1e03f436da263aab45175d1a1"},
service="NextDayAir",
to_address=to_address,
from_address=from_address,
parcel=parcel
)
We've been trying multiple ways. We will get the same error message if we passed the addresses & parcel data in as a dictionary or if we pass the return of Parcel.create()
and Address.create()
Hello, do you know if easypost support auto-translation (transliteration) from non-roman to Latin alphabet as it was mentioned in their blog?
This double nesting of the test case function is weird, is that intentional?
https://github.com/EasyPost/easypost-python/blob/master/tests/test_report.py
I get the error "Missing or invalid element: FromPhone" when running
rate = shipment.lowest_rate()
shipment.buy(rate=rate)
This shipment's from_address has the phone number in the form ##########, and I have verified that it is the correct phone number.
It is an international shipment from the US to Canada, and the shipment has customs info attached to it.
any ideas what might be happening? Let me know if more information would help, Thanks!
I also emailed [email protected] and will update if I hear back
Good morning, following the library guidelines i'm buyng the shipment with this line of code
shipment.buy(rate = shipment.lowest_rate())
i have 2 problems with this since toda 9th July 2019,
Can you help me?
When PYTHONWARNINGS=always
is set, I get the following from the pkg_resources library:
/usr/local/lib/python3.7/site-packages/pkg_resources/__init__.py:1151: DeprecationWarning:
Use of .. or absolute path in a resource path is not allowed and will raise exceptions in a future
release.
self, resource_name
We'll need to adjust the relative path to the VERSION
file in the near future to avoid throwing exceptions on each call. The offending code is in version.py
:
VERSION_FILE = pkg_resources.resource_stream('easypost', '../VERSION')
There is an issue when creating a pickup object and trying to specify specific carrier accounts. Our documentation states that you will need to use the carrier account object but this was not working correctly when the carrier account was retrieved and passed into the pickup create call.
Hi. The documentation says that a shipment can be refunded using POST request.
However the library does GET request.
Is it documentation or library bug? Or am I missing something?
What's a good way to extend Easypost python wrapper to support undocumented APIs like /v2/fedex_registrations
and v2/carrier_accounts/register
?
We're aware of calling the endpoints directly with packages like requests, but for maintaining our code design, is it possible to extend the wrapper to support new API resources?
Thanks!
Hey folks,
I'm working with your API and I usually use the Order flow, where we have several shipments linked to an order. On this Order, we set a reference field, but it appears that this reference is not added to the shipments. It also appears that we can't manually add a reference after a shipment has been created (which seems like an oversight to me, but I'm sure you have your reasons).
I was wondering if there was a way to make the shipments of an order inherit the order reference, or to set the reference manually after creation.
Many thanks in advance,
Robrecht
creating customs documentation for a shipment with more than 5 items returns :
<class 'applications.store.modules.shipping.easypost2.easypost.Error'> Internal Endicia Error: No 4X6 continuation page. Error encountered (Log ID: 25037)
The Python library makes a few requests in quick succession and then a particular one fails with the traceback.
Environment:
Request Method: POST
Request URL: http://mydopro.com:8000/marketplace/shipping-quote/
Django Version: 1.3.5
Python Version: 2.7.4
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.redirects',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.sitemaps',
'django.contrib.staticfiles',
'django.contrib.flatpages',
'django_facebook',
'widget_tweaks',
'django.contrib.humanize',
'django.contrib.sitemaps',
'askbot',
'askbot.deps.django_authopenid',
'compressor',
'south',
'askbot.deps.livesettings',
'keyedcache',
'robots',
'django_countries',
'djcelery',
'djkombu',
'followit',
'easy_thumbnails',
'guardian',
'tastypie',
'userena',
'apps.connect',
'apps.common',
'apps.learn',
'apps.prostore',
'apps.videos',
'apps.marketplace',
'apps.share',
'backbone_tastypie',
'authorizeni',
'apps.challenge',
'askbot',
'apps.contacts',
'apps.search',
'rest_framework',
'rest_framework.authtoken',
'django_extensions']
Installed Middleware:
('apps.common.middleware.RoundcubeSessionMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
'apps.connect.middleware.RoutingMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'userena.middleware.UserenaLocaleMiddleware',
'django.contrib.redirects.middleware.RedirectFallbackMiddleware',
'askbot.middleware.anon_user.ConnectToSessionMessagesMiddleware',
'askbot.middleware.forum_mode.ForumModeMiddleware',
'askbot.middleware.cancel.CancelActionMiddleware',
'django.middleware.transaction.TransactionMiddleware',
'askbot.middleware.view_log.ViewLogMiddleware',
'askbot.middleware.spaceless.SpacelessMiddleware',
'apps.common.middleware.RequireLoginMiddleware',
'apps.connect.middleware.ActivityMiddleware',
'apps.common.middleware.MobileDetectionMiddleware')
Traceback:
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/rest_framework/compat.py" in view
127. return self.dispatch(request, *args, **kwargs)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
39. resp = view_func(*args, **kwargs)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
52. return view_func(*args, **kwargs)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
399. response = self.handle_exception(exc)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/rest_framework/views.py" in dispatch
396. response = handler(request, *args, **kwargs)
File "/home/jgardner/izeni/doterra_pro/apps/marketplace/views.py" in post
124. quote = quote_req.cart.get_shipping()
File "/home/jgardner/izeni/doterra_pro/apps/marketplace/__init__.py" in get_shipping
99. quote, packages = self.get_quote(packages)
File "/home/jgardner/izeni/doterra_pro/apps/marketplace/__init__.py" in get_quote
244. return easypost_quote(packaging)
File "/home/jgardner/izeni/doterra_pro/apps/marketplace/__init__.py" in easypost_quote
223. batch = easypost.Batch.create(shipments=shipments)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/easypost/__init__.py" in create
483. response, api_key = requestor.request('post', url, wrapped_params)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/easypost/__init__.py" in request
202. http_body, http_status, my_api_key = self.request_raw(method, url, params)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/easypost/__init__.py" in request_raw
241. http_body, http_status = self.requests_request(method, abs_url, headers, params)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/easypost/__init__.py" in requests_request
266. data = self.encode(params)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/easypost/__init__.py" in encode
191. return urllib.urlencode(cls._encode_inner(params))
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/easypost/__init__.py" in _encode_inner
161. encoder(out, key, value)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/easypost/__init__.py" in encode_dict
127. out.extend(cls._encode_inner(n))
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/easypost/__init__.py" in _encode_inner
161. encoder(out, key, value)
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/easypost/__init__.py" in encode_list
135. out.extend(cls._encode_inner(n))
File "/home/jgardner/.virtualenvs/doterra_pro/local/lib/python2.7/site-packages/easypost/__init__.py" in _encode_inner
161. encoder(out, key, value)
Exception Type: TypeError at /marketplace/shipping-quote/
Exception Value: encode_none() takes exactly 3 arguments (4 given)
Reports are being wrapped weird when created via the Python client library and are not being created properly because of it.
Here is an example of code (from the EasyPost docs with Dotenv added) that do not create reports:
import easypost
import os
from dotenv import load_dotenv
load_dotenv()
eptest.api_key = os.getenv("EASYPOST_PROD_API_KEY")
payment_log_report = eptest.Report.create(
start_date="2019-08-01",
end_date="2019-08-23",
type="payment_log"
)
refund_report = eptest.Report.create(
start_date="2019-08-01",
end_date="2019-08-23",
type="refund"
)
shipment_report = eptest.Report.create(
start_date="2019-08-01",
end_date="2019-08-23",
type="shipment"
)
tracker_report = eptest.Report.create(
start_date="2019-08-01",
end_date="2019-08-23",
type="tracker"
)
The response looks like this:
{"report":{"end_date":"2019-08-23","start_date":"2019-08-01","type":"payment_log"},"format":"json","controller":"reports","action":"create","type":"payment_log"}
And should instead look like this:
{"end_date":"2019-08-23","start_date":"2019-08-01","type":"payment_log","format":"json","controller":"reports","action":"create"}
This has been confirmed with a few others trying similar code.
>>> easypost.Tracker.create('2756302021', carrier='DHLExpress')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/tribone/Library/Python/3.7/lib/python/site-packages/easypost/__init__.py", line 590, in create
response, api_key = requestor.request('post', url, wrapped_params)
File "/Users/tribone/Library/Python/3.7/lib/python/site-packages/easypost/__init__.py", line 260, in request
response = self.interpret_response(http_body, http_status)
File "/Users/tribone/Library/Python/3.7/lib/python/site-packages/easypost/__init__.py", line 321, in interpret_response
self.handle_api_error(http_status, http_body, response)
File "/Users/tribone/Library/Python/3.7/lib/python/site-packages/easypost/__init__.py", line 383, in handle_api_error
raise Error(error.get('message', ''), http_status, http_body)
easypost.Error: This api key is no longer active. Please use a different api key or reactivate this key.
The call is supposed to be easypost.Tracker.create(tacking_code='2756302021', carrier='DHLExpress')
, but the error says that the api key configured is not active.
Every time i try to cancel a pickup i receive this error message (it worked in past months)
Error in parsing request XML:Error: Element type "MetaData" must be declared.\n at line 11, column 13
Unable to create pickup, the carrier associated with the batch shipments is inconsistent.
I'm using this code.
`
try:
to_address = easypost.Address.create(
verify=["delivery"],
name='Dr. Steve Brule',
street1='179 N Harbor Dr',
city='Redondo Beach',
state='CA',
zip='90277',
country='US',
phone='4153334444',
email='[email protected]'
)
from_address = easypost.Address.create(
verify=["delivery"],
street1="417 Montgomery Street",
street2="FLOOR 5",
city="San Francisco",
state="CA",
zip="94104",
country="US",
company="EasyPost",
phone="415-456-7890"
)
new_address = easypost.Address.create(
verify=["delivery"],
street1="413835 N Northsight Blvd",
city="Scottsdale",
state="AZ",
zip="85260",
country="US",
phone="416-446-7897"
)
new_address2 = {
"name": 'james smith',
"street1": '1413835 N Northsight Blvd',
"city": 'Scottsdale',
"state": 'AZ',
"zip": '85260',
"country": 'US',
"phone": '8744883682',
"email": '[email protected]'
}
customs_item = easypost.CustomsItem.create(
description="EasyPost t-shirts",
hs_tariff_number=123456,
origin_country="US",
quantity=2,
value=96.27,
weight=21.1
)
customs_info = easypost.CustomsInfo.create(
customs_certify=1,
customs_signer="Hector Hammerfall",
contents_type="gift",
contents_explanation="",
eel_pfc="NOEEI 30.37(a)",
non_delivery_option="return",
restriction_type="none",
restriction_comments="",
customs_items=[customs_item]
)
parcel = easypost.Parcel.create(
length=20.2,
width=10.9,
height=5,
weight=65.9
)
shipment = easypost.Shipment.create(
to_address=to_address,
from_address=from_address,
parcel=parcel,
customs_info=customs_info,
carrier_accounts='ca_843506a2a61e485e94c6dfdab3e817df',
)
pickup = easypost.Pickup.create(
address=new_address2,
shipment=shipment,
mode='test',
carrier_accounts='ca_843506a2a61e485e94c6dfdab3e817df',
reference="my-first-pickup",
min_datetime="2017-07-21 10:30:00",
max_datetime="2017-07-22 10:30:00",
is_account_address=False,
instructions="Special pickup instructions")
carrier_accounts = easypost.CarrierAccount.all()
return HttpResponse(pickup)
except easypost.Error as e:
return HttpResponse(e)`
Currently the way that this repo uses Travis and API keys, Forks cannot pass as Travis will not pass the API key to the tests. We should investigate an alternative setup that is still secure but allows tests to pass on pull requests and forks.
This will increase confidence in PR's as tests will be allowed to pass and it will decrease confusion and frustration on part of the PR author and whoever merges in the changes as they currently need to manually run Travis as them instead of the author if I'm correct.
Per Travis' documentation: Please note that encrypted environment variables are not available for pull requests from forks.
For an example, you can view my latest PR where a KeyError was raised due to this:
TEST_API_KEY = os.environ['TEST_API_KEY']
338../../../virtualenv/python3.7.1/lib/python3.7/os.py:678: in __getitem__
339 raise KeyError(key) from None
340E KeyError: 'TEST_API_KEY'
341The command "py.test --cov=easypost --cov-report=term-missing --vcr-record=none --cov-fail-under=60 tests/" exited with 4.
In init.py Requestor.encode_none() is defined as a classmethod and takes 3 args including the class.
@classmethod
def encode_none(cls, out, key):
pass # do not include None-valued params in request
On line 163 it is called as:
encoder(out, key, value)
Where cls is of course being implicitly passed since it is a classmethod resulting in 4 args actually being received by the method. This is fine for the other encoder classmethods which are set up to take all 4 args, but encode_none raises an exception.
I'm using easypost version 3.1.1
. I had the newest version of the requests
module installed (2.12.4
) but all methods on the easypost library kept failing:
304 http_status = result.status_code
305 except Exception as e:
--> 306 raise Error("Unexpected error communicating with EasyPost. If this "
307 "problem persists please let us know at [email protected].")
308 return http_body, http_status
I eventually fixed the problem by reverting to an older version of the requests
library (2.7.0
) and then easypost worked again. Has anyone else encountered this?
The library doesn't support Python 3 at all.
Some of the issues I recall bumping into when trying to patch it:
urlparse
movedtypes.NoneType
doesn't exist, use type(None)
insteadfrom version import VERSION
needs to be a relative importAnd worst of all, lots of unicode stuff that obviously is broken in py3.
I tried patching stuff up but the unicode behavior is too much for me to handle at this point, and the lack of tests doesn't really help in that regard. I might go about building a completely new client, but right now I'm just building a lightweight wrapper of my own around the REST API.
Please consider updating the library so that projects that have migrated to Python 3 can use it.
It simply makes no sense to include api_key
in JSON dumps. Went through the code base and surprisedly found the fact that security seems not to be a big deal for EasyPost devs.
This may or may not be an issue as from my research you sometimes want to keep SSL sockets open but I wanted to report this in the off chance we need to address it. When PYTHONWARNINGS=always
is used, I get the following warning:
sys:1: ResourceWarning: unclosed <ssl.SSLSocket fd=5, family=AddressFamily.AF_INET6,
type=SocketKind.SOCK_STREAM, proto=0, laddr=('2601:681:201:15ec:5c9c:82f1:1c10:f6a9',
51562, 0, 0), raddr=('2607:f0d0:3803:ca::3', 443, 0, 0)>
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.