Skip to content

Commit 44ec530

Browse files
authored
Enable notebooks metadata with tags and image URLs (#1568)
* Add node scripts for managing notebook metadata * Generate metadata for several notebooks * Add metadata to 102 notebook * Add notebooks to prettier ignore * Add notebook tags js constant map * Add categories tags validator * Add to markdown function and command * Add initial workflow for notebook metadata validation * Set fetch depth to all * Add repository to validation workflow * Remove comment * Fetch all commit history * Try gh cli in metadata workflow * Set gh token * Add repository option to checkout step * Remove options for checkout step * Remove commit depth * Use js script for fetching changed notebooks * Add path to notebook metadata interface * Move notebook metadata validator * Add notebook metadata handlers and classes * Add notebook visualization to job summary * Remove paths ignore from workflow * Add npmrc * Remove spark dependency * Add modules extensions * Finish writing to job summary * Fix colab and binder regexp * Add inline metadata to 001 notebook * Add todos * Add validation step * Remove metadata json files * Add notebook specific info to validation error message * Fix errors collection in loop * Remove unused scripts and dependencies * Add notebook metadata to 001 and 002 notebooks * Set invalid categories tags for 102 notebook * Fix md formatter * Add validation check to markdown representation * Add early return for tags validator * Rename models file to notebook metadata * Add tasks tags * Add tasks tags validator * Update metadata for first steps notebooks * Fetch all git history in GH workflow * Enable tags keys validation * Format first steps notebooks * Add metadata to 101 notebook * Add metadata to 102 notebooks * Remove get fetch depth step * Add metadata to 103-109 notebooks * Add metadata for 111-119 notebooks * Add metadata to 120 notebook * Add metadata to 121 notebook * Add metadata to 122-126 notebooks * Add style stransfer task to tags * Add metadata to 121 legacy notebook * Add metadata fot 201-210 notebooks * Change tasks tag for 004 notebook * Add metadata for 211-220 notebooks * Fix metadata tags for 202, 205-207 notebooks * Add metadata for 221-230 notebooks * Fix preview images for 230 notebook metadata * Add metadata for 231-235, 237-240 notebooks * Update metadata tasks tags * Add metadata for 241-243 notebooks * Add metadata for 244-250 notebooks * Add metadata for 251-260 * Add metadata for 261-270 notebooks * Update notebooks tasks tags * Add metadata for 271-275 notebooks * Add metadata for Model Training notebooks * Add metadata for Live Demos notebooks * Update notebokk tasks tags * Update metadata for 124 notebook * Validate if categories tags are not empty * Update metadata for 004 notebook * Update metadata for 241, 256 notebooks * Remove unused tasks tags * Fix metadata md formatter to show undefined images as N/A * Fix task tag for 230 notebook * Add metadata for 236 notebook * Remove todos * Update task tags for 216, 220, 228, 232, 239 notebooks * Add new notebooks tasks tags * Update tasks tags for 219, 244 notebooks * Add new tasks tags * Enable skipped notebooks for metadata handler * Add metadata for 110 notebook * Change workflow title and job name * Add notebook metadata info to contributing.md * Update CONTRIBUTING.md * Add modified notebooks counter to workflow summary * Fix images in notebooks metadata * Filter deleted files from validate metadata workflow * Fix empty modified data * Add metadata for new notebooks
1 parent dea7bd6 commit 44ec530

File tree

163 files changed

+7850
-58
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

163 files changed

+7850
-58
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
name: Validate Notebooks Metadata
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
paths:
7+
- 'notebooks/**/*.ipynb'
8+
9+
concurrency:
10+
group: ${{ github.head_ref || github.ref_name }}
11+
cancel-in-progress: true
12+
13+
jobs:
14+
validate_notebooks_metadata:
15+
runs-on: ubuntu-20.04
16+
name: Validate notebooks metadata
17+
steps:
18+
- name: Checkout code
19+
uses: actions/checkout@v3
20+
with:
21+
ref: ${{ github.event.pull_request.head.ref }}
22+
repository: ${{ github.event.pull_request.head.repo.full_name }}
23+
fetch-depth: 0
24+
25+
- name: Setup Node.js
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version: 18
29+
30+
- name: Get changed notebook files
31+
id: get_changed_notebook_files
32+
uses: actions/github-script@v7
33+
with:
34+
script: |
35+
const { execSync } = require('child_process');
36+
const { commits } = context.payload.pull_request;
37+
const gitDiffCommand = `git diff --name-only --relative=notebooks --diff-filter=d HEAD~${commits} -- *.ipynb ':!notebooks/utils'`;
38+
const changedNotebooks = execSync(gitDiffCommand).toString().split('\n').filter(Boolean);
39+
core.exportVariable('CHANGED_NOTEBOOKS', JSON.stringify(changedNotebooks));
40+
41+
- name: Install Node.js dependencies
42+
working-directory: ./selector
43+
shell: bash
44+
run: npm ci
45+
46+
- name: Validate changed notebooks metadata
47+
uses: actions/github-script@v7
48+
with:
49+
script: |
50+
const { NotebookMetadataHandler } = await import('${{ github.workspace }}/selector/src/notebook-metadata/notebook-metadata-handler.js');
51+
const changedNotebooks = JSON.parse(process.env.CHANGED_NOTEBOOKS);
52+
const [error, metadataMarkdowns] = NotebookMetadataHandler.validateNotebooks(changedNotebooks);
53+
core.summary.addHeading(`Modified Notebooks (${metadataMarkdowns.length})`, '2');
54+
core.summary.addRaw(metadataMarkdowns.join('\n\n'));
55+
core.summary.write();
56+
if (error) {
57+
core.setFailed(error);
58+
}

CONTRIBUTING.md

+30
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
- [Recommendations for File Structure](#recommendations-for-file-structure)
1313
- [Notebook utils](#notebook-utils)
1414
- [Interactive inference with Gradio](#interactive-inference-with-gradio)
15+
- [Notebooks Metadata](#notebooks-metadata)
1516
- [Requirements](#requirements)
1617
- [Validation](#validation)
1718
- [Automated tests](#automated-tests)
@@ -233,6 +234,34 @@ Here are some guidelines to follow:
233234
- We use Gradio Blocks only when we need to create a complex interface. The Gradio Interface class provides an easy-to-use interface and saves development time, so we use it whenever possible. However, for more complex interfaces, Gradio Blocks gives us more flexibility and control.
234235

235236

237+
### Notebooks Metadata
238+
239+
Each notebook file has metadata that includes additional information about the notebook. Some metadata fields (e.g. title, creation date, links to GitHub, Colab, Binder etc.) are generated automatically from notebook content or related `README.md` file. However other fields (e.g. tags, image URL) should be defined by notebook contributor. As each notebook file has JSON format, manually defined metadata fields are stored in corresponding `.ipynb` file in global notebook metadata object (`metadata.openvino_notebooks` field in the end of notebook JSON structure).
240+
241+
Example of such manually defined notebook metadata:
242+
243+
```JSON
244+
"openvino_notebooks": {
245+
"imageUrl": "...",
246+
"tags": {
247+
"categories": [
248+
"First Steps"
249+
],
250+
"libraries": [],
251+
"other": [],
252+
"tasks": [
253+
"Image Classification"
254+
]
255+
}
256+
}
257+
```
258+
259+
Notebook tags in metadata can have several values and should be a subset of defined tags that can be found in `./selector/src/models/notebook-tags.js`.
260+
- `tags.categories` tags relate to notebook groups like "AI Trends", "First Steps", "Model Demos" etc.
261+
- `tags.tasks` tags relate to particular AI tasks that are demonstrated in notebook.
262+
- `tags.other` tags are free-form tags and can be any string (please follow capitalization naming convention).
263+
264+
236265
## Requirements
237266

238267
Contributors are encouraged to install the required packages at the top of their notebook using
@@ -261,6 +290,7 @@ and some style issues
261290
`docker run -it --entrypoint /tmp/scripts/test openvino_notebooks`. It is recommended to build the image on a clean
262291
repository because the full notebooks folder will be copied to the image.
263292
- [`CodeQL`](https://codeql.github.com/)
293+
- Notebooks Metadata Validation: verifies that all added or modified notebooks in PR have valid metadata and visualizes them in workflow summary.
264294

265295
- In the rest of this guide, the automated tests in GitHub
266296
Actions will be referred to as CI (for Continuous Integration).

notebooks/001-hello-world/001-hello-world.ipynb

+14-1
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,19 @@
307307
"pygments_lexer": "ipython3",
308308
"version": "3.8.10"
309309
},
310+
"openvino_notebooks": {
311+
"imageUrl": "https://user-images.githubusercontent.com/36741649/127172572-1cdab941-df5f-42e2-a367-2b334a3db6d8.jpg",
312+
"tags": {
313+
"categories": [
314+
"First Steps"
315+
],
316+
"libraries": [],
317+
"other": [],
318+
"tasks": [
319+
"Image Classification"
320+
]
321+
}
322+
},
310323
"widgets": {
311324
"application/vnd.jupyter.widget-state+json": {
312325
"state": {},
@@ -317,4 +330,4 @@
317330
},
318331
"nbformat": 4,
319332
"nbformat_minor": 5
320-
}
333+
}

notebooks/002-openvino-api/002-openvino-api.ipynb

+14
Original file line numberDiff line numberDiff line change
@@ -1454,6 +1454,20 @@
14541454
"pygments_lexer": "ipython3",
14551455
"version": "3.8.10"
14561456
},
1457+
"openvino_notebooks": {
1458+
"imageUrl": "",
1459+
"tags": {
1460+
"categories": [
1461+
"First Steps"
1462+
],
1463+
"libraries": [],
1464+
"other": [],
1465+
"tasks": [
1466+
"Image Classification",
1467+
"Image Segmentation"
1468+
]
1469+
}
1470+
},
14571471
"widgets": {
14581472
"application/vnd.jupyter.widget-state+json": {
14591473
"state": {},

notebooks/003-hello-segmentation/003-hello-segmentation.ipynb

+14-1
Original file line numberDiff line numberDiff line change
@@ -412,8 +412,21 @@
412412
"nbconvert_exporter": "python",
413413
"pygments_lexer": "ipython3",
414414
"version": "3.10.12"
415+
},
416+
"openvino_notebooks": {
417+
"imageUrl": "https://user-images.githubusercontent.com/15709723/128290691-e2eb875c-775e-4f4d-a2f4-15134044b4bb.png",
418+
"tags": {
419+
"categories": [
420+
"First Steps"
421+
],
422+
"libraries": [],
423+
"other": [],
424+
"tasks": [
425+
"Image Segmentation"
426+
]
427+
}
415428
}
416429
},
417430
"nbformat": 4,
418431
"nbformat_minor": 5
419-
}
432+
}

notebooks/004-hello-detection/004-hello-detection.ipynb

+14-1
Original file line numberDiff line numberDiff line change
@@ -388,8 +388,21 @@
388388
"nbconvert_exporter": "python",
389389
"pygments_lexer": "ipython3",
390390
"version": "3.10.12"
391+
},
392+
"openvino_notebooks": {
393+
"imageUrl": "https://user-images.githubusercontent.com/36741649/128489933-bf215a3f-06fa-4918-8833-cb0bf9fb1cc7.jpg",
394+
"tags": {
395+
"categories": [
396+
"First Steps"
397+
],
398+
"libraries": [],
399+
"other": [],
400+
"tasks": [
401+
"Object Detection"
402+
]
403+
}
391404
}
392405
},
393406
"nbformat": 4,
394407
"nbformat_minor": 5
395-
}
408+
}

