A Python wrapper for Yale's Lux API, provided by Yale University.
Project description
LuxY is a Python wrapper for Yale's Lux API. Lux allows users to search and filter the collections of Yale's museums and libraries, as well as external collections. This lets you find and connect with the cultural heritage collections across Yale's museums, archives, and libraries in new ways and all in one place.
LuxY gives you a Pythonic way to interact with the Lux API, making it easier to search and filter the collections and even download the data in JSON format. It can handle pagination, nested filters, and more.
Installation
To get started, install LuxY using pip:
pip install luxy
Usage
The classes of LuxY replicate the classes of the Lux API. They are:
- PeopleGroups (agent) - People and Groups that are either individuals or organizations
- Objects (item) - Physical objects in Yale's collections
- Works (work) - Visual and textual works, including images, texts, and other creative expressions
- Places (place) - Geographic locations and named spaces
- Concepts (concept) - Types, materials, languages, measurement units, currencies and other conceptual entities
- Events (event) - Historical events and occurrences
- Collections (set) - Collections and sets of objects curated by Yale's institutions
Each of these has common and unique filters that take different data types, from strings to numbers to dates. LuxY also supports nested filters, which are used to filter by multiple levels of the hierarchy. This allows users to create complex queries similar to the ones found in the Lux UI.
Understanding Options
Each filter has a set of options that can be used to filter the data. These options are stored in the get_options() method.
from luxy import PeopleGroups
options = PeopleGroups().get_options()
print(options)
# pretty print the options
PeopleGroups().list_filters()
People Groups
from luxy import PeopleGroups
result = PeopleGroups().filter(name="Rembrandt").get()
print(result.url)
print(result.view_url)
print(result.json)
Objects
from luxy import Objects
result = Objects().filter(name="Rembrandt").get()
print(result.url)
print(result.view_url)
print(result.json)
Works
from luxy import Works
result = Works().filter(name="Painting").get()
print(result.url)
print(result.view_url)
print(result.json)
Places
from luxy import Places
result = Places().filter(name="Amsterdam").get()
print(result.url)
print(result.view_url)
print(result.json)
Concepts
from luxy import Concepts
result = Concepts().filter(name="gilding").get()
print(result.url)
print(result.view_url)
print(result.json)
Events
from luxy import Events
result = Events().filter(name="Thirty Years War").get()
print(result.url)
print(result.view_url)
print(result.json)
Collections
from luxy import Collections
result = Collections().filter(name="Letters").get()
print(result.url)
print(result.view_url)
print(result.json)
Working with Numerical Filters
Numerical filters are a bit tricky because they require a tuple with the value and the comparison operator.
from luxy import Objects
result = Objects().filter(height=(1, ">=")).get()
print(result.url)
print(result.view_url)
print(result.json)
Working with Date Filters
Date filters are a bit tricky because they require a tuple with the value and the comparison operator. The value should be a string in the format of YYYY-MM-DDTHH:MM:SS.SSSZ.
from luxy import Objects
result = Objects().filter(encounteredDate=("1987-01-01T00:00:00.000Z", ">=")).get()
print(result.url)
print(result.view_url)
print(result.json)
Complex Example
from luxy import PeopleGroups
result = (
PeopleGroups()
.filter(recordType="person")
.filter(hasDigitalImage=True)
.filter(text="rembrandt")
.filter(gender={"name": "male"})
.get()
)
# print the number of results
print("Number of results:", result.num_results)
# print the url
print("URL:", result.url)
# print the json
print("JSON:", result.json)
Expected Output
Number of results: 131
URL: https://lux.collections.yale.edu/api/search/agent?q=%7B%22AND%22%3A%20%5B%7B%22recordType%22%3A%20%22person%22%7D%2C%20%7B%22hasDigitalImage%22%3A%201%7D%2C%20%7B%22text%22%3A%20%22rembrandt%22%7D%2C%20%7B%22gender%22%3A%20%7B%22id%22%3A%20%22https%3A//lux.collections.yale.edu/data/concept/6f652917-4c07-4d51-8209-fcdd4f285343%22%7D%7D%5D%7D
JSON: {'@context': 'https://linked.art/ns/v1/search.json'...
Working with Pagination
from luxy import PeopleGroups
result = (
PeopleGroups()
.filter(endAt={"name": "Amsterdam"})
.get()
)
# print the number of results
print("Number of results:", result.num_results)
print("Number of pages:", result.num_pages())
for i, page in enumerate(result.get_page_data_all(), 1):
if i > 2: # Break after 2 pages
break
print(f"Page {i}:", page["id"])
for j, item in enumerate(result.get_items(page)):
print(f"Item {j}:", result.get_item_data(item)["_label"])
Nested MemberOf Filters
result = (
Objects()
.filter(hasDigitalImage=True)
.filter(
OR=[
Objects().memberOf("Letters", depth=2),
Objects().memberOf("Letters", depth=3),
Objects().memberOf("Letters", depth=4)
]
)
.filter(name="letter")
.get()
)
print(result.url)
print(result.json)
Roadmap
v. 0.0.2
- Add support for People/Groups
- Filter by:
- Has Digital Image
- Gender
- Nationality (nationality)
- Person or Group Class
- Categorized As (classification)
- Born/Formed At (startAt)
- Born/Formed Date
- Carried Out (carriedOut)
- Created Object (produced)
- Created Works (created)
- Curated (curated)
- Died/Dissolved At (endAt)
- Died/Dissolved Date
- Encountered
- Founded By
- Founded Group
- Have Member
- ID
- Identifier
- Influenced (influenced)
- Influenced Creation Of Objects
- Influenced Creation Of Works
- Member Of (memberOf)
- Occupation/Role (occupation)
- Professional Activity Categorized As (professionalActivity)
- Professionally Active At (activeAt)
- Professionally Active Date
- Published (published)
- Subject Of
- Filter by:
- Add support for Objects
- Add support for Works
- Add support for Places
- Add support for Concepts
- Add support for Events
- Add support for Pagination
- Add support for Downloading Page JSON
- Add support for Downloading Item JSON
- Add more filters
- Add support for date filters
- Add support for numbers
- Greater Than
- Less Than
- Greater Than or Equal To
- Less Than or Equal To
- Equal To
- Not Equal To
- Add And support for filters
- Add support for OR filters
- Add support for have All of # AND
- Add support for have Any of # OR
- Add support for have None of # NOT
- Add more tests
- Add more documentation
- Add a check to make sure a filter exists
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file luxy-0.0.6.tar.gz.
File metadata
- Download URL: luxy-0.0.6.tar.gz
- Upload date:
- Size: 13.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a22295f59e4b44afda8bc6177252450b5eae25c309f5aee6c855be48d9a25f6
|
|
| MD5 |
727ed94ed9c530a27e568029a1f6f78b
|
|
| BLAKE2b-256 |
361f07f944b1416197dcb66ad87a586c2f5229490732534ccc2d509bc4185cf4
|
File details
Details for the file luxy-0.0.6-py3-none-any.whl.
File metadata
- Download URL: luxy-0.0.6-py3-none-any.whl
- Upload date:
- Size: 12.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2bd05372e0b47f10976fb03e4bee388f18df3f419b8eed4bf7cf22fc54e90a5e
|
|
| MD5 |
d3ac7ea1d97ea597b01d26f0318cf967
|
|
| BLAKE2b-256 |
38778ca018ac499a984cb15731d3d1df5eecb6b67f302dc411b47d7763e608cf
|