A framework for supporting MVC and observer patterns in Python
Project description
orrery
A framework for supporting MVC and observer patterns in Python
Example usage
Create a basic model to hold a simple value
from orrery.models import ValueModel
my_model = ValueModel()
Define a class to listen to callbacks
class CallbackClass:
def value_changed(self, model):
print(f"New value: {model.value}")
callback_class = CallbackClass()
Note: at present the callback needs to be a class function
Add an observer to listed to changes to the model:
my_model.add_value_changed_listener(callback_class.value_changed)
Change the value of the model:
my_model.value = "Foo"
read the value of a model:
current_value = model.value
print(f"Current model value is {current_value}")
Initial values
Models start in an uninitialised state. When a value is set, the model is
initialised. You can use the Model's has_value() method to determine if the
Model has been initialised
my_model = ValueModel()
print(my_model.has_value())
my_model.value = "Foo"
print(my_model.has_value())
If you want to create a model with an initial value, use:
my_model = ValueModel(value="Foo")
When you add an observer to an unititialised Model, the observer will receive a callback when the Model is set. If you add an observer to a Model which already has a value, the observer will immediately receive a callback with the value.
This ensures that te behaviour of your application is the same regardless of whether you set the values of the Models before or after you add the observers.
Dependent models
A dependent model is one that changes when other models change.
You create a dependent model by subclassing DependentModel and defining a
method get_model_results which computes the model value.
from orrery.models import Model, DependentModel
class SumModel(DependentModel):
def __init__(self, model_a: Model, model_b: Model):
self.model_a = model_a
self.model_b = model_b
super().__init__([model_a, model_b])
def get_model_result(self):
return self.model_a.value + self.model_b.value
model_a = ValueModel(value=2)
model_b = ValueModel(value=3)
sum_model = SumModel(model_a, model_b)
print(sum_model.value)
The key use of a DependentModel is that it will automatically recompute its value and fire value changed events whenever any of its dependencies change.
For example, if we use the CallbackClass we defined previously to listen for changes in our SumModel clas:
sum_model.add_value_changed_listener(callback_class.value_changed)
model_a.value = 8
We see that the change in the value of model_a automatically triggers an update to the SumModel.
Delayed initialisation and default values
ValueModels can also be given default values on creation. These are used for
delayed initialisation. You may not know the required value of a ValueModel at
the time it is created (for example, if the values are read in later from a
configuration file or web API) but you can set a default value:
my_model = ValueModel(default="Foo")
print(my_model.value)
Later, after your code has had a chance to optionally set the initial model
value, you can call the Model's initialise() method:
my_model.initialise()
print(my_model.value)
If the value has not been set, the model will then take on the default value.
Why is this different from setting an initial value? Because an initial value will cause an immediate callback with the initial value, and then a second callback when the delayed initialisation occurs. Using a default value, the initial callback only occurs once. This avoids the GUI flickering you can see with applications using other frameworks.
Source code
License
See license file
Copyright
© 2025 Code Choreography Limited
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
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 orrery-0.0.2.tar.gz.
File metadata
- Download URL: orrery-0.0.2.tar.gz
- Upload date:
- Size: 10.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97f18e3e58427e8fa7e2c4a444881519edd68649ebb6583e4638ba921b3bfe74
|
|
| MD5 |
55e0b4e0fff99aad35e451e2c28d4677
|
|
| BLAKE2b-256 |
aabb046ab214a33207c62f707266e931875fc65c3417741fdc46d89092598fb0
|
Provenance
The following attestation bundles were made for orrery-0.0.2.tar.gz:
Publisher:
publish.yml on CodeChoreography/orrery
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
orrery-0.0.2.tar.gz -
Subject digest:
97f18e3e58427e8fa7e2c4a444881519edd68649ebb6583e4638ba921b3bfe74 - Sigstore transparency entry: 607751745
- Sigstore integration time:
-
Permalink:
CodeChoreography/orrery@9a9ec349aee03918b4588dc4983572b9dde9d7d8 -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/CodeChoreography
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9a9ec349aee03918b4588dc4983572b9dde9d7d8 -
Trigger Event:
push
-
Statement type:
File details
Details for the file orrery-0.0.2-py3-none-any.whl.
File metadata
- Download URL: orrery-0.0.2-py3-none-any.whl
- Upload date:
- Size: 8.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1931c76cca6ce164dcbf154d90c02a99da9590291ce3b3934e87d772895d98de
|
|
| MD5 |
a80bf59ceebbd480f91ad2927eecced9
|
|
| BLAKE2b-256 |
2f65585366a7571e5caeb3165f59bc58da198a427bbf31218e44d78d3dfd46d1
|
Provenance
The following attestation bundles were made for orrery-0.0.2-py3-none-any.whl:
Publisher:
publish.yml on CodeChoreography/orrery
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
orrery-0.0.2-py3-none-any.whl -
Subject digest:
1931c76cca6ce164dcbf154d90c02a99da9590291ce3b3934e87d772895d98de - Sigstore transparency entry: 607751747
- Sigstore integration time:
-
Permalink:
CodeChoreography/orrery@9a9ec349aee03918b4588dc4983572b9dde9d7d8 -
Branch / Tag:
refs/tags/v0.0.2 - Owner: https://github.com/CodeChoreography
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9a9ec349aee03918b4588dc4983572b9dde9d7d8 -
Trigger Event:
push
-
Statement type: