Giter Site home page Giter Site logo

usps-api's Introduction

USPS API

Python 3.5, 3.6, 3.7, 3.8 Code Coverage MIT License


This is a simple Python wrapper for the USPS API. Instead of having to deal with XML, use this library and receive nicely formatted JSON back while tracking shipments, creating shipments, and validating addresses.

Installation

To install usps-api, use pip:

pip install usps-api

Or to install from source:

python setup.py install

Configuration

Note: In order to use any of these APIs, you need to register with USPS and get a USERID https://www.usps.com/business/web-tools-apis/welcome.htm. For the create_shipment endpoint, you will also need to request further permissions by emailing [email protected] about Label API access.

Usage

Track Shipments

from usps import USPSApi

usps = USPSApi('XXXXXXXXXXXX')
track = usps.track('00000000000000000000')
print(track.result)

Create Shipment

The create_shipment function needs a to and from address, weight (in ounces), service type and label type. Service types and lable types can be found in usps/constants.py. Defaults are SERVICE_PRIORITY and LABEL_ZPL.

from usps import USPSApi, Address
from usps import SERVICE_PRIORITY, LABEL_ZPL

to_address = Address(
    name='Tobin Brown',
    address_1='1234 Test Ave.',
    city='Test',
    state='NE',
    zipcode='55555'
)

from_address = Address(
    name='Tobin Brown',
    address_1='1234 Test Ave.',
    city='Test',
    state='NE',
    zipcode='55555'
)
weight = 12  # weight in ounces

usps = USPSApi('XXXXXXXXXXXX', test=True)
label = usps.create_label(to_address, from_address, weight, SERVICE_PRIORITY, LABEL_ZPL)
print(label.result)

Validate Address

from usps import USPSApi, Address

address = Address(
    name='Tobin Brown',
    address_1='1234 Test Ave.',
    city='Test',
    state='NE',
    zipcode='55555'
)
usps = USPSApi('XXXXXXXXXXXX', test=True)
validation = usps.validate_address(address)
print(validation.result)

License

MIT. See LICENSE for more details.

usps-api's People

Contributors

ckanoab avatar meichthys avatar micahlyle 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

Watchers

 avatar  avatar  avatar

usps-api's Issues

Address Validate response error - usps.usps.USPSApiError: XML Syntax Error: Please check the XML request to see if it can be parsed.(B)

The following address check "1400 Carpentier St Apt 326, San Leandro, CA 94577-3630" works fine but I get an error when "Apt" is replaced with a '#' sign.

address = Address(
name='Test',
address_1='1400 Carpentier St # 326',
city='San Leandro',
state='CA',
zipcode='94577-3630'
)
usps.usps.USPSApiError: XML Syntax Error: Please check the XML request to see if it can be parsed.(B)

Cannot install

pip install returns:

$ pip install usps-api
Defaulting to user installation because normal site-packages is not writeable
Collecting usps-api
Downloading usps-api-0.5.tar.gz (5.0 kB)
Preparing metadata (setup.py) ... done
Collecting lxml
Downloading lxml-4.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (7.1 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 7.1/7.1 MB 4.6 MB/s eta 0:00:00
Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from usps-api) (2.27.1)
Collecting xmltodict
Downloading xmltodict-0.13.0-py2.py3-none-any.whl (10.0 kB)
Building wheels for collected packages: usps-api
Building wheel for usps-api (setup.py) ... error
error: subprocess-exited-with-error

