google-cloud-php Document AI: INVALID_ARGUMENT - google-api

I am trying to use google-cloud-php to send documents to Google Document AI for processing.
Here is an example of my code:
require 'vendor/autoload.php';
putenv('GOOGLE_APPLICATION_CREDENTIALS=[###].json');
use Google\Cloud\DocumentAI\V1\Document;
use Google\Cloud\DocumentAI\V1\DocumentProcessorServiceClient;
$document = array();
$document['mime_type'] = 'application/pdf';
$document['content'] = file_get_contents('file.pdf');
$inlineDocument = new Document($document);
$postBody = array();
$postBody['inlineDocument'] = $inlineDocument;
$postBody['skipHumanReview'] = true;
$documentProcessorServiceClient = new DocumentProcessorServiceClient();
$formattedName = $documentProcessorServiceClient->processorName('[###]', 'eu', '[###]');
$operationResponse = $documentProcessorServiceClient->processDocument($formattedName, $postBody);
I am passing my arguments according to following documents:
processDocument Documentation
Document Documentation
However, I get the following response:
Fatal error: Uncaught Google\ApiCore\ApiException: { "message": "Request contains an invalid argument.", "code": 3, "status": "INVALID_ARGUMENT", "details": [] } thrown in \vendor\google\gax\src\ApiException.php on line 139
For some reason, the following document mentions to pass one argument as "mimeType" instead of "mime_type" compared to the previous link:
https://cloud.google.com/document-ai/docs/send-request
I tried that as well but that throws an exception in the php class.
Any help would be greatly appreciated!

I was running into the same issue, the problem is when other region than 'us'. If so, you should specify the apiEndpoint:
$documentProcessorServiceClient = new DocumentProcessorServiceClient([
'apiEndpoint' => 'eu-documentai.googleapis.com'
]);

Related

Elastic Search bulk request does not import all data, but shows no error

I use GuzzleHttp to send data via "_bulk" to an Elastic Search index. It is only a small dataset of 850 records. When I transfer the data record by record, I get an error message for 17 records. That's fine for me, so I can fix the errors.
But when I use _bulk, I do not get any error message at all. The 17 incorrect records are just ignored and are missing inside the index. How can I get an error message here? Are there some kind of options that I can use? Any ideas?
The endpoint is:
Here are my main code parts:
$jsonData = "xxxxx"; // the payload for the request
$elasticUrl = "https://xxxx.xx/xxxxx/_doc/_bulk";
$client = new Client([
"verify" => false, // disable ssl certificate verification
"timeout" => 600, // maximum timeout for requests
"http_errors" => false // disable exceptions
]);
$header = ["Content-Type" => "application/json"];
$result = $client->post($elasticUrl,
[
"headers" => $header,
"body" => $jsonData
]
);
if ($result->getStatusCode() != 200) {
$ret = "Error ".$result->getStatusCode()." with message: ".$result->getReasonPhrase();
}
A bulk request will always succeed with HTTP 200.
However, in the bulk response, you should see an indication whether each item succeeded or not. If you see errors: true in the response, then you know some of the items could not get indexed and looking into the items array, you'll find the error for the corresponding items.
As #Val pointed out the use of $response->getBody() gives the needed information:
$body = (string) $result->getBody();
$bodyArray = json_decode($body, true);
if ($bodyArray["errors"]) {
$retArray = [];
foreach ($bodyArray["items"] as $key => $item) {
if (isset($item["create"]["error"])) {
$retArray[] = $item["create"]["error"]["reason"].": ".json_encode($data[$key]);
}
}
$ret = implode(", ", $retArray);
}
As side note: in $data I keep the data as php array before sending it to Elastic Search.

Web Api Query for Actions msdyn_BookingResource and msdyn_BookingResourceRequirement

