How to process webhook result - webhooks

I am trying to connect a webhook to the nhs website using ibm cloud functions and then output result to my watson assistant chatbot
function main(params) {
const options = {
uri: "https://api.nhs.uk/conditions/coronavirus-covid-19/"+encodeURIComponent(params.query_topic)+"/?url=https://api.eu-gb.assistant.watson.cloud.ibm.com/instances/...",
json: true
}
return rp(options)
.then(res => {
return {text : res}
})
}
the webhook is successful and it passes the parameters to return information from the correct page
I want the result to just show the main body of text not all the tags so starting from "The main symptoms of coronavirus (COVID-19) are:..."
This is the full output(unable to add images)
"{"#context": "http://schema.org", "#type": "WebPage", "name": "Symptoms of coronavirus", "copyrightHolder": {"name": "Crown Copyright", "#type": "Organization"}, "license": "https://developer.api.nhs.uk/terms", "author": {"url": "https://www.nhs.uk", "logo": "https://www.nhs.uk/nhscwebservices/documents/logo1.jpg", "email": "nhswebsite.servicedesk#nhs.net", "#type": "Organization", "name": "NHS website"}, "about": {"#type": "WebPage", "name": "Symptoms of coronavirus"}, "description": "Find out about the main symptoms of coronavirus (COVID-19) and where to get medical advice if you think you have them.", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/symptoms/", "lastReviewed": ["2021-03-04T11:27:00+00:00", "2021-03-18T11:27:00+00:00"], "breadcrumb": {"#context": "http://schema.org", "#type": "BreadcrumbList", "itemListElement": [{"#type": "ListItem", "position": 0, "item": {"#id": "https://www.nhs.uk/conditions/", "name": "Health A to Z", "genre": "condition"}}, {"#type": "ListItem", "position": 1, "item": {"#id": "https://www.nhs.uk/conditions/coronavirus-covid-19/", "name": "Coronavirus (COVID-19)", "genre": "hub"}}, {"#type": "ListItem", "position": 2, "item": {"#id": "https://www.nhs.uk/conditions/coronavirus-covid-19/symptoms/", "name": "Symptoms of coronavirus", "genre": "guide"}}]}, "genre": "guide", "hasPart": [{"#type": "WebPageElement", "name": "symptoms", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/symptoms/#symptoms", "description": "The main symptoms of coronavirus (COVID-19) are a high temperature, a new, continuous cough and a loss or change to your sense of smell or taste.", "text": "<p>The main symptoms of coronavirus (COVID-19) are:</p><ul><li>a high temperature \u2013 this means you feel hot to touch on your chest or back (you do not need to measure your temperature)</li><li>a new, continuous cough \u2013 this means coughing a lot for more than an hour, or 3 or more coughing episodes in 24 hours (if you usually have a cough, it may be worse than usual)</li><li>a loss or change to your sense of smell or taste \u2013 this means you've noticed you cannot smell or taste anything, or things smell or taste different to normal</li></ul><p>If you have any of these symptoms, get a test to check if you have coronavirus and stay at home until you get your result.</p>", "title": ""}], "relatedLink": [{"#type": "LinkRole", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/", "name": "Coronavirus (COVID-19)", "linkRelationship": "Navigation", "position": 0}, {"#type": "LinkRole", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/symptoms/", "name": "Symptoms of coronavirus", "linkRelationship": "Navigation", "position": 1}, {"#type": "LinkRole", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/self-isolation-and-treatment/", "name": "Self-isolation and treating coronavirus symptoms", "linkRelationship": "Navigation", "position": 2}, {"#type": "LinkRole", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/testing-and-tracing/", "name": "Testing and tracing for coronavirus", "linkRelationship": "Navigation", "position": 3}, {"#type": "LinkRole", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/people-at-higher-risk/", "name": "People at higher risk from coronavirus", "linkRelationship": "Navigation", "position": 4}, {"#type": "LinkRole", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/social-distancing/", "name": "Social distancing and changes to everyday life", "linkRelationship": "Navigation", "position": 5}, {"#type": "LinkRole", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/research/", "name": "Take part in coronavirus research", "linkRelationship": "Navigation", "position": 6}, {"#type": "LinkRole", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/coronavirus-vaccination/", "name": "Coronavirus vaccination", "linkRelationship": "Navigation", "position": 7}, {"#type": "LinkRole", "url": "https://www.nhs.uk/conditions/coronavirus-covid-19/long-term-effects-of-coronavirus-long-covid/", "name": "Long-term effects of coronavirus (long COVID)", "linkRelationship": "Navigation", "position": 8}], "mainEntityOfPage": [{"identifier": "0", "name": "section heading", "position": 0, "#type": "WebPageElement", "headline": "", "text": "", "mainEntityOfPage": [{"position": 0, "identifier": "1", "text": "<p>If you have any of the main symptoms of coronavirus (COVID-19), get a test as soon as possible. Stay at home until you get the result.</p><h2><b>Main symptoms</b></h2><p>The main symptoms of coronavirus are:</p><ul><li><b>a high temperature</b> \u2013 this means you feel hot to touch on your chest or back (you do not need to measure your temperature)</li><li><b>a new, continuous cough</b> \u2013 this means coughing a lot for more than an hour, or 3 or more coughing episodes in 24 hours (if you usually have a cough, it may be worse than usual)</li><li><b>a loss or change to your sense of smell or taste</b> \u2013 this means you've noticed you cannot smell or taste anything, or things smell or taste different to normal</li></ul><p>Most people with coronavirus have at least 1 of these symptoms.</p><h2>What to do if you have symptoms</h2><p>If you have any of the main symptoms of coronavirus:</p><ol><li>Get a test to check if you have coronavirus as soon as possible.</li><li>You and anyone you live with should stay at home and not have visitors until you get your test result \u2013 only leave your home to have a test.</li></ol><p>Anyone in your support bubble should also stay at home if you have been in close contact with them since your symptoms started or during the 48 hours before they started.</p>", "#type": "WebPageElement", "name": "markdown"}, {"position": 1, "#type": "WebPageElement", "name": "Find a service", "identifier": "2", "text": "<p>Get a test to check if you have coronavirus on GOV.UK</p>\n"}, {"position": 3, "#type": "WebPageElement", "name": "urgent", "identifier": "5", "text": "<h2>Use the NHS 111 online coronavirus service if:</h2><div class=\"block-richtext\"><ul><li>you're worried about your symptoms</li><li>you're not sure what to do</li></ul></div>\n<div class=\"block-action_link\"><div class=\"nhsuk-action-link\">\n <a class=\"nhsuk-action-link__link\" href=\"https://111.nhs.uk/covid-19/\" >\n <svg class=\"nhsuk-icon nhsuk-icon__arrow-right-circle\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M0 0h24v24H0z\" fill=\"none\"></path>\n <path d=\"M12 2a10 10 0 0 0-9.95 9h11.64L9.74 7.05a1 1 0 0 1 1.41-1.41l5.66 5.65a1 1 0 0 1 0 1.42l-5.66 5.65a1 1 0 0 1-1.41 0 1 1 0 0 1 0-1.41L13.69 13H2.05A10 10 0 1 0 12 2z\"></path>\n </svg>\n <span class=\"nhsuk-action-link__text\">Use the NHS 111 online coronavirus service</span>\n </a>\n</div>\n</div>\n<div class=\"block-richtext\"><p>Call 111 if you cannot get help online. Do not go to places like a GP surgery, hospital or pharmacy.</p></div>"}]}, {"identifier": "0", "name": "section heading", "position": 1, "#type": "WebPageElement", "headline": "", "text": "", "mainEntityOfPage": [{"position": 0, "#type": "WebPageElement", "name": "Callout", "identifier": "4", "text": "<h2>Babies and children</h2><p>Call 111 if you're worried about a baby or child under 5.</p><p>If your child seems very unwell, is getting worse or you think there's something seriously wrong, call 999.</p><p>Do not delay getting help if you're worried. Trust your instincts.</p><p>Get more advice about coronavirus in children.</p>"}]}], "dateModified": "2021-03-04T20:52:05+00:00"}"
I have read through IBM Watson documentation, NHS API documentation and browsed through Stack Overflow, but couldn't find anything to help me.

