ebay-rest-client (0.1.0)

Published 2026-04-07 09:48:18 +00:00 by claudi

Installation

pip install --index-url  ebay-rest-client

About this package

REST-first eBay client with shared OAuth core and isolated OpenAPI-generated packages.

eBay REST Client

This workspace contains a REST-first Python client for the newer eBay APIs backed by:

  • a shared OAuth 2.0 core
  • a shared HTTP transport layer
  • handwritten public wrappers per API domain
  • isolated OpenAPI-generated Pydantic models per contract

Implemented API domains:

  • Notification
  • Inventory
  • Fulfillment
  • Account
  • Feed
  • Media

The public entry point is EbayClient, which wires all six wrappers behind one shared transport and one shared token store.

For a workflow-oriented guide with setup patterns, scope planning, and common usage recipes, see docs/usage-guide.md.

Project Layout

  • ebay_client/client.py: top-level EbayClient facade
  • ebay_client/<api>/client.py: handwritten wrapper layer for each API
  • ebay_client/generated/<api>/models.py: generated Pydantic models for that contract
  • ebay_client/core/auth/: OAuth configuration, token model, token store, and OAuth client
  • ebay_client/core/http/: shared transport and error handling
  • examples/: runnable examples for media workflows and FastAPI notification webhooks

Quick Start

Install the package from the project root:

& .\.venv\Scripts\python.exe -m pip install -e .

Install development dependencies when you want tests and code generation tooling:

& .\.venv\Scripts\python.exe -m pip install -e .[dev]

Packaging

Print the current package version:

& .\.venv\Scripts\python.exe .\scripts\set_version.py --print-current

Update the package version in pyproject.toml:

& .\.venv\Scripts\python.exe .\scripts\set_version.py 0.1.1

Build a wheel into dist\:

& .\.venv\Scripts\python.exe .\scripts\build_wheel.py

Set the version and build the wheel in one step:

& .\.venv\Scripts\python.exe .\scripts\build_wheel.py --version 0.1.1

Upload the wheel to the Forgejo package registry:

.\upload_wheel_to_forgejo_pypi.ps1

Force a rebuild before upload:

.\upload_wheel_to_forgejo_pypi.ps1 -Build

Build a specific version and upload it:

.\upload_wheel_to_forgejo_pypi.ps1 -Build -Version 0.1.1

Create .pypirc in the project root from .pypirc.example and fill in your Forgejo token before uploading.

Create a client with your eBay credentials:

from ebay_client import EbayClient
from ebay_client.core.auth.models import EbayOAuthConfig

oauth_config = EbayOAuthConfig(
	client_id="your-client-id",
	client_secret="your-client-secret",
	default_scopes=[
		"https://api.ebay.com/oauth/api_scope/sell.inventory",
	],
)

client = EbayClient(oauth_config)

inventory_page = client.inventory.get_inventory_items(limit=25)
orders_page = client.fulfillment.get_orders(limit=25)

EbayClient exposes these wrappers:

  • client.notification
  • client.inventory
  • client.fulfillment
  • client.account
  • client.feed
  • client.media

Authentication

The client uses a custom OAuth implementation in ebay_client.core.auth.oauth.EbayOAuthClient. There is no dependency on eBay's official OAuth client.

Important behavior:

  • EbayClient creates an internal EbayOAuthClient and uses it automatically for API calls.
  • The default token store is InMemoryTokenStore, so tokens are not persisted across process restarts.
  • If you want persistent tokens, provide your own TokenStore implementation to EbayClient.
  • redirect_uri is only required when you use the authorization-code flow.
  • For plain wrapper usage, the transport can obtain client-credentials tokens automatically.

If you need interactive OAuth flows, build and use EbayOAuthClient directly with the same token store you pass to EbayClient:

from ebay_client import EbayClient
from ebay_client.core.auth.models import EbayOAuthConfig
from ebay_client.core.auth.oauth import EbayOAuthClient
from ebay_client.core.auth.store import InMemoryTokenStore

store = InMemoryTokenStore()

