Current section

Files

Jump to
qlik_elixir lib qlik_elixir.ex
Raw

lib/qlik_elixir.ex

defmodule QlikElixir do
@moduledoc """
An Elixir client library for uploading CSV files to Qlik Cloud.
## Installation
Add `qlik_elixir` to your list of dependencies in `mix.exs`:
def deps do
[
{:qlik_elixir, "~> 0.1.0"}
]
end
## Configuration
Configure the client using environment variables:
export QLIK_API_KEY="your-api-key"
export QLIK_TENANT_URL="https://your-tenant.qlikcloud.com"
export QLIK_CONNECTION_ID="your-connection-id" # Optional
Or configure in your application config:
config :qlik_elixir,
api_key: "your-api-key",
tenant_url: "https://your-tenant.qlikcloud.com",
connection_id: "your-connection-id"
## Usage
# Upload a file
{:ok, %{"id" => file_id}} = QlikElixir.upload_csv("data.csv")
# Upload with options
QlikElixir.upload_csv("data.csv",
name: "custom_name.csv",
connection_id: "space-123",
overwrite: true
)
# Upload content directly
csv_content = "header1,header2\\nvalue1,value2"
QlikElixir.upload_csv_content(csv_content, "dynamic.csv")
# List files
{:ok, files} = QlikElixir.list_files()
# Check if file exists
QlikElixir.file_exists?("data.csv")
# Delete a file
QlikElixir.delete_file("file-id-123")
"""
alias QlikElixir.{Client, Config, Error, Uploader}
alias QlikElixir.REST.Helpers
@doc """
Uploads a CSV file from a file path.
## Options
* `:name` - Custom filename for the upload (defaults to original filename)
* `:connection_id` - Qlik connection ID (overrides configured default)
* `:overwrite` - Whether to overwrite existing files (default: false)
* `:config` - Custom configuration (overrides defaults)
## Examples
iex> QlikElixir.upload_csv("data.csv")
{:ok, %{"id" => "file-123", "name" => "data.csv", "size" => 1024}}
iex> QlikElixir.upload_csv("data.csv", name: "renamed.csv", overwrite: true)
{:ok, %{"id" => "file-456", "name" => "renamed.csv", "size" => 1024}}
"""
@spec upload_csv(String.t(), keyword()) :: {:ok, map()} | {:error, Error.t()}
def upload_csv(file_path, opts \\ []) do
config = get_config(opts)
Uploader.upload_file(file_path, config, opts)
end
@doc """
Uploads CSV content directly.
## Options
* `:connection_id` - Qlik connection ID (overrides configured default)
* `:overwrite` - Whether to overwrite existing files (default: false)
* `:config` - Custom configuration (overrides defaults)
## Examples
iex> content = "id,name\\n1,John\\n2,Jane"
iex> QlikElixir.upload_csv_content(content, "users.csv")
{:ok, %{"id" => "file-789", "name" => "users.csv", "size" => 28}}
"""
@spec upload_csv_content(binary(), String.t(), keyword()) :: {:ok, map()} | {:error, Error.t()}
def upload_csv_content(content, filename, opts \\ []) do
config = get_config(opts)
Uploader.upload_content(content, filename, config, opts)
end
@doc """
Lists uploaded files.
## Options
* `:limit` - Maximum number of files to return (default: 100)
* `:offset` - Number of files to skip (default: 0)
* `:config` - Custom configuration (overrides defaults)
## Examples
iex> QlikElixir.list_files()
{:ok, %{
"data" => [
%{"id" => "file-123", "name" => "data.csv", "size" => 1024},
%{"id" => "file-456", "name" => "users.csv", "size" => 2048}
],
"total" => 2
}}
iex> QlikElixir.list_files(limit: 10, offset: 20)
{:ok, %{"data" => [%{"id" => "file-789", "name" => "logs.csv", "size" => 512}], "total" => 50}}
"""
@spec list_files(keyword()) :: {:ok, map()} | {:error, Error.t()}
def list_files(opts \\ []) do
params =
[limit: Keyword.get(opts, :limit, 100), offset: Keyword.get(opts, :offset, 0)]
|> add_if(Keyword.get(opts, :includeAllSpaces, false), :includeAllSpaces, true)
query = QlikElixir.Pagination.build_query(params)
Client.get("api/v1/data-files?#{query}", get_config(opts))
end
defp add_if(params, true, key, value), do: Keyword.put(params, key, value)
defp add_if(params, false, _key, _value), do: params
@doc """
Deletes a file by ID.
## Examples
iex> QlikElixir.delete_file("file-123")
:ok
iex> QlikElixir.delete_file("non-existent")
{:error, %QlikElixir.Error{type: :file_not_found}}
"""
@spec delete_file(String.t(), keyword()) :: :ok | {:error, Error.t()}
def delete_file(file_id, opts \\ []) do
config = get_config(opts)
case Client.delete("api/v1/data-files/#{file_id}", config) do
{:ok, _} -> :ok
error -> error
end
end
@doc """
Checks if a file exists by name.
## Examples
iex> QlikElixir.file_exists?("data.csv")
true
iex> QlikElixir.file_exists?("non-existent.csv")
false
"""
@spec file_exists?(String.t(), keyword()) :: boolean()
def file_exists?(filename, opts \\ []) do
case find_file_by_name(filename, opts) do
{:ok, _} -> true
_ -> false
end
end
@doc """
Finds a file by name.
## Examples
iex> QlikElixir.find_file_by_name("data.csv")
{:ok, %{"id" => "file-123", "name" => "data.csv", "size" => 1024}}
iex> QlikElixir.find_file_by_name("non-existent.csv")
{:error, %QlikElixir.Error{type: :file_not_found}}
"""
@spec find_file_by_name(String.t(), keyword()) :: {:ok, map()} | {:error, Error.t()}
def find_file_by_name(filename, opts \\ []) do
config = get_config(opts)
case Client.get("api/v1/data-files?limit=100", config) do
{:ok, %{"data" => files}} ->
case Enum.find(files, fn file -> file["name"] == filename end) do
nil -> {:error, Error.file_not_found("File not found: #{filename}")}
file -> {:ok, file}
end
error ->
error
end
end
@doc """
Creates a new configuration struct.
This is useful when you need to work with multiple Qlik tenants or want to
override the default configuration.
## Examples
iex> config = QlikElixir.Config.new(
...> api_key: "different-key",
...> tenant_url: "https://other-tenant.qlikcloud.com"
...> )
iex> QlikElixir.upload_csv("data.csv", config: config)
"""
defdelegate new_config(opts), to: Config, as: :new
# Delegate to shared helper to avoid duplication
defp get_config(opts), do: Helpers.get_config(opts)
end