Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add conversation API & doc: update README API documentation #38

Merged
merged 2 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
mkdir $(pwd)/typesense-data
docker run -p 8108:8108 \
-d \
-v$(pwd)/typesense-data:/data typesense/typesense:27.0.rc35 \
-v$(pwd)/typesense-data:/data typesense/typesense:27.0 \
--data-dir /data \
--api-key=xyz \
--enable-cors
Expand Down
196 changes: 195 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,134 @@ let (data, response) = try await client.collection(name: "schools").documents().

This returns a `SearchResult` object as the data, which can be further parsed as desired.

### Bulk import documents

```swift
let jsonL = Data("{}".utf8)
let (data, response) = try await client.collection(name: "companies").documents().importBatch(jsonL, options: ImportDocumentsParameters(
action: .upsert,
batchSize: 10,
dirtyValues: .drop,
remoteEmbeddingBatchSize: 10,
returnDoc: true,
returnId: false
))
```

### Update multiple documents by query

```swift
let (data, response) = try await client.collection(name: "companies").documents().update(
document: ["company_size": "large"],
options: UpdateDocumentsByFilterParameters(filterBy: "num_employees:>1000")
)
```

### Delete multiple documents by query

```swift
let (data, response) = try await client.collection(name: "companies").documents().delete(
options: DeleteDocumentsParameters(filterBy: "num_employees:>100")
)
```

### Export documents

```swift
let (data, response) = try await client.collection(name: "companies").documents().export(options: ExportDocumentsParameters(excludeFields: "country"))
```

### Create or update a collection alias

```swift
let schema = CollectionAliasSchema(collectionName: "companies_june")
let (data, response) = try await client.aliases().upsert(name: "companies", collection: schema)
```

### Retrieve all aliases

```swift
let (data, response) = try await client.aliases().retrieve()
```

### Retrieve an alias

```swift
let (data, response) = try await client.aliases().retrieve(name: "companies")
```

### Delete an alias

```swift
let (data, response) = try await client.aliases().delete(name: "companies")
```

### Create an API key

```swift
let adminKey = ApiKeySchema(_description: "Test key with all privileges", actions: ["*"], collections: ["*"])
let (data, response) = try await client.keys().create(adminKey)
```

### Retrieve all API keys

```swift
let (data, response) = try await client.keys().retrieve()
```

### Retrieve an API key

```swift
let (data, response) = try await client.keys().retrieve(id: 1)
```

### Delete an API key

```swift
let (data, response) = try await client.keys().delete(id: 1)
```

### Create a conversation model

```swift
let schema = ConversationModelCreateSchema(
_id: "conv-model-1",
modelName: "openai/gpt-3.5-turbo",
apiKey: "OPENAI_API_KEY",
historyCollection: "conversation_store",
systemPrompt: "You are an assistant for question-answering...",
ttl: 10000,
maxBytes: 16384
)
let (data, response) = try await client.conversations().models().create(params: schema)
```

### Retrieve all conversation models

```swift
let (data, response) = try await client.conversations().models().retrieve()
```

### Retrieve a conversation model

```swift
let (data, response) = try await client.conversations().model(modelId: "conv-model-1").retrieve()
```

### Update a conversation model

```swift
let (data, response) = try await client.conversations().model(modelId: "conv-model-1").update(params: ConversationModelUpdateSchema(
systemPrompt: "..."
))
```

### Delete a conversation model

```swift
let (data, response) = try await client.conversations().model(modelId: "conv-model-1").delete()
```

### Create or update an override

```swift
Expand Down Expand Up @@ -187,12 +315,79 @@ let (data, response) = try await client.stopword("stopword_set1").retrieve()
let (data, response) = try await client.stopword("stopword_set1").delete()
```

### Create or update a synonym

```swift
let schema = SearchSynonymSchema(synonyms: ["blazer", "coat", "jacket"])
let (data, response) = try await client.collection(name: "products").synonyms().upsert(id: "coat-synonyms", schema)
```

### Retrieve all synonyms

```swift
let (data, response) = try await client.collection(name: "products").synonyms().retrieve()
```

### Retrieve a synonym

```swift
let (data, response) = try await client.collection(name: "products").synonyms().retrieve(id: "coat-synonyms")
```

### Delete a synonym

```swift
let (data, response) = try await myClient.collection(name: "products").synonyms().delete(id: "coat-synonyms")
```

### Retrieve debug information

```swift
let (data, response) = try await client.operations().getDebug()
```

### Retrieve health status

```swift
let (data, response) = try await client.operations().getHealth()
```

### Retrieve API stats

```swift
let (data, response) = try await client.operations().getStats()
```

