Skip to content

Commit a512978

Browse files
committed
## [v8.10]() (2021-08-16)
**Added** - added file `QueryMentions` that can be used to query mentions of specific event types. The class is currently in beta and not available to users unless they have permissions to use this endpoint. The classes `QueryMentions` and `QueryMentionsIter` can be used in the same way as classes for querying articles and events, except that some query parameters are addded and some removed. Examples for the classes were also added. **Updated** - When using method `initWithComplexQuery` we now check if the provided json is valid json object and report error in case it is not - some bugs that appeared in edge cases when querying Event Registry using `EventRegistry` class have been fixed.
1 parent 0413a65 commit a512978

File tree

10 files changed

+621
-33
lines changed

10 files changed

+621
-33
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Change Log
22

3+
## [v8.10]() (2021-08-16)
4+
5+
**Added**
6+
7+
- added file `QueryMentions` that can be used to query mentions of specific event types. The class is currently in beta and not available to users unless they have permissions to use this endpoint. The classes `QueryMentions` and `QueryMentionsIter` can be used in the same way as classes for querying articles and events, except that some query parameters are addded and some removed. Examples for the classes were also added.
8+
9+
**Updated**
10+
- When using method `initWithComplexQuery` we now check if the provided json is valid json object and report error in case it is not
11+
- some bugs that appeared in edge cases when querying Event Registry using `EventRegistry` class have been fixed.
12+
313
## [v8.9]() (2020-10-21)
414

515
**Added**

