I'm getting the error below while trying to upload media to Google Photos API, following the docs
This is how i retrieve my bytes array:
And this is how i make the request:
I've tried a lot of things and none of it work...
Note: I'm consuming other Google Photos API endpoints, such as Get Albums, Create Albums, Get Media and everything work as expected. The upload media is the only one i'm having trouble with.
Note 2: The token is being sent correctly.
Note 3: All the origin endpoints were configured in the google console (localhost included) so much so that other endpoints are working correctly.
Anyone can give me a light?
I am writing something similar in C# and was able to work with the photo api. My best advice is to double check headers. I hope this helps, additionally I added a postman screenshot of a successful call to the api:
public async Task<GoogleApiResponse> UploadPhoto(StorageFile photo)
{
var userInfo = UserInfoVault.GetUserInfo();
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", userInfo.AccessToken);
client.DefaultRequestHeaders.Add("X-Goog-Upload-File-Name", photo.DisplayName);
var fileStream = await photo.OpenAsync(FileAccessMode.Read);
var reader = new DataReader(fileStream.GetInputStreamAt(0));
await reader.LoadAsync((uint)fileStream.Size);
byte[] pixels = new byte[fileStream.Size];
reader.ReadBytes(pixels);
var httpContent = new ByteArrayContent(pixels);
httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
HttpResponseMessage photoResponse = client.PostAsync(ApiEdnpoints.UploadPhoto, httpContent).Result;
string strResponse = await photoResponse.Content.ReadAsStringAsync();
return null;
}
Postman screenshot of successful call to upload a photo
Related
I have a problem that is still unclear: I am trying to upload an image from Xamarin via the API. I check the code for the OK message, but the image can't be uploaded to the Server, I tried to test the API on Postman, swagger, it works fine. I checked read_external_storage and write_external_storage
async void pickimg_Tapped(System.Object sender, EventArgs e)
{
var pickResult = await MediaPicker.PickPhotoAsync();
var content = new MultipartFormDataContent();
content.Add(new StreamContent(await pickResult.OpenReadAsync()), "file", pickResult.FileName);
var httpClient = new HttpClient();
var responses = await httpClient.PostAsync("https://api.com/api/UploadFileFeeds", content);
lb_status.Text = responses.StatusCode.ToString();
}
I check the responses value returns OK. However I can't find the image on the Server's folder. Note that when I test on Postman vs swagger, the image is saved on the Server. What did I do wrong? Ask for a solution from everyone
I am trying to build a .NET small app to predict images using my model that was trianed on AutoML.
But I am getting this error:
Cloud AutoML API has not been used in project 618104708054 before or
it is disabled. Enable it by visiting
https://console.developers.google.com/apis/api/automl.googleapis.com/overview?project=618104708054
then retry. If you enabled this API recently, wait a few minutes for
the action to propagate to our systems and retry
First - this is not the project I am using.
Second - If I go to the link with my real project id - it says to me that the api is working well.
My code look like these:
public static string SendPOST(string url, string json)
{
var httpWebRequest = (HttpWebRequest)WebRequest.Create(url);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
httpWebRequest.Headers.Add("Authorization", "Bearer GOOGLE_CLOUD_TOKEN");
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Flush();
streamWriter.Close();
}
var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
//var res = new JavaScriptSerializer().Deserialize<Response>(result);
//return res;
return result;
}
}
I will appriciate your help,
Thanks.
I finally succeded to make it, the only issue is that I needed to create a service account using the web console:
https://console.cloud.google.com/projectselector/iam-admin/serviceaccounts?supportedpurview=project&project=&folder=&organizationId=
And then to download the json key and push it via the gcloud command from my PC -
gcloud auth activate-service-account --key-file="[/PATH/TO/KEY/FILE.json]
I found the solution in this post:
"(403) Forbidden" when trying to send an image to my custom AutoML model via the REST API
I am trying to do a reverse image search with the Google REST API with an image stored locally. I am using the new--not deprecated--REST API. I can do a text search and get results. I can not do a search with a local image. I can do a reverse image search on the image and get a result. Any suggestions?
My https string is:
https://www.googleapis.com/customsearch/v1?key=A******&cx=0****&q=file:///home/givonz/donald-trump-voicemail-feature.jpg
Also, tried this https string, which doesn't work either:
https://www.googleapis.com/customsearch/v1?key=A******&cx=0****&searchType=image&q=file:///home/givonz/donald-trump-voicemail-feature.jpg
This text string search works:
https://www.googleapis.com/customsearch/v1?key=A******&cx=0****&q=Some+String
It seems the service is deprecated and no longer available as an API and; it always needed a link (URL). There are a few services on the web that seem to provide the function. Bing, in spite of appearing to do so, doesn't seem to. Yahoo does a reverse image search, but, I couldn't find an API. "Incandescent" does provide this service and with an API.
This should work. Make sure you pass your key in the header.
var path = #"YOUR_IMAGE_PATH";
var url = "https://api.cognitive.microsoft.com/bing/v7.0/images/details?modules=similarimages";
using (var client = new HttpClient())
using (Stream imageFileStream = File.OpenRead(path))
{
var content = new MultipartFormDataContent();
var strContent = new StreamContent(imageFileStream);
strContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { FileName = "anynameworks" };
content.Add(strContent);
var message = await client.PostAsync(url, content);
return await message.Content.ReadAsStringAsync();
}
When using RestSharp to query account details in your MailChimp account I get a "401: unauthorized" with "API key is missing", even though it clearly isn't!
We're using the same method to create our RestClient with several different methods, and in all requests it is working flawlessly. However, when we're trying to request the account details, meaning the RestRequest URI is empty, we get this weird error and message.
Examples:
private static RestClient CreateApi3Client(string apikey)
{
var client = new RestClient("https://us2.api.mailchimp.com/3.0");
client.Authenticator = new HttpBasicAuthenticator(null, apiKey);
return client;
}
public void TestCases() {
var client = CreateApi3Client(_account.MailChimpApiKey);
var req1 = new RestRequest($"lists/{_account.MailChimpList}/webhooks", Method.GET);
var res1 = client.Execute(req1); // works perfectly
var req2 = new RestRequest($"automations/{account.MailChimpTriggerEmail}/emails", Method.GET);
var res2 = client.Execute(req2); // no problem
var req3 = new RestRequest(Method.GET);
var res3 = client.Execute(req3); // will give 401, api key missing
var req4 = new RestRequest(string.Empty, Method.GET);
var res4 = client.Execute(req4); // same here, 401
}
When trying the api call in Postman all is well. https://us2.api.mailchimp.com/3.0, GET with basic auth gives me all the account information and when debugging in c# all looks identical.
I'm trying to decide whether to point blame to a bug in either RestSharp or MailChimp API. Has anyone had a similar problem?
After several hours we finally found what was causing this..
When RestSharp is making the request to https://us2.api.mailchimp.com/3.0/ it's opting to omit the trailing '/'
(even if you specifically add this in the RestRequest, like: new RestRequest("/", Method.GET))
so the request was made to https://us2.api.mailchimp.com/3.0
This caused a serverside redirect to 'https://us2.api.mailchimp.com/3.0/' (with the trailing '/') and for some reason this redirect scrubbed away the authentication header.
So we tried making a
new RestRequest("/", Method.GET)
with some parameters (req.AddParameter("fields", "email")) to make it not scrub the trailing '/', but this to was failing.
The only way we were able to "fool" RestSharp was to write it a bit less sexy like:
new RestRequest("/?fields=email", Method.GET)
Short question:
Does anyone have a working solution authenticating with the Google Custom Search Api, post April 20th 2015?
Longer version:
I am trying to use the Google Custom Search Api to request on-demand indexing.
Before I even get started I am running into issues with Authentication.
According to the documentation you should use the ClientLogin Api to authenticate.
This Api was closed down on April 20th 2015, and it now returns 404 when you try and get a token from it.
The deprecation notice on the ClientLogin documentation states to use Oauth instead.
I have therefore tried to authenticate pretty much the same as Hossein here
I am receiving a bearer token from Google, but when I try to make a request I get a 401 with the following message
<Error>You are not authorized to access this resource. If you feel this is an error, try re-logging into your Google Account.</Error>
This is no real surprise, since there is no uptodate documentation and I am blindly stumbling along trying to find a correct solution.
My current code in C#:
private static async Task Run()
{
var credential = new ServiceAccountCredential( new ServiceAccountCredential.Initializer("blablabla#developer.gserviceaccount.com")
{
Scopes = new[] { "https://www.googleapis.com/auth/cse" }
}.FromPrivateKey("-----BEGIN PRIVATE KEY-----...-----END PRIVATE KEY-----\n"));
await credential.RequestAccessTokenAsync(CancellationToken.None);
var token = credential.Token;
var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token.AccessToken);
var content =
new StringContent(
#"<?xml version=""1.0"" encoding=""UTF-8""?><OnDemandIndex><Pages><Page url=""http://url.com/to/be/indexed"" /></Pages></OnDemandIndex>");
content.Headers.ContentType = new MediaTypeHeaderValue("text/xml");
var result = await client.PostAsync("http://www.google.com/cse/api/{user_id}/index/{CSE_Id}", content);
var resultContent = await result.Content.ReadAsStringAsync();
Console.WriteLine(resultContent);
}
Does anyone have a solution running that works up against the www.google.com/cse/api/... endpoints?
Any language would be useful, just to know that it actually does work.