How are you displaying the response now? Just $webhook_response_1?
If so, then I think this documentation will help.
About half way down there's a table with two columns: condition and response. See Screenshot
It says that if you make your condition $webhook_response_1 then your response would be something like this: Your words in Spanish: <? $webhook_result_1.translations[0].translation ?>.
Obviously, change the static text to what you're looking for and change the properties to match what your own JSON is returning.
EDIT:
Based on your comments you are trying to display the data with this: $webhook_result_1.text.mainEntityOfPage[9].text
However, based on the format of your json you would actually need to use $webhook_result_1.mainEntityOfPage[0].mainEntityOfPage[0].text

As mentioned in the posting above, currently you perform your request to the nhs web site, receive a response as a json payload, then return the complete response back to the Watson Assistant web hook. If you only require a sub element of the returned payload, you need either to extract that element via your cloud function and return this sub element. Or you can within Watson Assistant only "display" within the dialog bode the sub element, i.e. If you return the response to variable $webhook_result_1, then as show above you only use in the node $webhook_result_1.description (the json elements are not clear from above, so you may need to adjust to be correct). Its easier to manipulate the returned json within your cloud function, then within assistant.

Related

Indexing e-mails in Azure Search

I'm trying to best index contents of e-mail messages, subjects and email addresses. E-mails can contain both text and HTML representation. They can be in any language so I can't use language specific analysers unfortunately.
As I am new to this I have many questions:
First I used Standard Lucene analyser but after some testing and
checking what each analyser does I switched to using "simple"
analyser. Standard one didn't allow me to search by domain in
user#domain.com (It sees user and domain.com as tokens). Is "simple" the best I can use in my case?
How can I handle HTML contents of e-mail? I thought this should be
possible to do it in Azure Search but right now I think I would need
to strip HTML tags myself.
My users aren't tech savvy and I assumed "simple" query type will be
enough for them. I expect them to type word or two and find messages
containing this word/containing words starting with this word. From my tests it looks I need to append * to their queries to get "starting with" to work?
It would help if you included an example of your data and how you index and query. What happened, and what did you expect?
The standard Lucene analyzer will work with your user#domain.com example. It is correct that it produces the tokens user and domain.com. But the same happens when you query, and you will get records with the tokens user and domain.com.
CREATE INDEX
"fields": [
{"name": "Id", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true, "sortable": true, "facetable": false, "key": true, "indexAnalyzer": null, "searchAnalyzer": null, "analyzer": null, "synonymMaps": [] },
{"name": "Email", "type": "Edm.String", "filterable": true, "sortable": true, "facetable": false, "searchable": true, "analyzer": "standard"}
]
UPLOAD
{
"value": [
{
"#search.action": "mergeOrUpload",
"Id": "1",
"Email": "user#domain.com"
},
{
"#search.action": "mergeOrUpload",
"Id": "2",
"Email": "some.user#some-domain.com"
},
{
"#search.action": "mergeOrUpload",
"Id": "3",
"Email": "another#another.com"
}
]
}
QUERY
Query, using full and all.
https://{{SEARCH_SVC}}.{{DNS_SUFFIX}}/indexes/{{INDEX_NAME}}/docs?search=user#domain.com&$count=true&$select=Id,Email&searchMode=all&queryType=full&api-version={{API-VERSION}}
Which produces results as expected (all records containing user and domain.com):
{
"#odata.context": "https://<your-search-env>.search.windows.net/indexes('dg-test-65392234')/$metadata#docs(*)",
"#odata.count": 2,
"value": [
{
"#search.score": 0.51623213,
"Id": "1",
"Email": "user#domain.com"
},
{
"#search.score": 0.25316024,
"Id": "2",
"Email": "some.user#some-domain.com"
}
]
}
If your expected result is to only get the record above where the email matches completely, you could instead use a phrase search. I.e. replace the search parameter above with search="user#domain.com" and you would get:
{
"#search.score": 0.51623213,
"Id": "1",
"Email": "user#domain.com"
}
Alternatively, you could use the keyword analyzer.
ANALYZE
You can compare the different analyzers directly via REST. Using the keyword analyzer on the Email property will produce a single token.
{
"text": "some-user#some-domain.com",
"analyzer": "keyword"
}
Results in the following tokens:
"tokens": [
{
"token": "some-user#some-domain.com",
"startOffset": 0,
"endOffset": 25,
"position": 0
}
]
Compared to the standard tokenizer, which does a decent job for most types of unstructured content.
{
"text": "some-user#some-domain.com",
"analyzer": "standard"
}
Which produces reasonable results for cases where the email address was part of some generic text.
"tokens": [
{
"token": "some",
"startOffset": 0,
"endOffset": 4,
"position": 0
},
{
"token": "user",
"startOffset": 5,
"endOffset": 9,
"position": 1
},
{
"token": "some",
"startOffset": 10,
"endOffset": 14,
"position": 2
},
{
"token": "domain.com",
"startOffset": 15,
"endOffset": 25,
"position": 3
}
]
SUMMARY
This is a long answer already, so I won't cover your other two questions in detail. I would suggest splitting them to separate questions so it can benefit others.
HTML content: You can use a built-in HTML analyzer that strips HTML tags. Or you can strip the HTML yourself using custom code. I typically use Beautiful Soup for cases like these or simple regular expressions for simpler cases.
Wildcard search: Usually, users don't expect automatic wildcards appended. The only application that does this is the Outlook client, which destroys precision. When I search for "Jan" (a common name), I annoyingly get all emails sent in January(!). And a search for Dan (again, a name), I also get all emails from Danmark (Denmark).
Everything in search is a trade-off between precision and recall. In your first example with the email address, your expectation was heavily geared toward precision. But, in your last wildcard question, you seem to prefer extreme recall with wildcards on everything. It all comes down to your expectations.

