<jupyter_start><jupyter_text>Install dependcies`poetry install` or `pip install -r requirements.txt`  Set up functions<jupyter_code>import websocket
from websocket import create_connection

import json
import random 
import string
import re


from datetime import datetime
from time import sleep
from typing import List


class SESSION_ENUM:
    """
    Description:
        Session constants
    """
    WEBSOCKET: bool = False
    CHART: bool = True

def generate_sesssion(session) -> str:
    """
    Description:
        Get {session prefix}_{random string}
    params:
        session (bool)
            True: for websocket
            False: for chart
    returns:
        (str) web socket session
    """
    string_length = 12
    letters = string.ascii_lowercase
    random_string = "".join(
        random.choice(letters) for i in range(string_length)
    )
    prefix = "qs" if session else "cs"
    return f"qs_{random_string}"


def prepend_header(sentences: str)->str:
    """
    Description:
        format data into websocket message:
    params:
        sentence
            (str) contructed message
    returns:
        (str) An added prefix message
    example:
        ~m~54~m~{"m":"set_auth_token","p":["unauthorized_user_token"]}
    """
    return f"~m~{len(sentences)}~m~{sentences}"


def construct_message(function_name: str, parameters: List[str]) -> str:
    """
    params:
        function_name
            (str) Function to summit into websocket
        parameters:
            List[str]: list paramaters to input into the function
    returns:
        (str) a message as a JSON format join without space
    example:
        {"m":"set_auth_token","p":["unauthorized_user_token"]}
    """
    return json.dumps(
        {"m": function_name, "p": parameters}, separators=(",", ":")
    )

def create_message(function_name: str, parameters: List[str]) -> str:
    """
    Description:
        Integration of a created message function
    params:
        function_name:
            (str) Function to summit into websocket
        parameters:
            List[str]: list paramaters to input into the function
    returns:
        (str) message as websocket message format
    example:
        ~m~54~m~{"m":"set_auth_token","p":["unauthorized_user_token"]}
    """
    output = prepend_header(construct_message(function_name, parameters))
    return prepend_header(construct_message(function_name, parameters))
    
    
def send_message(
    ws: websocket._core.WebSocket,
    func: str, args: List[str]
) -> None:
    """
    Description:
        Send formatted message
    params:
        ws:
            (websocket._core.WebSocket) web socket sesssoin
        func:
            (str) Function to summit into websocket
        args:
            List[str]: list paramaters to input into the function
    """

    ws.send(create_message(func, args))<jupyter_output><empty_output><jupyter_text>Config<jupyter_code>headers = json.dumps({
    "Origin": "https://data.tradingview.com",
    "user-agent": "<<EMAIL>> scrape for education purpose"
})

symbol = "BINANCE:BTCUSDT"
# time_frame_in_minute = str(1 * 60)
time_frame_in_minute = "1H"
nubmer_of_bars = 5

resolve_symbol = json.dumps({"symbol": symbol, "adjustment": "splits"})<jupyter_output><empty_output><jupyter_text>Send messages<jupyter_code># Set up session

ws = create_connection(
    "wss://data.tradingview.com/socket.io/websocket", headers=headers
)

websocket_session = generate_sesssion(SESSION_ENUM.WEBSOCKET)
print(f"Web socket session generated: {websocket_session}")

chart_session = generate_sesssion(SESSION_ENUM.CHART)
print(f"Chart session generated: {chart_session}")


send_message(ws, "set_auth_token", ["unauthorized_user_token"])
send_message(ws, "chart_create_session", [chart_session, ""])
send_message(ws, "quote_create_session", [websocket_session])

send_message(
    ws, "quote_add_symbols", [websocket_session, symbol, {"flags": ["force_permission"]}]
)

send_message(ws, "resolve_symbol", [chart_session, "symbol_1", f"={resolve_symbol}"])
send_message(
    ws,
    "create_series",
    [chart_session, "btc_1", "btc_1", "symbol_1", time_frame_in_minute, nubmer_of_bars]
)<jupyter_output>Web socket session generated: qs_myldepzcukgh
Chart session generated: qs_hpdlntzkbgpo<jupyter_text>Receive response<jupyter_code>a = ""

while True:
    try:
        results: str = ws.recv()

        pattern = re.compile("~m~\d+~m~~h~\d+$")

        if pattern.match(results):
            # Send heart beat to keep connection alive
            ws.recv()
            ws.send(results)

        for r in results.split("~m~"):
            try:
                r = json.loads(r)
                if not isinstance(r, dict):
                     continue
                message = r.get("m")
                if message == "timescale_update" or message == "du":
                    print(r)
            except json.JSONDecodeError:
                pass
    except KeyboardInterrupt:
        print("End")
        break<jupyter_output>{'m': 'timescale_update', 'p': ['qs_hpdlntzkbgpo', {'btc_1': {'node': 'hkg1-charts-20-study-engine-6@hkg1-compute-20', 's': [{'i': 0, 'v': [1643468400.0, 37620.04, 37735.67, 37268.44, 37566.82, 1881.672089999958]}, {'i': 1, 'v': [1643472000.0, 37567.98, 37603.57, 37317.37, 37538.19, 1102.7421800000066]}, {'i': 2, 'v': [1643475600.0, 37538.19, 37720.77, 37532.15, 37646.31, 784.4718399999997]}, {'i': 3, 'v': [1643479200.0, 37646.31, 37904.19, 37556.56, 37806.23, 772.066929999998]}, {'i': 4, 'v': [1643482800.0, 37806.24, 37913.11, 37781.49, 37898.79, 195.86297000000047]}], 'ns': {'d': '', 'indexes': []}, 't': 'btc_1', 'lbs': {'bar_close_time': 1643486400}}}, {'index': 0, 'zoffset': 0, 'changes': [1643468400.0, 1643472000.0, 1643475600.0, 1643479200.0, 1643482800.0], 'marks': [[10, 1643450400, 0], [30, 1643454000, 1], [33, 1643457600, 2], [30, 1643461200, 3], [30, 1643464800, 4]], 'index_diff': []}], 't': 1643483868, 't_ms': 1643483868109}
{'m': 'du', 'p': ['qs_hpdlntzkbgpo', {'btc_1': {'s[...]
{'fraction_non_alphanumeric': 0.14103413987404706, 'fraction_numerical': 0.07640039774610541, 'mean_word_length': 3.3323761665470206, 'pattern_counts': {'":': 15, '<': 17, '<?xml version=': 0, '>': 22, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '576282', 'license': 'MIT', 'n_tokens_mistral': 2364, 'n_tokens_neox': 2014, 'n_words': 465, 'path': 'ScraperDemo.ipynb', 'repo_name': 'chayuton/trading-view-scraper', 'size': '6052'}