etcd3-py
etcd3-py copied to clipboard
setting a watch fails with AttributeError: 'ModelizedStreamResponse' object has no attribute 'raw'
- etcd3-py version: 0.1.6
- Python version: 3.7
- Operating System: linux
Description
I was trying to get a watch working in my app. It's currently complex, but if you have no idea why this is happening, I'll work on getting a stripped-down version working.
If it matters, I'm using an async client.
What I Did
Exception in thread Thread-1:
Traceback (most recent call last):
File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 283, in run
for event in self:
File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 356, in __iter__
if not self._resp or self._resp.raw.closed:
AttributeError: 'ModelizedStreamResponse' object has no attribute 'raw'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 284, in run
self.dispatch_event(event)
File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 338, in __exit__
self.stop()
File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 295, in stop
self._kill_response_stream()
File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 260, in _kill_response_stream
if not self._resp or (self._resp and self._resp.raw.closed):
AttributeError: 'ModelizedStreamResponse' object has no attribute 'raw'```
async stateful util not supported, yet.
I opened a issuse https://github.com/Revolution1/etcd3-py/issues/16 long time ago, if you need this feature, I can try starting working on it.
Is there a watch feature that does support async? I can maybe use that instead.
yes, you can use raw api client.watch_create instead
https://github.com/Revolution1/etcd3-py/blob/master/etcd3/stateful/watch.py#L386-L417
Hm. Given that I'm having difficulty understanding how it's all supposed to work, I should take you up on your offer to fix this feature for me. While you do that, I'll try and wrap my head around how the lower-level watch stuff works so I can maybe lend a hand.
okay
Any progress on this?
is there (failing) test code for this?
Meanwhile, this is how async watch works for me (in case someone may still need it):
def get_range_end(prefix):
return prefix[:-1] + chr(ord(prefix[-1]) + 1)
async def on_event(self, key, value, type):
# your K/V event processing code here
pass
async with etcd_client.watch_create(prefix, range_end=get_range_end(prefix)) as r:
async for msg in r:
log.info(msg)
if msg.events:
for event in msg.events:
try:
await on_event(event.kv.key, event.kv.value, event.type)
except Exception as e:
log.exception(f'Failed to process event : {event}')
This really should be in the documentation! The current docs give me absolutely no clue on how to use most of the async stuff.
@andr-c It is not correct way because it block event loop and it is no way to stop watch for async client, so until the author adds full async features supports we have no way to async client + watcher.