Azure Search - phonetic search implementation

I was trying out Phoenetic search using Azure Search without much luck. My objective is to work out an Index configuration that can handle typos and accomodate phonetic search for end users.
With the below configuration and sample data, I was trying to search for intentionally misspelled words like 'softvare' or 'alek'. I got results for 'alek' thanks for Phonetic analyzer; but didn't get any results for 'softvare'.
Looks like for this requirement phonetic search will not do the trick.
Only option that I found was to use synonyms map. The major pitfall is that I'm unable to use the Phonetics / Custom analyzer along with Synonyms :(
What are the various strategies that you would recommend for taking care of typos?
search query used
?api-version=2017-11-11&search=alec
?api-version=2017-11-11&search=softvare
Here is the index configuration
"name": "phonetichotels",
"fields": [
{"name": "hotelId", "type": "Edm.String", "key":true, "searchable": false},
{"name": "baseRate", "type": "Edm.Double"},
{"name": "description", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false, "analyzer":"my_standard"},
{"name": "hotelName", "type": "Edm.String", "analyzer":"my_standard"},
{"name": "category", "type": "Edm.String", "analyzer":"my_standard"},
{"name": "tags", "type": "Collection(Edm.String)", "analyzer":"my_standard"},
{"name": "parkingIncluded", "type": "Edm.Boolean"},
{"name": "smokingAllowed", "type": "Edm.Boolean"},
{"name": "lastRenovationDate", "type": "Edm.DateTimeOffset"},
{"name": "rating", "type": "Edm.Int32"},
{"name": "location", "type": "Edm.GeographyPoint"}
],
Analyzer (part of the index creation)
"analyzers":[
{
"name":"my_standard",
"#odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
"tokenizer":"standard_v2",
"tokenFilters":[ "lowercase", "asciifolding", "phonetic" ]
}
]
Analyze API Input and Output for 'software'
{
"analyzer":"my_standard",
"text": "software"
}
{
"#odata.context": "https://ctsazuresearchpoc.search.windows.net/$metadata#Microsoft.Azure.Search.V2017_11_11.AnalyzeResult",
"tokens": [
{
"token": "SFTW",
"startOffset": 0,
"endOffset": 8,
"position": 0
}
]
}
Analyze API Input and Output for 'softvare'
{
"analyzer":"my_standard",
"text": "softvare"
}
{
"#odata.context": "https://ctsazuresearchpoc.search.windows.net/$metadata#Microsoft.Azure.Search.V2017_11_11.AnalyzeResult",
"tokens": [
{
"token": "SFTF",
"startOffset": 0,
"endOffset": 8,
"position": 0
}
]
}
Sample data that I loaded
{
"#search.action": "upload",
"hotelId": "5",
"baseRate": 199.0,
"description": "Best hotel in town for software people",
"hotelName": "Fancy Stay",
"category": "Luxury",
"tags": ["pool", "view", "wifi", "concierge"],
"parkingIncluded": false,
"smokingAllowed": false,
"lastRenovationDate": "2010-06-27T00:00:00Z",
"rating": 5,
"location": { "type": "Point", "coordinates": [-122.131577, 47.678581] }
},
{
"#search.action": "upload",
"hotelId": "6",
"baseRate": 79.99,
"description": "Cheapest hotel in town ",
"hotelName": " Alec Baldwin Motel",
"category": "Budget",
"tags": ["motel", "budget"],
"parkingIncluded": true,
"smokingAllowed": true,
"lastRenovationDate": "1982-04-28T00:00:00Z",
"rating": 1,
"location": { "type": "Point", "coordinates": [-122.131577, 49.678581] }
},
With the right configuration, I should have got results even with the misspelled words.
I work on Azure Search. Before I suggest approaches to handle misspelled words, it would be helpful to look at your custom analyzer (my_standard) configuration. It might tell us why it's not able to handle the case for 'softvare'. As a DIY, you can use the Analyze API to see the tokens created using your custom analyzer and it should contain 'software' to actually match the docs.
Now then, here are a few ways that can be used independently or in conjunction to handle misspelled words. The best approach varies depending on the use-case and I strongly suggest you experiment with these to figure out the best one in your case.
You are already familiar with phonetic filters which is a common approach to handle similarly pronounced terms. If you haven't already, try different encoders for the filter to evaluate which configuration gives you the best results. Check out the list of encoders here.
Use fuzzy queries supported as part of the Lucene query syntax in Azure Search which returns terms that are near the original query term based on a distance metric. The limitation here is that it works on a single term. Check the docs for more details. Sample query would look like - search=softvare~1 You can also use term boosting to give the original term more boost in cases where the original term is also a valid term.
You also alluded to synonyms which is also used to query with misspelled terms. This approach gives you the most control over the process of handling typos but also require you to have prior knowledge of different typos for terms. You can use these docs if you want to experiment with synonyms.
As you could read in my post; my Objective was to handle the typos.
The only easy option is to use the inbuilt Lucene functionality - Fuzzy Search. I'm yet to check on the response times as the querytype has to be set to 'full' for using fuzzy search. Otherwise, the results were satisfactory.
Example:
search=softvare~&fuzzy=true&querytype=full
will return all documents with the 'Software' in it.
For further reading please go through Documentation

