Skip to content

Python JavaScript Bridge Architecture

levi edited this page Nov 6, 2025 · 2 revisions

Python-JavaScript Bridge Architecture

Table of Contents

  1. Introduction
  2. Architecture Overview
  3. Bidirectional Communication Mechanism
  4. HTTP-based RPC System
  5. Request/Response Flow
  6. Connection Lifecycle Management
  7. Widget Initialization and Configuration
  8. Class Type Handling and Request Routing
  9. Security Considerations
  10. Error Handling Strategies

Introduction

The TVBridge component enables bidirectional communication between Python and JavaScript environments, facilitating seamless integration with TradingView's widget system. This architecture allows Python applications to interact with TradingView's charting library through a robust HTTP-based RPC mechanism implemented with FastAPI and uvicorn. The bridge handles method calls between environments, manages connection lifecycle, and provides configuration provisioning for widget initialization. This documentation details the architectural components, communication protocols, and integration patterns that make this interoperability possible.

Architecture Overview

The TVBridge architecture implements a client-server model where Python acts as an HTTP server receiving requests from a Node.js environment, while simultaneously making outbound HTTP requests to communicate back to JavaScript. This bidirectional communication enables full interoperability between the two runtime environments.

graph TD
subgraph "Node.js Environment"
ND[Node.js Server]
TVWidget[TradingView Widget]
end
subgraph "Python Environment"
PY[Python Process]
TVBridge[TVBridge]
TVWidgetPy[TVWidget]
TVObjectPool[TVObjectPool]
end
ND < --> |HTTP POST /web/call/py| TVBridge
TVBridge < --> |HTTP POST /py/call/web| ND
TVBridge --> TVWidgetPy
TVBridge --> TVObjectPool
TVWidgetPy < --> TVObjectPool
Loading

Bidirectional Communication Mechanism

The bridge establishes two communication channels: one for web-to-Python calls and another for Python-to-web calls. This bidirectional architecture allows both environments to initiate method invocations on objects in the other environment.

The web-to-Python communication is handled through FastAPI endpoints that receive JSON payloads containing method call information. The Python-to-web communication uses aiohttp to make HTTP POST requests to the Node.js server with serialized method call data.

sequenceDiagram
participant Web as JavaScript Environment
participant Node as Node.js Server
participant Python as Python Bridge
Web->>Node : Method Call
Node->>Python : POST /web/call/py
Python->>Python : Route to appropriate handler
Python->>Node : Return response
Node->>Web : Return result
Python->>Node : POST /py/call/web
Node->>Web : Execute method
Web->>Node : Return result
Node->>Python : Return response
Loading

HTTP-based RPC System

The RPC system is built on FastAPI and uvicorn, providing a high-performance HTTP server for handling incoming method calls from the web environment. The system uses standardized data structures for method calls and responses, enabling consistent communication across the bridge.

flowchart TD
A[Incoming HTTP Request] --> B{Route Check}
B --> |/web/call/py| C[Parse TVMethodCall]
B --> |/connect/from/nd| D[Return bridge port]
B --> |/ping/from/nd| E[Return bridge port]
C --> F{Class Name Check}
F --> |TVWidget| G[Handle Widget Call]
F --> |TVObjectPool| H[Handle Object Pool Call]
F --> |TVBridge| I[Handle Bridge Call]
F --> |Other| J[Handle Generic Object Call]
G --> K[Return TVMethodResponse]
H --> K
I --> K
J --> K
K --> L[Send HTTP Response]
Loading

Request/Response Flow

The request/response flow is centered around two key data structures: TVMethodCall and TVMethodResponse. These classes define the contract for communication between the Python and JavaScript environments.

