Skip to content
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
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## major.minor.patch (yyyy.mm.dd)

## 0.5.2 (2025.01.16)

### Changed

* Documentation typos
* Tidy documentation flow

### Added

* Error status code missing from creating a snapshot
* More test coverage

## 0.5.1 (2025.01.12)

### Removed
Expand Down
74 changes: 43 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,27 @@ if config_env() == :prod do # if you'll use this in prod environment
...
```

> **Note**: The `options` key can be used to pass additional configuration options such as custom Finch instance or receive timeout settings. You can add any options supported by Req here. For more details check [Req documentation](https://hexdocs.pm/req/Req.Steps.html#run_finch/1-request-options).
> #### `options` key {: .tip}
>
> The `options` key can be used to pass additional configuration
> options such as custom Finch instance or receive timeout
> settings. You can add any options supported by Req here. For
> more details check [Req documentation](https://hexdocs.pm/req/Req.Steps.html#run_finch/1-request-options).

```
config :open_api_typesense,
api_key: "credential", # Admin API key
host: "111222333aaabbbcc-9.x9.typesense.net", # Nodes
port: 443,
scheme: "https"
options: [finch: MyApp.CustomFinch] # <- add options
```

> #### during tests {: .tip}
>
> If you have a different config for your app, consider
> adding it in `config/test.exs`.

> **Note**: If you use this for adding tests in your app, you might want to add this in `config/test.exs`:

For Cloud hosted, you can generate and obtain the credentials from cluster instance admin interface:

Expand Down Expand Up @@ -85,8 +103,15 @@ called `request` that contains 2 args:
Here's a custom client example ([`HTTPoison`](https://hexdocs.pm/httpoison/readme.html))
in order to match the usage:

<!-- tabs-open -->

### Client module

```elixir
defmodule MyApp.CustomClient do
@behaviour OpenApiTypesense.Client

