{"id":20588691,"url":"https://github.com/ciscodevnet/ncc","last_synced_at":"2025-04-06T09:09:10.346Z","repository":{"id":15167310,"uuid":"75196863","full_name":"CiscoDevNet/ncc","owner":"CiscoDevNet","description":"ncclient scripts and helpers","archived":false,"fork":false,"pushed_at":"2025-02-22T15:46:17.000Z","size":576,"stargazers_count":67,"open_issues_count":4,"forks_count":29,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-03-30T08:09:01.918Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Jupyter Notebook","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CiscoDevNet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-11-30T14:52:32.000Z","updated_at":"2025-03-25T14:04:50.000Z","dependencies_parsed_at":"2025-03-23T06:10:39.349Z","dependency_job_id":"1acf3e76-bc87-45da-99dc-c50c9cb71250","html_url":"https://github.com/CiscoDevNet/ncc","commit_stats":{"total_commits":196,"total_committers":9,"mean_commits":21.77777777777778,"dds":0.5051020408163265,"last_synced_commit":"920025b10a11beb5beb814a84850387474867c3a"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CiscoDevNet%2Fncc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CiscoDevNet%2Fncc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CiscoDevNet%2Fncc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CiscoDevNet%2Fncc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CiscoDevNet","download_url":"https://codeload.github.com/CiscoDevNet/ncc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247457803,"owners_count":20941906,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T07:25:55.243Z","updated_at":"2025-04-06T09:09:10.328Z","avatar_url":"https://github.com/CiscoDevNet.png","language":"Jupyter Notebook","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Various Scripts \u0026 Jupyter Notebooks\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Various Scripts \\\u0026 Jupyter Notebooks](#various-scripts--jupyter-notebooks)\n  - [New \\\u0026 Updated](#new--updated)\n  - [Introduction](#introduction)\n  - [PyPi Upload Instructions](#pypi-upload-instructions)\n  - [Python Scripts](#python-scripts)\n    - [Running The Scripts](#running-the-scripts)\n    - [ncc-establish-subscription.py](#ncc-establish-subscriptionpy)\n    - [ncc](#ncc)\n      - [Device Capabilities](#device-capabilities)\n      - [Snippets](#snippets)\n  - [Running The Jupyter Notebooks](#running-the-jupyter-notebooks)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## New \u0026 Updated\n\n|  Date  | Status |  Description  |\n| :----: | :----: | :------------ |\n| 02/22/25 | ![](images/new.png) | Moved to Poetry | \n| 08/17/18 |  | Added option to specify # bytes displayed for UnicodeDecodeError exceptions | \n| 08/15/18 |  | Added operation timing plus helpful display of UnicodeDecodeError exceptions to `ncc` | \n| 03/11/18 |  | Code review comments addressed, convenience links to still have .py versions of scripts added, `ncc --env` now shows command line option environment variables apply to |\n| 02/21/18 |  | Tweaks to `ncc-capture-schema` plus its addition to packaged scripts |\n| 02/14/18 |  | Addition of `--install-snippets` and `--env` options to `ncc`.\n| 02/14/18 |  | Preparation for pip installation and PyPi upload; removing `.py` extensions from scripts that will be pip-installed; addition of copyright statements and [`LICENSE.txt`](LICENSE.txt); removed legacy script links.\n| 02/09/18 |  | Addition of `--ns` option for XPath filters, allowing either direct list of namespace mapping or via a file (sample file [here](sample-ns.json)) \n\n\n## Introduction\n\nThis repository presents:\n\n* Python scripts using the ncclient library (`0.5.2` or greater as of writing) to talk to NETCONF-enabled devices.\n* Jupyter (IPython) Notebooks in the directory [`notebooks`](notebooks).\n\n\n## PyPi Upload Instructions\n\nFirst, tag your build appropriately (`git tag vX.Y.Z`) build using `poetry build` and ensure you have defined the repositories `ncc` and `ncc-test` in your `~/.pypirc` file. Then you may test the upload:\n\n```\ntwine upload --repository ncc-test dist/ncc-X.Y.Z.tar.gz\n```\n\nFinally, do the producvtion upload:\n\n```\ntwine upload --repository ncc dist/ncc-X.Y.Z.tar.gz\n```\n\n\n## Python Scripts\n\nAll scripts are in [`src/scripts`](src/scripts). Here is a description of those installed as part of the package:\n\n* `ncc` -- A kind of Swiss Army Knife script with many options to get-config, get, edit-config, pass in parameters for substitution, etc. Can be easily extended by users to have more edit-config templates or more named filter templates. Available content can be seen using the ```--list-templates``` and ```--list-filters``` parameters.\n\n* `ncc-get-all-schema` -- Script that attempts to download all the supported schema that the box has and tries to compile them, determine missing includes or imports, etc.\n\n* `ncc-get-schema` -- Script to get a single names schema and dup it to ```STDOUT```.\n\n* `ncc-capture-schema` -- Script to capture the schema from a device and commit int a git reposiroty structured per [YangModels/yang](https://github.com/YangModels/yang). Uses netmiko to capture some initial device information, and needs device type passed in from CLI (per netmiko device types). Currently only supports IOS-XR, IOS-XE and NX-OS without changes. Fairly easy to add other device types.\n\n* `ncc-yang-push` -- Script to work with telemetry subscriptions.\n\nThere are som other draft scripts that can serve as examples:\n\n* `ncc-establish-subscription.py` -- Simple script to allow the creation of multiple dynamic telemetry subscriptions per an early draft of the IETF YANG Push functionality. Currently supported on IOS-XE 16.6.1 and later. Initial support was for switching platforms, with other platforms being supported in subsequent releases. **Note that this script requires a fork of the `ncclient` library. Once the Python dependencies above have been installed, the forked version may be installed using the command `pip install --upgrade git+https://github.com/CiscoDevNet/ncclient.git`**. Please see [here](https://github.com/CiscoDevNet/ncclient/blob/master/README.md) for more details.\n\n* `ncc-filtered-get.py` -- Very simple script that takes a subtree filter and does a get.\n\n* `ncc-simple-poller.py` -- Script that polls a device on a specified cadence for a specified subtree or XPath filter.\n\n* `rc-xr.py` -- Embryonic RESTCONF sample script using the Python `requests` library.\n\n\nMore scripts may exist. The git repo is the most up to date record, not this README!\n\n\n### Running The Scripts\n\nThe scripts mostly have a fairly common set of options for help, hostname, port, username and password. Just try running with the `--help` option.\n\n\u003e Note that the help text displayed here may be out of step with the actual code. **Please run latest version of the script to ensure satisfaction!**\n\n\n### ncc-establish-subscription.py\n\n\u003e Note that this script requires a fork of the `ncclient` library. Once the Python dependencies above have been installed, the forked version may be installed using the command:\n\u003e\n\u003e`pip install --upgrade git+https://github.com/CiscoDevNet/ncclient.git`.\n\u003e\n\u003e Please see [here](https://github.com/CiscoDevNet/ncclient/blob/master/README.md) for more details.\n\n```\n$ ./ncc-establish-subscription.py --help\nusage: ncc-establish-subscription.py [-h] [--host HOST] [-u USERNAME]\n                                     [-p PASSWORD] [--port PORT] [-v]\n                                     [--delete-after DELETE_AFTER]\n                                     [-x XPATHS [XPATHS ...]]\n                                     (--period PERIOD | --dampening-period DAMPENING_PERIOD)\n\nSelect your telemetry parameters:\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --host HOST           The IP address for the device to connect to (default\n                        localhost)\n  -u USERNAME, --username USERNAME\n                        Username to use for SSH authentication (default\n                        'cisco')\n  -p PASSWORD, --password PASSWORD\n                        Password to use for SSH authentication (default\n                        'cisco')\n  --port PORT           Specify this if you want a non-default port (default\n                        830)\n  -v, --verbose         Exceedingly verbose logging to the console\n  --delete-after DELETE_AFTER\n                        Delete the established subscription after N seconds\n  -x XPATHS [XPATHS ...], --xpaths XPATHS [XPATHS ...]\n                        List of xpaths to subscribe to, one or more\n  --period PERIOD       Period in centiseconds for periodic subscription\n  --dampening-period DAMPENING_PERIOD\n                        Dampening period in centiseconds for on-change\n                        subscription\n\n```\n\n### ncc\n\n```\n$ ncc --help\nusage: ncc [-h] [--host HOST] [-u USERNAME] [-p PASSWORD] [--port PORT]\n           [--timeout TIMEOUT] [-v] [--default-op DEFAULT_OP]\n           [--device-type DEVICE_TYPE] [--snippets SNIPPETS]\n           [--ns NS [NS ...]] [--params PARAMS] [--params-file PARAMS_FILE]\n           [-f FILTER | --named-filter NAMED_FILTER [NAMED_FILTER ...] | -x\n           XPATH]\n           (--env | --install-snippets | -c | --is-supported IS_SUPPORTED | --list-templates | --list-filters | -g | --get-oper | --do-edits DO_EDITS [DO_EDITS ...] | -w)\n\nSelect your NETCONF operation and parameters:\n\noptional arguments:\n  -h, --help            show this help message and exit\n  --host HOST           The IP address for the device to connect to (default\n                        localhost)\n  -u USERNAME, --username USERNAME\n                        Username to use for SSH authentication (default\n                        'cisco')\n  -p PASSWORD, --password PASSWORD\n                        Password to use for SSH authentication (default\n                        'cisco')\n  --port PORT           Specify this if you want a non-default port (default\n                        830)\n  --timeout TIMEOUT     NETCONF operation timeout in seconds (default 60)\n  -v, --verbose         Exceedingly verbose logging to the console\n  --default-op DEFAULT_OP\n                        The NETCONF default operation to use (default 'merge')\n  --device-type DEVICE_TYPE\n                        The device type to pass to ncclient (default: None)\n  --snippets SNIPPETS   Directory where 'snippets' can be found; default is\n                        location of script\n  --ns NS [NS ...]      Specify list of prefix=NS bindings or JSON files with\n                        bindings. @filename will read a JSON file and update\n                        the set of namespace bindings, silently overwriting\n                        with any redefinitions.\n  --params PARAMS       JSON-encoded string of parameters dictionary for\n                        templates\n  --params-file PARAMS_FILE\n                        JSON-encoded file of parameters dictionary for\n                        templates\n  -f FILTER, --filter FILTER\n                        NETCONF subtree filter\n  --named-filter NAMED_FILTER [NAMED_FILTER ...]\n                        List of named NETCONF subtree filters\n  -x XPATH, --xpath XPATH\n                        NETCONF XPath filter\n  --env                 Display environment variables a user can set.\n  --install-snippets    Use git to obtain the snippets from GitHub and copy to\n                        the current directory\n  -c, --capabilities    Display capabilities of the device.\n  --is-supported IS_SUPPORTED\n                        Query the server capabilities to determine whether the\n                        device claims to support YANG modules matching the\n                        provided regular expression. The regex provided is not\n                        automatically anchored to start or end. Note that the\n                        regex supplied must be in a format valid for Python\n                        and that it may be necessary to quote the argument.\n  --list-templates      List out named edit-config templates\n  --list-filters        List out named filters\n  -g, --get-running     Get the running config\n  --get-oper            Get oper data\n  --do-edits DO_EDITS [DO_EDITS ...]\n                        Execute a sequence of named templates with an optional\n                        default operation and a single commit when candidate\n                        config supported. If only writable-running support,\n                        ALL operations will be attempted.\n  -w, --where           Print where script is and exit\n```\n\nIn subsequent sections some of its capabilities will be expanded on.\n\n#### Device Capabilities\n\nIt is now possible to query the device either to return a categorized list of capabilities and models or to return the models matching a provided Python regular expression.\n\nTo get device capabilities:\n\n```\npython ncc --host=192.239.42.222 --capabilities\nIETF NETCONF Capabilities:\n\turn:ietf:params:netconf:capability:rollback-on-error:1.0\n\turn:ietf:params:netconf:base:1.1\n\turn:ietf:params:netconf:capability:candidate:1.0\n\turn:ietf:params:netconf:capability:validate:1.1\n\turn:ietf:params:netconf:capability:confirmed-commit:1.1\nIETF Models:\n\tietf-netconf (urn:ietf:params:xml:ns:netconf:base:1.0)\n\tietf-syslog-types (urn:ietf:params:xml:ns:yang:ietf-syslog-types)\n\tietf-yang-smiv2 (urn:ietf:params:xml:ns:yang:ietf-yang-smiv2)\n\tietf-netconf-with-defaults (urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults)\n\tietf-netconf-monitoring (urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring)\n\tietf-yang-types (urn:ietf:params:xml:ns:yang:ietf-yang-types)\n\tiana-if-type (urn:ietf:params:xml:ns:yang:iana-if-type)\n\tietf-inet-types (urn:ietf:params:xml:ns:yang:ietf-inet-types)\nOpenConfig Models:\n\topenconfig-bgp-multiprotocol (http://openconfig.net/yang/bgp-multiprotocol)\n\topenconfig-bgp-policy (http://openconfig.net/yang/bgp-policy)\n\topenconfig-bgp-types (http://openconfig.net/yang/bgp-types)\n\topenconfig-mpls-rsvp (http://openconfig.net/yang/rsvp)\n\topenconfig-routing-policy (http://openconfig.net/yang/routing-policy)\n\topenconfig-bgp-operational (http://openconfig.net/yang/bgp-operational)\n\topenconfig-extensions (http://openconfig.net/yang/openconfig-ext)\n\topenconfig-telemetry (http://openconfig.net/yang/telemetry)\n\topenconfig-mpls-sr (http://openconfig.net/yang/sr)\n\topenconfig-if-ethernet (http://openconfig.net/yang/interfaces/ethernet)\n\topenconfig-vlan (http://openconfig.net/yang/vlan)\n\topenconfig-policy-types (http://openconfig.net/yang/policy-types)\n\topenconfig-types (http://openconfig.net/yang/openconfig-types)\n\topenconfig-mpls-types (http://openconfig.net/yang/mpls-types)\n\topenconfig-if-ip (http://openconfig.net/yang/interfaces/ip)\n\topenconfig-if-aggregate (http://openconfig.net/yang/interface/aggregate)\n\topenconfig-bgp (http://openconfig.net/yang/bgp)\n\topenconfig-mpls (http://openconfig.net/yang/mpls)\n\topenconfig-interfaces (http://openconfig.net/yang/interfaces)\n\topenconfig-mpls-ldp (http://openconfig.net/yang/ldp)\n...etc...\n```\n\nTo query for supported models (running against an IOS-XR image):\n\n```\n15:10 $ python ncc --host=192.239.42.222 --is-supported '(?i)snmp'\nSNMP-NOTIFICATION-MIB\nSNMP-MPD-MIB\nCisco-IOS-XR-snmp-entstatemib-cfg\nCisco-IOS-XR-snmp-agent-oper\nSNMP-FRAMEWORK-MIB\nCisco-IOS-XR-snmp-agent-cfg\nSNMP-COMMUNITY-MIB\nCisco-IOS-XR-snmp-entitymib-oper\nCisco-IOS-XR-snmp-test-trap-act\nCisco-IOS-XR-snmp-syslogmib-cfg\nCisco-IOS-XR-snmp-ifmib-oper\nSNMPv2-TC\nSNMP-USER-BASED-SM-MIB\nSNMPv2-MIB\nCisco-IOS-XR-snmp-ifmib-cfg\nCisco-IOS-XR-snmp-mib-rfmib-cfg\nCisco-IOS-XR-snmp-ciscosensormib-cfg\nSNMP-VIEW-BASED-ACM-MIB\nCisco-IOS-XR-snmp-entitymib-cfg\nSNMP-TARGET-MIB\nCisco-IOS-XR-snmp-sensormib-oper\nCisco-IOS-XR-snmp-frucontrolmib-cfg\n```\n\nAdditionally, this example shows how to use case-insentitive regex matches in Python.\n\n#### Snippets\n\nSnippets are a way to pre-define edit-config messages or complex filters that you want to use from the command line. Snippets are simple Jinja2 templates, with parameters provided either from the command line or via a file.\n\nSnippets are by default found in a directory  ```snippets``` colocated with the ```ncc.py``` script.\nNamed subtree filters are stored in [snippets/filters](snippets/filters) and named edit-config templates are stored in [snippets/editconfigs](snippets/editconfigs). The naming convention is fairly obvious; templates files end in ```.tmpl```, but when referred to via CLI arguments the extension is ommitted.\n\nThe command line option ```--snippets``` may be used to define an alternate location for the ```snippets``` directory.\nA directory structure as shown below must exist in the location pointed to by the ```--snippets``` parameter.\nFor example, ```--snippets ./snippets-xe``` would expect the following directory structure.\n\n```\nsnippets-xe\n├── editconfigs\n└── filters\n```\n\nThe snippets for both edit config messages and named filters now support a JSON format for specifying parameters either on the command line of in a provided file. For example, we may have the filter snippet in file ```intf-brief.tmpl```:\n\n```\n\u003cinterfaces xmlns=\"http://cisco.com/ns/yang/Cisco-IOS-XR-pfi-im-cmd-oper\"\u003e\n  \u003cinterface-briefs\u003e\n    \u003cinterface-brief\u003e\n      \u003cinterface-name\u003e{{INTF_NAME}}\u003c/interface-name\u003e\n    \u003c/interface-brief\u003e\n\u003c/interfaces\u003e\n```\n\nThen, run against IOS-XR:\n\n```\n$ python ncc --host=192.239.42.222 --get-oper --named-filter intf-brief --params '{\"INTF_NAME\":\"GigabitEthernet0/0/0/0\"}'\n\u003cdata xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"\u003e\n  \u003cinterfaces xmlns=\"http://cisco.com/ns/yang/Cisco-IOS-XR-pfi-im-cmd-oper\"\u003e\n   \u003cinterface-briefs\u003e\n    \u003cinterface-brief\u003e\n     \u003cinterface-name\u003eGigabitEthernet0/0/0/0\u003c/interface-name\u003e\n     \u003cinterface\u003eGigabitEthernet0/0/0/0\u003c/interface\u003e\n     \u003ctype\u003eIFT_GETHERNET\u003c/type\u003e\n     \u003cstate\u003eim-state-admin-down\u003c/state\u003e\n     \u003cactual-state\u003eim-state-admin-down\u003c/actual-state\u003e\n     \u003cline-state\u003eim-state-admin-down\u003c/line-state\u003e\n     \u003cactual-line-state\u003eim-state-admin-down\u003c/actual-line-state\u003e\n     \u003cencapsulation\u003eether\u003c/encapsulation\u003e\n     \u003cencapsulation-type-string\u003eARPA\u003c/encapsulation-type-string\u003e\n     \u003cmtu\u003e1514\u003c/mtu\u003e\n     \u003csub-interface-mtu-overhead\u003e0\u003c/sub-interface-mtu-overhead\u003e\n     \u003cl2-transport\u003efalse\u003c/l2-transport\u003e\n     \u003cbandwidth\u003e1000000\u003c/bandwidth\u003e\n    \u003c/interface-brief\u003e\n   \u003c/interface-briefs\u003e\n  \u003c/interfaces\u003e\n \u003c/data\u003e\n```\n\nOr:\n\n```\n$ echo '{\"INTF_NAME\":\"GigabitEthernet0/0/0/0\"}' \u003e test_params.json\n$ python ncc --host=192.239.42.222 --get-oper --named-filter intf-brief --params-file test_params.json\n\u003cdata xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"\u003e\n  \u003cinterfaces xmlns=\"http://cisco.com/ns/yang/Cisco-IOS-XR-pfi-im-cmd-oper\"\u003e\n   \u003cinterface-briefs\u003e\n    \u003cinterface-brief\u003e\n     \u003cinterface-name\u003eGigabitEthernet0/0/0/0\u003c/interface-name\u003e\n     \u003cinterface\u003eGigabitEthernet0/0/0/0\u003c/interface\u003e\n     \u003ctype\u003eIFT_GETHERNET\u003c/type\u003e\n     \u003cstate\u003eim-state-admin-down\u003c/state\u003e\n     \u003cactual-state\u003eim-state-admin-down\u003c/actual-state\u003e\n     \u003cline-state\u003eim-state-admin-down\u003c/line-state\u003e\n     \u003cactual-line-state\u003eim-state-admin-down\u003c/actual-line-state\u003e\n     \u003cencapsulation\u003eether\u003c/encapsulation\u003e\n     \u003cencapsulation-type-string\u003eARPA\u003c/encapsulation-type-string\u003e\n     \u003cmtu\u003e1514\u003c/mtu\u003e\n     \u003csub-interface-mtu-overhead\u003e0\u003c/sub-interface-mtu-overhead\u003e\n     \u003cl2-transport\u003efalse\u003c/l2-transport\u003e\n     \u003cbandwidth\u003e1000000\u003c/bandwidth\u003e\n    \u003c/interface-brief\u003e\n   \u003c/interface-briefs\u003e\n  \u003c/interfaces\u003e\n \u003c/data\u003e\n\n```\nIf you do not supply all of the required vars, you will get an error when using the template.  For example in the above\n\n```\npython ncc --host=192.239.42.222 --get-oper --named-filter intf-brief\nUndefined variable 'INTF_NAME' is undefined.  Use --params to specify json dict\n\n```\n\nIf you wish to leave a variable empty (for example in a filter, rather than edit-config, you can just specify it as \"\"\n\n```\n{\"INTF_NAME\" : \"\"}\n```\n\nWhen edit-config templates or filters are listed (```--list-templates``` or ```--list-filters```), the variables that need to be substituted are also listed. For example:\n\n```\n11:28 $ ncc --list-templates\nEdit-config templates:\n  add_neighbor                           \u003c\u003c-- template name\n    DESCRIPTION                          \u003c\u003c-- substitution\n    NEIGHBOR_ADDR\n    REMOTE_AS\n  add_static_route_default\n  del_neighbor\n    NEIGHBOR_ADDR\n```\n\n## Running The Jupyter Notebooks\n\nThe jupyter notebook server should be run inside the same Python virtualenv as you created above for running the Python scripts, with one addition, which is to run ```pip install jupyter``` in the virtual environment, as it is not currently listed in the [```requirements.txt```](requirements.txt) file.\n\nOnce Jupyter installed, the notebook server is run up thus:\n\n```\n$ pwd\n/opt/git-repos/ncc\n$ . v/bin/activate\n(v) EINARNN-M-D10Q:ncc einarnn$ jupyter notebook\n[I 16:39:38.230 NotebookApp] The port 8888 is already in use, trying another port.\n[I 16:39:38.240 NotebookApp] Serving notebooks from local directory: /opt/git-repos/ncc\n[I 16:39:38.240 NotebookApp] 0 active kernels\n[I 16:39:38.240 NotebookApp] The Jupyter Notebook is running at: http://localhost:8889/\n[I 16:39:38.240 NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).\n```\n\nWhen the notebook server is running, it will also open up a web page with your default web browser, pointing to the jupyter notebook server. Just pick one of the notebooks in the [notebooks](notebooks) directory (```*.ipynb```) and away you go!!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fciscodevnet%2Fncc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fciscodevnet%2Fncc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fciscodevnet%2Fncc/lists"}