Clarifai search (curl) how to get more images per call - php

I am trying to get more than 20 images with the searches endpoint:
$data = '{
"query": {
"ands": [
{
"output": {
"input": {
"data": {
"image": {
"url": "' . $url . '"
}
}
}
}
}
]
}
}';
$ch = curl_init('https://api.clarifai.com/v2/searches?
page=1&per_page=30');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: Key " . self::$clarify_user_apikey,
"Content-Type: application/json")
);
$output = curl_exec($ch);
curl_close($ch);
The images are initialized above in the $data variable.
Does the image search not have pagination and per_page attributes, or what am I doing wrong?
However I change the two attributes, I always get a max of 20 images back. The App / Project in question has more than 70k images, and the explorer app shows more images as well.
Thanks!

I found the answer.
For easier understanding I formatted the JSON part into an array.
$data = array(
"query" => array(
"ands" => array(
array(
"output" => array(
"input" => array(
"data" => array(
"image" => array(
"url" => $url
)
)
)
)
)
)
),
"pagination" => array(
"page" => 1,
"per_page" => 100
),
);
This code gives 100 images back. I haven't seen an upper limit yet, but it seems to work fine with 500 images as well. The request call gets slow then, though.

Related

Google Cloud Text to speech in php

I am trying to use google's text to speech in my php website to be hosted on a live Cpanel Server
I have enabled the text to speech API, Created API KEY in Credentials section, also downloaded the json file of credentials from Create service account key page.
Then I downloaded the sample files from Github and also used composer to build the library
Now I dont understand where to put my keys. At every place, it demangs to EXPORT the key in Shell, but that would work for 1 open command prompt session and will have to be exported every time.
As I want to run this code on a live cpanel based hosting, so I think it wont be possible to export.
Is there any place within the codes where I can pass the key?
On this url article at stackoverflow: the first answer exports the response of CURL to synthesize-text.txt but we require mp3 output
Another answer states that we should use jq but since its a shared hsoting server, I am not sure if we can arrange jq.
Is ther any way out to this problem?
Update
Tried the following code after referring to the answer by #V.Tur
$params = [
"audioConfig"=>[
"audioEncoding"=>"MP3",
"pitch"=> "1",
"speakingRate"=> "1",
"effectsProfileId"=> [
"medium-bluetooth-speaker-class-device"
]
],
"input"=>[
"ssml"=>'<speak>The <say-as interpret-as=\"characters\">SSML</say-as>
standard <break time=\"1s\"/>is defined by the
<sub alias=\"World Wide Web Consortium\">W3C</sub>.</speak>'
],
"voice"=>[
"languageCode"=> "hi-IN",
"name" =>"hi-IN-Wavenet-B",
'ssmlGender'=>'MALE'
]
];
$data_string = json_encode($params);
$speech_api_key = "My_Key_Here";
$url = 'https://texttospeech.googleapis.com/v1/text:synthesize?fields=audioContent&key=' . $speech_api_key;
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($handle, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string)
]
);
$response = curl_exec($handle);
$responseDecoded = json_decode($response, true);
curl_close($handle);
if($responseDecoded['audioContent']){
return $responseDecoded['audioContent'];
}
I get the audio downloaded but the pauses/breaks I have mentioned in ssml did not work. I tried passing data to $params as below
$params = "{
'input':{
'ssml':'<speak>The <say-as interpret-as=\"characters\">SSML</say-as>
standard <break time=\"1s\"/>is defined by the
<sub alias=\"World Wide Web Consortium\">W3C</sub>.</speak>'
},
'voice':{
'languageCode':'en-us',
'name':'en-US-Standard-B',
'ssmlGender':'MALE'
},
'audioConfig':{
'audioEncoding':'MP3'
}
}";
But I get the following error:
Array ( [error] => Array ( [code] => 400 [message] => Invalid JSON
payload received. Unknown name "": Root element must be a message.
[status] => INVALID_ARGUMENT [details] => Array ( [0] => Array (
[#type] => type.googleapis.com/google.rpc.BadRequest [fieldViolations]
=> Array ( [0] => Array ( [description] => Invalid JSON payload received. Unknown name "": Root element must be a message. ) ) ) ) ) )
How to solve this?
Below my working example text-to-speech, you could redo for your needs:
public static function getSound($text)
{
$text = trim($text);
if($text == '') return false;
$params = [
"audioConfig"=>[
"audioEncoding"=>"LINEAR16",
"pitch"=> "1",
"speakingRate"=> "1",
"effectsProfileId"=> [
"medium-bluetooth-speaker-class-device"
]
],
"input"=>[
"text"=>$text
],
"voice"=>[
"languageCode"=> "en-US",
"name" =>"en-US-Wavenet-F"
]
];
$data_string = json_encode($params);
$url = 'https://texttospeech.googleapis.com/v1/text:synthesize?fields=audioContent&key=' . $speech_api_key;
$handle = curl_init($url);
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($handle, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string)
]
);
$response = curl_exec($handle);
$responseDecoded = json_decode($response, true);
curl_close($handle);
if($responseDecoded['audioContent']){
return $responseDecoded['audioContent'];
}
return false;
}
using:
public static function saveSound($text)
{
$speech_data = SpeechAPI::getSound($text);//see method upper
if($speech_data) {
$file_name = strtolower(md5(uniqid($text)) . '.mp3');
$path = FileUpload::getFolder();//just return directory path
if(file_put_contents($path.$file_name, base64_decode($speech_data))){
return $file_name;
}
}
return null;
}
For SSML standart need to change input params:
$text = "<speak>The <say-as interpret-as=\"characters\">SSML</say-as>
standard <break time=\"1s\"/>is defined by the
<sub alias=\"World Wide Web Consortium\">W3C</sub>.</speak>";
$params = [
"audioConfig"=>[
"audioEncoding"=>"LINEAR16",
"pitch"=> "1",
"speakingRate"=> "1",
"effectsProfileId"=> [
"medium-bluetooth-speaker-class-device"
]
],
"input"=>[
//"text"=>$text
"ssml" => $text
],
"voice"=>[
"languageCode"=> "en-US",
"name" =>"en-US-Wavenet-F"
]
];
about choose audioEncoding - https://cloud.google.com/speech-to-text/docs/encoding

