Git Product home page Git Product logo

easypost-python's People

Contributors

abramclark avatar agconti avatar dev-guest-easypost avatar dlc37 avatar doriangray avatar fiendish avatar gdrosos avatar gsinkin avatar jamesbeith avatar jchen293 avatar jontsai avatar jstreebin avatar justintime50 avatar k-funk avatar mbeale avatar mwaldt avatar nwithan8 avatar rblakemesser avatar roehnan avatar roguelazer avatar ryannguyen16 avatar sawyer avatar shalakhin avatar thepsyjo avatar victoryftw avatar wyounas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easypost-python's Issues

Problem when creating a report by date

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:

response, api_key = requestor.request('post', url, wrapped_params, False)

Things appear to work properly when wrapped_params is changed to params like this:

response, api_key = requestor.request('post', url, params, False)

This api key is no longer active. Please use a different api key or reactivate this key.

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.

Request: Subclassed Exceptions

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.

CarrierAccount.types api_key not handled correctly

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

Can't buy using rate_id

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.

Orders label not working

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?

Enter a host to ping:

Enter a host to ping:

When use

import easypost
import urllib3
urllib3.disable_warnings()
easypost.api_key = 'API_KEY'

create address

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 ?

Needs to support multiple verify/verify_strict parameters to address create

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.

Support Pip install

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?

Error when passing unicode

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?

Multi-Shipment ScanForm Error

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.

batch_api_obj.label() returning 'AttributeError'

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'

Error: The Pickup Location is a mandatory field

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.txt

<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

Is weight for parcel round up?

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"

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.

'Tracker' object has no attribute 'id'

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,)```

Can't use `'key' in shipment`

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']

Issue with UPS tracking numbers that start with "105..."

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.

Support for multiple-package shipments?

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!

Getting HTTPS Issue

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.

Error Handling Around Customs Items Not Exposing Proper Message

Summary

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.

Acceptance Criteria

  • Investigate why the Wrong parameter type error is occurring
  • Investigate if this error occurs for other objects/fields or is only for this one field customs_item['description']
  • Create a PR to fix the error handling to properly return the message

Additional Info

Screen Shot 2021-09-07 at 1 28 06 PM

A typical error response should look something like:

{"error":{"code":"PARAMETER.INVALID_TYPE","message":"Wrong parameter type.","errors":[{"field":"weight","message":"must be a float"}]}}

Test Failure Due to API Change

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.

Shipment.create error message with no details

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()

Missing or invalid element: FromPhone.

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

Problem with shipment buy using lowest rate

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,

  1. the shipment selected is the highest rate (e.g. DHL Medical 35,65โ‚ฌ)
  2. i receive an error from the backend "ValueError: could not convert string to float: '35,65'"

Can you help me?

DeprecationWarning: Use of .. or absolute paths will raise exceptions...

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')

Creating Pickups and specifying carrier accounts

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.

Undocumented Easypost APIs

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!

Setting reference on shipment through order

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

Endica error on form 2976A

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)

Traceback when callilng encode_none

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)

Unable to Create Reports

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.

Unhelpful Error Message During Tracker.create

>>> 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.

Unable to cancel a pickup

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

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)` 

Encrypted Environment Variables are not Available on Forks - Travis CI Failing

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.

Requestor.encode_none() only takes 3 args, but is called 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.

Can't use library with newest version of Requests module

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?

Python 3 support

The library doesn't support Python 3 at all.

Some of the issues I recall bumping into when trying to patch it:

  • urlparse moved
  • types.NoneType doesn't exist, use type(None) instead
  • from version import VERSION needs to be a relative import

And 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.

ResourceWarning: Unclosed ssl.SSLSOCKET

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)>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.