Skip to main content

A Python library for the Typed Configuration language

Project description

Tyco Python

PyPI version Python Version License: MIT

A Python library for parsing and working with Tyco configuration files - a modern, type-safe configuration language designed for clarity and flexibility.

๐Ÿš€ Quick Start

Installation

pip install tyco

Basic Usage

environment = globals.environment debug = globals.debug timeout = globals.timeout databases = objects['Database'] # List of Database instances servers = objects['Server'] # List of Server instances db_host = primary_db.host db_port = primary_db.port

import tyco

# Load the bundled example.tyco file (included in the package)
with tyco.open_example_file() as f:
  context = tyco.load(f)
  # The path to the example file will be printed automatically

# Access global configuration values
globals = context.get_globals()
environment = globals.environment
debug = globals.debug
timeout = globals.timeout

# Get all instances as dictionaries
objects = context.get_objects()
databases = objects['Database']  # List of Database instances
servers = objects['Server']      # List of Server instances

# Access individual instance fields
primary_db = databases[0]
db_host = primary_db.host
db_port = primary_db.port

# Export to JSON
json_data = context.to_json()

Example Tyco File

The package includes a ready-to-use example Tyco file at:

tyco/example.tyco

(View on GitHub)

You can inspect this file after installation, or load it directly as shown above.

# Global configuration with type annotations
str environment: production
bool debug: false
int timeout: 30

# Database configuration struct
Database:
 *str name:           # Primary key field (*)
  str host:
  int port:
  str connection_string:
  # Instances
  - primary, localhost,    5432, "postgresql://localhost:5432/myapp"
  - replica, replica-host, 5432, "postgresql://replica-host:5432/myapp"

# Server configuration struct  
Server:
 *str name:           # Primary key for referencing
  int port:
  str host:
  ?str description:   # Nullable field (?) - can be null
  # Server instances
  - web1,    8080, web1.example.com,    description: "Primary web server"
  - api1,    3000, api1.example.com,    description: null
  - worker1, 9000, worker1.example.com, description: "Worker number 1"

# Feature flags array
str[] features: [auth, analytics, caching]

โœจ Features

๐ŸŽฏ Type Safety

  • Strong Type Annotations: str, int, float, bool, date, time, datetime
  • Array Types: int[], str[], etc. for typed arrays
  • Nullable Types: ?str, ?int for fields that can be null
  • Runtime Validation: Type safety enforced during parsing

๐Ÿ—๏ธ Structured Configuration

  • Struct Definitions: Define reusable configuration structures
  • Primary Key Fields: * marks fields used for instance references
  • Nullable Fields: ? allows fields to have null values
  • Multiple Instances: Create multiple instances of the same struct
  • Cross-References: Reference instances by their primary key values

๐Ÿ”ง Template System

  • Variable Substitution: Use {variable} syntax for dynamic values
  • Nested References: {struct.field} for complex relationships
  • Global Access: {global.variable} for explicit global scope
  • Template Expansion: Automatic resolution during parsing

๐ŸŒ Cross-Platform

  • Pure Python: No external dependencies
  • Python 3.8+: Modern Python support
  • All Operating Systems: Linux, macOS, Windows

๐Ÿ“– Language Features

Type Annotations

# Basic types
str app_name: MyApplication
int port: 8080
float timeout: 30.5
bool enabled: true

# Date and time types
date launch_date: 2025-01-01
time start_time: 09:00:00
datetime created_at: 2025-01-01 09:00:00Z

# Array types
str[] environments: [dev, staging, prod]
int[] ports: [80, 443, 8080]

# Nullable types (can be null)
?str description: null
?int backup_port: 8081
?str[] optional_tags: [tag1, tag2]

Struct Definitions

# Define a struct with primary key (*) and nullable (?) fields
User:
 *str username:        # Primary key field - used for references
  str email:           # Required field
 ?str full_name:       # Nullable field - can be null
 ?int age:             # Nullable with explicit value
  bool active: true    # Required field with default value
  # Create instances
  - admin, admin@example.com, "Administrator", 35, true
  - user1, user1@example.com, "John Doe", 28, true
  - guest, guest@example.com, null, null, false  # nulls for nullable fields

# Reference other struct instances using primary keys
Project:
 *str name:
  User owner:          # Reference to User struct by username
  str[] tags:
  - webapp, User(admin), [frontend, react]    # References user "admin"
  - api, User(user1), [backend, python, fastapi]

Primary Keys and References

# Structs with primary keys can be referenced
Host:
 *str name:           # Single primary key
  int cores:
  bool enabled:
  - web1, 4, true
  - db1, 8, false

Service:
 *str name:
 *str environment:    # Multiple primary keys
  Host host:
  int port:
  - auth, production, Host(web1), 8001
  - auth, staging, Host(db1), 8002