classDiagram
class TVMethodCall {
+str object_id
+str class_name
+str method_name
+Dict[str, Any] kwargs
+to_json() dict
+from_dict(data) TVMethodCall
}
class TVMethodResponse {
+Any result
+str error
+is_success bool
+to_json() dict
+from_dict(data) TVMethodResponse
+raise_if_error()
}
TVBridge --> TVMethodCall : "receives"
TVBridge --> TVMethodResponse : "returns"
TVObject --> TVMethodCall : "handles"
TVObject --> TVMethodResponse : "returns"
Loading

Connection Lifecycle Management

The bridge implements a robust connection lifecycle management system with port discovery and retry mechanisms. The system automatically detects available ports and establishes connections with exponential backoff on failure.

sequenceDiagram
participant Bridge as TVBridge
participant Node as Node Server
Bridge->>Bridge : Start HTTP Server
alt Port specified
Bridge->>Bridge : Use specified port
else
Bridge->>Bridge : Find available port
end
Bridge->>Node : Connect to Node server
loop Retry up to 50 times
Node-->>Bridge : Response or timeout
alt Connected
Bridge->>Bridge : Set connected state
break
else
Bridge->>Bridge : Wait with exponential backoff
Bridge->>Bridge : Increment port number
end
end
alt Connected
Bridge->>Bridge : Connection established
else
Bridge->>Bridge : Log connection failure
end
Loading

Widget Initialization and Configuration

The bridge facilitates widget initialization by providing configuration data and handling chart readiness events. It uses a callback registration system to notify Python code when key widget events occur.

sequenceDiagram
participant Engine as TVEngine
participant Bridge as TVBridge
participant Widget as TVWidget
Engine->>Bridge : register_config_provider(config)
Engine->>Bridge : register_chart_ready_callback(callback)
Widget->>Bridge : chartDataReady event
Bridge->>Engine : Invoke chart_ready_callback
Bridge->>Widget : Provide config on widgetInitConfig call
Loading

Class Type Handling and Request Routing

The bridge routes incoming requests based on class type, directing them to specialized handlers for different object types. This routing system enables appropriate processing of method calls for various components.

flowchart TD
A[Incoming Method Call] --> B{Class Name}
B --> |TVWidget| C[Handle Widget Call]
B --> |TVObjectPool| D[Handle Object Pool Call]
B --> |TVBridge| E[Handle Bridge Call]
B --> |Other| F[Handle Generic Object Call]
C --> G[Check method name]
G --> |widgetInitConfig| H[Return config]
G --> |chartDataReady| I[Invoke callback]
G --> |Other| J[Handle via TVObject]
D --> K[Delegate to TVObjectPool]
E --> L[Handle bridge-specific methods]
F --> M[Get TVObject instance]
M --> N[Call handle_remote_call]
Loading

Security Considerations

The bridge implements security measures through CORS configuration, allowing broad origin access while maintaining control over credentials and headers. The system is designed for local execution, reducing exposure to external threats.

flowchart TD
A[HTTP Request] --> B{Origin Check}
B --> |All origins| C[Allow]
C --> D{Credentials}
D --> |Allowed| E[Allow]
D --> |Not allowed| F[Deny]
C --> G{Methods}
G --> |All methods| H[Allow]
G --> |Specific methods| I[Check against allowed]
C --> J{Headers}
J --> |All headers| K[Allow]
J --> |Specific headers| L[Check against allowed]
Loading

Error Handling Strategies

The bridge implements comprehensive error handling for network failures and method invocation errors. It uses try-catch blocks around HTTP requests and validates method calls before processing.

flowchart TD
A[Incoming Request] --> B{Valid callParams?}
B --> |No| C[Return validation error]
B --> |Yes| D[Route to handler]
D --> E[Execute method]
E --> F{Success?}
F --> |Yes| G[Return result]
F --> |No| H[Log exception]
H --> I[Return error response]
J[Outgoing Request] --> K{Network error?}
K --> |Yes| L[Log debug info]
L --> M[Return None]
K --> |No| N{HTTP error?}
N --> |Yes| O[Log debug info]
O --> P[Return None]
N --> |No| Q[Return response]
Loading

Clone this wiki locally