Files
Beyhan Oğur d5f52cc3d3 first commit
2026-09-03 04:45:36 +03:00

17 KiB
Raw Permalink Blame History

Python Integration

**Referenced Files in This Document** - [ClassicAssist.Avalonia.csproj](file://ClassicAssist.Avalonia/ClassicAssist.Avalonia.csproj) - [Engine.cs](file://ClassicAssist.Avalonia/Engine.cs) - [Program.cs](file://ClassicAssist.Avalonia/Program.cs) - [AvaloniaUIInvoker.cs](file://ClassicAssist.Avalonia/AvaloniaUIInvoker.cs) - [AvaloniaDispatcher.cs](file://ClassicAssist.Avalonia/AvaloniaDispatcher.cs) - [PythonCompletionData.cs](file://ClassicAssist/Data/Macros/PythonCompletionData.cs) - [MacroManager.cs](file://ClassicAssist.Shared/Data/Macros/MacroManager.cs) - [MacroInvoker.cs](file://ClassicAssist.Shared/Data/Macros/MacroInvoker.cs) - [SystemMessageTextWriter.cs](file://ClassicAssist.Shared/Data/Macros/SystemMessageTextWriter.cs)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion
  10. Appendices

Introduction

This document explains how Python scripting is integrated into ClassicAssist.Avalonia using Python.NET (pythonnet). It covers the runtime initialization, execution environment setup, memory management across C# and Python contexts, the exposed API surface for macro scripts, IntelliSense and debugging support, practical automation patterns, performance considerations, and troubleshooting guidance.

Project Structure

The Python integration spans multiple projects:

  • ClassicAssist.Avalonia: Avalonia UI host that initializes the engine and exposes platform-specific invokers/dispatchers.
  • ClassicAssist.Shared: Shared logic including macro management and invocation infrastructure.
  • ClassicAssist: Legacy WPF project containing some Python-related assets and completion data used by the editor.

Key files related to Python integration:

  • Project configuration includes Python.NET dependencies.
  • Engine entry points initialize the Python runtime and expose APIs.
  • Macro manager and invoker orchestrate script execution.
  • Completion data supports IntelliSense for Python macros.
graph TB
subgraph "ClassicAssist.Avalonia"
A_Proj["ClassicAssist.Avalonia.csproj"]
A_Engine["Engine.cs"]
A_Program["Program.cs"]
A_UIInvoker["AvaloniaUIInvoker.cs"]
A_Dispatcher["AvaloniaDispatcher.cs"]
end
subgraph "ClassicAssist.Shared"
S_MacroMgr["MacroManager.cs"]
S_MacroInv["MacroInvoker.cs"]
S_SysWriter["SystemMessageTextWriter.cs"]
end
subgraph "ClassicAssist"
C_Completion["PythonCompletionData.cs"]
end
A_Proj --> A_Engine
A_Program --> A_Engine
A_Engine --> S_MacroMgr
S_MacroMgr --> S_MacroInv
S_MacroInv --> S_SysWriter
A_Engine --> A_UIInvoker
A_Engine --> A_Dispatcher
A_Engine -.-> C_Completion

Diagram sources

Section sources

Core Components

  • Python runtime initialization: The application bootstraps the Python runtime via Python.NET and configures import paths so that user macro scripts can import shared modules or third-party packages as needed.
  • Execution environment: The engine sets up a dedicated Python context per macro run, binds C# types and helpers, and provides a safe execution pipeline with logging and error capture.
  • Macro orchestration: MacroManager loads macro entries and delegates execution to MacroInvoker, which coordinates environment setup, script compilation/execution, and result handling.
  • UI thread bridging: AvaloniaUIInvoker and AvaloniaDispatcher ensure that any UI updates from Python-invoked C# code are marshaled onto the Avalonia UI thread safely.
  • IntelliSense and debugging: PythonCompletionData supplies completion metadata to the editor; debug support leverages standard Python.NET debugging facilities when available.

Section sources

Architecture Overview

The following diagram shows how Python.NET integrates with the Avalonia host and macro system.

sequenceDiagram
participant Host as "Program.cs"
participant Engine as "Engine.cs"
participant PyNET as "Python.NET Runtime"
participant MacroMgr as "MacroManager.cs"
participant Invoker as "MacroInvoker.cs"
participant Writer as "SystemMessageTextWriter.cs"
participant UIInv as "AvaloniaUIInvoker.cs"
participant Disp as "AvaloniaDispatcher.cs"
Host->>Engine : Initialize()
Engine->>PyNET : Initialize Python runtime
Engine->>Engine : Configure import paths and bindings
MacroMgr->>Invoker : Execute(macroEntry)
Invoker->>PyNET : Create execution context
Invoker->>PyNET : Load and execute macro script
PyNET-->>Invoker : Results / Exceptions
Invoker->>Writer : Write logs and messages
Invoker->>UIInv : Marshal UI updates
UIInv->>Disp : Invoke on Avalonia dispatcher
Disp-->>UIInv : UI update completed
Invoker-->>MacroMgr : Execution status

Diagram sources

Detailed Component Analysis

Python.NET Initialization and Environment Setup

  • Runtime bootstrap: The engine initializes the Python runtime once during application startup and ensures it remains alive for the process lifetime.
  • Import path configuration: Paths to user macro directories and shared libraries are added to sys.path so scripts can import modules without full paths.
  • Binding exposure: Selected C# classes and methods are exposed to Python through pythonnet’s automatic interop, enabling direct calls from macro scripts.
flowchart TD
Start(["Application Startup"]) --> InitPy["Initialize Python.NET Runtime"]
InitPy --> ConfigPaths["Configure sys.path and imports"]
ConfigPaths --> BindAPIs["Expose C# APIs to Python"]
BindAPIs --> Ready(["Execution Environment Ready"])

Diagram sources

Section sources

Macro Execution Pipeline

  • Loading: MacroManager enumerates and loads macro entries (including Python scripts).
  • Invocation: MacroInvoker prepares an isolated execution context, injects bindings, and runs the script.
  • Output: SystemMessageTextWriter captures output and logs for display in the UI.
  • Threading: Any UI interactions are marshaled via AvaloniaUIInvoker and AvaloniaDispatcher to avoid cross-thread exceptions.
sequenceDiagram
participant MM as "MacroManager.cs"
participant MI as "MacroInvoker.cs"
participant PY as "Python.NET"
participant SW as "SystemMessageTextWriter.cs"
participant UI as "AvaloniaUIInvoker.cs"
participant D as "AvaloniaDispatcher.cs"
MM->>MI : Execute(pythonScript)
MI->>PY : Create context and load script
MI->>SW : Redirect stdout/stderr
MI->>PY : Run script
PY-->>MI : Return results or raise exception
MI->>UI : Marshal UI updates if needed
UI->>D : Dispatch on UI thread
D-->>UI : Completed
MI-->>MM : Status and logs

Diagram sources

Section sources

Memory Management Between C# and Python

  • Reference semantics: Objects passed between C# and Python are wrapped by Python.NET. Long-lived references should be minimized to prevent GC pressure.
  • Disposal: When interacting with unmanaged resources (e.g., file handles), prefer explicit disposal patterns on the C# side and release references promptly in Python.
  • Cross-context lifetimes: Avoid holding strong references to Python objects in long-running C# caches; use weak references or periodic cleanup strategies where appropriate.
  • Thread affinity: Some C# objects may require access on specific threads; use the provided UI invoker/dispatcher to marshal calls safely.

[No sources needed since this section provides general guidance]

Python API Surface for Macros

The Python API surface consists of C# types and methods exposed to Python via Python.NET. Typical categories include:

  • Game state queries: Accessing entities, items, skills, spells, and other UO-related data.
  • Actions: Targeting, movement, casting, vendor operations, and other gameplay actions.
  • Utilities: Logging, timers, lists, dictionaries, and helper functions.
  • UI interaction: Safe UI updates via the Avalonia invoker.

For exact class names, methods, and properties, refer to the binding layer in the engine and the completion data used by the editor.

Section sources

IntelliSense Configuration and Code Completion

  • Completion data source: PythonCompletionData provides metadata about available symbols, method signatures, and parameter hints.
  • Editor integration: The editor consumes this metadata to provide autocomplete and signature help for Python macro scripts.
  • Customization: Extend completion data by adding new bindings in the engine and updating completion definitions accordingly.
classDiagram
class PythonCompletionData {
+ProvideCompletions()
+GetSymbolInfo(name)
+GetSignatureHelp(member)
}
class Engine {
+ExposeBindings()
+UpdateCompletionData()
}
Engine --> PythonCompletionData : "updates"

Diagram sources

Section sources

Debugging Support for Python Scripts

  • Standard debugging: Use Python.NET-compatible debuggers (e.g., VS Code with Python extension) attached to the process.
  • Breakpoints: Place breakpoints in Python scripts; ensure symbols are loaded and the correct interpreter path is configured.
  • Logging: Leverage SystemMessageTextWriter to capture outputs and errors for post-mortem analysis.

[No sources needed since this section provides general guidance]

Practical Automation Patterns

Common patterns for Python macros:

  • Conditional logic: Branch based on game state (e.g., health thresholds, inventory counts).
  • File I/O: Read/write configuration or logs using Python’s built-in file operations.
  • Network requests: Perform HTTP calls for external integrations or telemetry.
  • Timed loops: Use timers or sleep-based loops to poll state changes.

Example references:

  • Conditional branching and loops: See macro examples under the macros directory.
  • File operations: Refer to sample scripts demonstrating read/write patterns.
  • Network requests: Look at samples using urllib or requests within Python macros.

[No sources needed since this section provides general guidance]

Dependency Analysis

The Python integration depends on Python.NET and the macro subsystem. The following diagram highlights key dependencies.

graph TB
PNET["Python.NET (pythonnet)"]
CA_Av["ClassicAssist.Avalonia"]
CA_Shared["ClassicAssist.Shared"]
CA_WPF["ClassicAssist"]
CA_Av --> PNET
CA_Av --> CA_Shared
CA_Shared --> CA_WPF

Diagram sources

Section sources

Performance Considerations

  • Minimize cross-boundary calls: Batch operations and reduce frequent C# calls from Python to avoid overhead.
  • Prefer local computations: Perform heavy processing in Python when possible; only call C# for necessary interop.
  • Reuse objects: Cache frequently accessed C# objects in Python to avoid repeated lookups.
  • Avoid blocking the UI thread: Always marshal UI updates via the Avalonia invoker/dispatcher.
  • Manage references: Release large objects and avoid circular references between C# and Python contexts.

[No sources needed since this section provides general guidance]

Troubleshooting Guide

Common issues and resolutions:

  • Python runtime not found: Ensure Python.NET is correctly installed and the expected Python version is available on PATH.
  • Import errors: Verify sys.path configuration and that macro directories are included.
  • Cross-thread exceptions: Use AvaloniaUIInvoker and AvaloniaDispatcher for UI updates from Python.
  • Memory leaks: Check for lingering references to Python objects in C# caches; implement periodic cleanup.
  • IntelliSense missing symbols: Update PythonCompletionData and rebuild to refresh editor metadata.

Section sources

Conclusion

ClassicAssist.Avalonia integrates Python scripting via Python.NET, providing a robust execution environment, safe UI threading, and rich IntelliSense support. By following best practices for memory management and performance, developers can create efficient and maintainable Python macros that interact seamlessly with the game and UI.

Appendices

  • Example macro locations: Explore the macros directory for sample Python scripts demonstrating conditional logic, file I/O, and network requests.
  • API reference: Consult the engine’s binding layer and completion data for the complete list of exposed classes, methods, and properties.

[No sources needed since this section provides general guidance]