A Python wrapper for interfacing with Cobalt, open data APIs and datasets for the University of Toronto.
- Install through
pip
.
pip install cobaltuoft
- Install via source (download from here).
$ git clone https://github.com/kshvmdn/cobalt-uoft-python.git
$ cd cobalt-uoft-python && pip install -r ./requirements.txt
-
Directly interface with Cobalt APIs. Data is returned as a
Response
object. -
Initialize the class (a Cobalt API key is required, get one here).
>>> from cobaltuoft import Cobalt >>> cobalt = Cobalt(api_key='API_KEY')
-
Each active API can be accessed through a method of the same name. These methods have two optional parameters:
-
endpoint
– The endpoint to be accessed for the respective API. Any of the following values are accepted (for most of the APIs, refer to the docs for exceptions): -
params
– The URL parameters for this query. Accepts adict
of key-value pairs. Any of the following keys are accepted (read more about these parameters here):Parameter Endpoints Description limit
All except show
The number of results to return. skip
All except show
The number of results to skip. sort
All except show
The sorting procedure to be used on the returned list. q
search
orfilter
The search or filter query. For filter queries, refer to this. id
/date
show
The :id
or:date
value.
-
-
-
When using
filter
, theq
parameter can either be a Cobalt-filter string or a nested list of key-value pairs. -
Outer lists are joined by
"AND"
and inner lists are joined by"OR"
. Use atuple
for the key-value pair. -
You can use
Cobalt._process_filter
to test your filters. -
Here are some examples:
-
'instructor:"D Liu" AND level:<=200'
>>> [ ... [('instructor', '"D Liu"')], ... [('level', '<=200')] ... ]
-
'breadth:!2 OR code:"CSC"'
>>> [ ... [('breadth', '!2'), ('code', '"CSC"')] ... ]
-
instructor:"D Liu" AND level:<=200 AND 'breadth:!2 OR code:"CSC"'
>>> [ ... [('instructor', '"D Liu"')], ... [('level', '<=200')], ... [('breadth', '!2'), ('code', '"CSC"')] ... ]
-
-
-
Interface with full Cobalt datasets. Data is returned as a
Response
object. -
This class doesn't need to be instantiated, instead call it's methods directly.
-
Datasets.run()
Parameter Type Description tag
str
The release tag to request data for. Defaults to 'latest'
.datasets
`str [str]`
- The response object for each of the request modules.
Attribute | Type | Description |
---|---|---|
data |
`dict | [dict] |
error |
`dict | None` |
url |
str |
The request URL with query parameters. |
- More detailed examples can be found here.
from cobaltuoft import Cobalt
cobalt = Cobalt(api_key='API_KEY')
>>> courses = cobalt.courses(params={'skip': 10})
>>> courses
<class 'cobaltuoft.response.Response'>
>>> courses.error
None
>>> courses.data
[..., {...}]
>>> courses.url
'http://cobalt.qas.im/api/1.0/courses?skip=10&key={KEY}'
>>> building_134 = cobalt.buildings(endpoint='search', params={'id': 134})
>>> building_134.error
None
>>> building_134.data
{...} # not a list!
>>> building_134.url
'http://cobalt.qas.im/api/1.0/buildings/134?key={KEY}'
>>> building_1738 = cobalt.buildings(endpoint='search', params={'id': 1738})
>>> building_1738.error
{
'status_code': 400,
'message': 'A building with the specified identifier does not exist.'
}
>>> building_1738.data
None
>>> building_1738.url
'http://cobalt.qas.im/api/1.0/buildings/1738?key={KEY}'
>>> food = cobalt.food(endpoint='search', params={
... 'q': '"pizza"',
... 'limit': 2
... })
>>> food.error
None
>>> food.data
[{...}, {...}]
>>> food.url
'http://cobalt.qas.im/api/1.0/food/search?q="pizza"&limit=2&key={KEY}'
>>> textbooks = cobalt.textbooks(endpoint='filter', params={
... 'q': [
... [
... ('price', '>=500'),
... ('author', '"Queen"')
... ]
... ] # equivalent to 'q': 'price:>=500 OR author:"Queen"'
... })
>>> textbooks.error
None
>>> textbooks.data
[..., {...}]
>>> textbooks.url
'http://cobalt.qas.im/api/1.0/textbooks/filter?q=price:>=500 OR author="Queen"&key={KEY}'
from cobaltuoft import Datasets
>>> latest_datasets = Datasets.run(tag='latest', datasets='*')
>>> latest_datasets.error
None # the GitHub API only allows 60 requests per hour, this will be non-None after you hit that limit.
>>> latest_datasets.data
{
...,
'courses': [..., {...}],
'athletics': [..., {...}]
}
>>> courses_2015 = Datasets.run(tag='2015-2016', datasets='courses')
>>> courses_2015.data
{
'courses': [..., {...}]
}
>>> courses_2015.url
None # Datasets responses don't have a `url` attribute!
>>> datasets = Datasets.run(datasets=['athletics', 'shuttles', 'parking', 'libraries'])
>>> import json
>>> with open('datasets.json', 'w') as f:
... f.write(json.dumps(datasets.data, indent=2))
# https://gist.github.com/kshvmdn/6103bab0ff86fbc904b27c8072a32a2b
This project is completely open source. Feel free to open an issue for questions/requests or submit a pull request.
-
Clone the project.
git clone https://github.com/kshvmdn/cobalt-uoft-python.git && cd cobalt-uoft-python
-
Install requirements.
pip install -r ./requirements.txt