-
Notifications
You must be signed in to change notification settings - Fork 28
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
Fix/pagination next key #333
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,41 @@ | ||||||||||
import asyncio | ||||||||||
|
||||||||||
from pyinjective.async_client import AsyncClient | ||||||||||
from pyinjective.client.model.pagination import PaginationOption | ||||||||||
from pyinjective.core.network import Network | ||||||||||
|
||||||||||
|
||||||||||
async def main() -> None: | ||||||||||
network = Network.testnet() | ||||||||||
client = AsyncClient(network) | ||||||||||
pagination = PaginationOption( | ||||||||||
limit=10, | ||||||||||
count_total=True, | ||||||||||
) | ||||||||||
first_result = await client.fetch_total_supply( | ||||||||||
pagination=pagination, | ||||||||||
) | ||||||||||
print(f"First result:\n{first_result}") | ||||||||||
|
||||||||||
next_page_key = first_result["pagination"]["nextKey"] | ||||||||||
|
||||||||||
for i in range(5): | ||||||||||
if next_page_key == "": | ||||||||||
break | ||||||||||
|
||||||||||
next_request_pagination = PaginationOption( | ||||||||||
limit=pagination.limit, | ||||||||||
count_total=pagination.count_total, | ||||||||||
encoded_page_key=next_page_key, | ||||||||||
) | ||||||||||
|
||||||||||
next_result = await client.fetch_total_supply( | ||||||||||
pagination=next_request_pagination, | ||||||||||
) | ||||||||||
print(f"Page {i+2} result:\n{next_result}") | ||||||||||
|
||||||||||
next_page_key = next_result["pagination"]["nextKey"] | ||||||||||
|
||||||||||
|
||||||||||
if __name__ == "__main__": | ||||||||||
asyncio.get_event_loop().run_until_complete(main()) | ||||||||||
Comment on lines
+40
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider using - asyncio.get_event_loop().run_until_complete(main())
+ asyncio.run(main()) Committable suggestion
Suggested change
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import base64 | ||
from typing import Optional | ||
|
||
from pyinjective.proto.cosmos.base.query.v1beta1 import pagination_pb2 as pagination_pb | ||
|
@@ -6,7 +7,7 @@ | |
class PaginationOption: | ||
def __init__( | ||
self, | ||
key: Optional[str] = None, | ||
encoded_page_key: Optional[str] = None, | ||
skip: Optional[int] = None, | ||
limit: Optional[int] = None, | ||
start_time: Optional[int] = None, | ||
|
@@ -17,7 +18,7 @@ def __init__( | |
to_number: Optional[int] = None, | ||
): | ||
super().__init__() | ||
self.key = key | ||
self.encoded_page_key = encoded_page_key | ||
self.skip = skip | ||
self.limit = limit | ||
self.start_time = start_time | ||
|
@@ -30,8 +31,9 @@ def __init__( | |
def create_pagination_request(self) -> pagination_pb.PageRequest: | ||
page_request = pagination_pb.PageRequest() | ||
|
||
if self.key is not None: | ||
page_request.key = self.key.encode() | ||
if self.encoded_page_key is not None and self.encoded_page_key != "": | ||
page_key = base64.b64decode(self.encoded_page_key) | ||
page_request.key = page_key | ||
Comment on lines
+34
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tip Codebase Verification The
Please ensure to handle potential exceptions from incorrect base64 strings to avoid runtime errors. Analysis chainProper handling of base64 decoding for the page key. Ensure to handle potential exceptions from incorrect base64 strings. Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Verify exception handling for base64 decoding in `create_pagination_request`.
# Test: Search for exception handling patterns around base64 decoding.
ast-grep --lang python --pattern $'def create_pagination_request($_) {
try {
$$$
base64.b64decode($_)
$$$
} catch ($_){
$$$
}
}'
Length of output: 496 Script: #!/bin/bash
# Description: Locate the `create_pagination_request` method and check for exception handling around base64 decoding.
# Step 1: Locate the `create_pagination_request` method.
ast-grep --lang python --pattern 'def create_pagination_request($_) {
$$$
}' > create_pagination_request_location.txt
# Step 2: Check for try-except blocks within the `create_pagination_request` method.
if [ -s create_pagination_request_location.txt ]; then
# Extract the file path from the location result
file_path=$(head -n 1 create_pagination_request_location.txt | cut -d: -f1)
# Search for try-except blocks within the located method
ast-grep --lang python --pattern 'def create_pagination_request($_) {
$$$
try:
$$$
except $_:
$$$
}' $file_path
else
echo "Method create_pagination_request not found."
fi
Length of output: 695 Script: #!/bin/bash
# Description: Locate the `create_pagination_request` method and check for exception handling around base64 decoding.
# Step 1: Locate the `create_pagination_request` method.
ast-grep --lang python --pattern 'def create_pagination_request($_):' > create_pagination_request_location.txt
# Step 2: Check for try-except blocks within the `create_pagination_request` method.
if [ -s create_pagination_request_location.txt ]; then
# Extract the file path from the location result
file_path=$(head -n 1 create_pagination_request_location.txt | cut -d: -f1)
# Search for try-except blocks within the located method
ast-grep --lang python --pattern 'try:
$$$
except $_:
$$$' $file_path
else
echo "Method create_pagination_request not found."
fi
Length of output: 220 Script: #!/bin/bash
# Description: Search for the `create_pagination_request` method and inspect for exception handling around base64 decoding.
# Step 1: Search for the `create_pagination_request` method definition.
rg 'def create_pagination_request' > create_pagination_request_location.txt
# Step 2: Check for try-except blocks within the located method.
if [ -s create_pagination_request_location.txt ]; then
# Extract the file path from the location result
file_path=$(head -n 1 create_pagination_request_location.txt | cut -d: -f1)
# Search for try-except blocks within the located method
rg -A 10 'def create_pagination_request' $file_path | rg 'try:|except'
else
echo "Method create_pagination_request not found."
fi
Length of output: 307 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a fair point, but wonder how could this happen. Think it's better to crash if some of these exceptions are risen There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @nicolasbaum, I understand your perspective on preferring the application to crash in cases where exceptions like incorrect base64 strings occur, as it makes such issues more visible and likely to be fixed promptly. However, it's also worth considering the user experience, especially in a production environment where such crashes could lead to disruptions in service. An alternative approach could be to log these errors comprehensively while still allowing the application to continue running. This way, the issues are documented and can be addressed without immediately impacting end users. Would you like to explore setting up detailed logging for these exceptions, or would you prefer to proceed with the current approach where the application will crash under these circumstances? This decision can be aligned with how critical the stability of this feature is and the expected stability of the input data. Let me know how you'd like to proceed or if there's any other aspect of the implementation you'd like to discuss! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think this is a fair point. If there was an error in the base64 encoded string, the error would have happened before, when the response was converted into its JSON representation. Since we reached this point, we are sure the encoded pagination key can be decoded without issues. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
if self.skip is not None: | ||
page_request.offset = self.skip | ||
if self.limit is not None: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[tool.poetry] | ||
name = "injective-py" | ||
version = "1.5.2" | ||
version = "1.5.3" | ||
description = "Injective Python SDK, with Exchange API Client" | ||
authors = ["Injective Labs <[email protected]>"] | ||
license = "Apache-2.0" | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import base64 | ||
|
||
from pyinjective.client.model.pagination import PaginationOption | ||
|
||
|
||
class TestPaginationOption: | ||
def test_create_pagination_request(self): | ||
next_page_key = b"next page key" | ||
encoded_next_page_key = base64.b64encode(next_page_key).decode() | ||
pagination_option = PaginationOption( | ||
encoded_page_key=encoded_next_page_key, | ||
skip=5, | ||
limit=10, | ||
start_time=3, | ||
end_time=4, | ||
reverse=False, | ||
count_total=True, | ||
from_number=105, | ||
to_number=135, | ||
) | ||
|
||
page_request = pagination_option.create_pagination_request() | ||
assert page_request.key == next_page_key | ||
assert page_request.offset == pagination_option.skip | ||
assert page_request.limit == pagination_option.limit | ||
assert not page_request.reverse | ||
assert page_request.count_total | ||
|
||
def test_next_key_is_none_for_empty_encoded_page_key(self): | ||
pagination_option = PaginationOption( | ||
encoded_page_key="", | ||
) | ||
page_request = pagination_option.create_pagination_request() | ||
|
||
assert page_request.key == b"" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optimize the pagination loop to handle potential exceptions and ensure robustness.