eventregistry/EventRegistry.py

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,21 @@ def __init__(self,
2525
printHostInfo = True,
2626
settingsFName = None):
2727
"""
28-
@param apiKey: API key that should be used to make the requests to the Event Registry. API key is assigned to each user account and can be obtained on this page: http://eventregistry.org/me?tab=settings
28+
@param apiKey: API key that should be used to make the requests to the Event Registry. API key is assigned to each user account and can be obtained on
29+
this page: http://eventregistry.org/me?tab=settings
2930
@param host: host to use to access the Event Registry backend. Use None to use the default host.
3031
@param hostAnalytics: the host address to use to perform the analytics api calls
3132
@param logging: log all requests made to a 'requests_log.txt' file
3233
@param minDelayBetweenRequests: the minimum number of seconds between individual api calls
33-
@param repeatFailedRequestCount: if a request fails (for example, because ER is down), what is the max number of times the request should be repeated (-1 for indefinitely)
34-
@param allowUseOfArchive: default is True. Determines if the queries made should potentially be executed on the archive data. If False, all queries (regardless how the date conditions are set) will be
35-
executed on data from the last 31 days. Queries executed on the archive are more expensive so set it to False if you are just interested in recent data
36-
@param verboseOutput: if True, additional info about query times etc will be printed to console
34+
@param repeatFailedRequestCount: if a request fails (for example, because ER is down), what is the max number of times the request
35+
should be repeated (-1 for indefinitely)
36+
@param allowUseOfArchive: default is True. Determines if the queries made should potentially be executed on the archive data.
37+
If False, all queries (regardless how the date conditions are set) will be executed on data from the last 31 days.
38+
Queries executed on the archive are more expensive so set it to False if you are just interested in recent data
39+
@param verboseOutput: if True, additional info about errors etc will be printed to console
3740
@param printHostInfo: print which urls are used as the hosts
38-
@param settingsFName: If provided it should be a full path to 'settings.json' file where apiKey an/or host can be loaded from. If None, we will look for the settings file in the eventregistry module folder
41+
@param settingsFName: If provided it should be a full path to 'settings.json' file where apiKey an/or host can be loaded from.
42+
If None, we will look for the settings file in the eventregistry module folder
3943
"""
4044
self._host = host
4145
self._hostAnalytics = hostAnalytics
@@ -280,11 +284,10 @@ def jsonRequest(self, methodUrl, paramDict, customLogFName = None, allowUseOfArc
280284
self._headers = {} # reset any past data
281285
returnData = None
282286
respInfo = None
287+
url = self._host + methodUrl
283288
while self._repeatFailedRequestCount < 0 or tryCount < self._repeatFailedRequestCount:
284289
tryCount += 1
285290
try:
286-
url = self._host + methodUrl
287-
288291
# make the request
289292
respInfo = self._reqSession.post(url, json = paramDict)
290293
# remember the returned headers
@@ -298,21 +301,18 @@ def jsonRequest(self, methodUrl, paramDict, customLogFName = None, allowUseOfArc
298301
# remember the available requests
299302
self._dailyAvailableRequests = tryParseInt(self.getLastHeader("x-ratelimit-limit", ""), val = -1)
300303
self._remainingAvailableRequests = tryParseInt(self.getLastHeader("x-ratelimit-remaining", ""), val = -1)
301-
try:
302-
returnData = respInfo.json()
303-
break
304-
except Exception as ex:
305-
print("EventRegistry.jsonRequest(): Exception while parsing the returned json object. Repeating the query...")
306-
open("invalidJsonResponse.json", "w").write(respInfo.text)
304+
305+
returnData = respInfo.json()
306+
break
307307
except Exception as ex:
308308
self._lastException = ex
309-
print("Event Registry exception while executing the request:")
310309
if self._verboseOutput:
310+
print("Event Registry exception while executing the request:")
311311
print("endpoint: %s\nParams: %s" % (url, json.dumps(paramDict, indent=4)))
312-
self.printLastException()
312+
self.printLastException()
313313
# in case of invalid input parameters, don't try to repeat the search but we simply raise the same exception again
314314
if respInfo != None and respInfo.status_code in self._stopStatusCodes:
315-
raise ex
315+
break
316316
# in case of the other exceptions (maybe the service is temporarily unavailable) we try to repeat the query
317317
print("The request will be automatically repeated in 3 seconds...")
318318
time.sleep(3) # sleep for X seconds on error
@@ -347,17 +347,17 @@ def jsonRequestAnalytics(self, methodUrl, paramDict):
347347
# if we got some error codes print the error and repeat the request after a short time period
348348
if respInfo.status_code != 200:
349349
raise Exception(respInfo.text)
350+
350351
returnData = respInfo.json()
351352
break
352353
except Exception as ex:
353354
self._lastException = ex
354-
print("Event Registry Analytics exception while executing the request:")
355355
if self._verboseOutput:
356+
print("Event Registry Analytics exception while executing the request:")
356357
print("endpoint: %s\nParams: %s" % (url, json.dumps(paramDict, indent=4)))
357-
self.printLastException()
358-
# in case of invalid input parameters, don't try to repeat the action
359-
if respInfo != None and respInfo.status_code == 530:
360-
print("The request will not be repeated since we received a response code 530")
358+
self.printLastException()
359+
# in case of invalid input parameters, don't try to repeat the search but we simply raise the same exception again
360+
if respInfo != None and respInfo.status_code in self._stopStatusCodes:
361361
break
362362
print("The request will be automatically repeated in 3 seconds...")
363363
time.sleep(3) # sleep for X seconds on error
@@ -371,9 +371,10 @@ def jsonRequestAnalytics(self, methodUrl, paramDict):
371371

372372
def suggestConcepts(self, prefix, sources = ["concepts"], lang = "eng", conceptLang = "eng", page = 1, count = 20, returnInfo = ReturnInfo(), **kwargs):
373373
"""
374-
return a list of concepts that contain the given prefix. returned matching concepts are sorted based on their frequency of occurence in news (from most to least frequent)
374+
return a list of concepts that contain the given prefix. returned matching concepts are sorted based on their
375+
frequency of occurence in news (from most to least frequent)
375376
@param prefix: input text that should be contained in the concept
376-
@param sources: what types of concepts should be returned. valid values are person, loc, org, wiki, entities (== person + loc + org), concepts (== entities + wiki), conceptClass, conceptFolder
377+
@param sources: what types of concepts should be returned. valid values are person, loc, org, wiki, entities (== person + loc + org), concepts (== entities + wiki)
377378
@param lang: language in which the prefix is specified
378379
@param conceptLang: languages in which the label(s) for the concepts are to be returned
379380
@param page: page of the results (1, 2, ...)
@@ -539,7 +540,7 @@ def getConceptUri(self, conceptLabel, lang = "eng", sources = ["concepts"]):
539540
return a concept uri that is the best match for the given concept label
540541
if there are multiple matches for the given conceptLabel, they are sorted based on their frequency of occurence in news (most to least frequent)
541542
@param conceptLabel: partial or full name of the concept for which to return the concept uri
542-
@param sources: what types of concepts should be returned. valid values are person, loc, org, wiki, entities (== person + loc + org), concepts (== entities + wiki), conceptClass, conceptFolder
543+
@param sources: what types of concepts should be returned. valid values are person, loc, org, wiki, entities (== person + loc + org), concepts (== entities + wiki)
543544
"""
544545
matches = self.suggestConcepts(conceptLabel, lang = lang, sources = sources)
545546
if matches != None and isinstance(matches, list) and len(matches) > 0 and "uri" in matches[0]:

eventregistry/QueryArticles.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,10 @@ def initWithComplexQuery(query):
225225
q._setVal("query", json.dumps(query.getQuery()))
226226
# provided query as a string containing the json object
227227
elif isinstance(query, six.string_types):
228-
foo = json.loads(query)
228+
try:
229+
foo = json.loads(query)
230+
except:
231+
raise Exception("Failed to parse the provided string content as a JSON object. Please check the content provided as a parameter to the initWithComplexQuery() method")
229232
q._setVal("query", query)
230233
# provided query as a python dict
231234
elif isinstance(query, dict):

eventregistry/QueryEvents.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,10 @@ def initWithComplexQuery(query):
198198
q._setVal("query", json.dumps(query.getQuery()))
199199
# provided query as a string containing the json object
200200
elif isinstance(query, six.string_types):
201-
foo = json.loads(query)
201+
try:
202+
foo = json.loads(query)
203+
except:
204+
raise Exception("Failed to parse the provided string content as a JSON object. Please check the content provided as a parameter to the initWithComplexQuery() method")
202205
q._setVal("query", query)
203206
# provided query as a python dict
204207
elif isinstance(query, dict):

0 commit comments

Comments
 (0)