Control API: Service unavailable (503) - python

Good morning,
I want to query households (my first query and generally first experience with the Sonos API) and have authenticated successfully. I got an access token and query the Control API like this:
headers={"Content-Type" : "application/json",
"Authorization" : "Bearer " + token["access_token"]}
resp = re.get('http://api.ws.sonos.com/control/api/v1/househoulds', headers=headers)
It returns me a response with error code "503: Service unavailable":
Service Unavailable
Service Unavailable - Zero size object
The server is temporarily unable to service your request. Please try again
later.
Reference XXXXX
(I cut out the reference because I am not sure, if it contains credentials). I remember that when I intentionally changed my access token to a wrong one yesterday, I would get an error code back that I am not authorized. But now when I change it to a false one I still just get this same page back (503: Service unavailable).
Does anyone have the same problem? Might it be some security mechanism because I authorized many times in a short time or is the control API just currently down? I tried yesterday and today and don't see a blog post stating a downtime.

I see two issues with the code snippet you provided:
Issue 1: Your API URL has a typo. You used "househoulds" instead of
"households".
Issue 2: Your URL needs to use https://, not http://
If you fix those two issues and are indeed using a valid access token, your request should work.

Related

difficulty getting oauth 2 token file with yagmail

I am trying to use the python package yagmail to send emails but am having a tough time getting authorization to work.
My issue is getting an Oauth 2 token, but there is a disconnect with yagmail, as specified in a github thread. As stated in this post, https://github.com/kootenpv/yagmail/issues/143, it appears that google does not supply the credential file in the correct format. But I tried a bunch of things and each has its own problem.
When I set up a Client ID in the Google API console, download the
json as credentials.json and let the system create the token.json,
things work to a point: I am brought through google to "pick an
account, do you want to continue" and token is created. I am able to
print labels for the gmail account. But when I issue
yag.send(to='xxx#gmail.com', subject='Testing Yagmail',
contents='Hurray, it worked!'), I get an error "TypeError:
refresh_authorization() got an unexpected keyword argument 'token'."
When I look at the token file, it does contain the key 'token' which
it should not per this github post https://github.com/kootenpv/yagmail/issues/143#issuecomment-527115298][2].
If I go into the token and edit it to reflect the the expected
contents as identified in the above link by removing keys that are
not specified and prefixing the names with 'google_', I get an error
"ValueError: Authorized user info was not in the expected format,
missing fields refresh_token, client_id, client_secret." It doesn't
seem to like the 'google_' prefix.
editing the token file as above without the 'google_' prefix seems to
get further producing a different error "An error occurred:
<HttpError 403 when requesting
https://gmail.googleapis.com/gmail/v1/users/me/labels?alt=json
returned "Request had insufficient authentication scopes"
I am stuck. Relatively new to Oauth2, but it seems others are able to use yagmail. Is there a trick I am missing? I originally posted on Github because I found that other related post, but it seems SO is more geared toward Q&A. Is there a relation betweeen Github and SO? Difference?
Thanks for any assistance,
Brian
I finally found a solution and the answer was hidden in plain sight.
First the Oauth authorization needed to be set up as outlined in this post (which is excellent): Sending email via Gmail & Python
As stated, when yagmail is run the first time the authorization process gives instructions, the final stating to "Navigate to the following URL to auth:" and asks "Enter the localhost URL you were redirected to:"
The problem is the browser window shows what appears to be an error message, a sad face with a message "This site can’t be reached, localhost refused to connect, reload", etc. I never thought this was expected behavior. The url is the one being navigated to in the error screen.
Simply stating the error should be expected, and the url needs to be copied and pasted in the post above would help a lot.

fitbit API HTTPS error

