obi-notebook 0.1.dev10__tar.gz → 0.2.dev0__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.dev0}/PKG-INFO +1 -1
  2. obi_notebook-0.2.dev0/example.ipynb +147 -0
  3. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/src/obi_notebook/get_entities.py +72 -10
  4. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/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.dev0}/.github/workflows/sdist.yml +0 -0
  7. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/.github/workflows/tox.yml +0 -0
  8. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/.gitignore +0 -0
  9. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/CHANGELOG.rst +0 -0
  10. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/LICENSE.txt +0 -0
  11. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/README.md +0 -0
  12. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/demo.gif +0 -0
  13. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/pyproject.toml +0 -0
  14. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/setup.cfg +0 -0
  15. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/src/obi_notebook/__init__.py +0 -0
  16. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/src/obi_notebook/get_projects.py +0 -0
  17. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/src/obi_notebook.egg-info/SOURCES.txt +0 -0
  18. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/src/obi_notebook.egg-info/dependency_links.txt +0 -0
  19. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/src/obi_notebook.egg-info/requires.txt +0 -0
  20. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/src/obi_notebook.egg-info/top_level.txt +0 -0
  21. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/tox.ini +0 -0
  22. {obi_notebook-0.1.dev10 → obi_notebook-0.2.dev0}/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.dev0
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,147 @@
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"
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": null,
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": null,
44
+ "id": "77c47560-1163-4466-83fc-43abc6e0801a",
45
+ "metadata": {},
46
+ "outputs": [],
47
+ "source": [
48
+ "project_context = get_projects.get_projects(token)"
49
+ ]
50
+ },
51
+ {
52
+ "cell_type": "code",
53
+ "execution_count": null,
54
+ "id": "d538dcac-1bdc-496b-8840-a7b32ea842ed",
55
+ "metadata": {},
56
+ "outputs": [],
57
+ "source": [
58
+ "project_context"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": null,
64
+ "id": "93029f77-d71f-40f4-8c4d-9f23d2b650bc",
65
+ "metadata": {},
66
+ "outputs": [],
67
+ "source": [
68
+ "circuit_ids = []\n",
69
+ "circuit_ids = get_entities.get_entities(\n",
70
+ " \"circuit\",\n",
71
+ " token,\n",
72
+ " circuit_ids,\n",
73
+ " return_entities=False,\n",
74
+ " multi_select=True,\n",
75
+ " show_pages=True,\n",
76
+ " project_context=project_context,\n",
77
+ " page_size=10,\n",
78
+ " default_scale=\"small\",\n",
79
+ " exclude_scales=[\"single\"],\n",
80
+ " add_columns=[\"subject.name\"],\n",
81
+ ")"
82
+ ]
83
+ },
84
+ {
85
+ "cell_type": "code",
86
+ "execution_count": null,
87
+ "id": "da699ed4-39fd-4602-b54d-58a0b58c2539",
88
+ "metadata": {},
89
+ "outputs": [],
90
+ "source": [
91
+ "circuit_ids"
92
+ ]
93
+ },
94
+ {
95
+ "cell_type": "code",
96
+ "execution_count": null,
97
+ "id": "a5f5445d-a61a-4fbe-962f-51e701434771",
98
+ "metadata": {},
99
+ "outputs": [],
100
+ "source": [
101
+ "morph_ids = []\n",
102
+ "morph_ids = get_entities.get_entities(\n",
103
+ " \"reconstruction-morphology\",\n",
104
+ " token,\n",
105
+ " morph_ids,\n",
106
+ " return_entities=False,\n",
107
+ " multi_select=True,\n",
108
+ " show_pages=True,\n",
109
+ " project_context=project_context,\n",
110
+ " page_size=100,\n",
111
+ " add_columns=[\"mtypes\"],\n",
112
+ ")"
113
+ ]
114
+ },
115
+ {
116
+ "cell_type": "code",
117
+ "execution_count": null,
118
+ "id": "ab24b139",
119
+ "metadata": {},
120
+ "outputs": [],
121
+ "source": [
122
+ "morph_ids"
123
+ ]
124
+ }
125
+ ],
126
+ "metadata": {
127
+ "kernelspec": {
128
+ "display_name": ".venv (3.13.1)",
129
+ "language": "python",
130
+ "name": "python3"
131
+ },
132
+ "language_info": {
133
+ "codemirror_mode": {
134
+ "name": "ipython",
135
+ "version": 3
136
+ },
137
+ "file_extension": ".py",
138
+ "mimetype": "text/x-python",
139
+ "name": "python",
140
+ "nbconvert_exporter": "python",
141
+ "pygments_lexer": "ipython3",
142
+ "version": "3.13.1"
143
+ }
144
+ },
145
+ "nbformat": 4,
146
+ "nbformat_minor": 5
147
+ }
@@ -8,6 +8,10 @@ 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
+ STR_NO_MTYPE = "NONE"
14
+
11
15
 
12
16
  def _estimate_column_widths(df, char_width=8, padding=2, max_size=250):
13
17
  widths = {}
@@ -17,6 +21,47 @@ def _estimate_column_widths(df, char_width=8, padding=2, max_size=250):
17
21
  return widths
18
22
 
19
23
 
