Package: mfn-sdk
KNIX MicroFunctions SDKEasy-to use package to access the management interface of KNIX MicroFunctions as well as
deployed workflows.The latest version of the SDK can be obtained fromKNIX releases.
It is also hosted at PyPI and can be installed with the PyPA recommended tool for installing Python packages:pip3installmfn_sdkSetup the clientThe MFN client can be configured by various means, using precedence of the following order:configuration file../settings.json,~/settings.jsonand/or./settings.json)environment variables (MFN_URL,MFN_USER,MFN_PASSWORD,MFN_NAME)using the constructorMfnClient(mfn_url,mfn_user,mfn_password,mfn_name,proxies)The configuration file should contain a JSON dictionary with the parameter names as keys:{"mfn_url":"<http://host:port>","mfn_user":"<email>","mfn_password":"<password>","mfn_name":"<full name>","proxies":{"http":"http://<proxyhost>:<port>","https":"http://<proxyhost>:<port>"}}An equivalent of environment variables can also be used, with the exception of the proxy configuration, which uses thehttp_proxyandhttps_proxyvariables:exportMFN_URL="<http://host:port>"exportMFN_USER="<email>"exportMFN_PASSWORD="<password>"exportMFN_NAME="<full name>"exportHTTP_PROXY="http://<proxyhost>:<port>"# or http_proxyexportHTTPS_PROXY="http://<proxyhost>:<port>"# or https_proxyTo overwrite parameters at runtime, they can be passed in the constructor.frommfn_sdkimportMfnClient# MfnClient(mfn_url,mfn_user,mfn_password,mfn_name,proxies)mfn=MfnClient(mfn_url="<http://host:port>",mfn_user="<email>",mfn_password="<password>",mfn_name="<full name>",proxies={"http":"http://<proxyhost>:<port>","https":"http://<proxyhost>:<port>"})NOTE: Themfn_nameparameter is only used if the user does not exist (as it is required for every new user). If the parameter is missing, the client SDK will only try to login but won't create a user.List functions and workflowsfrommfn_sdkimportMfnClientmfn=MfnClient(mfn_url="https://knix.io",mfn_user="test@example.com",mfn_password="test123",mfn_name="Mr. Test")forfunctioninmfn.functions:print(function)forworkflowinmfn.workflows:print(workflow)Create a new workflowTo create a simple workflow with just a single function, the function source and the workflow description is required.
A function can have plaintext code or a ZIP file or both attached to it (more below).function=mfn.add_function("echo")function.code="""def handle(event, context):context.log("Echoing"+event)return event"""The associated workflow description is provided as a string containing the JSON.wf=mfn.add_workflow('wf_echo')wf.json="""{"Comment": "Echo workflow","StartAt": "entry","States": {"entry": {"Type": "Task","Resource": "echo","End": true}}}"""Read and write objects (Note: only strings are allowed)The key-value storage shared by workflows of a tenant can be modified or accessed using put(), get() and delete() on the client object:mfn.put("my_key","some-value")print("We have stored: "+mfn.get("my_key"))mfn.delete("my_key")mfn.keys()# should be empty listFunction ZIPsA function can be a source code string and/or a ZIP file. If the ZIP file contains a source file with the name of the resource (i.e., function name), then its handle function would be used as a starting point.
However, if source code is also attached as a string, it would overwrite said file and be used instead.In the following example, the current directory is zipped and uploaded as a function ZIP.importosfromzipfileimportZipFile# Create a new functiong=mfn.add_function('myfunction')# Create a zip file from the directory contentszip_name="myfunction.zip"ifos.path.exists(zip_name):os.remove(zip_name)forroot,dirs,filesinos.walk('.'):withZipFile(zip_name,'w')aszf:forfninfiles:zf.write(fn)# upload the zip fileg.upload(zip_name)Execute workflowsOnce a workflow has been created and its functions have been uploaded, it can be deployed and executed using the client SDK.
Thedeploy(timeout=None)function can use a timeout. Iftimeout=None, it will immediately return after requesting deployment. Iftimeout=0, it will wait indefinitely for the workflow to change its status to "deployed". Anytimeout > 0will wait for that many seconds and throw an exception if the workflow hasn't reached the status "deployed" by then.Theexecute(data,timeout=60)function invokes a deployed workflow. Here, timeout is passed to the Python requests HTTP transaction that invokes the workflow execution.Using the above echo workflow example, we have created anecho_wfworkflow object, which can be deployed and executed as follows:wf.deploy(timeout=0)# wait until wf.status=='deployed'print("Sending Hello")result=wf.execute("Hello")print(f"Received{result}")