Cloud Firestore add multiple document using REST API - PHP

I am trying to add multiple documents in one connection using google cloud firestore REST API. I can do this for single documant, but when I try to add more than one, I get an error.
The code I use to add a single document
$data = array(
'fields' => array(
'Field1' => array(
'stringValue' => 'deneme'
),
'Field2' => array(
'stringValue' => 'deneme2'
)
),
);
//$data = array_values($data);
$data_string = json_encode($data);
echo $data_string;
curl_setopt($ch, CURLOPT_URL, 'https://firestore.googleapis.com/v1beta1/projects/***/databases/(default)/documents/deneme/DEN6600011/TARIH');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
$headers = [
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string),
'Authorization: Bearer (MY-API-KEY)'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$sonuc = curl_exec($ch);
curl_close($ch);
echo $sonuc;
I tried to do this by changing the data array like this but at that time I get an error.
$data = array(
"documents" => array(
array('fields' => array(
'Field1' => array(
'stringValue' => 'deneme'
),
'Field2' => array(
'stringValue' => 'deneme2'
)
)),
array('fields' => array(
'Field1' => array(
'stringValue' => 'deneme'
),
'Field2' => array(
'stringValue' => 'deneme2'
)
)),
));
Error:
{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"documents\" at 'document': Cannot find field.",
"status": "INVALID_ARGUMENT",
"details": [
{
"#type": "type.googleapis.com/google.rpc.BadRequest",
"fieldViolations": [
{
"field": "document",
"description": "Invalid JSON payload received. Unknown name \"documents\" at 'document': Cannot find field."
}
]
}
]
}
}
I tried it in other ways, but I got errors in all of them. How can I add multiple data using single JSON with REST API?
You could use update to create multiple document
the update operation will create the document that does not exist, you should also provide the document id.
A similar question was asked here
Alternatively, you could try using the PHP Library.
Using create or set you will be able to create multiple document in one request.
As for the issue with your current way, this most-likely due to the json request body not being well defined.

Sage Accounting API UnexpectedError

