wiz-trader 0.10.0__tar.gz → 0.11.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wiz_trader
3
- Version: 0.10.0
3
+ Version: 0.11.0
4
4
  Summary: A Python SDK for connecting to the Wizzer.
5
5
  Home-page: https://bitbucket.org/wizzer-tech/quotes_sdk.git
6
6
  Author: Pawan Wagh
@@ -132,7 +132,7 @@ quotes_client = QuotesClient(log_level="debug") # Only override log level
132
132
 
133
133
  ## Quotes Client
134
134
 
135
- The `QuotesClient` enables you to connect to Wizzer's WebSocket server for real-time market data.
135
+ The `QuotesClient` enables you to connect to Wizzer's WebSocket server for realtime market data using **plain synchronous** callbacks—no `async def` required.
136
136
 
137
137
  ### Quotes Client Initialization
138
138
 
@@ -145,214 +145,155 @@ from wiz_trader import QuotesClient
145
145
  client = QuotesClient(
146
146
  base_url="wss://websocket-url/quotes",
147
147
  token="your-jwt-token",
148
- log_level="info", # Options: "error", "info", "debug"
149
- max_message_size=10 * 1024 * 1024, # Optional: Set max message size (default 10MB)
150
- batch_size=20 # Optional: Max instruments per subscription batch (default 20)
148
+ log_level="info", # Options: "error", "info", "debug"
149
+ max_message_size=10 * 1024 * 1024, # Optional: default 10MB
150
+ batch_size=20 # Optional: default 20 instruments per batch
151
151
  )
152
152
 
153
153
  # Method 2: Using environment variables
154
- # (Requires WZ__QUOTES_BASE_URL and WZ__TOKEN to be set)
154
+ # (Requires WZ__QUOTES_BASE_URL and WZ__TOKEN set)
155
155
  client = QuotesClient(log_level="info")
156
156
 
157
- # Method 3: Mixed approach (some params direct, some from env vars)
157
+ # Method 3: Mixed approach
158
158
  client = QuotesClient(
159
- base_url="wss://custom-websocket-url/quotes",
160
- log_level="debug"
161
- # token will be taken from WZ__TOKEN environment variable
159
+ base_url="wss://custom-url/quotes",
160
+ log_level="debug" # token from WZ__TOKEN env var
162
161
  )
163
162
  ```
164
163
 
165
164
  ### Connection Methods
166
165
 
167
- The `QuotesClient` offers two ways to connect:
168
-
169
166
  #### Blocking Connection
170
167
 
171
- This approach is similar to Zerodha's KiteTicker and is recommended for simple scripts:
168
+ Blocks your main thread, similar to Zerodhas KiteTicker:
172
169
 
173
170
  ```python
174
- # This will block and run until stopped
175
171
  client.connect()
176
172
  ```
177
173
 
178
- #### Non-Blocking Connection
174
+ #### NonBlocking Connection
179
175
 
180
- Use this for more complex applications where you need to perform other tasks:
176
+ Run alongside your own `asyncio` code:
181
177
 
182
178
  ```python
183
- # Start the connection in the background
184
179
  client.connect_async()
185
-
186
- # Later, when you want to stop:
180
+ # … do other work …
187
181
  client.stop()
188
182
  ```
189
183
 
190
184
  ### Callbacks
191
185
 
192
- Set up callbacks to handle different events:
186
+ All callbacks are **plain `def`** functions. Inside them you can call `subscribe(...)`, which under the hood schedules the actual async work—so you never `await` in your callbacks.
193
187
 
194
188
  ```python
195
189
  def on_tick(ws, tick):
196
- """Called when a tick is received"""
197
- print(f"Received tick: {tick}")
190
+ print("Tick:", tick)
198
191
 
199
192
  def on_connect(ws):
200
- """Called when the connection is established"""
201
- print("Connected to the quotes server")
202
- # Subscribe to instruments
203
- ws.subscribe(["NSE:SBIN:3045"])
193
+ print("Connected!")
194
+ # fire‑and‑forget subscribe—no await needed
195
+ ws.subscribe([
196
+ "NSE:SBIN:3045",
197
+ "NSE:RELIANCE:2885"
198
+ ])
204
199
 
205
200
  def on_close(ws, code, reason):
206
- """Called when the connection is closed"""
207
- print(f"Connection closed with code {code}: {reason}")
208
- # Optional: Stop the client (if you want to exit)
209
- # ws.stop()
201
+ print(f"Connection closed [{code}]: {reason}")
202
+ ws.stop() # to prevent auto‑reconnect
210
203
 