× python setup.py bdist_wheel did not run successfully.
│ exit code: 1
╰─> [59 lines of output]
running bdist_wheel
running build
running build_py
creating build
creating build/lib
creating build/lib/usps
copying usps/init.py -> build/lib/usps
copying usps/constants.py -> build/lib/usps
copying usps/address.py -> build/lib/usps
copying usps/tests.py -> build/lib/usps
copying usps/usps.py -> build/lib/usps
running egg_info
writing usps_api.egg-info/PKG-INFO
writing dependency_links to usps_api.egg-info/dependency_links.txt
writing requirements to usps_api.egg-info/requires.txt
writing top-level names to usps_api.egg-info/top_level.txt
reading manifest file 'usps_api.egg-info/SOURCES.txt'
writing manifest file 'usps_api.egg-info/SOURCES.txt'
/usr/lib/python3/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
installing to build/bdist.linux-x86_64/wheel
running install
running install_lib
Traceback (most recent call last):
File "", line 2, in
File "", line 34, in
File "/tmp/pip-install-8ild4rhv/usps-api_5380f40a8df740baa9beb673c4d78c88/setup.py", line 7, in
setup(
File "/usr/lib/python3/dist-packages/setuptools/init.py", line 153, in setup
return distutils.core.setup(**attrs)
File "/usr/local/lib/python3.10/distutils/core.py", line 148, in setup
dist.run_commands()
File "/usr/local/lib/python3.10/distutils/dist.py", line 966, in run_commands
self.run_command(cmd)
File "/usr/local/lib/python3.10/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "/usr/lib/python3/dist-packages/wheel/bdist_wheel.py", line 335, in run
self.run_command('install')
File "/usr/local/lib/python3.10/distutils/cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "/usr/local/lib/python3.10/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "/usr/lib/python3/dist-packages/setuptools/command/install.py", line 68, in run
return orig.install.run(self)
File "/usr/local/lib/python3.10/distutils/command/install.py", line 580, in run
self.run_command(cmd_name)
File "/usr/local/lib/python3.10/distutils/cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "/usr/local/lib/python3.10/distutils/dist.py", line 984, in run_command
cmd_obj.ensure_finalized()
File "/usr/local/lib/python3.10/distutils/cmd.py", line 107, in ensure_finalized
self.finalize_options()
File "/usr/lib/python3/dist-packages/setuptools/command/install_lib.py", line 17, in finalize_options
self.set_undefined_options('install',('install_layout','install_layout'))
File "/usr/local/lib/python3.10/distutils/cmd.py", line 290, in set_undefined_options
setattr(self, dst_option, getattr(src_cmd_obj, src_option))
File "/usr/local/lib/python3.10/distutils/cmd.py", line 103, in getattr
raise AttributeError(attr)
AttributeError: install_layout. Did you mean: 'install_platlib'?
[end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for usps-api
Running setup.py clean for usps-api
Failed to build usps-api
Installing collected packages: xmltodict, lxml, usps-api
Running setup.py install for usps-api ... error
error: subprocess-exited-with-error

× Running setup.py install for usps-api did not run successfully.
│ exit code: 1
╰─> [51 lines of output]
running install
/usr/lib/python3/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
warnings.warn(
running build
running build_py
creating build
creating build/lib
creating build/lib/usps
copying usps/init.py -> build/lib/usps
copying usps/constants.py -> build/lib/usps
copying usps/address.py -> build/lib/usps
copying usps/tests.py -> build/lib/usps
copying usps/usps.py -> build/lib/usps
running egg_info
writing usps_api.egg-info/PKG-INFO
writing dependency_links to usps_api.egg-info/dependency_links.txt
writing requirements to usps_api.egg-info/requires.txt
writing top-level names to usps_api.egg-info/top_level.txt
reading manifest file 'usps_api.egg-info/SOURCES.txt'
writing manifest file 'usps_api.egg-info/SOURCES.txt'
running install_lib
Traceback (most recent call last):
File "", line 2, in
File "", line 34, in
File "/tmp/pip-install-8ild4rhv/usps-api_5380f40a8df740baa9beb673c4d78c88/setup.py", line 7, in
setup(
File "/usr/lib/python3/dist-packages/setuptools/init.py", line 153, in setup
return distutils.core.setup(**attrs)
File "/usr/local/lib/python3.10/distutils/core.py", line 148, in setup
dist.run_commands()
File "/usr/local/lib/python3.10/distutils/dist.py", line 966, in run_commands
self.run_command(cmd)
File "/usr/local/lib/python3.10/distutils/dist.py", line 985, in run_command
cmd_obj.run()
File "/usr/lib/python3/dist-packages/setuptools/command/install.py", line 68, in run
return orig.install.run(self)
File "/usr/local/lib/python3.10/distutils/command/install.py", line 580, in run
self.run_command(cmd_name)
File "/usr/local/lib/python3.10/distutils/cmd.py", line 313, in run_command
self.distribution.run_command(command)
File "/usr/local/lib/python3.10/distutils/dist.py", line 984, in run_command
cmd_obj.ensure_finalized()
File "/usr/local/lib/python3.10/distutils/cmd.py", line 107, in ensure_finalized
self.finalize_options()
File "/usr/lib/python3/dist-packages/setuptools/command/install_lib.py", line 17, in finalize_options
self.set_undefined_options('install',('install_layout','install_layout'))
File "/usr/local/lib/python3.10/distutils/cmd.py", line 290, in set_undefined_options
setattr(self, dst_option, getattr(src_cmd_obj, src_option))
File "/usr/local/lib/python3.10/distutils/cmd.py", line 103, in getattr
raise AttributeError(attr)
AttributeError: install_layout. Did you mean: 'install_platlib'?
[end of output]

note: This error originates from a subprocess, and is likely not a problem with pip.
error: legacy-install-failure

× Encountered error while trying to install package.
╰─> usps-api

note: This is an issue with the package mentioned above, not pip.
hint: See above for output from the failure.

XML Syntax Error: Please check the XML request to see if it can be parsed (Potentially Encoding)

Using the address validate API with an address that has a city of "Kapaʻa" causes a returned error of "XML Syntax Error: Please check the XML request to see if it can be parsed".

The developer guide (https://www.usps.com/business/web-tools-apis/general-api-developer-guide.htm) points out that "ISO-8859-1 encoding is the expected character set for the request". I manually tested making a request setting the encoding='iso-8859-1' in etree's tostring and I initially thought that solved the problem, but then realized I had made a mistake and it didn't. Not sure at the moment why it's happening, or if it's just a USPS bug.

Address validation should allow us to pass revsion=1

The usps has a revision 1 for the address validation api in addition to the tracking api. The code should either allow us to set a revision to use for all calls or set the revision=1 flag on the address call in addition to the tracking call. I am happy to put a PR together for this if you want.

Support for tracking multiple packages

Thanks for an awesome package!

Since the USPS API can handle up to 35 tracking IDs per request, i'm wondering if there's a good way to pass a list with your existing package, or if it would be possible to add this feature.

I tried to generate the URL string using variations of the code below, but I lost the detailed dictionary that your single query code provides.

{'EventTime': '
'EventDate':
'Event':
'EventCity':
'EventState':
'EventZIPCode':
'EventCountry':
'FirmName':
'Name':
'AuthorizedAgent':
'DeliveryAttributeCode': },

-----------------------------------what I tried --------------------------------------------------

def USPSRequest(trackingNumbers,userID):

TrackingNumbersFormatted = f'<TrackRequest USERID="{userID}">'
TrackingNumbersFormatted = str(TrackingNumbersFormatted)
for i in trackingNumbers:
    TrackingNumbersFormatted += "<TrackID ID="
    TrackingNumbersFormatted +='"'
    TrackingNumbersFormatted += str(i).strip()
    TrackingNumbersFormatted +='"></TrackID>'

URL = f'https://secure.shippingapis.com/ShippingAPI.dll?API=TrackV2&XML={TrackingNumbersFormatted}</TrackRequest>'.replace('&amp;','&').replace('&lt;','<')
#return URL 
        
xml_response = requests.get(URL).content
response = json.loads(json.dumps(xmltodict.parse(xml_response)))
if 'Error' in response:
    raise USPSApiError(response['Error']['Description']) 
return response

I'm fairly new to APIs & XML so I'm sure there's a much more elegant way to do this.

Thanks again, and have a great night!

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.