Open cnm13ryan opened 3 weeks ago
@cnm13ryan Thank you very much for your advice. Using tenacity is indeed an effective approach. However, I suggest defining a separate DDGSearchRatelimitException, and only retry when a DDGSearchRatelimitException is triggered, rather than retrying on any exception.
@cnm13ryan And, feel free to raise a PR :)
Describe the Bug
The original
DDGAPIWrapper
raises aDuckDuckGoSearchException
due to exceeding DuckDuckGo API's rate limits. This prevents the application from retrieving search results effectively.Error Message
Steps to Reproduce
Integrate the original
DDGAPIWrapper
class into your project.Invoke the
run
method multiple times rapidly, for example:The application raises a
DuckDuckGoSearchException
with the messageRatelimit
.Sample Code of the original
DDGAPIWrapper
:Expected Behavior
The
DDGAPIWrapper.run
method should perform DuckDuckGo searches and return the specified number of results without triggering rate limit errors, even under multiple concurrent requests.Actual Behavior
The method intermittently raises a
DuckDuckGoSearchException
with the messageRatelimit
, indicating that the application is sending too many requests to the DuckDuckGo API in a short period.Analysis
Cause: The original script lacks mechanisms to control the frequency of API requests. Rapid or concurrent calls to the
run
method exceed DuckDuckGo's rate limits, resulting in exceptions.Impact: Failed search operations disrupt the application's functionality, leading to an inability to retrieve necessary search results.
Proposed Solution
Enhance the
DDGAPIWrapper
by implementing rate limiting, retry mechanisms, and caching to prevent exceeding DuckDuckGo's API rate limits.Modifications in
DDGAPIWrapper
(Script 2):Introduced libraries for rate limiting (
aiolimiter
), caching (aiocache
), and retries (tenacity
).Defined
DuckDuckGoSearchException
to handle specific search-related errors.Implemented
AsyncLimiter
to restrict to 1 request per second.Utilized
tenacity
to retry failed requests with exponential backoff upon encountering rate limit exceptions.Added caching to store search results for 5 minutes, reducing redundant API calls.
Improved exception handling to differentiate between rate limit errors and other issues.
Changed the main execution to use the
cached_run
method, leveraging caching and enhanced functionalities.Modified
DDGAPIWrapper
:Outcome
The application seems to have successfully mitigated rate limit issues.
I am saying this because I am using models inferred by ollama API endpoints, such that I have encountered issues with respect to token counting, which ollama community is still tackling.
So, it would be grateful for anyone who is able to test this proposed solution and see whether it does solve problems relating to DDG while not introducing other errors.
But overall, some comments on the proposed fix:
The
AsyncLimiter
ensures that search requests do not exceed 1 request per second, adhering to DuckDuckGo's rate limits.The retry mechanism automatically handles transient rate limit errors by retrying failed requests with exponential backoff.
Caching reduces redundant API calls for identical queries, optimizing performance and further preventing rate limit breaches.