# Buggy code
async def read(
    self, n: int, timeout: TimeoutConfig = None, flag: TimeoutFlag = None
) -> bytes:
    if timeout is None:
        timeout = self.timeout

    while True:
        # Check our flag at the first possible moment, and use a fine
        # grained retry loop if we're not yet in read-timeout mode.
        should_raise = flag is None or flag.raise_on_read_timeout
        read_timeout = timeout.read_timeout if should_raise else 0.01
        try:
            data = await asyncio.wait_for(self.stream_reader.read(n), read_timeout)
            break
        except asyncio.TimeoutError:
            if should_raise:
                raise ReadTimeout() from None
            # FIX(py3.6): yield control back to the event loop to give it a chance
            # to cancel `.read(n)` before we retry.
            # This prevents concurrent `.read()` calls, which asyncio
            # doesn't seem to allow on 3.6.
            # See: https://github.com/encode/httpx/issues/382
            await asyncio.sleep(0)

    return data


# Traceback (RuntimeError)
Traceback (most recent call last):
File "/Users/primoz/PycharmProjects/orange3-imageanalytics/example.py", line 63, in <module>
asyncio.get_event_loop().run_until_complete(cl.embedd_batch())
File "/Users/primoz/miniconda3/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "/Users/primoz/PycharmProjects/orange3-imageanalytics/example.py", line 18, in embedd_batch
embeddings = await asyncio.gather(*requests)
File "/Users/primoz/PycharmProjects/orange3-imageanalytics/example.py", line 41, in _send_to_server
emb = await self._send_request(client, im, url)
File "/Users/primoz/PycharmProjects/orange3-imageanalytics/example.py", line 56, in _send_request
data=image
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/client.py", line 484, in post
trust_env=trust_env,
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/client.py", line 626, in request
trust_env=trust_env,
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/client.py", line 650, in send
trust_env=trust_env,
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/client.py", line 265, in _get_response
return await get_response(request)
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/middleware/redirect.py", line 31, in __call__
response = await get_response(request)
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/client.py", line 226, in get_response
request, verify=verify, cert=cert, timeout=timeout
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/dispatch/connection_pool.py", line 126, in send
raise exc
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/dispatch/connection_pool.py", line 121, in send
request, verify=verify, cert=cert, timeout=timeout
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/dispatch/connection.py", line 62, in send
response = await self.h2_connection.send(request, timeout=timeout)
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/dispatch/http2.py", line 52, in send
status_code, headers = await self.receive_response(stream_id, timeout)
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/dispatch/http2.py", line 171, in receive_response
event = await self.receive_event(stream_id, timeout)
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/dispatch/http2.py", line 206, in receive_event
data = await self.stream.read(self.READ_NUM_BYTES, timeout, flag=flag)
File "/Users/primoz/venv/orange/lib/python3.7/site-packages/httpx/concurrency/asyncio.py", line 114, in read
data = await asyncio.wait_for(self.stream_reader.read(n), read_timeout)
File "/Users/primoz/miniconda3/lib/python3.7/asyncio/tasks.py", line 416, in wait_for
return fut.result()
File "/Users/primoz/miniconda3/lib/python3.7/asyncio/streams.py", line 640, in read
await self._wait_for_data('read')
File "/Users/primoz/miniconda3/lib/python3.7/asyncio/streams.py", line 460, in _wait_for_data
f'{func_name}() called while another coroutine is '
RuntimeError: read() called while another coroutine is already waiting for incoming data

# Fixed code
async def read(
    self, n: int, timeout: TimeoutConfig = None, flag: TimeoutFlag = None
) -> bytes:
    if timeout is None:
        timeout = self.timeout

    while True:
        # Check our flag at the first possible moment, and use a fine
        # grained retry loop if we're not yet in read-timeout mode.
        should_raise = flag is None or flag.raise_on_read_timeout
        read_timeout = timeout.read_timeout if should_raise else 0.01
        try:
            async with self.read_lock:
                data = await asyncio.wait_for(self.stream_reader.read(n), read_timeout)
        except asyncio.TimeoutError:
            if should_raise:
                raise ReadTimeout() from None
            # FIX(py3.6): yield control back to the event loop to give it a chance
            # to cancel `.read(n)` before we retry.
            # This prevents concurrent `.read()` calls, which asyncio
            # doesn't seem to allow on 3.6.
            # See: https://github.com/encode/httpx/issues/382
            await asyncio.sleep(0)
        else:
            break

    return data