Skip to main content

Wraps the eBay REST APIs.

Project description

ebay_rest

A Python 3 pip package that wraps eBay’s REST APIs.

BASIC Installation

Start with the basic installation of the package. It is easier to install, saves storage and is often enough.

Use the package manager pip to install ebay_rest. Substitute pip3 for pip if your computer also has Python 2 installed.

pip install ebay_rest

COMPLETE Installation

The complete installation has an extra ability; it can use browser automation to get what eBay calls a user token.

When installing the library, utilize the 'extra' we named complete.

pip install ebay_rest[complete]

Install Chrome.

pip install selenium

Install Webdriver, aka Chromedriver, for your version of Chrome .

Here is a method for installing Webdriver/Chromedriver on macOS and tweaking security to permit it.

Install HomeBrew

brew install chromedriver
cd /usr/local/Caskroom/chromedriver

cd to the subdirectory that matches your Chrome version, e.g., 91.0.4472.101

xattr -d com.apple.quarantine chromedriver

Setup

Follow the instructions here.

Usage

from ebay_rest import API, DateTime, Error, Reference

print(f"eBay's official date and time is {DateTime.to_string(DateTime.now())}.\n")

print("All valid eBay global id values, also known as site ids.")
print(Reference.get_global_id_values(), '\n')

try:
    api = API(application='production_1', user='production_1', header='US')
except Error as error:
    print(f'Error {error.number} is {error.reason}  {error.detail}.\n')
else:
    try:
        print("The five least expensive iPhone things now for sale on-eBay:")        
        for record in api.buy_browse_search(q='iPhone', sort='price', limit=5):
            if 'record' not in record:
                pass    # TODO Refer to non-records, they contain optimization information.
            else:
                item = record['record']
                print(f"item id: {item['item_id']} {item['item_web_url']}")
    except Error as error:
        print(f'Error {error.number} is {error.reason} {error.detail}.\n')
    else:
        pass

print("\nClass documentation:")
print(help(API))    # Over a hundred methods are available!
print(help(DateTime))
print(help(Error))
print(help(Reference))

FAQ - Frequently Asked Questions

Question: How are API results organized?

Answer:

  • Elemental information is stored in dates, integers, strings and other basic built-in types.
  • Dictionaries contain related elements.
  • Lists contain information organized repetitively; expect zero or more contents.
  • Dicts and Lists may be nested.
  • eBay classifies data as optional or mandatory. Optional elements, dicts or lists are omitted. Manditories have a None value.

Q: How are paged calls/results handled?

A: A simple generator is implemented.

  • To be clear, "Paging" is eBay's term for repeating a call while advancing a record offset to get all records.
  • eBay documentation has the word "Page" in the return type of paging calls.
  • Do NOT supply a record "offset" parameter when making a paging call.
  • The "limit" parameter is repurposed to control how many records from the entire set you want.
  • To get all possible records, don't supply a limit.
  • eBay imposes a hard limit on some calls, typically 10,000 records. Use filters to help keep below the limit. Use try-except to handle going over.
  • Avoid exhausting memory by making the call within a "for" loop.

Q: What should I do when the browser automation opens pops a window open on my computer?

A: Watch and be ready to act.

  • At the beginning, you may see a captcha; you need to complete it within 30-seconds.
  • Near the end, you may see a 2FA (two-factor authentication) prompt; you need to complete it within 30-seconds.
  • Otherwise, be patient, give the whole thing up to 2-minutes to complete, the pop-up will close automatically.

Q: Can the browser automation be stopped?

A1: Quoting a user of this library, "I use ebay_rest for a web server application and don't use [browser automation] to get refresh tokens. I use JS to push people to the right eBay web page when they click an 'authorize' button; they then fill in their login on the eBay site and I pick up the consent token on our 'live' server (the one specified on the eBay token details). The live server then builds a redirect which goes to the machine that actually requested the token originally (all this happens in the browser, including the original eBay redirect, so it all works fine with localhost addresses)."

A2: Reusing the result of the browser pop-up is possible. After running your program, check your terminal/console or info level logger to see your “production_refresh_token” and “refresh_token_expiry”.

When the following are blank, browser automation is used to get refresh tokens.

    "refresh_token": "",
    "refresh_token_expiry": ""

Instead, do something like this, with, of course, your token info.

    "refresh_token": "production_refresh_token",
    "refresh_token_expiry": "production_token_expiry"