# Reference by primary key values
Deployment:
 *str name:
  Service service:
  - prod_auth, Service(auth, production)  # References by both primary keys

Template Variables

# Global variables for reuse
str environment: production
str region: us-east-1
str domain: example.com

# Template expansion in values
str api_url: https://api-{environment}-{region}.{domain}
str log_path: /var/log/{environment}

# Templates in struct instances with field access
Service:
 *str name:
  str url:
  str log_file:
  - auth, https://{name}-{environment}.{domain}, /logs/{environment}/{name}.log
  - users, https://{name}-{environment}.{domain}, /logs/{environment}/{name}.log

# Global scope access in templates
Config:
 *str key:
  str value:
  str message:
  - region_key, {region}, "Region is {global.region}"
  - env_key, {environment}, "Environment: {global.environment}"

Nullable Values and Arrays

# Nullable global values
?str optional_config: null
?str present_config: "I have a value"

# Nullable arrays
?int[] optional_numbers: null
?str[] tags: [tag1, tag2, tag3]

# Struct with nullable fields
Resource:
 *str id:
  str name:
 ?str description:     # Can be null
 ?str[] labels:        # Nullable array
 ?int priority:        # Nullable number
  # Instances with null values
  - res1, "Resource One", "A description", [prod, web], 10
  - res2, "Resource Two", null, null, null  # All nullable fields are null
  - res3, "Resource Three", null, [test], 5

๐Ÿ”ง API Reference

Core Functions

tyco.load(filepath)

Load and parse a Tyco configuration file.

config = tyco.load('app.tyco')

Parameters:

  • filepath (str | Path): Path to the Tyco configuration file

Returns: TycoContext object with attribute access

tyco.loads(content)

Parse Tyco configuration from a string.

config_text = """
str app_name: MyApp
int port: 8080
"""
config = tyco.loads(config_text)

Parameters:

  • content (str): Tyco configuration content as string

Returns: TycoContext object

Configuration Access

config = tyco.load('config.tyco')

# Access global variables
app_name = config.app_name
port = config.port

# Access struct instances (returns list)
servers = config.Server  # All Server instances
first_server = config.Server[0]  # First server
server_names = [s.name for s in config.Server]  # Extract names

# Access specific fields
db_host = config.Database[0].host
api_url = config.Service[0].url  # Template expanded

# Handle nullable fields
description = config.Server[0].description  # May be None
if description is not None:
    print(f"Server description: {description}")

Working with References

# Define structs with primary keys
User:
 *str username:
  str email:
  - alice, alice@example.com
  - bob, bob@example.com

Project:
 *str name:
  User owner:
  - webapp, User(alice)  # Reference alice by username
  - api, User(bob)       # Reference bob by username
# Access referenced objects
config = tyco.load('config.tyco')

# Get the project and its owner
webapp = config.Project[0]  # First project
owner = webapp.owner        # This is the actual User instance
print(f"Project {webapp.name} owned by {owner.username} ({owner.email})")

๐Ÿงช Testing

The library includes comprehensive tests covering all language features:

# Run tests
python -m pytest

# Run with coverage
python -m pytest --cov=tyco --cov-report=html

Test Coverage

  • โœ… Type System: All basic types, arrays, nullable types
  • โœ… Structs: Primary keys, nullable fields, instances, defaults
  • โœ… References: Primary key lookup and cross-references
  • โœ… Templates: Variable substitution and nested references
  • โœ… Edge Cases: Complex nesting, special characters, error handling

๐Ÿ“ Project Structure

tyco-python/
โ”œโ”€โ”€ tyco/
โ”‚   โ”œโ”€โ”€ __init__.py          # Main API exports
โ”‚   โ”œโ”€โ”€ parser.py            # Core parsing logic and classes
โ”‚   โ””โ”€โ”€ tests/
โ”‚       โ”œโ”€โ”€ __init__.py
โ”‚       โ”œโ”€โ”€ test_parser.py   # Parser functionality tests
โ”‚       โ”œโ”€โ”€ test_load_features.py  # Load feature tests
โ”‚       โ”œโ”€โ”€ inputs/          # Test Tyco files
โ”‚       โ””โ”€โ”€ expected/        # Expected JSON outputs
โ”œโ”€โ”€ pyproject.toml           # Project configuration
โ”œโ”€โ”€ README.md               # This file
โ””โ”€โ”€ LICENSE                 # MIT License

๐ŸŒŸ Examples

Web Application Configuration

# app.tyco
str environment: production
bool debug: false
str secret_key: your-secret-key-here

# Database configuration with primary key
Database:
 *str name:               # Primary key for referencing
  str host:
  int port:
  str user:
 ?str password:           # Nullable - can be null for security
  str connection_string:
  - main, db.example.com, 5432, webapp_user, null, postgresql://{user}@{host}:{port}/{name}
  - cache, cache.example.com, 6379, cache_user, "secret123", redis://{host}:{port}