### Retrieve Cluster Metrics

```swift
let (data, response) = try await client.operations().getMetrics()
```

### Re-elect Leader

```swift
let (data, response) = try await client.operations().vote()
```

### Toggle Slow Request Log

```swift
let (data, response) = try await client.operations().toggleSlowRequestLog(seconds: 2)
```

### Clear cache

```swift
let (data, response) = try await client.operations().clearCache()
```

### Create Snapshot (for backups)

```swift
let (data, response) = try await client.operations().snapshot(path: "/tmp/typesense-data-snapshot")
```

## Contributing

Issues and pull requests are welcome on GitHub at [Typesense Swift](/~https://github.com/typesense/typesense-swift). Do note that the Models used in the Swift client are generated by [Swagger-Codegen](/~https://github.com/swagger-api/swagger-codegen) and are automated to be modified in order to prevent major errors. So please do use the shell script that is provided in the repo to generate the models:
Expand All @@ -205,5 +400,4 @@ The generated Models (inside the Models directory) are to be used inside the Mod

## TODO: Features

- Dealing with Dirty Data
- Scoped Search Key
4 changes: 4 additions & 0 deletions Sources/Typesense/Client.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ public struct Client {
return Collection(apiCall: apiCall, collectionName: name)
}

public func conversations() -> Conversations {
return Conversations(apiCall: apiCall)
}

public func keys() -> ApiKeys {
return ApiKeys(apiCall: apiCall)
}
Expand Down
48 changes: 48 additions & 0 deletions Sources/Typesense/ConversationModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

public struct ConversationModel {
private var apiCall: ApiCall
var modelId: String

init(apiCall: ApiCall, modelId: String) {
self.apiCall = apiCall
self.modelId = modelId
}

public func update(params: ConversationModelUpdateSchema) async throws -> (ConversationModelSchema?, URLResponse?) {
let schemaData = try encoder.encode(params)
let (data, response) = try await self.apiCall.put(endPoint: endpointPath(), body: schemaData)
if let result = data {
let decodedData = try decoder.decode(ConversationModelSchema.self, from: result)
return (decodedData, response)
}
return (nil, response)
}

public func retrieve() async throws -> (ConversationModelSchema?, URLResponse?) {
let (data, response) = try await self.apiCall.get(endPoint: endpointPath())
if let result = data {
let decodedData = try decoder.decode(ConversationModelSchema.self, from: result)
return (decodedData, response)
}
return (nil, response)
}

public func delete() async throws -> (ConversationModelSchema?, URLResponse?) {
let (data, response) = try await self.apiCall.delete(endPoint: endpointPath())
if let result = data {
let decodedData = try decoder.decode(ConversationModelSchema.self, from: result)
return (decodedData, response)
}
return (nil, response)
}

private func endpointPath() throws -> String {
return try "\(Conversations.RESOURCE_PATH)/\(ConversationModels.RESOURCE_PATH)/\(modelId.encodeURL())"
}


}
39 changes: 39 additions & 0 deletions Sources/Typesense/ConversationModels.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

public struct ConversationModels {
static let RESOURCE_PATH = "models"
private var apiCall: ApiCall


init(apiCall: ApiCall) {
self.apiCall = apiCall
}

public func create(params: ConversationModelCreateSchema) async throws -> (ConversationModelSchema?, URLResponse?) {
let schemaData = try encoder.encode(params)
let (data, response) = try await self.apiCall.post(endPoint: endpointPath(), body: schemaData)
if let result = data {
let decodedData = try decoder.decode(ConversationModelSchema.self, from: result)
return (decodedData, response)
}
return (nil, response)
}

public func retrieve() async throws -> ([ConversationModelSchema]?, URLResponse?) {
let (data, response) = try await self.apiCall.get(endPoint: endpointPath())
if let result = data {
let decodedData = try decoder.decode([ConversationModelSchema].self, from: result)
return (decodedData, response)
}
return (nil, response)
}

private func endpointPath() throws -> String {
return "\(Conversations.RESOURCE_PATH)/\(ConversationModels.RESOURCE_PATH)"
}


}
20 changes: 20 additions & 0 deletions Sources/Typesense/Conversations.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Foundation

public struct Conversations {
static let RESOURCE_PATH = "conversations"
private var apiCall: ApiCall


init(apiCall: ApiCall) {
self.apiCall = apiCall
}

public func models() -> ConversationModels {
return ConversationModels(apiCall: apiCall)
}

public func model(modelId: String) -> ConversationModel {
return ConversationModel(apiCall: apiCall, modelId: modelId)
}

}
Loading
Loading