Creating Packages
Packages can provide blueprints, service templates, and/or commands. This page will demonstrate creating a vendorless package for a PostGreSQL database. This is a simple example that will demonstrate the general workflow.
Setup
The command vl core package new
is used to create a new package.
The command will prompt you for some basic information about the package that you are creating.
The package will be preconfigured with the right structure, documentation, tests, and GitHub actions for CI.
If you have installed vendorless.core
via pip
you can run the vl
command directly, or you can run it via docker.
$ docker run ghcr.io/liambindle/vendorless:latest \
vendorless.core \
core package new
name: postgres
version:
description: PostgreSQL database
author: Liam Bindle
email: liam.bindle@gmail.com
github_username: LiamBindle
license:
Then you can run poetry install
to install your newly created package.
$ cd vendorless.postgres
$ poetry install
Blueprints
A blueprint is the Python module (.py file) that is used by vl core render
to render the Docker Compose files that stand up and application. Blueprints should go in vendorless.<package>.blueprints
where <package>
is the your package.
# vendorless.postgres.blueprints.basic_database
from vendorless.postgres import PostGreSQLDatabase
from vendorless.core import Volume
volume = Volume(
...
)
pg_databasn = PostGreSQLDatabase(
...
)
Service Templates
Service templates are black boxes that are configure services. They are effectively black boxes with input parameters that configure the service, and output parameters that can linked to the inputs of other service templates. This parameter linking is useful to ensure that things like ports, urls, service names, etc. are connected properly between services.
You can put service templates anywhere, but your top-level __init__.py
file should import all of the service templates that your package provides. Below is an example of creating a service template for a PostGreSQL database in a file called service_templates.py.
# vendorless.postgres.service_templates.py
from dataclasses import dataclass
from vendorless.core import Blueprint, parameter, computed_parameter, Volume
@dataclass
class PostGreSQLDatabase(Blueprint):
volume_name: str = parameter() # required because no default
data_path: str = parameter()
username: str = parameter("admin") # default is "admin"
password: str = parameter("admin")
service_name: str = parameter("postgres") # default is "postgres"
database_name: str = parameter("pgdata") # detault is "pgdata"
@computed_parameter
def port(self) -> int: # used to evaluate parameters lazily
return 5432
Then in the top-level __init__.py
file we would have
# vendorless.postgres.__init__.py
from .service_templates import PostGreSQLDatabase
This way, dependent packages have nicely formatted import statements like so:
from vendorless.postgres import PostGreSQLDatabase
Commands
The vl
command-line tool uses Click. If you want to add any commands to your package, you should implement them in vendorless.<package>.commands.py
using @cli.group()
. For example:
# vendorless.<package>.commands.py
# (...)
@cli.group()
@click.argument('message', type=click.STRING)
def echo(message: str):
click.echo(message)