I am trying to create a Sales Invoice through Sage Accounting API calls (its documentation can be found here: https://developer.sage.com/api/accounting/api/)
To make my code clearer I have created a class that helps me make those calls accordingly.
Here is the method I use to make those calls:
public function postRequest()
{
$url = $this->baseEndpoint . $this->request;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if (isset($this->params)) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->params);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Authorization: Bearer $this->token",
"Host: api.accounting.sage.com",
"Content-Type: application/json"
));
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
return $response;
}
How I call this method:
$params = array(
"sales_invoice" => array(
"contact_id" => "485fdfe0be154f9c9af44351de16e5be",
"date" => "2019-06-13",
"invoice_lines" => array(
array(
"description" => "description",
"ledger_account_id" => "f04157c90ff0496ab3a22f2558e46010",
"unit_price" => 10 ,
"quantity" => 1,
"tax_rate_id" => "ES_RE_STANDARD",
"tax_rate" => 0.1
)
)
)
);
$params = json_encode($params);
$request = "v3.1/sales_invoices";
$sageRequest = new SageRequest($token, $request, $params);
$sageRequest->postRequest();
According to the API documentation, that should work, but still I get this error:
[$severity] => error
[$dataCode] => UnexpectedError
[$message] => An unexpected error occurred.
[$source] =>
If there is anyone who has some experience with the Sage Accounting API, I would be more than grateful to know what I have done wrong.
This example works for me on a Spanish business:
{
"sales_invoice": {
"contact_id": "22b609fba11642238f2ecd0f5fe3e0b5",
"date": "2019-06-12",
"invoice_lines": [
{
"description": "Description",
"ledger_account_id": "829739738de811e996c90122ae3d08ca",
"quantity": 1,
"unit_price": 100,
"tax_rate_id": "ES_STANDARD"
}
],
"main_address": {
"city": "Madrid"
}
}
}
Make sure your contact is listed in the contact endpoint. Use GET https://api.accounting.sage.com/v3.1/ledger_accounts?visible_in=sales to get a list of all valid ledger accounts for sales objects.
I see your question uses ES_RE_STANDARD as tax rate. I will update this answer soon with an example for the "recargo de equivalencia" tax rate.

How to decode pagination in JSON?

