Package: nuclio-jupyter
Nuclio Function Automation for Python and JupyterPython package for automatically generating and deployingnuclioserverless functions from code, archives or Jupyter notebooks.
Providing a powerful mechanism for automating code and function generation,
simple debugging, lifecycle management, and native integration into data-science tools.The package provides the following featuresAutomatically convert code/files + dependencies (environment, packages configuration, data/files)into nuclio function spec or archiveAutomatically build and deploy nuclio functions (code, spec, or archive) onto a clusterProvide native integration intoJupyterIDE (Menu and %magic commands)Handle function+spec versioning and archiving against an external object storage (s3, http/s, git or iguazio)What is nuclio?nuclio is a high performance serverless platform which runs over docker or kubernetes
and automate the development, operation, and scaling of code (written in multiple supported languages).
nuclio functions can be triggered via HTTP, popular messaging/streaming protocols, scheduled events, and in batch.
nuclio can run in the cloud as a managed offering, or on any Kubernetes cluster (cloud, on-prem, or edge)read more about nuclio ...nuclio and this package are an integral part ofiguazio managed data science platform, you can see many end to end usage examples and notebooks iniguazio tutorialrepo.How does it work?nuclio takes code +function spec+ optional file artifacts and automatically convert them to auto-scaling services over Kubernetes.
the artifacts can be provided as a YAML file (with embedded code), as Dockerfiles, or as archives (Git or Zip).
function spec allow you todefine everythingfrom CPU/Mem/GPU requirements, package dependencies, environment variables, secrets, shared volumes, API gateway config, and more.this package is trying to simplify the configuration and deployment through more abstract APIs and%nucliomagic commands which eventually build the code + spec artifacts in YAML or Archive formats
(archives are best used when additional files need to be packaged or for version control)the%nucliomagic commands are simple to use, but may be limited, if you want more
programmability use thepython API calls(build_file,deploy_fileanddeploy_code) from your code or a notebook cell.UsageInstallingCreating and debugging functions inside a notebook using%nucliomagicExporting functions using Jupyter UICreating and deploying functions using the python APIThe ConfigSpec object, simple way to configure commands, env, triggers, and volumesRunning non python functionsExporting, versioning, and archiving functionsDeploy functions or versions directly from archive or gitControlling function code and configuration:# nuclio:markers- mark relevant code cells (ignore, start-code, end-code)%nuclio cmd- defining package dependencies%nuclio envandenv_file- configuring local and remote env variables%nuclio handler- function handler wrapper%nuclio mount- mounting shared volumes into a function%nuclio config- resources, spec, and triggers configuration%nuclio build- generate and/or upload function spec or archive%nuclio deploy- deploy functions onto the cluster%nuclio show- show generated function code and spec (YAML)Advanced topicsnuclioinit_context()hook for initializing resources (across invocations)changingcontext.loggerverbosity level to DEBUGusing DockerLinksDevelopingLicenceInstallingpip install  --upgrade nuclio-jupyterInstall in a Jupyter Notebook by running the following in a cell# nuclio: ignore
!pip install --upgrade nuclio-jupyterto access the library useimport nuclioCreating and debugging functions using%nucliomagic%nucliomagic commands and some comment notations (e.g.# nuclio: ignore)
help us provide non-intrusive hints as to how we want to convert the notebook into a full function + spec.
cells which we do not plan to include in the final function (e.g. prints, plots, debug code, etc.) are prefixed with# nuclio: ignoreif we want settings such as environment variables and package installations to automatically appear in the fucntion spec
we use theenvorcmdcommands and those will copy them self into the function spec.Note: if we want to ignore many cells at the beginning of the notebook (e.g.
data exploration and model training) we can use# nuclio: startat the first relevant code cell
instead of marking all the cells above with# nuclio: ignore.after we finish writing the code we can simulate the code with the built-in nucliocontextobject
(see: debugging functions) and when we are done we can use theexportcommand to generate the function YAML/archive
or usedeployto automatically deploy the function on a nuclio/kubernetes cluster.we can use other commands likeshowto print out the generated function + spec,configto set various spec params (like cpu/mem/gpu requirements, triggers, etc.),
andmountto auto-mount shared volumes into the function.for more details use the%nuclio helpor%nuclio help <command>.Example:Can see the following example for configuring resources, writing and testing code,
deploying the function, and testing the final function.
note serverless functions have an entry point (handler) which is called by the run time engine and triggers.
the handler carry two objects, acontext(run-time objects like logger) andevent(the body and other attributes delivered by the client or trigger).We start with, importnucilopackage, this initialize the%nucliomagic commands andcontextobject
this section should not be copied to the function so we mark this cell with# nuclio: ignore(or we can use# nuclio: start-codeor# nuclio: end-codeto mark the code section in the notebook).# nuclio: ignoreimportnuclioFunction spec/configurationthe following sections set an environment variable, install desired package,
and set some special configuration (e.g. set the base docker image used for the function).
note the environment variables and packages will be deployed in the notebook AND in the function,
we can specify that we are interested in having them only locally (-l) or in nuclio spec (-c).
we can use local environment variables in those commands with${VAR_NAME}, seehelpfor details.note:%is used for single line commands and%%means the command apply to the entire cell, seedetails%nuclio cmd pip install textblob
%nuclio env TO_LANG=fr
%nuclio config spec.build.baseImage = "python:3.7-buster"magic commands only accept constant values or local environment variables as parameters
if you are interested in more flexibility usenuclio.build_file()ornuclio.deploy_file()API calls, seepython API callsFunction codeIn the cell you'd like to become the handler, you can use one of two ways:create adef handler(context, event)function (the traditional nuclio way)or mark a cell with%%nuclio handlerwhich means this cell is the handler function (the Jupyter way)when using the 2nd approach we mark the return line using# nuclio:returnat the end of it.Local function testingwe can use the built-in nucliocontextandnuclio.Eventobjects to simulate our functions locally,
we create an event object (message body, headers, etc.) and call our function with
thecontextobject and our neweventobject, this will simulate a generated event trigger.
we can also simulate the function with multiple events simply by using aforloop# nuclio: ignoreevent=nuclio.Event(body=b'good morninng')handler(context,event)Function build or deployonce we are done we use the%nuclio deploycommand to build the function and run it on a real cluster,
note the deploy command return a valid HTTP end-point which can be used to test/use our real function.deploy the code as nuclio functionnlpunder projectai:%nuclio deploy -n nlp -p aiwe can use%nuclio buildif we only want to generate the function code + spec or
archive and/or upload/commit them to an external repository without running them on the cluster
this can also be used for automated CI/CD, functions can be built and pushed to GIT
and trigger a CI process which will only deploy the function after it passed tests.if you would like to see the generated code and YAML configuration file before you deploy use%nuclio showcommandfor more flexibility use thenuclio.build_file()ornuclio.deploy_file()API calls, see the example below:# nuclio: ignore# deploy the notebook code with extra configuration (env vars, config, etc.)spec=nuclio.ConfigSpec(config={'spec.maxReplicas':2},env={'EXTRA_VAR':'something'})addr=nuclio.deploy_file(name='nlp',project='ai',verbose=True,spec=spec,tag='v1.1')# invoke the generated functionresp=requests.get('http://'+addr)print(resp.text)Note: Cells containing# nuclio: ignorecomment will be omitted in the build
process.Example Notebook:visitthis linkto see the complete notebook
, or check out thisother exampleThe generated function spec for the above notebook will look like:apiVersion:nuclio.io/v1kind:Functionmetadata:name:nuclio-examplespec:build:baseImage:python:3.7-bustercommands:-pip install textblobnoBaseImagesPull:trueenv:-name:TO_LANGvalue:frhandler:handler:handlerruntime:pythonExporting functions using Jupyter UIin many cases we just want to export the function into a YAML/Zip file and loaded manually to nuclio (e.g. via nuclio UI).
this package automatically register itself as a Jupyter converter, which allow exporting a notebook into nuclio format,
see example below, chooseFile/Download as/Nuclioin Jupyter notebookNote: you might need to mark the notebook asTrustedin order for the Nuclio option to showOr you can runjupyter nbconvert --to nuclio example.ipynbThis will createexample.yamlorexample.zip(if the function include extra files) with your code, spec, and extra files.We currently don't supportGoogle Colaboratory,Kaggle Notebooksand other custom Jupyter versions.Creating and deploying functions using the python APIin some cases working from a notebook is an overkill, or we may want to generate code and configurations programmatically,
thenucliopackage provide two main function callsdeploy_codeanddeploy_filewhich allow us direct access as shown below:importrequestsimportnuclio# define my function code templatecode='''import globdef handler(context, event):context.logger.info('{}')return str(glob.glob('/data/*'))'''# substitute a string in the templatecode=code.format('Hello World!')# define a file share (mount my shared fs home dir into the function /data dir)vol=nuclio.Volume('data','~/')# deploy my code with extra configuration (env vars, mount)spec=nuclio.ConfigSpec(env={'MYENV_VAR':'something'},mount=vol)addr=nuclio.deploy_code(code,name='myfunc',project='proj',verbose=True,spec=spec)# invoke the generated functionresp=requests.get('http://'+addr)print(resp.text)thedeploy_fileAPI allow deploying functions from various file formats (.ipynb,.py,.go,.js,.java,.yaml, or.ziparchives)thebuild_fileAPI is the equivalent of%nuclio buildmagic command (create deployable function or archive and can upload it)The first attribute in those functions is the filename, if left blank it will use the current notebook as sourceThe ConfigSpec object, simple way to configure commands, env, triggers, and volumestheConfigSpecprovide a structures API for configuring functions, the class have the following methods:set_env(name, value)- add environment variableset_config(key, value)- add spec attributeadd_volume(local, remote, kind, name, key, readonly)- add a Kubernetes Volume (v3io or PVC)add_trigger(name, spec)- add a trigger (see below)with_v3io()- addv3ioenvironment variablesmethods can be nested, example:# nuclio: ignorespec=nuclio.ConfigSpec(cmd=build_commands)\.set_config('build.baseImage','python:3.7-buster')\.add_volume(local='User',remote='~/')spec.with_v3io()spec.add_trigger('web',nuclio.triggers.HttpTrigger(workers=4,port=32005).ingress(name,host,paths))spec.add_trigger('cron',nuclio.triggers.CronTrigger(interval='20s',body='scheduled_retraining'))spec.add_trigger('kafka',nuclio.triggers.KafkaTrigger(url,topic,partitions).sasl(user,password))addr=nuclio.deploy_file(name='training',project='netops',verbose=False,spec=spec)Note: such a section must be outside the code cells, usecode section markers.Running non python functionsthe library is not limited to python code, it support other languages such asgo,node.js,java, andbash. see the following example with bash code. note that
you can install any package/binary inside the function using the build commands (cmd=).importrequestsimportnucliocode='''echo "good morning"echo $SOME_ENV'''spec=nuclio.ConfigSpec(env={'SOME_ENV':'env text'},cmd=['apk --update --no-cache add imagemagick'])addr=nuclio.deploy_code(code,lang='.sh',name='mysh',project='demo',spec=spec)# invoke the generated functionresp=requests.get('http://'+addr)print(resp.text)output:good morning
env textExporting, versioning, and archiving functionsnuclio functions are a great way to provide well defined code + dependencies + environment definitions,
functions can be versioned, archived, and restored by simply storing and re-applying their artifacts.after we defined a functions using the%nucliomagic commands or directly from the API, we canbuildthem,
we can also use theaddmagic command orfilesAPI attribute to pack multiple files in the sameziparchive with the code and spec,
store it locally or upload the archive to cloud storage using a single command.when we want to deploy a function from a URL or archive we use thedeploycommand or API,
specify the URL (vs the code or notebook) as source and the function will be deployed automatically.we currently support the following archive options:local/shared file system, http(s) unauthenticated or with Basic auth, Github, AWS S3, and iguazio PaaS.note: that at this point nuclio doesnt support pulling archives directly from secret protected S3 bucketsseebuildanddeploycommands help below for detailsExample using magic commandsspecify additional files to pack with the function (will force the use ofzip)%nuclio add -f model.json -f mylib.pyconvert the current notebook into a function archive and upload into remote object store%nuclio build -p myproj -t v1.1 -o s3://my-bucket/sub-dir -adeploy and older version from an archive and name itnewfunc%nuclio deploy https://my-bucket.s3.amazonaws.com/sub-dir/myproj/funcname_v1.1.zip -n newfuncnote:buildanddeploycommands dont have to run from the same notebook, seehelpfor detailed command options.Example using the API# nuclio: ignorespec=nuclio.ConfigSpec(env={'TO_LANG':'de'})nuclio.build_file(name='nlp',spec=spec,project='proj',tag='v7',verbose=True,output_dir='v3io:///bigdata',archive=True)# deploy the archived functionspec=nuclio.ConfigSpec(env={'TO_LANG':'fr'})addr=nuclio.deploy_file('v3io:///bigdata/proj/nlp_v7.zip',name='nlp2',spec=spec,project='p1',tag='v8')# invoke the generated functionresp=requests.get('http://'+addr)print(resp.text)Deploy functions or versions directly from archive or gitusers can deploy functions from an archive (.zipfile) or Git repository,
and override various functionspecparameters (e.g. change environment variables,
add a custom trigger, etc.).functions are versioned (using thetagattribute), we can load from a version
and deploy under a version (which can have a different tag)in order to deploy from an archive you must specify an archive source URL (must start withhttp(s)://,v3io://, orgit://)example:%nuclio deploy https://myurl.com/projects/myfunc-v1.zip -n myfunc -p myprojDeploy functions directly from Githubexample: deploying functions from nuclio examples repositoryaddr=nuclio.deploy_file('git://github.com/nuclio/nuclio#master:/hack/examples/python/helloworld',name='hw',project='myproj')resp=requests.get('http://'+addr)print(resp.text)the Git URL convention is:git://[token@]github.com/org/repo#master[:<workdir>],
tokens are only needed for private repositories and can also be provided through theGIT_ACCESS_TOKENenvironment variable.workdiris optional, specify the sub directory for the function within the repositoryTo upload function artifact (function.yaml+ code + extra files) to git you can generate the artifacts using thebuildcommand (specify desiredoutput-dir), followed by committing and pushing the updates into your Git repo.note that you can specify the desired branch in the url.Controlling function code and configurationnuclio code section markers (# nuclio: ignore/code-start/code-end)A user may want to include code sections in the notebook which should not
translate to function code, for that he can use the following code markers (comment lines):# nuclio : ignore- ignore the current cell when building the function# nuclio : code-start- ignore any lines prior to this line/cell# nuclio : code-end- ignore any cell from this cell (included) to the endcmdRun a command, add it to "build.Commands" in exported configuration.Examples:
In [1]: %nuclio cmd pip install chardet==1.0.1

In [2]: %%nuclio cmd
...: apt-get install -y libyaml-dev
...: pip install pyyaml==3.13If you'd like to only to add the instructions to function.yaml without
running it locally, use the '--config-only' or '-c' flagIn [3]: %nuclio cmd --config-only apt-get install -y libyaml-devenvSet environment variable. Will update "spec.env" in configuration.Examples:
In [1]: %nuclio env USER=iguzaio
%nuclio: setting 'iguazio' environment variable

In [2]: %%nuclio env
...: USER=iguazio
...: PASSWORD=t0ps3cr3t
...:
...:
%nuclio: setting 'USER' environment variable
%nuclio: setting 'PASSWORD' environment variableNote: there is a magic environment variable%v3iowhich adds the v3io
connection env vars to the function, e.g.%nuclio env %v3ioIf you'd like to only to add the instructions to function.yaml without
running it locally, use the '--config-only' or '-c' flagIn [3]: %nuclio env --config-only MODEL_DIR=/homeIf you'd like to only run locally and not to add the instructions to
function.yaml, use the '--local-only' or '-l' flagenv_fileSet environment from file(s). Will update "spec.env" in configuration.Examples:
In [1]: %nuclio env_file env.yml

In [2]: %%nuclio env_file
...: env.yml
...: dev-env.ymlhandlerMark this cell as handler function. You can give optional name%%nuclio handler
context.logger.info('handler called')
# nuclio:return
'Hello ' + event.body

Will become

def handler(context, event):
    context.logger.info('handler called')
    # nuclio:return
    return 'Hello ' + event.bodymountMount a shared file Volume into the function.Example:
In [1]: %nuclio mount /data /projects/netops/data
mounting volume path /projects/netops/data as /dataconfigSet function configuration value (resources, triggers, build, etc.).
Values need to numeric, strings, or json strings (1, "debug", 3.3, {..})
You can use += to append values to a list.see thenuclio configuration referenceExample:
In [1] %nuclio config spec.maxReplicas = 5
In [2]: %%nuclio config
...: spec.maxReplicas = 5
...: spec.runtime = "python2.7"
...: build.commands +=  "apk --update --no-cache add ca-certificates"buildBuild notebook/code + config, and generate/upload yaml or archive.%nuclio build [filename] [flags]

when running inside a notebook the the default filename will be the
notebook it self

-n, --name path
    function name, optional (default is filename)
-t, --tag tag
    version tag (label) for the function
-p, --project
    project name (required for archives)
-a, --archive
    indicate that the output is an archive (zip)
-o, --output-dir path
    Output directory/file or upload URL (see below)
--handler name
    Name of handler function (if other than 'handler')
-e, --env key=value
    add/override environment variable, can be repeated
-v, --verbose
    emit more logs

supported output options:
    format:  [scheme://[username:secret@]path/to/dir/[name[.zip|yaml]]
             name will be derived from function name if not specified
             .zip extensions are used for archives (multiple files)

    supported schemes and examples:
        local file: my-dir/func
        AWS S3:     s3://<bucket>/<key-path>
        http(s):    http://<api-url>/path
        iguazio:    v3io://<api-url>/<data-container>/path

Example:
In [1] %nuclio build -v
In [2] %nuclio build --output-dir .
In [3] %nuclio build /path/to/code.py --handler faces
In [4] %nuclio build --tag v1.1 -e ENV_VAR1="some text" -e ENV_VAR2=xx
In [5] %nuclio build -p myproj -t v1.1 --output-dir v3io:///bigdata -adeployDeploy notebook/file with configuration as nuclio function.%nuclio deploy [file-path|url] [options]

parameters:
-n, --name path
    function name, optional (default is filename)
-p, --project
    project name (required)
-t, --tag tag
    version tag (label) for the function
-d, --dashboard-url
    nuclio dashboard url
-o, --output-dir path
    Output directory/file or upload URL (see below)
-a, --archive
    indicate that the output is an archive (zip)
--handler name
    Name of handler function (if other than 'handler')
-e, --env key=value
    add/override environment variable, can be repeated
-v, --verbose
    emit more logs

when deploying a function which contains extra files or if we want to
archive/version functions we specify output-dir with archiving option (-a)
(or pre-set the output using the NUCLIO_ARCHIVE_PATH env var
supported output options include local path, S3, and iguazio v3io

following urls can be used to deploy functions from a remote archive:
  http(s):  http://<api-url>/path.zip[#workdir]
  iguazio:  v3io://<api-url>/<data-container>/project/name_v1.zip[#workdir]
  git:      git://[token@]github.com/org/repo#master[:<workdir>]

Examples:
In [1]: %nuclio deploy
In [2] %nuclio deploy -d http://localhost:8080 -p tango
In [3] %nuclio deploy myfunc.py -n new-name -p faces
In [4] %nuclio deploy git://github.com/myorg/repo#master -n myfunc -p projshowPrint out the function code and spec (YAML).
You should save the notebook before calling this function.Advanced topicsnuclioinit_context()hook for initializing resources (across invocations)TBDchangingcontext.loggerverbosity level to DEBUGby default the built-in context object is set to print logs at INFO level and above,
if we want to print out the debug level logs we can type the followingnuclio.context.set_logger_level(True)this logging level only apply to the notebook/emulation, to change the function runtime
log level you should use theconfigor nuclio UI.using DockerYou can build a docker image and try it outBuild$ docker build -t jupyter-nuclio .Run$ docker run -p 8888:8888 jupyter-nuclioThen open your browser athttp://localhost:8888Linksiguazio tutorial repo- hosts many usage examplesDevelopingWe're usingpipenvas package manager. To install
dependencies run$ pipenv sync -dTo run the tests run$ pipenv run python -m pytest -v testsTo upload to pypi either runmake uploadafter changing version innuclio/__init__.pyorpython cut_release <version>. The latter will update
the version innuclio/__init__.py. You can use+for the next version. Ask
around for pypi credentials.LicenceApache 2.0 (seeLICENSE.txt)