I'm trying to get my heart rate and sleep data through fitbit API, i'm using this:
https://github.com/orcasgit/python-fitbit
in order to connect to the server and get the access and refresh tokens (i use gather_kays_oauth2 to get the tokens).
And when i'm conecting in HTTP I do manage to get the sleep data, but when i'm trying to get the HR like that:
client.time_series("https://api.fitbit.com/1/user/-/activities/heart/date/today/1d.json", period="1d")
I get this error:
HTTPBadRequest: this request must use the HTTPS protocol
And for some reason i can't connect in HTTPS - when i do try it, the browser pops up an ERR_SSL_PROTOCOL_ERROR even before the FITBIT Authorization Page.
i tried to follow and fix any settings that may cause the browser to fail, but they're all good and the error still pops up.
I've tried to change the callback URL, i searched for other fitbit OAUTH2 connection guides, but i only manage to connect in HTTP and not HTTPS
Does anyone knows how to solve it?
Your code should be client.time_series('activities/heart', period='1d') to get heart rate.
For the first parameter resource, it doesn't need the resource URL, but it asks you to put one of these: activities, body, foods, heart, sleep.
Here is the link of source code from python-fitbit:
http://python-fitbit.readthedocs.io/en/latest/_modules/fitbit/api.html#Fitbit.time_series
Added:
If you want to get the full heart rate data per minute (["activities-heart-intraday"] dataset), try client.intraday_time_series('activities/heart'). It will return data with the one-minute/one-second detail.
Ok I've worked out the HTTPS issue in relation to my need. It was because I sent a request to.
https://api.fitbit.com//1/user/-/activities/recent.json
I removed the additional forward slash after .com and it worked
https://api.fitbit.com/1/user/-/activities/recent.json
However, this is not the same issue you had which returned the same message for me this request must use the HTTPS protocol.
Which would suggest that any unhandled errors due to malformed requests to Fitbit return this same error. Rather than one that gives you a little more clue as to what just happened.

Google service account access token request: "Required parameter is missing: grant_type"

UPDATE: Solved. I was indeed making a basic mistake, among other things. My usage of the session.headers.update function was incorrect; instead of session.headers.update = {foo:bar}, I needed to be doing session.headers.update({foo:bar}). Additionally, I changed the following section of code:
From this:
payload = urllib.parse.urlencode({
"grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": str(token)
})
To this:
payload = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=" + token.decode("utf-8")
The code now works as intended.
Original question below
I've seen several hits on SO and Google about this problem; none of them have helped, although I've certainly made sure to double-check my code to make sure I'm not guilty of the same problems they detail. The problems people tend to have involve passing the POST data as parameters or POSTing to the wrong URL, which I'm not doing, as far as I can tell. Additionally, most of the hits I've found involve 3-legged OAuth2 involving users; I've found comparatively few hits pertaining to service accounts and JWTs, which differ enough from the user flow that I'm concerned about how relevant they are to my problem.
I'm trying to get an access token from the Google Authentication server for a service account. I've generated my JWT and now want to POST to the server to receive back my access token. I've set the headers according to the documentation described here, under "Making the access token request," and as far as I can tell, my request is up to spec, but Google responds back with a 400 response, and the following JSON:
{'error': 'invalid_request', 'error_description': 'Required parameter is missing: grant_type'}
Here's the code causing the problem:
# Returns the session, now with the Host and Authorization headers set.
def gAuthenticate(session):
token = createJWT()
session.headers.update = {
"Host": "www.googleapis.com",
"Content-Type": "application/x-www-form-urlencoded"
}
payload = urllib.parse.urlencode({
"grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer",
"assertion": str(token)
})
response = session.post("https://www.googleapis.com/oauth2/v4/token", data = payload)
session.headers.update = {"Authorization": "Bearer " + response.json()["access_token"]}
return session
I'm having a lot of strange issues with this code. First of all, if I don't urllib.parse.urlencode my dictionary (i.e. simply payload = {dictionary}), I get only a Bad Request / 'invalid_request' error, which I assume from the less specific error message means that this is less acceptable than what I'm currently doing. Why do I have to do this? Isn't Requests supposed to encode my data for me? I've never had this problem when POSTing with Requests before.
Second, examining the prepared request before it's sent reveals that my headers aren't being correctly set, despite the header update. Neither of the headers I've added to the request are being transmitted.
I've examined the request body and it looks to be identical (except of course the content of the JWT) to the one that Google provides as an example in the documentation.
All of this leads me to believe that I'm making a very basic error somewhere, but I haven't had any success finding it. What am I doing wrong here? Links to any helpful documentation would be extremely appreciated; thanks for your time and attention.
Try "grant_type": "authorization_code". And add grant type as header.
Also, check this link - Accessing Google oAuth giving invalid grant_type (Bad request)