@impl OpenApiTypesense.Client
def request(conn, params) do
url = %URI{
scheme: conn.scheme,
Expand All @@ -102,7 +127,7 @@ defmodule MyApp.CustomClient do
request =
if params[:request] do
[{content_type, _schema}] = params.request

headers = [
{"X-TYPESENSE-API-KEY", conn.api_key}
{"Content-Type", content_type}
Expand All @@ -125,41 +150,28 @@ defmodule MyApp.CustomClient do
end
```

Then add your client in your config file:
### Client config

```elixir
config :open_api_typesense,
api_key: "credential", # Admin API key
host: "111222333aaabbbcc-9.x9.typesense.net", # Nodes
port: 443,
scheme: "https",
api_key: "xyz", # Admin API key
host: "localhost", # Nodes
port: 8108,
scheme: "http",
client: MyApp.CustomClient # <- add this
```

And here's a reference taken from one of functions from [`Collections`](https://hexdocs.pm/open_api_typesense/OpenApiTypesense.Collections.html#create_collection/3), as
you may want to match the params:
<!-- tabs-close -->

Check [the examples](./guides/custom_http_client.md) on some HTTP client implementations.

## Adding [cache, retry, compress_body](https://hexdocs.pm/req/Req.html#new/1) in the built in client

E.g. when a user wants to change `retry` and `cache` options

```elixir
def create_collection(%Connection{} = conn, body, opts) when is_struct(conn) do
client = opts[:client] || @default_client
query = Keyword.take(opts, [:src_name])

client.request(conn, %{
args: [body: body],
call: {OpenApiTypesense.Collections, :create_collection},
url: "/collections",
body: body,
method: :post,
query: query,
request: [{"application/json", {OpenApiTypesense.CollectionSchema, :t}}],
response: [
{201, {OpenApiTypesense.CollectionResponse, :t}},
{400, {OpenApiTypesense.ApiResponse, :t}},
{409, {OpenApiTypesense.ApiResponse, :t}}
],
opts: opts
})
end
ExTypesense.get_collection("companies", req: [retry: false, cache: true])
```

Check [the examples](./guides/custom_http_client.md) on some HTTP client implementations.
See implementation [OpenApiTypesense.Client](`OpenApiTypesense.Client`) https://github.com/jaeyson/open_api_typesense/blob/main/lib/open_api_typesense/client.ex

73 changes: 56 additions & 17 deletions guides/custom_http_client.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ config :open_api_typesense,

```elixir
defmodule CustomClient do
@behaviour OpenApiTypesense.Client

@impl OpenApiTypesense.Client
def request(conn, params) do
uri =
%URI{
Expand Down Expand Up @@ -84,6 +87,9 @@ end

```elixir
defmodule MyApp.CustomClient do
@behaviour OpenApiTypesense.Client

@impl OpenApiTypesense.Client
def request(conn, params) do
url = %URI{
scheme: conn.scheme,
Expand Down Expand Up @@ -126,6 +132,9 @@ end

```elixir
defmodule MyApp.CustomClient do
@behaviour OpenApiTypesense.Client

@impl OpenApiTypesense.Client
def request(conn, params) do
url = %URI{
scheme: conn.scheme,
Expand Down Expand Up @@ -169,6 +178,9 @@ end

```elixir
defmodule MyApp.CustomClient do
@behaviour OpenApiTypesense.Client

@impl OpenApiTypesense.Client
def request(conn, params) do
url = %URI{
scheme: conn.scheme,
Expand Down Expand Up @@ -252,27 +264,15 @@ end

## [Finch](https://hexdocs.pm/finch)

Add to your supervision tree:

```elixir
# e.g. lib/my_app/application.ex
@impl true
def start(_type, _args) do
children = [
# Starts a worker by calling: Githubber.Worker.start_link(arg)
# {Githubber.Worker, arg}
{Finch, name: MyFinch} # <- add this
]
<!-- tabs-open -->

# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Githubber.Supervisor]
Supervisor.start_link(children, opts)
end
```
### Client

```elixir
defmodule MyApp.CustomClient do
@behaviour OpenApiTypesense.Client

@impl OpenApiTypesense.Client
def request(conn, _params) do
uri = %URI{
scheme: conn.scheme,
Expand Down Expand Up @@ -314,15 +314,44 @@ defmodule MyApp.CustomClient do
end
```

### `application.ex`

Add to your supervision tree:

```elixir
# e.g. lib/my_app/application.ex
@impl true
def start(_type, _args) do
children = [
# Starts a worker by calling: Githubber.Worker.start_link(arg)
# {Githubber.Worker, arg}
{Finch, name: MyFinch} # <- add this
]

# See https://hexdocs.pm/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: Githubber.Supervisor]
Supervisor.start_link(children, opts)
end
```

<!-- tabs-close -->

## [Tesla](https://hexdocs.pm/tesla)

<!-- tabs-open -->

### Adapter

```elixir
# e.g. config/config.exs
import Config

config :tesla, adapter: Tesla.Adapter.Hackney
```

### Config

```elixir
# e.g. config/runtime.exs
config :open_api_typesense,
Expand All @@ -333,8 +362,13 @@ config :open_api_typesense,
client: MyApp.CustomClient
```

### Client

```elixir
defmodule MyApp.CustomClient do
@behaviour OpenApiTypesense.Client

@impl OpenApiTypesense.Client
def request(conn, params) do
url =
%URI{
Expand Down Expand Up @@ -385,10 +419,15 @@ defmodule MyApp.CustomClient do
end
```

<!-- tabs-close -->

## [`:gun`](https://hexdocs.pm/gun)

```elixir
defmodule MyApp.CustomClient do
@behaviour OpenApiTypesense.Client

@impl OpenApiTypesense.Client
def request(conn, params) do
# Open a connection
{:ok, pid} =
Expand Down
14 changes: 5 additions & 9 deletions lib/open_api_typesense/client.ex
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,7 @@ defmodule OpenApiTypesense.Client do
# end
# end

defp parse_resp(%Req.TransportError{} = error, _opts_resp) do
{:error, Exception.message(error)}
end

defp parse_resp(%Req.HTTPError{} = error, _opts_resp) do
{:error, Exception.message(error)}
end

defp parse_resp(resp, opts_resp) do
defp parse_resp(%Req.Response{} = resp, opts_resp) do
{code, values} =
opts_resp
|> Enum.find(fn {code, _values} ->
Expand All @@ -184,6 +176,10 @@ defmodule OpenApiTypesense.Client do
parse_values(code, values, resp.body)
end

defp parse_resp(error, _opts_resp) do
{:error, Exception.message(error)}
end

@spec parse_values(
non_neg_integer(),
atom() | list() | tuple(),
Expand Down
4 changes: 4 additions & 0 deletions lib/open_api_typesense/connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ defmodule OpenApiTypesense.Connection do

@doc since: "0.2.0"
@spec new(t() | map()) :: %__MODULE__{}
def new(%__MODULE__{} = connection) when is_struct(connection) do
connection
end

def new(connection) when is_map(connection) do
missing_fields = Enum.sort(required_fields() -- Map.keys(connection))

Expand Down
13 changes: 12 additions & 1 deletion lib/open_api_typesense/operations/curation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ defmodule OpenApiTypesense.Curation do

@doc """
List all collection overrides

## Options

* `limit`: Limit results in paginating on collection listing.
* `offset`: Skip a certain number of results and start after that.

"""
@spec get_search_overrides(String.t()) ::
{:ok, OpenApiTypesense.SearchOverridesResponse.t()} | :error
Expand Down Expand Up @@ -109,13 +115,18 @@ defmodule OpenApiTypesense.Curation do

def get_search_overrides(%Connection{} = conn, collectionName, opts) when is_struct(conn) do
client = opts[:client] || @default_client
query = Keyword.take(opts, [:limit, :offset])

client.request(conn, %{
args: [collectionName: collectionName],
call: {OpenApiTypesense.Curation, :get_search_overrides},
url: "/collections/#{collectionName}/overrides",
method: :get,
response: [{200, {OpenApiTypesense.SearchOverridesResponse, :t}}],
query: query,
response: [
{200, {OpenApiTypesense.SearchOverridesResponse, :t}},
{404, {OpenApiTypesense.ApiResponse, :t}}
],
opts: opts
})
end
Expand Down
6 changes: 5 additions & 1 deletion lib/open_api_typesense/operations/documents.ex
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,11 @@ defmodule OpenApiTypesense.Documents do
method: :post,
query: query,
request: [{"application/json", :map}],
response: [{201, :map}, {404, {OpenApiTypesense.ApiResponse, :t}}],
response: [
{201, :map},
{404, {OpenApiTypesense.ApiResponse, :t}},
{409, {OpenApiTypesense.ApiResponse, :t}}
],
opts: opts
})
end
Expand Down
10 changes: 3 additions & 7 deletions lib/open_api_typesense/operations/health.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,14 @@ defmodule OpenApiTypesense.Health do
"""
@spec health(Connection.t() | map() | keyword()) ::
{:ok, OpenApiTypesense.HealthStatus.t()} | :error
def health(%Connection{} = conn) when is_struct(conn) do
health(conn, [])
def health(opts) when is_list(opts) do
health(Connection.new(), opts)
end

def health(conn) when not is_struct(conn) and is_map(conn) do
def health(conn) do
health(conn, [])
end

def health(opts) when is_list(opts) do
health(Connection.new(), opts)
end

@doc """
Either one of:
- `health(%{api_key: xyz, host: ...}, opts)`
Expand Down
5 changes: 4 additions & 1 deletion lib/open_api_typesense/operations/operations.ex
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ defmodule OpenApiTypesense.Operations do
url: "/operations/snapshot",
method: :post,
query: query,
response: [{201, {OpenApiTypesense.SuccessStatus, :t}}],
response: [
{201, {OpenApiTypesense.SuccessStatus, :t}},
{409, {OpenApiTypesense.ApiResponse, :t}}
],
opts: opts
})
end
Expand Down
Loading