# Application servers  
Server:
 *str name:               # Primary key
  str host:
  int port:
  int workers:
 ?str description:        # Nullable description
  Database database:      # Reference to Database by name
  - web, 0.0.0.0, 8080, 4, "Main web server", Database(main)
  - api, 0.0.0.0, 8081, 2, null, Database(main)  # null description
  - worker, 127.0.0.1, 8082, 1, "Background worker", Database(cache)

# Feature flags (non-nullable array)
str[] enabled_features: [authentication, caching, analytics]

# Optional configuration (nullable)
?str[] optional_modules: [reporting, monitoring]
?int max_connections: null
# app.py
import tyco

config = tyco.load('app.tyco')

# Use configuration
print(f"Environment: {config.environment}")
print(f"Debug mode: {config.debug}")

# Server configuration with references
for server in config.Server:
    db = server.database  # This is the actual Database instance
    desc = server.description or "No description"
    print(f"Server {server.name}: {server.host}:{server.port}")
    print(f"  Description: {desc}")
    print(f"  Database: {db.name} at {db.host}:{db.port}")
    
    # Handle nullable database password
    if db.password is not None:
        print(f"  Database has password configured")
    else:
        print(f"  Database password is null (using other auth)")

# Handle nullable configuration
if config.optional_modules is not None:
    print(f"Optional modules: {', '.join(config.optional_modules)}")
else:
    print("No optional modules configured")

Microservices with Multi-Key References

# services.tyco
str environment: staging
str base_domain: internal.company.com
int default_timeout: 30

# Services with compound primary key
Service:
 *str name:
 *str region:           # Multiple primary keys
  str host:
  int port:
  int timeout:
 ?str health_endpoint:  # Nullable health check
  - auth, us-east, auth-east.{base_domain}, 8001, {default_timeout}, /health
  - auth, us-west, auth-west.{base_domain}, 8001, {default_timeout}, /health
  - users, us-east, users-east.{base_domain}, 8002, {default_timeout}, null
  - payments, us-east, payments-east.{base_domain}, 8003, 60, /status

# Load balancer referencing services by compound keys
LoadBalancer:
 *str name:
  Service[] upstream_services:  # Array of service references
  str algorithm:
 ?int max_connections:          # Nullable configuration
  - east_lb, [
      Service(auth, us-east),
      Service(users, us-east),
      Service(payments, us-east)
    ], round_robin, 1000
  - west_lb, [Service(auth, us-west)], round_robin, null

# Monitoring with nullable fields
Monitor:
 *str service_name:
  Service service:
 ?str custom_endpoint:          # Override default health endpoint
  int check_interval:
  - auth_east_monitor, Service(auth, us-east), null, 30
  - users_east_monitor, Service(users, us-east), /api/status, 30

๐Ÿค Contributing

We welcome contributions! The parser implementation follows these principles:

  1. Type Safety: Strong type checking and validation
  2. Clarity: Clean, readable configuration syntax
  3. Flexibility: Support for complex referencing and nullable fields
  4. Performance: Efficient parsing for large configuration files
  5. Reliability: Comprehensive test coverage for all features

Development Setup

# Clone the repository
git clone https://github.com/typedconfig/tyco-python.git
cd tyco-python

# Install development dependencies
pip install -e .
pip install pytest pytest-cov

# Run tests
python -m pytest

๏ฟฝ๏ฟฝ Requirements

  • Python: 3.8 or higher
  • Dependencies: None (pure Python implementation)
  • Operating Systems: Linux, macOS, Windows

๏ฟฝ๏ฟฝ Related Projects

๐Ÿ“„ License

MIT License - see the LICENSE file for details.

๐ŸŒ Learn More

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

tyco-0.2.3.tar.gz (29.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tyco-0.2.3-py3-none-any.whl (26.3 kB view details)

Uploaded Python 3

File details

Details for the file tyco-0.2.3.tar.gz.

File metadata

  • Download URL: tyco-0.2.3.tar.gz
  • Upload date:
  • Size: 29.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for tyco-0.2.3.tar.gz
Algorithm Hash digest
SHA256 db39d36f043bda83de2ac116a5dc5f914cc6e7c8288ac575dc766ce9ed8d9b82
MD5 601dbffb754c76e5c93275a86da49119
BLAKE2b-256 43d832a6126a2032f646d1e9c4f59192177ef7cdc124573040fd796a0b42b8f6

See more details on using hashes here.

File details

Details for the file tyco-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: tyco-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 26.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for tyco-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 157958c8bc01604ff9b3e0fe7b2976bfe4389f0a0689bb132da71eb1d8c88edb
MD5 17c3caa2801b71aaa2b3acde583c5cbb
BLAKE2b-256 1683700f8b6bb74bb309949066cbcbe16a70df4bdb7901d07d73995da132447f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page