Using OpenWeatherMap API gives 401 error

I'm trying to get the weather data for London in JSON but I am getting HTTPError: HTTP Error 401: Unauthorized. How do I get the API working?
import urllib2
url = "http://api.openweathermap.org/data/2.5/forecast/daily?q=London&cnt=10&mode=json&units=metric"
response = urllib2.urlopen(url).read()
The docs open by telling you that you need to register for an API key first.
To access the API you need to sign up for an API key
Since your url doesn't contain a key, the site tells you you're not authorized. Follow the instructions to get a key, then add it to the query parameters.
http://api.openweathermap.org/data/2.5/forecast/daily?APPID=12345&q=...
Error:
Invalid API key. Please see http://openweathermap.org/faq#error401 for more info
API calls responds with 401 error:
You can get the error 401 in the following cases:
You did not specify your API key in API request.
Your API key is not activated yet. Within the next couple of hours, it will be activated and ready to use.
You are using wrong API key in API request. Please, check your right API key in personal account.
You have free subscription and try to get access to our paid services (for example, 16 days/daily forecast API, any historical weather data, Weather maps 2.0, etc). Please, check your tariff in your [personal account]([price and condition]).
here are some steps to find problem.
1) Check if API key is activated
some API services provide key information in dashboard whether its activated, expired etc. openWeatherMap don't.
to verify whether your key is working 'MAKE API CALL FROM BROWSER'
api.openweathermap.org/data/2.5/weather?q=peshawar&appid=API_key
replace API_key with your own key, if you get data successfully then your key is activated otherwise wait for few hours to get key activated.
2) Check .env for typos & syntax
.env is file which is used to hide credentials such as API_KEY in server side code.
make sure your .env file variables are using correct syntax which is
NAME=VALUE
API_KEY=djgkv43439d90bkckcs
no semicolon, quotes etc
3) Check request URL
check request url where API call will be made , make sure
It doesn't have spaces, braces etc
correct according to URL encoding
correct according to API documentation
4) Debug using dotenv:
to know if you dotenv package is parsing API key correctly use the following code
const result = dotenv.config()
if (result.error) {
throw result.error
}
console.log(result.parsed)
this code checks if .env file variables are being parsed, it will print API_KEY value if its been parsed otherwise will print error which occur while parsing.
Hopefully it helps :)
For a graduate i was helping, he had a correct api key and it was active, but the api was incorrectly 401 when no content type was given
it was a simple as adding a Content-Type: application/json, and hey presto the api started working
curl command
curl --location \
--request GET \
'https://api.openweathermap.org/data/2.5/forecast?lat=55&lon=-3&appid=xxx' \
--header 'Content-Type: application/json'
I also faced the same issue, I have just created an account on open weather map and also verified the email, tried to load the api using several different url , but they replied with 401 , api key not found.
Solution: after 1 hour they all started working, so the reason was for activation it took 1 or some more hours.
The api key not set in your url ! before all you must register in https://openweathermap.org/ then get api key in your pesrsonal account after that do it like this:
http://api.openweathermap.org/data/2.5/weather?q={city}&appid=YOUR_API_KEY_HERE&units=metric
replace you apikey code with {YOUR_API_KEY_HERE}
then run your app.
After registering, you need to verify email.

How to create a Wikipedia bot to add a new section to a talk page?

