3
3
4
4
Usage: python listen_to_websocket.py
5
5
"""
6
-
6
+ import argparse
7
7
import asyncio
8
8
import json
9
9
import logging
14
14
import websockets
15
15
from google .cloud import bigquery
16
16
from google .cloud .bigquery import SchemaField
17
- from v4_client_py .clients .constants import Network
18
17
19
18
# Import the BigQuery helpers
20
19
from bq_helpers import create_table , BatchWriter
23
22
with open ("config.json" , "r" ) as config_file :
24
23
config_json = json .load (config_file )
25
24
26
- DATASET_ID = "indexer_stream "
25
+ DATASET_ID = "indexer_stream_new "
27
26
TABLE_ID = "responses"
28
27
29
28
SCHEMA = [
30
29
SchemaField ("received_at" , "TIMESTAMP" , mode = "REQUIRED" ),
31
30
SchemaField ("uuid" , "STRING" , mode = "REQUIRED" ),
32
31
SchemaField ("response" , "JSON" , mode = "NULLABLE" ),
32
+ SchemaField ("server_address" , "STRING" , mode = "REQUIRED" ),
33
33
]
34
34
35
35
TIME_PARTITIONING = bigquery .TimePartitioning (field = "received_at" )
36
+ CLUSTERING_FIELDS = ["server_address" ]
37
+
36
38
# Batch settings
37
39
BATCH_SIZE = 9
38
40
BATCH_TIMEOUT = 10
39
41
WORKER_COUNT = 1
40
42
41
43
42
- def process_message (message ):
44
+ def process_message (message , url ):
43
45
return {
44
46
"received_at" : datetime .utcnow ().isoformat ("T" ) + "Z" ,
45
47
"uuid" : str (uuid .uuid4 ()),
46
48
"response" : message ,
49
+ "server_address" : url
47
50
}
48
51
49
52
50
53
class AsyncSocketClient :
51
- def __init__ (self , config , subaccount_ids , batch_writer ):
52
- self .url = config . websocket_endpoint
54
+ def __init__ (self , indexer_url : str , subaccount_ids , batch_writer ):
55
+ self .url = indexer_url
53
56
self .subaccount_ids = subaccount_ids
54
57
self .batch_writer = batch_writer
55
58
56
59
async def connect (self ):
57
60
retries = 0
58
61
while True :
59
62
try :
60
- async with websockets .connect (self .url ) as websocket :
63
+ async with websockets .connect (f"wss:// { self .url } /v4/ws" ) as websocket :
61
64
if self .subaccount_ids :
62
65
for subaccount_id in self .subaccount_ids :
63
66
await self .subscribe (
@@ -81,7 +84,7 @@ async def connect(self):
81
84
async def consumer_handler (self , websocket ):
82
85
async for message in websocket :
83
86
await self .batch_writer .enqueue_data (
84
- process_message (message )
87
+ process_message (message , self . url )
85
88
) # Enqueue data for batch writing
86
89
87
90
async def send (self , websocket , message ):
@@ -97,17 +100,19 @@ async def subscribe(self, websocket, channel, params=None):
97
100
await self .send (websocket , message )
98
101
99
102
100
- async def main ():
103
+ async def main (indexer_url : str ):
101
104
batch_writer = BatchWriter (
102
105
DATASET_ID , TABLE_ID , WORKER_COUNT , BATCH_SIZE , BATCH_TIMEOUT
103
106
)
104
- config = Network .config_network ().indexer_config
105
107
subaccount_ids = [
106
108
"/" .join ([config_json ["maker_address" ], str (0 )]),
107
109
"/" .join ([config_json ["taker_address" ], str (0 )]),
110
+ "/" .join ([config_json ["stateful_address" ], str (0 )]),
108
111
]
109
112
client = AsyncSocketClient (
110
- config , subaccount_ids = subaccount_ids , batch_writer = batch_writer
113
+ indexer_url ,
114
+ subaccount_ids = subaccount_ids ,
115
+ batch_writer = batch_writer ,
111
116
)
112
117
113
118
batch_writer_task = asyncio .create_task (batch_writer .batch_writer_loop ())
@@ -116,8 +121,19 @@ async def main():
116
121
117
122
118
123
if __name__ == "__main__" :
124
+ parser = argparse .ArgumentParser (
125
+ description = "Run the Indexer Websocket client for a given URL, e.g. indexer.v4testnet.dydx.exchange."
126
+ )
127
+ parser .add_argument (
128
+ "--indexer_url" ,
129
+ type = str ,
130
+ help = "The indexer API to read from." ,
131
+ )
132
+ args = parser .parse_args ()
133
+
134
+ log_id = args .indexer_url .replace (":" , "_" ).replace ("/" , "_" )
119
135
handler = RotatingFileHandler (
120
- "listen_to_websocket .log" ,
136
+ f"listen_to_websocket_ { log_id } .log" ,
121
137
maxBytes = 5 * 1024 * 1024 , # 5 MB
122
138
backupCount = 5
123
139
)
@@ -127,5 +143,5 @@ async def main():
127
143
format = "%(asctime)s - %(levelname)s - %(message)s" ,
128
144
)
129
145
130
- create_table (DATASET_ID , TABLE_ID , SCHEMA , TIME_PARTITIONING )
131
- asyncio .run (main ())
146
+ create_table (DATASET_ID , TABLE_ID , SCHEMA , TIME_PARTITIONING , CLUSTERING_FIELDS )
147
+ asyncio .run (main (args . indexer_url ))
0 commit comments