Skip to main content

Make constants in python more magic 🪄

Project description

magic-constants

Make constants in python more magic 🪄

A constant library with types in mind. Define a hierarchy of constants, with magic self-validation built in! More powerful when combined with multimethods!

SRE NL Talk + Jupyter Notebook

Features

  • Basic immutable value wrapper
  • Namespaces for constants
  • Input validation / type coercion for any subtype

Installation

pip install magic-constants

Usage

from magic-constants import Constant

class Location(Constant):
    # NB: To make your IDE autocomplete work, you should annotate
    # any sub-constants explicitly. Although, magic-constants will
    # self register with any parent class.
    DataCenter: "DataCenter"

class DataCenter(Location):
    ams1: "ams1"
    lon1: "lon1"

class ams1(DataCenter):
    value = "ams1"

class lon1(DataCenter):
    value = "lon1"

ams1            # DataCenter.ams1('ams1')
ams1()          # DataCenter.ams1('ams1')
ams1().value    # ams1

# Muliple ways to instantiate, type stable output
Location("ams1") == DataCenter("ams1") == Location.DataCenter.ams1 == DataCenter.ams1 == ams1()

# Helpful error messages on validation!

ams1("ams2")
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "/home/tom/repos/magic-constants/magic_constants/metaconstant.py", line 41, in __new__
#     raise ValueError(
# ValueError: 'ams2' cannot be validated as type ams1. Expected 'ams1'

DataCenter("ams2")
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
#   File "/home/tom/repos/magic-constants/magic_constants/metaconstant.py", line 32, in __new__
#     raise ValueError(
# ValueError: 'ams2' is not a valid DataCenter. Expected DataCenters: 'ams1', 'lon1'

More powerful with Multimethods!

Assume we want to encode some relatively complicated business logic...

↓env \ location → lon1 ams1 west1-a west2-a
prod
dev
pcc

We want to define a can_deploy check that:

  • Works in all Location for the Prod Environment
  • Works only on AvailabilityZones for the Dev Environment
  • Works only in ams1 for the PCC Environment

Define the additonal types...

# Yes, lazy registration works to register AvailabilityZone with Location!
class AvailabilityZone(Location):
    west1_a: "west1_a"
    west2_a: "west2_a"
    
class west1_a(AvailabilityZone):
    value = "west1-a"
    
class west2_a(AvailabilityZone):
    value = "west2-a"

class Environment(Constant):
    pass
    
class Prod(Environment):
    value = "prod"

class Dev(Environment):
    value = "dev"

class PCC(Environment):
    value = "pcc"

Define 4 multi methods that dispatch based on the argument types

from multimethod import multimethod

@multimethod
def check(environment:Environment, location:Location):
    # log f"Not a supported deployment combination ({environment}, {location})!"
    # By default, disable all deployments in any Environment or Location
    return False

@multimethod
def check(environment:Prod, location:Location):
    # Works in all `Location` for the `Prod` `Environment`
    return True

@multimethod
def check(environment:Dev, location:AvailabilityZone):
    # Works only on `AvailabilityZone`s for the `Dev` `Environment`
    return True

@multimethod
def check(environment:PCC, location:ams1):
    # Works only in `ams1` for the `PCC` `Environment`
    return True

environments = [Prod(), Dev(), PCC()]
locations = [lon1(), ams1(), west1_a(), west2_a()]

print(f"\t{'\t'.join([str(l) for l in locations])}")
for environment in environments:
    print(environment, end="\t")
    for location in locations:
        val = "✅" if check(environment, location) else "❌"
        print(val, end="\t")
    print()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

magic_constants-1.0.0.tar.gz (4.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

magic_constants-1.0.0-py3-none-any.whl (4.6 kB view details)

Uploaded Python 3

File details

Details for the file magic_constants-1.0.0.tar.gz.

File metadata

  • Download URL: magic_constants-1.0.0.tar.gz
  • Upload date:
  • Size: 4.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.0.1 CPython/3.10.12

File hashes

Hashes for magic_constants-1.0.0.tar.gz
Algorithm Hash digest
SHA256 3cad55185129ac78a571a4b9d2105a621a15036a9a127c8aa279c10a84a072bb
MD5 510eea877674a3f026a9ace7bd48f506
BLAKE2b-256 eae6b79262f4560236754bbfd5d58f65d13e05aefc543cc9cc3face610a00796

See more details on using hashes here.

File details

Details for the file magic_constants-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for magic_constants-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 10b2d9f5ed2f9655c50e12055376ba3c364c61943b233ca938c0f2841b034044
MD5 7d5f895d91c65f6d373f0305dcecc316
BLAKE2b-256 367d41a1d49d2589669526b912225859086b6b08bc9b85ba16a6774cc2e6a431

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page