obi-notebook 0.1.dev10__tar.gz → 0.2.dev1__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.
Files changed (22) hide show
  1. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/PKG-INFO +1 -1
  2. obi_notebook-0.2.dev1/example.ipynb +183 -0
  3. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/src/obi_notebook/get_entities.py +108 -12
  4. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/src/obi_notebook.egg-info/PKG-INFO +1 -1
  5. obi_notebook-0.1.dev10/example.ipynb +0 -194
  6. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/.github/workflows/sdist.yml +0 -0
  7. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/.github/workflows/tox.yml +0 -0
  8. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/.gitignore +0 -0
  9. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/CHANGELOG.rst +0 -0
  10. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/LICENSE.txt +0 -0
  11. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/README.md +0 -0
  12. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/demo.gif +0 -0
  13. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/pyproject.toml +0 -0
  14. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/setup.cfg +0 -0
  15. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/src/obi_notebook/__init__.py +0 -0
  16. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/src/obi_notebook/get_projects.py +0 -0
  17. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/src/obi_notebook.egg-info/SOURCES.txt +0 -0
  18. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/src/obi_notebook.egg-info/dependency_links.txt +0 -0
  19. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/src/obi_notebook.egg-info/requires.txt +0 -0
  20. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/src/obi_notebook.egg-info/top_level.txt +0 -0
  21. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/tox.ini +0 -0
  22. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev1}/uv.lock +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: obi_notebook
