Add media client and models for eBay media API; implement image and video handling methods

This commit is contained in:
claudi 2026-04-07 10:12:50 +02:00
parent e99937cc43
commit 1307d5691a
9 changed files with 615 additions and 1 deletions

View file

@ -13,6 +13,15 @@ from ebay_client.generated.account.models import Programs
from ebay_client.generated.feed.models import TaskCollection
from ebay_client.generated.fulfillment.models import Order
from ebay_client.generated.inventory.models import InventoryItemWithSkuLocaleGroupid
from ebay_client.generated.media.models import (
CreateDocumentFromUrlRequest,
CreateDocumentRequest,
CreateImageFromUrlRequest,
CreateVideoRequest,
DocumentResponse,
ImageResponse,
Video,
)
from ebay_client.generated.notification.models import (
Config,
CreateSubscriptionFilterRequest,
@ -26,6 +35,7 @@ from ebay_client.generated.notification.models import (
UpdateSubscriptionRequest,
)
from ebay_client.inventory.client import InventoryClient
from ebay_client.media.client import CreatedMediaResource, MediaClient
from ebay_client.notification.client import NotificationClient
@ -359,4 +369,155 @@ def test_feed_wrapper_accepts_any_documented_feed_scope_option(httpx_mock: HTTPX
["https://api.ebay.com/oauth/api_scope/sell.marketing"],
["https://api.ebay.com/oauth/api_scope/commerce.catalog.readonly"],
["https://api.ebay.com/oauth/api_scope/sell.analytics.readonly"],
]
]
def test_media_wrapper_returns_image_model_from_url(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
method="POST",
url="https://api.ebay.com/commerce/media/v1_beta/image/create_image_from_url",
json={"imageUrl": "https://i.ebayimg.com/images/g/demo.jpg", "expirationDate": "2026-12-31T00:00:00Z"},
status_code=201,
)
client = MediaClient(build_transport())
result = client.create_image_from_url(
CreateImageFromUrlRequest(imageUrl="https://example.test/demo.jpg")
)
assert isinstance(result, ImageResponse)
assert result.imageUrl == "https://i.ebayimg.com/images/g/demo.jpg"
request = httpx_mock.get_requests()[0]
body = json.loads(request.content.decode("utf-8"))
assert body["imageUrl"] == "https://example.test/demo.jpg"
def test_media_wrapper_serializes_multipart_image_upload(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
method="POST",
url="https://api.ebay.com/commerce/media/v1_beta/image/create_image_from_file",
json={"imageUrl": "https://i.ebayimg.com/images/g/uploaded.jpg"},
status_code=201,
)
client = MediaClient(build_transport())
result = client.create_image_from_file(
file_name="demo.jpg",
content=b"binary-image-content",
content_type="image/jpeg",
)
assert isinstance(result, ImageResponse)
request = httpx_mock.get_requests()[0]
assert request.headers["Content-Type"].startswith("multipart/form-data;")
assert b"name=\"image\"" in request.content
assert b"filename=\"demo.jpg\"" in request.content
assert b"binary-image-content" in request.content
def test_media_wrapper_returns_created_resource_location_for_video(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
method="POST",
url="https://api.ebay.com/commerce/media/v1_beta/video",
status_code=201,
headers={"Location": "https://api.ebay.com/commerce/media/v1_beta/video/VIDEO-1"},
)
client = MediaClient(build_transport())
result = client.create_video(
CreateVideoRequest(title="Demo", size=1024, classification=["ITEM"])
)
assert isinstance(result, CreatedMediaResource)
assert result.location == "https://api.ebay.com/commerce/media/v1_beta/video/VIDEO-1"
def test_media_wrapper_returns_video_model(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
method="GET",
url="https://api.ebay.com/commerce/media/v1_beta/video/VIDEO-1",
json={"videoId": "VIDEO-1", "status": "LIVE", "title": "Demo"},
)
client = MediaClient(build_transport())
result = client.get_video("VIDEO-1")
assert isinstance(result, Video)
assert result.videoId == "VIDEO-1"
def test_media_wrapper_uploads_video_bytes(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
method="POST",
url="https://api.ebay.com/commerce/media/v1_beta/video/VIDEO-1/upload",
status_code=200,
)
client = MediaClient(build_transport())
client.upload_video(
"VIDEO-1",
content=b"video-bytes",
content_length=11,
content_range="bytes 0-10/11",
)
request = httpx_mock.get_requests()[0]
assert request.headers["Content-Type"] == "application/octet-stream"
assert request.headers["Content-Length"] == "11"
assert request.headers["Content-Range"] == "bytes 0-10/11"
assert request.content == b"video-bytes"
def test_media_wrapper_returns_document_models(httpx_mock: HTTPXMock) -> None:
httpx_mock.add_response(
method="POST",
url="https://api.ebay.com/commerce/media/v1_beta/document",
json={"documentId": "DOC-1", "documentStatus": "PENDING_UPLOAD"},
status_code=201,
)
httpx_mock.add_response(
method="POST",
url="https://api.ebay.com/commerce/media/v1_beta/document/create_document_from_url",
json={"documentId": "DOC-2", "documentStatus": "SUBMITTED"},
status_code=201,
)
httpx_mock.add_response(
method="GET",
url="https://api.ebay.com/commerce/media/v1_beta/document/DOC-1",
json={"documentId": "DOC-1", "documentStatus": "ACCEPTED", "documentType": "USER_GUIDE_OR_MANUAL"},
)
httpx_mock.add_response(
method="POST",
url="https://api.ebay.com/commerce/media/v1_beta/document/DOC-1/upload",
json={"documentId": "DOC-1", "documentStatus": "SUBMITTED"},
status_code=200,
)
client = MediaClient(build_transport())
created = client.create_document(
CreateDocumentRequest(documentType="USER_GUIDE_OR_MANUAL", languages=["en-US"])
)
created_from_url = client.create_document_from_url(
CreateDocumentFromUrlRequest(
documentType="USER_GUIDE_OR_MANUAL",
documentUrl="https://example.test/guide.pdf",
languages=["en-US"],
)
)
fetched = client.get_document("DOC-1")
uploaded = client.upload_document(
"DOC-1",
file_name="guide.pdf",
content=b"%PDF-1.7",
content_type="application/pdf",
)
assert created.documentId == "DOC-1"
assert created_from_url.documentId == "DOC-2"
assert isinstance(fetched, DocumentResponse)
assert fetched.documentStatus == "ACCEPTED"
assert uploaded.documentStatus == "SUBMITTED"
upload_request = httpx_mock.get_requests()[3]
assert upload_request.headers["Content-Type"].startswith("multipart/form-data;")
assert b"filename=\"guide.pdf\"" in upload_request.content
assert b"%PDF-1.7" in upload_request.content