Profiles¶
Haps allows you to attach dependencies to configuration profile. It helps
with development, testing, and some other stuff. You can set active profiles
using Configuration
.
Example¶
One of many good use cases for profiles is mailing. Imagine you have to implement mailer class. Your production environment uses AWS SES, stage uses an internal SMTP system, on your local env every mail is printed to stdout, and mailer for tests do nothing. You may ask, how to implement this without nasty ifs? Well, it’s quite easy with profiles:
from haps import base, egg
@base
class IMailer
def send(self, to: str, message: str) -> None:
raise NotImplementedError
@egg(profile='production')
class SESMailer(IMailer):
def send(self, to: str, message: str) -> None:
# SES implementation
@egg(profile='stage')
class SMTPMailer(IMailer):
def send(self, to: str, message: str) -> None:
# SMTP implementation
@egg(profile='tests')
class DummyMailer(IMailer):
def send(self, to: str, message: str) -> None:
pass
@egg # missing profile means default
class LogMailer(IMailer):
def send(self, to: str, message: str) -> None:
print(f"Mail to {to}: {message})
And that’s it. Now you only need to run your app with HAPS_PROFILES=production
(or any other profile) and haps will choose proper dependency. You can set more than
one profile separating them by a comma: HAPS_PROFILES=stage,local-static,sqlite
If there is more than one egg for the given profiles list, the order decides about
priority. e.g. for HAPS_PROFILES=tests,production
the DummyMailer
class is chosen.
Profiles can be configured programmatically, before Container configuration:
from haps import PROFILES
from haps.config import Configuration
Configuration().set(PROFILES, ('tests', 'tmp-static', 'sqlite'))
# Container config / autodiscover
Note
Profiles that are set directly by Configuration
overrides profiles from the environment variable.