Metadata-Version: 2.4
Name: pyarxlab
Version: 0.2.4
Summary: A modern Python-based IDL and compiler for generating AUTOSAR ARXML
Author: Anton Autushka
License: MIT
Project-URL: Homepage, https://github.com/pyarxlab/pyarx
Project-URL: Repository, https://github.com/pyarxlab/pyarx.git
Project-URL: Bug Tracker, https://github.com/pyarxlab/pyarx/issues
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Topic :: Software Development :: Code Generators
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=7.0.0; extra == "dev"
Requires-Dist: black>=22.0.0; extra == "dev"
Requires-Dist: isort>=5.10.0; extra == "dev"
Requires-Dist: mypy>=1.0.0; extra == "dev"
Dynamic: license-file

# pyarx

`pyarx` is a modern, declarative, Python-based IDL (Interface Definition Language) and compiler designed to translate software architectures, interfaces, and data types into standardized, fully-conforming Adaptive AUTOSAR ARXML and JSON Schema representations.

Instead of writing thousands of lines of verbose, low-level XML or using highly boilerplate metamodel scripts, you can specify your entire system in clean, readable Python and compile it instantly.

---

## Elegant Declarative API

`pyarx` uses native Python 3 subclassing and type annotations to declare structured types, enumerations, service interfaces, events, and methods.

```python
from typing import Optional, Annotated
import enum
import dataclasses
from pyarx import (
    Struct,
    Enum,
    ServiceInterface,
    UInt16,
    Float32,
    Array,
    Vector,
    event,
    field,
    raises,
    namespace,
)

# 1. Standard Python Enums are supported natively
class SystemStatus(enum.Enum):
    OK = 0
    DEGRADED = 1
    CRITICAL = 2

# 2. Modern struct type declaration with limits and defaults
class GpsLocation(Struct):
    latitude: Annotated[Float32, "min=-90.0", "max=90.0", "unit=deg"]
    longitude: Annotated[Float32, "min=-180.0", "max=180.0", "unit=deg"]
    altitude: Float32 = 0.0

# 3. Standard dataclasses are automatically mapped to Structs
@dataclasses.dataclass
class CabinClimate:
    target_temp: float = 22.0
    fan_speed: int = 3
    air_quality: Optional[Annotated[int, "min=0", "max=500"]] = None

# 4. Service Interfaces with Events, Fields, and Methods
@namespace("car.comfort", cpp="car::comfort::service")
class CabinService(ServiceInterface):
    
    # Publish-Subscribe Event payload
    @event
    def on_climate_changed(self) -> CabinClimate:
        pass

    # Constrained field with notifications
    @field(min=0, max=100, unit="%", has_notifier=True)
    def ambient_brightness(self) -> UInt16:
        pass

    # Method showcasing arrays/vectors and standard types
    def SetRecentRoutes(self, routes: Vector[GpsLocation, 10]) -> bool:
        pass
```

---

## Key Features

*   **Standard Python Type Support**: Declare your IDL fields and structures directly with standard library `@dataclass`, `NamedTuple`, and `enum.Enum` classes. Under the hood, `pyarx` automatically wraps them as AUTOSAR compliant structs and enums.
*   **Flexible Arrays & Bounded/Unbounded Vectors**: Multiple syntax choices are supported out of the box:
    *   **Fixed-Size Arrays**: `Array[T, size]`, `Array(T, size=N)`
    *   **Bounded Vectors**: `Vector[T, max_size]`, `Vector(T, max_size=M)`
    *   **Unbounded Vectors**: `Vector[T]`, `list[T]`, `List[T]`, or compact literal `[T]`
*   **Optional Types**: Use `Optional[T]` or PEP 604 `T | None`. These are parsed and serialized as `<IS-OPTIONAL>true</IS-OPTIONAL>` in ARXML (Adaptive SOME/IP TLV compliant) and `"is_optional": true` in JSON.
*   **Annotated Constraints**: Unpack PEP 593 `typing.Annotated[BaseType, "min=X", "max=Y", "unit=Z", "default=W"]` directly.
*   **C++ Namespacing**: Support for specifying namespaces inside models using `_namespace_` / `_cpp_namespace_` attributes, or with decorators `@namespace("car.adas", cpp="car::adas")` and `@cpp_namespace("...")`.
*   **Conforming Multi-Format Emitters**:
    *   **ARXML**: Generates standard-compliant AUTOSAR Adaptive system descriptions.
    *   **JSON Schema**: Generates clean, structured JSON schemas.

---

## Project Structure

*   `src/pyarx/`:
    *   `types.py`: AUTOSAR primitives, dynamic standard-type converters, and `resolve_type`.
    *   `interfaces.py`: Service Interface decoration logic, events, fields, methods, and application errors.
    *   `emitters.py`: Translation layers for ARXML and JSON.
    *   `compiler.py`: Recursive compilation driver.
    *   `cli.py`: Entrypoint for command-line compilations.
*   `examples/`: Full recursive showcase models (e.g. `examples/car/`) and compile script.
*   `tests/`: Comprehensive unit tests confirming parser features, validation, and emitter schemas.

---

## Quick Installation

You can install `pyarx` directly from GitHub using `pip`:

```bash
pip install git+https://github.com/pyarxlab/pyarx.git
```

---

## Development & Usage

### Setup Environment

```bash
# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate

# Install package in editable mode with development dependencies
pip install -e ".[dev]"
```

### Running Tests

```bash
pytest
```

### Compiling Models

You can compile a directory package (recursively scanning all Python submodules) or a single `.py` file into ARXML or JSON using either the Python API or the Command Line Interface.

#### Via CLI:

```bash
# Compile package recursively to ARXML (defaults to saving as car.arxml in CWD)
pyarx arxml ./examples/car

# Compile a single Python IDL file to ARXML (defaults to saving as powertrain.arxml in CWD)
pyarx arxml ./examples/car/powertrain.py

# Compile package recursively to JSON (defaults to saving as car.json in CWD)
pyarx json ./examples/car

# Specify an explicit output path
pyarx arxml ./examples/car/powertrain.py -o ./powertrain_system.arxml
```

#### Via Python API:

```python
from pyarx import compile_package

# Recursively crawl and compile a package directory to ARXML
arxml_content = compile_package("examples/car", format="arxml")

with open("car_system.arxml", "w") as f:
    f.write(arxml_content)
```

## Disclaimer

This project is provided “as is” without warranty of any kind.

## Support

This is an independent project maintained in my personal time.  
Support is best-effort only.