We need to implement a bot which posts new sections on Wikipedia Talk pages.
As a matter of efficiency, we prefer to use python HTTP POST requests using MediaWiki API rather than available MediaWiki libraries.
We have not requested for an approval for the bot, and we are just trying to implement a trial version to test the bot on our own Talk pages.
For this purpose, I went through the following steps:
1- As discussed at https://en.wikipedia.org/wiki/Wikipedia:Creating_a_bot:
Create an account for your bot. Click here when logged in to create the account, linking it to yours. (If you do not create the bot account while logged in, it is likely to be blocked as a possible sockpuppet or unauthorised bot until you verify ownership)
Create a user page for your bot. Your bot's edits must not be made under your own account. Your bot will need its own account with its own username and password.
So, I logged in to my own Wikipedia account, and created a new account (for the bot).
2- As discussed at "API:Login" page: (Sorry, because of having less than 10 reputation, I am not able to add more than 2 links)
Logging in through the API requires two requests. For the first request, I wrote the following code in python:
def logInRequestToWikipedia():
# Add required parameters to the request.
request = { 'action' : 'login' }
request['lgname'] = 'BotName'
request['lgpassword'] = '*************'
url = 'https://en.wikipedia.org/w/api.php'
headers = { 'content-type' : 'application/x-www-form-urlencoded' }
r = requests.post(url, data = json.dumps(request), headers=headers)
The response starts with an error as follows:
<error code="help" info="" xml:space="preserve">
And continues with the API documentation.
3- As discussed at "API:Edit_-_Create%26Edit_pages" page:
Note: In this example, all parameters are passed in a GET request just for the sake of simplicity. However, action=edit requires POST requests; GET requests will cause an error. Do not forget to set the Content-Type header of your request to application/x-www-form-urlencoded. The token that you received is terminated with +\, this needs to be urlencoded (so it will end with %2B%5C) before it is passed back.
I added each of the following parameters separately and both together in the request data and tried all three cases, but it returns the same response.
request['lgtoken'] = '%2B%5C'
request['Content-Type'] = 'application/x-www-form-urlencoded'
4- Also I tried each of the followings in my request data, but it returns the same response:
request['format'] = 'json'
request['format'] = 'xml'
5- Moreover I found the following instruction at "User-Agent_policy" page:
User agents (browsers or scripts) that do not send a User-Agent header may now encounter an error message like this:
Scripts should use an informative User-Agent string with contact information, or they may be IP-blocked without notice.
User agents that send a User-Agent header that is blacklisted (for example, any User-Agent string that begins with "lwp", whether it is informative or not) may encounter a less helpful error message (lie) like this:
Our servers are currently experiencing a technical problem. This is probably temporary and should be fixed soon. Please try again in a few minutes.
This change is most likely to affect scripts (bots) accessing Wikimedia websites such as Wikipedia automatically, via api.php or otherwise, and command line programs.[3] If you run a bot, please send a User-Agent header identifying the bot and supplying some way of contacting you, e.g.:
User-Agent: MyCoolTool/1.1 (http://example.com/MyCoolTool/; MyCoolTool#example.com) BasedOnSuperLib/1.4
Do not copy a browser's user agent for your bot, as bot-like behavior with a browser's user agent will be assumed malicious.[4] For more information, please refer to the MediaWiki API Documentation
That's why I also tried my script with the following parameter, but the error response did not change:
request['User-Agent'] = "MyCoolTool/1.1 (http://example.com/MyCoolTool/; MyCoolTool#example.com) BasedOnSuperLib/1.4"
Do you think the problem can be related to the fact that we have not requested for an approval for the bot yet? Because we are just trying to implement a trial version to test the bot on our own Talk pages, and apply for the approval after making sure everything will work.
I'm pretty sure the problem is this line:
request['lgtoken'] = '%2B%5C'
The Login API you linked to doesn't include an lgtoken on the initial login attempt; it's only sent on the second ("Confirm token") step, using the token value from the NeedToken response.
And +\ doesn't look like a valid token.
So it's not surprising that you're getting an error.
Meanwhile, when I test this with my Wikipedia account, I get an error if I include that line, and success if I don't, which validates my suspicion that this is the problem.

Categories

Resources