notebooks/101-tensorflow-classification-to-openvino/101-tensorflow-classification-to-openvino.ipynb

+14-1
Original file line numberDiff line numberDiff line change
@@ -475,8 +475,21 @@
475475
"nbconvert_exporter": "python",
476476
"pygments_lexer": "ipython3",
477477
"version": "3.10.12"
478+
},
479+
"openvino_notebooks": {
480+
"imageUrl": "https://user-images.githubusercontent.com/36741649/127170593-86976dc3-e5e4-40be-b0a6-206379cd7df5.jpg",
481+
"tags": {
482+
"categories": [
483+
"Convert"
484+
],
485+
"libraries": [],
486+
"other": [],
487+
"tasks": [
488+
"Image Classification"
489+
]
490+
}
478491
}
479492
},
480493
"nbformat": 4,
481494
"nbformat_minor": 4
482-
}
495+
}

notebooks/102-pytorch-to-openvino/102-pytorch-onnx-to-openvino.ipynb

+14-1
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,19 @@
886886
"pygments_lexer": "ipython3",
887887
"version": "3.11.5"
888888
},
889+
"openvino_notebooks": {
890+
"imageUrl": "https://user-images.githubusercontent.com/29454499/203723317-1716e3ca-b390-47e1-bb98-07b4d8d097a0.png",
891+
"tags": {
892+
"categories": [
893+
"Convert"
894+
],
895+
"libraries": [],
896+
"other": [],
897+
"tasks": [
898+
"Image Segmentation"
899+
]
900+
}
901+
},
889902
"vscode": {
890903
"interpreter": {
891904
"hash": "e0404472fd7b5b63117a9fa5c50283296e2708c2449c6090d2cdf8903f95897f"
@@ -894,4 +907,4 @@
894907
},
895908
"nbformat": 4,
896909
"nbformat_minor": 5
897-
}
910+
}