How would I call the data in this object?

I am new to web development and am about half way through a full-stack web development course. How would I go about calling the value of the data stored with the source: "Rotten Tomatoes"?
I have tried Ratings[1].Value and it does not seem to work.
var movieObject = JSON.parse(body);
console.log('Rotten Tomatoes Rating: ', movieObject.Ratings[1].Value);
Body Content:
{
"Title": "Avatar",
"Year": "2009",
"Rated": "PG-13",
"Released": "18 Dec 2009",
"Runtime": "162 min",
"Genre": "Action, Adventure, Fantasy",
"Director": "James Cameron",
"Writer": "James Cameron",
"Actors": "Sam Worthington, Zoe Saldana, Sigourney Weaver, Stephen Lang",
"Plot": "A paraplegic marine dispatched to the moon Pandora on a unique mission becomes torn between following his orders and protecting the world he feels is his home.",
"Language": "English, Spanish",
"Country": "UK, USA",
"Awards": "Won 3 Oscars. Another 85 wins & 128 nominations.",
"Poster": "https://images-na.ssl-images-amazon.com/images/M/MV5BMTYwOTEwNjAzMl5BMl5BanBnXkFtZTcwODc5MTUwMw##._V1_SX300.jpg",
"Ratings": [
{
"Source": "Internet Movie Database",
"Value": "7.8/10"
},
{
"Source": "Rotten Tomatoes",
"Value": "83%"
},
{
"Source": "Metacritic",
"Value": "83/100"
}
],
"Metascore": "83",
"imdbRating": "7.8",
"imdbVotes": "967,488",
"imdbID": "tt0499549",
"Type": "movie",
"DVD": "22 Apr 2010",
"BoxOffice": "$749,700,000",
"Production": "20th Century Fox",
"Website": "http://www.avatarmovie.com/",
"Response": "True"
}
Your call is correct, so it must be something in the setup. Best guess is that you're calling JSON.parse() on an object that has already been converted to an object.

