Lens
A library for modifying Kubernetes manifests and other json-like objects.
Examples
You can use lenses for directly getting, setting, or mapping (modifying) data
# set the namespace of a Kubernetes object
namespace = kord("metadata") / KeyLens("namespace")
namespace.l_set(my_pod, "my-ns")
# modify the contents of a Kubernetes secret
admin_password = kord("data") / KeyLens("admin-password") / B64()
admin_password.l_set(my_secret, "super-secret-password")
# get the number of ready replicas of a Kubernetes deployment
ready_replicas = Lens()["status"]["readyReplicas"]
ready_replicas.l_get(my_deployment)
# get the name and resources of every container in a Kubernetes pod
containers = Lens()["spec"]["containers"]
resources = (containers * KeyLens("name")) % (containers * KeyLens("resources"))
# add one more replica to a deployment
replicas = Lens()["spec"]["replicas"]
replicas.l_map(my_deployment, lambda n: n + 1)
You can bind the mapping function to easily apply the same transformation multiple times:
# note how we can re-use `replicas` from above
add_replica = replicas @ (lambda n: n + 1)
add_replica.map(my_deployment)
You can combine several bound lenses to create pipelines
set_namespace = namespace @ Const("my-ns")
labels = kord("metadata") / kord("labels")
add_team_label = (labels / KeyLens("team", None)) @ Const("my_team")
global_pipeline = set_namespace % add_team_label
Usage
Lenses can be built using either their classes or their helpers. The helpers are the most convenient, and look like standard access:
# These are equivalent
l = Lens()["my-key"][0].my_attribute / B64()
l
KeyLens("my-key").l_compose(IndexLens(0)).l_compose(AttrLens("my_attribute")).l_compose(B64())
Lenses support 3 operations. They're all prefixed with "l_" to avoid conflicting with attributes that your objects might have.
l_get: get the value focused by the lensl_set: set the value focused by the lensl_map: use a function to modify the value focused by the lens
Types of Lenses
There are several lenses for moving through objects:
| Name | Description | equivalence and example |
|---|---|---|
| AttrLens | get an attribute | AttrLens("foo") -> object.foo |
| IndexLens | get an item by its index | IndexLens(1) -> object[1] |
| KeyLens | get an item by its key | KeyLens("foo") -> object["foo"] |
| ForEachLens | apply the sublens to all elements of a collection | a for loop |
| CodecLens | decode the item | CodecLens(json.loads, json.dumps) decodes the payload and re-encodes after modification |
| DataclassCodec | instantiate a dataclass from a dict | DataclassCodec(User) |
| FilterLens | focus if a predicate matches | ForEachLens(FilterLens(lambda x: x.value > 0)) will only operate on items whose value is positive |
There are helper lenses for common JSON/YAML operations:
| Name | Description | equivalence and example |
|---|---|---|
| kord | get the key, defaulting to an empty dictionary | kord("labels") -> KeyLens("labels", {}) |
| korl | get the key, defaulting to an empty list | korl("volumes") -> KeyLens("volumes", []) |
Theoretical underpinnings
Lenses have several formulations.
- Profunctors : These are generalisations of functions (think a fancy way of writing
map). The advantage is that optical composition is just function composition. The disadvantage is that this composition is not introspectable. This means that it isn't really possible to report when an optic fails to find an expected value.
Bibliography
- Don't Fear the Profunctor Optics! : a clear walkthrough of concrete optics, profunctors, and profunctor optics. It includes diagrams which visualise the core principle of "just gluing arrows together". It also uses more practical examples for motivation and illustration.
- :
Metadata
Release files for alpacloud.lens 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| alpacloud_lens-0.1.0.tar.gz | 11.7 kB | Without provenance | Details for alpacloud_lens-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| alpacloud.lens-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for alpacloud.lens-0.1.0-py3-none-any.whl |
Total release size: 22.9 kB
Release files / alpacloud_lens-0.1.0.tar.gz
| Download URL | alpacloud_lens-0.1.0.tar.gz |
|---|---|
| Size | 11.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
894562b42aa67b09e84097965298e5893fb05f73eaa790798e0ee650598eb5bc
|
|
BLAKE2b-256 checksum How to use checksums |
c0aa0a18d4a0f6e903fc8dc6dfc7883a59efb35d471b56238477567b220325c2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.1 CPython/3.12.3
|
Release files / alpacloud.lens-0.1.0-py3-none-any.whl
| Download URL | alpacloud.lens-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ffe98f2430ee1f891697f7e7edca2eefd0a7a71c0188c60dd7b73849f09578dc
|
|
BLAKE2b-256 checksum How to use checksums |
3e1e934b9fa3ea28d7d9ff1a2a5c81530c30a0ac0197e6a7e38bb60eea24e42a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.1.1 CPython/3.12.3
|
Security for alpacloud.lens 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.