I am trying to populate my website with products using the API of chinavasion.com. I've successfully fetch a list of products under a certain category but the response JSON only gives 10 products and a pagination which I literally don't know how to use, I'm guessing that it might be the one limiting the list of products echo'd?
Here is the sample JSON response:
{
"products": [
{
"product_id": 19433,
"model_code": "CVABR-C405",
"short_product_name": "13.3 Inch Roof Mounted Car Monitor ",
"product_url": "http://www.chinavasion.com/china/wholesale/Car_Video/Roof_Monitors/13.3-Inch-Roof-Mounted-Car-Monitor/",
"category_name": "Car Video",
"category_url": "http://www.chinavasion.com/china/wholesale/Car_Video/",
"subcategory_name": "Roof Monitors",
"status": "In Stock"
},
.... and 9 more.
"pagination": {
"start": 0,
"count": 10,
"total": 53
}
}
And here is my PHP so far, I just want to echo all the short product name of all the item, thing is I only get 10 items but there is a total of 53 items. (which can be seen on the sample JSON response pagination total)
<?php
$API_KEY = '4rxVx5-bxo7ldVQ5GcPSmX8XeqcSZoTnJnxF7xhRr8g.';
$url = "https://secure.chinavasion.com/api/getProductList.php";
$data = array(
'key' => $API_KEY,
'categories' => array('Car Video')
);
$content = json_encode($data);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
$response = json_decode($json_response, true);
foreach($response['products'] as $res)
{
echo $res['short_product_name'],'<br />';
}
?>
So is there a way to fetch the other remaining 43 products at this point? I am not pretty sure if its possible or not as I am really pretty new to programming and haven't done JSON before, hope you guys can help me.
That pagination array is there to indicate that there are more items. You just got to pass a start variable to get the next 10. Think of it as an offset in SQL.
next 10 items:
$API_KEY = '4rxVx5-bxo7ldVQ5GcPSmX8XeqcSZoTnJnxF7xhRr8g.';
$url = "https://secure.chinavasion.com/api/getProductList.php";
$data = array(
'key' => $API_KEY,
'categories' => array('Car Video'),
'pagination' => array('start' => 10)
);
$content = json_encode($data);
changing the 'pagination' => 'start' parameter you can set the starting item index.
EDIT:
you must insert the 'start' parameter inside the 'pagination' array.
An alternative way is to set the 'count' parameter to a big number. This way,you'll receive all items on a single call
$API_KEY = '4rxVx5-bxo7ldVQ5GcPSmX8XeqcSZoTnJnxF7xhRr8g.';
$url = "https://secure.chinavasion.com/api/getProductList.php";
$data = array(
'key' => $API_KEY,
'categories' => array('Car Video'),
'pagination' => array('count' => 999)
);

Python to PHP - Azure Machine Learning

Hi im trying to translate this python script to php. I don't have much knowledge of Python and limited for PHP.
The python script is:
import urllib2
import json
data = {
"Inputs": {
"input1": {
"ColumnNames": ["Client_ID"],
"Values": [ [ "0" ], [ "0" ], ]
},
},
"GlobalParameters": {}
}
body = str.encode(json.dumps(data))
url = 'https://ussouthcentral.services.azureml.net/workspaces/3e1515433b9d477f8bd02b659428cddc/services/cb1b14b17422435984943d51b5957ec7/execute?api-version=2.0&details=true'
api_key = 'abc123'
headers = {'Content-Type':'application/json', 'Authorization':('Bearer '+ api_key)}
req = urllib2.Request(url, body, headers)
try:
response = urllib2.urlopen(req)
result = response.read()
print(result)
except urllib2.HTTPError, error:
print("The request failed with status code: " + str(error.code))
print(error.info())
print(json.loads(error.read()))
In a bid to try and convert it myself, here is what I have done so far:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$data = array(
'Inputs'=> array(
'input1'=> array(
'ColumnNames' => ["Client_ID"],
'Values' => [ [ "0" ], [ "0" ], ]
),
),
'GlobalParameters'=> array()
);
$body = json_encode($data);
$url = 'https://ussouthcentral.services.azureml.net/workspaces/3e1515433b9d477f8bd02b659428cddc/services/cb1b14d17425435984943d41a5957ec7/execute?api-version=2.0&details=true';
$api_key = 'abc123';
$headers = array('Content-Type'=>'application/json', 'Authorization'=>('Bearer '+ $api_key));
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($curl);
var_dump($result);
im sure I have got lots wrong but would appreciate the help.
thanks
I just had to do this myself and though I'd provide an answer for you. If you're going to talk to Azure's ML platform using php, you need to build your CURL call like this:
$data = array(
'Inputs'=> array(
'input1'=> array(
'ColumnNames' => array("header1", "header2", "header3"),
'Values' => array( array("value1" , "value2" , "value3"))
),
),
'GlobalParameters'=> null
);
$body = json_encode($data);
$url = 'your-endpoint-url';
$api_key = 'your-api-key';
$headers = array('Content-Type: application/json', 'Authorization:Bearer ' . $api_key, 'Content-Length: ' . strlen($body));
$this->responseArray['body'] = $body;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($curl);
Of all the places to get hung up, it was on the GlobalParameters for me, and is for you, too. You need this instead:
GlobalParameters => null
This generates the following JSON
GlobalParameters: {}
whereas
GlobalParameters => array()
gives
GlobalParameters: []
it's a subtle distinction, but enough to make Azure throw a hissy fit.
I didn't test using your curl_setopt functions and instead used what I've included in my example. I'm assuming it will work using the curl_setopts you have, but I don't know for sure.
I had some trouble adapting this perfectly, and I wanted to be able to easily work with JSON & Guzzle. Below is the solution that I built.
First is the function for making the actual call to Azure. Note that Guzzle wants your URL to be split into the domain and URI pieces.
This should all be in your .env file (if you're using Laravel at least).
AZURE_BASE=https://ussouthcentral.services.azureml.net
AZURE_URL=/workspaces/[[YOUR_STUFF_HERE]]/services/[[YOUR_STUFF_HERE]]/execute?api-version=2.0&format=swagger
AZURE_PRIMARY_KEY=[[YOUR_KEY]]
use GuzzleHttp\Client;
public function learn () {
$client = new Client([
'base_uri' => env('AZURE_BASE'),
'timeout' => 2.0,
]);
$headers = [
'Authorization' => 'Bearer ' .env('AZURE_PRIMARY_KEY'),
'Accept' => 'application/json',
'Content-Type' => 'application/json'
];
$data = $this->test_data();
$body = json_encode($data);
$response = $client->request('POST', env('AZURE_URL'), [
'headers' => $headers,
'body' => $body
]);
return $response;
}
As other answers have noted, the data setup is very touchy. new \stdClass is the key here, as we need to end up with a JSON Object ({}) not an array ([]). stdClass creates that empty object for us.
function test_data () {
return array(
'Inputs'=> array(
'input1'=> array(
[
'DESC' => "",
'2-week-total'=> "1",
'last-week'=> "1",
'this-week'=> "1",
'delta'=> "1",
'normalized delta'=> "1",
'delta-percent'=> "1",
'high-total-delta'=> "1",
'high-total-amt'=> "1",
'role'=> ""
]
),
),
'GlobalParameters'=> new \stdClass,
);
}
Now when you call ->learn(), you'll get back some nice JSON to do what you need.

Categories