[hermes] add utoipa for API docs (#990)
* [hermes] add utoipa for docs * fix build * format
This commit is contained in:
parent
9e4242a20e
commit
61e29ac166
|
@ -1173,6 +1173,15 @@ dependencies = [
|
|||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-next"
|
||||
version = "2.0.0"
|
||||
|
@ -1183,6 +1192,17 @@ dependencies = [
|
|||
"dirs-sys-next",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys-next"
|
||||
version = "0.1.2"
|
||||
|
@ -1781,6 +1801,8 @@ dependencies = [
|
|||
"strum",
|
||||
"tokio",
|
||||
"tower-http",
|
||||
"utoipa",
|
||||
"utoipa-swagger-ui",
|
||||
"wormhole-sdk",
|
||||
]
|
||||
|
||||
|
@ -2070,6 +2092,7 @@ checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
|
|||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.0",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2969,6 +2992,16 @@ version = "0.3.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
|
@ -4252,6 +4285,41 @@ dependencies = [
|
|||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed"
|
||||
version = "6.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661"
|
||||
dependencies = [
|
||||
"rust-embed-impl",
|
||||
"rust-embed-utils",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "6.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.66",
|
||||
"quote 1.0.31",
|
||||
"rust-embed-utils",
|
||||
"shellexpand",
|
||||
"syn 2.0.26",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "7.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74"
|
||||
dependencies = [
|
||||
"sha2 0.10.7",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
|
@ -4414,6 +4482,15 @@ dependencies = [
|
|||
"cipher 0.4.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.22"
|
||||
|
@ -4727,6 +4804,15 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde"
|
||||
|
||||
[[package]]
|
||||
name = "shellexpand"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4"
|
||||
dependencies = [
|
||||
"dirs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
|
@ -6057,6 +6143,15 @@ dependencies = [
|
|||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.13"
|
||||
|
@ -6157,6 +6252,47 @@ version = "0.7.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||
|
||||
[[package]]
|
||||
name = "utoipa"
|
||||
version = "3.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c624186f22e625eb8faa777cb33d34cd595aa16d1742aa1d8b6cf35d3e4dda9"
|
||||
dependencies = [
|
||||
"indexmap 2.0.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"utoipa-gen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utoipa-gen"
|
||||
version = "3.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9ce5f21ca77e010f5283fa791c6ab892c68b3668a1bdc6b7ac6cf978f5d5b30"
|
||||
dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2 1.0.66",
|
||||
"quote 1.0.31",
|
||||
"regex",
|
||||
"syn 2.0.26",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utoipa-swagger-ui"
|
||||
version = "3.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4602d7100d3cfd8a086f30494e68532402ab662fa366c9d201d677e33cee138d"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"mime_guess",
|
||||
"regex",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"utoipa",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "value-bag"
|
||||
version = "1.4.1"
|
||||
|
@ -6193,6 +6329,16 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "want"
|
||||
version = "0.3.1"
|
||||
|
@ -6669,6 +6815,18 @@ dependencies = [
|
|||
"syn 2.0.26",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"crc32fast",
|
||||
"crossbeam-utils",
|
||||
"flate2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.11.2+zstd.1.5.2"
|
||||
|
|
|
@ -59,6 +59,8 @@ structopt = { version = "0.3.26" }
|
|||
strum = { version = "0.24.1", features = ["derive"] }
|
||||
tokio = { version = "1.26.0", features = ["full"] }
|
||||
tower-http = { version = "0.4.0", features = ["cors"] }
|
||||
utoipa = { version = "3.4.0", features = ["axum_extras"] }
|
||||
utoipa-swagger-ui = { version = "3.1.4", features = ["axum"] }
|
||||
wormhole-sdk = { git = "https://github.com/wormhole-foundation/wormhole", tag = "v2.17.1" }
|
||||
|
||||
[patch.crates-io]
|
||||
|
|
|
@ -75,6 +75,8 @@ fn main() {
|
|||
.output()
|
||||
.expect("failed to generate protobuf definitions");
|
||||
|
||||
let rust_target_arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||
|
||||
// Build the Go library.
|
||||
let mut cmd = Command::new("go");
|
||||
cmd.arg("build")
|
||||
|
@ -84,11 +86,28 @@ fn main() {
|
|||
.arg("src/network/p2p.go")
|
||||
.arg("src/network/p2p.pb.go");
|
||||
|
||||
// Cross-compile the Go binary based on the Rust target architecture
|
||||
match &*rust_target_arch {
|
||||
"x86_64" => {
|
||||
// CGO_ENABLED required for building amd64 on mac os
|
||||
cmd.env("GOARCH", "amd64").env("CGO_ENABLED", "1");
|
||||
}
|
||||
"aarch64" => {
|
||||
cmd.env("GOARCH", "arm64");
|
||||
}
|
||||
// Add other target architectures as needed.
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
||||
// Tell Rust to link our Go library at compile time.
|
||||
println!("cargo:rustc-link-search=native={out_var}");
|
||||
println!("cargo:rustc-link-lib=static=pythnet");
|
||||
println!("cargo:rustc-link-lib=resolv");
|
||||
|
||||
let status = cmd.status().unwrap();
|
||||
assert!(status.success());
|
||||
let go_build_output = cmd.output().expect("Failed to execute Go build command");
|
||||
if !go_build_output.status.success() {
|
||||
let error_message = String::from_utf8_lossy(&go_build_output.stderr);
|
||||
panic!("Go build failed:\n{}", error_message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,16 @@ use {
|
|||
sync::mpsc::Receiver,
|
||||
},
|
||||
tower_http::cors::CorsLayer,
|
||||
utoipa::{
|
||||
openapi::security::{
|
||||
ApiKey,
|
||||
ApiKeyValue,
|
||||
SecurityScheme,
|
||||
},
|
||||
Modify,
|
||||
OpenApi,
|
||||
},
|
||||
utoipa_swagger_ui::SwaggerUi,
|
||||
};
|
||||
|
||||
mod rest;
|
||||
|
@ -38,12 +48,27 @@ impl State {
|
|||
/// Currently this is based on Axum due to the simplicity and strong ecosystem support for the
|
||||
/// packages they are based on (tokio & hyper).
|
||||
pub async fn run(store: Arc<Store>, mut update_rx: Receiver<()>, rpc_addr: String) -> Result<()> {
|
||||
#[derive(OpenApi)]
|
||||
#[openapi(
|
||||
paths(
|
||||
rest::latest_price_feeds,
|
||||
),
|
||||
components(
|
||||
schemas(types::RpcPriceFeedMetadata, types::RpcPriceFeed)
|
||||
),
|
||||
tags(
|
||||
(name = "hermes", description = "Pyth Real-Time Pricing API")
|
||||
)
|
||||
)]
|
||||
struct ApiDoc;
|
||||
|
||||
let state = State::new(store);
|
||||
|
||||
// Initialize Axum Router. Note the type here is a `Router<State>` due to the use of the
|
||||
// `with_state` method which replaces `Body` with `State` in the type signature.
|
||||
let app = Router::new();
|
||||
let app = app
|
||||
.merge(SwaggerUi::new("/docs").url("/docs/openapi.json", ApiDoc::openapi()))
|
||||
.route("/", get(rest::index))
|
||||
.route("/live", get(rest::live))
|
||||
.route("/ready", get(rest::ready))
|
||||
|
|
|
@ -31,6 +31,7 @@ use {
|
|||
pyth_sdk::PriceIdentifier,
|
||||
serde_qs::axum::QsQuery,
|
||||
std::collections::HashSet,
|
||||
utoipa::IntoParams,
|
||||
};
|
||||
|
||||
pub enum RestError {
|
||||
|
@ -95,15 +96,32 @@ pub async fn latest_vaas(
|
|||
))
|
||||
}
|
||||
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
#[derive(Debug, serde::Deserialize, IntoParams)]
|
||||
pub struct LatestPriceFeedsQueryParams {
|
||||
#[param(value_type = String)]
|
||||
ids: Vec<PriceIdInput>,
|
||||
#[serde(default)]
|
||||
#[param(value_type = Option<bool>, required = false, nullable = true)]
|
||||
verbose: bool,
|
||||
#[serde(default)]
|
||||
#[param(value_type = Option<bool>, required = false, nullable = true)]
|
||||
binary: bool,
|
||||
}
|
||||
|
||||
/// Get the latest prices by price feed ids.
|
||||
///
|
||||
/// Get the latest price updates for a provided collection of price feed ids.
|
||||
///
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/latest_price_feeds",
|
||||
responses(
|
||||
(status = 200, description = "Price feeds retrieved successfully", body = [Vec<RpcPriceFeed>])
|
||||
),
|
||||
params(
|
||||
LatestPriceFeedsQueryParams
|
||||
)
|
||||
)]
|
||||
pub async fn latest_price_feeds(
|
||||
State(state): State<super::State>,
|
||||
QsQuery(params): QsQuery<LatestPriceFeedsQueryParams>,
|
||||
|
|
|
@ -19,6 +19,14 @@ use {
|
|||
Price,
|
||||
PriceIdentifier,
|
||||
},
|
||||
utoipa::{
|
||||
openapi::{
|
||||
RefOr,
|
||||
Schema,
|
||||
},
|
||||
IntoParams,
|
||||
ToSchema,
|
||||
},
|
||||
wormhole_sdk::Chain,
|
||||
};
|
||||
|
||||
|
@ -40,14 +48,16 @@ impl From<PriceIdInput> for PriceIdentifier {
|
|||
|
||||
type Base64String = String;
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
|
||||
pub struct RpcPriceFeedMetadata {
|
||||
#[schema(value_type = u64)]
|
||||
pub slot: Slot,
|
||||
pub emitter_chain: u16,
|
||||
#[schema(value_type = i64)]
|
||||
pub price_service_receive_time: UnixTimestamp,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, ToSchema)]
|
||||
pub struct RpcPriceFeed {
|
||||
pub id: PriceIdentifier,
|
||||
pub price: Price,
|
||||
|
@ -56,6 +66,7 @@ pub struct RpcPriceFeed {
|
|||
pub metadata: Option<RpcPriceFeedMetadata>,
|
||||
/// Vaa binary represented in base64.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
#[schema(value_type = Option<String>)]
|
||||
pub vaa: Option<Base64String>,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue