quicknode-sdk 0.1.0a15__tar.gz → 0.1.0a16__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/Cargo.lock +7 -7
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/Cargo.toml +1 -1
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/PKG-INFO +52 -4
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/Cargo.toml +5 -1
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/README.md +56 -3
- quicknode_sdk-0.1.0a16/crates/core/examples/admin.rs +59 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/examples/admin_e2e.rs +53 -2
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/examples/streams_e2e.rs +1 -1
- quicknode_sdk-0.1.0a16/crates/core/src/admin/endpoint_metrics.rs +148 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/endpoint_rate_limits.rs +44 -0
- quicknode_sdk-0.1.0a16/crates/core/src/admin/endpoint_urls.rs +47 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/endpoints.rs +6 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/mod.rs +308 -9
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/kvstore/mod.rs +85 -1
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/streams/mod.rs +2 -2
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/streams/stream.rs +2 -3
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/webhooks/mod.rs +28 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/python/src/lib.rs +64 -5
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/pyproject.toml +1 -1
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/python/README.md +51 -3
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/python/sdk/__init__.py +12 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/python/sdk/__init__.pyi +12 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/python/sdk/_core/__init__.pyi +241 -8
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/python/sdk/init_manual_override.pyi +12 -0
- quicknode_sdk-0.1.0a15/crates/core/examples/admin.rs +0 -35
- quicknode_sdk-0.1.0a15/crates/core/src/admin/endpoint_metrics.rs +0 -72
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/LICENSE +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/LICENSE +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/examples/kvstore_e2e.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/examples/streams.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/examples/webhooks_e2e.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/billing.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/bulk.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/chains.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/endpoint_security.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/logs.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/tags.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/teams.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/usage.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/config.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/errors.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/lib.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/webhooks/webhook.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/python/Cargo.toml +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/python/src/errors.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/python/src/streams_destination.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/python/src/webhooks_template.rs +0 -0
- {quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/python/sdk/py.typed +0 -0
|
@@ -441,9 +441,9 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813"
|
|
|
441
441
|
|
|
442
442
|
[[package]]
|
|
443
443
|
name = "either"
|
|
444
|
-
version = "1.
|
|
444
|
+
version = "1.16.0"
|
|
445
445
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
446
|
-
checksum = "
|
|
446
|
+
checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e"
|
|
447
447
|
|
|
448
448
|
[[package]]
|
|
449
449
|
name = "encoding_rs"
|
|
@@ -1679,7 +1679,7 @@ dependencies = [
|
|
|
1679
1679
|
|
|
1680
1680
|
[[package]]
|
|
1681
1681
|
name = "quicknode-sdk"
|
|
1682
|
-
version = "0.1.0-alpha.
|
|
1682
|
+
version = "0.1.0-alpha.16"
|
|
1683
1683
|
dependencies = [
|
|
1684
1684
|
"bon",
|
|
1685
1685
|
"config",
|
|
@@ -2156,7 +2156,7 @@ dependencies = [
|
|
|
2156
2156
|
|
|
2157
2157
|
[[package]]
|
|
2158
2158
|
name = "sdk-node"
|
|
2159
|
-
version = "0.1.0-alpha.
|
|
2159
|
+
version = "0.1.0-alpha.16"
|
|
2160
2160
|
dependencies = [
|
|
2161
2161
|
"napi",
|
|
2162
2162
|
"napi-build",
|
|
@@ -2168,7 +2168,7 @@ dependencies = [
|
|
|
2168
2168
|
|
|
2169
2169
|
[[package]]
|
|
2170
2170
|
name = "sdk-python"
|
|
2171
|
-
version = "0.1.0-alpha.
|
|
2171
|
+
version = "0.1.0-alpha.16"
|
|
2172
2172
|
dependencies = [
|
|
2173
2173
|
"pyo3",
|
|
2174
2174
|
"pyo3-async-runtimes",
|
|
@@ -2179,7 +2179,7 @@ dependencies = [
|
|
|
2179
2179
|
|
|
2180
2180
|
[[package]]
|
|
2181
2181
|
name = "sdk-python-stubs"
|
|
2182
|
-
version = "0.1.0-alpha.
|
|
2182
|
+
version = "0.1.0-alpha.16"
|
|
2183
2183
|
dependencies = [
|
|
2184
2184
|
"pyo3-stub-gen",
|
|
2185
2185
|
"sdk-python",
|
|
@@ -2187,7 +2187,7 @@ dependencies = [
|
|
|
2187
2187
|
|
|
2188
2188
|
[[package]]
|
|
2189
2189
|
name = "sdk-ruby"
|
|
2190
|
-
version = "0.1.0-alpha.
|
|
2190
|
+
version = "0.1.0-alpha.16"
|
|
2191
2191
|
dependencies = [
|
|
2192
2192
|
"magnus",
|
|
2193
2193
|
"quicknode-sdk",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quicknode-sdk
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.0a16
|
|
4
4
|
Classifier: Intended Audience :: Developers
|
|
5
5
|
Classifier: License :: OSI Approved :: MIT License
|
|
6
6
|
Classifier: Operating System :: POSIX :: Linux
|
|
@@ -52,6 +52,7 @@ This is one of four language bindings published from the same Rust core. See the
|
|
|
52
52
|
- [IP Custom Headers](#ip-custom-headers)
|
|
53
53
|
- [Method Rate Limits](#method-rate-limits)
|
|
54
54
|
- [Endpoint Rate Limits](#endpoint-rate-limits)
|
|
55
|
+
- [Endpoint URLs](#endpoint-urls)
|
|
55
56
|
- [Metrics](#metrics)
|
|
56
57
|
- [Chains](#chains)
|
|
57
58
|
- [Billing](#billing)
|
|
@@ -807,7 +808,7 @@ await qn.admin.delete_method_rate_limit("ep-123", "rl-1")
|
|
|
807
808
|
|
|
808
809
|
##### `update_rate_limits` / `updateRateLimits`
|
|
809
810
|
|
|
810
|
-
|
|
811
|
+
Partial update of the endpoint-level RPS / RPM / RPD caps. Only buckets included in the request are modified — omitted buckets are left unchanged. Values are capped by the account's plan tier. Sends `PATCH`.
|
|
811
812
|
|
|
812
813
|
**Parameters**: `id` (endpoint id, required); `rate_limits`: `RateLimitSettings` (`rps`, `rpm`, `rpd`, all optional).
|
|
813
814
|
|
|
@@ -818,6 +819,53 @@ Updates the endpoint-level RPS / RPM / RPD caps.
|
|
|
818
819
|
await qn.admin.update_rate_limits("ep-123", rps=100, rpm=5000)
|
|
819
820
|
```
|
|
820
821
|
|
|
822
|
+
##### `get_rate_limits` / `getRateLimits`
|
|
823
|
+
|
|
824
|
+
Returns the rate-limit rows currently enforced on the endpoint, each identifying its `bucket` (`"rps"` / `"rpm"` / `"rpd"`), `rate_limit`, and `source` (`"plan_default"` or `"user_override"`). User-set overrides expose an `id` (camelCased `id` in Node) you can pass to `delete_rate_limit_override`.
|
|
825
|
+
|
|
826
|
+
**Parameters**: `id` (endpoint id, required).
|
|
827
|
+
|
|
828
|
+
**Returns**: `GetRateLimitsResponse` with `data.rate_limits: RateLimitEntry[]`.
|
|
829
|
+
|
|
830
|
+
```python
|
|
831
|
+
# Python
|
|
832
|
+
resp = await qn.admin.get_rate_limits("123")
|
|
833
|
+
for row in resp.data.rate_limits:
|
|
834
|
+
print(row.bucket, row.rate_limit, row.source, row.id)
|
|
835
|
+
```
|
|
836
|
+
|
|
837
|
+
##### `delete_rate_limit_override` / `deleteRateLimitOverride`
|
|
838
|
+
|
|
839
|
+
Deletes a user-set rate-limit override by UUID. Plan defaults are not deletable — passing a UUID that does not match a user-set override on the endpoint returns 404.
|
|
840
|
+
|
|
841
|
+
**Parameters**: `id` (endpoint id, required); `override_id` / `overrideId` (UUID returned by `get_rate_limits`, required).
|
|
842
|
+
|
|
843
|
+
**Returns**: nothing.
|
|
844
|
+
|
|
845
|
+
```python
|
|
846
|
+
# Python
|
|
847
|
+
await qn.admin.delete_rate_limit_override("123", "ovr-uuid")
|
|
848
|
+
```
|
|
849
|
+
|
|
850
|
+
#### Endpoint URLs
|
|
851
|
+
|
|
852
|
+
##### `get_endpoint_urls` / `getEndpointUrls`
|
|
853
|
+
|
|
854
|
+
Returns the HTTP and WebSocket URLs for the endpoint without fetching the full endpoint record. For multichain endpoints, `multichain_urls` / `multichainUrls` is a per-network map of additional URLs; for single-chain endpoints it is `None` / `null`.
|
|
855
|
+
|
|
856
|
+
**Parameters**: `id` (endpoint id, required).
|
|
857
|
+
|
|
858
|
+
**Returns**: `GetEndpointUrlsResponse` with `data.http_url`, `data.wss_url`, and `data.multichain_urls`.
|
|
859
|
+
|
|
860
|
+
```python
|
|
861
|
+
# Python
|
|
862
|
+
resp = await qn.admin.get_endpoint_urls("123")
|
|
863
|
+
print(resp.data.http_url)
|
|
864
|
+
if resp.data.multichain_urls:
|
|
865
|
+
for network, urls in resp.data.multichain_urls.items():
|
|
866
|
+
print(network, urls.http_url)
|
|
867
|
+
```
|
|
868
|
+
|
|
821
869
|
#### Metrics
|
|
822
870
|
|
|
823
871
|
##### `get_endpoint_metrics` / `getEndpointMetrics`
|
|
@@ -826,7 +874,7 @@ Returns metric series for an endpoint over a time period.
|
|
|
826
874
|
|
|
827
875
|
**Parameters**: `id` (endpoint id, required); body: `period` (`"hour"` | `"day"` | `"week"` | `"month"`), `metric` (e.g. `"method_calls_over_time"`, `"response_status_breakdown"`).
|
|
828
876
|
|
|
829
|
-
**Returns**: `GetEndpointMetricsResponse` with `data: EndpointMetric[]`.
|
|
877
|
+
**Returns**: `GetEndpointMetricsResponse` with `data: list[EndpointMetric]`. Each `EndpointMetric` has a `tag: list[str]` and a `data: list[list[int]]` of `[timestamp, value]` pairs. Single-axis series (e.g. `response_time_over_time` with a percentile) come back as a one-element tag like `["p95"]`; multi-axis series come back as `["network", "arbitrum-mainnet"]`.
|
|
830
878
|
|
|
831
879
|
```python
|
|
832
880
|
# Python
|
|
@@ -843,7 +891,7 @@ Returns account-level metric series. Supports an optional `percentile` (e.g. `"p
|
|
|
843
891
|
|
|
844
892
|
**Parameters**: `period` (required), `metric` (required), `percentile` (string, optional).
|
|
845
893
|
|
|
846
|
-
**Returns**: `GetAccountMetricsResponse` with `data: EndpointMetric[]
|
|
894
|
+
**Returns**: `GetAccountMetricsResponse` with `data: list[EndpointMetric]`. See `get_endpoint_metrics` above for the `tag: list[str]` shape.
|
|
847
895
|
|
|
848
896
|
```python
|
|
849
897
|
# Python
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "quicknode-sdk"
|
|
3
|
-
version = "0.1.0-alpha.
|
|
3
|
+
version = "0.1.0-alpha.16"
|
|
4
4
|
edition.workspace = true
|
|
5
5
|
license.workspace = true
|
|
6
6
|
description = "Core library for quicknode sdk"
|
|
@@ -47,6 +47,10 @@ required-features = ["rust"]
|
|
|
47
47
|
name = "streams"
|
|
48
48
|
required-features = ["rust"]
|
|
49
49
|
|
|
50
|
+
[[example]]
|
|
51
|
+
name = "streams_e2e"
|
|
52
|
+
required-features = ["rust"]
|
|
53
|
+
|
|
50
54
|
[[example]]
|
|
51
55
|
name = "webhooks_e2e"
|
|
52
56
|
required-features = ["rust"]
|
|
@@ -28,6 +28,7 @@ This is one of four language bindings published from the same Rust core. See the
|
|
|
28
28
|
- [IP Custom Headers](#ip-custom-headers)
|
|
29
29
|
- [Method Rate Limits](#method-rate-limits)
|
|
30
30
|
- [Endpoint Rate Limits](#endpoint-rate-limits)
|
|
31
|
+
- [Endpoint URLs](#endpoint-urls)
|
|
31
32
|
- [Metrics](#metrics)
|
|
32
33
|
- [Chains](#chains)
|
|
33
34
|
- [Billing](#billing)
|
|
@@ -815,7 +816,7 @@ qn.admin.delete_method_rate_limit("ep-123", "rl-1").await?;
|
|
|
815
816
|
|
|
816
817
|
##### `update_rate_limits` / `updateRateLimits`
|
|
817
818
|
|
|
818
|
-
|
|
819
|
+
Partial update of the endpoint-level RPS / RPM / RPD caps. Only buckets included in the request are modified — omitted buckets are left unchanged. Values are capped by the account's plan tier. Sends `PATCH`.
|
|
819
820
|
|
|
820
821
|
**Parameters**: `id` (endpoint id, required); `rate_limits`: `RateLimitSettings` (`rps`, `rpm`, `rpd`, all optional).
|
|
821
822
|
|
|
@@ -828,6 +829,58 @@ let params = UpdateRateLimitsRequest { rate_limits };
|
|
|
828
829
|
qn.admin.update_rate_limits("ep-123", ¶ms).await?;
|
|
829
830
|
```
|
|
830
831
|
|
|
832
|
+
##### `get_rate_limits` / `getRateLimits`
|
|
833
|
+
|
|
834
|
+
Returns the rate-limit rows currently enforced on the endpoint, each identifying its `bucket` (`"rps"` / `"rpm"` / `"rpd"`), `rate_limit`, and `source` (`"plan_default"` or `"user_override"`). User-set overrides expose an `id` you can pass to `delete_rate_limit_override`.
|
|
835
|
+
|
|
836
|
+
**Parameters**: `id` (endpoint id, required).
|
|
837
|
+
|
|
838
|
+
**Returns**: `GetRateLimitsResponse` with `data.rate_limits: Vec<RateLimitEntry>`.
|
|
839
|
+
|
|
840
|
+
```rust
|
|
841
|
+
// Rust
|
|
842
|
+
let resp = qn.admin.get_rate_limits("123").await?;
|
|
843
|
+
for row in resp.data.unwrap().rate_limits {
|
|
844
|
+
println!("{} {} {} {:?}", row.bucket, row.rate_limit, row.source, row.id);
|
|
845
|
+
}
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
##### `delete_rate_limit_override` / `deleteRateLimitOverride`
|
|
849
|
+
|
|
850
|
+
Deletes a user-set rate-limit override by UUID. Plan defaults are not deletable — passing a UUID that does not match a user-set override on the endpoint returns 404.
|
|
851
|
+
|
|
852
|
+
**Parameters**: `id` (endpoint id, required); `override_id` (UUID returned by `get_rate_limits`, required).
|
|
853
|
+
|
|
854
|
+
**Returns**: nothing.
|
|
855
|
+
|
|
856
|
+
```rust
|
|
857
|
+
// Rust
|
|
858
|
+
qn.admin.delete_rate_limit_override("123", "ovr-uuid").await?;
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
#### Endpoint URLs
|
|
862
|
+
|
|
863
|
+
##### `get_endpoint_urls` / `getEndpointUrls`
|
|
864
|
+
|
|
865
|
+
Returns the HTTP and WebSocket URLs for the endpoint without fetching the full endpoint record. For multichain endpoints, `multichain_urls` is a per-network map of additional URLs; for single-chain endpoints it is `None`.
|
|
866
|
+
|
|
867
|
+
**Parameters**: `id` (endpoint id, required).
|
|
868
|
+
|
|
869
|
+
**Returns**: `GetEndpointUrlsResponse` with `data.http_url`, `data.wss_url`, and `data.multichain_urls`.
|
|
870
|
+
|
|
871
|
+
```rust
|
|
872
|
+
// Rust
|
|
873
|
+
let resp = qn.admin.get_endpoint_urls("123").await?;
|
|
874
|
+
if let Some(data) = resp.data {
|
|
875
|
+
println!("{}", data.http_url);
|
|
876
|
+
if let Some(mc) = data.multichain_urls {
|
|
877
|
+
for (network, urls) in mc {
|
|
878
|
+
println!("{network} {}", urls.http_url);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
```
|
|
883
|
+
|
|
831
884
|
#### Metrics
|
|
832
885
|
|
|
833
886
|
##### `get_endpoint_metrics` / `getEndpointMetrics`
|
|
@@ -836,7 +889,7 @@ Returns metric series for an endpoint over a time period.
|
|
|
836
889
|
|
|
837
890
|
**Parameters**: `id` (endpoint id, required); body: `period` (`"hour"` | `"day"` | `"week"` | `"month"`), `metric` (e.g. `"method_calls_over_time"`, `"response_status_breakdown"`).
|
|
838
891
|
|
|
839
|
-
**Returns**: `GetEndpointMetricsResponse` with `data: EndpointMetric[]`.
|
|
892
|
+
**Returns**: `GetEndpointMetricsResponse` with `data: Vec<EndpointMetric>`. Each `EndpointMetric` has `tag: Vec<String>` and `data: Vec<Vec<i64>>` of `[timestamp, value]` pairs. Single-axis series (e.g. `response_time_over_time` with a percentile) come back as a one-element tag like `vec!["p95"]`; multi-axis series come back as `vec!["network", "arbitrum-mainnet"]`.
|
|
840
893
|
|
|
841
894
|
```rust
|
|
842
895
|
// Rust
|
|
@@ -853,7 +906,7 @@ Returns account-level metric series. Supports an optional `percentile` (e.g. `"p
|
|
|
853
906
|
|
|
854
907
|
**Parameters**: `period` (required), `metric` (required), `percentile` (string, optional).
|
|
855
908
|
|
|
856
|
-
**Returns**: `GetAccountMetricsResponse` with `data: EndpointMetric
|
|
909
|
+
**Returns**: `GetAccountMetricsResponse` with `data: Vec<EndpointMetric>`. See `get_endpoint_metrics` above for the `tag: Vec<String>` shape.
|
|
857
910
|
|
|
858
911
|
```rust
|
|
859
912
|
// Rust
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
use quicknode_sdk::{admin::GetEndpointsRequest, QuicknodeSdk, SdkFullConfig};
|
|
2
|
+
|
|
3
|
+
#[tokio::main]
|
|
4
|
+
#[allow(clippy::unwrap_used, clippy::expect_used)]
|
|
5
|
+
async fn main() {
|
|
6
|
+
let config = SdkFullConfig::from_env().expect("Config from env failed");
|
|
7
|
+
let qn = QuicknodeSdk::new(&config).expect("sdk failed to initialize");
|
|
8
|
+
|
|
9
|
+
let params = GetEndpointsRequest::builder()
|
|
10
|
+
.limit(20)
|
|
11
|
+
.sort_by("created_at".to_string())
|
|
12
|
+
.sort_direction("desc".to_string())
|
|
13
|
+
.build();
|
|
14
|
+
|
|
15
|
+
let first_endpoint_id = match qn.admin.get_endpoints(¶ms).await {
|
|
16
|
+
Ok(resp) => {
|
|
17
|
+
if let Some(p) = &resp.pagination {
|
|
18
|
+
println!(
|
|
19
|
+
"{} of {} (offset {}, limit {})",
|
|
20
|
+
resp.data.len(),
|
|
21
|
+
p.total,
|
|
22
|
+
p.offset,
|
|
23
|
+
p.limit
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
for ep in &resp.data {
|
|
27
|
+
println!(
|
|
28
|
+
"{} | {} | {} | {} | dedicated={} flat={} multichain={}",
|
|
29
|
+
ep.id,
|
|
30
|
+
ep.name,
|
|
31
|
+
ep.status,
|
|
32
|
+
ep.chain,
|
|
33
|
+
ep.is_dedicated,
|
|
34
|
+
ep.is_flat_rate,
|
|
35
|
+
ep.is_multichain
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
resp.data.first().map(|ep| ep.id.clone())
|
|
39
|
+
}
|
|
40
|
+
Err(e) => {
|
|
41
|
+
eprintln!("get_endpoints error: {e}");
|
|
42
|
+
None
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
let Some(endpoint_id) = first_endpoint_id else {
|
|
47
|
+
return;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
match qn.admin.get_rate_limits(&endpoint_id).await {
|
|
51
|
+
Ok(resp) => println!("get_rate_limits: {:?}", resp.data),
|
|
52
|
+
Err(e) => eprintln!("get_rate_limits error: {e}"),
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
match qn.admin.get_endpoint_urls(&endpoint_id).await {
|
|
56
|
+
Ok(resp) => println!("get_endpoint_urls: {:?}", resp.data),
|
|
57
|
+
Err(e) => eprintln!("get_endpoint_urls error: {e}"),
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -97,7 +97,17 @@ async fn main() {
|
|
|
97
97
|
})
|
|
98
98
|
.await
|
|
99
99
|
{
|
|
100
|
-
Ok(resp) =>
|
|
100
|
+
Ok(resp) => {
|
|
101
|
+
let first = resp
|
|
102
|
+
.data
|
|
103
|
+
.first()
|
|
104
|
+
.map(|m| m.tag.join(":"))
|
|
105
|
+
.unwrap_or_else(|| "<none>".to_string());
|
|
106
|
+
println!(
|
|
107
|
+
"get_account_metrics: {} series, first tag: {first}",
|
|
108
|
+
resp.data.len()
|
|
109
|
+
);
|
|
110
|
+
}
|
|
101
111
|
Err(e) => eprintln!("get_account_metrics error: {e}"),
|
|
102
112
|
}
|
|
103
113
|
|
|
@@ -254,7 +264,17 @@ async fn main() {
|
|
|
254
264
|
)
|
|
255
265
|
.await
|
|
256
266
|
{
|
|
257
|
-
Ok(resp) =>
|
|
267
|
+
Ok(resp) => {
|
|
268
|
+
let first = resp
|
|
269
|
+
.data
|
|
270
|
+
.first()
|
|
271
|
+
.map(|m| m.tag.join(":"))
|
|
272
|
+
.unwrap_or_else(|| "<none>".to_string());
|
|
273
|
+
println!(
|
|
274
|
+
"get_endpoint_metrics: {} series, first tag: {first}",
|
|
275
|
+
resp.data.len()
|
|
276
|
+
);
|
|
277
|
+
}
|
|
258
278
|
Err(e) => eprintln!("get_endpoint_metrics error: {e}"),
|
|
259
279
|
}
|
|
260
280
|
|
|
@@ -534,6 +554,11 @@ async fn main() {
|
|
|
534
554
|
|
|
535
555
|
// --- Rate limits ---
|
|
536
556
|
|
|
557
|
+
match qn.admin.get_rate_limits(&endpoint_id).await {
|
|
558
|
+
Ok(resp) => println!("get_rate_limits before PATCH: {:?}", resp.data),
|
|
559
|
+
Err(e) => eprintln!("get_rate_limits error: {e}"),
|
|
560
|
+
}
|
|
561
|
+
|
|
537
562
|
match qn
|
|
538
563
|
.admin
|
|
539
564
|
.update_rate_limits(
|
|
@@ -551,6 +576,16 @@ async fn main() {
|
|
|
551
576
|
Err(e) => eprintln!("update_rate_limits error: {e}"),
|
|
552
577
|
}
|
|
553
578
|
|
|
579
|
+
match qn.admin.get_rate_limits(&endpoint_id).await {
|
|
580
|
+
Ok(resp) => println!("get_rate_limits after PATCH: {:?}", resp.data),
|
|
581
|
+
Err(e) => eprintln!("get_rate_limits error: {e}"),
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
match qn.admin.get_endpoint_urls(&endpoint_id).await {
|
|
585
|
+
Ok(resp) => println!("get_endpoint_urls: {:?}", resp.data),
|
|
586
|
+
Err(e) => eprintln!("get_endpoint_urls error: {e}"),
|
|
587
|
+
}
|
|
588
|
+
|
|
554
589
|
match qn.admin.get_method_rate_limits(&endpoint_id).await {
|
|
555
590
|
Ok(resp) => println!("get_method_rate_limits: {:?}", resp.data),
|
|
556
591
|
Err(e) => eprintln!("get_method_rate_limits error: {e}"),
|
|
@@ -806,6 +841,22 @@ async fn main() {
|
|
|
806
841
|
other => eprintln!("expected Api 404, got {other:?}"),
|
|
807
842
|
}
|
|
808
843
|
|
|
844
|
+
// 1b) Rate-limit override delete with a bogus override id — also a 404.
|
|
845
|
+
match qn
|
|
846
|
+
.admin
|
|
847
|
+
.delete_rate_limit_override("does-not-exist", "00000000-0000-0000-0000-000000000000")
|
|
848
|
+
.await
|
|
849
|
+
{
|
|
850
|
+
Err(SdkError::Api { status, body }) => {
|
|
851
|
+
println!(
|
|
852
|
+
"delete_rate_limit_override api error {status}: {}",
|
|
853
|
+
&body[..body.len().min(80)]
|
|
854
|
+
);
|
|
855
|
+
assert_eq!(status.as_u16(), 404);
|
|
856
|
+
}
|
|
857
|
+
other => eprintln!("expected Api 404 from delete_rate_limit_override, got {other:?}"),
|
|
858
|
+
}
|
|
859
|
+
|
|
809
860
|
// 2) Timeout path — unreachable base URL + 1s timeout forces a timeout
|
|
810
861
|
// from reqwest, which maps to SdkError::Http with http_kind() == Timeout.
|
|
811
862
|
let blackhole = SdkFullConfig {
|
|
@@ -33,7 +33,7 @@ async fn main() {
|
|
|
33
33
|
network: "ethereum-mainnet".to_string(),
|
|
34
34
|
dataset: StreamDataset::Block,
|
|
35
35
|
block: "17811625".to_string(),
|
|
36
|
-
filter_function:
|
|
36
|
+
filter_function: "ZnVuY3Rpb24gbWFpbihkYXRhKSB7IHJldHVybiBkYXRhOyB9".to_string(),
|
|
37
37
|
filter_language: None,
|
|
38
38
|
address_book_config: None,
|
|
39
39
|
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#[cfg(feature = "node")]
|
|
2
|
+
use napi_derive::napi;
|
|
3
|
+
#[cfg(feature = "python")]
|
|
4
|
+
use pyo3::pyclass;
|
|
5
|
+
#[cfg(feature = "python")]
|
|
6
|
+
use pyo3_stub_gen::derive::gen_stub_pyclass;
|
|
7
|
+
use serde::{Deserialize, Deserializer, Serialize};
|
|
8
|
+
|
|
9
|
+
// The metrics endpoints return `tag` as either a plain string (single-axis
|
|
10
|
+
// series like `"total"` or `"p95"`) or a tuple like `["network", "mainnet"]`
|
|
11
|
+
// (multi-axis series). Normalise both to a `Vec<String>` so callers always
|
|
12
|
+
// see an array.
|
|
13
|
+
fn tag_as_vec<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
|
|
14
|
+
where
|
|
15
|
+
D: Deserializer<'de>,
|
|
16
|
+
{
|
|
17
|
+
use serde::de::Error;
|
|
18
|
+
match serde_json::Value::deserialize(deserializer)? {
|
|
19
|
+
serde_json::Value::String(s) => Ok(vec![s]),
|
|
20
|
+
serde_json::Value::Array(items) => items
|
|
21
|
+
.into_iter()
|
|
22
|
+
.map(|v| match v {
|
|
23
|
+
serde_json::Value::String(s) => Ok(s),
|
|
24
|
+
other => Err(D::Error::custom(format!(
|
|
25
|
+
"expected string in tag array, got {other}"
|
|
26
|
+
))),
|
|
27
|
+
})
|
|
28
|
+
.collect(),
|
|
29
|
+
serde_json::Value::Null => Ok(Vec::new()),
|
|
30
|
+
other => Err(D::Error::custom(format!(
|
|
31
|
+
"expected string or array of strings for tag, got {other}"
|
|
32
|
+
))),
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// Parameters for `get_endpoint_metrics`.
|
|
37
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
38
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
39
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
40
|
+
#[derive(Debug, Clone, Default, Serialize)]
|
|
41
|
+
pub struct GetEndpointMetricsRequest {
|
|
42
|
+
/// Time period (`hour`, `day`, `week`, or `month`).
|
|
43
|
+
pub period: String,
|
|
44
|
+
/// Metric name (e.g. `method_calls_over_time`, `response_status_breakdown`).
|
|
45
|
+
pub metric: String,
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// Parameters for `get_account_metrics`.
|
|
49
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
50
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
51
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
52
|
+
#[derive(Debug, Clone, Default, Serialize)]
|
|
53
|
+
pub struct GetAccountMetricsRequest {
|
|
54
|
+
/// Time period (`hour`, `day`, `week`, or `month`).
|
|
55
|
+
pub period: String,
|
|
56
|
+
/// Metric name (e.g. `method_calls_over_time`, `credits_over_time`).
|
|
57
|
+
pub metric: String,
|
|
58
|
+
/// Optional percentile for latency metrics (e.g. `p50`, `p95`, `p99`).
|
|
59
|
+
#[serde(skip_serializing_if = "Option::is_none")]
|
|
60
|
+
pub percentile: Option<String>,
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/// A single metric series, consisting of a descriptive tag and timestamped data points.
|
|
64
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
65
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
66
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
67
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
68
|
+
pub struct EndpointMetric {
|
|
69
|
+
/// Data points, each as `[timestamp, value]`.
|
|
70
|
+
pub data: Vec<Vec<i64>>,
|
|
71
|
+
/// Tag identifying the series. Single-axis metrics return a one-element
|
|
72
|
+
/// vector (e.g. `["total"]`, `["p95"]`); multi-axis metrics return the
|
|
73
|
+
/// key/value pair (e.g. `["network", "arbitrum-mainnet"]`).
|
|
74
|
+
#[serde(deserialize_with = "tag_as_vec")]
|
|
75
|
+
pub tag: Vec<String>,
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/// Response from `get_endpoint_metrics`.
|
|
79
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
80
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
81
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
82
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
83
|
+
pub struct GetEndpointMetricsResponse {
|
|
84
|
+
/// Metric series returned for the endpoint.
|
|
85
|
+
#[serde(default)]
|
|
86
|
+
pub data: Vec<EndpointMetric>,
|
|
87
|
+
/// Error message when the request did not succeed.
|
|
88
|
+
pub error: Option<String>,
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/// Response from `get_account_metrics`.
|
|
92
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
93
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
94
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
95
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
96
|
+
pub struct GetAccountMetricsResponse {
|
|
97
|
+
/// Metric series returned for the account.
|
|
98
|
+
#[serde(default)]
|
|
99
|
+
pub data: Vec<EndpointMetric>,
|
|
100
|
+
/// Error message when the request did not succeed.
|
|
101
|
+
pub error: Option<String>,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
#[cfg(test)]
|
|
105
|
+
#[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
|
|
106
|
+
mod tests {
|
|
107
|
+
use super::EndpointMetric;
|
|
108
|
+
|
|
109
|
+
#[test]
|
|
110
|
+
fn tag_deserializes_from_string() {
|
|
111
|
+
let m: EndpointMetric =
|
|
112
|
+
serde_json::from_str(r#"{"data": [[1, 2]], "tag": "total"}"#).unwrap();
|
|
113
|
+
assert_eq!(m.tag, vec!["total".to_string()]);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
#[test]
|
|
117
|
+
fn tag_deserializes_from_tuple() {
|
|
118
|
+
let m: EndpointMetric =
|
|
119
|
+
serde_json::from_str(r#"{"data": [[1, 2]], "tag": ["network", "arbitrum-mainnet"]}"#)
|
|
120
|
+
.unwrap();
|
|
121
|
+
assert_eq!(
|
|
122
|
+
m.tag,
|
|
123
|
+
vec!["network".to_string(), "arbitrum-mainnet".to_string()]
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
#[test]
|
|
128
|
+
fn tag_deserializes_from_null() {
|
|
129
|
+
let m: EndpointMetric = serde_json::from_str(r#"{"data": [[1, 2]], "tag": null}"#).unwrap();
|
|
130
|
+
assert!(m.tag.is_empty());
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
#[test]
|
|
134
|
+
fn tag_rejects_mixed_array() {
|
|
135
|
+
let err =
|
|
136
|
+
serde_json::from_str::<EndpointMetric>(r#"{"data": [], "tag": ["x", 5]}"#).unwrap_err();
|
|
137
|
+
assert!(err.to_string().contains("expected string in tag array"));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
#[test]
|
|
141
|
+
fn tag_rejects_object() {
|
|
142
|
+
let err = serde_json::from_str::<EndpointMetric>(r#"{"data": [], "tag": {"k": "v"}}"#)
|
|
143
|
+
.unwrap_err();
|
|
144
|
+
assert!(err
|
|
145
|
+
.to_string()
|
|
146
|
+
.contains("expected string or array of strings for tag"));
|
|
147
|
+
}
|
|
148
|
+
}
|
{quicknode_sdk-0.1.0a15 → quicknode_sdk-0.1.0a16}/crates/core/src/admin/endpoint_rate_limits.rs
RENAMED
|
@@ -137,3 +137,47 @@ pub struct UpdateRateLimitsRequest {
|
|
|
137
137
|
/// Rate limit values to apply.
|
|
138
138
|
pub rate_limits: RateLimitSettings,
|
|
139
139
|
}
|
|
140
|
+
|
|
141
|
+
/// A single rate-limit row returned by `get_rate_limits`, identifying the
|
|
142
|
+
/// bucket (`rps`/`rpm`/`rpd`), the value enforced, and whether the value comes
|
|
143
|
+
/// from the plan default or a user-set override.
|
|
144
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
145
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
146
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
147
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
148
|
+
pub struct RateLimitEntry {
|
|
149
|
+
/// Which bucket this row applies to: `rps`, `rpm`, or `rpd`.
|
|
150
|
+
pub bucket: String,
|
|
151
|
+
/// The enforced value for this bucket.
|
|
152
|
+
pub rate_limit: i32,
|
|
153
|
+
/// Where the value comes from: `plan_default` or `user_override`.
|
|
154
|
+
pub source: String,
|
|
155
|
+
/// Row identifier. Present on `user_override` rows — pass it to
|
|
156
|
+
/// `delete_rate_limit_override` to remove the override. May be absent on
|
|
157
|
+
/// `plan_default` rows and cannot be deleted there.
|
|
158
|
+
#[serde(default)]
|
|
159
|
+
pub id: Option<String>,
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/// Inner data for `get_rate_limits`.
|
|
163
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
164
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
165
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
166
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
167
|
+
pub struct GetRateLimitsData {
|
|
168
|
+
/// One row per enforced bucket.
|
|
169
|
+
#[serde(default)]
|
|
170
|
+
pub rate_limits: Vec<RateLimitEntry>,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/// Response from `get_rate_limits`.
|
|
174
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
175
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
176
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
177
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
178
|
+
pub struct GetRateLimitsResponse {
|
|
179
|
+
/// Rate-limit rows with their source.
|
|
180
|
+
pub data: Option<GetRateLimitsData>,
|
|
181
|
+
/// Error message when the request did not succeed.
|
|
182
|
+
pub error: Option<String>,
|
|
183
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#[cfg(feature = "node")]
|
|
2
|
+
use napi_derive::napi;
|
|
3
|
+
#[cfg(feature = "python")]
|
|
4
|
+
use pyo3::pyclass;
|
|
5
|
+
#[cfg(feature = "python")]
|
|
6
|
+
use pyo3_stub_gen::derive::gen_stub_pyclass;
|
|
7
|
+
use serde::{Deserialize, Serialize};
|
|
8
|
+
use std::collections::HashMap;
|
|
9
|
+
|
|
10
|
+
/// HTTP/WSS URL pair for a single network on a multichain endpoint.
|
|
11
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
12
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
13
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
14
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
15
|
+
pub struct EndpointUrl {
|
|
16
|
+
/// HTTP RPC URL.
|
|
17
|
+
pub http_url: String,
|
|
18
|
+
/// WebSocket RPC URL, when available.
|
|
19
|
+
pub wss_url: Option<String>,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/// Inner data for `get_endpoint_urls` — the http/wss URLs for the endpoint and,
|
|
23
|
+
/// when the endpoint is multichain, a per-network map of additional URLs.
|
|
24
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
25
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
26
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
27
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
28
|
+
pub struct GetEndpointUrlsData {
|
|
29
|
+
/// HTTP RPC URL.
|
|
30
|
+
pub http_url: String,
|
|
31
|
+
/// WebSocket RPC URL, when available.
|
|
32
|
+
pub wss_url: Option<String>,
|
|
33
|
+
/// Per-network URLs for multichain endpoints; `None` for single-chain endpoints.
|
|
34
|
+
pub multichain_urls: Option<HashMap<String, EndpointUrl>>,
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/// Response from `get_endpoint_urls`.
|
|
38
|
+
#[cfg_attr(feature = "python", gen_stub_pyclass)]
|
|
39
|
+
#[cfg_attr(feature = "python", pyclass(get_all, set_all))]
|
|
40
|
+
#[cfg_attr(feature = "node", napi(object))]
|
|
41
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
42
|
+
pub struct GetEndpointUrlsResponse {
|
|
43
|
+
/// URLs for the endpoint.
|
|
44
|
+
pub data: Option<GetEndpointUrlsData>,
|
|
45
|
+
/// Error message when the request did not succeed.
|
|
46
|
+
pub error: Option<String>,
|
|
47
|
+
}
|