24
+ def _resolve_list_to_first_element(obj):
25
+ if isinstance(obj, list):
26
+ if len(obj) > 0:
27
+ return obj[0]["pref_label"]
28
+ return STR_NO_MTYPE
29
+ return obj["pref_label"]
30
+
31
+
32
+ _df_postprocess_funs = {"reconstruction-morphology": {"mtypes": _resolve_list_to_first_element}}
33
+
34
+
35
+ def _list_of_existing_mtypes(entity_core_url, token):
36
+ global LST_MTYPES_
37
+ if LST_MTYPES_ is None:
38
+ response = requests.get(
39
+ f"{entity_core_url}/mtype",
40
+ headers={"authorization": f"Bearer {token}"},
41
+ params={"page_size": 1000},
42
+ timeout=30,
43
+ )
44
+ data = response.json()
45
+ df_mtype = pd.json_normalize(data["data"])
46
+ LST_MTYPES_ = list(df_mtype["pref_label"])
47
+ return LST_MTYPES_
48
+
49
+
50
+ def _list_of_existing_species(entity_core_url, token):
51
+ global LST_SPECIES_
52
+ if LST_SPECIES_ is None:
53
+ response = requests.get(
54
+ f"{entity_core_url}/species",
55
+ headers={"authorization": f"Bearer {token}"},
56
+ params={"page_size": 1000},
57
+ timeout=30,
58
+ )
59
+ data = response.json()
60
+ df_species = pd.json_normalize(data["data"])
61
+ LST_SPECIES_ = list(df_species["name"])
62
+ return LST_SPECIES_
63
+
64
+
20
65
  def get_entities(
21
66
  entity_type,
22
67
  token,
@@ -46,6 +91,9 @@ def get_entities(
46
91
  if exclude_scales is None:
47
92
  exclude_scales = []
48
93
 
94
+ subdomain = "www" if env == "production" else "staging"
95
+ entity_core_url = f"https://{subdomain}.openbraininstitute.org/api/entitycore"
96
+
49
97
  # Widgets
50
98
  filters_dict = {}
51
99
  if entity_type == "circuit":
@@ -60,8 +108,20 @@ def get_entities(
60
108
  description="Scale:",
61
109
  )
62
110
  filters_dict["scale"] = scale_filter
111
+ elif entity_type == "reconstruction-morphology":
112
+ lst_mtypes = _list_of_existing_mtypes(entity_core_url, token) + [""]
113
+ mtype_filter = widgets.Combobox(
114
+ placeholder="Select M-Type",
115
+ description="M-Type:",
116
+ options=lst_mtypes,
117
+ ensure_option=True,
118
+ )
119
+ filters_dict["mtype__pref_label"] = mtype_filter
120
+ lst_species = _list_of_existing_species(entity_core_url, token) + [""]
121
+ species_filter = widgets.Dropdown(options=lst_species, value="", description="Species:")
122
+ filters_dict["species__name"] = species_filter
63
123
 
64
- filters_dict["name"] = widgets.Text(description="Name:")
124
+ filters_dict["name__ilike"] = widgets.Text(description="Name:")
65
125
 
66
126
  if show_pages:
67
127
  filters_dict["page"] = widgets.Dropdown(
@@ -76,9 +136,6 @@ def get_entities(
76
136
  # Output area
77
137
  output = widgets.Output()
78
138
 
79
- subdomain = "www" if env == "production" else "staging"
80
- entity_core_url = f"https://{subdomain}.openbraininstitute.org/api/entitycore"
81
-
82
139
  # Fetch and display function
83
140
  def fetch_data(filter_values):
84
141
  if page_size is None:
@@ -86,15 +143,15 @@ def get_entities(
86
143
  else:
87
144
  params = {"page_size": page_size}
88
145
  for k, v in filter_values.items():
89
- if k == "name":
90
- params["name__ilike"] = v
91
- else:
92
- params[k] = v
146
+ if isinstance(v, str):
147
+ if len(v.strip()) == 0:
148
+ continue
149
+ params[k] = v
93
150
 
94
151
  headers = {"authorization": f"Bearer {token}"}
95
152
  if project_context:
96
- headers["virtual-lab-id"] = project_context.virtual_lab_id
97
- headers["project-id"] = project_context.project_id
153
+ headers["virtual-lab-id"] = str(project_context.virtual_lab_id)
154
+ headers["project-id"] = str(project_context.project_id)
98
155
  response = requests.get(
99
156
  f"{entity_core_url}/{entity_type}",
100
157
  headers=headers,
@@ -128,6 +185,7 @@ def get_entities(
128
185
  "description",
129
186
  "brain_region.name",
130
187
  "subject.species.name",
188
+ "species.name", # For morphologies
131
189
  ] + add_columns
132
190
  if len(df) == 0:
133
191
  if show_pages and filters_dict["page"].value != 1:
@@ -139,6 +197,10 @@ def get_entities(
139
197
  proper_columns = [_col for _col in proper_columns if _col in df.columns]
140
198
  df = df[proper_columns].reset_index(drop=True)
141
199
 
200
+ for colname, fun in _df_postprocess_funs.get(entity_type, {}).items():
201
+ if colname in df.columns:
202
+ df[colname] = df[colname].apply(fun)
203
+
142
204
  if show_pages:
143
205
  num_pages = np.maximum(
144
206
  1, np.ceil(pagination["total_items"] / pagination["page_size"]).astype(int)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: obi_notebook
3
- Version: 0.1.dev10
3
+ Version: 0.2.dev0
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
- }