I am trying to receive results from The Google Cloud Text To Speech API, as per the demo on the official website under "Show json": https://cloud.google.com/text-to-speech by running this code:
import requests
r = requests.post('https://texttospeech.googleapis.com/v1beta1/text:synthesize', json={
"audioConfig": {
"audioEncoding": "LINEAR16",
"pitch": 0,
"speakingRate": 1
},
"input": {
"text": "Google Cloud Text-to-Speech enables developers to synthesize natural-sounding speech with 100+ voices, available in multiple languages and variants. It applies DeepMind’s groundbreaking research in WaveNet and Google’s powerful neural networks to deliver the highest fidelity possible. As an easy-to-use API, you can create lifelike interactions with your users, across many applications and devices."
},
"voice": {
"languageCode": "en-US",
"name": "en-US-Wavenet-D"
}
})
print(r.json())
However I am receiving this error message:
{'error': {'code': 403, 'message': 'The request is missing a valid API key.', 'status': 'PERMISSION_DENIED'}}
Despite having done everything for the setup with the account, API key and environment variable exactly as detailed here: https://cloud.google.com/text-to-speech/docs/before-you-begin
So I am at a bit of a loss for what I'm doing wrong. Any help would be much appreciated!
As the API response says, your request is missing the API key.
To fix this, you can either inject an Authorization bearer token in your request [the value is the access token, the output of gcloud auth application-default print-access-token]
-OR-
(as I can see you're using python)I suggest you use the client library to read your credentials automatically (since you've set the GOOGLE_APPLICATION_CREDENTIALS environment variable)
Installing via pip: pip install --upgrade google-cloud-texttospeech
Read more about using the client library here
Related
I am trying to request the usage metrics from a virtual machine I have running on Azure Devops. I know it's online because i've sent a ping. However, every time I try to run the program with the correct Get information filled in it gives me an error:
{"error":{"code":"AuthenticationFailed","message":"Authentication failed. The 'Authorization' header is missing."}}
I am following the instructions here: https://learn.microsoft.com/en-us/azure/virtual-machines/linux/metrics-vm-usage-rest
import requests
BASE_URL = "GET https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Compute/virtualMachines/{vmname}/providers/microsoft.insights/metrics?api-version=2018-01-01&metricnames=Percentage%20CPU×pan=2018-06-05T03:00:00Z/2018-06-07T03:00:00Z"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer {myPAT}"
}
response = requests.get(BASE_URL,headers)
print(response.text)
The bug lies in my Authorization header, what am I missing?
Edit: Actually this question Is there a way to call Azure Devops via python using 'requests'? solved my issue but now I have another error "{"error":{"code":"InvalidAuthenticationToken","message":"The access token is invalid."}}". I am reading the docs. https://learn.microsoft.com/en-us/azure/active-directory-b2c/access-tokens Thank you.
Basically, you cannot use the Azure DevOps PAT. You need to Create a Service Principal and Request the Access Token by following this document : Azure REST API Reference
It's easy to use curl to achieve that, please refer to Calling Azure REST API via curl for details.
And as mentioned in the blog, if you need a token just to run some test and you don’t want to go through Service Principal creation, then you can just run below command to get the access token. You’ll get your access token with a maximum validity of 1 hour.
az account get-access-token
After that you can use the access token in your script.
From documentation on https://developers.google.com/vault/guides/exports, I've been able to create, list, and retrieve exports, but I haven't found any way to download the exported data associated with a specific export. Is there any way to download the exported files via the API, or is this only available through the vault UI?
There is a cloudStorageSink key in the export metadata, but trying to use the values provided using the cloud storage API results in a generic permissions issue (403 Error).
Example export metadata response:
{
"status": "COMPLETED",
"cloudStorageSink": {
"files": [
{
"md5Hash": "da5e3979864d71d1e3ac776b618dcf48",
"bucketName": "408d9135-6155-4a43-9d3c-424f124b9474",
"objectName": "a740999b-e11b-4af5-b8b1-6c6def35d677/exportly-41dd7886-fe02-432f-83c-a4b6fd4520a5/Test_Export-1.zip",
"size": "37720"
},
{
"md5Hash": "d345a812e15cdae3b6277a0806668808",
"bucketName": "408d9135-6155-4a43-9d3c-424f124b9474",
"objectName": "a507999b-e11b-4af5-b8b1-6c6def35d677/exportly-41dd6886-fb02-4c2f-813c-a4b6fd4520a5/Test_Export-metadata.xml",
"size": "8943"
},
{
"md5Hash": "21e91e1c60e6c07490faaae30f8154fd",
"bucketName": "408d9135-6155-4a43-9d3c-424f124b9474",
"objectName": "a503959b-e11b-4af5-b8b1-6c6def35d677/exportly-41dd6786-fb02-42f-813c-a4b6fd4520a5/Test_Export-results-count.csv",
"size": "26"
}
]
},
"stats": {
"sizeInBytes": "46689",
"exportedArtifactCount": "7",
"totalArtifactCount": "7"
},
"name": "Test Export",
...
}
There are two approaches that can do the action you require:
The first:
using OAuth 2.0 refresh and access keys however it requires the intervention of the user, acknowledging your app access.
You can find a nice playground supplied by Google and more info here: https://developers.google.com/oauthplayground/.
You will first need to choose your desired API (in your case it is the: https://www.googleapis.com/auth/devstorage.full_controll under the Cloud Storage JSON API v1 section.
Then, you will need to log in with an admin account and click: "Exchange authorization code for tokens" (the fields "Refresh token" and "Access token" will be field automatically).
Lastly, you will need to choose the right URL to perform your request. I suggest using the "List possible operations" to choose the right URL. You will need to choose "Get Object - Retrieve the object" under Cloud Storage API v1 (notice that there are several options with the name -"Get Object", be sure to choose the one under Cloud Storage API v1 and not the one under Cloud Storage JSON API v1). Now just enter your bucket and object name in the appropriate placeholders and click Send the request.
The second:
Programmatically download it using Google client libraries. This is the approach suggested by #darkfolcer however I believe that the documentation provided by Google is insufficient and thus does not really help. If a python example will help, you can find one in the answer to the following question - How to download files from Google Vault export immediately after creating it with Python API?
Once all the exports are created you'll need to wait for them to be completed. You can use https://developers.google.com/vault/reference/rest/v1/matters.exports/list to check the status of every export in a matter. In the response refer to the “exports” array and check the value of “status” for each, any that say "COMPLETED" can be downloaded.
To download a completed export go to the “cloudStorageSink” object of each export and take the "bucketName" and "objectName" value of the first entry in the "files" Array. You’ll need to use the Cloud Storage API and these two values to download the files. This page has code examples for all the popular languages and using the API https://cloud.google.com/storage/docs/downloading-objects#storage-download-object-cpp.
Hope it helps.
The issue you are seeing is because the API works with the principle of least privilege.
The implications for you is that, since your objective is to download the files from the export, you would get the permissions to download only the files, not the whole bucket (even if it contains only those files).
This is why when you request information from the storage bucket, you get the 403 error (permission error). However, you do have permission to download the files inside the bucket. In this way, what you should do is get each object directly, doing requests like this (using the information on the question):
GET https://storage.googleapis.com/storage/v1/b/408d9135-6155-4a43-9d3c-424f124b9474/o/a740999b-e11b-4af5-b8b1-6c6def35d677/exportly-41dd7886-fe02-432f-83c-a4b6fd4520a5/Test_Export-1.zip
So, in short, instead of getting the full bucket, get each individual file generated by the export.
Hope this helps.
I have an issue with access to Youtube Analytics API for random youtube channels.
After a successful authorization with following scopes:
https://www.googleapis.com/auth/youtube.readonly
https://www.googleapis.com/auth/yt-analytics.readonly
I'm saving the token and refresh token in the database. Everything works well for some time. After a while (eg. three months) when my app makes a request, Google returns 403:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "forbidden",
"message": "Forbidden"
}
],
"code": 403,
"message": "Forbidden"
}
}
but only for Youtube Analytics API, other endpoints in Youtube Data API works fine with this token.
That happen for random accounts (channels). Owners of this channels didn't revoke access to my app, didn't change account password etc.
This issue affects about 40% of all channels in my application (the time when Youtube Analytics API stops working is different, from 1 to 6 months after obtaining OAuth2 token). Then I have to send them periodically a new authorization url.
Where is the problem?
This is how I generate an auth url and make requests:
Auth URL:
flow = client.flow_from_clientsecrets(
secret_file_path,
scope=["https://www.googleapis.com/auth/youtube.readonly",
"https://www.googleapis.com/auth/yt-analytics.readonly"],
redirect_uri=redirect_url,
prompt="consent"
)
flow.params["access_type"] = "offline"
url = flow.step1_get_authorize_url(state=state)
Stats request:
auth = client.OAuth2Credentials.from_json(credentials_from_db)
http_auth = auth.authorize(httplib2.Http())
api = discovery.build("youtubeAnalytics", "v1", http=http_auth,
cache_discovery=False)
api.reports().query(
ids="channel==%s" % channel_id,
metrics="estimatedMinutesWatched",
dimensions="video",
start_date=start_date,
end_date=end_date,
max_results=20,
filters="video=={}".format(",".join(video_ids))
).execute(http=http)
I'm using google-api-python-client 1.6.5
Edit
I attached screenshot while debugging requests to google API using google-api-python-client. Here's what's going on:
Retrieving channel's base stats using Youtube Data API
Retrieving channel's advanced stats using Youtube Analytics API
My point is that, the refresh token is successfully exchanged in both cases but works only with Youtube Data API. I purposely exchange it twice. The same result is when I access only Youtube Analytics API with one successful token exchange (without calling Youtube Data API).
And the most fun part is that, this code works for some time (a couple weeks or months) and then stops :-)
Ok lets start with a little background information.
There are sevral reasons why a refresh token would stop working.
It gets to old refresh tokens expire after six months if not used.
A user can reauthecate your application and get a new refresh token both refresh tokens will work you can have a max of fifty outstanding refresh tokens then the first will stop working.
the user can revoke your access.
Wakey daylight savings time bug of 2015. (we wont talk about that)
Now none of this is the case for you. Why because the refresh token still works your just drooping a scope. Which is crazy a user cant remove your access to one scope and it wont expire one scope.
That being said i am leading towards this being a bug. I have sent an email off to someone I know who is on the Oauth team.
In the mean time. I have an idea?
What happens if you try and request a new access token using the refresh token? Could it be an issue with the access token that was returned to you?
Given that you say that the token refresh works but the API call returns error, the only thing that I suspect is some issue on the api side.
Are you making these API calls from your server? For how many users? You may be running into per IP based limits. I don't know that for sure.
I think the easiest way to find the issue will be if you can send us a few tokens that start returning error. We can lookup if the tokens became invalid or there is an issue on the API side.
You can email them to oauth-help#google.com
I am having problem using python Google Analytics reports API to create new web property under account. I can get list of properties with no problem but when I try to insert it returns me 403. When I try to use API explorer it shows:
403 Forbidden
"errors": [
{
"domain": "global",
"reason": "insufficientPermissions",
"message": "Your project does not have access to this feature."
}
]
These API are currently in beta :
Write operations in the Management API (e.g. create, update, delete, patch) for Web Property, View (Profile), and Goal resources is currently available as a developer preview in limited beta. If you're interested in using these features, request access to the beta.
I have written python scripts to list repositories and commits.
To create a new repository, I have used the following code:
curl -F 'login=SolomonPeter26' -F 'token=mygithubapitoken' https://github.com/api/v2/json/repos/create -F 'name=REPONAME' -F 'description=This project is a test'
I can't access github API token of other users. So I couldn't write a python script for that sake.
Please suggest a better way to create such a new repository or a way to access the Github API token.( Can I get any help from oauth or oauth2)
Yeah. You can't access API tokens of other users. It's same with twitter. You need to use Oauth2, and each user should get the API keys\tokens and add them manually in the code. What you can do is provide an easy way for your users to add github API token.
I use Postman (a Chrome plug-ins). It can test success:
With the access_token, you can find personal access tokens of your account's setting.
There is a generic formula on Ritchie CLI to create a Github repository, using the user's Github API token.
Obs: The user will have to set the token manually the first time the command will be executed on the terminal (to save it locally).
Here are the code and the README file of this formula (in Python)
Here is an example of how it consumes the POST resource to create a repository with the Github API:
authorization = f'token {token}'
headers = {
"Accept": "application/vnd.github.v3+json",
"Authorization" : authorization,
}
r = requests.post(
url='https://api.github.com/user/repos',
data=json_data,
headers=headers
)
As you can customize the commands using the tool, it is possible to automate many other operations with Github API the same way.