3 releases
0.2.2 | Feb 17, 2024 |
---|---|
0.2.1 | Feb 10, 2024 |
0.2.0 | Nov 25, 2023 |
0.1.0 |
|
#1522 in Database interfaces
51 downloads per month
345KB
5.5K
SLoC
Weaviate Community
Community client for handling Weaviate vector database transactions written in Rust, for Rust.
More information on Weaviate can be found on the official Weaviate webpage.
Installation
Run the following in your project directory
cargo add weaviate-community
or add the following to your Cargo.toml
file
weaviate-community = "0.2.2"
Documentation
The library reference documentation can be found here
Usage
Below are some examples on how to interact with the Weaviate community Rust client.
Creating a new WeaviateClient
use std::error::Error;
use weaviate_community::WeaviateClient;
use weaviate_community::collections::auth::AuthApiKey;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// With anonymous access
let client = WeaviateClient::builder("http://localhost:8080")
.build()?;
// With Auth key
let client = WeaviateClient::builder("http://localhost:8080")
.with_auth_secret("your-key")
.build()?;
// With multiple other API key (eg, OpenAI, JinaAI, ..)
let client = WeaviateClient::builder("http://localhost:8080")
.with_auth_secret("your-key")
.with_api_key("X-OpenAI-Api-Key", "abcdefg")
.with_api_key("X-Jinaai-Api-Key", "hijklmn")
.build()?;
Ok(())
}
Schema endpoints
use weaviate_community::collections::schema::{
Class,
Property,
ShardStatus,
Tenants,
Tenant,
ActivityStatus
};
async fn schema_endpoints(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// Get full schema
let res = client.schema.get().await?;
// Get the schema for a single class
let res = client.schema.get_class("Article").await?;
// Create a new class in the schema
let my_class = Class::builder("Article").with_description("News article").build();
let res = client.schema.create_class(&my_class).await?;
// Update a class in the schema
let my_class = Class::builder("Article").with_description("Updated information").build();
let res = client.schema.update(&my_class).await?;
// Add a property to a class
let property = Property::builder("title", vec!["text"]).build();
let res = client.schema.add_property("Article", &property).await?;
// Get the shards for a class
let res = client.schema.get_shards("Article").await?;
// Update a class shard
let res = client.schema.update_class_shard("Article", "abcdefg", ShardStatus::READONLY).await?;
// List tenants for a class
let res = client.schema.list_tenants("Article").await?;
// Add tenants to a class
let tenants = Tenants::new(vec![Tenant::builder("TENANT_B").build()]);
let res = client.schema.add_tenants("Article", &tenants).await?;
// Update tenants
let tenants = Tenants::new(
vec![
Tenant::builder("TENANT_B").with_activity_status(ActivityStatus::COLD).build()
]
);
let res = client.schema.update_tenants("Article", &tenants).await?;
// Remove tenants from a class
let tenants = vec!["TENANT_B"];
let res = client.schema.add_tenants("Article", &tenants).await?;
// Delete a class from the schema
let res = client.schema.delete("Article").await?;
Ok(())
}
Objects endpoints
use uuid::Uuid;
use weaviate_community::collections::objects::{Object, ObjectListParameters};
async fn objects_endpoints(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// List every single object
let res = client.objects.list(ObjectListParameters::new()).await?;
// List all objects for a single class
let params = ObjectListParameters::builder().with_class_name("Article").build();
let res = client.objects.list(params).await?;
// Create a new object
let my_object = Object::builder("Article", serde_json::json!({})).build();
let res = client.objects.create(&my_object, None).await?;
// Get an object based on its UUID
let uuid = Uuid::new_v4();
let res = client.objects.get("Article", uuid, None, None, None).await?;
// Check if a data object exists
let uuid = Uuid::new_v4();
let res = client.objects.exists("Article", uuid, None, None).await?;
// Update a data object
let uuid = Uuid::parse_str("ee22d1b8-3b95-4e94-96d5-9a2b60fbd303")?;
let properties = serde_json::json!({
"title": "new title",
});
let res = client.objects.update(&properties, "Article", &uuid, None).await?;
// Replace a data object
let uuid = Uuid::parse_str("ee22d1b8-3b95-4e94-96d5-9a2b60fbd303")?;
let properties = serde_json::json!({
"properties": {
"author": "Jodi Kantor",
}
});
let res = client.objects.replace(&properties, "Publication", &uuid, None).await?;
// Delete a data object
let uuid = Uuid::parse_str("ee22d1b8-3b95-4e94-96d5-9a2b60fbd303")?;
let res = client.objects.delete("Article", &uuid, None, None).await?;
// Validate a data object
let properties = serde_json::json!({
"name": "New York Times"
});
let uuid = Uuid::parse_str("12345678-1234-1234-1234-123456789012")?;
let res = client.objects.validate("Publication", &properties, &uuid).await?;
// Add a cross-reference
let uuid1 = Uuid::parse_str("12345678-1234-1234-1234-123456789012")?;
let uuid2 = Uuid::parse_str("20ffc68d-986b-5e71-a680-228dba18d7ef")?;
let reference = Reference::new(
"JeopardyQuestion",
&uuid1,
"hasCategory",
"JeopardyCategory",
&uuid2,
);
let res = client.objects.reference_add(reference).await?;
// Update a cross-reference
let uuid1 = Uuid::parse_str("12345678-1234-1234-1234-123456789012")?;
let uuid2 = Uuid::parse_str("20ffc68d-986b-5e71-a680-228dba18d7ef")?;
let res = client.objects.reference_update(
"JeopardyQuestion",
&uuid1,
"hasCategory",
vec!["JeopardyCategory"],
vec![&uuid2],
None,
None
).await?;
// Delete a cross-reference
let uuid1 = Uuid::parse_str("12345678-1234-1234-1234-123456789012")?;
let uuid2 = Uuid::parse_str("20ffc68d-986b-5e71-a680-228dba18d7ef")?;
let reference = Reference::new(
"JeopardyQuestion",
&uuid1,
"hasCategory",
"JeopardyCategory",
&uuid2,
);
let res = client.objects.reference_delete(reference).await?;
Ok(())
}
Backups endpoints
use weaviate_community::collections::backups::{
BackupCreateRequest,
BackupRestoreRequest,
BackupBackends
};
async fn backups_endpoints(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// Create a new backup - with wait for completion
let req = BackupCreateRequest::builder("my-backup").build();
let res = client.backups.create(BackupBackends::FILESYSTEM, req, true).await?;
// Create a new backup - without wait for completion
let req = BackupCreateRequest::builder("my-backup").build();
let res = client.backups.create(BackupBackends::FILESYSTEM, req, false).await?;
// Get the status of a backup create
let res = client.backups.get_backup_status(
BackupBackends::FILESYSTEM,
"my-backup",
false
).await?;
// Restore a backup - with wait for completion
let req = BackupRestoreRequest::builder().build();
let res = client.backups.restore(BackupBackends::FILESYSTEM, "my-backup", req, true).await?;
// Restore a backup - without wait for completion
let req = BackupRestoreRequest::builder().build();
let res = client.backups.restore(BackupBackends::FILESYSTEM, "my-backup", req, false).await?;
// Get the status of a backup restore
let res = client.backups.get_backup_status(
BackupBackends::FILESYSTEM,
"my-backup",
true
).await?;
Ok(())
}
Batch endpoints
use uuid::Uuid;
use weaviate_community::collections::objects::{
Object,
MultiObject,
Reference,
References,
ConsistencyLevel,
};
use weaviate_community::collections::batch::{BatchDeleteRequest, MatchConfig};
async fn batch_endpoints(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// Batch add objects
let author_uuid = Uuid::parse_str("36ddd591-2dee-4e7e-a3cc-eb86d30a4303").unwrap();
let article_a_uuid = Uuid::parse_str("6bb06a43-e7f0-393e-9ecf-3c0f4e129064").unwrap();
let article_b_uuid = Uuid::parse_str("b72912b9-e5d7-304e-a654-66dc63c55b32").unwrap();
let article_a = Object::builder("Article", serde_json::json!({}))
.with_id(article_a_uuid.clone())
.build();
let article_b = Object::builder("Article", serde_json::json!({}))
.with_id(article_b_uuid.clone())
.build();
let author = Object::builder("Author", serde_json::json!({}))
.with_id(author_uuid.clone())
.build();
let res = client.batch.objects_batch_add(
MultiObjects::new(
vec![article_a, article_b, author]),
Some(ConsistencyLevel::ALL),
None
).await?;
// Batch delete objects
let req = BatchDeleteRequest::builder(
MatchConfig::new(
"Article",
serde_json::json!({
"operator": "Like",
"path": ["id"],
"valueText": "*4*",
})
)
).build();
let res = client.batch.objects_batch_delete(
req,
Some(ConsistencyLevel::ALL),
None
).await?;
// Batch add references
let references = References::new(vec![
Reference::new(
"Author",
&author_uuid,
"wroteArticles",
"Article",
&article_a_uuid,
),
Reference::new(
"Author",
&author_uuid,
"wroteArticles",
"Article",
&article_b_uuid,
),
]);
let res = client.batch.references_batch_add(
references,
Some(ConsistencyLevel::ALL),
None
).await?;
Ok(())
}
Meta endpoint
async fn meta_endpoint(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// Get database metadata
let res = client.meta.get_meta().await?;
Ok(())
}
Nodes endpoint
async fn nodes_endpoint(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// Get the nodes status'
let res = client.nodes.get_nodes_status().await?;
Ok(())
}
OIDC endpoint
async fn oidc_endpoint(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// Get the OIDC config
let res = client.oidc.get_open_id_configuration().await?;
Ok(())
}
Querying
use weaviate_community::collections::query::{
GetQuery,
AggregateQuery,
ExploreQuery,
RawQuery
};
async fn querying(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// Get
let query = GetQuery::builder(
"JeopardyQuestion",
vec![
"question",
"answer",
"points",
"hasCategory { ... on JeopardyCategory { title }}"
])
.with_limit(1)
.with_additional(vec!["id"])
.build();
let res = client.query.get(query).await?;
// Aggregate
let query = AggregateQuery::builder("Article")
.with_meta_count()
.with_fields(vec!["wordCount {count maximum mean median minimum mode sum type}"])
.build();
let res = client.query.aggregate(query).await?;
// Explore
let query = ExploreQuery::builder()
.with_limit(1)
.with_near_vector("{vector: [-0.36840257,0.13973749,-0.28994447]}")
.with_fields(vec!["beacon", "className", "certainty"])
.build();
let res = client.query.explore(query).await?;
// Raw
let query = RawQuery::new("{ Get { JeopardyQuestion { question answer points } } }");
let res = client.query.raw(query).await?;
Ok(())
}
Health endpoints
async fn health_endpoints(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// Check database is live
let res = client.is_live().await?;
// Check database is ready
let res = client.is_ready().await?;
Ok(())
}
Classification endpoints
use uuid::Uuid;
use weaviate_community::collections::classification::{
ClassificationRequest,
ClassificationType
};
async fn classification_endpoints(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// Schedule a new classification
let req = ClassificationRequest::builder()
.with_type(ClassificationType::KNN)
.with_class("Article")
.with_based_on_properties(vec!["summary"])
.with_classify_properties(vec!["hasPopularity"])
.with_filters(serde_json::json!({
"trainingSetWhere": {
"path": ["wordCount"],
"operator": "GreaterThan",
"valueInt": 100
}
}))
.with_settings(serde_json::json!({
"k": 3
}))
.build();
let res = client.classification.schedule(req).await?;
// Get the status of a classification
let uuid = Uuid::parse_str("00037775-1432-35e5-bc59-443baaef7d80")?;
let res = client.classification.get(uuid).await?;
Ok(())
}
Module (text2vec-contextionary) endpoints
use weaviate_community::collections::modules::ContextionaryExtend;
async fn module_endpoints(client: WeaviateClient) -> Result<(), Box<dyn Error>> {
// Get a concept
let res = client.modules.contextionary_get_concept("magazine").await?;
// Extend contextionary
let ext = ContextionaryExtension::new(
"weaviate",
"Open source cloud native real time vector database",
1.0
);
let res = client.modules.contextionary_extend(ext).await?;
Ok(())
}
Roadmap
- SI test update
- Improvements to the GraphQL query system (and batch delete match config)
- Create full schema in one command
- General improvements to try and remove as much serde_json in the deserialized objects..
- Embedded functionality
- gRPC (after beta testing for official clients)
Contributing
Any bug reports and feature requests welcome on GitHub
License
This project is licensed under the MIT License open-source license.
Dependencies
~6–18MB
~262K SLoC