notebooks/102-pytorch-to-openvino/102-pytorch-to-openvino.ipynb

+13
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,19 @@
11491149
"nbconvert_exporter": "python",
11501150
"pygments_lexer": "ipython3",
11511151
"version": "3.8.10"
1152+
},
1153+
"openvino_notebooks": {
1154+
"imageUrl": "https://user-images.githubusercontent.com/29454499/250586825-2a4a74a6-e091-4e47-8f29-59a72fe4975f.png",
1155+
"tags": {
1156+
"categories": [
1157+
"Convert"
1158+
],
1159+
"libraries": [],
1160+
"other": [],
1161+
"tasks": [
1162+
"Image Classification"
1163+
]
1164+
}
11521165
}
11531166
},
11541167
"nbformat": 4,

notebooks/103-paddle-to-openvino/103-paddle-to-openvino-classification.ipynb

+13
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,19 @@
711711
"pygments_lexer": "ipython3",
712712
"version": "3.10.12"
713713
},
714+
"openvino_notebooks": {
715+
"imageUrl": "https://user-images.githubusercontent.com/77325899/127503530-72c8ce57-ef6f-40a7-808a-d7bdef909d11.png",
716+
"tags": {
717+
"categories": [
718+
"Convert"
719+
],
720+
"libraries": [],
721+
"other": [],
722+
"tasks": [
723+
"Image Classification"
724+
]
725+
}
726+
},
714727
"vscode": {
715728
"interpreter": {
716729
"hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1"

notebooks/104-model-tools/104-model-tools.ipynb

+13-1
Original file line numberDiff line numberDiff line change
@@ -714,8 +714,20 @@
714714
"nbconvert_exporter": "python",
715715
"pygments_lexer": "ipython3",
716716
"version": "3.10.12"
717+
},
718+
"openvino_notebooks": {
719+
"imageUrl": "",
720+
"tags": {
721+
"categories": [
722+
"API Overview",
723+
"Convert"
724+
],
725+
"libraries": [],
726+
"other": [],
727+
"tasks": []
728+
}
717729
}
718730
},
719731
"nbformat": 4,
720732
"nbformat_minor": 5
721-
}
733+
}

