Google Cloud Vision API - DOCUMENT_TEXT_DETECTION: no "property" field in "pages" - python-3.x

I'm trying to extract the language from the detection response:
response.full_text_annotation.pages[0].property.detected_languages[0].language_code
but it seems that sometimes the detections are missing the TextProperty (property) field - as specified here: Page
Is it not always guaranteed to be in the detection?
Also, is there a way to receive only the fullTextAnnotation without the singular textAnnotations fields?

I think is not possible to receive only the fullTextAnnotation without the singular textAnnotations, because the response structure is TextAnnotation -> Page -> Block -> Paragraph -> Word -> Symbol and if you look into the TextAnnotation response, there is no way to modify it.
Regarding the missing TextProperty (property) field, you can try to fix this by using “DOCUMENT_TEXT_DETECTION” instead of “TEXT_DETECTION” towards TYPE. According to the documentation, The TEXT_DETECTION endpoint will auto-detect only a subset of supported languages, while the DOCUMENT_TEXT_DETECTION endpoint will auto-detect the full set of supported languages.

Related

How to convert REST API's request body of String datatype into JSON Object in Node JS and test that in Postman?

I have a Node JS application running with Express and mongodb. I have a use case where my device sends data to my server. It might be JSON data or Comma-Separated String(Only String, not CSV file). I need to check which type of data is coming and manipulate that to JSON if request body would be a String. When I was trying to display the data type of data being sent to the server, it's displaying as "object" even after giving the "String" data as input. And the operation is getting successful but data is not inserting into the database. Can anyone help me in resolving this issue?
Sample Payload(request.body) would be,
"heat:22,humidity:36,deviceId:sb-0001"
Expected response is,
{
"heat": "22",
"humidity": "36",
"deviceId": "sb-0001"
}
#Aravind Actually typeof will returns "string" if operand is a string.So please check whether the string is coming or not in body, because if it is null then typeof will return "object".
I need to check which type of data is coming and manipulate that to JSON ...
HTTP is build upon the media-type concept that defines the syntax used in the payload of that type as well as the semantics of the elements used within that payload. You might take a look at how HTML defines forms to get a grip what a media-type specification should include. Through content negotiation client and server agree on a common media-type and thus a representation format to exchange payloads for supported by both. This simply increases interoperability between the participants as they exchange data in well-defined, hopefully standardized, representation formats both understand and support.
Through Accept headers a receiver can state preferences on which types to receive, including a weighting scheme to indicate that a certain representation format is preferred over an other one but the recipient is also fine with the other one, while a Content-Type header will indicate the actual representation format being sent.
RFC 7111 defines text/csv for CSV based representations and RFC 8259 specifies application/json for JSON payload. As the sender hopefully knows what kind of document it sends to the receiver, you can use this information to distinguish the payload on the receiver side. Note however that according to Fielding true REST APIs must use representation formats that support hypertext-driven interaction flows to allow clients to take further actions upon the payload received without having to invoke some external documentation. Both, JSON and CSV, by default don't support such an interaction model, that is abreviated with the term HATEOAS. For your simple scenario the content type negotiation might though be sufficient enough to solve your needs.
In terms of processing CSV and converting the data to JSON this is simply a matter of splitting up the CSV string on the delimiter symbol (, in the sample) to key-value pairs and then splitting the key and values further on the : symbol and adding these to a new JSON object. There is also a csvtojson library available at NPM that you might utilize in such a case.

Request has type LocalProxy, but expected one of: bytes, unicode

