Skip to main content

10x Platform Core

Project description

py10x-core

Jerboa Logo

Early preview release – USE AT YOUR OWN RISK. NO WARRANTIES.

10x Platform Core

The purpose of this package is to make 10x engineers even more productive.

Architecture & Licensing

Project Structure

The 10x platform is developed and maintained by 10X CONCEPTS LLC and follows a layered architecture:

10x Software Platform
    ├── 10x Platform Core (Python) - open source and governed by the MIT License
    └── Native extensions (C++) - binary distributions governed by proprietary licenses (see below))

10x Platform Core

This package implements the trait system, object modeling framework, dependency graph, UI abstractions, and infrastructure integrations. It is released under the MIT License and includes the following packages:

  • py10x-core
    • core_10x: Core data modeling with traits, traitables, and serialization
    • ui_10x: Cross-platform UI components focused on traitable editing and management
    • infra_10x: Infrastructure components including MongoDB storage integration

You are free to:

  • Use the code
  • Study it
  • Modify it
  • Fork it
  • Build on top of it

All Python source in this repository is fully open and governed by the MIT License.

Native C++ Components

Some performance-critical functionality is implemented in C++ and exposed to Python via pybind11.

  • Distributed as compiled binaries
  • Not included in this repository
  • Governed by a separate proprietary license
  • Required for full functionality of the framework
  • You are free to use and distribute them subject to the license terms (see below)

This separation allows the Python framework to remain transparent and extensible while delivering performance where it matters.

Licensing Summary

  • All Python source code in this repository is licensed under the MIT License.
  • Native C++ binary components are proprietary and installed as package dependencies - py10x-kernel and py10x-infra
  • Use of proprietary components is subject to their respective license terms
  • By installing py10x-core, you agree to the terms of the proprietary licenses for py10x-kernel and py10x-infra.

Installation

For detailed installation instructions including all prerequisites and platform-specific setup, see INSTALLATION.md.

Quick Prerequisites

  • Python 3.12 (recommended), 3.11+ supported
  • UV - Python installer and package manager
  • MongoDB (for running tests and examples)
    • A passwordless MongoDB instance (localhost would be the easiest) required for running some tests and examples

Install with UV (Recommended)

# Clone the repository
git clone https://github.com/10x-software/py10x.git
cd py10x

# Install everything (recommended for development)
uv sync --all-extras

# Or install specific combinations
uv sync --extra dev --extra rio  # Development + Rio UI
uv sync --extra dev --extra qt   # Development + Qt6 UI
uv sync --extra rio              # Rio UI only
uv sync --extra qt              # Qt6 UI only

Install with pip

git clone https://github.com/10x-software/py10x.git
cd py10x
pip install -e .

# With optional dependencies
pip install -e ".[rio]"  # Rio UI backend
pip install -e ".[qt]"   # Qt6 UI backend
pip install -e ".[dev]"  # Development tools

Quick Start

For a comprehensive introduction to py10x-core, see our Getting Started Guide.

Core Data Modeling with Object Identification

from core_10x.traitable import Traitable, T, RT, RC, RC_TRUE
from core_10x.exec_control import CACHE_ONLY
from datetime import date, datetime

# Endogenous Traitable object example
class Person(Traitable):
    # ID traits - contribute to the object ID. Objects with same ID share values globally
    first_name: str = T(T.ID)
    last_name: str  = T(T.ID)
    
    # Regular traits (T() is required for persistence)
    dob: date           = T()
    weight_lbs: float   = T()
    
    # Runtime traits (not stored, computed on-demand)
    age: int            = RT()  # RT() is optional for runtime traits
    full_name: str              # RT() omitted - still a runtime trait

    def age_get(self) -> int:
        """age getter method - computes age from date of birth."""
        if not self.dob:
            return 0
        today = date.today()
        return today.year - self.dob.year

    def full_name_get(self) -> str:
        """full_name getter method - combines first and last name."""
        return f"{self.first_name} {self.last_name}"
    
    def age_set(self, trait, value: int) -> RC:
        """age setter method - validates age and updates date of birth."""
        if value < 0:
            return RC(False, "Age cannot be negative")
        if value > 150:
            return RC(False, "Age cannot exceed 150")
        
        # Calculate year of birth from age
        today = date.today()
        birth_year = today.year - value
        dob = self.dob
        self.dob = date(birth_year, dob.month, dob.day)
        return RC_TRUE

    def first_name_verify(self, t, value: str) -> RC:
        """Verifier: run on entity.verify() or entity.save(); not on set."""
        if value and value.isalpha():
            return RC_TRUE
        return RC(False, f"{t.name} may have letters only")

    def last_name_verify(self, t, value: str) -> RC:
        """Verifier: run on entity.verify() or entity.save(); not on set."""
        if value and value.isalpha():
            return RC_TRUE
        return RC(False, f"{t.name} may have letters only")
    # See [Verifiers](GETTING_STARTED.md#verifiers-validation-on-verify-and-save) for when verifiers run.