notebooks/105-language-quantize-bert/105-language-quantize-bert.ipynb

+12
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,18 @@
941941
"pygments_lexer": "ipython3",
942942
"version": "3.8.10"
943943
},
944+
"openvino_notebooks": {
945+
"imageUrl": "",
946+
"tags": {
947+
"categories": [
948+
"API Overview",
949+
"Optimize"
950+
],
951+
"libraries": [],
952+
"other": [],
953+
"tasks": []
954+
}
955+
},
944956
"vscode": {
945957
"interpreter": {
946958
"hash": "cec18e25feb9469b5ff1085a8097bdcd86db6a4ac301d6aeff87d0f3e7ce4ca5"

notebooks/106-auto-device/106-auto-device.ipynb

+13-2
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@
138138
"\n",
139139
"### Default behavior of Core::compile_model API without device_name\n",
140140
"[back to top ⬆️](#Table-of-contents:)\n",
141-
"",
141+
"\n",
142142
"\n",
143143
"By default, `compile_model` API will select **AUTO** as `device_name` if no device is specified."
144144
]
@@ -794,6 +794,17 @@
794794
"pygments_lexer": "ipython3",
795795
"version": "3.11.5"
796796
},
797+
"openvino_notebooks": {
798+
"imageUrl": "https://user-images.githubusercontent.com/15709723/161451847-759e2bdb-70bc-463d-9818-400c0ccf3c16.png",
799+
"tags": {
800+
"categories": [
801+
"API Overview"
802+
],
803+
"libraries": [],
804+
"other": [],
805+
"tasks": []
806+
}
807+
},
797808
"toc-autonumbering": false,
798809
"toc-showmarkdowntxt": false,
799810
"toc-showtags": false,
@@ -807,4 +818,4 @@
807818
},
808819
"nbformat": 4,
809820
"nbformat_minor": 5
810-
}
821+
}

notebooks/107-speech-recognition-quantization/107-speech-recognition-quantization-data2vec.ipynb

+13
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,19 @@
10151015
"pygments_lexer": "ipython3",
10161016
"version": "3.8.10"
10171017
},
1018+
"openvino_notebooks": {
1019+
"imageUrl": "",
1020+
"tags": {
1021+
"categories": [
1022+
"Optimize"
1023+
],
1024+
"libraries": [],
1025+
"other": [],
1026+
"tasks": [
1027+
"Speech Recognition"
1028+
]
1029+
}
1030+
},
10181031
"vscode": {
10191032
"interpreter": {
10201033
"hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1"

0 commit comments

Comments
 (0)