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
Locationfor theProdEnvironment - Works only on
AvailabilityZones for theDevEnvironment - Works only in
ams1for thePCCEnvironment
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3cad55185129ac78a571a4b9d2105a621a15036a9a127c8aa279c10a84a072bb
|
|
| MD5 |
510eea877674a3f026a9ace7bd48f506
|
|
| BLAKE2b-256 |
eae6b79262f4560236754bbfd5d58f65d13e05aefc543cc9cc3face610a00796
|
File details
Details for the file magic_constants-1.0.0-py3-none-any.whl.
File metadata
- Download URL: magic_constants-1.0.0-py3-none-any.whl
- Upload date:
- Size: 4.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.0.1 CPython/3.10.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
10b2d9f5ed2f9655c50e12055376ba3c364c61943b233ca938c0f2841b034044
|
|
| MD5 |
7d5f895d91c65f6d373f0305dcecc316
|
|
| BLAKE2b-256 |
367d41a1d49d2589669526b912225859086b6b08bc9b85ba16a6774cc2e6a431
|