From the web api reference here
I tried querying the api with no luck of success specially with the parameter Schedules being stated as type string.
1.) For msdyn_BookingResource
POST: https://bhaud365dev.crm6.dynamics.com/api/data/v9.0/msdyn_BookingResource
BODY:
{"ResourceId":[GUID],"BookingStatusId":[GUID],"BookingMethod":690970003,"BookingType":1,"Schedules":"[{\"StartDateTime\":\"2019-07-15T00:00:00Z\",\"EndDateTime\":\"2019-07-19T00:00:00Z\"}]","Timeframe":5}
RESPONSE: {
"error": {
"code": "0x80040224",
"message": "The added or subtracted value results in an un-representable DateTime.\r\nParameter name: value",
2.) For msdyn_BookingResourceRequirement
POST: https://bhaud365dev.crm6.dynamics.com/api/data/v9.1/msdyn_resourcerequirements([GUID])/Microsoft.Dynamics.CRM.msdyn_BookingResourceRequirement
BODY: {
"BookingMethod": 690970003,
"BookingStatusId": [GUID],
"BookingType": 1,
"EndDateTime": "2019-07-19T07:29:00Z",
"ResourceId": [GUID],
"StartDateTime": "2019-07-15T22:00:00Z"
}
RESPONSE: {
"error": {
"code": "0x80040224",
"message": "Object reference not set to an instance of an object.",
I was able to api query for functions but for the actions I am stuck and I am not sure on what am I doing wrong. Any tips or example is greatly appreciated.
BTW. tried the above queries also in CRM REST BUILDER v2.6.0.0 Same error responses.
I spent some time, getting same weird error and then I realized they are Internal Use only Actions. It's not intended for our usage & it's highly unsupported as they tend to break in future versions when Microsoft planned to change.
I was able to successfully create the Bookable Resource Bookings with the help of below web api request.
var entity = {};
entity["Resource#odata.bind"] = "/bookableresources(7B203E2F-F2FB-E911-A813-000D3A5A1BF8)";
entity["BookingStatus#odata.bind"] = "/bookingstatuses(026BDCEF-9257-4C10-9E49-C92539B883D6)";
entity["endtime"] = "2019-11-07T21:00:00Z";
entity["starttime"] = "2019-11-07T20:00:00Z"
entity.bookingtype = 1;
entity.msdyn_bookingmethod = 690970003;
Xrm.WebApi.online.createRecord("bookableresourcebooking", entity).then(
function success(result) {
var newEntityId = result.id;
},
function(error) {
Xrm.Utility.alertDialog(error.message);
}
);

when i want change get become post it not work well

i have problem when i want to change Get become Post.
when i use Get i can get the data
but when use post i cannot get the data please help me
i have change the web.php or routes become Post but i cannot get my data when i use post
i have change get become post in my web.php in my laravel. but the result not the same
this is my code in laravel
public function getHistoryEvent(Request $request) {
$consumer_data = array();
$consumer_data['consumer_key'] = request()->header('consumer-key');
$consumer_data['consumer_secret'] = request()->header('consumer-secret');
$consumer_data['consumer_nonce'] = request()->header('consumer-nonce');
$consumer_data['consumer_device_id'] = request()->header('consumer-device-id');
$consumer_data['consumer_url'] = __FUNCTION__;
$authController = new AppSettingController();
$authenticate = $authController->apiAuthenticate($consumer_data);
if($authenticate==1 || $authenticate==0){
$event = DB::table('u_history_events')
->select('u_history_events.history_events_id','u_history_events.events_image','u_history_events.events_description','u_history_events.date_create')
->where('u_history_events.events_id',$request->events_id)
->where('u_history_events.kode_customers',$request->kode_customer)
->get();
$responseData = array('success'=>'1', 'data'=>$event, 'message'=>"Success.");
}else{
$responseData = array('success'=>'0', 'data'=>array(), 'message'=>"Unauthenticated call.");
}
$orderResponse = json_encode($responseData);
print $orderResponse;
}
when use get i can get this data the result are :
{"success": "1",
"data": [
{"history_events_id": 2,
"events_image": "",
"events_description": "",
"date_create": "2019-05-11 10:59:01"
},
{
"history_events_id": 3,
"events_image": "",
"events_description": "",
"date_create": "2019-05-11 11:59:35"
}
}
but when i use post i only get
{"success":"1","data":[],"message":"Success."}
I am no Laravel expert, but according to the docs, looks like you have to explicitly define a route for the POST verb to your controller's method:
Route::post($uri, $callback);
Or according to Controllers docs:
// change <your path here> and <your method name> to your desired path and
// method names
Route::get('<your path here>', 'AppSettingController#<your method name>');
I also recommend you to read MDN's An overview of HTTP.

Drive Api v3: Changes watch request TeamDriveId being ignored?

I'm trying to specify a Team Drive to watch according to the docs here: https://developers.google.com/drive/api/v3/reference/changes/watch
teamDriveId | string | The Team Drive from which changes will be returned. If specified the change IDs will be reflective of the Team Drive; use the combined Team Drive ID and change ID as an identifier.
(Side note teamDriveId appears to be deprecated in favour of driveId, but the docs don't reflect that)
I read that as saying if you supply an ID only changes related to that folder (File) and its children will cause a push notification, but I still get notifications for any changes in that user's Drive. Am I reading the docs incorrectly?
I originally posted the question to the DotNet client library repo as I'm doing this in C#. Jon Skeet suggested that IncludeItemsFromAllDrives should be false, which seems perfectly logical and I had tried that first because of that. However, that results in the following error being returned from the API endpoint:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "includeTeamDriveItemsRequired",
"message": "The includeItemsFromAllDrives parameter must be set to true when driveId is specified or corpora contains drive or allDrives."
}
],
"code": 403,
"message": "The includeItemsFromAllDrives parameter must be set to true when driveId is specified or corpora contains drive or allDrives."
}
}
I've tried several variations of the following properties to see if I can restrict it down to a Team Drive, but have been unsuccessful:
SupportsTeamDrives
SupportsAllDrives
IncludeItemsFromAllDrives
RestrictToMyDrive
Clarification would be very welcome.
Edit:
Code as requested, it's in C#, but the issue is likely to be the main API according to Jon Skeet:
Channel channel = new Channel()
{
Id = Guid.NewGuid().ToString(),
Type = "web_hook",
Address = [address],
Token = [token], //max 256 chars
Expiration = new DateTimeOffset(DateTime.Now.AddMinutes(10).ToUnixTimeMilliseconds(),
};
var watchRequest = _driveService.Changes.Watch(channel, startPageToken);
//watchRequest.SupportsTeamDrives = true;
watchRequest.SupportsAllDrives = true;
//watchRequest.TeamDriveId = rootFolderId;
//watchRequest.IncludeTeamDriveItems = true;
watchRequest.IncludeItemsFromAllDrives = true;
watchRequest.DriveId = rootFolderId;
watchRequest.RestrictToMyDrive = true;
channel = await watchRequest.ExecuteAsync();
I've tried several variations as the commented out code shows.

AttributeError: 'Search' object has no attribute 'execute_suggest'

Here is my code:
class SearchSuggest(View):
def get(self, request):
key_words = request.GET.get('s', '')
re_datas = []
if key_words:
s = ArticleType.search()
s = s.suggest('my_suggest', key_words, completion={
"field": "suggest", "fuzzy": {
"fuzziness": 1
},
"size": 5
})
suggestions = s.execute_suggest()
for match in suggestions.my_suggest[0].options:
source = match._source
re_datas.append(source["title"])
return HttpResponse(json.dumps(re_datas),
content_type="application/json")
It's a piece of code in views in django.when I run this project.It raise:
File "/home/yixuan/PycharmProjects/Scrapy/LcvSearch/search/views.py", line 20, in get
suggestions = s.execute_suggest()
AttributeError: 'Search' object has no attribute 'execute_suggest'
I don't know where is error. I will appreciate it if you can solve it.
my version is:
elasticsearch-dsl==6.1.0
elasticsearch==6.2.0
It looks like elasticsearch-dsl has removed the function execute_suggest from their Search object. Had to check the source code for this, since it appears it hasn't been documented in their changelogs or releases.
I assume you can just use execute and parse the response according to your needs, but just in case, here is the source code for execute_suggest, if you want to implement it someway yourself.
def execute_suggest(self):
es = connections.get_connection(self._using)
return SuggestResponse(
es.suggest(
index=self._index,
body=self._suggest,
**self._params
)
)
SuggestResponse is just an AttrDict it appears.
Source:
https://github.com/elastic/elasticsearch-dsl-py/blob/6.1.0/elasticsearch_dsl/search.py
https://github.com/elastic/elasticsearch-dsl-py/blob/5.4.0/elasticsearch_dsl/search.py
Hope this helps.
check your elasticsearch-dsl version #elasticsearch-dsl --version
Elasticsearch 6.x
elasticsearch-dsl>=6.0.0,<7.0.0
Elasticsearch 5.x
elasticsearch-dsl>=5.0.0,<6.0.0
Elasticsearch 2.x
elasticsearch-dsl>=2.0.0,<3.0.0

Resources