oauth_config = EbayOAuthConfig(
	client_id="your-client-id",
	client_secret="your-client-secret",
	redirect_uri="https://your-app.example/callback",
	default_scopes=[
		"https://api.ebay.com/oauth/api_scope",
		"https://api.ebay.com/oauth/api_scope/commerce.notification.subscription",
	],
)

oauth = EbayOAuthClient(oauth_config, token_store=store)
authorization_url = oauth.build_authorization_url(state="csrf-token")

client = EbayClient(oauth_config, token_store=store)

Authentication Caveats

The wrappers handle scope selection for you, but a few behaviors are worth calling out explicitly.

  • Read methods often accept either a readonly scope or the broader write scope. Internally, the wrappers express this through scope_options, so an already-cached broader token is reused instead of forcing a narrower re-auth.
  • Write methods request the stronger write scope directly.
  • If the current token is missing required scopes, the OAuth layer requests a new token with the needed scope set.
  • default_scopes matter most when you explicitly use build_authorization_url(), exchange_code(), or refresh_access_token() without passing scopes.
  • Notification inbound webhooks are not authenticated with bearer tokens. They are validated through the X-EBAY-SIGNATURE header and eBay's public-key lookup flow.

Known endpoint-specific caveats:

  • FulfillmentClient.issue_refund() uses https://api.ebay.com/oauth/api_scope/sell.finances, not the normal fulfillment scope.
  • Payment-dispute methods use https://api.ebay.com/oauth/api_scope/sell.payment.dispute and target https://apiz.ebay.com/sell/fulfillment/v1/.... The shared transport already supports this alternate host.
  • Some Inventory write endpoints require a Content-Language header. Those wrapper methods require content_language=... explicitly.
  • eBay documents additional Digital Signatures requirements for some refund scenarios, especially for some EU and UK sellers. That signing flow is not implemented in this client yet, so refund support is limited to the normal OAuth-backed request path.

Implemented Functionality

This section is intended as the quick capability map for the handwritten wrappers. For payload and response shapes, use the generated models in ebay_client/generated/<api>/models.py.

Notification

Management and subscription features:

  • config: get_config(), update_config()
  • topics: get_topics(), get_topic()
  • destinations: get_destinations(), create_destination(), get_destination(), update_destination(), delete_destination()
  • subscriptions: get_subscriptions(), create_subscription(), get_subscription(), update_subscription(), delete_subscription()
  • subscription state actions: disable_subscription(), enable_subscription(), test_subscription()
  • filters: create_subscription_filter(), get_subscription_filter(), delete_subscription_filter()
  • public-key lookup: get_public_key()

Webhook helpers in ebay_client.notification.webhook cover:

  • challenge responses
  • signature-header parsing
  • signature verification against eBay public keys
  • normalized event envelopes
  • framework-neutral request handling

See examples/fastapi_notification_webhook.py for a concrete FastAPI integration.

Inventory

Inventory wrapper coverage includes:

  • inventory items: get_inventory_item(), get_inventory_items(), create_or_replace_inventory_item(), delete_inventory_item()
  • bulk item workflows: bulk_get_inventory_item(), bulk_create_or_replace_inventory_item()
  • price and quantity updates: bulk_update_price_quantity()
  • product compatibility: get_product_compatibility(), create_or_replace_product_compatibility(), delete_product_compatibility()
  • inventory item groups: get_inventory_item_group(), create_or_replace_inventory_item_group(), delete_inventory_item_group()
  • offers: get_offer(), get_offers(), create_offer(), bulk_create_offer(), update_offer(), delete_offer()
  • listing publication: publish_offer(), bulk_publish_offer(), publish_offer_by_inventory_item_group()
  • listing withdrawal: withdraw_offer(), withdraw_offer_by_inventory_item_group()
  • fees: get_listing_fees()
  • locations: get_inventory_location(), get_inventory_locations(), create_inventory_location(), update_inventory_location(), delete_inventory_location(), enable_inventory_location(), disable_inventory_location()
  • migration and mapping: bulk_migrate_listing(), get_sku_location_mapping(), create_or_replace_sku_location_mapping(), delete_sku_location_mapping()

Fulfillment