211
204
  def on_error(ws, error):
212
- """Called when an error occurs"""
213
- print(f"Error: {error}")
205
+ print("Error:", error)
214
206
 
215
- # Set the callbacks
216
- client.on_tick = on_tick
207
+ client.on_tick = on_tick
217
208
  client.on_connect = on_connect
218
- client.on_close = on_close
219
- client.on_error = on_error
209
+ client.on_close = on_close
210
+ client.on_error = on_error
220
211
  ```
221
212
 
222
213
  ### Subscribing to Instruments
223
214
 
224
- Subscribe to receive market data for specific instruments:
215
+ Call `ws.subscribe([...])` directly; the SDK will batch large lists and send them over the socket:
225
216
 
226
217
  ```python
227
- # Inside an on_connect callback:
228
218
  def on_connect(ws):
229
- # Subscribe to a single instrument
230
- ws.subscribe(["NSE:SBIN:3045"])
231
-
232
- # Or subscribe to multiple instruments at once
219
+ # subscribe without await
233
220
  ws.subscribe([
234
221
  "NSE:SBIN:3045",
235
222
  "NSE:ICICIBANK:4963",
236
- "NSE:RELIANCE:2885"
223
+ "NSE:RELIANCE:2885",
237
224
  ])
238
225
  ```
239
226
 
240
- For large lists of instruments, the client will automatically batch them to avoid message size issues.
241
-
242
227
  ### Unsubscribing from Instruments
243
228
 
244
- To stop receiving data for specific instruments:
229
+ Similarly, plain call to `unsubscribe`:
245
230
 
246
231
  ```python
247
- # Unsubscribe from specific instruments
248
232
  ws.unsubscribe(["NSE:SBIN:3045", "NSE:ICICIBANK:4963"])
249
233
  ```
250
234
 
251
- ### Handling WebSocket Connection
252
-
253
- The WebSocket connection automatically attempts to reconnect with exponential backoff if disconnected. You don't need to handle this manually.
254
-
255
- To explicitly close the connection:
256
-
257
- ```python
258
- # In a blocking context:
259
- client.stop()
260
-
261
- # In an async context:
262
- await client.close()
263
- ```
264
-
265
- ### Quotes Client Examples
235
+ ### Complete Examples
266
236
 
267
- #### Complete Blocking Example
237
+ #### Blocking Example
268
238
 
269
239
  ```python
270
240
  import logging
271
241
  from wiz_trader import QuotesClient
272
242
 
273
- # Configure logging
274
- logging.basicConfig(level=logging.DEBUG)
243
+ logging.basicConfig(level=logging.INFO)
275
244
 
276
- # Initialize the client
277
245
  client = QuotesClient(
278
246
  base_url="wss://websocket-url/quotes",
279
247
  token="your-jwt-token"
280
248
  )
281
249
 
282
250
  def on_tick(ws, tick):
283
- """Process incoming market data"""
284
- logging.debug("Received tick: %s", tick)
251
+ logging.debug("Tick: %s", tick)
285
252
 
286
253
  def on_connect(ws):
287
- """Handle successful connection"""
288
- logging.info("Connected to quotes server")
289
- # Subscribe to instruments
290
- ws.subscribe(["NSE:SBIN:3045", "NSE:RELIANCE:2885"])
254
+ logging.info("Connected.")
255
+ ws.subscribe(["NSE:SBIN:3045", "NSE:RELIANCE:2885"]) # no await
291
256
 
292
257
  def on_close(ws, code, reason):
293
- """Handle connection closure"""
294
- logging.info("Connection closed: %s", reason)
258
+ logging.warning("Closed: %s", reason)
259
+ ws.stop()
295
260
 
296
261
  def on_error(ws, error):
297
- """Handle errors"""
298
- logging.error("Error occurred: %s", error)
262
+ logging.error("Error: %s", error)
299
263
 
300
- # Set callbacks
301
- client.on_tick = on_tick
264
+ client.on_tick = on_tick
302
265
  client.on_connect = on_connect
303
- client.on_close = on_close
304
- client.on_error = on_error
266
+ client.on_close = on_close
267
+ client.on_error = on_error
305
268
 
306
- # Connect and run (blocking call)
307
269
  try:
308
270
  client.connect()
309
271
  except KeyboardInterrupt:
310
- print("Interrupted by user, shutting down...")
311
272
  client.stop()