Parsing nested objects Python 3.4

I am trying to extract user reviews linked to a business from the google places API.
I am using the requests library :
import requests
r = requests.get('https://maps.googleapis.com/maps/api/place/details/json?placeid=ChIJlc_6_jM4DW0RQUUtaQj2_lk&key=AIzaSyBuS4meH_HW3FO1cpUaCm6jbqzRCWe7mjc')
json_data_dic = r.json()
print(json_data_dic)
So I get the json object converted to a python object for me to parse and extract my user ratings & reviews .
I get a "lump" of text back (see below). As someone new to python/coding, all I see is a tangle of nested dictionaries and lists. In situations where there is nesting- how do I refer to an items such as 'rating', or the 'text' of the review?
Any guidance would be appreciated.
{
"html_attributions": [],
"result": {
"reviews": [
{
"relative_time_description": "in the last week",
"profile_photo_url": "//lh6.googleusercontent.com/-06-3qCU8jEg/AAAAAAAAAAI/AAAAAAAAACc/a1z-ga9rOhs/photo.jpg",
"rating": 1,
"time": 1481050128,
"author_name": "Tass Wilson",
"text": "Worse company I've had the pleasure of dealing with. They don't follow through on what they say, their technical support team knows jack all. They are unreliable and lie. The only good part about their entire team is the sales team and thats to get you in the door, signed up and committed to a 12 month contract so they can then screw you over many times without taking you out to dinner first\n\nI would literally rather go back to using smoke signals and frikkin carrier pigeons then use Orcon again as an internet provider",
"aspects": [
{
"rating": 0,
"type": "overall"
}
],
"language": "en",
"author_url": "https://www.google.com/maps/contrib/116566965301711692941/reviews"
},
{
"relative_time_description": "3 weeks ago",
"rating": 1,
"time": 1479258972,
"author_name": "Anne-Marie Petersen",
"text": "I have experienced nothing but pain with them - from the start to (almost the end) in fact so I could skip the 5 days without internet I have had my other provider set up my fibre and just cut the loss of the extra month as the final bad money I will ever have to pay them. I called them to ask why I hadn't been offered an upgrade to fibre - I was told I wasn't eligible for fibre due to bad credit rating. I flipped out. Namely because I have a good credit score - it's something I check regularly. So I said well how do you know - they gave me the number of the company they use so I could call them. I hung up, called the number - it was the YELLOW PAGES number. I call back, I get given the same number (same person answered) I am seeing RED by this point, so I say just give me the name of the company. I find the number myself - I then call them only to be told they don't even work with Orcon. Then the guy offers to do a quick scan of the system to see if my name is in then. Doesn't even appear. Round and round the mulberry bush - I called another company and finally have had my fibre installed and everything ago. I still have no idea how to use the extra remote they've given me but the internet is fabulous. Oh - and I also got sick of every time something was wrong it was always MY fault even though I knew they would go offline and fix something. I used to WORK at a telco company let me tell you I get the system. Finally I have to send the modem back but I've already been advised to take it into their head office and take a photo of myself handing it in because they have on numerous occasions said to people that they've never received the modem even though they had.... why the hell are they still even a company????\n\nUPDATE>> got sent two cancellation notices - neither of which were for accounts that I had power over apparently. Have taken to twitter to have a public forum so they can't get me on not returning my modem.",
"aspects": [
{
"rating": 0,
"type": "overall"
}
],
"language": "en",
"author_url": "https://www.google.com/maps/contrib/113533966859873380749/reviews"
},
{
"relative_time_description": "4 months ago",
"profile_photo_url": "//lh4.googleusercontent.com/-lAEJbEHaIoE/AAAAAAAAAAI/AAAAAAAAEFo/IATRvjK2Oak/photo.jpg",
"rating": 1,
"time": 1469481312,
"author_name": "Keith Rankine",
"text": "Everything works well until you try to cancel your account. Do not be fooled into thinking you cannot give them notice to cancel within your contract term. They will try everything in their power to squeeze an extra month from you. \nI had a 12 month contract and informed them of my wish to cancel on the anniversary on that sign up date. All their emails were carefully worded to imply that this could not be done. If read carefully, and you argue, they will agree to it.",
"aspects": [
{
"rating": 0,
"type": "overall"
}
],
"language": "en",
"author_url": "https://www.google.com/maps/contrib/115729563512218272075/reviews"
},
{
"relative_time_description": "a month ago",
"rating": 1,
"time": 1476082876,
"author_name": "Wayne Furlong",
"text": "Completely useless. Dishonest, lazy and downright incompetent. Corporate bullies. I'm so much happier with Bigpipe.",
"aspects": [
{
"rating": 0,
"type": "overall"
}
],
"language": "en",
"author_url": "https://www.google.com/maps/contrib/113527219809275504416/reviews"
},
{
"relative_time_description": "3 months ago",
"rating": 1,
"time": 1471292986,
"author_name": "Shaun b",
"text": "Recently upgraded to \"unlimited\" Fibre with Orcon. Most mornings (5-9) we have a limited wired or wireless connection. Too often (as is the case this morning) we have no internet (so while at home we have to use phone data). This is on Wellington's cbd area. Their customer service is such that a reply could take upwards of 4 weeks. I intend to change provider.",
"aspects": [
{
"rating": 0,
"type": "overall"
}
],
"language": "en",
"author_url": "https://www.google.com/maps/contrib/101110905108291593535/reviews"
}
],
"utc_offset": 780,
"adr_address": "<span class=\"street-address\">1 The Strand</span>, <span class=\"extended-address\">Takapuna</span>, <span class=\"locality\">Auckland</span> <span class=\"postal-code\">0622</span>, <span class=\"country-name\">New Zealand</span>",
"photos": [
{
"html_attributions": [
"Orcon"
],
"height": 877,
"photo_reference": "CoQBdwAAAO0RRplNcUkeQUxtJLTNk3uAOTadHfKZQ8g2NMa6XLRmGX2oKdUHItfnKZP0CG2WwIj198PwzfDRJpZIw4M1wSENCEOD9mFjITSwWTMjHkw1PzHb9teT6vuuROxcCdH-fwCYp0tkeBc75R8RHb2drPbTk-NN_5q88jkJTfNwdZQDEhB-25Az9550mGd00B-zK-LRGhQpTusm33tZBFXA1952txiuAUsgQA",
"width": 878
}
],
"id": "a7c161a7081101d8897c2dd2fb41fa94b812b050",
"scope": "GOOGLE",
"vicinity": "1 The Strand, Takapuna, Auckland",
"international_phone_number": "+64 800 131 415",
"url": "https://maps.google.com/?cid=6484891029444838721",
"types": [
"point_of_interest",
"establishment"
],
"name": "Orcon",
"rating": 1.8,
"geometry": {
"viewport": {
"northeast": {
"lat": -36.7889585,
"lng": 174.77310355
},
"southwest": {
"lat": -36.7890697,
"lng": 174.77302975
}
},
"location": {
"lat": -36.78901820000001,
"lng": 174.7730694
}
},
"place_id": "ChIJlc_6_jM4DW0RQUUtaQj2_lk",
"formatted_address": "1 The Strand, Takapuna, Auckland 0622, New Zealand",
"reference": "CmRRAAAAD0loSIVYDAuRKLbv5Cp6ZM_jxKHbzJ7EOrDLakY1PAlmq5YDTJ82A4qzWje0ILFv3lsEdaUpCtkuVHuOxXW6so5yqxDSfkgEnXbzd84jtfItuxis7Izu-y87vwkD7JO4EhBZB6aIdHSchBT6_USM5B5VGhTTRgmnDKndDt6amWnPkXw-57-Pww",
"icon": "https://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
"website": "https://www.orcon.net.nz/",
"formatted_phone_number": "0800 131 415",
"address_components": [
{
"short_name": "1",
"types": [
"street_number"
],
"long_name": "1"
},
{
"short_name": "The Strand",
"types": [
"route"
],
"long_name": "The Strand"
},
{
"short_name": "Takapuna",
"types": [
"sublocality_level_1",
"sublocality",
"political"
],
"long_name": "Takapuna"
},
{
"short_name": "Auckland",
"types": [
"locality",
"political"
],
"long_name": "Auckland"
},
{
"short_name": "Auckland",
"types": [
"administrative_area_level_1",
"political"
],
"long_name": "Auckland"
},
{
"short_name": "NZ",
"types": [
"country",
"political"
],
"long_name": "New Zealand"
},
{
"short_name": "0622",
"types": [
"postal_code"
],
"long_name": "0622"
}
]
},
"status": "OK"
}
json_data_dic.get("result").get("reviews") or json_data_dic['result']['reviews'] gives you the list of reviews
json_data_dic.get("result").get("reviews")[0].get("text") returns the text of the first review
If you need to get each review:
for review in json_data_dic.get("result").get("reviews"):
print review.get("text")
In general, use .get(KEY) or [KEY] access a dictionary item by the key and use
[INDEX] access an item in a list by the index (starting from 0)

Flickr API Not Returning Actual Photos

Hi i'm on a project and want to use Flickr for my image galery, i'm using the photosets.* method but whenever i make a request i don't get images, i only get info.
Json Result:
{
"photoset": {
"id": "77846574839405047",
"primary": "88575847594",
"owner": "998850450#N03",
"ownername": "mr.barde",
"photo": [
{
"id": "16852316982",
"secret": "857fur848c",
"server": "8568",
"farm": 9,
"title": "wallpaper-lenovo-blue-pc-brand",
"isprimary": "1",
"ispublic": 1,
"isfriend": 0,
"isfamily": 0
},
{
"id": "16665875068",
"secret": "857fur848c",
"server": "7619",
"farm": 8,
"title": "white_horses-1280x720",
"isprimary": "0",
"ispublic": 1,
"isfriend": 0,
"isfamily": 0
}
],
"page": 1,
"per_page": "2",
"perpage": "2",
"pages": 3,
"total": "6",
"title": "My First Album"
},
"stat": "ok"
}
Please would like to have actual image URLs returned, how can i do this.
Thanks to the comment by #CBroe
I found this in the Flickr API doc.
You can construct the source URL to a photo once you know its ID, server ID, farm ID and secret, as returned by many API methods.
https://farm{farm-id}.staticflickr.com/{server-id}/{id}_{secret}.jpg
or
https://farm{farm-id}.staticflickr.com/{server-id}/{id}_{secret}_[mstzb].jpg
or
https://farm{farm-id}.staticflickr.com/{server-id}/{id}_{o-secret}_o.(jpg|gif|png)
The final result would then look something like this.
https://farm1.staticflickr.com/2/1418878_1e92283336_m.jpg
Reference: https://www.flickr.com/services/api/misc.urls.html

Resources