3
- Version: 0.1.dev10
3
+ Version: 0.2.dev1
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>
@@ -0,0 +1,183 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "7eb47475-67c6-499a-a2b4-19f8a64974d0",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "import obi_auth\n",
11
+ "\n",
12
+ "from obi_notebook import get_entities, get_projects\n",
13
+ "\n",
14
+ "environment_str = \"staging\""
15
+ ]
16
+ },
17
+ {
18
+ "cell_type": "markdown",
19
+ "id": "4d984b92-cadd-4b07-9813-b2333272610f",
20
+ "metadata": {},
21
+ "source": [
22
+ "get authentication token for production"
23
+ ]
24
+ },
25
+ {
26
+ "cell_type": "code",
27
+ "execution_count": null,
28
+ "id": "323cb45c-91e3-451f-8a80-374e61433d31",
29
+ "metadata": {},
30
+ "outputs": [],
31
+ "source": [
32
+ "token = obi_auth.get_token(environment=environment_str)"
33
+ ]
34
+ },
35
+ {
36
+ "cell_type": "markdown",
37
+ "id": "b60e8643-3ad5-4619-a052-5bd8b64713fd",
38
+ "metadata": {},
39
+ "source": [
40
+ "a widget to select project to use"
41
+ ]
42
+ },
43
+ {
44
+ "cell_type": "code",
45
+ "execution_count": null,
46
+ "id": "77c47560-1163-4466-83fc-43abc6e0801a",
47
+ "metadata": {},
48
+ "outputs": [],
49
+ "source": [
50
+ "project_context = get_projects.get_projects(token, env=\"staging\")"
51
+ ]
52
+ },
53
+ {
54
+ "cell_type": "code",
55
+ "execution_count": null,
56
+ "id": "d538dcac-1bdc-496b-8840-a7b32ea842ed",
57
+ "metadata": {},
58
+ "outputs": [],
59
+ "source": [
60
+ "project_context"
61
+ ]
62
+ },
63
+ {
64
+ "cell_type": "code",
65
+ "execution_count": null,
66
+ "id": "93029f77-d71f-40f4-8c4d-9f23d2b650bc",
67
+ "metadata": {},
68
+ "outputs": [],
69
+ "source": [
70
+ "circuit_ids = []\n",
71
+ "circuit_ids = get_entities.get_entities(\n",
72
+ " \"circuit\",\n",
73
+ " token,\n",
74
+ " circuit_ids,\n",
75
+ " return_entities=False,\n",
76
+ " multi_select=True,\n",
77
+ " show_pages=True,\n",
78
+ " project_context=project_context,\n",
79
+ " page_size=10,\n",
80
+ " default_scale=\"small\",\n",
81
+ " exclude_scales=[\"single\"],\n",
82
+ " add_columns=[\"subject.name\"],\n",
83
+ " env=environment_str,\n",
84
+ ")"
85
+ ]
86
+ },
87
+ {
88
+ "cell_type": "code",
89
+ "execution_count": null,
90
+ "id": "da699ed4-39fd-4602-b54d-58a0b58c2539",
91
+ "metadata": {},
92
+ "outputs": [],
93
+ "source": [
94
+ "circuit_ids"
95
+ ]
96
+ },
97
+ {
98
+ "cell_type": "code",
99
+ "execution_count": null,
100
+ "id": "a5f5445d-a61a-4fbe-962f-51e701434771",
101
+ "metadata": {},
102
+ "outputs": [],
103
+ "source": [
104
+ "morph_ids = []\n",
105
+ "morph_ids = get_entities.get_entities(\n",
106
+ " \"reconstruction-morphology\",\n",
107
+ " token,\n",
108
+ " morph_ids,\n",
109
+ " return_entities=False,\n",
110
+ " multi_select=True,\n",
111
+ " show_pages=True,\n",
112
+ " project_context=project_context,\n",
113
+ " page_size=100,\n",
114
+ " add_columns=[\"mtypes\"],\n",
115
+ " env=environment_str,\n",
116
+ ")"
117
+ ]
118
+ },
119
+ {
120
+ "cell_type": "code",
121
+ "execution_count": null,
122
+ "id": "2c9d28c4",
123
+ "metadata": {},
124
+ "outputs": [],
125
+ "source": [
126
+ "morph_ids"
127
+ ]
128
+ },
129
+ {
130
+ "cell_type": "code",
131
+ "execution_count": null,
132
+ "id": "90757b52",
133
+ "metadata": {},
134
+ "outputs": [],
135
+ "source": [
136
+ "cell_mesh_ids = []\n",
137
+ "circuit_ids = get_entities.get_entities(\n",
138
+ " \"em-cell-mesh\",\n",
139
+ " token,\n",
140
+ " cell_mesh_ids,\n",
141
+ " return_entities=False,\n",
142
+ " multi_select=True,\n",
143
+ " show_pages=True,\n",
144
+ " project_context=project_context,\n",
145
+ " page_size=10,\n",
146
+ " env=environment_str,\n",
147
+ " add_columns=[\"dense_reconstruction_cell_id\", \"subject.name\"],\n",
148
+ ")"
149
+ ]
150
+ },
151
+ {
152
+ "cell_type": "code",
153
+ "execution_count": null,
154
+ "id": "6964ebe2",
155
+ "metadata": {},
156
+ "outputs": [],
157
+ "source": [
158
+ "cell_mesh_ids"
159
+ ]
160
+ }
161
+ ],
162
+ "metadata": {
163
+ "kernelspec": {
164
+ "display_name": ".venv (3.13.1)",
165
+ "language": "python",
166
+ "name": "python3"
167
+ },
168
+ "language_info": {
169
+ "codemirror_mode": {
170
+ "name": "ipython",
171
+ "version": 3
172
+ },
173
+ "file_extension": ".py",
174
+ "mimetype": "text/x-python",
175
+ "name": "python",
176
+ "nbconvert_exporter": "python",
177
+ "pygments_lexer": "ipython3",
178
+ "version": "3.13.1"
179
+ }
180
+ },
181
+ "nbformat": 4,
182
+ "nbformat_minor": 5
183
+ }
@@ -8,6 +8,12 @@ from entitysdk import Client, models, types
8
8
  from ipydatagrid import DataGrid, TextRenderer
9
9
  from IPython.display import clear_output, display
10
10
 
11
+ LST_MTYPES_ = None
12
+ LST_SPECIES_ = None
13
+ LST_EMDATASETS_ = None
14
+ STR_NO_MTYPE = "NONE"
15
+ ENTITY_CLASS_DICT = {"em-cell-mesh": "EMCellMesh"}
16
+
11
17
 
12
18
  def _estimate_column_widths(df, char_width=8, padding=2, max_size=250):
13
19
  widths = {}
@@ -17,6 +23,65 @@ def _estimate_column_widths(df, char_width=8, padding=2, max_size=250):
17
23
  return widths
18
24
 
19
25
 
