Configuration
Configuration Files
Section titled “Configuration Files”Orionis Framework manages application configuration using dataclasses, centralizing parameters in the config/ directory. These files allow you to define key aspects such as database, email, sessions, and other essential behaviors.
Each file extends a base class with default values, which you can override according to your project requirements.
Below are the main configuration files, their properties, and available options.
app.py
Section titled “app.py”The app.py file contains the main configuration for your Orionis Framework application, defining essential parameters such as environment, debugging, networking, workers, localization, and encryption. This centralized configuration allows you to adapt the application’s behavior according to your project’s needs and deployment environment.
How does application configuration work in Orionis Framework?
Section titled “How does application configuration work in Orionis Framework?”Configuration is defined using a dataclass that extends the base App class, leveraging environment variables for specific values and providing safe defaults. This enables you to maintain different configurations for development, testing, and production without changing your code.
Configuration structure
Section titled “Configuration structure”from dataclasses import dataclassfrom orionis.foundation.config.app.entities.app import Appfrom orionis.foundation.config.app.enums.ciphers import Cipherfrom orionis.foundation.config.app.enums.environments import Environmentsfrom orionis.services.environment.env import Envfrom orionis.services.system.workers import Workers
@dataclassclass BootstrapApp(App): # ... configuration propertiesMain configuration properties
Section titled “Main configuration properties”Below are all available options, their purpose, and usage examples:
-
nameApplication name.- Loaded from the
APP_NAMEenvironment variable or defaults to'Orionis Application'. - Used in browser titles, logs, and internal framework references.
- Example:
name = Env.get('APP_NAME', 'My Web Application')
- Loaded from the
-
envApplication runtime environment.- Loaded from
APP_ENVor defaults toEnvironments.DEVELOPMENT. - Available options:
DEVELOPMENT,TESTING,PRODUCTION. - Affects logging, error handling, and optimizations.
You can use the provided ENUM:
from orionis.foundation.config.app.enums.environments import Environments# Available options:Environments.DEVELOPMENTEnvironments.PRODUCTIONEnvironments.TESTINGOr assign the environment as a string:
env = "development" # Or "production", "testing" - Loaded from
-
debugApplication debug mode.- Loaded from
APP_DEBUGor defaults toTrue. - When enabled (
True): shows detailed errors, enables auto-reload, and verbose logs. - Important: Should be disabled (
False) in production for security.
- Loaded from
-
hostIP address the application listens on.- Loaded from
APP_HOSTor defaults to'127.0.0.1'. '127.0.0.1': Local access only (recommended with a reverse proxy likeNginxorApache).'0.0.0.0': Allows external access (use with caution in production).
- Loaded from
-
portNetwork port the application listens on.- Loaded from
APP_PORTor defaults to8000. - Ports below
1024require administrator privileges. - Common suggestions:
80for HTTP,443for HTTPS in production.
- Loaded from
-
workersNumber of worker processes for handling concurrent requests.- Loaded from
APP_WORKERSor usesWorkers().calculate()for automatic calculation. - Defaults to
1, but you can increase it for better performance in production.
Consider if your application is
stateful(keeps state in memory) orstateless(each request is independent):- Stateful: Keep
workers = 1or implement Orionis Framework’sCachesystem (e.g., usingMemcachedorRedisin a separate container) to share state between processes. - Stateless: You can increase the number of workers according to server capacity. A general rule is
2 × CPU cores + 1.
Orionis Framework allows automatic calculation of optimal workers:
from orionis.services.system.workers import Workersworkers = Workers()real_workers = workers.calculate()Recommended example in
app.py:from orionis.services.system.workers import Workers@dataclassclass BootstrapApp(App):workers = Env.get('APP_WORKERS', Workers().calculate())To assign memory per worker:
workers = Env.get('APP_WORKERS', Workers(ram_per_worker=0.5).calculate())# Orworkers = Env.get('APP_WORKERS', Workers().setRamPerWorker(0.5).calculate())Important note: Use the class directly in configuration files, as the facade is only available after application bootstrap.
- Loaded from
-
reloadAutomatic reload when code changes are detected.- Loaded from
APP_RELOADor defaults toTrue. - Useful in development, should be disabled (
False) in production. - Only works with
workers = 1.
- Loaded from
-
timezoneDefault application time zone.- Loaded from
APP_TIMEZONEor defaults to'America/Bogota'. - You can set any valid time zone, such as
'UTC','America/New_York','Europe/Madrid','America/Bogota', etc. - Affects date and time formatting throughout the application.
- Loaded from
-
localeDefault regional setting.- Loaded from
APP_LOCALEor defaults to'en'. - You can change it to
'es','fr','de', etc. - Defines language for messages, number, and date formats.
- Loaded from
-
fallback_localeFallback regional setting.- Loaded from
APP_FALLBACK_LOCALEor defaults to'en'. - Used when the main language is unavailable.
- Ensures the application always has a functional language.
- Loaded from
-
cipherEncryption algorithm for protecting sensitive data.- Loaded from
APP_CIPHERor defaults toCipher.AES_256_CBC. - Default:
AES-256-CBC. Available options:AES-128-CBC,AES-256-CBC,AES-128-GCM,AES-256-GCM. AES-256offers higher security thanAES-128.GCMprovides authenticated encryption,CBCis more compatible.
Orionis Framework provides an ENUM for encryption algorithms:
from orionis.foundation.config.app.enums.ciphers import Cipher# Available options:Cipher.AES_128_CBCCipher.AES_256_CBCCipher.AES_128_GCMCipher.AES_256_GCM - Loaded from
-
keyEncryption key used by the specified algorithm.- Loaded from
APP_KEY(no default value for security). - Critical: Must be a secure, unique, and secret key per application.
- Always store it in environment variables, never in source code.
- Change this key if security is compromised.
- Loaded from
Configuration recommendations
Section titled “Configuration recommendations”- Development: Use
debug=True,reload=True,workers=1for easier development. - Production: Set
debug=False,reload=False, optimizeworkersaccording to hardware. - Security: Keep
keyin environment variables and use HTTPS in production. - Environment variables: Use
.envfiles for environment-specific configurations.
Additional considerations
Section titled “Additional considerations”- Changes to
app.pyrequire restarting the application to take effect. - The framework automatically validates configuration types and values.
- Use
Workers().calculate()to leverage automatic optimal worker calculation. - Configuration is loaded once during application initialization and remains immutable during execution.
auth.py
Section titled “auth.py”This configuration file is still under development and will be available in future versions of Orionis Framework.
cache.py
Section titled “cache.py”This configuration file is still under development and will be available in future versions of Orionis Framework.
cors.py
Section titled “cors.py”The cors.py file allows you to configure CORS (Cross-Origin Resource Sharing) behavior in your Orionis Framework application, controlling how and from where clients can access your API. CORS is essential for the security and functionality of modern web applications, as it defines which external origins can interact with your backend and under what conditions.
How does CORS work in Orionis Framework?
Section titled “How does CORS work in Orionis Framework?”When a browser makes a request to your API from a different origin (domain, protocol, or port), the server responds with CORS headers indicating whether the request is allowed. Orionis Framework uses the configuration defined in cors.py to automatically generate these headers for every response.
Main configuration properties
Section titled “Main configuration properties”Below are all available options, their purpose, and usage examples:
-
allow_originsList of allowed origins that can access the API.- Use
["*"]to allow any origin (not recommended in production for security reasons). - You can specify specific domains, e.g.:
["https://myapp.com", "https://admin.myapp.com"]. - If a request comes from an origin not included, it will be rejected by the browser.
- Use
-
allow_origin_regexRegular expression to allow origins matching a pattern.- Useful for allowing dynamic subdomains, e.g.:
r"^https://.*\.myapp\.com$". - If defined, it takes precedence over
allow_origins.
- Useful for allowing dynamic subdomains, e.g.:
-
allow_methodsList of HTTP methods allowed in CORS requests.- Use
["*"]to allow all methods (GET,POST,PUT,DELETE, etc.). - You can restrict to specific methods:
["GET", "POST"].
- Use
-
allow_headersList of HTTP headers the client can send in CORS requests.- Use
["*"]to allow all headers. - For better security, limit to only those needed:
["Authorization", "Content-Type"].
- Use
-
expose_headersList of headers the browser can access in the response.- By default, the browser only exposes standard headers.
- Example:
["X-Custom-Header", "Authorization"].
-
allow_credentialsAllows the use of credentials (cookies, authorization headers, etc.) in CORS requests.- If set to
True, the browser will send and receive credentials. - Important: You cannot use
["*"]inallow_originsifallow_credentialsisTrue(due to CORS standard restrictions).
- If set to
-
max_ageMaximum time (in seconds) the browser can cache the preflight (OPTIONS) response.- Reduces the number of preflight requests and improves performance.
- Example:
max_age = 600(10 minutes).
Security recommendations
Section titled “Security recommendations”- Production: Limit allowed origins and methods, and enable credentials only if necessary.
- Development: You can use more permissive values (
["*"]) for testing, but never use them in production. - Custom headers: Only expose the headers your frontend actually needs.
Additional considerations
Section titled “Additional considerations”- If you use credentials (
allow_credentials = True), you must specify explicit origins inallow_origins. - Changes to
cors.pyare applied automatically when you restart the application. - Orionis Framework validates and enforces these rules on every request, ensuring compliance with the CORS standard.
- You must use
fieldto assign lists to configuration properties, due to limitations of Pythondataclasses.
Example:
from dataclasses import dataclass, field
#...@dataclassclass BootstrapCors(Cors):
# ... allow_origins: List[str] = field( default_factory = lambda: ["myapp.com", "admin.myapp.com"] )This configuration lets you adapt API access according to your project’s needs, maintaining a balance between functionality and security.
database.py
Section titled “database.py”This configuration file is still under development and will be available in future versions of Orionis Framework.
filesystems.py
Section titled “filesystems.py”The filesystems.py file defines the filesystem configuration for Orionis Framework, enabling you to manage different types of storage such as local disks, public storage, and cloud services like AWS S3. This centralized configuration streamlines file handling for both internal application use and public files accessible by users.
How does the filesystem work in Orionis Framework?
Section titled “How does the filesystem work in Orionis Framework?”The filesystem uses a multi-disk pattern, where each disk represents a different storage location with its own settings. You can dynamically switch between disks as needed, providing flexibility for storing various types of files.
Configuration structure
Section titled “Configuration structure”from dataclasses import dataclassfrom orionis.foundation.config.filesystems.entitites.aws import S3from orionis.foundation.config.filesystems.entitites.disks import Disksfrom orionis.foundation.config.filesystems.entitites.filesystems import Filesystemsfrom orionis.foundation.config.filesystems.entitites.local import Localfrom orionis.foundation.config.filesystems.entitites.public import Public
@dataclassclass BootstrapFilesystems(Filesystems): # ... configuration propertiesMain configuration properties
Section titled “Main configuration properties”Below are all available options, their purpose, and usage examples:
-
defaultName of the default filesystem disk to use.- Default: The value of the
"FILESYSTEM_DISK"environment variable, or"local"if not set. - Specifies which disk is used when none is explicitly indicated.
- Common options:
"local","public","aws".
- Default: The value of the
-
disksConfiguration for the different filesystem disks available to the application.- Default: An instance of
Diskswith default values. - Contains settings for each available storage type.
- Default: An instance of
Available disk configurations
Section titled “Available disk configurations”local – Private local disk
Section titled “local – Private local disk”Configuration for private local storage.
path: Path where private files are stored.- Default:
"storage/app/private".
- Default:
- Ideal for: Configuration files, internal logs, temporary data not meant to be public.
public – Public disk
Section titled “public – Public disk”Configuration for publicly accessible storage via the web.
path: Path where public files are stored.- Default:
"storage/app/public".
- Default:
url: Base URL to access public files.- Default:
"/static".
- Default:
- Ideal for: User images, public assets, downloadable files.
aws – Amazon S3
Section titled “aws – Amazon S3”Configuration for cloud storage using Amazon S3.
-
key: AWS Access Key ID.- Default:
""(must be set). - Obtain from AWS IAM console.
- Default:
-
secret: AWS Secret Access Key.- Default:
""(must be set). - Keep secure and never expose in source code.
- Default:
-
region: AWS region where the bucket is located.- Default:
"us-east-1". - Examples:
"us-west-2","eu-west-1","ap-southeast-1".
- Default:
-
bucket: S3 bucket name.- Default:
""(must be set). - Must already exist in your AWS account.
- Default:
-
url: Custom URL to access the bucket (optional).- Default:
None(uses standard S3 URL). - Useful for CloudFront or custom domains.
- Default:
-
endpoint: Custom S3 endpoint (optional).- Default:
None(uses standard endpoint). - Useful for S3-compatible services like MinIO.
- Default:
-
use_path_style_endpoint: Use path-style instead of virtual-hosted-style URLs.- Default:
False. - Set to
Truefor S3-compatible services that require it.
- Default:
-
throw: Throw exceptions on operation errors.- Default:
False. - Set to
Truefor strict error handling.
- Default:
Configuration recommendations
Section titled “Configuration recommendations”- Development: Mainly use
localandpublicdisks for simplicity and speed. - Production: Consider using
awsfor scalability and redundancy in large applications. - Security: Keep AWS credentials in environment variables, never in source code.
- Performance: Use
publicfor frequently accessed static files.
Additional considerations
Section titled “Additional considerations”- Changes to
filesystems.pyrequire restarting the application to take effect. - Ensure local storage paths have appropriate write permissions.
- For AWS S3, verify credentials have the necessary permissions for the bucket.
- The framework automatically validates configurations and provides descriptive error messages if something is misconfigured.
logging.py
Section titled “logging.py”The logging.py file defines the logging system configuration for Orionis Framework, allowing you to manage multiple logging channels with rotation strategies, retention policies, and custom log levels. This centralized configuration streamlines monitoring, debugging, and auditing through a flexible system of structured logs.
How does logging work in Orionis Framework?
Section titled “How does logging work in Orionis Framework?”The logging system uses multiple channels, each representing a different strategy for storing and rotating logs. You can configure different logging levels, file paths, retention policies, and rotation strategies according to your application’s monitoring needs.
Configuration structure
Section titled “Configuration structure”from dataclasses import dataclassfrom datetime import timefrom orionis.foundation.config.logging.entities.channels import Channelsfrom orionis.foundation.config.logging.entities.chunked import Chunkedfrom orionis.foundation.config.logging.entities.daily import Dailyfrom orionis.foundation.config.logging.entities.hourly import Hourlyfrom orionis.foundation.config.logging.entities.logging import Loggingfrom orionis.foundation.config.logging.entities.monthly import Monthlyfrom orionis.foundation.config.logging.entities.stack import Stackfrom orionis.foundation.config.logging.entities.weekly import Weeklyfrom orionis.foundation.config.logging.enums.levels import Level
@dataclassclass BootstrapLogging(Logging): # ... configuration propertiesMain configuration properties
Section titled “Main configuration properties”Below are all available options, their purpose, and usage examples:
-
defaultName of the default logging channel to use.- Default: The value of the
"LOG_CHANNEL"environment variable, or"stack"if not set. - Specifies which channel is used when none is explicitly indicated.
- Available options:
"stack","hourly","daily","weekly","monthly","chunked".
- Default: The value of the
-
channelsConfiguration for the different logging channels available to the application.- Default: An instance of
Channelswith default settings. - Contains the configuration for each available logging strategy.
- Default: An instance of
Available logging channel configurations
Section titled “Available logging channel configurations”stack – Basic cumulative logging
Section titled “stack – Basic cumulative logging”Configuration for basic logging without automatic rotation.
path: Log file path.- Default:
'storage/logs/stack.log'.
- Default:
level: Minimum logging level.- Default:
Level.INFO.
- Default:
- Ideal for: Development, simple logs, basic debugging.
hourly – Hourly rotation
Section titled “hourly – Hourly rotation”Configuration for logging with rotation every hour.
path: Log file path.- Default:
'storage/logs/hourly.log'.
- Default:
level: Minimum logging level.- Default:
Level.INFO.
- Default:
retention_hours: Number of hours to retain log files.- Default:
24(keeps logs for the last 24 hours).
- Default:
- Ideal for: High-activity applications, granular event monitoring.
daily – Daily rotation
Section titled “daily – Daily rotation”Configuration for logging with daily rotation.
path: Log file path.- Default:
'storage/logs/daily.log'.
- Default:
level: Minimum logging level.- Default:
Level.INFO.
- Default:
retention_days: Number of days to retain log files.- Default:
7(keeps logs for the last week).
- Default:
at: Specific time for rotation.- Default:
time(0, 0)(midnight).
- Default:
- Ideal for: Production applications, daily auditing, trend analysis.
weekly – Weekly rotation
Section titled “weekly – Weekly rotation”Configuration for logging with weekly rotation.
path: Log file path.- Default:
'storage/logs/weekly.log'.
- Default:
level: Minimum logging level.- Default:
Level.INFO.
- Default:
retention_weeks: Number of weeks to retain log files.- Default:
4(keeps logs for the last month).
- Default:
- Ideal for: Weekly trend analysis, periodic reports, lower-activity applications.
monthly – Monthly rotation
Section titled “monthly – Monthly rotation”Configuration for logging with monthly rotation.
path: Log file path.- Default:
'storage/logs/monthly.log'.
- Default:
level: Minimum logging level.- Default:
Level.INFO.
- Default:
retention_months: Number of months to retain log files.- Default:
4(keeps logs for the last 4 months).
- Default:
- Ideal for: Historical archives, regulatory compliance, long-term analysis.
chunked – Size-based rotation
Section titled “chunked – Size-based rotation”Configuration for logging with rotation based on file size.
path: Log file path.- Default:
'storage/logs/chunked.log'.
- Default:
level: Minimum logging level.- Default:
Level.INFO.
- Default:
mb_size: Maximum file size in MB.- Default:
10MB.
- Default:
files: Maximum number of files to keep.- Default:
5files.
- Default:
- Ideal for: Disk space control, applications with variable log volume.
Available logging levels
Section titled “Available logging levels”Logging levels follow the Python logging standard:
Level.DEBUG: Detailed information for debugging.Level.INFO: General operational information.Level.WARNING: Warnings that do not prevent operation.Level.ERROR: Errors affecting specific functionalities.Level.CRITICAL: Critical errors that may stop the application.
Configuration recommendations
Section titled “Configuration recommendations”- Development: Use
stackordailywithDEBUGlevel for maximum information. - Production: Combine
dailyfor general logs andchunkedfor disk space control. - Intensive monitoring: Use
hourlyfor critical, high-activity applications. - Historical archives: Configure
monthlyfor compliance and long-term audits.
Additional considerations
Section titled “Additional considerations”- Log files are rotated automatically according to the configured strategy.
- Ensure logging paths have appropriate write permissions.
- Old logs are deleted automatically based on retention policies.
- The framework automatically creates directories if they do not exist.
- You can use multiple channels simultaneously for different event types.
mail.py
Section titled “mail.py”The mail.py file defines the email system configuration for Orionis Framework, allowing you to manage different email transports such as SMTP for real delivery and local files for development and testing. This centralized configuration streamlines email sending from your application, with support for multiple providers and delivery strategies.
How does the mail system work in Orionis Framework?
Section titled “How does the mail system work in Orionis Framework?”The mail system uses multiple mailers (transports), where each mailer represents a different strategy for delivering emails. You can switch between transports depending on the environment (development, testing, production) without changing your application code—just update the configuration.
Configuration structure
Section titled “Configuration structure”from dataclasses import dataclassfrom orionis.foundation.config.mail.entities.file import Filefrom orionis.foundation.config.mail.entities.mail import Mailfrom orionis.foundation.config.mail.entities.mailers import Mailersfrom orionis.foundation.config.mail.entities.smtp import Smtpfrom orionis.services.environment.env import Env
@dataclassclass BootstrapMail(Mail): # ... configuration propertiesMain configuration properties
Section titled “Main configuration properties”Below are all available options, their purpose, and usage examples:
-
defaultName of the default mailer (transport) used for sending emails.- Loaded from the
MAIL_MAILERenvironment variable or defaults to'smtp'. - Specifies which transport will be used when none is explicitly indicated.
- Available options:
"smtp","file", etc.
- Loaded from the
-
mailersConfiguration for the different email transports available to the application.- Default: An instance of
Mailerswith default settings. - Contains the configuration for each available email delivery strategy.
- Default: An instance of
Available mailer configurations
Section titled “Available mailer configurations”smtp – SMTP Server
Section titled “smtp – SMTP Server”Configuration for sending emails via an SMTP server.
-
url: Full SMTP connection URL (optional, alternative to individual settings).- Loaded from
MAIL_URLor defaults to''. - Format:
smtp://user:password@server:port - If defined, it takes precedence over individual settings.
- Loaded from
-
host: SMTP server for sending emails.- Loaded from
MAIL_HOSTor defaults to''. - Examples:
smtp.gmail.com,smtp.mailgun.org,localhost.
- Loaded from
-
port: SMTP server port.- Loaded from
MAIL_PORTor defaults to587. - Common ports:
25(no encryption),587(STARTTLS),465(SSL/TLS).
- Loaded from
-
encryption: Encryption type for the SMTP connection.- Loaded from
MAIL_ENCRYPTIONor defaults to'TLS'. - Options:
'TLS'(STARTTLS),'SSL'(SSL/TLS),None(no encryption).
- Loaded from
-
username: Username for SMTP authentication.- Loaded from
MAIL_USERNAMEor defaults to''. - Usually the email address or a specific username.
- Loaded from
-
password: Password for SMTP authentication.- Loaded from
MAIL_PASSWORDor defaults to''. - Important: Always keep in environment variables for security.
- Loaded from
-
timeout: SMTP connection timeout in seconds.- Default:
None(uses system default timeout). - Useful for adjusting behavior on slow networks or remote servers.
- Default:
file – File Storage
Section titled “file – File Storage”Configuration for saving emails as files instead of sending them.
path: Directory where emails are stored as files.- Default:
"storage/mail". - Emails are saved in
.emlformat for later inspection.
- Default:
- Ideal for: Development, testing, debugging emails without real delivery.
Popular SMTP provider configurations
Section titled “Popular SMTP provider configurations”smtp = Smtp( host = "smtp.gmail.com", port = 587, encryption = "TLS", username = "your_email@gmail.com", password = "your_app_password")Outlook/Hotmail
Section titled “Outlook/Hotmail”smtp = Smtp( host = "smtp-mail.outlook.com", port = 587, encryption = "TLS", username = "your_email@outlook.com", password = "your_password")SendGrid
Section titled “SendGrid”smtp = Smtp( host = "smtp.sendgrid.net", port = 587, encryption = "TLS", username = "apikey", password = "your_sendgrid_api_key")Mailgun
Section titled “Mailgun”smtp = Smtp( host = "smtp.mailgun.org", port = 587, encryption = "TLS", username = "postmaster@your_domain.mailgun.org", password = "your_mailgun_password")Configuration recommendations
Section titled “Configuration recommendations”- Development: Use the
filetransport to avoid accidental sends and inspect emails. - Testing: Combine
filefor automated tests andsmtpfor occasional manual tests. - Production: Configure
smtpwith a reliable provider and secure credentials. - Security: Use application-specific passwords whenever possible.
Recommended environment variables
Section titled “Recommended environment variables”MAIL_MAILER=smtpMAIL_HOST=smtp.gmail.comMAIL_PORT=587MAIL_ENCRYPTION=TLSMAIL_USERNAME=your_email@gmail.comMAIL_PASSWORD=your_app_passwordAdditional considerations
Section titled “Additional considerations”- Changes to
mail.pyrequire restarting the application to take effect. - Ensure the file transport directory has write permissions.
- Many providers require two-factor authentication and application-specific passwords.
- For Gmail, enable 2-step verification and generate an app password.
- The framework automatically creates directories for the
filetransport. - Consider using transactional services like SendGrid or Mailgun for production applications.
- Emails stored as files include all headers and content for complete debugging.
paths.py
Section titled “paths.py”The paths.py file defines the project’s path configuration for Orionis Framework, establishing the locations of all the application’s important directories. This centralized configuration allows both the framework and your application to automatically locate files and directories without relying on hardcoded paths, making project organization and maintenance easier.
How does the path system work in Orionis Framework?
Section titled “How does the path system work in Orionis Framework?”The path system uses Python’s Path objects to define absolute locations for key directories. All paths are resolved from the project’s root directory, ensuring consistency regardless of where the application is run. The framework uses these paths to automatically locate controllers, models, views, and other components.
Configuration structure
Section titled “Configuration structure”from pathlib import Pathfrom orionis.foundation.config.roots.paths import Paths
class BootstrapPaths(Paths): # ... path propertiesMain configuration properties
Section titled “Main configuration properties”Below are all available paths, their purpose, and default locations:
Main project paths
Section titled “Main project paths”-
rootProject root directory.- Default:
Path.cwd().resolve()(current working directory). - Base for all other project paths.
- Contains files like
main.py,requirements.txt,.env.
- Default:
-
appMain application directory.- Default:
{root}/app. - Contains all application logic organized in subdirectories.
- The heart of your project’s source code.
- Default:
-
configConfiguration files directory.- Default:
{root}/config. - Contains all
.pyconfiguration files (app.py, cors.py, mail.py, etc.). - Centralizes all application configuration.
- Default:
-
bootstrapInitialization files directory.- Default:
{root}/bootstrap. - Contains files that configure application startup.
- Includes provider and initial service configurations.
- Default:
Application logic paths
Section titled “Application logic paths”-
consoleConsole commands and scheduled tasks directory.- Default:
{root}/app/console. - Contains subdirectories for custom commands and
scheduler.py. - Organizes all CLI functionality.
- Default:
-
exceptionsCustom exception handlers directory.- Default:
{root}/app/exceptions. - Contains classes for specific error and exception handling.
- Allows customizing error responses by exception type.
- Default:
-
httpHTTP-related components directory.- Default:
{root}/app/http. - Contains controllers, middleware, validation requests.
- Organizes all web logic for the application.
- Default:
-
modelsORM models directory.- Default:
{root}/app/models. - Contains classes representing database tables.
- Defines relationships, validations, and data logic.
- Default:
-
providersService providers directory.- Default:
{root}/app/providers. - Contains classes that register services in the container.
- Configures dependency injection and bindings.
- Default:
-
notificationsNotification classes directory.- Default:
{root}/app/notifications. - Contains logic for sending emails, SMS, push notifications.
- Organizes different channels and notification types.
- Default:
-
servicesBusiness logic services directory.- Default:
{root}/app/services. - Contains reusable business logic classes.
- Separates complex logic from controllers and models.
- Default:
-
jobsQueue jobs directory.- Default:
{root}/app/jobs. - Contains classes for asynchronous tasks and background processing.
- Organizes jobs executed outside the request-response cycle.
- Default:
Resource and storage paths
Section titled “Resource and storage paths”-
databaseSQLite database file directory.- Default:
{root}/database/database. - Location for the SQLite file when using this driver.
- May also contain migrations and seeds.
- Default:
-
resourcesApplication resources directory.- Default:
{root}/resources. - Contains views, language files, raw assets.
- Organizes content that is not Python code.
- Default:
-
routesRoute definition directory.- Default:
{root}/routes. - Contains files defining Console, Web, and API routes.
- Organizes application routing.
- Default:
-
storageFile storage directory.- Default:
{root}/storage. - Contains logs, cache, uploaded files, sessions.
- Must have write permissions for the application.
- Default:
-
testsTest files directory.- Default:
{root}/tests. - Contains all unit, integration, and functional tests.
- Organizes the project’s automated tests.
- Default:
Typical project structure
Section titled “Typical project structure”my_project/ # root├── app/ # app│ ├── console/ # console│ ├── exceptions/ # exceptions│ ├── http/ # http│ │ ├── controllers/│ │ ├── middleware/│ │ └── requests/│ ├── jobs/ # jobs│ ├── models/ # models│ ├── notifications/ # notifications│ ├── providers/ # providers│ └── services/ # services├── bootstrap/ # bootstrap├── config/ # config├── database/ # database├── resources/ # resources├── routes/ # routes├── storage/ # storage├── tests/ # testsConfiguration recommendations
Section titled “Configuration recommendations”- Development: Default paths are suitable for most projects.
- Customization: Only modify paths if you have specific organizational requirements.
- Consistency: Maintain the standard structure for easier maintenance and collaboration.
- Permissions: Ensure the
storagedirectory has write permissions.
Additional considerations
Section titled “Additional considerations”- Paths are automatically resolved as absolute paths to avoid location issues.
- The framework uses these paths for class and component autoloading.
- Changing paths requires restarting the application and may require additional adjustments.
- All paths are globally available once configuration is loaded.
- The path system is compatible with different operating systems (Windows, Linux, macOS).
- If you modify paths, be sure to update any deployment or CI/CD scripts as well.
queue.py
Section titled “queue.py”This configuration file is still under development and will be available in future versions of Orionis Framework.
session.py
Section titled “session.py”This configuration file is still under development and will be available in future versions of Orionis Framework.
testing.py
Section titled “testing.py”The testing.py file defines the testing system configuration for Orionis Framework, allowing you to customize automated test behavior, including verbosity, parallel execution, result persistence, and web report generation. This centralized configuration streamlines test management for both development and continuous integration.
How does the testing system work in Orionis Framework?
Section titled “How does the testing system work in Orionis Framework?”The testing system provides flexible configuration options to run tests in different ways according to your project needs. You can adjust the output detail level, choose between sequential or parallel execution, and enable advanced features such as persistent results and interactive web reports.
Configuration structure
Section titled “Configuration structure”from dataclasses import dataclassfrom orionis.foundation.config.testing.entities.testing import Testingfrom orionis.foundation.config.testing.enums import ExecutionMode, PersistentDrivers, VerbosityMode
@dataclassclass BootstrapTesting(Testing): # ... configuration propertiesMain configuration properties
Section titled “Main configuration properties”Below are all available options, their purpose, and usage examples:
Output and verbosity configuration
Section titled “Output and verbosity configuration”verbosityVerbosity level for test output.- Default:
VerbosityMode.DETAILED. - Available options:
VerbosityMode.SILENT(0): No output, only final results.VerbosityMode.MINIMAL(1): Minimal output, dots per test.VerbosityMode.DETAILED(2): Detailed output with names and results.
- You can also use numeric values:
0,1,2.
- Default:
Execution configuration
Section titled “Execution configuration”-
execution_modeTest execution mode.- Default:
ExecutionMode.SEQUENTIAL. - Available options:
ExecutionMode.SEQUENTIAL: Sequential execution (one test at a time).ExecutionMode.PARALLEL: Parallel execution (multiple tests simultaneously).
- You can also use strings:
"sequential","parallel".
- Default:
-
max_workersMaximum number of workers for parallel execution.- Default:
1. - Only applies when
execution_modeisPARALLEL. - Recommendation: Do not exceed the number of available CPU cores.
- Example to use all cores:
max_workers = Workers().calculate().
- Default:
-
fail_fastStop execution after the first failure.- Default:
False. - If
True: Stops at the first failed test. - If
False: Runs all tests regardless of failures. - Useful for rapid development when fixing errors one by one.
- Default:
-
throw_exceptionRaise exception if a test fails.- Default:
True. - If
True: Raises exception on failures (useful for CI/CD). - If
False: Completes execution and reports failures without raising exceptions.
- Default:
Test discovery configuration
Section titled “Test discovery configuration”-
folder_pathPattern for searching subfolders for tests.- Default:
'*'(all subfolders in the maintest/directory). - Can be a simple string or a list of patterns.
- Examples:
'example': Only searches the'example'subdirectory.['example', 'integration']: Searches multiple subdirectories.
- Default:
-
patternPattern for test file names.- Default:
'test_*.py'. - Defines which files are considered tests.
- Common examples:
'test_*.py': Files starting with “test_”.'*_test.py': Files ending with “_test”.'test*.py': Any file starting with “test”.
- Default:
-
test_name_patternPattern to filter specific test names.- Default:
None(runs all tests). - Allows running only tests matching a pattern.
- Examples:
'test*': Only test methods starting with'test*', e.g.,testUserCreation.'*Integration*': Only methods containing'Integration'in their name, e.g.,testIntegrationFlow.
- Default:
Persistence and reporting configuration
Section titled “Persistence and reporting configuration”-
persistentKeep persistent test results.- Default:
False. - If
True: Saves results for later analysis. - Useful for progress tracking and trend analysis.
- Default:
-
persistent_driverDriver for storing persistent results.- Default:
PersistentDrivers.JSON. - Available options:
PersistentDrivers.JSON: Stores in JSON files.PersistentDrivers.SQLITE: Stores in SQLite database (different from main database).
- You can also use strings:
"json","sqlite".
- Default:
-
web_reportGenerate interactive web report.- Default:
False. - If
True: Generates an HTML report with charts and statistics.
- Default:
Recommended configurations by environment
Section titled “Recommended configurations by environment”Local development
Section titled “Local development”verbosity = VerbosityMode.DETAILEDexecution_mode = ExecutionMode.SEQUENTIALfail_fast = Truepersistent = Falseweb_report = TrueContinuous integration (CI/CD)
Section titled “Continuous integration (CI/CD)”verbosity = VerbosityMode.MINIMALexecution_mode = ExecutionMode.PARALLELmax_workers = Workers().calculate()fail_fast = Falsethrow_exception = Truepersistent = Trueweb_report = FalseConfiguration recommendations
Section titled “Configuration recommendations”- Development: Use
DETAILEDverbosity andSEQUENTIALexecution for easy debugging. - CI/CD: Enable
throw_exceptionfor continuous integration. - Debugging: Activate
fail_fastto quickly fix errors during development.
Additional considerations
Section titled “Additional considerations”- Parallel execution may not be suitable for tests that share state or resources.
- Web reports are generated in the
storage/testing/reportsdirectory. - Persistent results are stored in
storage/testing/results. - The framework automatically creates necessary storage directories.
- The configuration applies to all framework testing tools.
- Web reports include runtime metrics and code coverage when available.
Bootstrapping
Section titled “Bootstrapping”The bootstrapping process in Orionis Framework is responsible for automatically loading and initializing all configurations during application startup. This system ensures that all configuration parameters are available and validated before any application component begins to operate.
How does configuration bootstrapping work?
Section titled “How does configuration bootstrapping work?”During startup, the framework:
- Automatic loading: Reads all configuration files defined in the
config/directory. - Validation: Checks that configurations meet expected types and values.
- Initialization: Registers configurations in the service container for global access.
- Fallback: Uses safe default values when specific configurations are not provided.
Main bootstrapping file
Section titled “Main bootstrapping file”Bootstrapping is performed in the bootstrap/app.py file, which acts as the central initialization point for the application:
from orionis.foundation.application.application import Applicationfrom orionis.foundation.contracts.application.application import IApplication
# Import custom configuration classesfrom config.app import BootstrapAppfrom config.auth import BootstrapAuthfrom config.cache import BootstrapCachefrom config.cors import BootstrapCorsfrom config.database import BootstrapDatabasefrom config.filesystems import BootstrapFilesystemsfrom config.logging import BootstrapLoggingfrom config.mail import BootstrapMailfrom config.paths import BootstrapPathsfrom config.queue import BootstrapQueuefrom config.session import BootstrapSessionfrom config.testing import BootstrapTesting
# Initialize an application instanceapp: IApplication = Application()
# Register all custom configurationsapp.withConfigurators( app=BootstrapApp, auth=BootstrapAuth, cache=BootstrapCache, cors=BootstrapCors, database=BootstrapDatabase, filesystems=BootstrapFilesystems, logging=BootstrapLogging, mail=BootstrapMail, paths=BootstrapPaths, queue=BootstrapQueue, session=BootstrapSession, testing=BootstrapTesting)
# Start the application with all configurations loadedapp.create()Default configurations and fallback
Section titled “Default configurations and fallback”One of the core principles of Orionis Framework is to provide a “works out of the box” experience. For this reason:
- Safe defaults: Each configuration includes secure default values for development.
- Automatic fallback: If a configuration file does not exist, default values are used.
- Minimal setup: You can run an application without creating custom configuration files.
- Automatic validation: The framework automatically validates types and value ranges.
Benefits of the bootstrapping system
Section titled “Benefits of the bootstrapping system”Consistency and predictability
Section titled “Consistency and predictability”- All applications follow the same initialization pattern.
- Developers always know where to find and modify configurations.
- Behavior is predictable regardless of the execution environment.
Flexibility without complexity
Section titled “Flexibility without complexity”- You can override only the configurations you need to change.
- Unused configurations do not affect application performance.
- Easy migration between environments using environment variables.
Early error detection
Section titled “Early error detection”- Configuration errors are detected during startup, not at runtime.
- Clear error messages indicate exactly which configuration has issues.
- Type validation prevents silent errors that are hard to debug.
Modifying the bootstrapping process
Section titled “Modifying the bootstrapping process”In most cases, you do not need to modify the bootstrap/app.py file. However, you can customize it in specific situations:
Use cases for modification:
Section titled “Use cases for modification:”- Applications that do not follow the framework’s standard structure.
- Need for additional configurations not provided by default.
- Integration with external configuration systems.
- Applications requiring special service initialization.
Example of custom bootstrapping:
Section titled “Example of custom bootstrapping:”# Custom bootstrap/app.pyfrom orionis.foundation.application.application import Applicationfrom mi_configuracion_personalizada import MiConfigApp
app: IApplication = Application()
# Register only the configurations you needapp.withConfigurators( app=MiConfigApp, # Omit configurations not needed for your application)
# Initialize the applicationapp.create()Configuration Alternatives
Section titled “Configuration Alternatives”Development with Standard Skeleton (Recommended)
Section titled “Development with Standard Skeleton (Recommended)”The recommended way to work with Orionis Framework is by using the standard directory and file structure. This approach offers:
Advantages:
Section titled “Advantages:”- Convention over configuration: Fewer decisions to make, more time to develop.
- Comprehensive documentation: Everything is documented and exemplified.
- Compatibility: Works perfectly with all framework tools.
- Maintainability: Easy for other developers to understand and maintain.
Standard structure:
Section titled “Standard structure:”my_project/├── app/ # Application logic├── bootstrap/ # Initialization├── config/ # Custom configurations├── database/ # Database and migrations├── resources/ # Resources (views, languages)├── routes/ # Route definitions├── storage/ # Storage (logs, cache)├── tests/ # Automated testsDevelopment Outside the Standard Skeleton
Section titled “Development Outside the Standard Skeleton”For special cases where the standard structure does not fit your needs, you can create a fully customized implementation:
When to consider this option:
Section titled “When to consider this option:”- Migrating existing applications with a different structure.
- Integrating with enterprise systems with specific standards.
- Embedded applications with file structure restrictions.
- Projects requiring multiple applications in a single repository.
Custom implementation:
Section titled “Custom implementation:”from dataclasses import dataclassfrom orionis.foundation.config.app.entities.app import Appfrom orionis.foundation.config.app.enums.environments import Environments
@dataclassclass MyCustomConfig(App): name: str = 'My Enterprise Application' env: str = Environments.PRODUCTION debug: bool = False host: str = '0.0.0.0' # Accessible from any IP port: int = 8080 # Standard enterprise port # Other custom configurations...
# Company-specific settings company_code: str = 'ACME001' integration_enabled: bool = Truefrom orionis.foundation.application.application import Applicationfrom orionis.foundation.contracts.application.application import IApplicationfrom my_config.app_config import MyCustomConfig
# Initialize an application instanceapp: IApplication = Application()
# Register only the configurations you needapp.withConfigurators( app=MyCustomConfig, # Omit or add other configurations as needed)
# Initialize the applicationapp.create()Orionis Framework is flexible enough for developers to define any custom structure, as long as the necessary configurations are registered during bootstrapping.
If you do not wish to create custom configuration classes, you can register configurations using the application’s own methods.
Example:
from orionis.foundation.application.application import Applicationfrom orionis.foundation.contracts.application.application import IApplication
# Initialize an application instanceapp: IApplication = Application()
# Use methods to configure the application directly.app.setConfigApp()( name='My Application', env='production', debug=False)
# Other methods to configure each aspect individually.# app.setConfigAuth(...)# app.setConfigCache(...)# app.setConfigCors(...)# app.setConfigDatabase(...)# app.setConfigFilesystems(...)# app.setConfigLogging(...)# app.setConfigMail(...)# app.setConfigQueue(...)# app.setConfigSession(...)# app.setConfigTesting(...)# app.setConfigPaths(...)# app.setConfig(...)
# Initialize the applicationapp.create()Recommendations by Project Type
Section titled “Recommendations by Project Type”For New Applications:
Section titled “For New Applications:”- ✅ Use the standard skeleton – It’s the fastest and most maintainable option.
- ✅ Follow conventions – Makes collaboration and maintenance easier.
- ✅ Customize only what’s necessary – Override specific configurations without changing the structure.
For Migrating Existing Applications:
Section titled “For Migrating Existing Applications:”- ⚖️ Assess complexity – Compare the cost of adapting vs. keeping your current structure.
- 🔄 Gradual migration – Consider adopting parts of the standard skeleton progressively.
- 📚 Document deviations – If you use a custom structure, document it clearly.
For Enterprise Applications:
Section titled “For Enterprise Applications:”- 🏢 Consider corporate standards – Some companies require specific directory structures.
- 🔒 Security and compliance – Ensure your structure meets security requirements.
- 🔧 CI/CD tools – Make sure your structure is compatible with existing pipelines.
Key Considerations
Section titled “Key Considerations”- Maintenance: Custom structures require more documentation and ongoing maintenance.
- Updates: The standard skeleton receives automatic improvements with each framework release.
- Community: It’s easier to get help when using the standard structure.
- Tools: CLI commands and generators are optimized for the standard skeleton.
In summary, while Orionis Framework offers the flexibility to work with fully customized structures, the general recommendation is to use the standard skeleton and customize it through specific configurations according to your project’s needs.
Accessing Configurations from Your Application
Section titled “Accessing Configurations from Your Application”Once the application has been initialized through the bootstrapping process, all configurations defined in the configuration files are globally available via the service container. Orionis Framework provides multiple ways to access these configurations efficiently and securely.
How to Access Configurations
Section titled “How to Access Configurations”The recommended way to access configurations is through the Application facade, which provides a clean and expressive interface:
from orionis.support.facades.application import Application
# Access basic configurationsapp_name = Application.config('app.name')environment = Application.config('app.env')debug_enabled = Application.config('app.debug')
# Access nested configurationssmtp_host = Application.config('mail.mailers.smtp.host')smtp_port = Application.config('mail.mailers.smtp.port')Changing Configurations at Runtime
Section titled “Changing Configurations at Runtime”The Application facade also allows you to modify configurations at runtime if needed. Simply provide the configuration key and the new value:
from orionis.support.facades.application import Application
# Change configuration at runtimeApplication.config('app.debug', True)This way, you can dynamically adjust the application’s behavior according to environment needs or specific conditions.
Restoring Configurations to Default Values
Section titled “Restoring Configurations to Default Values”If needed, you can restore configurations to their default values as defined in the original configuration files:
from orionis.support.facades.application import Application
# Restore configuration to default valueApplication.resetConfig()A simple yet extremely useful way to maintain flexibility in configuration management throughout the application lifecycle.
Common Usage Patterns
Section titled “Common Usage Patterns”Practical examples of how to use configurations in different parts of your application:
Configuration in Controllers
Section titled “Configuration in Controllers”from orionis.support.facades.application import Applicationfrom orionis.http.controller import Controller
class HomeController(Controller):
def index(self): # Retrieve configurations for the view app_name = Application.config('app.name') env = Application.config('app.env') debug = Application.config('app.debug')
return self.view('home', { 'app_name': app_name, 'environment': env, 'debug_mode': debug })Configuration in Services
Section titled “Configuration in Services”from orionis.support.facades.application import Application
class EmailService:
def __init__(self): # Configure the service based on settings self.mailer = Application.config('mail.default', 'smtp') self.from_address = Application.config('mail.from.address') self.from_name = Application.config('mail.from.name')
def send_email(self, to, subject, content): # Sending logic using configurations if self.mailer == 'file': # Development mode - save to file file_path = Application.config('mail.mailers.file.path') # ... logic to save file else: # Production mode - send via SMTP smtp_config = Application.config('mail.mailers.smtp') # ... SMTP sending logicPerformance Considerations
Section titled “Performance Considerations”- Configurations are loaded only once during bootstrapping, so subsequent access is extremely fast.
- Feel free to use
Application.config()liberally – there is no significant performance penalty.
The configuration system in Orionis Framework is designed to be both powerful and easy to use, providing flexible access to all settings while maintaining type safety and sensible defaults.