I'm trying to use the Google Cloud Platform Natural Language API with Python within a Google Cloud Function. Whenever I use the code provided in this Google tutorial for analyzing entity analysis using text in Cloud Storage, I get the following error message:
File "/user_code/main.py", line 9, in entity_sentiment_file
type=enums.Document.Type.PLAIN_TEXT)
TypeError: <Request 'http://25e4801f1004e4eb41d11633d9b2e9e9-dot-ad6bdc7c397c15e62-tp.appspot.com/'
[POST]> has type LocalProxy, but expected one of: bytes, unicode
I obtain that error message after successfully deploying the function and clicking "Test the Function" with a triggering event of empty curly braces {}, then going to the View Logs page.
I've tried providing the test event parameters like below, but I obtained the same result.
{"gcs_uri":"gs://test-news-articles/news-article-1.txt"}
Here's my entire function:
from google.cloud import language
from google.cloud.language import enums
from google.cloud.language import types
def entity_sentiment_file(gcs_uri,request=None):
print('gcs_uri: {}'.format(gcs_uri))
client = language.LanguageServiceClient()
document = types.Document(
gcs_content_uri=gcs_uri,
type=enums.Document.Type.PLAIN_TEXT)
# Detect and send native Python encoding to receive correct word offsets.
encoding = enums.EncodingType.UTF32
if sys.maxunicode == 65535:
encoding = enums.EncodingType.UTF16
result = client.analyze_entity_sentiment(document, encoding)
for entity in result.entities:
print(u'Name: "{}"'.format(entity.name))
for mention in entity.mentions:
print(u' Begin Offset : {}'.format(mention.text.begin_offset))
print(u' Content : {}'.format(mention.text.content))
print(u' Magnitude : {}'.format(mention.sentiment.magnitude))
print(u' Sentiment : {}'.format(mention.sentiment.score))
print(u' Type : {}'.format(mention.type))
print(u'Salience: {}'.format(entity.salience))
print(u'Sentiment: {}\n'.format(entity.sentiment))
Any help would be much appreciated.
A function that responds to an HTTP request needs to have the signature:
def my_function(request):
...
where request is provided by the Cloud Functions runtime on every new request.
Right now, gcs_uri is getting set to the request value (which is a LocalProxy type) and then you're trying to format a string with it, which causes the exception.
I'm not sure where you're expecting gcs_uri to come from, but it won't be provided to the function as an argument. If you're making a request with JSON, it will be available using request.json['gcs_uri']. See "Writing HTTP Functions" for more details.

Correct parameters for RateCard API

I am trying to fetch the RateCards for my Azure subscription, however I am unable to figure out the correct (combination of) parameters for my call to the API. I keep getting the following message:
{
"Message": "Invalid query specified. Please specify valid values for OfferDurableId, Currency, Locale and RegionInfo."
}
I'm currently supplying the following parameters:
$filter=OfferDurableId eq ’MS-AZR-0003P’ and Currency eq ’EUR’ and Locale eq ’en-US’ and RegionInfo eq ’NL’
I'm not certain whether there are any requirements between the OfferDurableId, Currency and Locale parameters, but I think these are fine. The parameter I'm mostly confused about is RegionInfo. As per the documentation (whatever little there is), this is the 2-letter ISO code which represents the country in which I purchased my subscription. I am quite certain that this was bought in the Netherlands, hence my attempt with NL, but it doesn't work. I've tried IE, GB, US and some neighbouring countries, but none of them work.
I should mention, the example in the docs (MS-AZR-0003P, USD, en-US and US) doesn't work for my subscription either, I'm guessing due to a mismatch in RegionInfo.
What would be a correct combination of values? Where would I find these values? (e.g. where would I find RegionInfo?)
As per #GauravMantri's response, the issue was indeed in the quotes. The "weird backquotes" (which were copied straight from Microsoft's documentation itself) are the issue. When replaced with normal single quotes (and after url-encoding the $filter value), the query works and returns my rate cards.

Getting arguments/parameters values from api.ai

I'm now stuck on the problem of getting user input (what user says) in my index.js. For example, the user says: please tell me if {animals} can live between temperature {x} to {y}. I want to get exact value (in string) for what animals, x and y so that I can check if it is possible in my own server. I am wondering how to do that since the entities need to map to some exact key values if I annotate these three parameters to some entities category.
The methods for ApiAiApp is very limited: https://developers.google.com/actions/reference/nodejs/ApiAiApp
And from my perspective, none of the listed methods work in this case.
Please help!
Generally API.AI entities are for some set of known values, rather than listening for any value and validating in the webhook. First, I'd identify the kinds of entities you expect to validate against. For the temperatures (x and y), I'd use API.AI's system entities. Calling getArgument() for those parameters (as explained in the previous answer) should return the exact number value.
For the animals, I'd use API.AI's developer entities. You can upload them in the Entity console using JSON or CSV. You can enable API.AI's automated expansion to allow the user to speak animals which you don't support, and then getArgument() in webhook the webhook will return the new value recognized by API.AI. You can use this to validate and respond with an appropriate message. For each animal, you can also specify synonymous names and when any of these are spoken, and getArgument() will return the canonical entity value for that animal.
Extra tip, if you expect the user might speak more than one animal, make sure to check the Is List box in the parameter section of the API.AI intent.
If "animals", "x", and "y" are defined as parameters in your Intent in API.AI, then you can use the getArgument() method defined in ApiAiApp.
So the following should work:
function tempCheck( app ){
var animals = app.getArgument('animals');
var x = app.getArgument('x');
var y = app.getArgument('y');
// Check the range and then use something like app.tell() to give a response.
}

Passing sets of properties and nodes as a POST statement wit KOA-NEO4J or BOLT

I am building a REST API which connects to a NEO4J instance. I am using the koa-neo4j library as the basis (https://github.com/assister-ai/koa-neo4j-starter-kit). I am a beginner at all these technologies but thanks to some help from this forum I have the basic functionality working. For example the below code allows me to create a new node with the label "metric" and set the name and dateAdded propertis.
URL:
/metric?metricName=Test&dateAdded=2/21/2017
index.js
app.defineAPI({
method: 'POST',
route: '/api/v1/imm/metric',
cypherQueryFile: './src/api/v1/imm/metric/createMetric.cyp'
});
createMetric.cyp"
CREATE (n:metric {
name: $metricName,
dateAdded: $dateAdded
})
return ID(n) as id
However, I am struggling to know how I can approach more complicated examples. How can I handle situations when I don't know how many properties will be added when creating a new node beforehand or when I want to create multiple nodes in a single post statement. Ideally I would like to be able to pass something like JSON as part of the POST which would contain all of the nodes, labels and properties that I want to create. Is something like this possible? I tried using the below Cypher query and passing a JSON string in the POST body but it didn't work.
UNWIND $props AS properties
CREATE (n:metric)
SET n = properties
RETURN n
Would I be better off switching tothe Neo4j Rest API instead of the BOLT protocol and the KOA-NEO4J framework. From my research I thought it was better to use BOLT but I want to have a Rest API as the middle layer between my front and back end so I am willing to change over if this will be easier in the longer term.
Thanks for the help!
Your Cypher syntax is bad in a couple of ways.
UNWIND only accepts a collection as its argument, not a string.
SET n = properties is only legal if properties is a map, not a string.
This query should work for creating a single node (assuming that $props is a map containing all the properties you want to store with the newly created node):
CREATE (n:metric $props)
RETURN n
If you want to create multiple nodes, then this query (essentially the same as yours) should work (but only if $prop_collection is a collection of maps):
UNWIND $prop_collection AS props
CREATE (n:metric)
SET n = props
RETURN n
I too have faced difficulties when trying to pass complex types as arguments to neo4j, this has to do with type conversions between js and cypher over bolt and there is not much one could do except for filing an issue in the official neo4j JavaScript driver repo. koa-neo4j uses the official driver under the hood.
One way to go about such scenarios in koa-neo4j is using JavaScript to manipulate the arguments before sending to Cypher:
https://github.com/assister-ai/koa-neo4j#preprocess-lifecycle
Also possible to further manipulate the results of a Cypher query using postProcess lifecycle hook:
https://github.com/assister-ai/koa-neo4j#postprocess-lifecycle

Resources