Fulfillment wrapper coverage includes:

  • orders: get_order(), get_orders()
  • refunds: issue_refund()
  • shipping fulfillments: get_shipping_fulfillments(), get_shipping_fulfillment(), create_shipping_fulfillment()
  • payment disputes: get_payment_dispute(), get_payment_dispute_summaries(), get_payment_dispute_activities(), contest_payment_dispute(), accept_payment_dispute()
  • dispute evidence: upload_evidence_file(), add_evidence(), update_evidence(), fetch_evidence_content()
  • helper types: CreatedShippingFulfillment, EvidenceFileDownload, extract_fulfillment_id()

Account

Account wrapper coverage includes:

  • fulfillment policies: list, get, create, update, delete, and get_fulfillment_policy_by_name()
  • payment policies: list, get, create, update, delete, and get_payment_policy_by_name()
  • return policies: list, get, create, update, delete, and get_return_policy_by_name()
  • seller capabilities: get_privileges(), get_opted_in_programs()

Feed

Feed wrapper coverage includes:

  • tasks: get_tasks(), create_task(), get_task()
  • task files: upload_file(), get_input_file(), get_result_file(), get_latest_result_file()
  • schedule templates: get_schedule_templates(), get_schedule_template()
  • schedules: get_schedules(), create_schedule(), get_schedule(), update_schedule(), delete_schedule()
  • helper types: CreatedFeedResource, FeedFileDownload, extract_feed_resource_id()

Media

Media wrapper coverage includes raw API methods plus higher-level workflow helpers.

Core operations:

  • images: create_image_from_file(), create_image_from_path(), create_image_from_url(), get_image()
  • videos: create_video(), upload_video(), get_video(), wait_for_video()
  • documents: create_document(), create_document_from_url(), upload_document(), upload_document_from_path(), get_document(), wait_for_document()

Workflow helpers:

  • create_upload_and_wait_video()
  • create_upload_and_wait_video_from_path()
  • create_upload_and_wait_document()
  • create_upload_and_wait_document_from_path()
  • create_document_from_url_and_wait()
  • extract_resource_id()
  • guess_media_content_type()
  • result types: VideoWorkflowResult, DocumentWorkflowResult

See examples/media_workflows.py for end-to-end examples.

Working With Generated Models

The wrapper layer is intentionally thin. For request bodies and typed responses, import the generated models for the relevant API package.

Example:

from ebay_client import EbayClient
from ebay_client.core.auth.models import EbayOAuthConfig
from ebay_client.generated.media.models import CreateDocumentRequest

client = EbayClient(
	EbayOAuthConfig(
		client_id="your-client-id",
		client_secret="your-client-secret",
		default_scopes=["https://api.ebay.com/oauth/api_scope/sell.inventory"],
	)
)

result = client.media.create_upload_and_wait_document_from_path(
	CreateDocumentRequest(
		documentType="USER_GUIDE_OR_MANUAL",
		languages=["en-US"],
	),
	"./manual.pdf",
)

Webhook Usage

For Notification inbound events, the recommended flow is:

  • handle the eBay challenge request with WebhookRequestHandler.handle_challenge()
  • resolve the notification public key through WebhookPublicKeyResolver
  • validate X-EBAY-SIGNATURE with WebhookSignatureValidator
  • dispatch the verified event envelope returned by WebhookRequestHandler.handle_notification()

The FastAPI example in examples/fastapi_notification_webhook.py shows the complete GET challenge and POST notification flow.

Code Generation

The project uses a dedicated code generation environment because the main runtime is currently on Python 3.14 while datamodel-code-generator is run from the separate codegen environment.

Generate all API model packages from the project root:

& .\.venv\Scripts\python.exe .\scripts\generate_clients.py

Generate only one API package:

& .\.venv\Scripts\python.exe .\scripts\generate_clients.py --api notification

Generated output is written to ebay_client/generated/<api>/models.py.

Validation

Run the test suite from the project root:

& .\.venv\Scripts\python.exe -m pytest

Requirements

Requires Python: >=3.11
Details
PyPI
2026-04-07 09:48:18 +00:00
0
141 KiB
Assets (1)
Versions (1) View all
0.1.0 2026-04-07