Source code for vtpy.data.events

"""Event data models for VTube Studio API."""

# TODO:
# - make event configs fields optional
# - document fields
# - replace type str for path where appropriate
# - check for enums in API docs

from ast import Str
from typing import Optional, List, Dict, Any, Literal, Union
from enum import Enum
from pydantic import BaseModel, Field
from vtpy.data.common import (
    BaseRequest,
    BaseResponse,
    BaseEvent,
    ErrorData,
    MessageType,
    HotkeyAction,
)

__all__ = [
    "EventType",
    "EVENT_MODEL_MAP",
    "WindowSize",
    "AnimationEventType",
    "ItemEventType",
    "BaseEventSubscriptionRequest",
    "EventSubscriptionResponseData",
    "EventSubscriptionResponse",
    "MouseButtonID",
    "TestEventSubscriptionRequestConfig",
    "TestEventSubscriptionRequestData",
    "TestEventSubscriptionRequest",
    "TestEventData",
    "TestEvent",
    "ModelLoadedEventSubscriptionRequestConfig",
    "ModelLoadedEventSubscriptionRequestData",
    "ModelLoadedEventSubscriptionRequest",
    "ModelLoadedEventData",
    "ModelLoadedEvent",
    "TrackingStatusChangedEventSubscriptionRequestConfig",
    "TrackingStatusChangedEventSubscriptionRequestData",
    "TrackingStatusChangedEventSubscriptionRequest",
    "TrackingStatusChangedEventData",
    "TrackingStatusChangedEvent",
    "BackgroundChangedEventSubscriptionRequestConfig",
    "BackgroundChangedEventSubscriptionRequestData",
    "BackgroundChangedEventSubscriptionRequest",
    "BackgroundChangedEventData",
    "BackgroundChangedEvent",
    "ModelConfigChangedEventSubscriptionRequestConfig",
    "ModelConfigChangedEventSubscriptionRequestData",
    "ModelConfigChangedEventSubscriptionRequest",
    "ModelConfigChangedEventData",
    "ModelConfigChangedEvent",
    "ModelMovedEventSubscriptionRequestConfig",
    "ModelMovedEventSubscriptionRequestData",
    "ModelMovedEventSubscriptionRequest",
    "ModelPositionData",
    "ModelMovedEventData",
    "ModelMovedEvent",
    "ModelOutlineEventSubscriptionRequestConfig",
    "ModelOutlineEventSubscriptionRequestData",
    "ModelOutlineEventSubscriptionRequest",
    "ConvexHullPoint",
    "ModelOutlineEventData",
    "ModelOutlineEvent",
    "HotkeyTriggeredEventSubscriptionRequestConfig",
    "HotkeyTriggeredEventSubscriptionRequestData",
    "HotkeyTriggeredEventSubscriptionRequest",
    "HotkeyTriggeredEventData",
    "HotkeyTriggeredEvent",
    "ModelAnimationEventSubscriptionRequestConfig",
    "ModelAnimationEventSubscriptionRequestData",
    "ModelAnimationEventSubscriptionRequest",
    "ModelAnimationEventData",
    "ModelAnimationEvent",
    "ItemEventSubscriptionRequestConfig",
    "ItemEventSubscriptionRequestData",
    "ItemEventSubscriptionRequest",
    "ItemPosition",
    "ItemEventData",
    "ItemEvent",
    "ModelClickedEventSubscriptionRequestConfig",
    "ModelClickedEventSubscriptionRequestData",
    "ModelClickedEventSubscriptionRequest",
    "HitInfo",
    "ArtMeshHit",
    "ClickPosition",
    "ModelClickedEventData",
    "ModelClickedEvent",
    "PostProcessingEventSubscriptionRequestConfig",
    "PostProcessingEventSubscriptionRequestData",
    "PostProcessingEventSubscriptionRequest",
    "PostProcessingEventData",
    "PostProcessingEvent",
    "Live2DCubismEditorConnectedEventSubscriptionRequestConfig",
    "Live2DCubismEditorConnectedEventSubscriptionRequestData",
    "Live2DCubismEditorConnectedEventSubscriptionRequest",
    "Live2DCubismEditorConnectedEventData",
    "Live2DCubismEditorConnectedEvent",
]
# ============================================================================
# Event Types
# ============================================================================