Use of an ebay_rest.json file is optional; the Class initializer accepts relevant keyword parameters.

        :param application (str or dict, optional) :
        Supply the name of the desired application record in ebay_rest.json or a dict with application credentials.

        Can omit when ebay_rest.json contains only one application record.
        :param user (str or dict, optional) :
        Supply the name of the desired user record in ebay_rest.json or a dict with user credentials.
        Can omit when ebay_rest.json contains only one user record.

        :param header (str or dict, optional) :
        Supply the name of the desired header record in ebay_rest.json or a dict with header credentials.
        Can omit when ebay_rest.json contains only one header record.

Sample code.

from ebay_rest import API, Error

application = {
    "app_id": "placeholder-placeholder-PRD-placeholder-placeholder",
    "cert_id": "PRD-placeholder-placeholder-placeholder-placeholder-placeholder",
    "dev_id": "placeholder-placeholder-placeholder-placeholder-placeholder",
    "redirect_uri": "placeholder-placeholder-placeholder-placeholder"
}

user = {
    "email_or_username": "<production-username>",
    "password": "<production-user-password>",
    "scopes": [
        "https://api.ebay.com/oauth/api_scope",
        "https://api.ebay.com/oauth/api_scope/sell.inventory",
        "https://api.ebay.com/oauth/api_scope/sell.marketing",
        "https://api.ebay.com/oauth/api_scope/sell.account",
        "https://api.ebay.com/oauth/api_scope/sell.fulfillment"
    ],
    "refresh_token": "production-refresh_token",
    "refresh_token_expiry": "production-token_expiry"
}

header = {
    "accept_language": "en-US",
    "affiliate_campaign_id": "",
    "affiliate_reference_id": "",
    "content_language": "en-CA",
    "country": "CA",
    "currency": "CAD",
    "device_id": "",
    "marketplace_id": "EBAY_ENCA",
    "zip": ""
}

try:
    api = API(application=application, user=user, header=header)
except Error as error:
    print(f'Error {error.number} is {error.reason}  {error.detail}.\n')
else:
    try:
        print("The five least expensive iPhone things now for sale on-eBay:")        
        for record in api.buy_browse_search(q='iPhone', sort='price', limit=5):
            if 'record' not in record:
                pass    # TODO Refer to non-records, they contain optimization information.
            else:
                item = record['record']
                print(f"item id: {item['item_id']} {item['item_web_url']}")
    except Error as error:
        print(f'Error {error.number} is {error.reason} {error.detail}.\n')
    else:
        pass

When using eBay's sandbox:

  1. Omit "scopes."
  2. Your credentials will contain 'SBX' instead of 'PRD.'

Output.

The five least expensive iPhone things now for sale on eBay:
item id: v1|110551100598|410108380484 http://www.sandbox.ebay.com/itm/Retro-Magnetic-Wallet-Leather-Case-For-Apple-iPhone-13-Pro-Max-12-11-XR-8-Cover-/110551100598?hash=item19bd5becb6:g:aXsAAOSwaiFiyAV9
item id: v1|110551164737|410108400925 http://www.sandbox.ebay.com/itm/For-iPhone-6-6-7-8-Plus-LCD-Display-Touch-Screen-Replacement-Home-Button-Camera-/110551164737?hash=item19bd5ce741:g:6hcAAOSwE3Ni45Qu
item id: v1|110551164738|410108400957 http://www.sandbox.ebay.com/itm/For-iPhone-6-6-7-8-Plus-LCD-Display-Touch-Screen-Replacement-Home-Button-Camera-/110551164738?hash=item19bd5ce742:g:4BcAAOSwG8Ni45Ra
item id: v1|110551164739|410108400989 http://www.sandbox.ebay.com/itm/For-iPhone-6-6-7-8-Plus-LCD-Display-Touch-Screen-Replacement-Home-Button-Camera-/110551164739?hash=item19bd5ce743:g:4CEAAOSwG8Ni45SQ

Q: Why is eBay giving an "Internal Error" or "Internal Server Error"?

A: Rapidly repeating an API call with the same parameter values can trigger this.

Q: Parallelism, is it safe to do treading or multiprocessing?

A: Yes, for treading. Multiprocessing is unknown, help wanted.

Q: How to optimize API calls?

