A multi-purpose application framework embodying beauty in form.
Project description
Tiferet - A Python Framework for Domain-Driven Design
Introduction
Tiferet is a Python framework that elegantly distills Domain-Driven Design (DDD) into a practical, powerful tool. Drawing inspiration from the concept of beauty in balance as expressed in Kabbalah, Tiferet weaves purpose and functionality into software that not only performs but resonates deeply with its intended vision. As a cornerstone for crafting diverse applications, Tiferet empowers developers to build solutions with clarity, grace, and thoughtful design.
Tiferet embraces the complexity of real-world processes through DDD, transforming intricate business logic and evolving requirements into clear, manageable models. Far from merely navigating this labyrinth, Tiferet provides a graceful path to craft software that reflects its intended purpose with wisdom and precision, embodying beauty and balance in form and function. This tutorial guides you through building a simple calculator application, demonstrating how Tiferet harmonizes code and concept. By defining domain events and their configurations, you'll create a robust and extensible calculator that resonates with Tiferet's philosophy.
Getting Started with Tiferet
Embark on your Tiferet journey with a few simple steps to set up your Python environment. Whether you're new to Python or a seasoned developer, these instructions will prepare you to craft a calculator application with grace and precision.
Installing Python
Tiferet requires Python 3.10 or later. Follow these steps to install it:
Windows
Visit python.org, navigate to the Downloads section, and select the Python 3.10 installer for Windows. Run the installer, ensuring you check "Add Python 3.10 to PATH," then click "Install Now."
macOS
Download the Python 3.10 installer from python.org. Open the .pkg file and follow the installation prompts.
Linux (Ubuntu/Debian)
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install python3.10
Verify the installation by running:
python3.10 --version
You should see Python 3.10.x if successful.
Setting Up a Virtual Environment
To keep your project dependencies organized, create a virtual environment named tiferet_app for your calculator application:
Create the Environment
# Windows
python -m venv tiferet_app
# macOS/Linux
python3.10 -m venv tiferet_app
Activate the Environment
Activate the environment to isolate your project's dependencies:
# Windows (Command Prompt)
tiferet_app\Scripts\activate
# Windows (PowerShell)
.\tiferet_app\Scripts\Activate.ps1
# macOS/Linux
source tiferet_app/bin/activate
Your terminal should display (tiferet_app), confirming the environment is active. You can now install Tiferet and other dependencies without affecting your system’s Python setup.
Deactivate the Environment
When finished, deactivate the environment with:
deactivate
Your First Calculator App
With your tiferet_app virtual environment activated, you're ready to install Tiferet and start building your calculator application. Follow these steps to set up your project and begin crafting with Tiferet’s elegant approach.
Installing Tiferet
Install the Tiferet package using pip in your activated virtual environment:
# Windows
pip install tiferet
# macOS/Linux
pip3 install tiferet
Project Structure
Create a project directory structure to organize your calculator application:
project_root/
├── basic_calc.py
├── calc_cli.py
└── app/
├── events/
│ ├── __init__.py
│ ├── calc.py
│ └── settings.py
└── configs/
├── __init__.py
├── app.yml
├── cli.yml
├── di.yml
├── error.yml
├── feature.yml
└── logging.yml
The app/events/ directory holds domain event classes for arithmetic operations (calc.py) and input validation (settings.py). The app/configs/ directory contains configuration files for application settings (app.yml), CLI commands (cli.yml), dependency injection (di.yml), error handling (error.yml), feature workflows (feature.yml), and logging (logging.yml). The basic_calc.py script at the root initializes and runs the application. We recommend keeping the app directory name for internal projects to ensure consistency, though it can be customized for package releases. The calc_cli.py script provides a flexible command-line interface, easily integrated with shell scripts or external systems.
Crafting the Calculator Application
With Tiferet installed and your project structured, it's time to build your calculator application. This section guides you through creating a base domain event for numeric validation, defining arithmetic domain events, and setting up the application's behavior with configurations. By weaving together domain events and configurations, you'll experience Tiferet's elegant design, harmonizing functionality with clarity and precision.
Defining Base and Arithmetic Domain Event Classes
Start by creating domain event classes for numeric validation and arithmetic operations. The BasicCalcEvent in app/events/settings.py provides validation logic, while arithmetic domain events (AddNumber, SubtractNumber, MultiplyNumber, DivideNumber, ExponentiateNumber) in app/events/calc.py perform calculations. All arithmetic domain events inherit from BasicCalcEvent, which extends Tiferet's DomainEvent class, ensuring robust numeric validation and core event functionality.
Base Domain Event in events/settings.py
Numeric validation is critical to ensure the calculator handles inputs correctly, preventing errors from invalid data. The BasicCalcEvent class centralizes validation logic, making it reusable across all arithmetic domain events by converting string inputs to integers or floats.
Create app/events/settings.py with the following contents:
# *** imports
# ** infra
from tiferet.events import *
# *** events
# ** event: basic_calc_event
class BasicCalcEvent(DomainEvent):
'''
A domain event to validate that a value can be a Number object.
'''
# * method: verify_number
def verify_number(self, value: str) -> int | float:
'''
Verify that the value can be converted to an integer or float.
:param value: The value to verify.
:type value: str
:return: The numeric value as an integer or float.
:rtype: int | float
'''
# Check if the value is a valid number.
is_valid = isinstance(value, str) and (value.isdigit() or (value.replace('.', '', 1).isdigit() and value.count('.') < 2))
# Verify the value.
self.verify(
is_valid,
'INVALID_INPUT',
f"Invalid number: {value}",
value
)
# If valid, return the value as a float or int.
if '.' in value:
return float(value)
return int(value)
The BasicCalcEvent extends Tiferet's DomainEvent class, providing a verify_number method that validates string inputs and returns them as int or float. It raises an INVALID_INPUT error for invalid inputs, ensuring all arithmetic domain events inherit robust validation.
Arithmetic Domain Events in events/calc.py
The arithmetic domain events are the heart of the calculator, delivering core mathematical operations: addition, subtraction, multiplication, division, and exponentiation. These domain events leverage Python's numeric capabilities, processing validated inputs to produce precise results.
Create app/events/calc.py with the following content:
# *** imports
# ** core
from typing import Any
# ** infra
from tiferet.events import *
# ** app
from .settings import BasicCalcEvent
# *** events
# ** event: add_number
class AddNumber(BasicCalcEvent):
'''
A domain event to perform addition of two numbers.
'''
def execute(self, a: Any, b: Any, **kwargs) -> int | float:
'''
Execute the addition event.
:param a: A number representing the first operand.
:type a: Any
:param b: A number representing the second operand.
:type b: Any
:param kwargs: Additional keyword arguments.
:type kwargs: dict
:return: The sum of a and b.
:rtype: int | float
'''
# Verify numeric inputs
a_verified = self.verify_number(str(a))
b_verified = self.verify_number(str(b))
# Add verified values of a and b.
result = a_verified + b_verified
# Return the result.
return result
# ** event: subtract_number
class SubtractNumber(BasicCalcEvent):
'''
A domain event to perform subtraction of two numbers.
'''
def execute(self, a: Any, b: Any, **kwargs) -> int | float:
'''
Execute the subtraction event.
:param a: A number representing the first operand.
:type a: Any
:param b: A number representing the second operand.
:type b: Any
:param kwargs: Additional keyword arguments.
:type kwargs: dict
:return: The difference of a and b.
:rtype: int | float
'''
# Verify numeric inputs
a_verified = self.verify_number(str(a))
b_verified = self.verify_number(str(b))
# Subtract verified values of b from a.
result = a_verified - b_verified
# Return the result.
return result
# ** event: multiply_number
class MultiplyNumber(BasicCalcEvent):
'''
A domain event to perform multiplication of two numbers.
'''
def execute(self, a: Any, b: Any, **kwargs) -> int | float:
'''
Execute the multiplication event.
:param a: A number representing the first operand.
:type a: Any
:param b: A number representing the second operand.
:type b: Any
:param kwargs: Additional keyword arguments.
:type kwargs: dict
:return: The product of a and b.
:rtype: int | float
'''
# Verify numeric inputs
a_verified = self.verify_number(str(a))
b_verified = self.verify_number(str(b))
# Multiply the verified values of a and b.
result = a_verified * b_verified
# Return the result.
return result
# ** event: divide_number
class DivideNumber(BasicCalcEvent):
'''
A domain event to perform division of two numbers.
'''
def execute(self, a: Any, b: Any, **kwargs) -> int | float:
'''
Execute the division event.
:param a: A number representing the numerator.
:type a: Any
:param b: A number representing the denominator, must be non-zero.
:type b: Any
:param kwargs: Additional keyword arguments.
:type kwargs: dict
:return: The quotient of a and b.
:rtype: int | float
'''
# Verify numeric inputs
a_verified = self.verify_number(str(a))
b_verified = self.verify_number(str(b))
# Check if b is zero to avoid division by zero.
self.verify(b_verified != 0, 'DIVISION_BY_ZERO')
# Divide the verified values of a by b.
result = a_verified / b_verified
# Return the result.
return result
# ** event: exponentiate_number
class ExponentiateNumber(BasicCalcEvent):
'''
A domain event to perform exponentiation of two numbers.
'''
def execute(self, a: Any, b: Any, **kwargs) -> int | float:
'''
Execute the exponentiation event.
:param a: A number representing the base.
:type a: Any
:param b: A number representing the exponent.
:type b: Any
:param kwargs: Additional keyword arguments.
:type kwargs: dict
:return: The result of a raised to the power of b.
:rtype: int | float
'''
# Verify numeric inputs
a_verified = self.verify_number(str(a))
b_verified = self.verify_number(str(b))
# Exponentiate the verified value of a by b.
result = a_verified ** b_verified
# Return the result.
return result
These domain events perform arithmetic operations on flexible input values, validated by BasicCalcEvent.verify_number to ensure they are valid integers or floats. The method converts string inputs to int or float before computation, returning the result as a numeric value. The DivideNumber event includes a check to prevent division by zero, raising a configured DIVISION_BY_ZERO error if needed.
Configuring the Calculator Application
With domain event classes defined, it's time to configure the Tiferet application to recognize and orchestrate them, enabling seamless user interaction through features and interfaces. This section guides you through setting up the application interface (app/configs/app.yml), defining domain event classes as container attributes (app/configs/container.yml), specifying error messages (app/configs/error.yml), and organizing features (app/configs/feature.yml). These configurations weave together Tiferet's dependency injection and feature-driven design, ensuring a robust and extensible calculator.
Configuring the App Interface in configs/app.yml
Define the calculator's user interface in app/configs/app.yml to specify the interface type and its core attributes. This configuration enables Tiferet to initialize the application with default settings, supporting multiple interfaces for flexible feature execution.
Create app/configs/app.yml with the following content:
interfaces:
basic_calc:
name: Basic Calculator
description: Perform basic calculator operations
The interfaces section configures the basic_calc interface with a name and description, using Tiferet's default settings to streamline application setup. This setup aligns with the project structure, preparing the calculator for domain event and feature integration.
Configuring the Container in configs/container.yml
Expose domain event classes to Tiferet by defining them as container attributes in app/configs/container.yml. This configuration maps each domain event to its module and class, enabling dependency injection for seamless feature execution.
Create the app/configs/container.yml with the following content:
attrs:
add_number_event:
module_path: app.events.calc
class_name: AddNumber
subtract_number_event:
module_path: app.events.calc
class_name: SubtractNumber
multiply_number_event:
module_path: app.events.calc
class_name: MultiplyNumber
divide_number_event:
module_path: app.events.calc
class_name: DivideNumber
exponentiate_number_event:
module_path: app.events.calc
class_name: ExponentiateNumber
The attrs section lists each domain event with a unique identifier (ending in _event), specifying its module path and class name. This setup ensures Tiferet can instantiate and execute the calculator's arithmetic domain events efficiently.
Configuring the Errors in configs/error.yml
Handle errors gracefully by defining error messages in app/configs/error.yml. This configuration specifies error codes and multilingual messages, ensuring clear feedback for invalid inputs or operations.
Create app/configs/error.yml with the following content:
errors:
invalid_input:
name: Invalid Numeric Input
message:
- lang: en_US
text: 'Value {} must be a number'
- lang: es_ES
text: 'El valor {} debe ser un número'
division_by_zero:
name: Division By Zero
message:
- lang: en_US
text: 'Cannot divide by zero'
- lang: es_ES
text: 'No se puede dividir por cero'
The errors section defines invalid_input for failed numeric validations and division_by_zero for division errors, supporting English (en_US) and Spanish (es_ES) messages. This configuration enhances user experience with localized, precise error handling.
Configuring the Features in configs/feature.yml
Orchestrate domain event execution by defining features in app/configs/feature.yml. This configuration organizes arithmetic operations into reusable workflows, mapping each feature to its corresponding domain event for streamlined execution.
Create app/configs/feature.yml with the following content:
features:
calc:
add:
name: 'Add Number'
description: 'Adds one number to another'
commands:
- attribute_id: add_number_event
name: Add `a` and `b`
subtract:
name: 'Subtract Number'
description: 'Subtracts one number from another'
commands:
- attribute_id: subtract_number_event
name: Subtract `b` from `a`
multiply:
name: 'Multiply Number'
description: 'Multiplies one number by another'
commands:
- attribute_id: multiply_number_event
name: Multiply `a` and `b`
divide:
name: 'Divide Number'
description: 'Divides one number by another'
commands:
- attribute_id: divide_number_event
name: Divide `a` by `b`
exp:
name: 'Exponentiate Number'
description: 'Raises one number to the power of another'
commands:
- attribute_id: exponentiate_number_event
name: Raise `a` to the power of `b`
sqrt:
name: 'Square Root'
description: 'Calculates the square root of a number'
commands:
- attribute_id: exponentiate_number_event
name: Calculate square root of `a`
params:
b: '0.5' # Square root is equivalent to raising to the power of 0.5
The features section maps each operation (e.g., calc.add, calc.sqrt) to its domain event via attribute_id, with descriptive names and parameters. The calc.sqrt feature reuses exponentiate_number_event with a fixed b value of 0.5, showcasing Tiferet's flexible workflow design.
Initializing and Demonstrating the Calculator in basic_calc.py
Bring the Tiferet calculator to life with basic_calc.py, a script that initializes the application and demonstrates its arithmetic prowess. This script leverages Tiferet’s App class to load the basic_calc interface and execute features, showcasing robust calculations and error handling.
Create basic_calc.py with the following content:
from tiferet import App, TiferetError
# Initialize the Tiferet application with configuration settings.
app = App()
# Define test cases for calculator features.
test_cases = [
('calc.add', dict(a=1, b=2), '{} + {} = {}'),
('calc.subtract', dict(a=5, b=3), '{} - {} = {}'),
('calc.multiply', dict(a=4, b=3), '{} * {} = {}'),
('calc.divide', dict(a=8, b=2), '{} / {} = {}'),
('calc.divide', dict(a=8, b=0), '{} / {} = {}'), # Expect error
('calc.exp', dict(a=2, b=3), '{} ** {} = {}'),
('calc.sqrt', dict(a=16), '√{} = {}')
]
# Execute each test case, demonstrating calculator features.
for feature_id, data, format_str in test_cases:
a, b = data.get('a'), data.get('b', None)
try:
result = app.run('basic_calc', feature_id, data=data)
print(format_str.format(a, b if b is not None else a, result))
except TiferetError as e:
print(f'Error: {e.message}')
The basic_calc.py script initializes the Tiferet application with settings from app/configs/app.yml, executes a series of test cases for arithmetic features, and handles errors gracefully. It demonstrates the calculator’s core functionality, from addition to square root, with clear output formatting.
Demonstrating the Calculator
Run the calculator to see its features in action, ensuring Tiferet’s power is fully unleashed. Activate your tiferet_app virtual environment and confirm Tiferet is installed, then execute the script to observe the results.
Execute the following command:
python basic_calc.py
This command runs basic_calc.py, producing output for each arithmetic operation and error case, leveraging configurations from app/configs/ to deliver precise, user-friendly results.
The Calculator as a CLI App
Unleash the calculator’s full potential with a dynamic command-line interface (CLI) powered by Tiferet’s CliContext. Implemented in calc_cli.py at the project root, this script offers a scriptable, user-friendly interface that complements the basic_calc.py test script for debugging. Leveraging Tiferet’s App class and CliContext, it executes features defined in app/configs/feature.yml, accepting command-line arguments for operations like addition (calc.add), subtraction (calc.subtract), multiplication (calc.multiply), division (calc.divide), exponentiation (calc.exp), and square root (calc.sqrt). This CLI interface seamlessly integrates with shell scripts and external systems, showcasing Tiferet’s flexibility in runtime environments.
Configure CLI Commands in configs/cli.yml
Define the CLI’s command structure in app/configs/cli.yml to enable CliContext to parse user inputs. This configuration specifies commands, their arguments, and descriptions, ensuring intuitive interaction with the calculator’s features.
Create app/configs/cli.yml with the following content:
cli:
cmds:
calc:
add:
group_key: calc
key: add
description: Adds two numbers.
args:
- name_or_flags:
- a
description: The first number to add.
- name_or_flags:
- b
description: The second number to add.
name: Add Number Command
subtract:
group_key: calc
key: subtract
description: Subtracts one number from another.
args:
- name_or_flags:
- a
description: The number to subtract from.
- name_or_flags:
- b
description: The number to subtract.
name: Subtract Number Command
multiply:
group_key: calc
key: multiply
description: Multiplies two numbers.
args:
- name_or_flags:
- a
description: The first number to multiply.
- name_or_flags:
- b
description: The second number to multiply.
name: Multiply Number Command
divide:
group_key: calc
key: divide
description: Divides one number by another.
args:
- name_or_flags:
- a
description: The numerator.
- name_or_flags:
- b
description: The denominator.
name: Divide Number Command
sqrt:
group_key: calc
key: sqrt
description: Calculates the square root of a number.
args:
- name_or_flags:
- a
description: The number to square root.
name: Square Root Command
The cli.cmds section maps each feature (e.g., calc.add) to its command group (calc), key (e.g., add), and arguments (a, b), enabling CliContext to parse inputs and execute features with precision.
Configuring the CLI Interface in configs/app.yml
Enable the CLI interface by adding the calc_cli interface to app/configs/app.yml. This configuration integrates CliContext with its dependencies, CliYamlProxy and CliHandler, to manage command-line interactions.
Add the calc_cli interface to the interfaces section:
interfaces:
basic_calc:
name: Basic Calculator
description: Perform basic calculator operations
calc_cli:
name: Calculator CLI
description: Perform basic calculator operations via CLI
module_path: tiferet.contexts.cli
class_name: CliContext
attrs:
cli_repo:
module_path: tiferet.proxies.yaml.cli
class_name: CliYamlProxy
params:
cli_config_file: app/configs/cli.yml
cli_service:
module_path: tiferet.handlers.cli
class_name: CliHandler
The calc_cli interface specifies CliContext as its implementation, with cli_repo and cli_service attributes linking to CliYamlProxy (loading cli.yml) and CliHandler for command processing. This setup ensures robust CLI functionality within Tiferet’s ecosystem.
Creating the CLI Script
Craft a streamlined CLI script in calc_cli.py to initialize and run the calculator’s command-line interface. This script uses Tiferet’s App class to load the calc_cli interface, powered by CliContext, for seamless command execution.
Create calc_cli.py with the following content:
from tiferet import App
# Create new app (manager) instance.
app = App()
# Load the CLI app instance.
cli = app.load_interface('calc_cli')
# Run the CLI app.
if __name__ == '__main__':
cli.run()
The calc_cli.py script initializes the App, loads the calc_cli interface, and executes commands via CliContext, with error handling to ensure user-friendly feedback for invalid inputs or operations.
Demonstrating the CLI Calculator
Experience the calculator’s CLI in action by running commands that showcase its arithmetic and error-handling capabilities. Ensure the tiferet_app virtual environment is activated and Tiferet is installed, then execute the script with feature-specific arguments.
Run the CLI with commands like:
# Add two numbers
python calc_cli.py calc add 1 2
# Output: 3
# Calculate square root
python calc_cli.py calc sqrt 4
# Output: 2.0
# Division by zero
python calc_cli.py calc divide 5 0
# Output: Error: Cannot divide by zero
The calc_cli.py script offers a versatile, scriptable interface that integrates effortlessly with shell scripts or external systems, powered by CliContext for robust command execution. For quick testing or debugging, use basic_calc.py to run individual features with predefined values, while the CLI provides precise, argument-driven control.
Documentation
Tiferet provides detailed documentation for framework internals and utility usage.
Core Design Documents
Architectural references for framework contributors and advanced users:
- Code Style — Artifact comments, spacing, docstrings, and formatting conventions
- Domain Objects — Domain model structure and factory patterns
- Domain Events — Event patterns, validation, and testing
- Interfaces — Service contract conventions
- Mappers — Aggregate and TransferObject patterns
- Utilities — Infrastructure utilities design and best practices
Domain Guides
Practical guides for working with Tiferet's domain layers:
- App (Bootstrap & Assembly) — Application interfaces, service dependency bindings, runtime wiring
- CLI (Command-Line Interface) — CLI commands, arguments, CLI-to-feature bridge
- DI (Dependency Injection) — Service configurations, flagged dependencies, flag-based resolution
- Error (Structured Error Handling) — Error definitions, multilingual messages, formatting flow
- Feature (Workflow Orchestration) — Features, steps, parameter resolution, execution flow
- Logging (Observability) — Formatters, handlers, loggers, dictConfig assembly
- Mappers – Strategies and Patterns — Aggregate and TransferObject design decisions, nested sub-objects, role strategies, and round-trip mapping
Utility Guides
Practical guides for using Tiferet's built-in utilities:
- FileLoader (File) — Base file I/O with context-manager lifecycle
- YamlLoader (Yaml) — YAML read/write with node navigation
- JsonLoader (Json) — JSON read/write with path support
- CsvLoader (Csv) — List and dict-based CSV operations
- SqliteClient (Sqlite) — SQLite database client with transaction management
Conclusion
Embark on a journey of elegance and precision with Tiferet's Domain-Driven Design framework, as this tutorial has crafted a robust calculator application. You've defined arithmetic and validation domain events in app/events/calc.py and app/events/settings.py, orchestrated them with configurations in app/configs/app.yml, app/configs/feature.yml, and app/configs/cli.yml, and brought them to life through basic_calc.py and the CliContext-powered calc_cli.py. This configuration-driven approach, enriched with dependency injection and multilingual error handling, reflects Tiferet's harmonious balance of clarity and power, making development both functional and delightful.
Extend your calculator's potential with Tiferet's modular design. Create a terminal user interface (TUI) in calc_tui.py, leveraging CliContext for interactive operation, or define a scientific calculator interface (sci_calc) in app/configs/app.yml with advanced features like trigonometric functions. Integrate the calculator into larger systems, such as financial modeling, by adding new domain events and features in app/configs/feature.yml. Experiment with calc_cli.py to test additional operations, tweak configurations in app/configs/, or explore Tiferet's documentation for advanced DDD techniques. Let Tiferet's graceful framework guide you to solutions that resonate with purpose and precision, transforming complexity into clarity.
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 tiferet-2.0.0a4.tar.gz.
File metadata
- Download URL: tiferet-2.0.0a4.tar.gz
- Upload date:
- Size: 133.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3aca33fc9df67fac850f011a15fdf7f83fa7043e80ba5a9b4b6ff6fc1b69025d
|
|
| MD5 |
8d1058e01be3d2e1c5761edd0aa7569d
|
|
| BLAKE2b-256 |
8a66f6b24c29b3555eb2bf604b41c746a5019fe314332b3eb1e22e149b30f81d
|
Provenance
The following attestation bundles were made for tiferet-2.0.0a4.tar.gz:
Publisher:
python-publish.yml on greatstrength/tiferet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tiferet-2.0.0a4.tar.gz -
Subject digest:
3aca33fc9df67fac850f011a15fdf7f83fa7043e80ba5a9b4b6ff6fc1b69025d - Sigstore transparency entry: 1056128504
- Sigstore integration time:
-
Permalink:
greatstrength/tiferet@0736b279d0454990c303c458929115688d071591 -
Branch / Tag:
refs/tags/v2.0.0a4 - Owner: https://github.com/greatstrength
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@0736b279d0454990c303c458929115688d071591 -
Trigger Event:
release
-
Statement type:
File details
Details for the file tiferet-2.0.0a4-py3-none-any.whl.
File metadata
- Download URL: tiferet-2.0.0a4-py3-none-any.whl
- Upload date:
- Size: 194.0 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 |
5dc45c042d679d97ea704b23037797c30960d2f0a1099024fd088b5c1cb9fd77
|
|
| MD5 |
ddd73d91c1b89838ea41545e741a1420
|
|
| BLAKE2b-256 |
c5a76e00027716a48f50c1dc13041a5b8dc895c287d6549a925f3bcbd501a7a0
|
Provenance
The following attestation bundles were made for tiferet-2.0.0a4-py3-none-any.whl:
Publisher:
python-publish.yml on greatstrength/tiferet
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
tiferet-2.0.0a4-py3-none-any.whl -
Subject digest:
5dc45c042d679d97ea704b23037797c30960d2f0a1099024fd088b5c1cb9fd77 - Sigstore transparency entry: 1056128505
- Sigstore integration time:
-
Permalink:
greatstrength/tiferet@0736b279d0454990c303c458929115688d071591 -
Branch / Tag:
refs/tags/v2.0.0a4 - Owner: https://github.com/greatstrength
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@0736b279d0454990c303c458929115688d071591 -
Trigger Event:
release
-
Statement type: