Skip to content

Commit

Permalink
Merge pull request #38 from phiHero/conversation
Browse files Browse the repository at this point in the history
feat: add conversation API & doc: update README API documentation
  • Loading branch information
jasonbosco authored Aug 30, 2024
2 parents f0f1c03 + 900c067 commit 67cc20a
Show file tree
Hide file tree
Showing 16 changed files with 661 additions and 30 deletions.
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

0 comments on commit 67cc20a

Please sign in to comment.