Skip to content

Commit 6235a38

Browse files
Merge pull request #14 from brainstem-org/python_api_tool_v2
Python api tool v2
2 parents bc595e3 + 4159329 commit 6235a38

11 files changed

Lines changed: 2235 additions & 488 deletions

File tree

.github/workflows/tests.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: tests
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
pull_request:
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
python-version: ["3.8", "3.10", "3.12"]
14+
15+
steps:
16+
- uses: actions/checkout@v4
17+
18+
- uses: actions/setup-python@v5
19+
with:
20+
python-version: ${{ matrix.python-version }}
21+
22+
- name: Install package and dev deps
23+
run: pip install -e ".[dev]"
24+
25+
- name: Run tests
26+
run: pytest --tb=short

README.md

Lines changed: 132 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,154 @@ You can install the package using `pip`:
88
pip install brainstem_python_api_tools
99
```
1010

11+
## Authentication
12+
13+
Authentication uses a **browser-based device authorization flow** that supports two-factor authentication (2FA). No credentials are entered into the tool itself.
14+
15+
```python
16+
from brainstem_api_tools import BrainstemClient
17+
18+
# First run: opens a browser window for secure login.
19+
# The token is cached at ~/.config/brainstem/token and reused automatically.
20+
client = BrainstemClient()
21+
```
22+
23+
To skip the browser flow, pass a token directly:
24+
```python
25+
client = BrainstemClient(token="YOUR_TOKEN")
26+
```
27+
28+
For headless environments (no browser available):
29+
```python
30+
client = BrainstemClient(headless=True) # prints a URL + code to enter manually
31+
```
32+
33+
To connect to a different server (e.g. a local development instance):
34+
```python
35+
client = BrainstemClient(url="http://127.0.0.1:8000/")
36+
```
37+
38+
> **Security note:** The cached token file is stored with owner-read-only permissions (`0600`). Treat it like a password and do not commit it to version control.
39+
1140
## Getting Started
1241
To get started with the BrainSTEM API tools, please refer to the tutorial script provided:
1342

1443
- **Tutorial:** `brainstem_api_tutorial.py`
1544

1645
The tutorial demonstrates how to:
1746

18-
- **Authenticate:** Load the client and authenticate using your credentials.
19-
- **Loading Data:** Load sessions and filter data using flexible options.
20-
- **Updating Entries:** Modify existing models and update them in the database.
21-
- **Creating Entries:** Submit new data entries with required fields.
22-
- **Loading Public Data:** Access public projects and data using the public portal.
47+
- **Authenticate:** Load the client and authenticate via your browser.
48+
- **Load Data:** Load sessions and filter data using flexible options.
49+
- **Paginate:** Retrieve large datasets using `limit` / `offset` or `load_all=True`.
50+
- **Convenience Loaders:** Use `load_session()`, `load_subject()`, etc. for common queries.
51+
- **Update Entries:** Modify existing records and update them in the database.
52+
- **Create Entries:** Submit new data entries with required fields.
53+
- **Delete Entries:** Remove records by ID.
54+
- **Load Public Data:** Access public projects and data using the public portal.
2355

2456
## Example Usage
2557
```python
2658
from brainstem_api_tools import BrainstemClient
2759

2860
client = BrainstemClient()
29-
response = client.load_model('session', sort=['name'])
61+
62+
# Load sessions sorted by name
63+
response = client.load('session', sort=['name'])
3064
print(response.json())
65+
66+
# Filter and include related data
67+
response = client.load(
68+
'session',
69+
filters={'name.icontains': 'Rat'},
70+
sort=['-name'],
71+
include=['projects'],
72+
)
73+
74+
# Paginate results (manual)
75+
page2 = client.load('session', limit=20, offset=20).json()
76+
77+
# Auto-paginate — fetches every page and returns a merged dict
78+
all_sessions = client.load('session', load_all=True)
79+
80+
# Convenience loaders — sensible defaults with named filter kwargs
81+
# load_session embeds dataacquisition, behaviors, manipulations, epochs
82+
sessions = client.load_session(name='Rat', load_all=True)
83+
84+
# load_subject embeds procedures and subjectlogs
85+
subjects = client.load_subject(sex='M', projects='<project-uuid>', load_all=True)
86+
87+
# load_project embeds sessions, subjects, collections, cohorts
88+
projects = client.load_project(name='MyProject')
89+
90+
# load_behavior / load_dataacquisition / load_manipulation scope by session UUID
91+
behaviors = client.load_behavior(session='<session-uuid>', load_all=True)
92+
93+
# load_procedure scopes by subject UUID
94+
procedures = client.load_procedure(subject='<subject-uuid>', load_all=True)
95+
96+
# Create a record
97+
client.save('session', data={'name': 'New session', 'projects': ['<project-uuid>']})
98+
99+
# Update a record
100+
client.save('session', id='<session-uuid>', data={'description': 'updated'})
101+
102+
# Delete a record
103+
client.delete('session', id='<session-uuid>')
104+
```
105+
106+
## Command-line Interface
107+
108+
After installation a `brainstem` command is available in your shell.
109+
110+
### Authentication
111+
```bash
112+
# Authenticate (opens browser) and cache token
113+
brainstem login
114+
115+
# Headless — prints URL + code instead of opening browser
116+
brainstem login --headless
117+
118+
# Connect to a local dev server
119+
brainstem login --url http://127.0.0.1:8000/
120+
121+
# Remove cached token
122+
brainstem logout
123+
```
124+
125+
### Loading data
126+
```bash
127+
# Load all sessions (private portal)
128+
brainstem load session
129+
130+
# Filter, sort and embed related data
131+
brainstem load session --filters name.icontains=Rat --sort -name --include projects
132+
133+
# Load a single record by UUID
134+
brainstem load session --id <uuid>
135+
136+
# Manual pagination
137+
brainstem load session --limit 20 --offset 20
138+
139+
# Public portal
140+
brainstem load project --portal public
31141
```
32142

143+
### Creating and updating records
144+
```bash
145+
# Create a new session
146+
brainstem save session --data '{"name":"New session","projects":["<uuid>"]}'
147+
148+
# Update an existing record
149+
brainstem save session --id <uuid> --data '{"description":"updated"}'
150+
```
151+
152+
### Deleting records
153+
```bash
154+
brainstem delete session --id <uuid>
155+
```
156+
157+
All subcommands accept `--token`, `--headless`, and `--url` to override defaults.
158+
33159
## Contributing
34160
Contributions are welcome! Feel free to open issues or submit pull requests on GitHub.
35161

brainstem_api_tools/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
from .brainstem_api_client import BrainstemClient, ModelType, PortalType
1+
from .brainstem_api_client import BrainstemClient, ModelType, PortalType, AuthenticationError
2+
3+
__version__ = "2.0.0"

0 commit comments

Comments
 (0)