hakai_api 1.5.2__tar.gz → 2.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hakai_api-1.5.2 → hakai_api-2.0.1}/.github/workflows/release.yaml +2 -0
- {hakai_api-1.5.2 → hakai_api-2.0.1}/.gitignore +4 -0
- {hakai_api-1.5.2 → hakai_api-2.0.1}/.pre-commit-config.yaml +12 -7
- hakai_api-2.0.1/CONTRIBUTING.md +202 -0
- {hakai_api-1.5.2 → hakai_api-2.0.1}/LICENSE +1 -1
- hakai_api-2.0.1/PKG-INFO +203 -0
- hakai_api-1.5.2/PKG-INFO → hakai_api-2.0.1/README.md +87 -23
- hakai_api-2.0.1/example.py +14 -0
- hakai_api-2.0.1/pyproject.toml +81 -0
- hakai_api-2.0.1/src/hakai_api/__init__.py +24 -0
- hakai_api-2.0.1/src/hakai_api/auth/__init__.py +7 -0
- hakai_api-2.0.1/src/hakai_api/auth/base.py +256 -0
- hakai_api-2.0.1/src/hakai_api/auth/desktop.py +263 -0
- hakai_api-2.0.1/src/hakai_api/auth/desktop_callback.html +94 -0
- hakai_api-2.0.1/src/hakai_api/auth/web.py +94 -0
- hakai_api-2.0.1/src/hakai_api/client.py +390 -0
- hakai_api-2.0.1/tests/test_auth_strategies.py +464 -0
- hakai_api-2.0.1/tests/test_backwards_compatability.py +344 -0
- hakai_api-2.0.1/tests/test_client.py +600 -0
- hakai_api-2.0.1/uv.lock +758 -0
- hakai_api-1.5.2/CONTRIBUTING.md +0 -99
- hakai_api-1.5.2/README.md +0 -110
- hakai_api-1.5.2/example.py +0 -14
- hakai_api-1.5.2/pyproject.toml +0 -28
- hakai_api-1.5.2/src/hakai_api/Client.py +0 -168
- hakai_api-1.5.2/src/hakai_api/__init__.py +0 -3
- hakai_api-1.5.2/tests/test_Client.py +0 -184
- hakai_api-1.5.2/uv.lock +0 -566
- {hakai_api-1.5.2 → hakai_api-2.0.1}/.github/workflows/lint.yaml +0 -0
- {hakai_api-1.5.2 → hakai_api-2.0.1}/.github/workflows/test.yaml +0 -0
- {hakai_api-1.5.2 → hakai_api-2.0.1}/CODEOWNERS +0 -0
- {hakai_api-1.5.2 → hakai_api-2.0.1}/tests/__init__.py +0 -0
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
# See https://pre-commit.com for more information
|
|
2
2
|
# See https://pre-commit.com/hooks.html for more hooks
|
|
3
|
+
exclude: ^.*\.lock$
|
|
3
4
|
repos:
|
|
5
|
+
- repo: https://github.com/asottile/pyupgrade
|
|
6
|
+
rev: v3.20.0
|
|
7
|
+
hooks:
|
|
8
|
+
- id: pyupgrade
|
|
4
9
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
10
|
rev: v5.0.0
|
|
6
11
|
hooks:
|
|
12
|
+
- id: check-added-large-files
|
|
13
|
+
- id: check-ast
|
|
14
|
+
- id: check-merge-conflict
|
|
15
|
+
- id: debug-statements
|
|
16
|
+
- id: mixed-line-ending
|
|
7
17
|
- id: trailing-whitespace
|
|
8
18
|
- id: end-of-file-fixer
|
|
9
|
-
- id: check-yaml
|
|
10
|
-
- id: check-added-large-files
|
|
11
19
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
12
|
-
|
|
13
|
-
rev: v0.11.9
|
|
20
|
+
rev: v0.12.3
|
|
14
21
|
hooks:
|
|
15
|
-
|
|
16
|
-
- id: ruff
|
|
22
|
+
- id: ruff-check
|
|
17
23
|
args: [ --fix ]
|
|
18
|
-
# Run the formatter.
|
|
19
24
|
- id: ruff-format
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
This document describes how to set up a development environment for this project, modify
|
|
4
|
+
and test the code, and deploy a new version.
|
|
5
|
+
|
|
6
|
+
<details>
|
|
7
|
+
|
|
8
|
+
<summary>Table of Contents</summary>
|
|
9
|
+
|
|
10
|
+
[Project structure](#project-structure)
|
|
11
|
+
|
|
12
|
+
[Configuration](#configuration)
|
|
13
|
+
|
|
14
|
+
[Tests](#tests)
|
|
15
|
+
- [Running Tests](#running-tests)
|
|
16
|
+
- [Authentication Flow Testing](#authentication-flow-testing)
|
|
17
|
+
- [Linting and Formatting](#linting-and-formatting)
|
|
18
|
+
- [Environment Variables for Testing](#environment-variables-for-testing)
|
|
19
|
+
|
|
20
|
+
[Deployment](#deployment)
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
## Project structure
|
|
25
|
+
|
|
26
|
+
The business logic for this package is located
|
|
27
|
+
in [`src/hakai_api/client.py`](src/hakai_api/client.py).
|
|
28
|
+
All tests are located in the `tests/` directory.
|
|
29
|
+
|
|
30
|
+
Key components:
|
|
31
|
+
- `client.py` - Main OAuth2Session client with authentication flows
|
|
32
|
+
- `auth/` - Authentication strategies (web and desktop flows)
|
|
33
|
+
- `tests/` - Comprehensive test suite including authentication flow tests
|
|
34
|
+
|
|
35
|
+
## Configuration
|
|
36
|
+
|
|
37
|
+
### uv
|
|
38
|
+
|
|
39
|
+
This project uses [uv](https://github.com/astral-sh/uv) for dependency management and
|
|
40
|
+
package installation. Install `uv` using the instructions on their website before continuing.
|
|
41
|
+
|
|
42
|
+
To set up an environment for development, clone this repository and run the following
|
|
43
|
+
commands from the root directory of the repository:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Install the package and its dependencies (uv handles virtual environment automatically)
|
|
47
|
+
uv sync
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Pre-commit
|
|
51
|
+
|
|
52
|
+
This project uses [pre-commit](https://pre-commit.com/) to run lint checks and tests
|
|
53
|
+
before every commit. To install the pre-commit hooks, run the following command from the
|
|
54
|
+
root directory of the repository while the virtual environment is active:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pre-commit install
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
This is highly recommended and will prevent failed builds on GitHub Actions, as well as
|
|
61
|
+
ensure consistent code style and quality.
|
|
62
|
+
|
|
63
|
+
You can also run the pre-commit hooks manually on all files by running:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
pre-commit run -a
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Tests
|
|
70
|
+
|
|
71
|
+
Tests and lint checks are automatically run on pull requests and pushes to the main
|
|
72
|
+
branch using GitHub Actions.
|
|
73
|
+
|
|
74
|
+
### Running Tests
|
|
75
|
+
|
|
76
|
+
To run the tests locally:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Run all tests
|
|
80
|
+
pytest
|
|
81
|
+
|
|
82
|
+
# Run a specific test file
|
|
83
|
+
pytest tests/test_client.py
|
|
84
|
+
|
|
85
|
+
# Run a specific test function
|
|
86
|
+
pytest tests/test_client.py::test_get_valid_credentials_from_file
|
|
87
|
+
|
|
88
|
+
# Run tests with verbose output
|
|
89
|
+
pytest -v
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Authentication Flow Testing
|
|
93
|
+
|
|
94
|
+
The project includes comprehensive tests for both authentication flows:
|
|
95
|
+
|
|
96
|
+
- **Web flow tests**: Test credential parsing, file operations, and web-based authentication
|
|
97
|
+
- **Desktop flow tests**: Test OAuth2 with PKCE flow, token refresh, and callback handling
|
|
98
|
+
- **Mock tests**: Most tests use mocked authentication to avoid requiring real credentials
|
|
99
|
+
|
|
100
|
+
When adding new authentication features, ensure you add appropriate tests for both flows.
|
|
101
|
+
|
|
102
|
+
#### Web Authentication Flow
|
|
103
|
+
|
|
104
|
+
The web flow requires users to manually copy credentials from a browser:
|
|
105
|
+
|
|
106
|
+
```mermaid
|
|
107
|
+
sequenceDiagram
|
|
108
|
+
participant User
|
|
109
|
+
participant Client
|
|
110
|
+
participant Browser
|
|
111
|
+
participant API
|
|
112
|
+
|
|
113
|
+
User->>Client: Create Client()
|
|
114
|
+
Client->>Client: Check cached credentials
|
|
115
|
+
alt No valid cached credentials
|
|
116
|
+
Client->>User: Display login URL
|
|
117
|
+
User->>Browser: Open login URL
|
|
118
|
+
Browser->>API: User logs in
|
|
119
|
+
API->>Browser: Display credentials token
|
|
120
|
+
Browser->>User: Show credentials token
|
|
121
|
+
User->>Client: Copy/paste credentials
|
|
122
|
+
Client->>Client: Parse and validate credentials
|
|
123
|
+
Client->>Client: Cache credentials to file
|
|
124
|
+
end
|
|
125
|
+
Client->>API: Make authenticated request
|
|
126
|
+
API->>Client: Return response
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### Desktop Authentication Flow (OAuth2 with PKCE)
|
|
130
|
+
|
|
131
|
+
The desktop flow uses OAuth2 with PKCE for more secure authentication:
|
|
132
|
+
|
|
133
|
+
```mermaid
|
|
134
|
+
sequenceDiagram
|
|
135
|
+
participant User
|
|
136
|
+
participant Client
|
|
137
|
+
participant LocalServer
|
|
138
|
+
participant Browser
|
|
139
|
+
participant API
|
|
140
|
+
|
|
141
|
+
User->>Client: Create Client(auth_flow="desktop")
|
|
142
|
+
Client->>Client: Check cached credentials
|
|
143
|
+
alt No valid cached credentials
|
|
144
|
+
Client->>Client: Generate PKCE code_verifier & code_challenge
|
|
145
|
+
Client->>LocalServer: Start local callback server
|
|
146
|
+
Client->>Browser: Open OAuth URL with PKCE params
|
|
147
|
+
Browser->>API: User logs in and authorizes
|
|
148
|
+
API->>Browser: Redirect to local callback with auth code
|
|
149
|
+
Browser->>LocalServer: Send auth code
|
|
150
|
+
LocalServer->>Client: Receive auth code
|
|
151
|
+
Client->>API: Exchange auth code + code_verifier for tokens
|
|
152
|
+
API->>Client: Return access_token & refresh_token
|
|
153
|
+
Client->>Client: Cache credentials to file
|
|
154
|
+
Client->>LocalServer: Shutdown callback server
|
|
155
|
+
end
|
|
156
|
+
Client->>API: Make authenticated request
|
|
157
|
+
alt Token expired
|
|
158
|
+
Client->>API: Use refresh_token to get new access_token
|
|
159
|
+
API->>Client: Return new access_token
|
|
160
|
+
Client->>Client: Update cached credentials
|
|
161
|
+
end
|
|
162
|
+
API->>Client: Return response
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Linting and Formatting
|
|
166
|
+
|
|
167
|
+
To run lint checks locally:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
ruff check .
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
To automatically fix linting issues:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
ruff check --fix .
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
To automatically format the code:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
ruff format .
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Environment Variables for Testing
|
|
186
|
+
|
|
187
|
+
Some tests may require environment variables:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# Optional: Set custom user agent for testing
|
|
191
|
+
export HAKAI_API_USER_AGENT="test-client/1.0"
|
|
192
|
+
|
|
193
|
+
# Optional: Set custom credentials file location
|
|
194
|
+
export HAKAI_API_CREDENTIALS="/tmp/test-credentials"
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Deployment
|
|
198
|
+
|
|
199
|
+
To build and deploy a new PyPi package version, push a tag matching the
|
|
200
|
+
pattern `v[0-9]+.[0-9]+.[0-9]+` or `v[0-9]+.[0-9]+.[0-9]+rc[0-9]+` (e.g. `v0.4.1`
|
|
201
|
+
or `v0.5.2rc1`) to GitHub. GitHub Actions will take care of packaging and pushing it
|
|
202
|
+
to Hakai's PyPi repository from there.
|
hakai_api-2.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hakai_api
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: Get Hakai database resources using http calls
|
|
5
|
+
Author-email: Taylor Denouden <taylor.denouden@hakai.org>, Chris Davis <chris.davis@hakai.org>, Nate Rosenstock <nate.rosenstock@hakai.org>, Sam Albers <sam.albers@hakai.org>
|
|
6
|
+
Maintainer-email: Taylor Denouden <taylor.denouden@hakai.org>, Sam Albers <sam.albers@hakai.org>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Python: >=3.8
|
|
10
|
+
Requires-Dist: loguru>=0.7.3
|
|
11
|
+
Requires-Dist: pkce>=1.0.3
|
|
12
|
+
Requires-Dist: pytz>=2025.2
|
|
13
|
+
Requires-Dist: requests-oauthlib>=2.0.0
|
|
14
|
+
Requires-Dist: requests>=2.32.3
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# Hakai Api Python Client
|
|
18
|
+
|
|
19
|
+
This project exports a single Python class that can be used to make HTTP requests to the
|
|
20
|
+
Hakai API resource server.
|
|
21
|
+
The exported `Client` class extends the functionality of the
|
|
22
|
+
Python [requests library](https://docs.python-requests.org/en/master/) to supply Hakai
|
|
23
|
+
OAuth2 credentials with url requests.
|
|
24
|
+
|
|
25
|
+
 [](https://github.com/HakaiInstitute/hakai-api-client-py/actions/workflows/test.yaml) [](https://opensource.org/licenses/MIT)
|
|
26
|
+
|
|
27
|
+
<details>
|
|
28
|
+
|
|
29
|
+
<summary>Table of Contents</summary>
|
|
30
|
+
|
|
31
|
+
[Installation](#installation)
|
|
32
|
+
|
|
33
|
+
[Quickstart](#quickstart)
|
|
34
|
+
- [Desktop OAuth Flow](#desktop-oauth-flow)
|
|
35
|
+
- [User Agent Configuration](#user-agent-configuration)
|
|
36
|
+
|
|
37
|
+
[Methods](#methods)
|
|
38
|
+
|
|
39
|
+
[API endpoints](#api-endpoints)
|
|
40
|
+
|
|
41
|
+
[Advanced usage](#advanced-usage)
|
|
42
|
+
- [Custom API Endpoints](#custom-api-endpoints)
|
|
43
|
+
- [Relative Endpoint Support](#relative-endpoint-support)
|
|
44
|
+
- [Credentials Configuration](#credentials-configuration)
|
|
45
|
+
|
|
46
|
+
[Contributing](#contributing)
|
|
47
|
+
|
|
48
|
+
</details>
|
|
49
|
+
|
|
50
|
+
# Installation
|
|
51
|
+
|
|
52
|
+
Python 3.8 or higher is required. Install with pip:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install hakai-api
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
# Quickstart
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
from hakai_api import Client
|
|
62
|
+
|
|
63
|
+
# Get the api request client
|
|
64
|
+
client = Client() # Follow stdout prompts to get an API token
|
|
65
|
+
|
|
66
|
+
# Make a data request for chlorophyll data (using relative endpoint)
|
|
67
|
+
response = client.get('/eims/views/output/chlorophyll?limit=50')
|
|
68
|
+
|
|
69
|
+
print(response.json())
|
|
70
|
+
# [{'action': '', 'event_pk': 7064, 'rn': '1', 'date': '2012-05-17', 'work_area': 'CALVERT'...
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Desktop OAuth Flow
|
|
74
|
+
|
|
75
|
+
For native applications and automated scripts, use the desktop OAuth flow with PKCE:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from hakai_api import Client
|
|
79
|
+
|
|
80
|
+
# Use desktop OAuth flow (opens browser, more secure)
|
|
81
|
+
client = Client(auth_flow="desktop")
|
|
82
|
+
|
|
83
|
+
# Or use the factory method
|
|
84
|
+
client = Client.create_desktop_client()
|
|
85
|
+
|
|
86
|
+
# Make requests using relative endpoints
|
|
87
|
+
response = client.get('/eims/views/output/stations')
|
|
88
|
+
print(response.json())
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## User Agent Configuration
|
|
92
|
+
|
|
93
|
+
**Important**: Set a descriptive user agent to help identify your application on the backend. Often the repository url is a good way to identify yourself:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from hakai_api import Client
|
|
97
|
+
import os
|
|
98
|
+
|
|
99
|
+
# Set user agent during initialization
|
|
100
|
+
client = Client(user_agent="MyApp/1.0 (contact@example.com)")
|
|
101
|
+
|
|
102
|
+
# Or set via environment variable
|
|
103
|
+
os.environ['HAKAI_API_USER_AGENT'] = "MyApp/1.0 (contact@example.com)"
|
|
104
|
+
client = Client()
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
# Methods
|
|
108
|
+
|
|
109
|
+
This library exports a single client name `Client`. Instantiating this class produces
|
|
110
|
+
a `requests.Session` client from the Python requests library. The Hakai API Python
|
|
111
|
+
Client inherits directly from `requests.Session` thus all methods available on that
|
|
112
|
+
parent class are available. For details see
|
|
113
|
+
the [requests documentation](http://docs.python-requests.org/).
|
|
114
|
+
|
|
115
|
+
The hakai_api `Client` class also contains a property `api_root` which is useful for
|
|
116
|
+
constructing urls to access data from the API. The
|
|
117
|
+
above [Quickstart example](#quickstart) demonstrates using this property to construct a
|
|
118
|
+
url to access project names.
|
|
119
|
+
|
|
120
|
+
# API endpoints
|
|
121
|
+
|
|
122
|
+
For details about the API, including available endpoints where data can be requested
|
|
123
|
+
from, see the [Hakai API documentation](https://github.com/HakaiInstitute/hakai-api).
|
|
124
|
+
|
|
125
|
+
# Advanced usage
|
|
126
|
+
|
|
127
|
+
## Custom API Endpoints
|
|
128
|
+
|
|
129
|
+
You can specify which API to access when instantiating the Client. By default, the API
|
|
130
|
+
uses `https://portal.hakai.org/api` as the API root. It may be useful to use this
|
|
131
|
+
library to access a locally running API instance or to access the Goose API for testing
|
|
132
|
+
purposes. If you are always going to be accessing data from a locally running API
|
|
133
|
+
instance, you are better off using the requests.py library directly since Authorization
|
|
134
|
+
is not required for local requests.
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from hakai_api import Client
|
|
138
|
+
|
|
139
|
+
# Get a client for a locally running API instance
|
|
140
|
+
client = Client("http://localhost:8666")
|
|
141
|
+
print(client.api_root) # http://localhost:8666
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## Relative Endpoint Support
|
|
145
|
+
|
|
146
|
+
The client supports relative endpoints that automatically prepend the API root:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from hakai_api import Client
|
|
150
|
+
|
|
151
|
+
client = Client()
|
|
152
|
+
|
|
153
|
+
# These are equivalent:
|
|
154
|
+
response1 = client.get('/eims/views/output/stations')
|
|
155
|
+
response2 = client.get('https://portal.hakai.org/api/eims/views/output/stations')
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Credentials Configuration
|
|
159
|
+
|
|
160
|
+
### Direct Credentials
|
|
161
|
+
|
|
162
|
+
You can pass in the credentials string retrieved from the hakai API login page
|
|
163
|
+
while initiating the Client class.
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from hakai_api import Client
|
|
167
|
+
|
|
168
|
+
# Pass a credentials token as the Client Class is initiated
|
|
169
|
+
client = Client(credentials="CREDENTIAL_TOKEN")
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Environment Variables
|
|
173
|
+
|
|
174
|
+
Set credentials using the `HAKAI_API_CREDENTIALS` environment variable. This is useful
|
|
175
|
+
for e.g. setting credentials in a docker container. The value of the environment variable
|
|
176
|
+
should be the credentials token retrieved from the Hakai API login page.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
export HAKAI_API_CREDENTIALS="your_credential_token_here"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Custom Credentials File Location
|
|
183
|
+
|
|
184
|
+
By default, credentials are saved to `~/.hakai-api-auth`. You can customize this location:
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
from hakai_api import Client
|
|
188
|
+
|
|
189
|
+
# Set custom credentials file path
|
|
190
|
+
client = Client(credentials_file="/path/to/my/credentials")
|
|
191
|
+
|
|
192
|
+
# Or use environment variable
|
|
193
|
+
# export HAKAI_API_CREDENTIALS="/path/to/my/credentials"
|
|
194
|
+
client = Client()
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
# Contributing
|
|
198
|
+
|
|
199
|
+
See [CONTRIBUTING](CONTRIBUTING.md)
|
|
200
|
+
|
|
201
|
+
# License
|
|
202
|
+
|
|
203
|
+
See [LICENSE](LICENSE.md)
|
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: hakai_api
|
|
3
|
-
Version: 1.5.2
|
|
4
|
-
Summary: Get Hakai database resources using http calls
|
|
5
|
-
Author-email: Taylor Denouden <taylor.denouden@hakai.org>
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
License-File: LICENSE
|
|
8
|
-
Requires-Python: >=3.8
|
|
9
|
-
Requires-Dist: pytz>=2025.2
|
|
10
|
-
Requires-Dist: requests-oauthlib>=2.0.0
|
|
11
|
-
Requires-Dist: requests>=2.32.3
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
|
|
14
1
|
# Hakai Api Python Client
|
|
15
2
|
|
|
16
3
|
This project exports a single Python class that can be used to make HTTP requests to the
|
|
@@ -28,12 +15,17 @@ OAuth2 credentials with url requests.
|
|
|
28
15
|
[Installation](#installation)
|
|
29
16
|
|
|
30
17
|
[Quickstart](#quickstart)
|
|
18
|
+
- [Desktop OAuth Flow](#desktop-oauth-flow)
|
|
19
|
+
- [User Agent Configuration](#user-agent-configuration)
|
|
31
20
|
|
|
32
21
|
[Methods](#methods)
|
|
33
22
|
|
|
34
23
|
[API endpoints](#api-endpoints)
|
|
35
24
|
|
|
36
25
|
[Advanced usage](#advanced-usage)
|
|
26
|
+
- [Custom API Endpoints](#custom-api-endpoints)
|
|
27
|
+
- [Relative Endpoint Support](#relative-endpoint-support)
|
|
28
|
+
- [Credentials Configuration](#credentials-configuration)
|
|
37
29
|
|
|
38
30
|
[Contributing](#contributing)
|
|
39
31
|
|
|
@@ -55,15 +47,47 @@ from hakai_api import Client
|
|
|
55
47
|
# Get the api request client
|
|
56
48
|
client = Client() # Follow stdout prompts to get an API token
|
|
57
49
|
|
|
58
|
-
# Make a data request for chlorophyll data
|
|
59
|
-
|
|
60
|
-
response = client.get(url)
|
|
50
|
+
# Make a data request for chlorophyll data (using relative endpoint)
|
|
51
|
+
response = client.get('/eims/views/output/chlorophyll?limit=50')
|
|
61
52
|
|
|
62
|
-
print(url) # https://hecate.hakai.org/api/eims/views/output/chlorophyll...
|
|
63
53
|
print(response.json())
|
|
64
54
|
# [{'action': '', 'event_pk': 7064, 'rn': '1', 'date': '2012-05-17', 'work_area': 'CALVERT'...
|
|
65
55
|
```
|
|
66
56
|
|
|
57
|
+
## Desktop OAuth Flow
|
|
58
|
+
|
|
59
|
+
For native applications and automated scripts, use the desktop OAuth flow with PKCE:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from hakai_api import Client
|
|
63
|
+
|
|
64
|
+
# Use desktop OAuth flow (opens browser, more secure)
|
|
65
|
+
client = Client(auth_flow="desktop")
|
|
66
|
+
|
|
67
|
+
# Or use the factory method
|
|
68
|
+
client = Client.create_desktop_client()
|
|
69
|
+
|
|
70
|
+
# Make requests using relative endpoints
|
|
71
|
+
response = client.get('/eims/views/output/stations')
|
|
72
|
+
print(response.json())
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## User Agent Configuration
|
|
76
|
+
|
|
77
|
+
**Important**: Set a descriptive user agent to help identify your application on the backend. Often the repository url is a good way to identify yourself:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from hakai_api import Client
|
|
81
|
+
import os
|
|
82
|
+
|
|
83
|
+
# Set user agent during initialization
|
|
84
|
+
client = Client(user_agent="MyApp/1.0 (contact@example.com)")
|
|
85
|
+
|
|
86
|
+
# Or set via environment variable
|
|
87
|
+
os.environ['HAKAI_API_USER_AGENT'] = "MyApp/1.0 (contact@example.com)"
|
|
88
|
+
client = Client()
|
|
89
|
+
```
|
|
90
|
+
|
|
67
91
|
# Methods
|
|
68
92
|
|
|
69
93
|
This library exports a single client name `Client`. Instantiating this class produces
|
|
@@ -84,8 +108,10 @@ from, see the [Hakai API documentation](https://github.com/HakaiInstitute/hakai-
|
|
|
84
108
|
|
|
85
109
|
# Advanced usage
|
|
86
110
|
|
|
111
|
+
## Custom API Endpoints
|
|
112
|
+
|
|
87
113
|
You can specify which API to access when instantiating the Client. By default, the API
|
|
88
|
-
uses `https://
|
|
114
|
+
uses `https://portal.hakai.org/api` as the API root. It may be useful to use this
|
|
89
115
|
library to access a locally running API instance or to access the Goose API for testing
|
|
90
116
|
purposes. If you are always going to be accessing data from a locally running API
|
|
91
117
|
instance, you are better off using the requests.py library directly since Authorization
|
|
@@ -99,7 +125,25 @@ client = Client("http://localhost:8666")
|
|
|
99
125
|
print(client.api_root) # http://localhost:8666
|
|
100
126
|
```
|
|
101
127
|
|
|
102
|
-
|
|
128
|
+
## Relative Endpoint Support
|
|
129
|
+
|
|
130
|
+
The client supports relative endpoints that automatically prepend the API root:
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from hakai_api import Client
|
|
134
|
+
|
|
135
|
+
client = Client()
|
|
136
|
+
|
|
137
|
+
# These are equivalent:
|
|
138
|
+
response1 = client.get('/eims/views/output/stations')
|
|
139
|
+
response2 = client.get('https://portal.hakai.org/api/eims/views/output/stations')
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Credentials Configuration
|
|
143
|
+
|
|
144
|
+
### Direct Credentials
|
|
145
|
+
|
|
146
|
+
You can pass in the credentials string retrieved from the hakai API login page
|
|
103
147
|
while initiating the Client class.
|
|
104
148
|
|
|
105
149
|
```python
|
|
@@ -109,10 +153,30 @@ from hakai_api import Client
|
|
|
109
153
|
client = Client(credentials="CREDENTIAL_TOKEN")
|
|
110
154
|
```
|
|
111
155
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
156
|
+
### Environment Variables
|
|
157
|
+
|
|
158
|
+
Set credentials using the `HAKAI_API_CREDENTIALS` environment variable. This is useful
|
|
159
|
+
for e.g. setting credentials in a docker container. The value of the environment variable
|
|
160
|
+
should be the credentials token retrieved from the Hakai API login page.
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
export HAKAI_API_CREDENTIALS="your_credential_token_here"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Custom Credentials File Location
|
|
167
|
+
|
|
168
|
+
By default, credentials are saved to `~/.hakai-api-auth`. You can customize this location:
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from hakai_api import Client
|
|
172
|
+
|
|
173
|
+
# Set custom credentials file path
|
|
174
|
+
client = Client(credentials_file="/path/to/my/credentials")
|
|
175
|
+
|
|
176
|
+
# Or use environment variable
|
|
177
|
+
# export HAKAI_API_CREDENTIALS="/path/to/my/credentials"
|
|
178
|
+
client = Client()
|
|
179
|
+
```
|
|
116
180
|
|
|
117
181
|
# Contributing
|
|
118
182
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""An example showing how to use the Hakai Api Python Client."""
|
|
2
|
+
|
|
3
|
+
from hakai_api import Client
|
|
4
|
+
|
|
5
|
+
if __name__ == "__main__":
|
|
6
|
+
# WEB FLOW (default)
|
|
7
|
+
client = Client()
|
|
8
|
+
response = client.get(f"{client.api_root}/whoami")
|
|
9
|
+
print(response.json())
|
|
10
|
+
|
|
11
|
+
# DESKTOP FLOW
|
|
12
|
+
client = Client(auth_flow="desktop") # Follow the prompts in the webpage that opens
|
|
13
|
+
response = client.get("/whoami")
|
|
14
|
+
print(response.json())
|