# Influxdb client package

**URL:** https://discourse.julialang.org/t/influxdb-client-package/82890
**Category:** Data
**Tags:** database
**Created:** [June 16, 2022, 6:05pm UTC](https://discourse.julialang.org/t/influxdb-client-package/82890 "2022-06-16T18:05:52Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![gmouts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gmouts/32/9896_2.png) [@gmouts](https://discourse.julialang.org/u/gmouts)
#### Post date: [June 16, 2022, 6:05pm UTC](https://discourse.julialang.org/t/influxdb-client-package/82890/1 "2022-06-16T18:05:52Z")

</div>

I’m looking into getting data from influxdb. I found this [package](https://github.com/staticfloat/InfluxDB.jl) but it seems abandoned. Is this functionality added somewhere else or this is all there is?

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [June 17, 2022, 4:32am UTC](https://discourse.julialang.org/t/influxdb-client-package/82890/2 "2022-06-17T04:32:05Z")

</div>

Would you consider using the Python client library ([Use the InfluxDB Python client library | InfluxDB OSS 2.2 Documentation](https://docs.influxdata.com/influxdb/v2.2/api-guide/client-libraries/python/)) with PythonCall ([GitHub - cjdoris/PythonCall.jl: Python and Julia in harmony.](https://github.com/cjdoris/PythonCall.jl))? Or you can use the R client library ([GitHub - influxdata/influxdb-client-r: InfluxDB (v2+) Client R Package](https://github.com/influxdata/influxdb-client-r)) with RCall ([Getting Started · RCall.jl](https://juliainterop.github.io/RCall.jl/stable/gettingstarted/)).

---

<div class="post-metadata">

### Author: ![gmouts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gmouts/32/9896_2.png) [@gmouts](https://discourse.julialang.org/u/gmouts)
#### Post date: [June 17, 2022, 10:35am UTC](https://discourse.julialang.org/t/influxdb-client-package/82890/3 "2022-06-17T10:35:11Z")

</div>

Since I only need to read data, I copy-pasted code from the package and tweaked it a bit and it works 🙂

So I guess the answer to my question is that this package is all there is for now, right?

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [June 17, 2022, 10:57am UTC](https://discourse.julialang.org/t/influxdb-client-package/82890/4 "2022-06-17T10:57:02Z")

</div>

> [@gmouts](#):
>
> it works 🙂

Glad to hear. Looks like that’s all there is (maybe it’s all you need?); there is also this other personal repo [GitHub - tallakt/InfluxFlux](https://github.com/tallakt/InfluxFlux), a one-file module.

---

<div class="post-metadata">

### Author: ![adenoz](https://avatars.discourse-cdn.com/v4/letter/a/22d042/32.png) [@adenoz](https://discourse.julialang.org/u/adenoz)
#### Post date: [July 20, 2022, 6:58am UTC](https://discourse.julialang.org/t/influxdb-client-package/82890/5 "2022-07-20T06:58:30Z")

</div>

Are you able to share the minimal code you used to access an influxdb database? I’ll be looking to doing this after I’ve finished working through PostgreSQL databases.

---

<div class="post-metadata">

### Author: ![gmouts](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gmouts/32/9896_2.png) [@gmouts](https://discourse.julialang.org/u/gmouts)
#### Post date: [July 25, 2022, 5:41pm UTC](https://discourse.julialang.org/t/influxdb-client-package/82890/6 "2022-07-25T17:41:29Z")

</div>

Sure. But use it with caution!

```julia
using JSON, HTTP
using HTTP.URIs: URI
import Base: write
using MacroTools
using DataFrames
using Dates

struct InfluxServer
    endpoint::URI
    username::Union{String,Nothing}
    password::Union{String,Nothing}

    function InfluxServer(address::AbstractString; username=nothing, password=nothing)
        if isnothing(match(r"^https?://", address))
            address = "http://$address"
        end
        uri = URI(address)

        if isempty(uri.port)
            uri = Base.merge(uri, port=8086)
        end

        return new(uri, username, password)
    end
end

struct Query
    verb::String
    fields::Vector{String}
    tags::Vector{String}
    measurements::Vector{String}
    condition::Union{String,Nothing}
    order::Union{String,Nothing}
    limit::Union{Int,Nothing}
end

function authenticate!(server::InfluxServer, query::Dict)
    if server.username != nothing && server.password != nothing
        query["u"] = server.username
        query["p"] = server.password
    end
end

function query(server::InfluxServer, query_data::Dict; type::Symbol = :get)
    authenticate!(server, query_data)

    if type == :get
        response = HTTP.get(string(server.endpoint, "/query"); query=query_data)
    else
        response = HTTP.post(string(server.endpoint, "/query"); query=query_data)
    end
    
    response_data = String(response.body)
    if response.status != 200
        error(response_data)
    end
        
    response = JSON.parse(response_data)

    if !haskey(response, "results") || !haskey(response["results"][1], "series")
        return
    end
        
    function series_df(series_dict)
        df = DataFrame()
        for name_idx in 1:length(series_dict["columns"])
            col = Symbol(series_dict["columns"][name_idx])
            df[!, col] = [x[name_idx] for x in series_dict["values"]]
        end
        return df
    end
        
    return series_df.(response["results"][1]["series"])
end
    
query(server::InfluxServer, data::AbstractString; kwargs...) = query(server, Dict("q" => data); kwargs...)

query(server::InfluxServer, db::AbstractString, q::Query) = query(server, Dict("q" => payload(q), "db" => db))

querify(e) = string(e)
querify(e::Symbol) = string("\"", e, "\"")
querify(e::AbstractString) = string("'", e, "'")
querify(e::QuoteNode) = querify(e.value)
function querify(e::Expr)
    args = e.args
    head = e.head

    # Peel :call and :macrocall nodes first
    if head == :call
        head = args[1]
        args = args[2:end]
    elseif head == :macrocall && length(args) == 3 && args[2] == nothing
        head = args[1]
        args = args[3:end]
    end

    if head == :&&
        head = "AND"
    elseif head == :||
        head = "OR"
    elseif head == Symbol("==")
        head = "="
    elseif head == :~
        head = "=~"
    elseif head == Symbol("@r_str")
        return string("/", args[1], "/")
    else
        head = string(head)
    end

    return string(querify(args[1]), " ", head, " ", querify(args[2]))
end

macro querify(ex)
    return querify(MacroTools.striplines(ex))
end

function Query(verb::String; fields::Vector = String[],
                             tags::Vector = String[],
                             measurements::Vector = String[],
                             condition::Union{String,Nothing} = nothing,
                             order::Union{String,Nothing} = nothing,
                             limit::Union{Int,Nothing} = nothing)
    if isempty(fields) && !isempty(tags)
        @warn(
            "InfluxDB has strange behavior when 'fields' is empty but 'tags' is not!",
            "https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/#selecting-tag-keys-in-the-select-clause",
        )
    end
    
    return Query(
        verb,
        String.(fields),
        String.(tags),
        String.(measurements),
        condition,
        order,
        limit,
    )
end

SELECT(;kwargs...) = Query("SELECT"; kwargs...)

function join_typed(io, v::Vector, type_name, delim = ",")
    if isempty(v)
        return
    end
    
    write(io, "\"", v[1], "\"", "::", type_name)
    for idx in 2:length(v)
        write(io, delim, "\"", v[idx], "\"", "::", type_name)
    end
end

function payload(q::Query)
    buff = IOBuffer()
    payload!(buff, q)
    return String(take!(buff))
end

function payload!(io::IO, q::Query)
    write(io, q.verb, " ")
    
    if isempty(q.fields)
        write(io, "*")
    else
        join_typed(io, q.fields, "field")
        if !isempty(q.tags)
            write(io, ",")
            join_typed(io, q.tags, "tag")
        end
    end
    
    if !isempty(q.measurements)
        write(io, " FROM ")
        join(io, [string("\"", m, "\"") for m in q.measurements], ",")
    end

    if q.condition != nothing
        write(io, " WHERE ")
        write(io, q.condition)
    end

    if q.order != nothing
        write(io, " order by ")
        write(io, q.order)
    end

    if q.limit != nothing
        write(io, " LIMIT ", string(q.limit))
    end
end

function list_measurements(server::InfluxServer, db::AbstractString)
    return query(server, "SHOW MEASUREMENTS ON $db")
end

```

After that, I do:

```julia
q = Query("SELECT", measurements=["measurement_name"], order="time desc", limit=10000)
s = InfluxServer("localhost")
df = query(s, "db_name", q)[1]

```

Read through the definition of `Query` to see how to construct more complicated queries.

I hope it helps!

---

<div class="post-metadata">

### Author: ![adenoz](https://avatars.discourse-cdn.com/v4/letter/a/22d042/32.png) [@adenoz](https://discourse.julialang.org/u/adenoz)
#### Post date: [August 7, 2022, 2:19am UTC](https://discourse.julialang.org/t/influxdb-client-package/82890/7 "2022-08-07T02:19:53Z")

</div>

I know I’m late replying but I did note this when posted. Your response is much appreciated! I’ll use this when I do get to working on influxdb use.

---

<div class="post-metadata">

### Author: ![ashleysommer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashleysommer/32/35964_2.png) [@ashleysommer](https://discourse.julialang.org/u/ashleysommer)
#### Post date: [August 17, 2022, 3:38am UTC](https://discourse.julialang.org/t/influxdb-client-package/82890/8 "2022-08-17T03:38:30Z")

</div>

It looks like this is client code using the SQL-like query protocol used in InfluxDB v1.8, is that right?  
InfluxDB v2.0+ uses a much different query protocol.

---

<div class="post-metadata">

### Author: ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)
#### Post date: [October 12, 2022, 10:08am UTC](https://discourse.julialang.org/t/influxdb-client-package/82890/9 "2022-10-12T10:08:42Z")

</div>

I drafted this pkg for Influxdb V2.  
It is in a relatively rough state. I fulfills my current needs though.

> **[GitHub - kafisatz/InfluxDBClient.jl: A Julia client for InfluxDB V2 OSS](https://github.com/kafisatz/InfluxDBClient.jl)**
>
> A Julia client for InfluxDB V2 OSS. Contribute to kafisatz/InfluxDBClient.jl development by creating an account on GitHub.
