mirror of
https://github.com/qdrant/qdrant.git
synced 2026-07-23 11:11:00 -05:00
OpenAPI 3.0 doc generation
This commit is contained in:
45
Cargo.lock
generated
45
Cargo.lock
generated
@@ -608,6 +608,7 @@ dependencies = [
|
||||
"parking_lot 0.11.0",
|
||||
"rand 0.7.3",
|
||||
"rmp-serde",
|
||||
"schemars",
|
||||
"segment",
|
||||
"serde 1.0.116",
|
||||
"serde_cbor",
|
||||
@@ -857,6 +858,12 @@ version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4358a9e11b9a09cf52383b451b49a169e8d797b68aa02301ff586d70d9661ea3"
|
||||
|
||||
[[package]]
|
||||
name = "dyn-clone"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d55796afa1b20c2945ca8eabfc421839f2b766619209f1ede813cf2484f31804"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.3"
|
||||
@@ -1798,6 +1805,7 @@ dependencies = [
|
||||
"log 0.4.8",
|
||||
"num_cpus",
|
||||
"rand 0.7.3",
|
||||
"schemars",
|
||||
"segment",
|
||||
"serde 1.0.116",
|
||||
"serde_json",
|
||||
@@ -2070,6 +2078,30 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "763f667253711994847f7e73befe859d6fff7bea2b7a7f01669d2c5b60765c37"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"schemars_derive",
|
||||
"serde 1.0.116",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d1d457e2e37415f32b7628ddc5a7fea06ef63bd029ed180d65166e87ca25ce21"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde_derive_internals",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
@@ -2086,6 +2118,7 @@ dependencies = [
|
||||
"memmap 0.7.0",
|
||||
"ordered-float",
|
||||
"rmp-serde",
|
||||
"schemars",
|
||||
"serde 1.0.116",
|
||||
"serde_cbor",
|
||||
"serde_json",
|
||||
@@ -2159,6 +2192,17 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive_internals"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1dbab34ca63057a1f15280bdf3c39f2b1eb1b54c17e98360e511637aef7418c6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.53"
|
||||
@@ -2344,6 +2388,7 @@ dependencies = [
|
||||
"num_cpus",
|
||||
"parking_lot 0.11.0",
|
||||
"rand 0.7.3",
|
||||
"schemars",
|
||||
"segment",
|
||||
"serde 1.0.116",
|
||||
"sled",
|
||||
|
||||
@@ -22,6 +22,7 @@ rand = "0.7.3"
|
||||
serde = { version = "~1.0", features = ["derive"] }
|
||||
serde_yaml = "~0.8"
|
||||
serde_json = "~1.0"
|
||||
schemars = "0.8.0"
|
||||
itertools = "0.9"
|
||||
|
||||
config = "~0.10.1"
|
||||
@@ -29,10 +30,16 @@ config = "~0.10.1"
|
||||
actix-web = "3"
|
||||
tokio = {version = "~0.3", features = ["full"]}
|
||||
|
||||
|
||||
segment = {path = "lib/segment"}
|
||||
collection = {path = "lib/collection"}
|
||||
storage = {path = "lib/storage"}
|
||||
|
||||
[[bin]]
|
||||
name = "schema_generator"
|
||||
path = "src/schema_generator.rs"
|
||||
test = false
|
||||
bench = false
|
||||
|
||||
[workspace]
|
||||
members = ["lib/*"]
|
||||
|
||||
@@ -33,3 +33,4 @@ segment = {path = "../segment"}
|
||||
|
||||
itertools = "0.9"
|
||||
indicatif = "0.15.0"
|
||||
schemars = "0.8.0"
|
||||
@@ -5,9 +5,10 @@ use segment::types::SegmentConfig;
|
||||
use crate::segment_manager::optimizers::merge_optimizer::MergeOptimizer;
|
||||
use std::path::Path;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
pub struct OptimizersConfig {
|
||||
pub deleted_threshold: f64,
|
||||
pub vacuum_min_vector_number: usize,
|
||||
|
||||
@@ -3,8 +3,9 @@ pub mod point_ops;
|
||||
pub mod payload_ops;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[serde(untagged)]
|
||||
pub enum CollectionUpdateOperations {
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
use serde;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
use segment::types::{PointIdType, PayloadKeyType, PayloadType, GeoPoint};
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[serde(untagged)]
|
||||
pub enum PayloadVariant<T> {
|
||||
@@ -23,7 +24,7 @@ impl<T: Clone> PayloadVariant<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[serde(tag = "type", content = "value")]
|
||||
pub enum PayloadInterface {
|
||||
@@ -46,7 +47,7 @@ impl PayloadInterface {
|
||||
|
||||
|
||||
/// Define operations description for point payloads manipulation
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PayloadOps {
|
||||
/// Overrides
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
use segment::types::{PointIdType, PayloadKeyType};
|
||||
use crate::operations::types::VectorType;
|
||||
use std::collections::HashMap;
|
||||
use crate::operations::payload_ops::PayloadInterface;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct PointStruct {
|
||||
pub id: PointIdType,
|
||||
@@ -13,7 +14,7 @@ pub struct PointStruct {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PointInsertOps {
|
||||
#[serde(rename = "batch")]
|
||||
@@ -27,7 +28,7 @@ pub enum PointInsertOps {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum PointOps {
|
||||
/// Insert or update points
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
use segment::types::{VectorElementType, PointIdType, TheMap, PayloadKeyType, PayloadType, SeqNumberType, Filter, SearchParams, SegmentConfig};
|
||||
use serde;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
|
||||
/// Type of vector in API
|
||||
pub type VectorType = Vec<VectorElementType>;
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct Record {
|
||||
pub id: PointIdType,
|
||||
@@ -14,7 +15,7 @@ pub struct Record {
|
||||
pub vector: Option<Vec<VectorElementType>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
pub struct CollectionInfo {
|
||||
pub vectors_count: usize,
|
||||
pub segments_count: usize,
|
||||
@@ -24,7 +25,7 @@ pub struct CollectionInfo {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, PartialEq)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum UpdateStatus {
|
||||
Acknowledged,
|
||||
@@ -32,7 +33,7 @@ pub enum UpdateStatus {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct UpdateResult {
|
||||
pub operation_id: SeqNumberType,
|
||||
@@ -40,7 +41,7 @@ pub struct UpdateResult {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct SearchRequest {
|
||||
pub vector: Vec<VectorElementType>,
|
||||
|
||||
@@ -23,3 +23,4 @@ thiserror = "1.0"
|
||||
atomic_refcell = "0.1.6"
|
||||
atomicwrites = "0.2.5"
|
||||
memmap = "0.7.0"
|
||||
schemars = "0.8.0"
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
use std::cmp::{Ordering};
|
||||
use ordered_float::OrderedFloat;
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
@@ -17,7 +18,7 @@ pub type TagType = u64;
|
||||
pub type VectorElementType = f64;
|
||||
|
||||
/// Type of internal tags, build from payload
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, Copy)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone, Copy)]
|
||||
pub enum Distance {
|
||||
Cosine,
|
||||
Euclid,
|
||||
@@ -29,7 +30,7 @@ pub enum Order {
|
||||
SmallBetter,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize, Copy, Clone, PartialEq, Debug)]
|
||||
#[derive(Deserialize, Serialize, JsonSchema, Copy, Clone, PartialEq, Debug)]
|
||||
pub struct ScoredPoint {
|
||||
pub idx: PointIdType,
|
||||
pub score: ScoreType,
|
||||
@@ -50,7 +51,7 @@ impl PartialOrd for ScoredPoint {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone, Copy, PartialEq)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone, Copy, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SegmentType {
|
||||
/// Segment cheap insert & delete operations
|
||||
@@ -62,7 +63,7 @@ pub enum SegmentType {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone, Copy, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct SegmentInfo {
|
||||
pub segment_type: SegmentType,
|
||||
@@ -74,7 +75,7 @@ pub struct SegmentInfo {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone, Copy, PartialEq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum SearchParams {
|
||||
Hnsw {
|
||||
@@ -91,7 +92,7 @@ pub fn distance_order(distance: &Distance) -> Order {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Copy, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[serde(tag = "type", content = "options")]
|
||||
pub enum Indexes {
|
||||
@@ -109,7 +110,7 @@ impl Default for Indexes {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Copy, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Copy, Clone, PartialEq, Eq)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[serde(tag = "type", content = "options")]
|
||||
pub enum StorageType {
|
||||
@@ -124,7 +125,7 @@ impl Default for StorageType {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct SegmentConfig {
|
||||
pub vector_size: usize,
|
||||
@@ -133,21 +134,21 @@ pub struct SegmentConfig {
|
||||
pub storage_type: StorageType
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct SegmentState {
|
||||
pub version: SeqNumberType,
|
||||
pub config: SegmentConfig,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GeoPoint {
|
||||
pub lon: f64,
|
||||
pub lat: f64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
#[serde(tag = "type", content = "value")]
|
||||
pub enum PayloadType {
|
||||
@@ -158,7 +159,7 @@ pub enum PayloadType {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct Match {
|
||||
pub key: PayloadKeyType,
|
||||
@@ -166,7 +167,7 @@ pub struct Match {
|
||||
pub integer: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct Range {
|
||||
pub key: PayloadKeyType,
|
||||
@@ -176,7 +177,7 @@ pub struct Range {
|
||||
pub lte: Option<f64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct GeoBoundingBox {
|
||||
pub key: PayloadKeyType,
|
||||
@@ -185,7 +186,7 @@ pub struct GeoBoundingBox {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum Condition {
|
||||
Filter(Filter),
|
||||
@@ -195,7 +196,7 @@ pub enum Condition {
|
||||
HasId(HashSet<PointIdType>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct Filter {
|
||||
pub should: Option<Vec<Condition>>,
|
||||
|
||||
@@ -16,7 +16,7 @@ rand = "0.7.3"
|
||||
wal = { git = "https://github.com/generall/wal.git" }
|
||||
tokio = {version = "~0.3", features = ["rt-multi-thread"]}
|
||||
serde = { version = "~1.0", features = ["derive"] }
|
||||
|
||||
schemars = "0.8.0"
|
||||
|
||||
|
||||
segment = {path = "../segment"}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
use segment::types::{Distance, Indexes};
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AliasOperations {
|
||||
CreateAlias {
|
||||
collection_name: String,
|
||||
@@ -16,21 +18,19 @@ pub enum AliasOperations {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum StorageOps {
|
||||
/// Create new collection and (optionally) specify index params
|
||||
CreateCollection {
|
||||
name: String,
|
||||
dim: usize,
|
||||
vector_size: usize,
|
||||
distance: Distance,
|
||||
index: Option<Indexes>,
|
||||
},
|
||||
/// Drop collection
|
||||
DeleteCollection {
|
||||
collection_name: String,
|
||||
},
|
||||
/// Perform changes of index aliases
|
||||
/// Delete collection with given name
|
||||
DeleteCollection(String),
|
||||
/// Perform changes of collection aliases
|
||||
ChangeAliases {
|
||||
actions: Vec<AliasOperations>,
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ impl TableOfContent {
|
||||
match operation {
|
||||
StorageOps::CreateCollection {
|
||||
name: collection_name,
|
||||
dim,
|
||||
vector_size,
|
||||
distance,
|
||||
index
|
||||
} => {
|
||||
@@ -168,7 +168,7 @@ impl TableOfContent {
|
||||
|
||||
|
||||
let segment_config = SegmentConfig {
|
||||
vector_size: dim,
|
||||
vector_size,
|
||||
index: index.unwrap_or(Default::default()),
|
||||
distance,
|
||||
storage_type: Default::default(),
|
||||
@@ -187,7 +187,7 @@ impl TableOfContent {
|
||||
write_collections.insert(collection_name, Arc::new(segment));
|
||||
Ok(true)
|
||||
}
|
||||
StorageOps::DeleteCollection { collection_name } => {
|
||||
StorageOps::DeleteCollection(collection_name) => {
|
||||
let removed = self.collections.write().remove(&collection_name).is_some();
|
||||
if removed {
|
||||
let path = self.get_collection_path(&collection_name);
|
||||
|
||||
@@ -1,22 +1,23 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
use collection::collection_builder::optimizers_builder::OptimizersConfig;
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
pub struct PerformanceConfig {
|
||||
pub max_search_threads: usize,
|
||||
pub max_optimize_threads: usize,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
pub struct WalConfig {
|
||||
pub wal_capacity_mb: usize,
|
||||
pub wal_segments_ahead: usize,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema, Clone)]
|
||||
pub struct StorageConfig {
|
||||
pub storage_path: String,
|
||||
pub optimizers: OptimizersConfig,
|
||||
|
||||
187
openapi/openapi.yaml
Normal file
187
openapi/openapi.yaml
Normal file
@@ -0,0 +1,187 @@
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: Qdrant API
|
||||
description: "API description for Qdrant vector search engine. Describes CRUD and search operations on collections of points (vectors with payload)."
|
||||
contact:
|
||||
email: andrey@vasnetsov.com
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
version: 0.1.0
|
||||
externalDocs:
|
||||
description: Find out more about Qdrant
|
||||
url: https://github.com/generall/qdrant
|
||||
servers:
|
||||
- url: http://localhost:6333/
|
||||
tags:
|
||||
- name: collection
|
||||
description: Searchable collection of points.
|
||||
- name: point
|
||||
description: Float-point vector with payload.
|
||||
|
||||
paths:
|
||||
/collections:
|
||||
get:
|
||||
tags:
|
||||
- collection
|
||||
summary: Get list of existing collections
|
||||
operationId: get_collections
|
||||
responses:
|
||||
200:
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
time:
|
||||
type: number
|
||||
format: float
|
||||
description: Time spent to process this request
|
||||
status:
|
||||
type: string
|
||||
enum: ["Ok"]
|
||||
result:
|
||||
$ref: "./models.json#/definitions/CollectionsResponse"
|
||||
default:
|
||||
description: error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
post:
|
||||
tags:
|
||||
- collection
|
||||
summary: Perform update operation on collections
|
||||
operationId: update_collections
|
||||
requestBody:
|
||||
description: Operation to perform on collections
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "./models.json#/definitions/StorageOps"
|
||||
responses:
|
||||
200:
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
time:
|
||||
type: number
|
||||
format: float
|
||||
description: Time spent to process this request
|
||||
status:
|
||||
type: string
|
||||
enum: ["Ok"]
|
||||
result:
|
||||
type: boolean
|
||||
default:
|
||||
description: error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
/collections/{name}:
|
||||
get:
|
||||
tags:
|
||||
- collection
|
||||
summary: Get information about existing collection
|
||||
operationId: get_collection
|
||||
parameters:
|
||||
- name: name
|
||||
in: path
|
||||
description: Name of the collection to retrieve
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
time:
|
||||
type: number
|
||||
format: float
|
||||
description: Time spent to process this request
|
||||
status:
|
||||
type: string
|
||||
enum: ["Ok"]
|
||||
result:
|
||||
$ref: "./models.json#/definitions/CollectionInfo"
|
||||
default:
|
||||
description: error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
|
||||
/collections/{name}/vectors/{id}:
|
||||
get:
|
||||
tags:
|
||||
- point
|
||||
summary: Retrieve point by id
|
||||
operationId: get_point
|
||||
parameters:
|
||||
- name: name
|
||||
in: path
|
||||
description: Name of the collection to retrieve from
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: id
|
||||
in: path
|
||||
description: Id of the point
|
||||
required: true
|
||||
schema:
|
||||
type: integer
|
||||
responses:
|
||||
200:
|
||||
description: successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
time:
|
||||
type: number
|
||||
format: float
|
||||
description: Time spent to process this request
|
||||
status:
|
||||
type: string
|
||||
enum: ["Ok"]
|
||||
result:
|
||||
$ref: "./models.json#/definitions/Record"
|
||||
default:
|
||||
description: error
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorResponse"
|
||||
|
||||
|
||||
components:
|
||||
schemas:
|
||||
ErrorResponse:
|
||||
type: object
|
||||
properties:
|
||||
time:
|
||||
type: number
|
||||
format: float
|
||||
description: Time spent to process this request
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: string
|
||||
description: Description of the occurred error.
|
||||
result:
|
||||
type: object
|
||||
nullable: true
|
||||
0
openapi/schemas/.keep
Normal file
0
openapi/schemas/.keep
Normal file
@@ -1,14 +1,15 @@
|
||||
use serde;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct CollectionDescription {
|
||||
pub name: String
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct CollectionsResponse {
|
||||
pub collections: Vec<CollectionDescription>
|
||||
|
||||
@@ -3,37 +3,49 @@ use storage::content_manager::toc::TableOfContent;
|
||||
use crate::common::helpers::process_response;
|
||||
use actix_web::rt::time::Instant;
|
||||
use segment::types::PointIdType;
|
||||
use serde::{Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
use storage::content_manager::errors::StorageError;
|
||||
use collection::operations::types::Record;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct VectorRequest {
|
||||
#[derive(Deserialize, Serialize, JsonSchema)]
|
||||
pub struct PointRequest {
|
||||
pub ids: Vec<PointIdType>
|
||||
}
|
||||
|
||||
#[get("/collections/{name}/vectors/{id}")]
|
||||
pub async fn get_vector(
|
||||
#[get("/collections/{name}/points/{id}")]
|
||||
pub async fn get_point(
|
||||
toc: web::Data<TableOfContent>,
|
||||
web::Path((name, vector_ids)): web::Path<(String, PointIdType)>,
|
||||
web::Path((name, point_id)): web::Path<(String, PointIdType)>,
|
||||
) -> impl Responder {
|
||||
let timing = Instant::now();
|
||||
|
||||
let response = {
|
||||
toc.get_collection(&name)
|
||||
.and_then(|collection| collection
|
||||
.retrieve(&vec![vector_ids], true, true)
|
||||
.retrieve(&vec![point_id], true, true)
|
||||
.map_err(|err| err.into())
|
||||
.map(|points| points.into_iter().next())
|
||||
)
|
||||
};
|
||||
|
||||
let response = match response {
|
||||
Ok(record) => match record {
|
||||
None => Err(StorageError::NotFound { description: format!("Point with id {} does not exists!", point_id) }),
|
||||
Some(record) => Ok(record)
|
||||
},
|
||||
Err(e) => Err(e)
|
||||
};
|
||||
|
||||
process_response(response, timing)
|
||||
}
|
||||
|
||||
|
||||
#[post("/collections/{name}/vectors")]
|
||||
#[post("/collections/{name}/points")]
|
||||
pub async fn get_vectors(
|
||||
toc: web::Data<TableOfContent>,
|
||||
web::Path(name): web::Path<String>,
|
||||
request: web::Json<VectorRequest>,
|
||||
request: web::Json<PointRequest>,
|
||||
) -> impl Responder {
|
||||
let timing = Instant::now();
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use actix_web::rt::time::Instant;
|
||||
use std::sync::Arc;
|
||||
use collection::operations::types::SearchRequest;
|
||||
|
||||
#[post("/collections/{name}/vectors/search")]
|
||||
#[post("/collections/{name}/points/search")]
|
||||
pub async fn search_vectors(
|
||||
toc: web::Data<TableOfContent>,
|
||||
web::Path(name): web::Path<String>,
|
||||
|
||||
@@ -4,10 +4,10 @@ use actix_web::rt::time::Instant;
|
||||
use crate::common::helpers::process_response;
|
||||
use collection::operations::CollectionUpdateOperations;
|
||||
use actix_web::web::Query;
|
||||
use serde::{Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use schemars::{JsonSchema};
|
||||
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[derive(Deserialize, Serialize, JsonSchema)]
|
||||
pub struct UpdateParam {
|
||||
pub wait: Option<bool>
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use serde::{Serialize, Deserialize};
|
||||
use schemars::{JsonSchema};
|
||||
use std::fmt::Debug;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[derive(Debug, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum ApiStatus {
|
||||
Ok,
|
||||
@@ -9,7 +10,7 @@ pub enum ApiStatus {
|
||||
}
|
||||
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[derive(Debug, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub struct ApiResponse<D: Serialize + Debug> {
|
||||
pub result: Option<D>,
|
||||
|
||||
@@ -14,7 +14,7 @@ use env_logger;
|
||||
use storage::content_manager::toc::TableOfContent;
|
||||
use crate::api::collections_api::{get_collections, update_collections, get_collection};
|
||||
use crate::api::update_api::update_vectors;
|
||||
use crate::api::retrieve_api::{get_vectors, get_vector};
|
||||
use crate::api::retrieve_api::{get_vectors, get_point};
|
||||
use crate::api::search_api::search_vectors;
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ async fn main() -> std::io::Result<()> {
|
||||
.service(update_collections)
|
||||
.service(get_collection)
|
||||
.service(update_vectors)
|
||||
.service(get_vector)
|
||||
.service(get_point)
|
||||
.service(get_vectors)
|
||||
.service(search_vectors)
|
||||
;
|
||||
|
||||
44
src/schema_generator.rs
Normal file
44
src/schema_generator.rs
Normal file
@@ -0,0 +1,44 @@
|
||||
mod common;
|
||||
mod api;
|
||||
|
||||
use schemars::{schema_for, JsonSchema};
|
||||
use serde_json;
|
||||
use std::path::{Path};
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
|
||||
use crate::api::models::CollectionsResponse;
|
||||
use crate::api::retrieve_api::PointRequest;
|
||||
|
||||
use collection::operations::types::{CollectionInfo, Record, SearchRequest, UpdateResult};
|
||||
use storage::content_manager::storage_ops::StorageOps;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use segment::types::ScoredPoint;
|
||||
use collection::operations::CollectionUpdateOperations;
|
||||
|
||||
#[derive(Deserialize, Serialize, JsonSchema)]
|
||||
struct AllDefinitions {
|
||||
a1: CollectionsResponse,
|
||||
a2: CollectionInfo,
|
||||
a3: StorageOps,
|
||||
a4: PointRequest,
|
||||
a5: Record,
|
||||
a6: SearchRequest,
|
||||
a7: ScoredPoint,
|
||||
a8: UpdateResult,
|
||||
a9: CollectionUpdateOperations,
|
||||
}
|
||||
|
||||
|
||||
fn save_schema<T:JsonSchema>(path: &Path) {
|
||||
let schema = schema_for!(T);
|
||||
let mut file = File::create(path).unwrap();
|
||||
|
||||
let schema_str = serde_json::to_string_pretty(&schema).unwrap();
|
||||
file.write_all(schema_str.as_bytes()).unwrap();
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
save_schema::<AllDefinitions>("./openapi/schemas/AllDefinitions.json".as_ref());
|
||||
}
|
||||
26
tools/generate_openapi_models.sh
Normal file
26
tools/generate_openapi_models.sh
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
# This script generate model definitions for OpenAPI 3.0 documentation
|
||||
|
||||
set -e
|
||||
|
||||
# Ensure current path is project root
|
||||
cd "$(dirname "$0")/../"
|
||||
|
||||
cargo run --package qdrant --bin schema_generator
|
||||
|
||||
(
|
||||
cd tools/schema2openapi/
|
||||
docker build . --tag schema2openapi
|
||||
)
|
||||
|
||||
docker run --rm \
|
||||
-v $(pwd)/openapi/schemas/AllDefinitions.json:/app/schema.json \
|
||||
schema2openapi | sed -e 's/"type": "null"/"nullable": true/g' >./openapi/models.json
|
||||
|
||||
# (cd tools/openapi-merge/ ; docker build . --tag merge-openapi)
|
||||
|
||||
echo "WARNING: This file is auto-generated. Do NOT edit it manually!" >./openapi/openapi-merged.yaml
|
||||
|
||||
docker run \
|
||||
-v $(pwd)/openapi:/project \
|
||||
wework/speccy resolve /project/openapi.yaml >>./openapi/openapi-merged.yaml
|
||||
9
tools/schema2openapi/Dockerfile
Normal file
9
tools/schema2openapi/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
||||
FROM node:lts-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN npm install
|
||||
|
||||
CMD ["node", "convert.js"]
|
||||
16
tools/schema2openapi/convert.js
Normal file
16
tools/schema2openapi/convert.js
Normal file
@@ -0,0 +1,16 @@
|
||||
const toOpenApi = require('@openapi-contrib/json-schema-to-openapi-schema');
|
||||
|
||||
const fs = require('fs');
|
||||
|
||||
let rawdata = fs.readFileSync('schema.json');
|
||||
|
||||
let schema = JSON.parse(rawdata);
|
||||
|
||||
(async () => {
|
||||
const convertedSchema = await toOpenApi(schema);
|
||||
console.log(JSON.stringify(convertedSchema, null, 4));
|
||||
})();
|
||||
|
||||
|
||||
|
||||
|
||||
149
tools/schema2openapi/package-lock.json
generated
Normal file
149
tools/schema2openapi/package-lock.json
generated
Normal file
@@ -0,0 +1,149 @@
|
||||
{
|
||||
"name": "tools",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@cloudflare/json-schema-walker": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@cloudflare/json-schema-walker/-/json-schema-walker-0.1.1.tgz",
|
||||
"integrity": "sha512-P3n0hEgk1m6uKWgL4Yb1owzXVG4pM70G4kRnDQxZXiVvfCRtaqiHu+ZRiRPzmwGBiLTO1LWc2yR1M8oz0YkXww=="
|
||||
},
|
||||
"@openapi-contrib/json-schema-to-openapi-schema": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@openapi-contrib/json-schema-to-openapi-schema/-/json-schema-to-openapi-schema-1.2.0.tgz",
|
||||
"integrity": "sha512-oCxl/vecpA25UzI2zg11ekz9vEaXYEVtwC5krbjZw38qPUsvuYLjs/llFSjn9LjxPA+eMEARcXG/BmZZDLrt8w==",
|
||||
"requires": {
|
||||
"@cloudflare/json-schema-walker": "^0.1.1",
|
||||
"@stoplight/json-ref-resolver": "^2.3.0",
|
||||
"@stoplight/yaml": "^3.7.1",
|
||||
"node-fetch": "^2.6.0",
|
||||
"tslib": "^1.11.1"
|
||||
}
|
||||
},
|
||||
"@stoplight/json": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.9.0.tgz",
|
||||
"integrity": "sha512-jgEKIPMLbhaU5Nw9yw+VBw2OSfDxm8VQ/k5JNezAuDMjcmqCPz3rOQTVNOROStzi70l4DRxF7eBN9liYJq5Ojw==",
|
||||
"requires": {
|
||||
"@stoplight/ordered-object-literal": "^1.0.1",
|
||||
"@stoplight/types": "^11.9.0",
|
||||
"jsonc-parser": "~2.2.1",
|
||||
"lodash": "^4.17.15",
|
||||
"safe-stable-stringify": "^1.1"
|
||||
}
|
||||
},
|
||||
"@stoplight/json-ref-resolver": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@stoplight/json-ref-resolver/-/json-ref-resolver-2.4.1.tgz",
|
||||
"integrity": "sha512-y9G0BybShiJ/1NaPPG1BPelL2zI8/0rKXRtUpD2JBHEb72L9n4Bin85+MfrHYoHeJxojDpewsJA3FVRnUVL1dw==",
|
||||
"requires": {
|
||||
"@stoplight/json": "^3.1.2",
|
||||
"@stoplight/path": "^1.3.0",
|
||||
"@stoplight/types": "^11.0.0",
|
||||
"@types/urijs": "1.x.x",
|
||||
"dependency-graph": "~0.8.0",
|
||||
"fast-memoize": "^2.5.1",
|
||||
"immer": "^3.2.0",
|
||||
"lodash": "^4.17.15",
|
||||
"tslib": "^1.10.0",
|
||||
"urijs": "~1.19.1"
|
||||
}
|
||||
},
|
||||
"@stoplight/ordered-object-literal": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@stoplight/ordered-object-literal/-/ordered-object-literal-1.0.1.tgz",
|
||||
"integrity": "sha512-kDcBIKwzAXZTkgzaiPXH2I0JXavBkOb3jFzYNFS5cBuvZS3s/K+knpk2wLVt0n8XrnRQsSffzN6XG9HqUhfq6Q=="
|
||||
},
|
||||
"@stoplight/path": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@stoplight/path/-/path-1.3.2.tgz",
|
||||
"integrity": "sha512-lyIc6JUlUA8Ve5ELywPC8I2Sdnh1zc1zmbYgVarhXIp9YeAB0ReeqmGEOWNtlHkbP2DAA1AL65Wfn2ncjK/jtQ=="
|
||||
},
|
||||
"@stoplight/types": {
|
||||
"version": "11.9.0",
|
||||
"resolved": "https://registry.npmjs.org/@stoplight/types/-/types-11.9.0.tgz",
|
||||
"integrity": "sha512-4bzPpWZobt0e+d0OtALCJyl1HGzKo6ur21qxnId9dTl8v3yeD+5HJKZ2h1mv7e94debH5QDtimMU80V6jbXM8Q==",
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.4",
|
||||
"utility-types": "^3.10.0"
|
||||
}
|
||||
},
|
||||
"@stoplight/yaml": {
|
||||
"version": "3.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@stoplight/yaml/-/yaml-3.8.1.tgz",
|
||||
"integrity": "sha512-wbhcgo7dTjwjjwFziC/SAcQlwPucYhYq6vjzyOjj8zeOVnnmoa7hzU1i9Kj31473FG/re7xtt6j3LWu2VnYbxg==",
|
||||
"requires": {
|
||||
"@stoplight/ordered-object-literal": "^1.0.1",
|
||||
"@stoplight/types": "^11.1.1",
|
||||
"@stoplight/yaml-ast-parser": "0.0.45",
|
||||
"lodash": "^4.17.15"
|
||||
}
|
||||
},
|
||||
"@stoplight/yaml-ast-parser": {
|
||||
"version": "0.0.45",
|
||||
"resolved": "https://registry.npmjs.org/@stoplight/yaml-ast-parser/-/yaml-ast-parser-0.0.45.tgz",
|
||||
"integrity": "sha512-0MTEvgp3XMdeMUSTCGiNECuC+YlLbzytDEIOJVDHrrmzVZpIR3gGnHI6mmPI4P7saPxUiHxFF2uuoTuCNlKjrw=="
|
||||
},
|
||||
"@types/json-schema": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz",
|
||||
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw=="
|
||||
},
|
||||
"@types/urijs": {
|
||||
"version": "1.19.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/urijs/-/urijs-1.19.12.tgz",
|
||||
"integrity": "sha512-+BmVXyxXCmGuS177d6yj9zt3tBugh35ZIPgYTWctDf2/LwGirIWIyaH01dmTzxjro6LNiaYIIj3jveKetMmZ1A=="
|
||||
},
|
||||
"dependency-graph": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.8.1.tgz",
|
||||
"integrity": "sha512-g213uqF8fyk40W8SBjm079n3CZB4qSpCrA2ye1fLGzH/4HEgB6tzuW2CbLE7leb4t45/6h44Ud59Su1/ROTfqw=="
|
||||
},
|
||||
"fast-memoize": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-memoize/-/fast-memoize-2.5.2.tgz",
|
||||
"integrity": "sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw=="
|
||||
},
|
||||
"immer": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/immer/-/immer-3.3.0.tgz",
|
||||
"integrity": "sha512-vlWRjnZqoTHuEjadquVHK3GxsXe1gNoATffLEA8Qbrdd++Xb+wHEFiWtwAKTscMBoi1AsvEMXhYRzAXA8Ex9FQ=="
|
||||
},
|
||||
"jsonc-parser": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz",
|
||||
"integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w=="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
|
||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||
},
|
||||
"safe-stable-stringify": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-1.1.1.tgz",
|
||||
"integrity": "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw=="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||
},
|
||||
"urijs": {
|
||||
"version": "1.19.2",
|
||||
"resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.2.tgz",
|
||||
"integrity": "sha512-s/UIq9ap4JPZ7H1EB5ULo/aOUbWqfDi7FKzMC2Nz+0Si8GiT1rIEaprt8hy3Vy2Ex2aJPpOQv4P4DuOZ+K1c6w=="
|
||||
},
|
||||
"utility-types": {
|
||||
"version": "3.10.0",
|
||||
"resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.10.0.tgz",
|
||||
"integrity": "sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg=="
|
||||
}
|
||||
}
|
||||
}
|
||||
15
tools/schema2openapi/package.json
Normal file
15
tools/schema2openapi/package.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "tools",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "convert.js",
|
||||
"dependencies": {
|
||||
"@openapi-contrib/json-schema-to-openapi-schema": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"convert": "node convert.js"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
||||
217
tools/schema2openapi/schema.json
Normal file
217
tools/schema2openapi/schema.json
Normal file
@@ -0,0 +1,217 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "StorageOps",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Create new collection and (optionally) specify index params",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"create_collection"
|
||||
],
|
||||
"properties": {
|
||||
"create_collection": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"distance",
|
||||
"name",
|
||||
"vector_size"
|
||||
],
|
||||
"properties": {
|
||||
"distance": {
|
||||
"$ref": "#/definitions/Distance"
|
||||
},
|
||||
"index": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/Indexes"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"vector_size": {
|
||||
"type": "integer",
|
||||
"format": "uint",
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Delete collection with given name",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"delete_collection"
|
||||
],
|
||||
"properties": {
|
||||
"delete_collection": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Perform changes of collection aliases",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"change_aliases"
|
||||
],
|
||||
"properties": {
|
||||
"change_aliases": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"actions"
|
||||
],
|
||||
"properties": {
|
||||
"actions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/AliasOperations"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"definitions": {
|
||||
"AliasOperations": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"create_alias"
|
||||
],
|
||||
"properties": {
|
||||
"create_alias": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"alias_name",
|
||||
"collection_name"
|
||||
],
|
||||
"properties": {
|
||||
"alias_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"collection_name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"delete_alias"
|
||||
],
|
||||
"properties": {
|
||||
"delete_alias": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"alias_name"
|
||||
],
|
||||
"properties": {
|
||||
"alias_name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"rename_alias"
|
||||
],
|
||||
"properties": {
|
||||
"rename_alias": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"new_alias_name",
|
||||
"old_alias_name"
|
||||
],
|
||||
"properties": {
|
||||
"new_alias_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"old_alias_name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Distance": {
|
||||
"description": "Type of internal tags, build from payload",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Cosine",
|
||||
"Euclid",
|
||||
"Dot"
|
||||
]
|
||||
},
|
||||
"Indexes": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"options",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"options": {
|
||||
"type": "object"
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"plain"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"options",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"options": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"ef_construct",
|
||||
"m"
|
||||
],
|
||||
"properties": {
|
||||
"ef_construct": {
|
||||
"type": "integer",
|
||||
"format": "uint",
|
||||
"minimum": 0.0
|
||||
},
|
||||
"m": {
|
||||
"type": "integer",
|
||||
"format": "uint",
|
||||
"minimum": 0.0
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"hnsw"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user