A: Prioritized, do the first things first.

  1. Cache results to avoid repeating calls with identical parameter values.
  2. Some calls have filtering options; omit unneeded data.
  3. When the call returns a list, make the call in a "for" loop.
  4. Use threading to make calls in parallel but don't exhaust RAM.
  5. Use multiprocessing. -- Multiprocessing support is a goal. -- A safe workaround is to concurrently run copies of your program and divide the work among each.
  6. Reuse the API object.
  7. Switch to a faster internet connection.
  8. Switch to computer with faster cores.

Q: How to get data from a response header?

A: It is not currently possible; it is an open issue. Workarounds:

  1. In some cases, another call can get the information; a demonstration is in the unit tests, search for test_sell_feed_create_inventory_task and task_id_new.
  2. You could fork this library, and hack the call you need, so that it returns that needed data.
  3. You could write code from scratch to make the RestFul call.

Q: How to upload a file?

A: It is not currently possible; it is an open issue. Workarounds:

  1. In some cases, another call can be made for each record instead of doing a bulk upload.
  2. You could fork this library, and hack the call you need, to force-feed it to your file location.
  3. You could write code from scratch to make the RestFul call.

Contributing

  • Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
  • Note the error number guide documented in the Error class definition.
  • Observe README.me files found in directories that contain generated code.
  • Please make sure to update unit tests as appropriate.

Setup Steps

  1. Use your preferred Python development tools, I use PyCharm.
  2. Make a virtual environment for pip; I use 'venv.'
  3. Install the Python libraries needed for code generation and release.
python3 -m pip install -r requirements_dev.txt
  1. Install the code generator from Swagger. Run 'brew' on macOS and 'sudo' on Linux.
brew install swagger-codegen
sudo apt-get install swagger-codegen
  1. In the test directory, copy "ebay_rest_sample.json" to "ebay_rest.json" and follow the instructions in the file.
  2. Follow the earlier instructions about installing Chome and chromedriver.

Development Steps:

  • Watch for README.md files in directories; they contain warnings about generated code and perhaps other things.
  • Do test driven development; while adding features or fixing bugs, modify /test/ebay_rest.py and run it.
  • Periodically run /script/generate_code.py to get the latest API information from eBay and generate code.

Release Steps

  1. in the root directory of the project, run CLI commands
    1. (macOS only) brew update && brew upgrade && brew cleanup
    2. (Linux only) sudo apt-get update && sudo apt-get upgrade
    3. python3 -m pip install --upgrade pip
    4. python3 -m pip install --upgrade -r requirements_dev.txt
    5. pipreqs --print src
  2. edit the setup.cfg file
    1. update the section install_requires per the output from pipregs
    2. advance the version number
  3. repeat until error-free
    1. run /ebay_rest/scripts/generate_code.py
    2. run /test/ebay_rest.py
    3. resolve any errors but don't directly edit the code generated by generate_code.py
  4. in the root directory of the project, run CLI commands
    1. python3 -m build
    2. python3 -m twine upload dist/*0.0.XX*
      1. in place of 0.0.xx put the new version number
      2. username: __token__
      3. password: your token

Legal

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ebay_rest-0.0.29.tar.gz (1.3 MB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ebay_rest-0.0.29-py3-none-any.whl (2.6 MB view details)

Uploaded Python 3

File details

Details for the file ebay_rest-0.0.29.tar.gz.

File metadata

  • Download URL: ebay_rest-0.0.29.tar.gz
  • Upload date:
  • Size: 1.3 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.1

File hashes

Hashes for ebay_rest-0.0.29.tar.gz
Algorithm Hash digest
SHA256 f874d77e83d57643bbcaec4b741c649c41eb24f02e4deb6de26f373003643e6f
MD5 421ee3966af99ad06c8a84ea96279a11
BLAKE2b-256 cb3fd3843e67ea873f660a6e328bd3ddf2a9a138161e5a9cfd12e3d6696331a9

See more details on using hashes here.

File details

Details for the file ebay_rest-0.0.29-py3-none-any.whl.

File metadata

  • Download URL: ebay_rest-0.0.29-py3-none-any.whl
  • Upload date:
  • Size: 2.6 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.11.1

File hashes

Hashes for ebay_rest-0.0.29-py3-none-any.whl
Algorithm Hash digest
SHA256 e2474c92073710783e831386b939713d0647c18566f477e6a321f2579a081bd8
MD5 7d41d756488e788c6a8865f33c8e611c
BLAKE2b-256 633436b96f907af9cb61d05bbcdec37c1bdb9e1d523517a9177b9395c9706c33

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page