Skip to content
Merged
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,23 @@

All notable changes to this project will be documented in this file.

## [1.5.0] - 9999-99-99
## [1.6.0] - 9999-99-99
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Add surrounding blank lines for headings.

+
## [1.6.0] - 9999-99-99
+

Headings should be surrounded by blank lines to enhance the readability and structure of the document.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
## [1.6.0] - 9999-99-99
## [1.6.0] - 9999-99-99

### Added
- Added support for all queries in the chain 'tendermint' module
- Added support for all queries in the IBC Transfer module

### Changed
- Refactored cookies management logic to use all gRPC calls' responses to update the current cookies

## [1.5.0] - 2024-04-19
### Changed
- Refactoring in Network class to support mixed secure and insecure endpoints.
- Marked the Network parameter `use_secure_connection` as deprecated.

## [1.4.2] - 2024-03-19
### Changed
- Updated `aiohttp` dependency version to ">=3.9.2" to solve a security vulnerability detected by Dependabot

Comment on lines +5 to +21
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ensure consistency in list item markers.

- * Synchronized markets and tokens config files to add KIRA/INJ, NINJA/INJ, KATANA/INJ, BRETT/INJ and nINJ/INJ spot markets
+ - Synchronized markets and tokens config files to add KIRA/INJ, NINJA/INJ, KATANA/INJ, BRETT/INJ and nINJ/INJ spot markets

The use of asterisks (*) for list items is inconsistent with the use of dashes (-) in other parts of the document. Consider standardizing to dashes for all list items to maintain consistency.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
## [1.6.0] - 9999-99-99
### Added
- Added support for all queries in the chain 'tendermint' module
- Added support for all queries in the IBC Transfer module
### Changed
- Refactored cookies management logic to use all gRPC calls' responses to update the current cookies
## [1.5.0] - 2024-04-19
### Changed
- Refactoring in Network class to support mixed secure and insecure endpoints.
- Marked the Network parameter `use_secure_connection` as deprecated.
## [1.4.2] - 2024-03-19
### Changed
- Updated `aiohttp` dependency version to ">=3.9.2" to solve a security vulnerability detected by Dependabot
## [1.6.0] - 9999-99-99
### Added
- Added support for all queries in the chain 'tendermint' module
- Added support for all queries in the IBC Transfer module
### Changed
- Refactored cookies management logic to use all gRPC calls' responses to update the current cookies
- Synchronized markets and tokens config files to add KIRA/INJ, NINJA/INJ, KATANA/INJ, BRETT/INJ and nINJ/INJ spot markets
## [1.5.0] - 2024-04-19
### Changed
- Refactoring in Network class to support mixed secure and insecure endpoints.
- Marked the Network parameter `use_secure_connection` as deprecated.
## [1.4.2] - 2024-03-19
### Changed
- Updated `aiohttp` dependency version to ">=3.9.2" to solve a security vulnerability detected by Dependabot

## [1.4.1] - 2024-03-12
### Changed
- Updates example scripts that were still using deprecated methods
Expand Down
385 changes: 193 additions & 192 deletions poetry.lock

Large diffs are not rendered by default.

33 changes: 12 additions & 21 deletions pyinjective/async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ def __init__(
self,
network: Network,
insecure: Optional[bool] = None,
credentials=grpc.ssl_channel_credentials(),
credentials=None,
):
# the `insecure` parameter is ignored and will be deprecated soon. The value is taken directly from `network`
if insecure is not None:
Expand All @@ -104,6 +104,13 @@ def __init__(
DeprecationWarning,
stacklevel=2,
)
# the `credentials` parameter is ignored and will be deprecated soon. The value is taken directly from `network`
if credentials is not None:
warn(
"credentials parameter in AsyncClient is no longer used and will be deprecated",
DeprecationWarning,
stacklevel=2,
)

self.addr = ""
self.number = 0
Comment on lines 104 to 116
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tip

Codebase Verification

The output from the executed script reveals extensive usage of the credentials parameter across various files in the codebase. This includes direct references in the AsyncClient class within test_async_client_deprecation_warnings.py, as well as numerous instances across various protocol buffer (gRPC) service files. The references in the protocol buffer files are mostly related to channel_credentials and call_credentials, which are standard parameters for gRPC channel and call configurations and do not directly relate to the credentials parameter being deprecated in the AsyncClient class.