312
273
  ```
313
274
 
314
- #### Non-Blocking Example with Other Operations
275
+ #### NonBlocking Example
315
276
 
316
277
  ```python
317
278
  import asyncio
318
279
  import logging
319
- from wiz_trader import QuotesClient, WizzerClient
280
+ from wiz_trader import QuotesClient
320
281
 
321
282
  async def main():
322
- # Configure logging
323
283
  logging.basicConfig(level=logging.INFO)
324
-
325
- # Initialize the quotes client
326
- quotes_client = QuotesClient(
284
+ client = QuotesClient(
327
285
  base_url="wss://websocket-url/quotes",
328
286
  token="your-jwt-token"
329
287
  )
330
-
331
- # Initialize the REST API client
332
- wizzer_client = WizzerClient(
333
- base_url="https://api-url.in",
334
- token="your-jwt-token"
335
- )
336
-
337
- # Set up quotes callbacks
338
- quotes_client.on_tick = lambda ws, tick: logging.info(f"Tick: {tick}")
339
- quotes_client.on_connect = lambda ws: ws.subscribe(["NSE:SBIN:3045"])
340
-
341
- # Connect in non-blocking mode
342
- quotes_client.connect_async()
343
-
344
- # Perform other operations
345
- indices = await asyncio.to_thread(wizzer_client.get_indices, exchange="NSE")
346
- logging.info(f"Available indices: {[idx['name'] for idx in indices[:5]]}")
347
-
348
- # Wait for some time
288
+ client.on_tick = lambda ws, tick: logging.info(tick)
289
+ client.on_connect = lambda ws: ws.subscribe(["NSE:SBIN:3045"])
290
+ client.connect_async()
291
+
292
+ # Your other async work here...
349
293
  await asyncio.sleep(60)
350
-
351
- # Stop the quotes client
352
- quotes_client.stop()
294
+ client.stop()
353
295
 
354
- if __name__ == "__main__":
355
- asyncio.run(main())
296
+ asyncio.run(main())
356
297
  ```
357
298
 
358
299
  ## Wizzer Client
@@ -105,7 +105,7 @@ quotes_client = QuotesClient(log_level="debug") # Only override log level
105
105
 
106
106
  ## Quotes Client
107
107
 
108
- The `QuotesClient` enables you to connect to Wizzer's WebSocket server for real-time market data.
108
+ The `QuotesClient` enables you to connect to Wizzer's WebSocket server for realtime market data using **plain synchronous** callbacks—no `async def` required.
109
109
 
110
110
  ### Quotes Client Initialization
111
111
 
@@ -118,214 +118,155 @@ from wiz_trader import QuotesClient
118
118
  client = QuotesClient(
119
119
  base_url="wss://websocket-url/quotes",
120
120
  token="your-jwt-token",
121
- log_level="info", # Options: "error", "info", "debug"
122
- max_message_size=10 * 1024 * 1024, # Optional: Set max message size (default 10MB)
123
- batch_size=20 # Optional: Max instruments per subscription batch (default 20)
121
+ log_level="info", # Options: "error", "info", "debug"
122
+ max_message_size=10 * 1024 * 1024, # Optional: default 10MB
123
+ batch_size=20 # Optional: default 20 instruments per batch
124
124
  )
125
125
 
126
126
  # Method 2: Using environment variables
127
- # (Requires WZ__QUOTES_BASE_URL and WZ__TOKEN to be set)
127
+ # (Requires WZ__QUOTES_BASE_URL and WZ__TOKEN set)
128
128
  client = QuotesClient(log_level="info")
129
129
 
130
- # Method 3: Mixed approach (some params direct, some from env vars)
130
+ # Method 3: Mixed approach
131
131
  client = QuotesClient(
132
- base_url="wss://custom-websocket-url/quotes",
133
- log_level="debug"
134
- # token will be taken from WZ__TOKEN environment variable
132
+ base_url="wss://custom-url/quotes",
133
+ log_level="debug" # token from WZ__TOKEN env var
135
134
  )
136
135
  ```
137
136
 
138
137
  ### Connection Methods
139
138
 
140
- The `QuotesClient` offers two ways to connect:
141
-
142
139
  #### Blocking Connection
143
140
 
144
- This approach is similar to Zerodha's KiteTicker and is recommended for simple scripts:
141
+ Blocks your main thread, similar to Zerodhas KiteTicker:
145
142
 
146
143
  ```python
147
- # This will block and run until stopped
148
144
  client.connect()
149
145
  ```
150
146
 
151
- #### Non-Blocking Connection
147
+ #### NonBlocking Connection
152
148
 
153
- Use this for more complex applications where you need to perform other tasks:
149
+ Run alongside your own `asyncio` code:
154
150
 
155
151
  ```python
156
- # Start the connection in the background
157
152
  client.connect_async()
158
-
159
- # Later, when you want to stop:
153
+ # … do other work …
160
154
  client.stop()
161
155
  ```
162
156
 
163
157
  ### Callbacks
164
158
 
165
- Set up callbacks to handle different events:
159
+ All callbacks are **plain `def`** functions. Inside them you can call `subscribe(...)`, which under the hood schedules the actual async work—so you never `await` in your callbacks.
166
160
 
167
161
  ```python
168
162
  def on_tick(ws, tick):
169
- """Called when a tick is received"""
170
- print(f"Received tick: {tick}")
163
+ print("Tick:", tick)
171
164
 
172
165
  def on_connect(ws):
173
- """Called when the connection is established"""
174
- print("Connected to the quotes server")
175
- # Subscribe to instruments
176
- ws.subscribe(["NSE:SBIN:3045"])
166
+ print("Connected!")
167
+ # fire‑and‑forget subscribe—no await needed
168
+ ws.subscribe([
169
+ "NSE:SBIN:3045",
170
+ "NSE:RELIANCE:2885"
171
+ ])
177
172
 
178
173
  def on_close(ws, code, reason):
179
- """Called when the connection is closed"""
180
- print(f"Connection closed with code {code}: {reason}")
181
- # Optional: Stop the client (if you want to exit)
182
- # ws.stop()
174
+ print(f"Connection closed [{code}]: {reason}")
175
+ ws.stop() # to prevent auto‑reconnect
183
176
 
184
177
  def on_error(ws, error):
185
- """Called when an error occurs"""
186
- print(f"Error: {error}")
178
+ print("Error:", error)
187
179
 
188
- # Set the callbacks
189
- client.on_tick = on_tick
180
+ client.on_tick = on_tick
190
181
  client.on_connect = on_connect
191
- client.on_close = on_close
192
- client.on_error = on_error
182
+ client.on_close = on_close
183
+ client.on_error = on_error
193
184
  ```
194
185
 
195
186
  ### Subscribing to Instruments
196
187
 
197
- Subscribe to receive market data for specific instruments:
188
+ Call `ws.subscribe([...])` directly; the SDK will batch large lists and send them over the socket:
198
189
 
199
190
  ```python
200
- # Inside an on_connect callback:
201
191
  def on_connect(ws):
202
- # Subscribe to a single instrument
203
- ws.subscribe(["NSE:SBIN:3045"])
204
-
205
- # Or subscribe to multiple instruments at once
192
+ # subscribe without await
206
193
  ws.subscribe([
207
194
  "NSE:SBIN:3045",
208
195
  "NSE:ICICIBANK:4963",
209
- "NSE:RELIANCE:2885"
196
+ "NSE:RELIANCE:2885",
210
197
  ])
211
198
  ```
212
199
 
213
- For large lists of instruments, the client will automatically batch them to avoid message size issues.
214
-
215
200
  ### Unsubscribing from Instruments
216
201
 
217
- To stop receiving data for specific instruments:
202
+ Similarly, plain call to `unsubscribe`:
218
203
 
219
204
  ```python
220
- # Unsubscribe from specific instruments
221
205
  ws.unsubscribe(["NSE:SBIN:3045", "NSE:ICICIBANK:4963"])
222
206
  ```
223
207
 
224
- ### Handling WebSocket Connection
225
-
226
- The WebSocket connection automatically attempts to reconnect with exponential backoff if disconnected. You don't need to handle this manually.
227
-
228
- To explicitly close the connection:
229
-
230
- ```python
231
- # In a blocking context:
232
- client.stop()
233
-
234
- # In an async context:
235
- await client.close()
236
- ```
237
-
238
- ### Quotes Client Examples
208
+ ### Complete Examples
239
209
 
240
- #### Complete Blocking Example
210
+ #### Blocking Example
241
211
 
242
212
  ```python
243
213
  import logging
244
214
  from wiz_trader import QuotesClient
245
215
 
246
- # Configure logging
247
- logging.basicConfig(level=logging.DEBUG)
216
+ logging.basicConfig(level=logging.INFO)
248
217
 
249
- # Initialize the client
250
218
  client = QuotesClient(
251
219
  base_url="wss://websocket-url/quotes",
252
220
  token="your-jwt-token"
253
221
  )
254
222
 
255
223
  def on_tick(ws, tick):
256
- """Process incoming market data"""
257
- logging.debug("Received tick: %s", tick)
224
+ logging.debug("Tick: %s", tick)
258
225
 
259
226
  def on_connect(ws):
260
- """Handle successful connection"""
261
- logging.info("Connected to quotes server")
262
- # Subscribe to instruments
263
- ws.subscribe(["NSE:SBIN:3045", "NSE:RELIANCE:2885"])
227
+ logging.info("Connected.")
228
+ ws.subscribe(["NSE:SBIN:3045", "NSE:RELIANCE:2885"]) # no await
264
229
 
265
230
  def on_close(ws, code, reason):
266
- """Handle connection closure"""
267
- logging.info("Connection closed: %s", reason)
231
+ logging.warning("Closed: %s", reason)
232
+ ws.stop()
268
233
 
269
234
  def on_error(ws, error):
270
- """Handle errors"""
271
- logging.error("Error occurred: %s", error)
235
+ logging.error("Error: %s", error)
272
236
 
273
- # Set callbacks
274
- client.on_tick = on_tick
237
+ client.on_tick = on_tick
275
238
  client.on_connect = on_connect
276
- client.on_close = on_close
277
- client.on_error = on_error
239
+ client.on_close = on_close
240
+ client.on_error = on_error
278
241
 
279
- # Connect and run (blocking call)
280
242
  try:
281
243
  client.connect()
282
244
  except KeyboardInterrupt:
283
- print("Interrupted by user, shutting down...")
284
245
  client.stop()
285
246
  ```
286
247
 
287
- #### Non-Blocking Example with Other Operations
248
+ #### NonBlocking Example
288
249
 
289
250
  ```python
290
251
  import asyncio
291
252
  import logging
292
- from wiz_trader import QuotesClient, WizzerClient
253
+ from wiz_trader import QuotesClient
293
254
 
294
255
  async def main():
295
- # Configure logging
296
256
  logging.basicConfig(level=logging.INFO)
297
-
298
- # Initialize the quotes client
299
- quotes_client = QuotesClient(
257
+ client = QuotesClient(
300
258
  base_url="wss://websocket-url/quotes",
301
259
  token="your-jwt-token"
302
260
  )
303
-
304
- # Initialize the REST API client
305
- wizzer_client = WizzerClient(
306
- base_url="https://api-url.in",
307
- token="your-jwt-token"
308
- )
309
-
310
- # Set up quotes callbacks
311
- quotes_client.on_tick = lambda ws, tick: logging.info(f"Tick: {tick}")
312
- quotes_client.on_connect = lambda ws: ws.subscribe(["NSE:SBIN:3045"])
313
-
314
- # Connect in non-blocking mode
315
- quotes_client.connect_async()
316
-
317
- # Perform other operations
318
- indices = await asyncio.to_thread(wizzer_client.get_indices, exchange="NSE")
319
- logging.info(f"Available indices: {[idx['name'] for idx in indices[:5]]}")
320
-
321
- # Wait for some time
261
+ client.on_tick = lambda ws, tick: logging.info(tick)
262
+ client.on_connect = lambda ws: ws.subscribe(["NSE:SBIN:3045"])
263
+ client.connect_async()
264
+
265
+ # Your other async work here...
322
266
  await asyncio.sleep(60)
323
-
324
- # Stop the quotes client
325
- quotes_client.stop()
267
+ client.stop()
326
268
 
327
- if __name__ == "__main__":
328
- asyncio.run(main())
269
+ asyncio.run(main())
329
270
  ```
330
271
 
331
272
  ## Wizzer Client
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wiz_trader"
7
- version = "0.10.0"
7
+ version = "0.11.0"
8
8
  description = "A Python SDK for connecting to the Wizzer."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name='wiz_trader',
5
- version='0.10.0',
5
+ version='0.11.0',
6
6
  description='A Python SDK for connecting to the Wizzer.',
7
7
  long_description=open('README.md').read() if open('README.md') else "",
8
8
  long_description_content_type='text/markdown',
@@ -3,6 +3,6 @@
3
3
  from .quotes import QuotesClient
4
4
  from .apis import WizzerClient
5
5
 
6
- __version__ = "0.10.0"
6
+ __version__ = "0.11.0"
7
7
 
8
8
  __all__ = ["QuotesClient", "WizzerClient"]