{"id":16935097,"url":"https://github.com/vishal-biyani/fission-spec-example","last_synced_at":"2026-04-13T10:31:52.798Z","repository":{"id":92985821,"uuid":"162718742","full_name":"vishal-biyani/fission-spec-example","owner":"vishal-biyani","description":null,"archived":false,"fork":false,"pushed_at":"2018-12-24T10:34:53.000Z","size":17,"stargazers_count":2,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-21T04:30:00.989Z","etag":null,"topics":["faas","fission","kubernetes","specs"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vishal-biyani.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2018-12-21T13:42:22.000Z","updated_at":"2023-03-04T08:16:48.000Z","dependencies_parsed_at":"2023-08-24T19:32:41.853Z","dependency_job_id":null,"html_url":"https://github.com/vishal-biyani/fission-spec-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/vishal-biyani/fission-spec-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vishal-biyani%2Ffission-spec-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vishal-biyani%2Ffission-spec-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vishal-biyani%2Ffission-spec-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vishal-biyani%2Ffission-spec-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vishal-biyani","download_url":"https://codeload.github.com/vishal-biyani/fission-spec-example/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vishal-biyani%2Ffission-spec-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31748974,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T09:16:15.125Z","status":"ssl_error","status_checked_at":"2026-04-13T09:16:05.023Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["faas","fission","kubernetes","specs"],"created_at":"2024-10-13T20:53:40.534Z","updated_at":"2026-04-13T10:31:52.786Z","avatar_url":"https://github.com/vishal-biyani.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fission Spec Example\n\n## Building source code locally\n\nThis example will showcase how to use specs in Fission so that CI/CD flow can be designed better using the specs. Also we are building the function as part of this flow - so it is assumed that the Kubernetes cluster does not have internet connectivity and can not run things like `pip` or `maven` to fetch dependencies for building from source to package.\n\nWe have a simple python function which needs one library for it's working. The files are:\n\n```\n$ tree .\n.\n├── __init__.py\n├── requirements.txt\n└── user.py\n\n0 directories, 4 files\n```\n\nThe user.py is a simple function which uses yaml library and dumps a simple document:\n\n```\n$ cat user.py \nimport sys\nimport yaml\n\ndocument = \"\"\"\n  a: 1\n  b:\n    c: 3\n    d: 4\n\"\"\"\n\ndef main():\n    return yaml.dump(yaml.load(document))\n```\nIn the requirements file we declare the `pyyaml` library that we need\n\n```\n$ cat requirements.txt \npyyaml\n```\n\nFinally - we want to build the source code locally so that all dependencies of the function are packed with function. For this you can run `pip install` in a way that dependencies are placed in same directory or you can use a simple helper script below which uses a docker container to build it. The docker container is useful if the machine on which you build source code does not have pip installed.\n\n```\n$ cat build.sh \n#/bin/bash\n# A script which builds the source code using pip and a docker container so that you don't need Pip on host machine\n#\ndocker run -it --rm -v$(pwd):/app chauffer/pip3-compile pip install -r requirements.txt -t /app\n```\n\nWhen we run above script, we can see that the yaml module is downloaded.\n\n```\n$ ./build.sh\nCollecting pyyaml (from -r requirements.txt (line 1))\n  Downloading https://files.pythonhosted.org/packages/9e/a3/1d13970c3f36777c583f136c136f804d70f500168edc1edea6daa7200769/PyYAML-3.13.tar.gz (270kB)\n    100% |████████████████████████████████| 276kB 215kB/s \nBuilding wheels for collected packages: pyyaml\n  Running setup.py bdist_wheel for pyyaml ... done\n  Stored in directory: /root/.cache/pip/wheels/ad/da/0c/74eb680767247273e2cf2723482cb9c924fe70af57c334513f\nSuccessfully built pyyaml\nInstalling collected packages: pyyaml\nSuccessfully installed pyyaml-3.13\n\n```\n\nYou can also confirm that the yaml module is downloaded in same directory as source code - now the function and it's dependencies are all in same directory.\n\n```\n$ tree -L 1\n.\n├── PyYAML-3.13.dist-info\n├── __init__.py\n├── _yaml.cpython-37m-x86_64-linux-gnu.so\n├── build.sh\n├── requirements.txt\n├── user.py\n└── yaml\n\n2 directories, 5 files\n```\n\n## Using Fission Specs\n\nNow let's use spec to create environment and function and deploy to a cluster. The first step is to initialize the fission spec - so that it creates a spec directory and stores all specs in that directory.\n\n```\n$ fission spec init\nCreating fission spec directory 'specs'\n```\n\nNext is to create environment spec - this does not actually create environment since we are using the `--spec` flag. If you look at the environment spec file, it's like a Kubernetes YAML definition. \n\n```\n$ fission env create --name python --image fission/python-env --spec\n\n$ cat specs/env-python.yaml \napiVersion: fission.io/v1\nkind: Environment\nmetadata:\n  creationTimestamp: null\n  name: python\n  namespace: default\nspec:\n  TerminationGracePeriod: 360\n  builder: {}\n  keeparchive: false\n  poolsize: 3\n  resources: {}\n  runtime:\n    functionendpointport: 0\n    image: fission/python-env\n    loadendpointpath: \"\"\n    loadendpointport: 0\n  version: 1\n```\nNext, let's create the function specs. This will also create the package spec inside the function file.\n\n```\n$ fission fn create --name pyfunc --env python --executortype newdeploy --minscale 1 --deploy \"*\" --entrypoint user.main --spec\n$ cat specs/function-pyfunc.yaml \ninclude:\n- '*'\nkind: ArchiveUploadSpec\nname: default-kxFr\n\n---\napiVersion: fission.io/v1\nkind: Package\nmetadata:\n  creationTimestamp: null\n  name: dfxr\n  namespace: default\nspec:\n  deployment:\n    checksum: {}\n    type: url\n    url: archive://default-kxFr\n  environment:\n    name: python\n    namespace: default\n  source:\n    checksum: {}\nstatus:\n  buildstatus: none\n\n---\napiVersion: fission.io/v1\nkind: Function\nmetadata:\n  creationTimestamp: null\n  name: pyfunc\n  namespace: default\nspec:\n  InvokeStrategy:\n    ExecutionStrategy:\n      ExecutorType: newdeploy\n      MaxScale: 1\n      MinScale: 1\n      TargetCPUPercent: 80\n    StrategyType: execution\n  configmaps: null\n  environment:\n    name: python\n    namespace: default\n  package:\n    functionName: user.main\n    packageref:\n      name: dfxr\n      namespace: default\n  resources: {}\n  secrets: null\n```\nSimilarly you can create a route for the function\n\n```\n$ fission route create --url /some/test --function pyfunc --createingress --spec\n$ cat specs/route-ede2f2c7-c0fb-4801-a619-c81dbae3719e.yaml \napiVersion: fission.io/v1\nkind: HTTPTrigger\nmetadata:\n  creationTimestamp: null\n  name: ede2f2c7-c0fb-4801-a619-c81dbae3719e\n  namespace: default\nspec:\n  createingress: true\n  functionref:\n    functionweights: null\n    name: pyfunc\n    type: name\n  host: \"\"\n  method: GET\n  relativeurl: /some/test\n```\n\nNow next step is to validate the specs and apply them. In a typical CI/CD workflow, the developer will create specs and commit them to Git. The CI/CD system will only validate and apply specs. The apply command makes sure that the changes only are applied to the cluster.\n\n\n```\n$ fission spec validate\n$ fission spec apply\nuploading archive archive://default-kxFr\n1 environment created: python\n1 package created: dfxr\n1 function created: pyfunc\n```\n\nNow is the time to quickly check if the function works:\n\n```\n$ fission fn test --name pyfunc\na: 1\nb: {c: 3, d: 4}\n```\n\nAfter you are done, you can use destroy command to delete all related objects - and you don't need to individually delete one object at a time:\n\n```\n$ fission spec destroy\nDeleted Environment default/python\nDeleted Package default/dfxr\nDeleted Function default/pyfunc\n```\n\n## Specs on steroids\n\n### Environment Variables\n\nThe specs allow you do additional things. The `spec.runtime.container` is basically the container spec from Kubernetes. This allows you add environment variables to Functions as shown below. In future Fission might support `PodSpec` - which will allow to do more things in future.\n\n```\napiVersion: fission.io/v1\nkind: Environment\nmetadata:\n  creationTimestamp: null\n  name: jvm\n  namespace: default\nspec:\n  TerminationGracePeriod: 360\n  builder: {}\n  keeparchive: true\n  poolsize: 3\n  resources: {}\n  runtime:\n    functionendpointport: 0\n    image: fission/jvm-env\n    loadendpointpath: \"\"\n    loadendpointport: 0\n    container:\n      env:\n      - name: JVM_OPTS\n        value: \"-Xms256M -Xmx1024M\"\n  version: 2\n```\n\n### Using code from one folder and libraries from others\n\nIf you have code in one directory - but the libraries which code uses in some other directory, then it makes sense not to replicate the library code into every function code. The spec and multiple deploy options allow you to fetch code from multiple directories and build a function.\n\nSource code directory:\n```\n$ tree\n.\n├── README.md\n├── __init__.py\n├── build.sh\n├── requirements.txt\n├── specs\n│   ├── README\n│   ├── env-python.yaml\n│   ├── fission-deployment-config.yaml\n│   ├── function-pyfunc.yaml\n│   └── route-ede2f2c7-c0fb-4801-a619-c81dbae3719e.yaml\n└── user.py\n\n1 directory, 10 files\n\n```\n\n\nAnd the directory which has library code:\n\n```\n$ tree -L 1 ../lib_pyyaml/\n../lib_pyyaml/\n├── PyYAML-3.13.dist-info\n├── _yaml.cpython-37m-x86_64-linux-gnu.so\n└── yaml\n\n```\n\nNow you can refer to both places using multiple `--deploy` argument and build a function:\n\n```\n$ fission fn create --name pyfunc --env python --executortype newdeploy --minscale 1 --deploy \"*\" --deploy \"../lib_pyyaml/*\" --entrypoint user.main --spec\n\n```\n\nYou will notice that the file upload picks up all the files specified:\n\n```\n$ cat specs/function-pyfunc.yaml \ninclude:\n- '*'\n- ../lib_pyyaml/*\nkind: ArchiveUploadSpec\nname: default-CRfl\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvishal-biyani%2Ffission-spec-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvishal-biyani%2Ffission-spec-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvishal-biyani%2Ffission-spec-example/lists"}