Skip to content

Commit

Permalink
Merge pull request #15 from kevinheavey/missing-bits
Browse files Browse the repository at this point in the history
Missing bits
  • Loading branch information
kevinheavey authored Oct 10, 2022
2 parents 229d09b + 6b316d0 commit 25c8aee
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.7.0
current_version = 0.8.0
commit = True
tag = False

Expand Down
14 changes: 12 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
# Changelog

## [0.8.0] - 2022-10-10

### Changed

- `parse_websocket_message` now supports parsing an array of messages, and always returns a list [(#15)](https://github.com/kevinheavey/solders/pull/15)

### Fixed

- Add missing getters to `RpcBlockhash` [(#15)](https://github.com/kevinheavey/solders/pull/15)

## [0.7.0] - 2022-10-09

### Changed

- Replace `parse_<name>_maybe_json` funcs with `<name>MaybeJsonParsed` classes. Also fix bugs with parsing mixed responses.
- Make `batch_from_json` pure Rust instead of relying on the Python `from_json` method.
- Replace `parse_<name>_maybe_json` funcs with `<name>MaybeJsonParsed` classes. Also fix bugs with parsing mixed responses. [(#14)](https://github.com/kevinheavey/
- Make `batch_from_json` pure Rust instead of relying on the Python `from_json` method. [(#14)](https://github.com/kevinheavey/solders/pull/14)

## [0.6.0] - 2022-10-05

Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "solders"
version = "0.7.0"
version = "0.8.0"
edition = "2021"
include = ["/src", "/LICENSE", "/pyproject.toml"]
description = "Python binding to the Solana Rust SDK"
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
author = "Kevin Heavey"

# The full version, including alpha/beta/rc tags
release = "0.7.0"
release = "0.8.0"


# -- General configuration ---------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "solders"
version = "0.7.0"
version = "0.8.0"
description = "Python bindings for Solana Rust tools"
authors = ["kevinheavey <kevinheavey123@gmail.com>"]
license = "Apache"
Expand Down Expand Up @@ -29,7 +29,7 @@ build-backend = "maturin"

[project]
name = "solders"
version = "0.7.0"
version = "0.8.0"
description = "Python binding to the Solana Rust SDK"
authors = [ {name = "kevinheavey", email = "kevinheavey123@gmail.com"} ]
license = {file = "LICENSE"}
Expand Down
2 changes: 1 addition & 1 deletion python/solders/rpc/responses.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -2244,4 +2244,4 @@ RPCResult = Union[
def batch_to_json(resps: Sequence[RPCResult]) -> str: ...
def batch_from_json(raw: str, parsers: Sequence[Any]) -> List[RPCResult]: ...
def parse_notification(raw: str) -> Notification: ...
def parse_websocket_message(raw: str) -> WebsocketMessage: ...
def parse_websocket_message(raw: str) -> List[WebsocketMessage]: ...
33 changes: 28 additions & 5 deletions src/rpc/responses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use pyo3::{
PyClass, PyTypeInfo,
};
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr, FromInto, TryFromInto};
use serde_with::{serde_as, DisplayFromStr, FromInto, OneOrMany, TryFromInto};
use solana_sdk::{
clock::{Epoch, Slot, UnixTimestamp},
epoch_info::EpochInfo as EpochInfoOriginal,
Expand Down Expand Up @@ -395,6 +395,16 @@ impl IntoPy<PyObject> for WebsocketMessage {
}
}

#[serde_as]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct WebsocketMessages(#[serde_as(deserialize_as = "OneOrMany<_>")] Vec<WebsocketMessage>);

impl IntoPy<PyObject> for WebsocketMessages {
fn into_py(self, py: Python<'_>) -> PyObject {
self.0.into_py(py)
}
}

macro_rules! contextful_struct_def_eq {
($name:ident, $inner:ty) => {
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)]
Expand Down Expand Up @@ -1250,7 +1260,9 @@ contextful_resp_eq!(GetLargestAccountsResp, Vec<RpcAccountBalance>);
#[pyclass(module = "solders.rpc.responses", subclass)]
pub struct RpcBlockhash {
#[serde_as(as = "DisplayFromStr")]
#[pyo3(get)]
pub blockhash: SolderHash,
#[pyo3(get)]
pub last_valid_block_height: u64,
}

Expand Down Expand Up @@ -2673,7 +2685,7 @@ pub fn parse_notification(msg: &str) -> PyResult<Notification> {
serde_json::from_str(msg).map_err(to_py_err)
}

/// Parse a message received by a Solana websocket subscription.
/// Parse a message or array of messages received by a Solana websocket subscription.
///
/// Args:
/// msg (str): The raw message JSON.
Expand All @@ -2685,13 +2697,24 @@ pub fn parse_notification(msg: &str) -> PyResult<Notification> {
/// >>> from solders.rpc.responses import parse_websocket_message
/// >>> raw = '{ "jsonrpc": "2.0", "method": "rootNotification", "params": { "result": 4, "subscription": 0 } }'
/// >>> parse_websocket_message(raw)
/// RootNotification {
/// [RootNotification {
/// result: 4,
/// subscription: 0,
/// }
/// }]
/// >>> raw_multi = '[{"jsonrpc": "2.0", "result": 0, "id": 1}, {"jsonrpc": "2.0", "result": 1, "id": 2}]'
/// >>> parse_websocket_message(raw_multi)
/// [SubscriptionResult {
/// jsonrpc: TwoPointOh,
/// id: 1,
/// result: 0,
/// }, SubscriptionResult {
/// jsonrpc: TwoPointOh,
/// id: 2,
/// result: 1,
/// }]
///
#[pyfunction]
pub fn parse_websocket_message(msg: &str) -> PyResult<WebsocketMessage> {
pub fn parse_websocket_message(msg: &str) -> PyResult<WebsocketMessages> {
serde_json::from_str(msg).map_err(to_py_err)
}

Expand Down
18 changes: 11 additions & 7 deletions tests/test_rpc_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -2508,14 +2508,18 @@ def test_vote_notification() -> None:
def test_parse_ws_message() -> None:
raw_err = '{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid param: WrongSize"},"id":1}'
parsed_err = parse_websocket_message(raw_err)
assert isinstance(parsed_err, SubscriptionError)
assert isinstance(parsed_err.error, RpcError)
assert isinstance(parsed_err[0], SubscriptionError)
assert isinstance(parsed_err[0].error, RpcError)
raw_ok = '{ "jsonrpc": "2.0", "result": 23784, "id": 3 }'
parsed_ok = parse_websocket_message(raw_ok)
assert isinstance(parsed_ok, SubscriptionResult)
assert parsed_ok.result == 23784
assert parsed_ok.id == 3
assert isinstance(parsed_ok[0], SubscriptionResult)
assert parsed_ok[0].result == 23784
assert parsed_ok[0].id == 3
raw_notification = '{ "jsonrpc": "2.0", "method": "rootNotification", "params": { "result": 4, "subscription": 0 } }'
parsed_notification = parse_websocket_message(raw_notification)
assert isinstance(parsed_notification, RootNotification)
assert parsed_notification.result == 4
assert isinstance(parsed_notification[0], RootNotification)
assert parsed_notification[0].result == 4
raw_multi = '[{"jsonrpc": "2.0", "result": 0, "id": 1}, {"jsonrpc": "2.0", "result": 1, "id": 2}]'
parsed_multi = parse_websocket_message(raw_multi)
assert len(parsed_multi) == 2
assert isinstance(parsed_multi[0], SubscriptionResult)

0 comments on commit 25c8aee

Please sign in to comment.