I'm trying to filter data from an API request to get only registers that were created or updated yesterday.
There are some notes listed in the documentation, some are shown below.
2. The query must be URL encoded
4. Query string must be enclosed between a pair of double quotes and can have up to 512 characters
5. Logical operators AND, OR along with parentheses () can be used to group conditions
6. Relational operators greater than or equal to :> and less than or equal to :< can be used along with date fields and numeric fields
The format of the request is: .../api/v2/search/tickets?query="created_at:>'2017-01-01' OR updated_at:>'2017-01-01'"
Url encoded it becomes: .../api/v2/search/tickets?query="created_at:>%272017-01-01%27%20OR%20updated_at:>%272017-01-01%27"
I wrote the following code:
import datetime as dt
import urllib.parse
import requests
url = f".../api/v2/search/tickets"
params={}
yesterday = dt.date.today() - dt.timedelta(days = 1)
query = urllib.parse.quote(f"created_at:>{yesterday} OR updated_at:>{yesterday}")
params["query"] = query
response = requests.get(url, auth=(api_key, "X"), params=params)
I'm using urllib.parse.quote
to URL encode the string but I'm getting a different format if compared to the example provided from the API documentation.
.../tickets?query=created_at%253A%253E%25272022-10-30%2527%2520OR%2520updated_at%253A%253E%25272022-10-30%2527
Error raised: requests.exceptions.HTTPError: 400 Client Error: Bad Request for url
I can't find a way to keep the double quotes, I tried to enclose the double quotes in single quotes but it doesn't work.
I can't find a way to encode the filter string as the example shown in the API Documentation.
Any help?
Here's the result if you let requests
do the encoding. This is proper URL encoding:
import datetime as dt
import urllib.parse
import requests
url = "http://timr.example.com/api/v2/search/tickets"
api_key = "7"
params={}
yesterday = dt.date.today() - dt.timedelta(days = 1)
query = f'"created_at:>{yesterday} OR updated_at:>{yesterday}"'
params["query"] = query
response = requests.get(url, auth=(api_key, "X"), params=params)
print(response.url)
Output:
http://timr.example.com/api/v2/search/tickets?query=%22created_at%3A%3E2022-10-30+OR+updated_at%3A%3E2022-10-30%22
OK, there's a way you can do this, by interrupting requests
automated processing. You have it prepare almost everything, then you insert your fake encoded query at the end:
import datetime
import requests
def fakeencode(s):
return s.replace("'","%27").replace(' ','%20')
query = "created_at:>'2017-01-01' OR updated_at:>'2017-01-01'"
url = "http://timr.example.com/api/v2/search/tickets"
api_key = "7"
yesterday = datetime.date.today() - datetime.timedelta(days = 1)
query = f"created_at:>'{yesterday}' OR updated_at:>'{yesterday}'"
query = '?query="'+fakeencode(query)+'"'
sess = requests.Session()
req = requests.Request('GET', url, auth=(api_key,"X"))
p = req.prepare()
p.url += query
response = sess.send(p)
print(response.url)
Output:
http://timr.example.com/api/v2/search/ticketsquery="created_at:>%272022-10-31%27%20OR%20updated_at:>%272022-10-31%27"