# Exogeneous Traitable object example
class DataCaptureEvent(Traitable):
    capture_time: datetime  = T()
    raw_data: str           = T()
    processed_data: str     # Runtime trait - RT() omitted (still not stored)
    
    def processed_data_get(self) -> str:
        """Runtime computation - not stored in store."""
        return self.raw_data.upper().strip()

# Use CACHE_ONLY mode - no backing store required
with CACHE_ONLY():
    # Endogenous traitables (with ID traits) share trait values globally
    person1 = Person(first_name='Alice', last_name='Smith')
    person1.dob = date(1990, 5, 15)  # Set a non-ID trait
    print( '---',person1.dob)

    # Using setter method for age validation
    person1.age = 25  # Set age, updates date of birth
    print(f'Age: {person1.age}')  # 25
    print(f'Date of birth: {person1.dob}')  # Calculated from age
    
    # Test validation
    try:
        person1.age = -5  # This will fail validation
    except Exception as e:
        print(f"Validation error: {e}")

    person1.verify().throw()  # Runs verifiers (e.g. first_name_verify); save() also calls verify()

    person2 = Person(first_name='Alice', last_name='Smith')  # Same ID traits
    # person2 automatically has the same dob value as person1
    assert person2.dob == date(2001, 5, 15)  # Shared trait values
    assert person1 == person2  # Equal due to same ID traits
    # Note: person1 is person2 would be False - they're different objects

    # Exogenous traitables (no ID traits) get auto-generated UUID
    class DataCaptureEvent(Traitable):
        data: str
        timestamp: float

    # Endogenous vs Exogenous demonstration
    person = Person(first_name='Alice', last_name='Smith')  # Endogenous
    event = DataCaptureEvent(data='sensor_reading', timestamp=1234567890.0)  # Exogenous

    print(f'Person ID: {person.id()}')  # Based on ID traits (first_name, last_name)
    print(f'Event ID: {event.id()}')    # Auto-generated UUID

Dependency Graph and Execution Control

from core_10x.exec_control import GRAPH_ON, GRAPH_OFF, INTERACTIVE
from core_10x.traitable import Traitable, RT

class Calculator(Traitable):
    x: int = RT()
    y: int = RT()
    sum: int        = RT()  # Computed via sum_get()
    product: int    = RT()  # Computed via product_get()

    def sum_get(self) -> int:
        return self.x + self.y

    def product_get(self) -> int:
        return self.x * self.y

# Enable dependency graph for automatic computation
with GRAPH_ON():
    calc = Calculator(x=5, y=3)
    # sum and product computed automatically when accessed
    print(calc.sum)      # 8
    print(calc.product)  # 15
    
    calc.x = 10  # Automatically recomputes dependent traits
    print(calc.sum)      # 13

Using Storage

Storable Traitable objects are kept in instances of TsStore. Currently, MongoDB is the only supportable type of TsStore. Here's how to use a store explicitly.

from infra_10x.mongodb_store import MongoStore
from core_10x.code_samples.person import Person
from datetime import date

# Connect to MongoDB
traitable_store = MongoStore.instance(hostname='localhost', dbname='myapp') 

# Use traitable store context for persistence
with traitable_store:
    person = Person(first_name='Alice', last_name='Smith')
    person.dob = date(1990, 5, 15)
    
    person.save()  # Persists to traitable store backed by Mongo

Alternatively, you can use TsStore with specific URI.

from core_10x.ts_store import TsStore
from core_10x.code_samples.person import Person
from datetime import date

# Connect to a "passwordless" myapp store 
traitable_store = TsStore.instance_from_uri('mongodb://localhost/myapp') 

# Use traitable store context for persistence
with traitable_store:
    person = Person(first_name='Alice', last_name='Smith')
    person.dob = date(1990, 5, 15)
    
    person.save()  # Persists to traitable store myapp@localhost

Finally, you can specify a TsStore instance to use via an environment variable XX_MAIN_TS_STORE_URI. If it's defined, all storable traitable objects will be sought/saved there.

For more complex scenarios, there's a way to associate particular subclasses of Traitable to different instances of TsStore.

Core Features

Object Identification System

  • Endogenous Traitables: Traitables with ID computed from ID traits, traits shared by ID
  • Exogenous Traitables: Traitables without ID traits get auto-generated UUIDs, traits shared by ID
  • Anonymous Traitables: Traitables without ID - cannot be shared or persisted alone, can be embedded in other traitables
  • ID Method: traitable.id() returns ID based on ID traits (endogenous) or auto-generated UUID (exogenous)
  • Global Cache: Automatic sharing of trait values for traitables with the same ID