[docs] class EventType(Enum): """Event type identifiers.""" TestEvent = "TestEvent" ModelLoadedEvent = "ModelLoadedEvent" TrackingStatusChangedEvent = "TrackingStatusChangedEvent" BackgroundChangedEvent = "BackgroundChangedEvent" ModelConfigChangedEvent = "ModelConfigChangedEvent" ModelMovedEvent = "ModelMovedEvent" ModelOutlineEvent = "ModelOutlineEvent" HotkeyTriggeredEvent = "HotkeyTriggeredEvent" ModelAnimationEvent = "ModelAnimationEvent" ItemEvent = "ItemEvent" ModelClickedEvent = "ModelClickedEvent" PostProcessingEvent = "PostProcessingEvent" Live2DCubismEditorConnectedEvent = "Live2DCubismEditorConnectedEvent"
[docs] class AnimationEventType(Enum): Custom = "Custom" Start = "Start" End = "End"
[docs] class ItemEventType(Enum): Added = "Added" Removed = "Removed" DroppedPinned = "DroppedPinned" DroppedUnpinned = "DroppedUnpinned" Clicked = "Clicked" Locked = "Locked" Unlocked = "Unlocked"
# ============================================================================ # Helper Types # ============================================================================
[docs] class WindowSize(BaseModel): x: float y: float
# ============================================================================ # Event Sub # ============================================================================
[docs] class BaseEventSubscriptionRequest(BaseRequest): """Request to subscribe to events.""" messageType: Literal[MessageType.EventSubscriptionRequest] = ( MessageType.EventSubscriptionRequest )
[docs] class EventSubscriptionResponseData(BaseModel): """Data for event subscription response.""" subscribedEventCount: int subscribedEvents: List[EventType]
[docs] class EventSubscriptionResponse(BaseResponse): """Response from event subscription request.""" messageType: Literal[MessageType.EventSubscriptionResponse] = ( MessageType.EventSubscriptionResponse ) data: Union[EventSubscriptionResponseData, ErrorData]
[docs] class MouseButtonID(Enum): Left = 0 Right = 1 Middle = 2
# ============================================================================ # Test Events # ============================================================================
[docs] class TestEventSubscriptionRequestConfig(BaseModel): """Config for test event subscription request.""" testMessageForEvent: Optional[str] = Field( None, description="Test message returned in the event." )
[docs] class TestEventSubscriptionRequestData(BaseModel): """Config for test event subscription request.""" eventName: Literal[EventType.TestEvent] = EventType.TestEvent subscribe: bool = True config: TestEventSubscriptionRequestConfig
[docs] class TestEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: TestEventSubscriptionRequestData
[docs] class TestEventData(BaseModel): """Data for model loaded event.""" yourTestMessage: str = Field(description="Test message returned in the event.") counter: int = Field(description="Counter of the event.")
[docs] class TestEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.TestEvent] = EventType.TestEvent data: TestEventData
# ============================================================================ # Model Events # ============================================================================
[docs] class ModelLoadedEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request.""" modelID: Optional[List[str]] = Field(None, description="The ID of the model to listen for.")
[docs] class ModelLoadedEventSubscriptionRequestData(BaseModel): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.ModelLoadedEvent] = EventType.ModelLoadedEvent subscribe: bool = True config: ModelLoadedEventSubscriptionRequestConfig
[docs] class ModelLoadedEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: ModelLoadedEventSubscriptionRequestData
[docs] class ModelLoadedEventData(BaseModel): """Data for model loaded event.""" modelLoaded: bool modelName: str modelID: str
[docs] class ModelLoadedEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.ModelLoadedEvent] = EventType.ModelLoadedEvent data: ModelLoadedEventData
# ============================================================================ # Tracking Events # ============================================================================
[docs] class TrackingStatusChangedEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request."""
[docs] class TrackingStatusChangedEventSubscriptionRequestData(BaseModel): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.TrackingStatusChangedEvent] = EventType.TrackingStatusChangedEvent subscribe: bool = True config: TrackingStatusChangedEventSubscriptionRequestConfig
[docs] class TrackingStatusChangedEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: TrackingStatusChangedEventSubscriptionRequestData
[docs] class TrackingStatusChangedEventData(BaseModel): """Data for model loaded event.""" faceFound: bool leftHandFound: bool rightHandFound: bool
[docs] class TrackingStatusChangedEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.TrackingStatusChangedEvent] = ( EventType.TrackingStatusChangedEvent ) data: TrackingStatusChangedEventData
# ============================================================================ # Background Events # ============================================================================
[docs] class BackgroundChangedEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request."""
[docs] class BackgroundChangedEventSubscriptionRequestData(BaseModel): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.BackgroundChangedEvent] = EventType.BackgroundChangedEvent subscribe: bool = True config: BackgroundChangedEventSubscriptionRequestConfig
[docs] class BackgroundChangedEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: BackgroundChangedEventSubscriptionRequestData
[docs] class BackgroundChangedEventData(BaseModel): """Data for model loaded event.""" backgroundName: str
[docs] class BackgroundChangedEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.BackgroundChangedEvent] = EventType.BackgroundChangedEvent data: BackgroundChangedEventData
# ============================================================================ # Model Config Events # ============================================================================
[docs] class ModelConfigChangedEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request."""
[docs] class ModelConfigChangedEventSubscriptionRequestData(BaseModel): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.ModelConfigChangedEvent] = EventType.ModelConfigChangedEvent subscribe: bool = True config: ModelConfigChangedEventSubscriptionRequestConfig
[docs] class ModelConfigChangedEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: ModelConfigChangedEventSubscriptionRequestData
[docs] class ModelConfigChangedEventData(BaseModel): """Data for model loaded event.""" modelID: str modelName: str hotkeyConfigChanged: bool
[docs] class ModelConfigChangedEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.ModelConfigChangedEvent] = EventType.ModelConfigChangedEvent data: ModelConfigChangedEventData
# ============================================================================ # Model Moved Events # ============================================================================
[docs] class ModelMovedEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request."""
[docs] class ModelMovedEventSubscriptionRequestData(BaseModel): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.ModelMovedEvent] = EventType.ModelMovedEvent subscribe: bool = True config: ModelMovedEventSubscriptionRequestConfig
[docs] class ModelMovedEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: ModelMovedEventSubscriptionRequestData
[docs] class ModelPositionData(BaseModel): """Data for model position.""" positionX: float positionY: float rotation: float size: float
[docs] class ModelMovedEventData(BaseModel): """Data for model loaded event.""" modelID: str modelName: str modelPosition: ModelPositionData
[docs] class ModelMovedEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.ModelMovedEvent] = EventType.ModelMovedEvent data: ModelMovedEventData
# ============================================================================ # Model Outline Events # ============================================================================
[docs] class ModelOutlineEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request.""" draw: Optional[bool] = Field(None, description="Whether to draw the model outline.")
[docs] class ModelOutlineEventSubscriptionRequestData(BaseModel): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.ModelOutlineEvent] = EventType.ModelOutlineEvent subscribe: bool = True config: ModelOutlineEventSubscriptionRequestConfig
[docs] class ModelOutlineEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: ModelOutlineEventSubscriptionRequestData
[docs] class ConvexHullPoint(BaseModel): x: float y: float
[docs] class ModelOutlineEventData(BaseModel): """Data for model loaded event.""" modelID: str modelName: str convexHull: List[ConvexHullPoint] convexHullCenter: ConvexHullPoint windowSize: WindowSize
[docs] class ModelOutlineEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.ModelOutlineEvent] = EventType.ModelOutlineEvent data: ModelOutlineEventData
# ============================================================================ # Hotkey Events # ============================================================================
[docs] class HotkeyTriggeredEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request.""" onlyForAction: Optional[HotkeyAction] = Field( None, description="Only trigger events for this action." ) ignoreHotkeysTriggeredByAPI: bool = Field( False, description="Ignore hotkeys triggered by the API." )
[docs] class HotkeyTriggeredEventSubscriptionRequestData(BaseModel): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.HotkeyTriggeredEvent] = EventType.HotkeyTriggeredEvent subscribe: bool = True config: HotkeyTriggeredEventSubscriptionRequestConfig
[docs] class HotkeyTriggeredEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: HotkeyTriggeredEventSubscriptionRequestData
[docs] class HotkeyTriggeredEventData(BaseModel): """Data for model loaded event.""" hotkeyID: str hotkeyName: str hotkeyAction: HotkeyAction hotkeyFile: str hotkeyTriggeredByAPI: bool modelID: str modelName: str isLive2DItem: bool
[docs] class HotkeyTriggeredEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.HotkeyTriggeredEvent] = EventType.HotkeyTriggeredEvent data: HotkeyTriggeredEventData
# ============================================================================ # Animation Events # ============================================================================
[docs] class ModelAnimationEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request.""" ignoreLive2DItems: bool = Field(False, description="Ignore live2d items.") ignoreIdleAnimations: bool = Field(False, description="Ignore idle animations.")
[docs] class ModelAnimationEventSubscriptionRequestData(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.ModelAnimationEvent] = EventType.ModelAnimationEvent subscribe: bool = True config: ModelAnimationEventSubscriptionRequestConfig
[docs] class ModelAnimationEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: ModelAnimationEventSubscriptionRequestData
[docs] class ModelAnimationEventData(BaseModel): """Data for model loaded event.""" animationEventType: AnimationEventType animationEventTime: float animationEventData: str animationName: str animationLength: float isIdleAnimation: bool modelID: str modelName: str isLive2DItem: bool
[docs] class ModelAnimationEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.ModelAnimationEvent] = EventType.ModelAnimationEvent data: ModelAnimationEventData
# ============================================================================ # Item Events # ============================================================================
[docs] class ItemEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request.""" itemInstanceIDs: Optional[List[str]] = Field( None, description="The IDs of the items to listen for." ) itemFileNames: Optional[List[str]] = Field( None, description="The file names of the items to listen for." )
[docs] class ItemEventSubscriptionRequestData(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.ItemEvent] = EventType.ItemEvent subscribe: bool = True config: ItemEventSubscriptionRequestConfig
[docs] class ItemEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: ItemEventSubscriptionRequestData
[docs] class ItemPosition(BaseModel): x: float y: float
[docs] class ItemEventData(BaseModel): """Data for model loaded event.""" itemEventType: ItemEventType itemInstanceID: str itemFileName: str itemPosition: ItemPosition
[docs] class ItemEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.ItemEvent] = EventType.ItemEvent data: ItemEventData
# ============================================================================ # Model Clicked Events # ============================================================================
[docs] class ModelClickedEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request.""" onlyClicksOnModel: Optional[bool] = Field( True, description="Only trigger events for clicks on the model." )
[docs] class ModelClickedEventSubscriptionRequestData(BaseModel): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.ModelClickedEvent] = EventType.ModelClickedEvent subscribe: bool = True config: ModelClickedEventSubscriptionRequestConfig
[docs] class ModelClickedEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: ModelClickedEventSubscriptionRequestData
[docs] class HitInfo(BaseModel): modelID: str artMeshID: str angle: float size: float vertexID1: int vertexID2: int vertexID3: int vertexWeight1: float vertexWeight2: float vertexWeight3: float
[docs] class ArtMeshHit(BaseModel): artMeshOrder: int isMasked: bool hitInfo: HitInfo
[docs] class ClickPosition(BaseModel): x: float y: float
[docs] class ModelClickedEventData(BaseModel): """Data for model loaded event.""" modelLoaded: bool loadedModelID: str loadedModelName: str modelWasClicked: bool mouseButtonID: MouseButtonID clickPosition: ClickPosition windowSize: WindowSize clickedArtMeshCount: int artMeshHits: List[ArtMeshHit]
[docs] class ModelClickedEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.ModelClickedEvent] = EventType.ModelClickedEvent data: ModelClickedEventData
# ============================================================================ # Post Processing Events # ============================================================================
[docs] class PostProcessingEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request."""
[docs] class PostProcessingEventSubscriptionRequestData(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.PostProcessingEvent] = EventType.PostProcessingEvent subscribe: bool = True config: PostProcessingEventSubscriptionRequestConfig
[docs] class PostProcessingEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: PostProcessingEventSubscriptionRequestData
[docs] class PostProcessingEventData(BaseModel): """Data for model loaded event.""" currentState: bool currentPreset: str
[docs] class PostProcessingEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.PostProcessingEvent] = EventType.PostProcessingEvent data: PostProcessingEventData
# ============================================================================ # Live2D Cubism Editor Events # ============================================================================
[docs] class Live2DCubismEditorConnectedEventSubscriptionRequestConfig(BaseModel): """Config for model loaded event subscription request."""
[docs] class Live2DCubismEditorConnectedEventSubscriptionRequestData(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" eventName: Literal[EventType.Live2DCubismEditorConnectedEvent] = ( EventType.Live2DCubismEditorConnectedEvent ) subscribe: bool = True config: Live2DCubismEditorConnectedEventSubscriptionRequestConfig
[docs] class Live2DCubismEditorConnectedEventSubscriptionRequest(BaseEventSubscriptionRequest): """Request to subscribe to model loaded events.""" data: Live2DCubismEditorConnectedEventSubscriptionRequestData
[docs] class Live2DCubismEditorConnectedEventData(BaseModel): """Data for model loaded event.""" tryingToConnect: bool connected: bool shouldSendParameters: bool
[docs] class Live2DCubismEditorConnectedEvent(BaseEvent): """Event fired when a model is loaded.""" messageType: Literal[EventType.Live2DCubismEditorConnectedEvent] = ( EventType.Live2DCubismEditorConnectedEvent ) data: Live2DCubismEditorConnectedEventData
# Mapping of event types to their corresponding Pydantic models EVENT_MODEL_MAP: Dict[EventType, type] = { EventType.TestEvent: TestEvent, EventType.ModelLoadedEvent: ModelLoadedEvent, EventType.TrackingStatusChangedEvent: TrackingStatusChangedEvent, EventType.BackgroundChangedEvent: BackgroundChangedEvent, EventType.ModelConfigChangedEvent: ModelConfigChangedEvent, EventType.ModelMovedEvent: ModelMovedEvent, EventType.ModelOutlineEvent: ModelOutlineEvent, EventType.HotkeyTriggeredEvent: HotkeyTriggeredEvent, EventType.ModelAnimationEvent: ModelAnimationEvent, EventType.ItemEvent: ItemEvent, EventType.ModelClickedEvent: ModelClickedEvent, EventType.PostProcessingEvent: PostProcessingEvent, EventType.Live2DCubismEditorConnectedEvent: Live2DCubismEditorConnectedEvent, }