Skip to content

Conversation

@briluza
Copy link
Contributor

@briluza briluza commented Oct 22, 2025

Changes

  • Use httpx stream for streaming RTTF response
  • Optimize RTTF functionalities to yield line by line instead of storing it in memory
  • Update test cases
image

@jbabac
Copy link
Contributor

jbabac commented Oct 22, 2025

LGTM! Good job @briluza !

@briluza briluza merged commit 6ffe955 into release-2.6.0 Oct 22, 2025
12 checks passed
)
if should_wait:
log.info(f"Sleeping for {wait_for}s.")
time.sleep(wait_for)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sleep is going to happen after a subsequent GET request has already been made. This will likely cause a timeout.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ohh nice catch here! should be above before making request so every connection is fresh


should_wait = (
wait_for
and wait_for > 0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you checking if it is greater than 0? If wait_for is 0 then it will be False and checked in the previous line. I don't think wait_for can be negative given that it is the difference of the safe_after and now.

should_wait = (
wait_for
and wait_for > 0
and not (self.api.rate_limit and (self.product == "account-information"))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The not self.api.rate_limit is already checked in the _wait_time() call. Why check it here again? And how can the product be "account-information" in a class specifically only used for the Feeds products?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking this again, this should be removed as this was from the base class and this is specific for feeds.

yield line
except Exception as e:
self.latest_feeds_status_code = 500
yield {"status_ready": True, "error": str(e)}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If an exception occurs, this line will be yielded to the user. Is this what is desired?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

answer is related to my comment here #180 (comment)

for line in response.iter_lines():
if line:
yield line
except Exception as e:
Copy link

@kelvinatorr kelvinatorr Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than a blanket Exception don't you think it will be more useful to the user to capture specific httpx exceptions: https://www.python-httpx.org/exceptions/ so the error messages are more specific? If the exception happens during iter_lines() above. The "FATAL: Failed to start the feed generator in _make_request. Reason:" message will be shown, but it will be inaccurate because the iteration already started and the user already has jsonlines yielded to them.

Also if you catch HTTPStatusError you can use raise_for_status() so then you don't have to do the unusual thing of setting self.latest_feeds_status_code, yielding a throwaway line, and then having self.setStatus(self.latest_feeds_status_code) in _get_results() check the status.

Copy link
Contributor Author

@briluza briluza Oct 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, this answer the yield part on exception but rather doing that, I'll set the status and throw the exception as well to the user.

Aslo when calling setStatus, if its not a success status code then it will throw the exception and it will stop the execution before yielding back to user.

yield {"status_ready": True}

for line in response.iter_lines():
if line:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need this check. There should never be a double \n in the RTTF responses. And if there were, it shouldn't be hidden from the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh okay, thanks for the info!

user-agent:
- python-httpx/0.28.1
x-api-key:
- 4b02d-a4719-e33e7-93128-5a5ff

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should remove this api_key from this repo.

"""

from itertools import chain
import json

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import is unused

from itertools import zip_longest
from itertools import zip_longest, chain
from typing import Generator
from httpx import Client

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one too

Highlevel process:
httpx stream -> yield each json line -> check status code -> yield back data to client

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this sequence is right. Isn't it actually:

httpx stream ->  check status code -> yield back data to client -> repeat if 206

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 thanks for spotting this! redunant 'yield'

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

Successfully merging this pull request may close these issues.

4 participants