# pollination-dsl
A Python Domain Specific Language (DSL) to create Pollination Plugins and Recipes.
Pollination uses [Queenbee](https://github.com/pollination/queenbee) as its workflow
language. Pollination-dsl makes it easy to create Queenbee object without the need to
learn Queenbee.
![pollination-dsl](https://user-images.githubusercontent.com/2915573/106669142-36d04880-6579-11eb-9763-a718aec27166.jpg)
# API docs
[Pollination-DSL API docs](https://pollination.github.io/pollination-dsl/docs/pollination_dsl.html#subpackages)
# Requirements
Python >=3.7
# Installation
Using pip:
`pip install pollination-dsl`
For local development:
1. Clone this repository.
2. Change directory to root folder of the repository.
3. `pip install -e .`
## Function
```python
from dataclasses import dataclass
from pollination_dsl.function import Function, command, Inputs, Outputs
@dataclass
class CreateOctreeWithSky(Function):
"""Generate an octree from a Radiance folder and sky!"""
# inputs
include_aperture = Inputs.str(
default='include',
description='A value to indicate if the static aperture should be included in '
'octree. Valid values are include and exclude. Default is include.',
spec={'type': 'string', 'enum': ['include', 'exclude']}
)
black_out = Inputs.str(
default='default',
description='A value to indicate if the black material should be used. Valid '
'values are default and black. Default value is default.',
spec={'type': 'string', 'enum': ['black', 'default']}
)
model = Inputs.folder(description='Path to Radiance model folder.', path='model')
sky = Inputs.file(description='Path to sky file.', path='sky.sky')
@command
def create_octree(self):
return 'honeybee-radiance octree from-folder model --output scene.oct ' \
'--{{self.include_aperture}}-aperture --{{self.black_out}} ' \
'--add-before sky.sky'
# outputs
scene_file = Outputs.file(description='Output octree file.', path='scene.oct')
```
If you want to access the `Queenbee` objects you can use `queenbee` property. For example
try `print(CreateOctreeWithSky().queenbee.yaml())` and you should see the full Queenbee
definition:
```yaml
type: Function
annotations: {}
inputs:
- type: FunctionStringInput
annotations: {}
name: black-out
description: A value to indicate if the black material should be used. Valid values
are default and black. Default value is default.
default: default
alias: []
required: false
spec:
type: string
enum:
- black
- default
- type: FunctionStringInput
annotations: {}
name: include-aperture
description: A value to indicate if the static aperture should be included in octree.
Valid values are include and exclude. Default is include.
default: include
alias: []
required: false
spec:
type: string
enum:
- include
- exclude
- type: FunctionFolderInput
annotations: {}
name: model
description: Path to Radiance model folder.
default: null
alias: []
required: true
spec: null
path: model
- type: FunctionFileInput
annotations: {}
name: sky
description: Path to sky file.
default: null
alias: []
required: true
spec: null
path: sky.sky
extensions: null
outputs:
- type: FunctionFileOutput
annotations: {}
name: scene-file
description: Output octree file.
path: scene.oct
name: create-octree-with-sky
description: Generate an octree from a Radiance folder and sky!
command: honeybee-radiance octree from-folder model --output scene.oct --{{inputs.include-aperture}}-aperture
--{{inputs.black-out}} --add-before sky.sky
```
Since the functions are standard Python classes you can also subclass them from one
another as long as you use the same name for the `@command` method. Otherwise it will
create an invalid function with two commands.
## Plugin
To create a Pollination plugin use the functions to create a standard Python module.
The only change is that you need to provide the information for Pollination plugin in
the `__init__.py` file as dictionary assigned to `__pollination__` variable.
Follow the standard way to install a Python package. Once the package is installed you
can use `pollination-dsl` to load the package or write it to a folder.
```python
from pollination_dsl.package import load, write
# name of the pollination package
python_package = 'pollination_honeybee_radiance'
# load this package as Pollination Plugin
plugin = load(python_package)
# or write the package as a Pollination plugin to a folder directly
write(python_package, './pollination-honeybee-radiance')
```
Here are two real world examples of Pollination plugins:
- [`pollination-honeybee-radiance` plugin](https://github.com/pollination/honeybee-radiance)
- [`pollination-honeybee-energy` plugin](https://github.com/pollination/honeybee-energy)
## Recipe
`Recipe` is a collection of `DAG`s. Each `DAG` is a collection of interrelated `task`s.
You can use pollination-dsl to create complex recipes with minimum code by reusing the
`functions` as templates for each task.
Packaging a plugin is exactly the same as packaging a plugin.
```python
from pollination_dsl.package import load, translate
# name of the pollination package
python_package = 'daylight-factor'
# load this package as Pollination Recipe
recipe = load(python_package, baked=True)
# or translate and write the package as a Pollination plugin to a folder directly
translate(python_package, './daylight-factor')
```
Here are number of real world examples of Pollination recipes:
- [`Annual energy use` recipe](https://github.com/pollination/annual-energy-use)
- [`Daylight factor` recipe](https://github.com/pollination/daylight-factor)
- [`Annual daylight` recipe](https://github.com/pollination/annual-daylight)
# How to create a pollination-dsl package
Pollination-dsl uses Python's standard packaging to package pollination plugins and recipes.
It parses most of the data from inputs in `setup.py` file and some Pollination specific
information from `__init__.py` file. Below is an example of how these file should look
like.
By taking advantage of [Python's native namespace packaging](https://packaging.python.org/guides/packaging-namespace-packages/#native-namespace-packages)
we keep all the packages under the `pollination` namespace.
## setup.py
Here is an example `setup.py` file. You can see the latest version of the file [here](https://github.com/pollination/honeybee-radiance/blob/master/setup.py).
```python
#!/usr/bin/env python
import setuptools
with open("README.md", "r") as fh:
long_description = fh.read()
with open('requirements.txt') as f:
requirements = f.read().splitlines()
setuptools.setup(
name='pollination-honeybee-radiance', # required - will be used for package name
author='ladybug-tools', # required - author must match the owner account name on Pollination
author_email='info@ladybug.tools',
packages=setuptools.find_namespace_packages(include=['pollination.*']), # required - that's how pollination find the package
version='0.1.0', # required - will be used as package tag. you can also use semantic versioning
install_requires=requirements,
url='https://github.com/pollination/pollination-honeybee-radiance', # optional - will be translated to home
project_urls={
'icon': 'https://raw.githubusercontent.com/ladybug-tools/artwork/master/icons_bugs/grasshopper_tabs/HB-Radiance.png', # optional but strongly encouraged - link to package icon
},
description='Honeybee Radiance plugin for Pollination.', # optional - will be used as package description
long_description=long_description, # optional - will be translated to ReadMe content on Pollination
long_description_content_type="text/markdown",
maintainer='maintainer_1, maintainer_2', # optional - will be translated to maintainers. For multiple maintainers
maintainer_email='maintainer_1@example.come, maintainer_2@example.com', # use comma inside the string.
keywords='honeybee, radiance, ladybug-tools, daylight', # optional - will be used as keywords
license='PolyForm Shield License 1.0.0, https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt', # optional - the license link should be separated by a comma
zip_safe=False # required - set to False to ensure the packaging will always work
)
```
## __init__.py
Here is an example `__init__.py` for a plugin. The latest version of the file is
accessible [here](https://github.com/pollination/honeybee-radiance/blob/master/pollination/honeybee_radiance/__init__.py).
```python
"""Honeybee Radiance plugin for Pollination."""
from pollination_dsl.common import get_docker_image_from_dependency
# set the version for docker image dynamically based on honeybee-radiance version
# in dependencies
image_id = get_docker_image_from_dependency(
__package__, 'honeybee-radiance', 'ladybugtools'
)
__pollination__ = {
'app_version': '5.4', # optional - tag for version of Radiance
'config': {
'docker': {
'image': image_id,
'workdir': '/home/ladybugbot/run'
}
}
}
```
Here is an example `__init__.py` for a recipe. The latest version of the file is
accessible [here](https://github.com/pollination/annual-daylight/blob/master/pollination/annual_daylight/__init__.py).
```python
from .entry import AnnualDaylightEntryPoint
__pollination__ = {
'entry_point': AnnualDaylightEntryPoint
}
```
Raw data
{
"_id": null,
"home_page": "https://github.com/pollination/pollination-dsl",
"name": "pollination-dsl",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "",
"keywords": "",
"author": "Pollination",
"author_email": "info@pollination.cloud",
"download_url": "https://files.pythonhosted.org/packages/2c/62/b0de49c246a766d3f60f2b20e88e8d620a314eec2da5f7fafe3b5c7f3594/pollination-dsl-0.15.3.tar.gz",
"platform": null,
"description": "# pollination-dsl\nA Python Domain Specific Language (DSL) to create Pollination Plugins and Recipes.\n\nPollination uses [Queenbee](https://github.com/pollination/queenbee) as its workflow\nlanguage. Pollination-dsl makes it easy to create Queenbee object without the need to\nlearn Queenbee.\n\n![pollination-dsl](https://user-images.githubusercontent.com/2915573/106669142-36d04880-6579-11eb-9763-a718aec27166.jpg)\n\n# API docs\n[Pollination-DSL API docs](https://pollination.github.io/pollination-dsl/docs/pollination_dsl.html#subpackages)\n\n# Requirements\nPython >=3.7\n\n# Installation\n\nUsing pip:\n\n`pip install pollination-dsl`\n\nFor local development:\n\n1. Clone this repository.\n2. Change directory to root folder of the repository.\n3. `pip install -e .`\n\n## Function\n\n```python\nfrom dataclasses import dataclass\nfrom pollination_dsl.function import Function, command, Inputs, Outputs\n\n\n@dataclass\nclass CreateOctreeWithSky(Function):\n \"\"\"Generate an octree from a Radiance folder and sky!\"\"\"\n\n # inputs\n include_aperture = Inputs.str(\n default='include',\n description='A value to indicate if the static aperture should be included in '\n 'octree. Valid values are include and exclude. Default is include.',\n spec={'type': 'string', 'enum': ['include', 'exclude']}\n )\n\n black_out = Inputs.str(\n default='default',\n description='A value to indicate if the black material should be used. Valid '\n 'values are default and black. Default value is default.',\n spec={'type': 'string', 'enum': ['black', 'default']}\n )\n\n model = Inputs.folder(description='Path to Radiance model folder.', path='model')\n\n sky = Inputs.file(description='Path to sky file.', path='sky.sky')\n\n @command\n def create_octree(self):\n return 'honeybee-radiance octree from-folder model --output scene.oct ' \\\n '--{{self.include_aperture}}-aperture --{{self.black_out}} ' \\\n '--add-before sky.sky'\n\n # outputs\n scene_file = Outputs.file(description='Output octree file.', path='scene.oct')\n\n```\n\nIf you want to access the `Queenbee` objects you can use `queenbee` property. For example\ntry `print(CreateOctreeWithSky().queenbee.yaml())` and you should see the full Queenbee\ndefinition:\n\n```yaml\ntype: Function\nannotations: {}\ninputs:\n- type: FunctionStringInput\n annotations: {}\n name: black-out\n description: A value to indicate if the black material should be used. Valid values\n are default and black. Default value is default.\n default: default\n alias: []\n required: false\n spec:\n type: string\n enum:\n - black\n - default\n- type: FunctionStringInput\n annotations: {}\n name: include-aperture\n description: A value to indicate if the static aperture should be included in octree.\n Valid values are include and exclude. Default is include.\n default: include\n alias: []\n required: false\n spec:\n type: string\n enum:\n - include\n - exclude\n- type: FunctionFolderInput\n annotations: {}\n name: model\n description: Path to Radiance model folder.\n default: null\n alias: []\n required: true\n spec: null\n path: model\n- type: FunctionFileInput\n annotations: {}\n name: sky\n description: Path to sky file.\n default: null\n alias: []\n required: true\n spec: null\n path: sky.sky\n extensions: null\noutputs:\n- type: FunctionFileOutput\n annotations: {}\n name: scene-file\n description: Output octree file.\n path: scene.oct\nname: create-octree-with-sky\ndescription: Generate an octree from a Radiance folder and sky!\ncommand: honeybee-radiance octree from-folder model --output scene.oct --{{inputs.include-aperture}}-aperture\n --{{inputs.black-out}} --add-before sky.sky\n```\n\nSince the functions are standard Python classes you can also subclass them from one\nanother as long as you use the same name for the `@command` method. Otherwise it will\ncreate an invalid function with two commands.\n\n## Plugin\n\nTo create a Pollination plugin use the functions to create a standard Python module.\nThe only change is that you need to provide the information for Pollination plugin in\nthe `__init__.py` file as dictionary assigned to `__pollination__` variable.\n\nFollow the standard way to install a Python package. Once the package is installed you\ncan use `pollination-dsl` to load the package or write it to a folder.\n\n```python\nfrom pollination_dsl.package import load, write\n\n# name of the pollination package\npython_package = 'pollination_honeybee_radiance'\n\n# load this package as Pollination Plugin\nplugin = load(python_package)\n\n# or write the package as a Pollination plugin to a folder directly\nwrite(python_package, './pollination-honeybee-radiance')\n\n```\n\nHere are two real world examples of Pollination plugins:\n\n- [`pollination-honeybee-radiance` plugin](https://github.com/pollination/honeybee-radiance)\n- [`pollination-honeybee-energy` plugin](https://github.com/pollination/honeybee-energy)\n\n## Recipe\n\n`Recipe` is a collection of `DAG`s. Each `DAG` is a collection of interrelated `task`s.\nYou can use pollination-dsl to create complex recipes with minimum code by reusing the\n`functions` as templates for each task.\n\nPackaging a plugin is exactly the same as packaging a plugin.\n\n```python\nfrom pollination_dsl.package import load, translate\n\n# name of the pollination package\npython_package = 'daylight-factor'\n\n# load this package as Pollination Recipe\nrecipe = load(python_package, baked=True)\n\n# or translate and write the package as a Pollination plugin to a folder directly\ntranslate(python_package, './daylight-factor')\n\n```\n\nHere are number of real world examples of Pollination recipes:\n\n- [`Annual energy use` recipe](https://github.com/pollination/annual-energy-use)\n- [`Daylight factor` recipe](https://github.com/pollination/daylight-factor)\n- [`Annual daylight` recipe](https://github.com/pollination/annual-daylight)\n\n\n# How to create a pollination-dsl package\n\nPollination-dsl uses Python's standard packaging to package pollination plugins and recipes.\nIt parses most of the data from inputs in `setup.py` file and some Pollination specific\ninformation from `__init__.py` file. Below is an example of how these file should look\nlike.\n\nBy taking advantage of [Python's native namespace packaging](https://packaging.python.org/guides/packaging-namespace-packages/#native-namespace-packages)\nwe keep all the packages under the `pollination` namespace.\n\n## setup.py\n\nHere is an example `setup.py` file. You can see the latest version of the file [here](https://github.com/pollination/honeybee-radiance/blob/master/setup.py).\n\n```python\n\n#!/usr/bin/env python\nimport setuptools\n\nwith open(\"README.md\", \"r\") as fh:\n long_description = fh.read()\n\nwith open('requirements.txt') as f:\n requirements = f.read().splitlines()\n\nsetuptools.setup(\n name='pollination-honeybee-radiance', # required - will be used for package name\n author='ladybug-tools', # required - author must match the owner account name on Pollination\n author_email='info@ladybug.tools',\n packages=setuptools.find_namespace_packages(include=['pollination.*']), # required - that's how pollination find the package\n version='0.1.0', # required - will be used as package tag. you can also use semantic versioning\n install_requires=requirements,\n url='https://github.com/pollination/pollination-honeybee-radiance', # optional - will be translated to home\n project_urls={\n 'icon': 'https://raw.githubusercontent.com/ladybug-tools/artwork/master/icons_bugs/grasshopper_tabs/HB-Radiance.png', # optional but strongly encouraged - link to package icon\n },\n description='Honeybee Radiance plugin for Pollination.', # optional - will be used as package description\n long_description=long_description, # optional - will be translated to ReadMe content on Pollination\n long_description_content_type=\"text/markdown\",\n maintainer='maintainer_1, maintainer_2', # optional - will be translated to maintainers. For multiple maintainers\n maintainer_email='maintainer_1@example.come, maintainer_2@example.com', # use comma inside the string.\n keywords='honeybee, radiance, ladybug-tools, daylight', # optional - will be used as keywords\n license='PolyForm Shield License 1.0.0, https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt', # optional - the license link should be separated by a comma\n zip_safe=False # required - set to False to ensure the packaging will always work\n)\n\n```\n\n## __init__.py\n\nHere is an example `__init__.py` for a plugin. The latest version of the file is\naccessible [here](https://github.com/pollination/honeybee-radiance/blob/master/pollination/honeybee_radiance/__init__.py).\n\n\n```python\n\n\"\"\"Honeybee Radiance plugin for Pollination.\"\"\"\nfrom pollination_dsl.common import get_docker_image_from_dependency\n\n# set the version for docker image dynamically based on honeybee-radiance version\n# in dependencies\nimage_id = get_docker_image_from_dependency(\n __package__, 'honeybee-radiance', 'ladybugtools'\n)\n\n__pollination__ = {\n 'app_version': '5.4', # optional - tag for version of Radiance\n 'config': {\n 'docker': {\n 'image': image_id,\n 'workdir': '/home/ladybugbot/run'\n }\n }\n}\n```\n\nHere is an example `__init__.py` for a recipe. The latest version of the file is\naccessible [here](https://github.com/pollination/annual-daylight/blob/master/pollination/annual_daylight/__init__.py).\n\n```python\nfrom .entry import AnnualDaylightEntryPoint\n\n__pollination__ = {\n 'entry_point': AnnualDaylightEntryPoint\n}\n\n```\n",
"bugtrack_url": null,
"license": "",
"summary": "A Python DSL to create Pollination recipes and plugins.",
"version": "0.15.3",
"project_urls": {
"Homepage": "https://github.com/pollination/pollination-dsl"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "a368c05e58aefa492f100475d15b4b3cb7d42ec238a1fef360a8e83ed5597097",
"md5": "6ca1fbaebbf3ec40deeca84480c91608",
"sha256": "0e25e381d150ea88ac6c10f810d0ad413cfe876cb2487d66e0f409311f43c07c"
},
"downloads": -1,
"filename": "pollination_dsl-0.15.3-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "6ca1fbaebbf3ec40deeca84480c91608",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=3.7",
"size": 38354,
"upload_time": "2023-09-12T19:20:49",
"upload_time_iso_8601": "2023-09-12T19:20:49.386460Z",
"url": "https://files.pythonhosted.org/packages/a3/68/c05e58aefa492f100475d15b4b3cb7d42ec238a1fef360a8e83ed5597097/pollination_dsl-0.15.3-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2c62b0de49c246a766d3f60f2b20e88e8d620a314eec2da5f7fafe3b5c7f3594",
"md5": "11b0188d11b162c828e52a6999dde441",
"sha256": "71670d2be5615a3fcb7033493cab87e04a8de11accc04da47df96be6d9ba13be"
},
"downloads": -1,
"filename": "pollination-dsl-0.15.3.tar.gz",
"has_sig": false,
"md5_digest": "11b0188d11b162c828e52a6999dde441",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 38889,
"upload_time": "2023-09-12T19:20:51",
"upload_time_iso_8601": "2023-09-12T19:20:51.239469Z",
"url": "https://files.pythonhosted.org/packages/2c/62/b0de49c246a766d3f60f2b20e88e8d620a314eec2da5f7fafe3b5c7f3594/pollination-dsl-0.15.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-09-12 19:20:51",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "pollination",
"github_project": "pollination-dsl",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "pollination-dsl"
}