mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-28 08:39:59 -07:00
global: snapshot
This commit is contained in:
@@ -6,11 +6,11 @@ use axum::{
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_error::Result;
|
||||
use brk_types::{Format, MetricSelection, Output};
|
||||
use quick_cache::sync::GuardResult;
|
||||
|
||||
use crate::{
|
||||
Result,
|
||||
api::metrics::{CACHE_CONTROL, MAX_WEIGHT},
|
||||
extended::HeaderMapExtended,
|
||||
};
|
||||
@@ -18,22 +18,10 @@ use crate::{
|
||||
use super::AppState;
|
||||
|
||||
pub async fn handler(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
query: Query<MetricSelection>,
|
||||
State(state): State<AppState>,
|
||||
) -> Response {
|
||||
match req_to_response_res(uri, headers, query, state).await {
|
||||
Ok(response) => response,
|
||||
Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn req_to_response_res(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
Query(params): Query<MetricSelection>,
|
||||
AppState { query, cache, .. }: AppState,
|
||||
State(AppState { query, cache, .. }): State<AppState>,
|
||||
) -> Result<Response> {
|
||||
// Phase 1: Search and resolve metadata (cheap)
|
||||
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;
|
||||
|
||||
@@ -6,11 +6,11 @@ use axum::{
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_error::Result;
|
||||
use brk_types::{Format, MetricSelection, Output};
|
||||
use quick_cache::sync::GuardResult;
|
||||
|
||||
use crate::{
|
||||
Result,
|
||||
api::metrics::{CACHE_CONTROL, MAX_WEIGHT},
|
||||
extended::HeaderMapExtended,
|
||||
};
|
||||
@@ -18,22 +18,10 @@ use crate::{
|
||||
use super::AppState;
|
||||
|
||||
pub async fn handler(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
query: Query<MetricSelection>,
|
||||
State(state): State<AppState>,
|
||||
) -> Response {
|
||||
match req_to_response_res(uri, headers, query, state).await {
|
||||
Ok(response) => response,
|
||||
Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn req_to_response_res(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
Query(params): Query<MetricSelection>,
|
||||
AppState { query, cache, .. }: AppState,
|
||||
State(AppState { query, cache, .. }): State<AppState>,
|
||||
) -> Result<Response> {
|
||||
// Phase 1: Search and resolve metadata (cheap)
|
||||
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;
|
||||
|
||||
@@ -6,11 +6,11 @@ use axum::{
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_error::Result;
|
||||
use brk_types::{Format, MetricSelection, OutputLegacy};
|
||||
use quick_cache::sync::GuardResult;
|
||||
|
||||
use crate::{
|
||||
Result,
|
||||
api::metrics::{CACHE_CONTROL, MAX_WEIGHT},
|
||||
extended::HeaderMapExtended,
|
||||
};
|
||||
@@ -18,22 +18,10 @@ use crate::{
|
||||
use super::AppState;
|
||||
|
||||
pub async fn handler(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
query: Query<MetricSelection>,
|
||||
State(state): State<AppState>,
|
||||
) -> Response {
|
||||
match req_to_response_res(uri, headers, query, state).await {
|
||||
Ok(response) => response,
|
||||
Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
async fn req_to_response_res(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
Query(params): Query<MetricSelection>,
|
||||
AppState { query, cache, .. }: AppState,
|
||||
State(AppState { query, cache, .. }): State<AppState>,
|
||||
) -> Result<Response> {
|
||||
// Phase 1: Search and resolve metadata (cheap)
|
||||
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;
|
||||
|
||||
@@ -170,6 +170,7 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
|
||||
state,
|
||||
)
|
||||
.await
|
||||
.into_response()
|
||||
},
|
||||
|op| op
|
||||
.id("get_metric")
|
||||
@@ -188,7 +189,9 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/metrics/bulk",
|
||||
get_with(
|
||||
bulk::handler,
|
||||
|uri, headers, query, state| async move {
|
||||
bulk::handler(uri, headers, query, state).await.into_response()
|
||||
},
|
||||
|op| op
|
||||
.id("get_metrics")
|
||||
.metrics_tag()
|
||||
@@ -225,7 +228,9 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
|
||||
Metrics::from(split.collect::<Vec<_>>().join(separator)),
|
||||
range,
|
||||
));
|
||||
legacy::handler(uri, headers, Query(params), state).await
|
||||
legacy::handler(uri, headers, Query(params), state)
|
||||
.await
|
||||
.into_response()
|
||||
},
|
||||
|op| op
|
||||
.metrics_tag()
|
||||
@@ -250,7 +255,9 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
|
||||
state: State<AppState>|
|
||||
-> Response {
|
||||
let params: MetricSelection = params.into();
|
||||
legacy::handler(uri, headers, Query(params), state).await
|
||||
legacy::handler(uri, headers, Query(params), state)
|
||||
.await
|
||||
.into_response()
|
||||
},
|
||||
|op| op
|
||||
.metrics_tag()
|
||||
|
||||
@@ -48,7 +48,7 @@ impl ApiRoutes for ApiRouter<AppState> {
|
||||
.add_server_routes()
|
||||
.route("/api/server", get(Redirect::temporary("/api#tag/server")))
|
||||
.api_route(
|
||||
"/api.json",
|
||||
"/openapi.json",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Extension(api): Extension<Arc<OpenApi>>|
|
||||
@@ -62,7 +62,7 @@ impl ApiRoutes for ApiRouter<AppState> {
|
||||
),
|
||||
)
|
||||
.api_route(
|
||||
"/api.trimmed.json",
|
||||
"/api.json",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Extension(api_trimmed): Extension<Arc<String>>|
|
||||
@@ -72,12 +72,13 @@ impl ApiRoutes for ApiRouter<AppState> {
|
||||
Response::static_json(&headers, &value)
|
||||
},
|
||||
|op| {
|
||||
op.id("get_openapi_trimmed")
|
||||
op.id("get_api")
|
||||
.server_tag()
|
||||
.summary("Trimmed OpenAPI specification")
|
||||
.summary("Compact OpenAPI specification")
|
||||
.description(
|
||||
"Compact OpenAPI specification optimized for LLM consumption. \
|
||||
Removes redundant fields while preserving essential API information.",
|
||||
Removes redundant fields while preserving essential API information. \
|
||||
Full spec available at `/openapi.json`.",
|
||||
)
|
||||
.ok_response::<serde_json::Value>()
|
||||
},
|
||||
|
||||
@@ -29,7 +29,7 @@ pub fn create_openapi() -> OpenApi {
|
||||
- **Metrics**: Thousands of time-series metrics across multiple indexes (date, block height, etc.)
|
||||
- **[Mempool.space](https://mempool.space/docs/api/rest) compatible** (WIP): Most non-metrics endpoints follow the mempool.space API format
|
||||
- **Multiple formats**: JSON and CSV output
|
||||
- **LLM-optimized**: Compact OpenAPI spec at [`/api.trimmed.json`](/api.trimmed.json) for AI tools
|
||||
- **LLM-optimized**: Compact OpenAPI spec at [`/api.json`](/api.json) for AI tools (full spec at [`/openapi.json`](/openapi.json))
|
||||
|
||||
### Client Libraries
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
<script>
|
||||
Scalar.createApiReference("#app", {
|
||||
url: "/api.json",
|
||||
url: "/openapi.json",
|
||||
hideClientButton: true,
|
||||
telemetry: false,
|
||||
// showToolbar: "never",
|
||||
|
||||
Reference in New Issue
Block a user