Is there a way to get Wikidata page information based on the name of the entity for example if I wanted to get page data for Google.
I think it has to be done using "entity" with the corresponding entity value however I am not sure of there is any easy way to determine the entity value.
If you want to do this using the API, you would first use wbsearchentities to find out which entity do you want. For example:
https://www.wikidata.org/w/api.php?action=wbsearchentities&search=Google&language=en
The problem with this is that there are multiple entities called "Google": the company (Google Inc.), the search engine (Google Web Search), the verb (to google) and even a Wikipedia disambiguation page.
After you somehow decide which entity to access, use wbgetentities to actually get the information you want:
https://www.wikidata.org/w/api.php?action=wbgetentities&ids=Q95&languages=en
Or, if you can't decide which entity to use, you could get information for all of them at the same time:
https://www.wikidata.org/w/api.php?action=wbgetentities&ids=Q95|Q9366|Q961680|Q1156923&languages=en
If you are familiar with Python you could do it programmatically with the Wikidata api, using Pywikibot The following python script, obtains the wikidata entities. If you want the data objects for each individual wikidata entity, you need to uncomment the last two lines
from pywikibot.data import api
import pywikibot
import pprint
def getItems(site, itemtitle):
params = { 'action' :'wbsearchentities' , 'format' : 'json' , 'language' : 'en', 'type' : 'item', 'search': itemtitle}
request = api.Request(site=site,**params)
return request.submit()
def getItem(site, wdItem, token):
request = api.Request(site=site,
action='wbgetentities',
format='json',
ids=wdItem)
return request.submit()
def prettyPrint(variable):
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(variable)
# Login to wikidata
site = pywikibot.Site("wikidata", "wikidata")
repo = site.data_repository()
token = repo.token(pywikibot.Page(repo, 'Main Page'), 'edit')
wikidataEntries = getItems(site, "Google")
# Print the different Wikidata entries to the screen
prettyPrint(wikidataEntries)
# Print each wikidata entry as an object
#for wdEntry in wikidataEntries["search"]:
# prettyPrint(getItem(site, wdEntry["id"], token))
which results in
{ u'search': [ { u'aliases': [u'Google Inc.'],
u'description': u'American multinational Internet and technology corporation',
u'id': u'Q95',
u'label': u'Google',
u'url': u'//www.wikidata.org/wiki/Q95'},
{ u'aliases': [u'Google Search', u'Google Web Search'],
u'description': u'Internet search engine developed by Google, Inc.',
u'id': u'Q9366',
u'label': u'Google',
u'url': u'//www.wikidata.org/wiki/Q9366'},
{ u'description': u'Wikipedia disambiguation page',
u'id': u'Q961680',
u'label': u'Google',
u'url': u'//www.wikidata.org/wiki/Q961680'},
{ u'aliases': [u'Google'],
u'description': u'verb',
u'id': u'Q1156923',
u'label': u'google',
u'url': u'//www.wikidata.org/wiki/Q1156923'},
{ u'id': u'Q10846831',
u'label': u'google',
u'url': u'//www.wikidata.org/wiki/Q10846831'},
{ u'aliases': [u'Google Android'],
u'description': u'operating system for mobile devices created by Google',
u'id': u'Q94',
u'label': u'Android',
u'url': u'//www.wikidata.org/wiki/Q94'},
{ u'description': u'web browser developed by Google',
u'id': u'Q777',
u'label': u'Google Chrome',
u'url': u'//www.wikidata.org/wiki/Q777'}],
u'searchinfo': { u'search': u'Google'},
u'success': 1}
Maybe you can use sparql, to run a query:
SELECT ?item WHERE {
?item rdfs:label "Google"#en
}
You can use in python using pywikibot:
import pywikibot
from pywikibot import pagegenerators, WikidataBot
sparql = "SELECT ?item WHERE { ?item rdfs:label 'Google'#en }"
entities = pagegenerators.WikidataSPARQLPageGenerator(sparql, site=repo)
entities = list(entities)
Related
I am currently using Calendar API using Python to create a google calendar Event and send invitations to an attendee.
Is there an Event link I can send to him by SMS? so that he could join it using that link also.
The Calendar API gives the Event link in response but If I open it as Attendee. It says Event is not found.
My Code
from __future__ import print_function
import datetime
import os.path
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google.oauth2 import service_account
# If modifying these scopes, delete the file token.json.
SCOPES = ['https://www.googleapis.com/auth/calendar','https://www.googleapis.com/auth/calendar.events',
'https://www.googleapis.com/auth/admin.directory.resource.calendar',
'https://www.googleapis.com/auth/gmail.send']
SERVICE_ACCOUNT_FILE = 'credentials.json'
def main():
"""Shows basic usage of the Google Calendar API.
Prints the start and name of the next 10 events on the user's calendar.
"""
creds = None
# The file token.json stores the user's access and refresh tokens, and is
# created automatically when the authorization flow completes for the first
# time.
creds =service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
delegated_credentials = creds.with_subject('username#domain.com')
service = build('calendar', 'v3', credentials=delegated_credentials)
event = {
'summary': 'Driving Lessons 5',
'location': 'Location',
'description': 'Usman is Testing',
'start': {
'dateTime': '2022-08-27T09:00:00-07:00',
'timeZone': 'America/Los_Angeles',
},
'end': {
'dateTime': '2022-08-27T17:00:00-07:00',
'timeZone': 'America/Los_Angeles',
},
'recurrence': [
'RRULE:FREQ=DAILY;COUNT=1'
],
'attendees': [
{'email': 'attendee1#mail.com'},
{'email': 'attendee2#mail.com'},
],
'reminders': {
'useDefault': False,
'overrides': [
{'method': 'email', 'minutes': 24 * 60}
],
},
}
event = service.events().insert(calendarId='mycalenderid', body=event,sendUpdates='all').execute()
print ('Event created: %s' % (event.get('htmlLink')))
if __name__ == '__main__':
main()
Event link Generated when I run this code
https://www.google.com/calendar/event?eid=OHY5M3JlcmRzZ2RoM2tvMnZuZHQ0dXB1MDRfMjAyMjA4MjdUMTYwMDAwWiB1c21hbkBkcml2aW9sb2d5LmNvbQ
If I copy and Paste this link in browser as an attendee, it says event not found.
The link you get in the response is the htmlLink which will open successfully only with the account you're creating the event from, this contains specifically the event ID that was created in your calendar.
I did some research and unfortunately it seems there is no option with the Google Calendar API to generate an external event link or share a link by SMS, this feature was removed in 2019. You can always send a notification by email by adding the sendUpdates parameter in your code.
Now, the only workaround I found is sharing the link that you can generate directly from the event in the Google Calendar interface, click the three dots to the right, when clicking an event, and select "Publish event". The format to that link is:
https://calendar.google.com/event?action=TEMPLATE&tmeid=YOUR_EVENTID&tmsrc=add_the_attendee_email_address
However, if the attendee clicks on "Save" when openning the link you share, it will be created as a new event, this link is just like a template which means any changes the attendee makes it won't be reflected in your calendar.
If you have any questions let me know!
I'm attempting to use Python + requests to talk with MS Graph API (v1.0) in order to filter user objects by the onPremisesSamAccountName property but am receiving this error when sending the simple query:
endpoint = "https://graph.microsoft.com/v1.0/users"
query_parameters = {
'$filter': 'onPremisesSamAccountName eq \'somevalue\'',
'$select': 'id,displayName,mail,onPremisesSamAccountName'
}
user_graph_data = requests.get(
endpoint,
headers={'Authorization': 'Bearer ' + result['access_token']},
params=query_parameters
).json()
==============================
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "Unsupported or invalid query filter clause specified for property 'onPremisesSamAccountName' of resource 'User'.",
"innerError": {
"date": "...",
"request-id": "...",
"client-request-id": "..."
}
}
}
I am able to filter using this field while using Microsoft's Graph Explorer:
https://developer.microsoft.com/en-us/graph/graph-explorer and the corresponding Javascript call in the developer console shows a successful call and response based on the filter with onPremisesSamAccountName.
The MS Graph docs for v1.0 state that this is a supported field for filtering as well:
Returned only on $select. Supports $filter (eq, ne, NOT, ge, le, in,
startsWith).
I'm also able to successfully filter using other fields such as 'mail' (i.e. changing the $filter string from 'onPremisesSamAccountName eq \'somevalue\'' to 'mail eq \'somevalue\'' works just fine, so I don't believe this is a syntactical error)
I'm trying to create external user on Nexus 3 using nexus 3 APIs. Following are the details:
Posting Groovy Script using: http://localhost:8081/nexus3/service/rest/v1/script
{
"name": "d8b3baeb-628a-43cc-9a9c-9a156f399e2",
"type": "groovy",
"content": "security.addUser('q018246a', '', '', '', true, 'd8b3baeb-628a-43cc-9a9c-9a156f399ae2', ['abc_test_role Developer Role']);"
}
Running Script using: http://localhost:8081/nexus3/service/rest/v1/script/d8b3baeb-628a-43cc-9a9c-9a156f399e2/run
Response:
{
"name": "d8b3baeb-628a-43cc-9a9c-9a156f399e2",
"result": "User{userId='q018246a', firstName='', lastName='', source='default'}"
}
Hitting though Postman, all working fine and users getting created. But through Application server it is giving Bad request.
Awkward behavior is, it's letting me create user using postman post script with blank first_name, last_name, email, password, but all these parameters are required on UI.
Another thing, It's showing source as default but how to I ensure source as LDAP?
I assume you're trying to map an LDAP user? If so, this will work:
import org.sonatype.nexus.security.role.RoleIdentifier;
import org.sonatype.nexus.security.user.User;
String userId = 'someuser';
String newRoleId = 'nx-admin'
User user = security.securitySystem.getUser(userId, 'LDAP')
if(user != null) {
RoleIdentifier newRole = new RoleIdentifier('default', newRoleId);
user.addRole(newRole)
security.securitySystem.setUsersRoles(user.getUserId(), 'LDAP', user.getRoles());
} else {
log.warn("No user with ID of $userId found.")
}
I am using Roxy to manage my project. Also using MarkLogic 8.0-6.1
I am trying to submit a searchTerm, and return a custom formatted search:snippet
Here are the complete steps that I am taking:
./../roxy/ml new test-app --server-version=8 --app-type=rest
Configure my build.properties
cd test-app/
./ml local bootstrap
Now I have my project Structure.
Create File - test-app/rest-api/ext/show-search.xqy
xquery version "1.0-ml";
module namespace ss = "http://marklogic.com/rest-api/resource/show-search";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
import module namespace json = "http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";
declare
function ss:get(
$context as map:map,
$params as map:map
) as document-node()*
{
map:put($context, "output-types", "application/json"),
map:put($context, "output-status", (200, "OK")),
let $search-term := map:get($params, "searchTerm")
let $query := search:search($search-term,
<options xmlns="http://marklogic.com/appservices/search">
<transform-results apply="raw"/>
</options>
)
return document {$query}
};
(:
:)
declare
function ss:put(
$context as map:map,
$params as map:map,
$input as document-node()*
) as document-node()?
{
map:put($context, "output-types", "application/xml"),
map:put($context, "output-status", (201, "Created")),
document { "PUT called on the ext service extension" }
};
(:
:)
declare
function ss:post(
$context as map:map,
$params as map:map,
$input as document-node()*
) as document-node()*
{
map:put($context, "output-types", "application/xml"),
map:put($context, "output-status", (201, "Created")),
document { "POST called on the ext service extension" }
};
(:
:)
declare
function ss:delete(
$context as map:map,
$params as map:map
) as document-node()?
{
map:put($context, "output-types", "application/xml"),
map:put($context, "output-status", (200, "OK")),
document { "DELETE called on the ext service extension" }
};
The above GET request uses the transform-results apply=raw option, deploys, and functions properly (I have some test documents).
However I do not want to return the whole document, I want to return a whole section of the json that had a match, no matter where in that seciton the match happened (lower levels)
So I try to write my own snipper
Create File - test-app/rest-api/ext/show-search-snipper.xqy
xquery version "1.0-ml";
module namespace sss = "http://marklogic.com/rest-api/resource/show-search-snipper";
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
import module namespace json = "http://marklogic.com/xdmp/json" at "/MarkLogic/json/json.xqy";
declare
function sss:my-snippet(
$result as node(),
$ctsquery as schema-element(cts:query),
$options as element(search:transform-results)?
) as element(search:snippet)
{
<search:snippet>
</search:snippet>
};
I then update the search:search call to the following
let $query := search:search($search-term,
<options xmlns="http://marklogic.com/appservices/search">
<transform-results apply="my-snippet" ns="http://marklogic.com/rest-api/resource/show-search-snipper" at="show-search-snipper.xqy"/>
</options>
)
Now I should have everything I need (I think)
I run the deploy ./ml local deploy rest
and get the following
Minty-linux test-app # ./ml local deploy rest Loading REST properties
in /opt/this-is-a-test/test-app/rest-api/config/properties.xml Loading
REST options in /opt/this-is-a-test/test-app/rest-api/config/options
Loading REST extensions from /opt/this-is-a-test/test-app/rest-api/ext
ERROR: 400 "Bad Request" ERROR: {"errorResponse":{"statusCode":400,
"status":"Bad Request", "messageCode":"RESTAPI-INVALIDCONTENT",
"message":"RESTAPI-INVALIDCONTENT: (err:FOER0000) Invalid content:
invalid show-search-snipper extension: show-search-snipper either is
not a valid module or does not provide extension functions (delete,
get, put, post) in the
http://marklogic.com/rest-api/resource/show-search-snipper
namespace"}}
So I tried moving the show-search-snipper.xqy file up 1 level (to test-app/rest-api/show-search-snipper.xqy`
Run the deployment
Deployment Works No errors
Hit the URL and receive the following
500 Internal Server Error
INTERNAL ERROR
RESTAPI-INVALIDREQ: (err:FOER0000) Invalid request: reason: Extension
show-search does not exist. . See the MarkLogic server error log for
further detail.
Although I know the extension was created properly, since it worked fine before the introduction of the custom snip function. (with apply="raw")
Any thoughts how I can apply my custom snip function or what I am doing wrong in deployment?
Should you decide to stick with a custom snippeter:
It looks like Roxy is trying to treat it your snippeter module as a resource extension, which it is not. Your snippeter should be just a vanilla module in the modules db.
IDK how to configure Roxy, unfortunately, but what you're aiming for is to get Roxy to either install it using PUT /v1/ext/directories/asset or a straight up insert (`PUT /v1/documents) on your modules db. See http://docs.marklogic.com/REST/PUT/v1/ext/[directories]/[asset].
Assuming Roxy uses /ext, then the path to your snippeter would NOT be the unqualified path you have in your options. It would be an absolute path rooted at /ext/. See http://docs.marklogic.com/guide/rest-dev/search#id_72390.
There's a simpler way -- you can do this with the extract-document-data search option.
I set up some sample data to work with like this:
xquery version "1.0-ml";
for $i in (1 to 10)
return
xdmp:document-insert(
'/test-content-' || $i || '.json',
xdmp:unquote('{ "important": { "foo": 1, "bar": 2 }, "not-important": { "stuff": 3, "blah": 4 } }')
)
Having bootstrapped and deployed modules, I can get search results at http://localhost:8040/v1/search. However, I can start taking more control of the search results by using stored search options. Take a look in your project at rest-api/config/options/all.xml. They were already deployed for you when you run ml local deploy modules, so you now can search using http://localhost:8040/v1/search?options=all. Since you're using JSON data, I took it one step further and ran with: http://localhost:8040/v1/search?format=json&options=all.
I added this to rest-api/config/options/all.xml:
<extract-document-data selected="include">
<extract-path>/important</extract-path>
</extract-document-data>
This tells the search options to include the specified path with all search results. After deploying and running the search again, one result looks like this:
{
"index":1,
"uri":"/test-content-6.json",
"path":"fn:doc(\"/test-content-6.json\")",
"score":0,
"confidence":0,
"fitness":0,
"href":"/v1/documents?uri=%2Ftest-content-6.json",
"mimetype":"application/json",
"format":"json",
"matches":[{"path":"fn:doc(\"/test-content-6.json\")/object-node()", "match-text":[]}],
"extracted":{
"kind":"array",
"content":[
{"important":{"foo":1, "bar":2}}
]
}
},
Notice the "extracted" part at the end there -- I get the "important" JSON property, as specified in the options.
For a full list of options you can set to control search, see the Query Options Reference appendix.
I am successfully downloading results from Google Analytics using the reporting API (version 4), with the PHP client library. But I have not figured out how to correctly filter these results.
I see how this would work via cURL, but not through the client library. I looked through the client library code, and there is a class method:
apiclient-services/Google/Service/AnalyticsReporting/ReportRequest.php:
public function setMetricFilterClauses($metricFilterClauses)
I do not see any documentation or any usage of the associated get method:
public function getMetricFilterClauses()
Are there examples of using filters through the PHP client library?
Background
The Google API Client libraries are generated from the Google Discovery Service. And the PHP client library generates a setProperty and getProperty for every property of a resource.
Analytics Reporting API V4
The Analytics Reporting API V4 reference docs exhustively describe the API. The Developer Guide gives the underlying JSON example which the client libraries will generate:
POST https://analyticsreporting.googleapis.com/v4/reports:batchGet
{
"reportRequests":
[
{
"viewId": "XXXX",
"dateRanges": [
{"endDate": "2014-11-30", "startDate": "2014-11-01"}
],
"metrics": [
{"expression": "ga:pageviews"},
{"expression": "ga:sessions"}
],
"dimensions": [{"name": "ga:browser"}, {"name": "ga:country"}],
"dimensionFilterClauses": [
{
"filters": [
{
"dimensionName": "ga:browser",
"operator": "EXACT",
"expressions": ["Chrome"]
}
]
}
]
}
]
}
And the Samples page gives many examples requests in Python, Java, PHP and JavaScript, which should give you a good sense of how to work with the individual client libraries. But you are correct there is not an explicit example of PHP using a filter.
PHP Filter Example
Below is the same example as the request above:
// Create the DateRange object.
$dateRange = new Google_Service_AnalyticsReporting_DateRange();
$dateRange->setStartDate("2014-11-01");
$dateRange->setEndDate("2014-11-30");
// Create the Metrics object.
$pageviews = new Google_Service_AnalyticsReporting_Metric();
$pageviews->setExpression("ga:pageviews");
$sessions = new Google_Service_AnalyticsReporting_Metric();
$sessions->setExpression("ga:sessions");
//Create the Dimensions object.
$browser = new Google_Service_AnalyticsReporting_Dimension();
$browser->setName("ga:browser");
$country = new Google_Service_AnalyticsReporting_Dimension();
$country->setName("ga:country");
// Create the DimensionFilter.
$dimensionFilter = new Google_Service_AnalyticsReporting_DimensionFilter();
$dimensionFilter->setDimensionName('ga:browser');
$dimensionFilter->setOperator('EXACT');
$dimensionFilter->setExpressions(array('Chrome'));
// Create the DimensionFilterClauses
$dimensionFilterClause = new Google_Service_AnalyticsReporting_DimensionFilterClause();
$dimensionFilterClause->setFilters(array($dimensionFilter));
// Create the ReportRequest object.
$request = new Google_Service_AnalyticsReporting_ReportRequest();
$request->setViewId("XXXX");
$request->setDateRanges($dateRange);
$request->setDimensions(array($browser, $country));
$request->setDimensionFilterClauses(array($dimensionFilterClause));
$request->setMetrics(array($pageviews, $sessions));
$body = new Google_Service_AnalyticsReporting_GetReportsRequest();
$body->setReportRequests( array( $request) );
return $analyticsreporting->reports->batchGet( $body );
As you probably noticed I never once used a $object->getProperty(). Basically All it would do is give me its current value. When Calling the API you should only ever need to $object->setProperty($value); Hence why I gave you the background that the client libraries are generated.
Conclusion
The Analytics Reporting API itself is complex and there are many client library languages. It is not always possible to give an example every possible usage of an API in every possible client library language. That is why it is necessary to understand how to look at the reference docs and understand how the client libraries are generated from the structure described.
There is an issue with DimensionFilter() class in a script above, i get error that it is not defined, but i have changed it to Google_Service_AnalyticsReporting_DimensionFilter() class and now it is working hope that will help to someone.