Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document issue: requests usage example has a bug #16

Open
awarecan opened this issue May 4, 2018 · 4 comments
Open

Document issue: requests usage example has a bug #16

awarecan opened this issue May 4, 2018 · 4 comments

Comments

@awarecan
Copy link

awarecan commented May 4, 2018

python 3.6
requests 2.18.4
sseclient-py 1.7

When using requests library, should use response.iter_content() as event source

response = requests.get(url, stream=True, allow_redirects=False, headers={'Accept': 'text/event-stream'})
client = sseclient.SSEClient(response.iter_content())
awarecan referenced this issue in theaquarium/python-nest May 4, 2018
…ream out of NestAuthAdd logic to handle connection closed by server
@reidmeyer
Copy link

bump. Would like to see the sseclient work with iter_content or httpx

@mpetazzoni
Copy link
Owner

I'm not sure I understand why this is necessary. Internally, sseclient iterates over the event source with a simple loop (https://github.com/mpetazzoni/sseclient/blob/master/sseclient/__init__.py#L48):

for chunk in self._event_source:
  # ...

This will in turn get an iterator from the requests.Response object by calling its __iter__ method (https://github.com/psf/requests/blob/main/requests/models.py#L751-L753), which calls iter_content() already:

def __iter__(self):
    """Allows you to use a response as an iterator."""
    return self.iter_content(128)

@reidmeyer
Copy link

For me, I bumped this because sseclient is throwing an error when i try to plug in my Response object from my async_asgi_testclient.
The Response object is from the http requests library.

Code like this:

        resp = await async_client.get("/streaming-egress/v1/trouble_tickets/", stream=True, headers=headers)
        client = sseclient.SSEClient(resp)
        for event in client.events():
            print(event)

this code throws an error

            client = sseclient.SSEClient(resp)
>           for event in client.events():

tests/test_api/test_basic_functionality.py:68: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
.venv/lib/python3.10/site-packages/sseclient/__init__.py:58: in events
    for chunk in self._read():
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sseclient.SSEClient object at 0x1079c4940>

    def _read(self):
        """Read the incoming event source stream and yield event chunks.
    
        Unfortunately it is possible for some servers to decide to break an
        event into multiple HTTP chunks in the response. It is thus necessary
        to correctly stitch together consecutive response chunks and find the
        SSE delimiter (empty new line) to yield full, correct event chunks."""
        data = b''
>       for chunk in self._event_source:
E       TypeError: iter() returned non-iterator of type 'async_generator'

.venv/lib/python3.10/site-packages/sseclient/__init__.py:48: TypeError

I am able to get streaming data out of the response using:

        async for line in resp.iter_content(1000):

which is why I bumped this issue about iter_content, thinking a level down it might work.

@mpetazzoni
Copy link
Owner

Ah, that's because your async client provides an async response that includes an async_generator, which don't work directly as iterators. You can probably wrap your response in an adapter that implements an iterator but handles the async for ... part.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants