Properties
The Properties
class in PySpring provides a way to manage application-specific configurations. It allows you to load properties from a file and inject them into components.
Key Features
- Properties Registration: Properties classes are registered within the
ApplicationContext
, similar to components, controllers, and bean collections. - Configuration Management:
Properties
classes provide a structured way to manage application settings. They are loaded from a properties file, typically in JSON or YAML format. - Unique Identifiers: Each
Properties
class has a unique key (__key__
) that is used to identify it within the application. This key must be set as a class-level attribute in yourProperties
subclass. - Automatic Loading and Injection: PySpring automatically loads properties during the application initialization process and injects them into components where they are needed.
- File Format Support: Properties can be loaded from JSON or YAML files. The
_PropertiesLoader
class handles the parsing of these files. - Validation: The
Properties
class usesPydantic
for data validation. This ensures that the loaded properties conform to the expected schema. - Singleton Scope: Properties are typically loaded as singletons within the application context and are shared across the application.
How to Define Properties
To define your properties, you need to create a class that inherits from Properties
and set the __key__
class variable . This key must be a unique string that will be used to identify this Properties
class.
from py_spring_core import Properties
from pydantic import Field
class AppConfigProperties(Properties):
__key__ = "app_config" # Unique key for this properties class
app_name: str
version: str = Field(default="0.1.0")
log_level: str = "INFO"
In the above example:
AppConfigProperties
inherits from the baseProperties
class.__key__
is set to"app_config"
, which is used to identify this specific set of properties.app_name
,version
, andlog_level
are properties defined using Pydantic's field syntax.
How Properties are Loaded
The _PropertiesLoader
class is used to load properties from a file.
- During application startup, the
PySpringApplication
initializes anApplicationContext
that loads the properties. - The application scans for all classes that inherit from
Properties
. - The properties file path is defined in the application config (e.g.,
./application-properties.json
or./application-properties.yaml
). - The loader attempts to read and parse the file based on its extension (
.json
,.yaml
, or.yml
). - The loader validates the properties against the classes that inherit from
Properties
, ensuring the keys match what has been defined in the application, and raises an error if validation fails. - Once loaded, the properties are stored in the
ApplicationContext
and are accessible for dependency injection.
How to Use Properties
Dependency Injection
Once properties are loaded, you can inject them into your components using type annotations.
from py_spring_core import Component, Properties
from .app_config_properties import AppConfigProperties
class MyComponent(Component):
app_config: AppConfigProperties
def post_construct(self):
print(f"App Name: {self.app_config.app_name}")
print(f"Log Level: {self.app_config.log_level}")`
- The
MyComponent
class has a type annotationapp_config: AppConfigProperties
, whereAppConfigProperties
is the properties class defined above. - The application context automatically injects an instance of
AppConfigProperties
into theapp_config
attribute of theMyComponent
instance. - The properties can then be accessed within the
MyComponent
's methods.
Accessing Properties Directly
You can also access properties directly from the _PropertiesLoader
if needed. Note, this is typically not necessary if you are using dependency injection.
from py_spring_core.core.entities.properties.properties_loader import _PropertiesLoader
app_config = _PropertiesLoader.get_properties("app_config")
if app_config:
print(f"Direct access: App Name: {app_config.app_name}")`
Configuration File Examples
JSON
A JSON properties file might look like this. The key app_config
must match the key defined in the Properties
subclass.
YAML
A YAML properties file might look like this. The key app_config
must match the key defined in the Properties
subclass.
Important Considerations
- Key Uniqueness: Ensure that each
Properties
class has a unique__key__
to avoid conflicts. - File Path: The properties file path must be correctly configured in the application's configuration file.
- File Format: PySpring supports both JSON and YAML formats for properties files.
- Validation: Ensure that your properties files match the structure defined in your
Properties
classes. Pydantic will enforce data types and raise errors if there are mismatches. - Dependency Injection: For loose coupling, use dependency injection to make your properties available to components, which is typically preferred over directly accessing properties from
_PropertiesLoader
. - Error Handling: Be aware of the exceptions that can be raised during properties loading, such as
InvalidPropertiesKeyError
, andTypeError
if the properties are not found or are not properly configured.
By using the Properties
class, you can effectively manage your application's configurations in a structured and maintainable way.