Interact with CanLII programmatically
Project description
Call CanLii
CanLii is an indispensable research tool for lawyers, law students, judges, adjudicators, and researchers. Largely funded by Canadian lawyers, it is the international gold standard when it comes to the free and open access to law.
With an intuitive and beautiful interface, researchers use CanLii to look up an individual case or statute, read it, see what cites it, and see what it cites.
Some legal researchers and social scientists require bulk access to legal data for their projects. Fortunately, CanLii provides an API that allows (limited) programmatic access to its databases. Too few legal researchers, however, know how to use and interact with APIs.
This library’s purpose is simple: make it easier to use CanLii’s APIs. More than that, I demonstrate how easy it is to use code to facilitate aspects of legal research. Use the library, but look at its source code and see if it inspires you to do more. You can do this!
Install
pip install canliicalls
or
conda install canliicalls
then:
from canliicalls.caller import *
Usage
Get and use your secret API key
To use CanLii’s API, you need your own secret access key. Applying for a key is simple. Just send a request through the Canlii feedback form.
Once you have your API key, the rest is easy. First, enter your secret API key and, second, enter your preferred language (‘en’ or ‘fr’). Then call the object.
api = 'MY SECRET API KEY' #this will look like lots of numbers and letters
language = 'en'
my_caller = Caller(api, language)
A sample research project
To see how to use the library, let’s do a simple research project and figure out what statutes a recent Supreme Court of Canada case cites to. To do this, we need to figure out where CanLii stores the case and the case name.
Lookup CanLii database names
First, let’s get a list of CanLii database names.
my_caller.list_tribunals()
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
databaseId | jurisdiction | name | |
---|---|---|---|
0 | qccdoooq | qc | Conseil de discipline de l'Ordre des opticiens... |
1 | qcoaciq | qc | Comité de discipline de l'organisme d'autorégl... |
2 | skqb | sk | Court of King's Bench for Saskatchewan |
3 | onsc | on | Superior Court of Justice |
4 | abmgb | ab | Alberta Municipal Government Board |
... | ... | ... | ... |
357 | ytrto | yk | Yukon Residential Tenancies Office |
358 | nbsec | nb | Financial and Consumer Services Tribunal |
359 | onbcc | on | Building Code Commission |
360 | exchc-cech | ca | Exchequer Court of Canada |
361 | nttc | nt | Territorial Court of the Northwest Territories |
362 rows × 3 columns
We can do a few things from here. First, if you want to save this as an excel or a csv file, that’s easy!
my_caller.list_tribunals().to_csv('CanLii_tribunal_list.csv')
Or you can search directly for the Supreme Court of Canada’s database ID.
df = my_caller.list_tribunals()
df[df['name'] == 'Supreme Court of Canada']
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
databaseId | jurisdiction | name | |
---|---|---|---|
90 | csc-scc | ca | Supreme Court of Canada |
Find recent decisions by the SCC
Great! Now that we have the database ID for SCC cases, we can zero in on a recent case. To list individual cases from the database, we call a different function.
This function has a few paramaters. You can decide whether you want the results in ascending or descending chronological order (defaults to descending) and how many results you want the API to return (defaults to 100).
my_caller.list_decisions(databaseId='csc-scc', offset=0, resultCount=10)
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
caseId | title | citation | |
---|---|---|---|
0 | 2022scc34 | R. v. Schneider | 2022 SCC 34 (CanLII) |
1 | 2022scc33 | R. v. Kirkpatrick | 2022 SCC 33 (CanLII) |
2 | 2022scc32 | R. v. Lafrance | 2022 SCC 32 (CanLII) |
3 | 2022scc31 | R. v. Sundman | 2022 SCC 31 (CanLII) |
4 | 2022scc30 | Society of Composers, Authors and Music Publis... | 2022 SCC 30 (CanLII) |
5 | 2022scc29 | Law Society of Saskatchewan v. Abrametz | 2022 SCC 29 (CanLII) |
6 | 2022scc28 | R. v. J.J. | 2022 SCC 28 (CanLII) |
7 | 2022scc27 | British Columbia (Attorney General) v. Council... | 2022 SCC 27 (CanLII) |
8 | 2022scc26 | Canada (Attorney General) v. Collins Family Trust | 2022 SCC 26 (CanLII) |
9 | 2022scc25 | R. v. Goforth | 2022 SCC 25 (CanLII) |
Search for case metadata
We can look up the metadata for any case. Let’s see what the fifth case down is about.
my_caller.case_metadata(databaseId='csc-scc', caseId='2022scc30')
databaseId csc-scc
caseId 2022scc30
url https://canlii.ca/t/jqgw0
title Society of Composers, Authors and Music Publis...
citation 2022 SCC 30 (CanLII)
language en
docketNumber 39418
decisionDate 2022-07-15
keywords technological neutrality — available for on-de...
topics
concatenatedId 2022csc-scc30
dtype: object
Check to see what legislation the Court cites
Interesting! This case is interesting, I wonder what statutory provisions in cites?
my_caller.case_cites_of_legislation(databaseId='csc-scc', caseId='2022scc30')
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
</style>
databaseId | legislationId | title | citation | type | |
---|---|---|---|---|---|
0 | cas | rsc-1985-c-c-42 | Copyright Act | RSC 1985, c C-42 | STATUTE |
1 | caa | sc-2012-c-20 | Copyright Modernization Act | SC 2012, c 20 | ANNUAL_STATUTE |
Only two! Even though the full judgement is long, this looks right.
Using loops
This program is designed to support queries at scale. You can, for example, retrieve all of the keywords for the last ten SCC decisions.
First, request a dataframe of the last ten decisions.
df = my_caller.list_decisions(databaseId='csc-scc', offset=0, resultCount=10)
df
Second, loop over the dataframe and make a separate call for the keywords of each case.
for index,row in df.iterrows():
case = df.loc[index,'caseId']
print(f'Keywords for {case}.')
print(my_caller.case_metadata(databaseId='csc-scc', caseId=case)['keywords'])
print('---')
Keywords for 2022scc34.
brother — overheard — jury — evidence — probative value
---
Keywords for 2022scc33.
stare decisis — sexual activity — precedent — without a condom — sex
---
Keywords for 2022scc32.
police — detainee — detention — interview — encounter
---
Keywords for 2022scc31.
unlawful confinement — degree murder — domination — truck — temporal-causal connection
---
Keywords for 2022scc30.
technological neutrality — available for on-demand streaming — work — royalties — works
---
Keywords for 2022scc29.
abuse — inordinate delay — process — stay — prejudice
---
Keywords for 2022scc28.
record screening regime — complainants — privacy — evidence — defence
---
Keywords for 2022scc27.
well-developed factual setting — public interest standing — access to justice — disabilities — legality
---
Keywords for 2022scc26.
tax — rescission — taxpayer — rectification — mistake
---
Keywords for 2022scc25.
jury — unlawfully causing bodily harm — necessaries — mens rea requirement — marked departure
---
Project details
Release history Release notifications | RSS feed
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
File details
Details for the file canliicalls-0.0.1.tar.gz
.
File metadata
- Download URL: canliicalls-0.0.1.tar.gz
- Upload date:
- Size: 12.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.10.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 403d9769acbb055cce26bacb32be327b0a919c201dcb2e700c02d2f964ab91dc |
|
MD5 | 1b46fbda637b888fd78e3176bda65741 |
|
BLAKE2b-256 | e8ba45ef245cd3a16fe59a3b282df497c98270541e7b307aeb795b0718077fc5 |
File details
Details for the file canliicalls-0.0.1-py3-none-any.whl
.
File metadata
- Download URL: canliicalls-0.0.1-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.10.6
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 55b785c0d408f10ee78f6c815f692e1be04ca84ddc26c430b33362cf4bf5ae24 |
|
MD5 | fddfd77a2cbbd9f3ab81b1badb8ef841 |
|
BLAKE2b-256 | d7edd18389574a01ee6aef53fba2963c3ba5b5d47b287e30971e27384a344c5b |