I'm trying to query the public Art Institute of Chicago API to only show me results that match certain criteria. For example:
classification_title
= "painting"colorfulness
<= 13material_titles
includes "paper (fiber product)"
The API documentation states:
Behind the scenes, our search is powered by Elasticsearch. You can use its Query DSL to interact with our API.
I can't figure out how to take an Elasticsearch DSL JSON-like object and pass it into the API URL, beyond a single criteria.
Here are some working single-criteria examples specific to this API:
requests.get("https://api.artic.edu/api/v1/artworks/search?q=woodblock[classification_title]").json()
requests.get("https://api.artic.edu/api/v1/artworks/search?q=monet[artist_title]").json()
And here are some of my failed attempts to have return only items that pass 2 criteria items:
requests.get("https://api.artic.edu/api/v1/artworks/search?q=woodblock[classification_title]monet[artist_title]")
requests.get("https://api.artic.edu/api/v1/artworks/search?q=woodblock[classification_title],monet[artist_title]")
requests.get("https://api.artic.edu/api/v1/artworks/search?q=+classification_title:(woodblock) +artist_title:(monet)")
And lastly some of my failed attempts to return more complex criteria, like range:
requests.get("https://api.artic.edu/api/v1/artworks/search?q={range:lte:10}&query[colorfulness]").json()
requests.get("https://api.artic.edu/api/v1/artworks/search?q=<10&query[colorfulness]").json()
requests.get("https://api.artic.edu/api/v1/artworks/search?q=+date_display:<1900").json()
All of these failed attempts return data but not within my passed criteria. For example, woodblock[classification_title]monet[artist_title]
should return no results.
How could I query all of these criteria, only returning results (if any) that match all these conditions? The JSON-like Query DSL does not seem compatible with a requests.get
.
CodePudding user response:
Solved. I was lacking knowledge on GET
and POST
. I can indeed use the JSON-like Query DSL. It just needs to be sent as part of a requests.post
instead of a requests.get
, like so:
import requests
fields = "id,image_id,title,artist_id,classification_title,colorfulness,material_titles"
url = f"https://api.artic.edu/api/v1/artworks/search?&fields={fields}"
criteria = {
"query": {
"bool": {
"must": [
{"match": {"classification_title": "painting"}},
{"range": {"colorfulness": {"lte": 13}}},
{"match": {"material_titles": "paper (fiber product)"}},
],
}
}
}
r = requests.post(url, json=criteria)
art = r.json()
print(art)
Notice within the requests.post
that the desired criteria query is passed through as a json
argument, separate from the url
.