obi-notebook 0.1.dev9__tar.gz → 0.1.dev10__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.
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/PKG-INFO +1 -1
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/example.ipynb +33 -21
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/src/obi_notebook/get_entities.py +80 -10
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/src/obi_notebook.egg-info/PKG-INFO +1 -1
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/.github/workflows/sdist.yml +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/.github/workflows/tox.yml +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/.gitignore +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/CHANGELOG.rst +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/LICENSE.txt +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/README.md +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/demo.gif +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/pyproject.toml +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/setup.cfg +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/src/obi_notebook/__init__.py +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/src/obi_notebook/get_projects.py +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/src/obi_notebook.egg-info/SOURCES.txt +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/src/obi_notebook.egg-info/dependency_links.txt +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/src/obi_notebook.egg-info/requires.txt +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/src/obi_notebook.egg-info/top_level.txt +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/tox.ini +0 -0
- {obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: obi_notebook
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.dev10
|
|
4
4
|
Summary: convenience functions for OBI notebooks
|
|
5
5
|
Author-email: Open Brain Institute <jean-denis.courcol@epfl.ch>
|
|
6
6
|
Maintainer-email: Open Brain Institute <jean-denis.courcol@epfl.ch>
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"outputs": [],
|
|
9
9
|
"source": [
|
|
10
10
|
"import obi_auth\n",
|
|
11
|
-
"
|
|
11
|
+
"\n",
|
|
12
|
+
"from obi_notebook import get_entities, get_projects"
|
|
12
13
|
]
|
|
13
14
|
},
|
|
14
15
|
{
|
|
@@ -46,12 +47,12 @@
|
|
|
46
47
|
{
|
|
47
48
|
"data": {
|
|
48
49
|
"application/vnd.jupyter.widget-view+json": {
|
|
49
|
-
"model_id": "
|
|
50
|
+
"model_id": "281a37021ded4183b265b05213be6b56",
|
|
50
51
|
"version_major": 2,
|
|
51
52
|
"version_minor": 0
|
|
52
53
|
},
|
|
53
54
|
"text/plain": [
|
|
54
|
-
"Dropdown(description='Select:', options=(('
|
|
55
|
+
"Dropdown(description='Select:', options=(('My first project', {'id': '7d22829c-edc6-4b1d-8ab9-99dd9e511e74', '…"
|
|
55
56
|
]
|
|
56
57
|
},
|
|
57
58
|
"metadata": {},
|
|
@@ -71,7 +72,7 @@
|
|
|
71
72
|
{
|
|
72
73
|
"data": {
|
|
73
74
|
"text/plain": [
|
|
74
|
-
"ProjectContext(project_id=UUID('
|
|
75
|
+
"ProjectContext(project_id=UUID('7d22829c-edc6-4b1d-8ab9-99dd9e511e74'), virtual_lab_id=UUID('5f8376bf-b84f-4188-8ef5-e1df3d7529b4'), environment=<DeploymentEnvironment.production: 'production'>)"
|
|
75
76
|
]
|
|
76
77
|
},
|
|
77
78
|
"execution_count": 4,
|
|
@@ -85,19 +86,19 @@
|
|
|
85
86
|
},
|
|
86
87
|
{
|
|
87
88
|
"cell_type": "code",
|
|
88
|
-
"execution_count":
|
|
89
|
+
"execution_count": 5,
|
|
89
90
|
"id": "93029f77-d71f-40f4-8c4d-9f23d2b650bc",
|
|
90
91
|
"metadata": {},
|
|
91
92
|
"outputs": [
|
|
92
93
|
{
|
|
93
94
|
"data": {
|
|
94
95
|
"application/vnd.jupyter.widget-view+json": {
|
|
95
|
-
"model_id": "
|
|
96
|
+
"model_id": "62af910b9d8e4094853ad04fa4b62426",
|
|
96
97
|
"version_major": 2,
|
|
97
98
|
"version_minor": 0
|
|
98
99
|
},
|
|
99
100
|
"text/plain": [
|
|
100
|
-
"HBox(children=(Dropdown(description='Scale:', options=('
|
|
101
|
+
"HBox(children=(Dropdown(description='Scale:', index=1, options=('pair', 'small', 'microcircuit', 'region', 'sy…"
|
|
101
102
|
]
|
|
102
103
|
},
|
|
103
104
|
"metadata": {},
|
|
@@ -106,7 +107,7 @@
|
|
|
106
107
|
{
|
|
107
108
|
"data": {
|
|
108
109
|
"application/vnd.jupyter.widget-view+json": {
|
|
109
|
-
"model_id": "
|
|
110
|
+
"model_id": "d55601c877f54aaa8a0dc6a92a9440d4",
|
|
110
111
|
"version_major": 2,
|
|
111
112
|
"version_minor": 0
|
|
112
113
|
},
|
|
@@ -120,27 +121,38 @@
|
|
|
120
121
|
],
|
|
121
122
|
"source": [
|
|
122
123
|
"circuit_ids = []\n",
|
|
123
|
-
"circuit_ids = get_entities.get_entities(\"
|
|
124
|
+
"circuit_ids = get_entities.get_entities(\n",
|
|
125
|
+
" \"circuit\",\n",
|
|
126
|
+
" token,\n",
|
|
127
|
+
" circuit_ids,\n",
|
|
128
|
+
" return_entities=False,\n",
|
|
129
|
+
" multi_select=True,\n",
|
|
130
|
+
" show_pages=True,\n",
|
|
131
|
+
" page_size=10,\n",
|
|
132
|
+
" default_scale=\"small\",\n",
|
|
133
|
+
" exclude_scales=[\"single\"],\n",
|
|
134
|
+
" add_columns=[\"subject.name\"],\n",
|
|
135
|
+
")"
|
|
124
136
|
]
|
|
125
137
|
},
|
|
126
138
|
{
|
|
127
139
|
"cell_type": "code",
|
|
128
|
-
"execution_count":
|
|
140
|
+
"execution_count": 6,
|
|
129
141
|
"id": "da699ed4-39fd-4602-b54d-58a0b58c2539",
|
|
130
142
|
"metadata": {},
|
|
131
143
|
"outputs": [
|
|
132
144
|
{
|
|
133
145
|
"data": {
|
|
134
146
|
"text/plain": [
|
|
135
|
-
"['
|
|
136
|
-
" '
|
|
137
|
-
" '
|
|
138
|
-
" '
|
|
139
|
-
" '
|
|
140
|
-
" '
|
|
147
|
+
"['e9380365-7f37-4b8f-854b-7de929c59a48',\n",
|
|
148
|
+
" '51fd0040-7d0e-424f-b8d9-87cd28321081',\n",
|
|
149
|
+
" 'beb65adc-5d4d-42b2-b45e-dc6ae83e4236',\n",
|
|
150
|
+
" '1eb58db1-9dc9-4b9a-b842-543fb79754dc',\n",
|
|
151
|
+
" '05cfa4e6-a44e-44ce-9005-65f204a406a6',\n",
|
|
152
|
+
" '30a3a072-6e60-4042-8698-01bb0875be63']"
|
|
141
153
|
]
|
|
142
154
|
},
|
|
143
|
-
"execution_count":
|
|
155
|
+
"execution_count": 6,
|
|
144
156
|
"metadata": {},
|
|
145
157
|
"output_type": "execute_result"
|
|
146
158
|
}
|
|
@@ -152,7 +164,7 @@
|
|
|
152
164
|
{
|
|
153
165
|
"cell_type": "code",
|
|
154
166
|
"execution_count": null,
|
|
155
|
-
"id": "
|
|
167
|
+
"id": "a5f5445d-a61a-4fbe-962f-51e701434771",
|
|
156
168
|
"metadata": {},
|
|
157
169
|
"outputs": [],
|
|
158
170
|
"source": []
|
|
@@ -160,9 +172,9 @@
|
|
|
160
172
|
],
|
|
161
173
|
"metadata": {
|
|
162
174
|
"kernelspec": {
|
|
163
|
-
"display_name": "
|
|
175
|
+
"display_name": "obi-one",
|
|
164
176
|
"language": "python",
|
|
165
|
-
"name": "obi-
|
|
177
|
+
"name": "obi-one"
|
|
166
178
|
},
|
|
167
179
|
"language_info": {
|
|
168
180
|
"codemirror_mode": {
|
|
@@ -174,7 +186,7 @@
|
|
|
174
186
|
"name": "python",
|
|
175
187
|
"nbconvert_exporter": "python",
|
|
176
188
|
"pygments_lexer": "ipython3",
|
|
177
|
-
"version": "3.12.
|
|
189
|
+
"version": "3.12.9"
|
|
178
190
|
}
|
|
179
191
|
},
|
|
180
192
|
"nbformat": 4,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"""A table widget to select entities."""
|
|
2
2
|
|
|
3
3
|
import ipywidgets as widgets
|
|
4
|
+
import numpy as np
|
|
4
5
|
import pandas as pd
|
|
5
6
|
import requests
|
|
6
|
-
from entitysdk import Client, models
|
|
7
|
+
from entitysdk import Client, models, types
|
|
7
8
|
from ipydatagrid import DataGrid, TextRenderer
|
|
8
9
|
from IPython.display import clear_output, display
|
|
9
10
|
|
|
@@ -17,24 +18,61 @@ def _estimate_column_widths(df, char_width=8, padding=2, max_size=250):
|
|
|
17
18
|
|
|
18
19
|
|
|
19
20
|
def get_entities(
|
|
20
|
-
entity_type,
|
|
21
|
+
entity_type,
|
|
22
|
+
token,
|
|
23
|
+
result,
|
|
24
|
+
env="production",
|
|
25
|
+
project_context=None,
|
|
26
|
+
return_entities=False,
|
|
27
|
+
multi_select=True,
|
|
28
|
+
page_size=10,
|
|
29
|
+
show_pages=True,
|
|
30
|
+
add_columns=None,
|
|
31
|
+
default_scale=None,
|
|
32
|
+
exclude_scales=None,
|
|
21
33
|
):
|
|
22
34
|
"""Select entities of type entity_type and add them to result.
|
|
23
35
|
|
|
24
36
|
Note: The 'result' parameter is a mutable object (a list) that is modified in-place
|
|
25
37
|
and also returned.
|
|
26
38
|
"""
|
|
39
|
+
if page_size is not None:
|
|
40
|
+
if page_size <= 0:
|
|
41
|
+
raise ValueError("ERROR: Page size must be larger than 0!")
|
|
42
|
+
# TODO: Could add an upper limit as well here
|
|
43
|
+
|
|
44
|
+
if add_columns is None:
|
|
45
|
+
add_columns = []
|
|
46
|
+
if exclude_scales is None:
|
|
47
|
+
exclude_scales = []
|
|
48
|
+
|
|
27
49
|
# Widgets
|
|
28
50
|
filters_dict = {}
|
|
29
51
|
if entity_type == "circuit":
|
|
52
|
+
scale_options = [
|
|
53
|
+
_scale.value for _scale in types.CircuitScale if _scale.value not in exclude_scales
|
|
54
|
+
]
|
|
55
|
+
if default_scale is None or default_scale not in scale_options:
|
|
56
|
+
default_scale = scale_options[0]
|
|
30
57
|
scale_filter = widgets.Dropdown(
|
|
31
|
-
options=
|
|
58
|
+
options=scale_options,
|
|
59
|
+
value=default_scale,
|
|
32
60
|
description="Scale:",
|
|
33
61
|
)
|
|
34
62
|
filters_dict["scale"] = scale_filter
|
|
35
63
|
|
|
36
64
|
filters_dict["name"] = widgets.Text(description="Name:")
|
|
37
65
|
|
|
66
|
+
if show_pages:
|
|
67
|
+
filters_dict["page"] = widgets.Dropdown(
|
|
68
|
+
options=[1],
|
|
69
|
+
value=1,
|
|
70
|
+
description="Results page:",
|
|
71
|
+
disabled=False,
|
|
72
|
+
style={"description_width": "auto"},
|
|
73
|
+
layout=widgets.Layout(width="max-content"),
|
|
74
|
+
)
|
|
75
|
+
|
|
38
76
|
# Output area
|
|
39
77
|
output = widgets.Output()
|
|
40
78
|
|
|
@@ -43,7 +81,10 @@ def get_entities(
|
|
|
43
81
|
|
|
44
82
|
# Fetch and display function
|
|
45
83
|
def fetch_data(filter_values):
|
|
46
|
-
|
|
84
|
+
if page_size is None:
|
|
85
|
+
params = {}
|
|
86
|
+
else:
|
|
87
|
+
params = {"page_size": page_size}
|
|
47
88
|
for k, v in filter_values.items():
|
|
48
89
|
if k == "name":
|
|
49
90
|
params["name__ilike"] = v
|
|
@@ -64,10 +105,11 @@ def get_entities(
|
|
|
64
105
|
try:
|
|
65
106
|
data = response.json()
|
|
66
107
|
df = pd.json_normalize(data["data"])
|
|
67
|
-
|
|
108
|
+
pagination = data["pagination"]
|
|
109
|
+
return df, pagination
|
|
68
110
|
except Exception as e:
|
|
69
111
|
print("Error fetching or parsing data:", e)
|
|
70
|
-
return pd.DataFrame()
|
|
112
|
+
return pd.DataFrame(), None
|
|
71
113
|
|
|
72
114
|
grid = None
|
|
73
115
|
|
|
@@ -78,7 +120,7 @@ def get_entities(
|
|
|
78
120
|
with output:
|
|
79
121
|
clear_output()
|
|
80
122
|
filter_values = {k: v.value for k, v in filters_dict.items()}
|
|
81
|
-
df = fetch_data(filter_values)
|
|
123
|
+
df, pagination = fetch_data(filter_values)
|
|
82
124
|
|
|
83
125
|
proper_columns = [
|
|
84
126
|
"id",
|
|
@@ -86,12 +128,24 @@ def get_entities(
|
|
|
86
128
|
"description",
|
|
87
129
|
"brain_region.name",
|
|
88
130
|
"subject.species.name",
|
|
89
|
-
]
|
|
131
|
+
] + add_columns
|
|
90
132
|
if len(df) == 0:
|
|
91
|
-
|
|
133
|
+
if show_pages and filters_dict["page"].value != 1:
|
|
134
|
+
filters_dict["page"].options = [1] # Will update .value as well
|
|
135
|
+
else:
|
|
136
|
+
print("no results")
|
|
92
137
|
return
|
|
93
138
|
|
|
139
|
+
proper_columns = [_col for _col in proper_columns if _col in df.columns]
|
|
94
140
|
df = df[proper_columns].reset_index(drop=True)
|
|
141
|
+
|
|
142
|
+
if show_pages:
|
|
143
|
+
num_pages = np.maximum(
|
|
144
|
+
1, np.ceil(pagination["total_items"] / pagination["page_size"]).astype(int)
|
|
145
|
+
)
|
|
146
|
+
filters_dict["page"].options = range(1, num_pages + 1)
|
|
147
|
+
df.index = df.index + (pagination["page"] - 1) * pagination["page_size"]
|
|
148
|
+
|
|
95
149
|
column_widths = _estimate_column_widths(df)
|
|
96
150
|
grid = DataGrid(
|
|
97
151
|
df,
|
|
@@ -99,7 +153,6 @@ def get_entities(
|
|
|
99
153
|
# auto_fit_columns=True,
|
|
100
154
|
auto_fit_params={"area": "all"},
|
|
101
155
|
selection_mode="row", # Enable row selection
|
|
102
|
-
selection_behavior="multi",
|
|
103
156
|
column_widths=column_widths,
|
|
104
157
|
)
|
|
105
158
|
grid.default_renderer = TextRenderer()
|
|
@@ -107,6 +160,23 @@ def get_entities(
|
|
|
107
160
|
|
|
108
161
|
def on_selection_change(event, grid=grid):
|
|
109
162
|
with output:
|
|
163
|
+
if not multi_select and len(grid.selections) > 0:
|
|
164
|
+
if (event["new"][-1]["r1"] != event["new"][-1]["r2"]) or len(
|
|
165
|
+
grid.selections
|
|
166
|
+
) > 1: # Multiple rows selected
|
|
167
|
+
if event["new"][-1]["r1"] == event["old"][-1]["r1"]: # r1 unchanged
|
|
168
|
+
new_r = event["new"][-1]["r1"]
|
|
169
|
+
else: # r2 unchanged
|
|
170
|
+
new_r = event["new"][-1]["r2"]
|
|
171
|
+
# Enforce selection of a single row (last one that was selected)
|
|
172
|
+
grid.selections = [
|
|
173
|
+
{
|
|
174
|
+
"r1": new_r,
|
|
175
|
+
"r2": new_r,
|
|
176
|
+
"c1": grid.selections[-1]["c1"],
|
|
177
|
+
"c2": grid.selections[-1]["c2"],
|
|
178
|
+
}
|
|
179
|
+
]
|
|
110
180
|
result.clear()
|
|
111
181
|
l_ids = set()
|
|
112
182
|
for selection in grid.selections:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: obi_notebook
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.dev10
|
|
4
4
|
Summary: convenience functions for OBI notebooks
|
|
5
5
|
Author-email: Open Brain Institute <jean-denis.courcol@epfl.ch>
|
|
6
6
|
Maintainer-email: Open Brain Institute <jean-denis.courcol@epfl.ch>
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{obi_notebook-0.1.dev9 → obi_notebook-0.1.dev10}/src/obi_notebook.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|