Scaffolding From Scratch¶
In this section we’ll create the basic files we need for a plugin.
Plugin Name: | peek_plugin_tutorial We’ll finish up with a plugin which we can build a python package for, but it won’t run on any services, we’ll add that later. |
---|
Plugin File Structure¶
Create Directory peek-plugin-tutorial
¶
peek-plugin-tutorial
is the name of the project directory, it could be anything.
For consistency, we name it the same as the plugin with hypons instead of underscores,
Python can’t import directories with hypons, so there will be no confusion there.
This directory will contain our plugin package, documentation, build scripts, README, license, etc. These won’t be included when the python package is built and deployed.
–
Create the plugin project root directory, and CD to it.
peek-plugin-tutorial/
Commands:
mkdir peek-plugin-tutorial
cd peek-plugin-tutorial
Note
Future commands will be run from the plugin project root directory.
Add File .gitignore
¶
The .gitignore
file tells the git version control software to ignore certain
files in the project.
gitignore - Specifies intentionally untracked files to ignore.
Create .gitignore
, and populate it with the following
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# auth generated js and jsmap files
*.js
*.js.map
# Distribution / packaging
.Python
env/
build/
develop-eggs/
*.egg-info
MANIFEST
dist
.idea
.vscode
docs/api_autoapi
Add .editorconfig
¶
Create the file .editorconfig
, with the following content:
# https://editorconfig.org/
root = true
[*]
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
charset = utf-8
Add Package peek_plugin_tutorial
¶
Package peek_plugin_tutorial
is the root
python package.
for our plugin.
This package will contain everything that is packaged up and deployed for the Peek Platform to run. This includes:
- The public declarations of the APIs used by other plugins. They are declared using Python Abstract Base Classes.
- Private code that other plugins shouldn’t reference.
- Angular2 Components, modules, services and HTML.
Note
Commands will be run from the plugin project root directory, which is
peek-plugin-tutorial
.
Create the peek_plugin_tutorial
Package. Commands:
mkdir -p peek_plugin_tutorial
touch peek_plugin_tutorial/__init__.py
Add the version string to the peek_plugin_tutorial
package.
echo "__version__ = '0.0.0'" > peek_plugin_tutorial/__init__.py
Note
This version is automatically updated by the publish.sh script.
Add Package _private
¶
Package peek_plugin_tutorial._private
will contain the parts of the plugin
that won’t be exposed/shared for other plugins to use.
Create the peek_plugin_tutorial._private
Package. Commands:
mkdir -p peek_plugin_tutorial/_private
touch peek_plugin_tutorial/_private/__init__.py
The structure should now be:
peek-plugin-tutorial
└── .gitignore
└── peek_plugin_tutorial
├── __init__.py
└── _private
└── __init__.py
Add File setup.py
¶
The setup.py
file tells the python distribution tools how to create a
distributable file for the plugin.
Read more here.
Download setup.py
from
peek-plugin-noop/setup.py
Modify the options near the top of the file for your plugin. We’ve modified the following values:
- py_package_name
- description
- package_version
#
# Modify these values to fork a new plugin
#
author = "Synerty"
author_email = 'contact@synerty.com'
py_package_name = "peek_plugin_tutorial"
pip_package_name = py_package_name.replace('_', '-')
package_version = '0.0.0'
description = 'Peek Plugin Tutorial - My first enhancement.'
download_url = 'https://bitbucket.org/synerty/%s/get/%s.zip'
download_url %= pip_package_name, package_version
url = 'https://bitbucket.org/synerty/%s' % pip_package_name
Add File publish.sh
¶
The publish.sh
file is custom script for building and publishing the plugin that
performs the following tasks:
- Updates the version number in the project text files.
- Pushes tags to git
- Copies the built releases to $RELEASE_DIR if defined
- Runs setup.py
- Pushes the release to pypi.python.org
Download publish.sh
from
peek-plugin-noop/publish.sh
Modify the options near the top. We’ve modified the following:
- PY_PACKAGE
#------------------------------------------------------------------------------
# Configure package preferences here
PY_PACKAGE="peek_plugin_tutorial"
# Leave blank not to publish
# Or select one of the index servers defined in ~/.pypirc
PYPI_PUBLISH=""
Create publish.settings.sh
with the following content:
#!/usr/bin/env bash
PY_PACKAGE="peek_plugin_tutorial"
PYPI_PUBLISH="0"
VER_FILES_TO_COMMIT=""
VER_FILES=""
Add File README.rst
¶
The file:README.rst file is a verbose description of this plugin, it’s the file that version control systems, such as BitBucket or GitHub will display when the project is viewed on their sites.
It’s ideal to include a great overview about the plugin in this file.
Create a README, create a README.rst
file and populate it.
Here is a suggestion:
=================
Tutorial Plugin 1
=================
This is a Peek Plugin, from the tutorial.
Add File plugin_package.json
¶
The plugin_package.json
describes the plugin to the Peek Platform. These details
include:
- The version
- The name
- Which services the plugin needs
- Additional settings for each service
- File locations for the Angular applications (admin, desktop and mobile)
- The path of the icon for the plugin,
- ect.
Create the peek_plugin_tutorial/plugin_package.json
file with the following
contents:
{
"plugin": {
"title": "Tutorial Plugin",
"packageName": "peek_plugin_tutorial",
"version": "0.0.0",
"buildNumber": "#PLUGIN_BUILD#",
"buildDate": "#BUILD_DATE#",
"creator": "Synerty Pty Ltd",
"website": "www.synerty.com"
},
"requiresServices": [
],
"admin": {
"moduleDir": "plugin-module"
},
"mobile": {
"moduleDir": "plugin-module"
},
"desktop": {
"moduleDir": "plugin-module"
}
}
Check that your plugin now looks like this:
peek-plugin-tutorial
├── peek_plugin_tutorial
│ ├── __init__.py
│ ├── plugin_package.json
│ └── _private
│ └── __init__.py
├── publish.sh
├── README.rst
└── setup.py
Add File PluginNames.py
¶
The PluginNames.py
file defines some constants that are used throughout the
plugin. More details on where these are used will be later in the documentation.
Since all of the plugin is on the one package, both the part of the plugin running on the server and the part of the plugin running on the client can import this file.
Guaranteeing that there is no mismatch of names when they send data to each other.
Create the peek_plugin_tutorial/_private/PluginNames.py
file with the following
contents:
tutorialPluginName = "peek_plugin_tutorial"
tutorialFilt = {"plugin": "peek_plugin_tutorial"}
tutorialTuplePrefix = "peek_plugin_tutorial."
tutorialObservableName = "peek_plugin_tutorial"
tutorialActionProcessorName = "peek_plugin_tutorial"
tutorialTupleOfflineServiceName = "peek_plugin_tutorial"
Add Directory plugin-module/_private
¶
We now move onto the frontends, and TypeScript.
The plugin-module/_private
directory will contain code that shouldn’t be used
outside of this plugin.
The plugin-module
directory will contain any code that needs to be either:
- Running all the time in the background.
- Shared with other modules.
This directory is sync’d to node_modules/@peek/peek_plugin_tutorial
on mobile,
admin and desktop services.
Developers can use some index.ts
magic to abstract the layout of their
directories.
An exmaple of importing declaration is as follows:
import {tutorialFilt} from "@peek/peek_plugin_tutorial/_private";
Create directory peek_plugin_tutorial/plugin-module/_private
,
with command
mkdir -p peek_plugin_tutorial/plugin-module/_private
Add File package.json
¶
The package.json
file is required to keep NPM from winging, since this
directory is linked in under node_modules/@peek
Create file
peek_plugin_tutorial/plugin-module/package.json
,
with contents
{
"name": "@peek/peek_plugin_tutorial",
"version": "0.0.0"
}
Add File PluginNames.ts
¶
The PluginNames.ts
file defines constants used by this plugin to define,
payload filts, tuple names, oberservable names, etc.
Create file
peek_plugin_tutorial/plugin-module/_private/PluginNames.ts
,
with contents
export let tutorialFilt = {"plugin": "peek_plugin_tutorial"};
export let tutorialTuplePrefix = "peek_plugin_tutorial.";
export let tutorialObservableName = "peek_plugin_tutorial";
export let tutorialActionProcessorName = "peek_plugin_tutorial";
export let tutorialTupleOfflineServiceName = "peek_plugin_tutorial";
export let tutorialBaseUrl = "peek_plugin_tutorial";
Add File _private/index.ts
¶
The _private/index.ts
file defines exports from other files in _private.
This lets the code
import tutorialFilt from "@peek/peek_plugin_tutorial/_private";
work instead of
import tutorialFilt from "@peek/peek_plugin_tutorial/_private/PluginNames";
.
It seems trival a this point, but it becomes more usefull as the TypeScript code grows.
Create file
peek_plugin_tutorial/plugin-module/_private/index.ts
, with contents
export * from "./PluginNames";
Install in Development Mode¶
Installing the plugin in development mode, links the development directory of the plugin (the directory we create in these instructions) into the python virtual environment.
With this link in place, any python code that want’s to use our plugin, is able to import it, and the code run will be the code we’re working on.
Install the python plugin package in development mode, run the following:
# Check to ensure we're using the right python
which python
python setup.py develop
You can test that it’s worked with the following python code, run the following in bash:
python << EOPY
import peek_plugin_tutorial
import os
print(peek_plugin_tutorial.__version__)
print(os.path.dirname(peek_plugin_tutorial.__file__))
EOPY
You now have a basic plugin. In the next section we’ll make it run on some services.