Traitable Framework

The Traitable base class provides:

  • Trait-based attributes: Define typed attributes with validation
  • ID Traits: Mark traits as identifiers for global sharing
  • Regular Traits: Used for data storage and searching
  • Runtime Traits: Not stored, computed on-demand (RT() is optional)
  • Caching: Built-in caching system for trait values and entity state
  • Serialization: Automatic serialization/deserialization
  • Versioning: Automatic revision tracking
  • Validation: Type checking and integrity validation

Dependency Graph System

  • Automatic Computation: Traits computed automatically when accessed
  • Dependency Tracking: Changes to traits trigger dependent trait updates
  • Execution Control: Fine-grained control over computation modes
  • Performance: Expensive computations cached and reused

Seamless UI Framework

Cross-platform UI with automatic framework selection:

  • Auto-Detection: Framework chosen based on installed packages
  • Environment Variables: Override framework selection
  • Unified API: Same code works with Rio or Qt6 backends
  • Traitable Integration: Built-in entity editors and viewers

Infrastructure

  • Storage Integration: MongoDB store with revision tracking and flexible data persistence
  • Resource Management: Manual resource management using context managers (enterprise resource management planned for future release)

Development

Running Tests

Note: The infra_10x/unit_tests/ suite requires a local MongoDB instance running on the default port (27017).

# Run all unit tests (with coverage by default)
pytest

# Run specific test suites
pytest core_10x/unit_tests/
pytest ui_10x/unit_tests/
pytest infra_10x/unit_tests/  # Requires MongoDB

# Manual tests are debugging scripts (run directly)
python core_10x/manual_tests/trivial_graph_test.py
python ui_10x/rio/manual_tests/basic_test.py

Code Style

The project uses ruff for linting and formatting:

# Check style
ruff check .

# Fix issues
ruff check --fix .

# Format code
ruff format .

Building

# Build wheel
python -m build

# Build with UV
uv build

Architecture

Core Components

  • Nucleus: Base serialization and type system
  • Traitable: Object modeling with traits
  • Trait System: Type-safe attribute definitions
  • Storage Layer: Pluggable storage backends

UI Architecture

  • Platform Interface: Abstract UI component interface
  • Component Builder: Widget construction and layout
  • Backend Implementations: Rio and Qt6 specific implementations

Contributing

See CONTRIBUTING.md for development guidelines.

License

This project is licensed under the MIT License - see the LICENSE file for details. For copyright holders, proprietary components, and third-party attributions, see NOTICE.

Legal & Security

  • This project is developed and maintained by 10X CONCEPTS LLC. USE AT YOUR OWN RISK. NO WARRANTIES.
  • Dependencies have been audited for known vulnerabilities and license compatibility (see checklist in release notes).
  • For security issues or vulnerabilities, please report privately to security@10x-software.org (do not open public issues).
  • See SECURITY.md for full security policy, reporting guidelines, and known issues.

Contact

Getting Help

  • Check existing issues and discussions
  • Ask questions in GitHub Discussions
  • Join our community on Discord for discussion, support, and collaboration
  • Contact maintainers for complex issues

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

py10x_core-0.1.12.tar.gz (946.7 kB view details)

Uploaded Source

Built Distribution

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

py10x_core-0.1.12-py3-none-any.whl (311.9 kB view details)

Uploaded Python 3

File details

Details for the file py10x_core-0.1.12.tar.gz.

File metadata

  • Download URL: py10x_core-0.1.12.tar.gz
  • Upload date:
  • Size: 946.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for py10x_core-0.1.12.tar.gz
Algorithm Hash digest
SHA256 012ca71663079ad5db0c932171492c1a20283817e357744c9ff6c6868b5dc590
MD5 f35cea278d039c02858be37991b9448b
BLAKE2b-256 3ecce90227b61e6c3d26ef025ab897abb9b190e8b383a7766f2619352bee3bb6

See more details on using hashes here.

File details

Details for the file py10x_core-0.1.12-py3-none-any.whl.

File metadata

  • Download URL: py10x_core-0.1.12-py3-none-any.whl
  • Upload date:
  • Size: 311.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.2 {"installer":{"name":"uv","version":"0.10.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for py10x_core-0.1.12-py3-none-any.whl
Algorithm Hash digest
SHA256 2d4d546937864735d62927fa11b7c5d9ca2f3575894fb7d5ee01a7dff00d9aa9
MD5 a57f235f3c7ffa304b7986f5022c0fcf
BLAKE2b-256 99e962ae8b830a244b5a3d25ac1a4d3726c68d1343f851b4e4d5e1b5c2f2f0e3

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