However, the direct usage of the credentials parameter in the test_async_client_deprecation_warnings.py suggests that there might be a need to update the test cases to align with the new method of handling credentials through the network object, as indicated in the original review comment.

Given this information, it is clear that while the deprecation of the credentials parameter in the AsyncClient class is handled, there are still dependencies in the test suite that require attention to fully migrate away from using this deprecated parameter.

Conclusion:

  • The deprecation of the credentials parameter in the AsyncClient class is correctly implemented with appropriate warnings.
  • The test suite (test_async_client_deprecation_warnings.py) still uses the deprecated credentials parameter, which needs to be updated to use the new method through the network object.

Action Items:

  • Update the test suite to remove direct usage of the deprecated credentials parameter and ensure it aligns with the new implementation.
Analysis chain

📝 NOTE
This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [98-113]

Deprecation of credentials parameter handled correctly with warnings.

Ensure that all dependent code has been updated to use the new method of handling credentials through the network object.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Search for any remaining direct uses of the `credentials` parameter in the codebase.
rg --type py 'credentials='

Length of output: 125138

Expand All @@ -112,11 +119,7 @@ def __init__(
self.network = network

# chain stubs
self.chain_channel = (
grpc.aio.secure_channel(network.grpc_endpoint, credentials)
if (network.use_secure_connection and credentials is not None)
else grpc.aio.insecure_channel(network.grpc_endpoint)
)
self.chain_channel = self.network.create_chain_grpc_channel()

self.stubCosmosTendermint = tendermint_query_grpc.ServiceStub(self.chain_channel)
self.stubAuth = auth_query_grpc.QueryStub(self.chain_channel)
Expand All @@ -128,11 +131,7 @@ def __init__(
self.timeout_height = 1

# exchange stubs
self.exchange_channel = (
grpc.aio.secure_channel(network.grpc_exchange_endpoint, credentials)
if (network.use_secure_connection and credentials is not None)
else grpc.aio.insecure_channel(network.grpc_exchange_endpoint)
)
self.exchange_channel = self.network.create_exchange_grpc_channel()
self.stubMeta = exchange_meta_rpc_grpc.InjectiveMetaRPCStub(self.exchange_channel)
self.stubExchangeAccount = exchange_accounts_rpc_grpc.InjectiveAccountsRPCStub(self.exchange_channel)
self.stubOracle = oracle_rpc_grpc.InjectiveOracleRPCStub(self.exchange_channel)
Expand All @@ -145,18 +144,10 @@ def __init__(
self.stubPortfolio = portfolio_rpc_grpc.InjectivePortfolioRPCStub(self.exchange_channel)

# explorer stubs
self.explorer_channel = (
grpc.aio.secure_channel(network.grpc_explorer_endpoint, credentials)
if (network.use_secure_connection and credentials is not None)
else grpc.aio.insecure_channel(network.grpc_explorer_endpoint)
)
self.explorer_channel = self.network.create_explorer_grpc_channel()
self.stubExplorer = explorer_rpc_grpc.InjectiveExplorerRPCStub(self.explorer_channel)

self.chain_stream_channel = (
grpc.aio.secure_channel(network.chain_stream_endpoint, credentials)
if (network.use_secure_connection and credentials is not None)
else grpc.aio.insecure_channel(network.chain_stream_endpoint)
)
self.chain_stream_channel = self.network.create_chain_stream_grpc_channel()
self.chain_stream_stub = stream_rpc_grpc.StreamStub(channel=self.chain_stream_channel)

self._timeout_height_sync_task = None
Expand Down
112 changes: 102 additions & 10 deletions pyinjective/core/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
from abc import ABC, abstractmethod
from http.cookies import SimpleCookie
from typing import List, Optional
from warnings import warn

import grpc
from grpc import ChannelCredentials
from grpc.aio import Call, Metadata


Expand Down Expand Up @@ -115,8 +118,20 @@ def __init__(
chain_cookie_assistant: CookieAssistant,
exchange_cookie_assistant: CookieAssistant,
explorer_cookie_assistant: CookieAssistant,
use_secure_connection: bool = False,
use_secure_connection: Optional[bool] = None,
grpc_channel_credentials: Optional[ChannelCredentials] = None,
grpc_exchange_channel_credentials: Optional[ChannelCredentials] = None,
grpc_explorer_channel_credentials: Optional[ChannelCredentials] = None,
chain_stream_channel_credentials: Optional[ChannelCredentials] = None,
):
# the `use_secure_connection` parameter is ignored and will be deprecated soon.
if use_secure_connection is not None:
warn(
"use_secure_connection parameter in Network is no longer used and will be deprecated",
DeprecationWarning,
stacklevel=2,
)

self.lcd_endpoint = lcd_endpoint
self.tm_websocket_endpoint = tm_websocket_endpoint
self.grpc_endpoint = grpc_endpoint
Expand All @@ -129,7 +144,10 @@ def __init__(
self.chain_cookie_assistant = chain_cookie_assistant
self.exchange_cookie_assistant = exchange_cookie_assistant
self.explorer_cookie_assistant = explorer_cookie_assistant
self.use_secure_connection = use_secure_connection
self.grpc_channel_credentials = grpc_channel_credentials
self.grpc_exchange_channel_credentials = grpc_exchange_channel_credentials
self.grpc_explorer_channel_credentials = grpc_explorer_channel_credentials
self.chain_stream_channel_credentials = chain_stream_channel_credentials

@classmethod
def devnet(cls):
Expand Down Expand Up @@ -157,6 +175,11 @@ def testnet(cls, node="lb"):
if node not in nodes:
raise ValueError("Must be one of {}".format(nodes))

grpc_channel_credentials = grpc.ssl_channel_credentials()
grpc_exchange_channel_credentials = grpc.ssl_channel_credentials()
grpc_explorer_channel_credentials = grpc.ssl_channel_credentials()
chain_stream_channel_credentials = grpc.ssl_channel_credentials()

if node == "lb":
lcd_endpoint = "https://testnet.sentry.lcd.injective.network:443"
tm_websocket_endpoint = "wss://testnet.sentry.tm.injective.network:443/websocket"
Expand All @@ -167,7 +190,6 @@ def testnet(cls, node="lb"):
chain_cookie_assistant = BareMetalLoadBalancedCookieAssistant()
exchange_cookie_assistant = BareMetalLoadBalancedCookieAssistant()
explorer_cookie_assistant = BareMetalLoadBalancedCookieAssistant()
use_secure_connection = True
else:
lcd_endpoint = "https://testnet.lcd.injective.network:443"
tm_websocket_endpoint = "wss://testnet.tm.injective.network:443/websocket"
Expand All @@ -178,7 +200,6 @@ def testnet(cls, node="lb"):
chain_cookie_assistant = DisabledCookieAssistant()
exchange_cookie_assistant = DisabledCookieAssistant()
explorer_cookie_assistant = DisabledCookieAssistant()
use_secure_connection = True

return cls(
lcd_endpoint=lcd_endpoint,
Expand All @@ -193,7 +214,10 @@ def testnet(cls, node="lb"):
chain_cookie_assistant=chain_cookie_assistant,
exchange_cookie_assistant=exchange_cookie_assistant,
explorer_cookie_assistant=explorer_cookie_assistant,
use_secure_connection=use_secure_connection,
grpc_channel_credentials=grpc_channel_credentials,
grpc_exchange_channel_credentials=grpc_exchange_channel_credentials,
grpc_explorer_channel_credentials=grpc_explorer_channel_credentials,
chain_stream_channel_credentials=chain_stream_channel_credentials,
)

@classmethod
Expand All @@ -213,7 +237,10 @@ def mainnet(cls, node="lb"):
chain_cookie_assistant = BareMetalLoadBalancedCookieAssistant()
exchange_cookie_assistant = BareMetalLoadBalancedCookieAssistant()
explorer_cookie_assistant = BareMetalLoadBalancedCookieAssistant()
use_secure_connection = True
grpc_channel_credentials = grpc.ssl_channel_credentials()
grpc_exchange_channel_credentials = grpc.ssl_channel_credentials()
grpc_explorer_channel_credentials = grpc.ssl_channel_credentials()
chain_stream_channel_credentials = grpc.ssl_channel_credentials()

return cls(
lcd_endpoint=lcd_endpoint,
Expand All @@ -228,7 +255,10 @@ def mainnet(cls, node="lb"):
chain_cookie_assistant=chain_cookie_assistant,
exchange_cookie_assistant=exchange_cookie_assistant,
explorer_cookie_assistant=explorer_cookie_assistant,
use_secure_connection=use_secure_connection,
grpc_channel_credentials=grpc_channel_credentials,
grpc_exchange_channel_credentials=grpc_exchange_channel_credentials,
grpc_explorer_channel_credentials=grpc_explorer_channel_credentials,
chain_stream_channel_credentials=chain_stream_channel_credentials,
)

@classmethod
Expand All @@ -246,7 +276,6 @@ def local(cls):
chain_cookie_assistant=DisabledCookieAssistant(),
exchange_cookie_assistant=DisabledCookieAssistant(),
explorer_cookie_assistant=DisabledCookieAssistant(),
use_secure_connection=False,
)

@classmethod
Expand All @@ -263,8 +292,20 @@ def custom(
chain_cookie_assistant: Optional[CookieAssistant] = None,
exchange_cookie_assistant: Optional[CookieAssistant] = None,
explorer_cookie_assistant: Optional[CookieAssistant] = None,
use_secure_connection: bool = False,
use_secure_connection: Optional[bool] = None,
grpc_channel_credentials: Optional[ChannelCredentials] = None,
grpc_exchange_channel_credentials: Optional[ChannelCredentials] = None,
grpc_explorer_channel_credentials: Optional[ChannelCredentials] = None,
chain_stream_channel_credentials: Optional[ChannelCredentials] = None,
):
# the `use_secure_connection` parameter is ignored and will be deprecated soon.
if use_secure_connection is not None:
warn(
"use_secure_connection parameter in Network is no longer used and will be deprecated",
DeprecationWarning,
stacklevel=2,
)

chain_assistant = chain_cookie_assistant or DisabledCookieAssistant()
exchange_assistant = exchange_cookie_assistant or DisabledCookieAssistant()
explorer_assistant = explorer_cookie_assistant or DisabledCookieAssistant()
Expand All @@ -281,8 +322,59 @@ def custom(
chain_cookie_assistant=chain_assistant,
exchange_cookie_assistant=exchange_assistant,
explorer_cookie_assistant=explorer_assistant,
use_secure_connection=use_secure_connection,
grpc_channel_credentials=grpc_channel_credentials,
grpc_exchange_channel_credentials=grpc_exchange_channel_credentials,
grpc_explorer_channel_credentials=grpc_explorer_channel_credentials,
chain_stream_channel_credentials=chain_stream_channel_credentials,
)

@classmethod
def custom_chain_and_public_indexer_mainnet(
cls,
lcd_endpoint,
tm_websocket_endpoint,
grpc_endpoint,
chain_stream_endpoint,
chain_cookie_assistant: Optional[CookieAssistant] = None,
):
mainnet_network = cls.mainnet()

return cls.custom(
lcd_endpoint=lcd_endpoint,
tm_websocket_endpoint=tm_websocket_endpoint,
grpc_endpoint=grpc_endpoint,
grpc_exchange_endpoint=mainnet_network.grpc_exchange_endpoint,
grpc_explorer_endpoint=mainnet_network.grpc_explorer_endpoint,
chain_stream_endpoint=chain_stream_endpoint,
chain_id="injective-1",
env="mainnet",
chain_cookie_assistant=chain_cookie_assistant or DisabledCookieAssistant(),
exchange_cookie_assistant=mainnet_network.exchange_cookie_assistant,
explorer_cookie_assistant=mainnet_network.explorer_cookie_assistant,
grpc_channel_credentials=None,
grpc_exchange_channel_credentials=mainnet_network.grpc_exchange_channel_credentials,
grpc_explorer_channel_credentials=mainnet_network.grpc_explorer_channel_credentials,
chain_stream_channel_credentials=None,
)

def string(self):
return self.env

def create_chain_grpc_channel(self) -> grpc.Channel:
return self._create_grpc_channel(self.grpc_endpoint, self.grpc_channel_credentials)

def create_exchange_grpc_channel(self) -> grpc.Channel:
return self._create_grpc_channel(self.grpc_exchange_endpoint, self.grpc_exchange_channel_credentials)

def create_explorer_grpc_channel(self) -> grpc.Channel:
return self._create_grpc_channel(self.grpc_explorer_endpoint, self.grpc_explorer_channel_credentials)

def create_chain_stream_grpc_channel(self) -> grpc.Channel:
return self._create_grpc_channel(self.chain_stream_endpoint, self.chain_stream_channel_credentials)

def _create_grpc_channel(self, endpoint: str, credentials: Optional[ChannelCredentials]) -> grpc.Channel:
if credentials is None:
channel = grpc.aio.insecure_channel(endpoint)
else:
channel = grpc.aio.secure_channel(endpoint, credentials)
return channel
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "injective-py"
version = "1.5.0-pre"
version = "1.6.0-pre"
description = "Injective Python SDK, with Exchange API Client"
authors = ["Injective Labs <[email protected]>"]
license = "Apache-2.0"
Expand Down
54 changes: 54 additions & 0 deletions tests/core/test_network_deprecation_warnings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from warnings import catch_warnings

from pyinjective.core.network import DisabledCookieAssistant, Network


class TestNetworkDeprecationWarnings:
def test_use_secure_connection_parameter_deprecation_warning(self):
with catch_warnings(record=True) as all_warnings:
Network(
lcd_endpoint="lcd_endpoint",
tm_websocket_endpoint="tm_websocket_endpoint",
grpc_endpoint="grpc_endpoint",
grpc_exchange_endpoint="grpc_exchange_endpoint",
grpc_explorer_endpoint="grpc_explorer_endpoint",
chain_stream_endpoint="chain_stream_endpoint",
chain_id="chain_id",
fee_denom="fee_denom",
env="env",
chain_cookie_assistant=DisabledCookieAssistant(),
exchange_cookie_assistant=DisabledCookieAssistant(),
explorer_cookie_assistant=DisabledCookieAssistant(),
use_secure_connection=True,
)

deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)]
assert len(deprecation_warnings) == 1
assert (
str(deprecation_warnings[0].message)
== "use_secure_connection parameter in Network is no longer used and will be deprecated"
)

def test_use_secure_connection_parameter_in_custom_network_deprecation_warning(self):
with catch_warnings(record=True) as all_warnings:
Network.custom(
lcd_endpoint="lcd_endpoint",
tm_websocket_endpoint="tm_websocket_endpoint",
grpc_endpoint="grpc_endpoint",
grpc_exchange_endpoint="grpc_exchange_endpoint",
grpc_explorer_endpoint="grpc_explorer_endpoint",
chain_stream_endpoint="chain_stream_endpoint",
chain_id="chain_id",
env="env",
chain_cookie_assistant=DisabledCookieAssistant(),
exchange_cookie_assistant=DisabledCookieAssistant(),
explorer_cookie_assistant=DisabledCookieAssistant(),
use_secure_connection=True,
)

deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)]
assert len(deprecation_warnings) == 1
assert (
str(deprecation_warnings[0].message)
== "use_secure_connection parameter in Network is no longer used and will be deprecated"
)
17 changes: 16 additions & 1 deletion tests/test_async_client_deprecation_warnings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from warnings import catch_warnings

import grpc
import pytest

from pyinjective.async_client import AsyncClient
Expand Down Expand Up @@ -586,7 +587,7 @@ async def test_get_oracle_prices_deprecation_warning(
assert str(deprecation_warnings[0].message) == "This method is deprecated. Use fetch_oracle_price instead"

@pytest.mark.asyncio
async def test_stream_keepalive_deprecation_warning(
async def test_stream_oracle_prices_deprecation_warning(
self,
oracle_servicer,
):
Expand Down Expand Up @@ -1707,3 +1708,17 @@ async def test_get_latest_block_deprecation_warning(
deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)]
assert len(deprecation_warnings) == 1
assert str(deprecation_warnings[0].message) == "This method is deprecated. Use fetch_latest_block instead"

def test_credentials_parameter_deprecation_warning(
self,
auth_servicer,
):
with catch_warnings(record=True) as all_warnings:
AsyncClient(network=Network.local(), credentials=grpc.ssl_channel_credentials())

deprecation_warnings = [warning for warning in all_warnings if issubclass(warning.category, DeprecationWarning)]
assert len(deprecation_warnings) == 1
assert (
str(deprecation_warnings[0].message)
== "credentials parameter in AsyncClient is no longer used and will be deprecated"
)