Closed albytterc closed 1 year ago
Albert,
When the following are blank, Selenium 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:
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
Did I understand your question, and is my response satisfactory?
Thank you for this detailed and quick response. But I was more wondering if there was a way to not have to provide the user's credentials in the API object constructor directly, so the user could log in themselves. It seems to me the user's credentials must be provided in some way to the API before logging in (either through the keywords or the json file). For example, my application is trying to create listings on the user's sandbox account through this library,.so it would require them to login manually.
Re. It seems to me.
eBay is rigid and only provides one or two ways of doing things. My understanding of what eBay expects and prefers is baked into the eBay-rest library. If you want to modify ebay-rest to make it more flexible, a PR would be warmly received.
Re. My application is trying to create listings on the user's sandbox account.
You are fortunate; dozens and maybe even hundreds of applications and websites already do that; they give you viable examples. Have you found one that handles eBay credentials in a way your end-users will like and tried to mimic it?
An easy option is to switch ebay_rest from Selenium to Playwright and, while doing so, make it headless. This would also eliminate a chrome driver dependency.
Requests is already a dependency, so utilizing it would be even better; more labour to implement.
Upon further consideration, urllib is already baked into the Swagger-generated code, so using urllib would be better than Requests because it makes progress towards reducing dependencies.
In answer to a user's question.
Note that the “production_refresh_token” and “refresh_token_expiry” are dumped to the log file.
That happens in this file https://github.com/matecsaj/ebay_rest/blob/main/src/ebay_rest/token.py, where the following line is located. message = f'Edit to your ebay_rest.json file to avoid the browser pop-up.\n'
If your project uses log-level info or higher, the info will appear in your log. Alternately, put a breakpoint after the line of code, and cut-paste the values.
I determined that urlib or requests can't fully substitute for Selenium or Playwright because some pages rely on javascript.
I also discovered that we don't need to switch to Playwrite to run headless; let us give this change https://github.com/matecsaj/ebay_rest/commit/e61178931a7f2530f136758048b169c371d72a4f a try with the next release.
The headless change was commented out until captcha automation is added. https://github.com/matecsaj/ebay_rest/commit/d1ad19c75d7a29b7a15cb505730710c29cff5702
Perhaps some things have changed in a helpful way, give eBay's documentation a careful read. https://developer.ebay.com/api-docs/static/get_auth_n_auth_tokens.html
I use ebay_rest for a web server application and don't use Selenium 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).
(that said, I haven't tried updating to a new version of ebay_rest in a while and that would probably break everything as selenium seems to have become a required dependency again...)
Hi matecsaj,
Is there any way to avoid the Selenium automation when trying to get a user token? For example, instead of providing the user credentials in the ebay_rest.json file, to just go through the traditional OAuth flow where the login is provided by the end user?
Something like this would be useful in supporting multiple eBay users logging in.
Thanks, Albert