26
+ def _resolve_list_to_first_element(obj):
27
+ if isinstance(obj, list):
28
+ if len(obj) > 0:
29
+ return obj[0]["pref_label"]
30
+ return STR_NO_MTYPE
31
+ return obj["pref_label"]
32
+
33
+
34
+ _df_postprocess_funs = {
35
+ "reconstruction-morphology": {"mtypes": _resolve_list_to_first_element},
36
+ "em-cell-mesh": {"dense_reconstruction_cell_id": str},
37
+ }
38
+
39
+
40
+ def _list_of_existing_mtypes(entity_core_url, token):
41
+ global LST_MTYPES_
42
+ if LST_MTYPES_ is None:
43
+ response = requests.get(
44
+ f"{entity_core_url}/mtype",
45
+ headers={"authorization": f"Bearer {token}"},
46
+ params={"page_size": 1000},
47
+ timeout=30,
48
+ )
49
+ data = response.json()
50
+ df_mtype = pd.json_normalize(data["data"])
51
+ LST_MTYPES_ = list(df_mtype["pref_label"])
52
+ return LST_MTYPES_
53
+
54
+
55
+ def _list_of_existing_species(entity_core_url, token):
56
+ global LST_SPECIES_
57
+ if LST_SPECIES_ is None:
58
+ response = requests.get(
59
+ f"{entity_core_url}/species",
60
+ headers={"authorization": f"Bearer {token}"},
61
+ params={"page_size": 1000},
62
+ timeout=30,
63
+ )
64
+ data = response.json()
65
+ df_species = pd.json_normalize(data["data"])
66
+ LST_SPECIES_ = list(df_species["name"])
67
+ return LST_SPECIES_
68
+
69
+
70
+ def _list_of_existing_em_dense_datasets(entity_core_url, token):
71
+ global LST_EMDATASETS_
72
+ if LST_EMDATASETS_ is None:
73
+ response = requests.get(
74
+ f"{entity_core_url}/em-dense-reconstruction-dataset",
75
+ headers={"authorization": f"Bearer {token}"},
76
+ params={"page_size": 1000},
77
+ timeout=30,
78
+ )
79
+ data = response.json()
80
+ df_species = pd.json_normalize(data["data"])
81
+ LST_EMDATASETS_ = list(df_species["name"])
82
+ return LST_EMDATASETS_
83
+
84
+
20
85
  def get_entities(
21
86
  entity_type,
22
87
  token,
@@ -46,6 +111,9 @@ def get_entities(
46
111
  if exclude_scales is None:
47
112
  exclude_scales = []
48
113
 
114
+ subdomain = "www" if env == "production" else "staging"
115
+ entity_core_url = f"https://{subdomain}.openbraininstitute.org/api/entitycore"
116
+
49
117
  # Widgets
50
118
  filters_dict = {}
51
119
  if entity_type == "circuit":
@@ -60,8 +128,30 @@ def get_entities(
60
128
  description="Scale:",
61
129
  )
62
130
  filters_dict["scale"] = scale_filter
63
-
64
- filters_dict["name"] = widgets.Text(description="Name:")
131
+ filters_dict["name__ilike"] = widgets.Text(description="Name:")
132
+ elif entity_type == "reconstruction-morphology":
133
+ lst_mtypes = _list_of_existing_mtypes(entity_core_url, token) + [""]
134
+ mtype_filter = widgets.Combobox(
135
+ placeholder="Select M-Type",
136
+ description="M-Type:",
137
+ options=lst_mtypes,
138
+ ensure_option=True,
139
+ )
140
+ filters_dict["mtype__pref_label"] = mtype_filter
141
+ lst_species = _list_of_existing_species(entity_core_url, token) + [""]
142
+ species_filter = widgets.Dropdown(options=lst_species, value="", description="Species:")
143
+ filters_dict["species__name"] = species_filter
144
+ filters_dict["name__ilike"] = widgets.Text(description="Name:")
145
+ elif entity_type == "em-cell-mesh":
146
+ lst_em_datasets = _list_of_existing_em_dense_datasets(entity_core_url, token) + [""]
147
+ em_dataset_filter = widgets.Combobox(
148
+ placeholder="Select EM Dataset",
149
+ description="EM-Dataset:",
150
+ options=lst_em_datasets,
151
+ ensure_option=True,
152
+ )
153
+ filters_dict["em_dense_reconstruction_dataset__name__ilike"] = em_dataset_filter
154
+ filters_dict["dense_reconstruction_cell_id"] = widgets.Text(description="Cell ID:")
65
155
 
66
156
  if show_pages:
67
157
  filters_dict["page"] = widgets.Dropdown(
@@ -76,9 +166,6 @@ def get_entities(
76
166
  # Output area
77
167
  output = widgets.Output()
78
168
 
79
- subdomain = "www" if env == "production" else "staging"
80
- entity_core_url = f"https://{subdomain}.openbraininstitute.org/api/entitycore"
81
-
82
169
  # Fetch and display function
83
170
  def fetch_data(filter_values):
84
171
  if page_size is None:
@@ -86,15 +173,15 @@ def get_entities(
86
173
  else:
87
174
  params = {"page_size": page_size}
88
175
  for k, v in filter_values.items():
89
- if k == "name":
90
- params["name__ilike"] = v
91
- else:
92
- params[k] = v
176
+ if isinstance(v, str):
177
+ if len(v.strip()) == 0:
178
+ continue
179
+ params[k] = v
93
180
 
94
181
  headers = {"authorization": f"Bearer {token}"}
95
182
  if project_context:
96
- headers["virtual-lab-id"] = project_context.virtual_lab_id
97
- headers["project-id"] = project_context.project_id
183
+ headers["virtual-lab-id"] = str(project_context.virtual_lab_id)
184
+ headers["project-id"] = str(project_context.project_id)
98
185
  response = requests.get(
99
186
  f"{entity_core_url}/{entity_type}",
100
187
  headers=headers,
@@ -128,6 +215,7 @@ def get_entities(
128
215
  "description",
129
216
  "brain_region.name",
130
217
  "subject.species.name",
218
+ "species.name", # For morphologies
131
219
  ] + add_columns
132
220
  if len(df) == 0:
133
221
  if show_pages and filters_dict["page"].value != 1:
@@ -139,6 +227,10 @@ def get_entities(
139
227
  proper_columns = [_col for _col in proper_columns if _col in df.columns]
140
228
  df = df[proper_columns].reset_index(drop=True)
141
229
 
230
+ for colname, fun in _df_postprocess_funs.get(entity_type, {}).items():
231
+ if colname in df.columns:
232
+ df[colname] = df[colname].apply(fun)
233
+
142
234
  if show_pages:
143
235
  num_pages = np.maximum(
144
236
  1, np.ceil(pagination["total_items"] / pagination["page_size"]).astype(int)
@@ -190,7 +282,11 @@ def get_entities(
190
282
  token_manager=token,
191
283
  )
192
284
 
193
- model_class = getattr(models, entity_type.capitalize())
285
+ entity_class_default = "".join(
286
+ [_token.capitalize() for _token in entity_type.split("-")]
287
+ )
288
+ entity_class_name = ENTITY_CLASS_DICT.get(entity_type, entity_class_default)
289
+ model_class = getattr(models, entity_class_name)
194
290
  retrieved_entities = client.search_entity(
195
291
  entity_type=model_class, query={"id__in": list(l_ids)}
196
292
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: obi_notebook
3
- Version: 0.1.dev10
3
+ Version: 0.2.dev1
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>
@@ -1,194 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 1,
6
- "id": "7eb47475-67c6-499a-a2b4-19f8a64974d0",
7
- "metadata": {},
8
- "outputs": [],
9
- "source": [
10
- "import obi_auth\n",
11
- "\n",
12
- "from obi_notebook import get_entities, get_projects"
13
- ]
14
- },
15
- {
16
- "cell_type": "markdown",
17
- "id": "4d984b92-cadd-4b07-9813-b2333272610f",
18
- "metadata": {},
19
- "source": [
20
- "get authentication token for production"
21
- ]
22
- },
23
- {
24
- "cell_type": "code",
25
- "execution_count": 2,
26
- "id": "323cb45c-91e3-451f-8a80-374e61433d31",
27
- "metadata": {},
28
- "outputs": [],
29
- "source": [
30
- "token = obi_auth.get_token(environment=\"production\")"
31
- ]
32
- },
33
- {
34
- "cell_type": "markdown",
35
- "id": "b60e8643-3ad5-4619-a052-5bd8b64713fd",
36
- "metadata": {},
37
- "source": [
38
- "a widget to select project to use"
39
- ]
40
- },
41
- {
42
- "cell_type": "code",
43
- "execution_count": 3,
44
- "id": "77c47560-1163-4466-83fc-43abc6e0801a",
45
- "metadata": {},
46
- "outputs": [
47
- {
48
- "data": {
49
- "application/vnd.jupyter.widget-view+json": {
50
- "model_id": "281a37021ded4183b265b05213be6b56",
51
- "version_major": 2,
52
- "version_minor": 0
53
- },
54
- "text/plain": [
55
- "Dropdown(description='Select:', options=(('My first project', {'id': '7d22829c-edc6-4b1d-8ab9-99dd9e511e74', '…"
56
- ]
57
- },
58
- "metadata": {},
59
- "output_type": "display_data"
60
- }
61
- ],
62
- "source": [
63
- "project_context = get_projects.get_projects(token)"
64
- ]
65
- },
66
- {
67
- "cell_type": "code",
68
- "execution_count": 4,
69
- "id": "d538dcac-1bdc-496b-8840-a7b32ea842ed",
70
- "metadata": {},
71
- "outputs": [
72
- {
73
- "data": {
74
- "text/plain": [
75
- "ProjectContext(project_id=UUID('7d22829c-edc6-4b1d-8ab9-99dd9e511e74'), virtual_lab_id=UUID('5f8376bf-b84f-4188-8ef5-e1df3d7529b4'), environment=<DeploymentEnvironment.production: 'production'>)"
76
- ]
77
- },
78
- "execution_count": 4,
79
- "metadata": {},
80
- "output_type": "execute_result"
81
- }
82
- ],
83
- "source": [
84
- "project_context"
85
- ]
86
- },
87
- {
88
- "cell_type": "code",
89
- "execution_count": 5,
90
- "id": "93029f77-d71f-40f4-8c4d-9f23d2b650bc",
91
- "metadata": {},
92
- "outputs": [
93
- {
94
- "data": {
95
- "application/vnd.jupyter.widget-view+json": {
96
- "model_id": "62af910b9d8e4094853ad04fa4b62426",
97
- "version_major": 2,
98
- "version_minor": 0
99
- },
100
- "text/plain": [
101
- "HBox(children=(Dropdown(description='Scale:', index=1, options=('pair', 'small', 'microcircuit', 'region', 'sy…"
102
- ]
103
- },
104
- "metadata": {},
105
- "output_type": "display_data"
106
- },
107
- {
108
- "data": {
109
- "application/vnd.jupyter.widget-view+json": {
110
- "model_id": "d55601c877f54aaa8a0dc6a92a9440d4",
111
- "version_major": 2,
112
- "version_minor": 0
113
- },
114
- "text/plain": [
115
- "Output()"
116
- ]
117
- },
118
- "metadata": {},
119
- "output_type": "display_data"
120
- }
121
- ],
122
- "source": [
123
- "circuit_ids = []\n",
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
- ")"
136
- ]
137
- },
138
- {
139
- "cell_type": "code",
140
- "execution_count": 6,
141
- "id": "da699ed4-39fd-4602-b54d-58a0b58c2539",
142
- "metadata": {},
143
- "outputs": [
144
- {
145
- "data": {
146
- "text/plain": [
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']"
153
- ]
154
- },
155
- "execution_count": 6,
156
- "metadata": {},
157
- "output_type": "execute_result"
158
- }
159
- ],
160
- "source": [
161
- "circuit_ids"
162
- ]
163
- },
164
- {
165
- "cell_type": "code",
166
- "execution_count": null,
167
- "id": "a5f5445d-a61a-4fbe-962f-51e701434771",
168
- "metadata": {},
169
- "outputs": [],
170
- "source": []
171
- }
172
- ],
173
- "metadata": {
174
- "kernelspec": {
175
- "display_name": "obi-one",
176
- "language": "python",
177
- "name": "obi-one"
178
- },
179
- "language_info": {
180
- "codemirror_mode": {
181
- "name": "ipython",
182
- "version": 3
183
- },
184
- "file_extension": ".py",
185
- "mimetype": "text/x-python",
186
- "name": "python",
187
- "nbconvert_exporter": "python",
188
- "pygments_lexer": "ipython3",
189
- "version": "3.12.9"
190
- }
191
- },
192
- "nbformat": 4,
193
- "nbformat_minor": 5
194
- }