InfluxDB.Client 4.8.0-dev.9099

This is a prerelease version of InfluxDB.Client.
There is a newer version of this package available.
See the version list below for details.
dotnet add package InfluxDB.Client --version 4.8.0-dev.9099                
NuGet\Install-Package InfluxDB.Client -Version 4.8.0-dev.9099                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="InfluxDB.Client" Version="4.8.0-dev.9099" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add InfluxDB.Client --version 4.8.0-dev.9099                
#r "nuget: InfluxDB.Client, 4.8.0-dev.9099"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install InfluxDB.Client as a Cake Addin
#addin nuget:?package=InfluxDB.Client&version=4.8.0-dev.9099&prerelease

// Install InfluxDB.Client as a Cake Tool
#tool nuget:?package=InfluxDB.Client&version=4.8.0-dev.9099&prerelease                

InfluxDB.Client

CircleCI

The reference client that allows query, write and management (bucket, organization, users) for the InfluxDB 2.x.

Documentation

This section contains links to the client library documentation.

Features

Queries

For querying data we use QueryApi that allow perform asynchronous, streaming, synchronous and also use raw query response.

Asynchronous Query

The asynchronous query is not intended for large query results because the Flux response can be potentially unbound.

using System;
using System.Threading.Tasks;
using InfluxDB.Client;

namespace Examples
{
    public static class AsynchronousQuery
    {
        private static readonly string Token = "";

        public static async Task Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
            
            var queryApi = client.GetQueryApi();

            //
            // QueryData
            //
            var tables = await queryApi.QueryAsync(flux, "org_id");
            tables.ForEach(table =>
            {
                table.Records.ForEach(record =>
                {
                    Console.WriteLine($"{record.GetTime()}: {record.GetValueByKey("_value")}");
                });
            });
        }        
    }
}

The asynchronous query offers a possibility map FluxRecords to POCO:

using System;
using System.Threading.Tasks;
using InfluxDB.Client;
using InfluxDB.Client.Core;

namespace Examples
{
    public static class AsynchronousQuery
    {
        private static readonly string Token = "";

        public static async Task Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
            
            var queryApi = client.GetQueryApi();

            //
            // QueryData
            //
            var temperatures = await queryApi.QueryAsync<Temperature>(flux, "org_id");
            temperatures.ForEach(temperature =>
            {
                Console.WriteLine($"{temperature.Location}: {temperature.Value} at {temperature.Time}");
            });
        }  
        
        [Measurement("temperature")]
        private class Temperature
        {
            [Column("location", IsTag = true)] public string Location { get; set; }

            [Column("value")] public double Value { get; set; }

            [Column(IsTimestamp = true)] public DateTime Time { get; set; }
        }
    }
}

Streaming Query

The Streaming query offers possibility to process unbound query and allow user to handle exceptions, stop receiving more results and notify that all data arrived.

using System;
using System.Threading.Tasks;
using InfluxDB.Client;

namespace Examples
{
    public static class StreamingQuery
    {
        private static readonly string Token = "";

        public static async Task Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";

            var queryApi = client.GetQueryApi();

            //
            // QueryData
            //
            await queryApi.QueryAsync(flux, record =>
            {
                //
                // The callback to consume a FluxRecord.
                //
                Console.WriteLine($"{record.GetTime()}: {record.GetValueByKey("_value")}");
            }, exception =>
            {
                //
                // The callback to consume any error notification.
                //
                Console.WriteLine($"Error occurred: {exception.Message}");
            }, () =>
            {
                //
                // The callback to consume a notification about successfully end of stream.
                //
                Console.WriteLine("Query completed");
            }, "org_id");
        }
    }
}

And there is also a possibility map FluxRecords to POCO:

using System;
using System.Threading.Tasks;
using InfluxDB.Client;
using InfluxDB.Client.Core;

namespace Examples
{
    public static class StreamingQuery
    {
        private static readonly string Token = "";

        public static async Task Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";
            
            var queryApi = client.GetQueryApi();

            //
            // QueryData
            //
            await queryApi.QueryAsync<Temperature>(flux, temperature =>
            {
                //
                // The callback to consume a FluxRecord mapped to POCO.
                //
                Console.WriteLine($"{temperature.Location}: {temperature.Value} at {temperature.Time}");
            }, org: "org_id");
        }  
        
        [Measurement("temperature")]
        private class Temperature
        {
            [Column("location", IsTag = true)] public string Location { get; set; }

            [Column("value")] public double Value { get; set; }

            [Column(IsTimestamp = true)] public DateTime Time { get; set; }
        }
    }
}

Raw Query

The Raw query allows direct processing original CSV response:

using System;
using System.Threading.Tasks;
using InfluxDB.Client;

namespace Examples
{
    public static class RawQuery
    {
        private static readonly string Token = "";

        public static async Task Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";

            var queryApi = client.GetQueryApi();

            //
            // QueryData
            //
            var csv = await queryApi.QueryRawAsync(flux, org: "org_id");
            
            Console.WriteLine($"CSV response: {csv}");
        }
    }
}

The Streaming version allows processing line by line:

using System;
using System.Threading.Tasks;
using InfluxDB.Client;

namespace Examples
{
    public static class RawQueryAsynchronous
    {
        private static readonly string Token = "";

        public static async Task Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            var flux = "from(bucket:\"temperature-sensors\") |> range(start: 0)";

            var queryApi = client.GetQueryApi();

            //
            // QueryData
            //
            await queryApi.QueryRawAsync(flux, line =>
            {
                //
                // The callback to consume a line of CSV response
                //
                Console.WriteLine($"Response: {line}");
            }, org: "org_id");
        }
    }
}

Synchronous query

The synchronous query is not intended for large query results because the response can be potentially unbound.

using System;
using InfluxDB.Client;

namespace Examples
{
    public static class SynchronousQuery
    {
        public static void Main()
        {
            using var client = new InfluxDBClient("http://localhost:9999", "my-token");

            const string query = "from(bucket:\"my-bucket\") |> range(start: 0)";
           
            //
            // QueryData
            //
            var queryApi = client.GetQueryApiSync();
            var tables = queryApi.QuerySync(query, "my-org");
            
            //
            // Process results
            //
            tables.ForEach(table =>
            {
                table.Records.ForEach(record =>
                {
                    Console.WriteLine($"{record.GetTime()}: {record.GetValueByKey("_value")}");
                });
            });
        }
    }
}

Writes

For writing data we use WriteApi or WriteApiAsync which is simplified version of WriteApi without batching support.

WriteApi supports:

  1. writing data using InfluxDB Line Protocol, Data Point, POCO
  2. use batching for writes
  3. produces events that allow user to be notified and react to this events
    • WriteSuccessEvent - published when arrived the success response from server
    • WriteErrorEvent - published when occurs a unhandled exception from server
    • WriteRetriableErrorEvent - published when occurs a retriable error from server
    • WriteRuntimeExceptionEvent - published when occurs a runtime exception in background batch processing
  4. use GZIP compression for data

The writes are processed in batches which are configurable by WriteOptions:

Property Description Default Value
BatchSize the number of data point to collect in batch 1000
FlushInterval the number of milliseconds before the batch is written 1000
JitterInterval the number of milliseconds to increase the batch flush interval by a random amount 0
RetryInterval the number of milliseconds to retry unsuccessful write. The retry interval is used when the InfluxDB server does not specify "Retry-After" header. 5000
MaxRetries the number of max retries when write fails 3
MaxRetryDelay the maximum delay between each retry attempt in milliseconds 125_000
ExponentialBase the base for the exponential retry delay, the next delay is computed using random exponential backoff as a random value within the interval retryInterval * exponentialBase^(attempts-1) and retryInterval * exponentialBase^(attempts). Example for retryInterval=5_000, exponentialBase=2, maxRetryDelay=125_000, maxRetries=5 Retry delays are random distributed values within the ranges of [5_000-10_000, 10_000-20_000, 20_000-40_000, 40_000-80_000, 80_000-125_000] 2

Writing data

By POCO

Write Measurement into specified bucket:

using System;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Core;

namespace Examples
{
    public static class WritePoco
    {
        private static readonly string Token = "";

        public static void Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            //
            // Write Data
            //
            using (var writeApi = client.GetWriteApi())
            {
                //
                // Write by POCO
                //
                var temperature = new Temperature {Location = "south", Value = 62D, Time = DateTime.UtcNow};

                writeApi.WriteMeasurement(temperature, WritePrecision.Ns, "bucket_name", "org_id");
            }
        }
        
        [Measurement("temperature")]
        private class Temperature
        {
            [Column("location", IsTag = true)] public string Location { get; set; }

            [Column("value")] public double Value { get; set; }

            [Column(IsTimestamp = true)] public DateTime Time { get; set; }
        }
    }
}
By Data Point

Write Data point into specified bucket:

using System;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Writes;

namespace Examples
{
    public static class WriteDataPoint
    {
        private static readonly string Token = "";

        public static void Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            //
            // Write Data
            //
            using (var writeApi = client.GetWriteApi())
            {
                //
                // Write by Data Point
                
                var point = PointData.Measurement("temperature")
                    .Tag("location", "west")
                    .Field("value", 55D)
                    .Timestamp(DateTime.UtcNow.AddSeconds(-10), WritePrecision.Ns);
                
                writeApi.WritePoint(point, "bucket_name", "org_id");
            }
        }
    }
}

DataPoint Builder Immutability: The builder is immutable therefore won't have side effect when using for building multiple point with single builder.

using System;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Writes;

namespace Examples
{
    public static class WriteDataPoint
    {
        private static readonly string Token = "";

        public static void Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            //
            // Write Data
            //
            using (var writeApi = client.GetWriteApi())
            {
                //
                // Write by Data Point
                
                var builder = PointData.Measurement("temperature")
                    .Tag("location", "west");
                
                var pointA = builder
                    .Field("value", 55D)
                    .Timestamp(DateTime.UtcNow.AddSeconds(-10), WritePrecision.Ns);
                
                writeApi.WritePoint(pointA, "bucket_name", "org_id");
                
                var pointB = builder
                    .Field("age", 32)
                    .Timestamp(DateTime.UtcNow, WritePrecision.Ns);
                
                writeApi.WritePoint(pointB, "bucket_name", "org_id");
            }
        }
    }
}
By LineProtocol

Write Line Protocol record into specified bucket:

using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;

namespace Examples
{
    public static class WriteLineProtocol
    {
        private static readonly string Token = "";

        public static void Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            //
            // Write Data
            //
            using (var writeApi = client.GetWriteApi())
            {
                //
                //
                // Write by LineProtocol
                //
                writeApi.WriteRecord("temperature,location=north value=60.0", WritePrecision.Ns,"bucket_name", "org_id");
            }
        }
    }
}
Using WriteApiAsync
using System;
using System.Threading.Tasks;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Core;
using InfluxDB.Client.Writes;

namespace Examples
{
    public static class WriteApiAsyncExample
    {   
        [Measurement("temperature")]
        private class Temperature
        {
            [Column("location", IsTag = true)] public string Location { get; set; }

            [Column("value")] public double Value { get; set; }

            [Column(IsTimestamp = true)] public DateTime Time { get; set; }
        }
        
        public static async Task Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", 
                            "my-user", "my-password");

            //
            // Write Data
            //
            var writeApiAsync = client.GetWriteApiAsync();

            //
            //
            // Write by LineProtocol
            //
            await writeApiAsync.WriteRecordAsync("temperature,location=north value=60.0", WritePrecision.Ns,
                "my-bucket", "my-org");

            //
            //
            // Write by Data Point
            //               
            var point = PointData.Measurement("temperature")
                            .Tag("location", "west")
                            .Field("value", 55D)
                            .Timestamp(DateTime.UtcNow.AddSeconds(-10), WritePrecision.Ns);

            await writeApiAsync.WritePointAsync(point, "my-bucket", "my-org");

            //
            // Write by POCO
            //
            var temperature = new Temperature {Location = "south", Value = 62D, Time = DateTime.UtcNow};

            await writeApiAsync.WriteMeasurementAsync(temperature, WritePrecision.Ns, "my-bucket", "my-org");

            //
            // Check written data
            //
            var tables = await influxDbClient.GetQueryApi()
                            .QueryAsync("from(bucket:\"my-bucket\") |> range(start: 0)", "my-org");
            
            tables.ForEach(table =>
            {
                var fluxRecords = table.Records;
                fluxRecords.ForEach(record =>
                {
                    Console.WriteLine($"{record.GetTime()}: {record.GetValue()}");
                });
            });
        }
    }
}
Default Tags

Sometimes is useful to store same information in every measurement e.g. hostname, location, customer. The client is able to use static value, app settings or env variable as a tag value.

The expressions:

  • California Miner - static value
  • ${version} - application settings
  • ${env.hostname} - environment property
Via Configuration file

In a configuration file you are able to specify default tags by tags element.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="influx2" type="InfluxDB.Client.Configurations.Influx2, InfluxDB.Client" />
    </configSections>
    <appSettings>
        <add key="SensorVersion" value="v1.00"/>
    </appSettings>
    <influx2 url="http://localhost:8086"
             org="my-org"
             bucket="my-bucket"
             token="my-token"
             logLevel="BODY"
             timeout="10s">
        <tags>
            <tag name="id" value="132-987-655"/>
            <tag name="customer" value="California Miner"/>
            <tag name="hostname" value="${env.Hostname}"/>
            <tag name="sensor-version" value="${SensorVersion}"/>
        </tags>
    </influx2>
</configuration>
Via API
var options = new InfluxDBClientOptions(Url)
{
    Token = token,
    DefaultTags = new Dictionary<string, string>
    {
        {"id", "132-987-655"},
        {"customer", "California Miner"},
    }
};   
options.AddDefaultTag("hostname", "${env.Hostname}")
options.AddDefaultTags(new Dictionary<string, string>{{ "sensor-version", "${SensorVersion}" }})

Both of configurations will produce the Line protocol:

mine-sensor,id=132-987-655,customer="California Miner",hostname=example.com,sensor-version=v1.00 altitude=10

Handle the Events

Events that can be handle by WriteAPI EventHandler are:

  • WriteSuccessEvent - for success response from server
  • WriteErrorEvent - for unhandled exception from server
  • WriteRetriableErrorEvent - for retriable error from server
  • WriteRuntimeExceptionEvent - for runtime exception in background batch processing

Number of events depends on number of data points to collect in batch. The batch size is configured by BatchSize option (default size is 1000) - in case of one data point, event is handled for each point, independently on used writing method (even for mass writing of data like WriteMeasurements, WritePoints and WriteRecords).

Events can be handled by register writeApi.EventHandler or by creating custom EventListener:

Register EventHandler
writeApi.EventHandler += (sender, eventArgs) =>
{
    switch (eventArgs)
    {
        case WriteSuccessEvent successEvent:
            string data = @event.LineProtocol;
            //
            // handle success response from server
            // Console.WriteLine($"{data}");
            //
            break;
        case WriteErrorEvent error:
            string data = @error.LineProtocol;
            string errorMessage = @error.Exception.Message;
            //
            // handle unhandled exception from server
            //
            // Console.WriteLine($"{data}");
            // throw new Exception(errorMessage);
            //
            break;
        case WriteRetriableErrorEvent error:
            string data = @error.LineProtocol;
            string errorMessage = @error.Exception.Message;
            //
            // handle retrievable error from server
            //
            // Console.WriteLine($"{data}");
            // throw new Exception(errorMessage);
            //
            break;
        case WriteRuntimeExceptionEvent error:
            string errorMessage = @error.Exception.Message;
            //
            // handle runtime exception in background batch processing
            // throw new Exception(errorMessage);
            //
            break;
    }
};

//
// Write by LineProtocol
//
writeApi.WriteRecord("influxPoint,writeType=lineProtocol value=11.11" +
    $" {DateTime.UtcNow.Subtract(EpochStart).Ticks * 100}", WritePrecision.Ns, "my-bucket", "my-org");
Custom EventListener

Advantage of using custom Event Listener is possibility of waiting on handled event between different writings - for more info see EventListener.

Delete Data

Delete data from specified bucket:

using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;

namespace Examples
{
    public static class WriteLineProtocol
    {
        private static readonly string Token = "";

        public static void Main()
        {
            using var client = new InfluxDBClient("http://localhost:8086", Token);

            //
            // Delete data
            //
            await client.GetDeleteApi().Delete(DateTime.UtcNow.AddMinutes(-1), DateTime.Now, "", "bucket", "org");
        }
    }
}

Management API

The client has following management API:

API endpoint Description Implementation
/api/v2/authorizations Managing authorization data AuthorizationsApi
/api/v2/buckets Managing bucket data BucketsApi
/api/v2/orgs Managing organization data OrganizationsApi
/api/v2/users Managing user data UsersApi
/api/v2/sources Managing sources SourcesApi
/api/v2/tasks Managing one-off and recurring tasks TasksApi
/api/v2/scrapers Managing ScraperTarget data ScraperTargetsApi
/api/v2/labels Managing resource labels LabelsApi
/api/v2/telegrafs Managing telegraf config data TelegrafsApi
/api/v2/setup Managing onboarding setup InfluxDBClient#OnBoarding()
/ready Get the readiness of a instance at startup InfluxDBClient#Ready()
/health Get the health of an instance anytime during execution InfluxDBClient#Health()

The following example demonstrates how to use a InfluxDB 2.x Management API. For further information see endpoints implementation.

using System;
using System.Collections.Generic;
using System.Linq;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using Task = System.Threading.Tasks.Task;

namespace Examples
{
    public static class ManagementExample
    {
        public static async Task Main()
        {
            const string url = "http://localhost:8086";
            const string token = "my-token";
            const string org = "my-org";
            
            using var client = new InfluxDBClient(url, token);

            // Find ID of Organization with specified name (PermissionAPI requires ID of Organization).
            var orgId = (await client.GetOrganizationsApi().FindOrganizationsAsync(org: org)).First().Id;

            //
            // Create bucket "iot_bucket" with data retention set to 3,600 seconds
            //
            var retention = new BucketRetentionRules(BucketRetentionRules.TypeEnum.Expire, 3600);

            var bucket = await client.GetBucketsApi().CreateBucketAsync("iot_bucket", retention, orgId);

            //
            // Create access token to "iot_bucket"
            //
            var resource = new PermissionResource(PermissionResource.TypeBuckets, bucket.Id, null,
                orgId);

            // Read permission
            var read = new Permission(Permission.ActionEnum.Read, resource);

            // Write permission
            var write = new Permission(Permission.ActionEnum.Write, resource);

            var authorization = await client.GetAuthorizationsApi()
                .CreateAuthorizationAsync(orgId, new List<Permission> { read, write });

            //
            // Created token that can be use for writes to "iot_bucket"
            //
            Console.WriteLine($"Authorized token to write into iot_bucket: {authorization.Token}");
        }
    }
}

If there is no API implementation for particular service you could create the service by:

var dbrpService = _client.CreateService<DBRPsService>(typeof(DBRPsService));

Advanced Usage

Monitoring & Alerting

The example below show how to create a check for monitoring a stock price. A Slack notification is created if the price is lesser than 35.

Create Threshold Check

The Check set status to Critical if the current value for a stock measurement is lesser than 35.

var org = ...;

var query = "from(bucket: \"my-bucket\") "
        + "|> range(start: v.timeRangeStart, stop: v.timeRangeStop)  "
        + "|> filter(fn: (r) => r._measurement == \"stock\")  "
        + "|> filter(fn: (r) => r.company == \"zyz\")  "
        + "|> aggregateWindow(every: 5s, fn: mean)  "
        + "|> filter(fn: (r) => r._field == \"current\")  "
        + "|> yield(name: \"mean\")";

var threshold = new LesserThreshold(value: 35F, level: CheckStatusLevel.CRIT,
                type: LesserThreshold.TypeEnum.Lesser);

var message = "The Stock price for XYZ is on: ${ r._level } level!";

await Client
    .GetChecksApi()
    .CreateThresholdCheckAsync("XYZ Stock value", query, "5s", message, threshold, org.Id);
Create Slack Notification endpoint
var url = "https://hooks.slack.com/services/x/y/z"; 

var endpoint = await Client
    .GetNotificationEndpointsApi()
    .CreateSlackEndpointAsync("Slack Endpoint", url, org.Id);
Create Notification Rule
await Client
    .GetNotificationRulesApi()
    .CreateSlackRuleAsync("Critical status to Slack", "10s", "${ r._message }", RuleStatusLevel.CRIT, endpoint, org.Id);

Custom mapping of DomainObject to/from InfluxDB

The default mapper uses Column attributes to define how the DomainObject will be mapped to and from the InfluxDB. The our APIs also allow to specify custom mapper. For more information see following example:

using System;
using System.Threading.Tasks;
using InfluxDB.Client;
using InfluxDB.Client.Api.Domain;
using InfluxDB.Client.Core.Flux.Domain;
using InfluxDB.Client.Writes;

namespace Examples
{
    public static class CustomDomainMapping
    {
        /// <summary>
        /// Define Domain Object
        /// </summary>
        private class Sensor
        {
            /// <summary>
            /// Type of sensor.
            /// </summary>
            public String Type { get; set; }
            
            /// <summary>
            /// Version of sensor.
            /// </summary>
            public String Version { get; set; }

            /// <summary>
            /// Measured value.
            /// </summary>
            public double Value { get; set; }

            public DateTimeOffset Timestamp { get; set; }

            public override string ToString()
            {
                return $"{Timestamp:MM/dd/yyyy hh:mm:ss.fff tt} {Type}, {Version} value: {Value}";
            }
        }

        /// <summary>
        /// Define Custom Domain Object Converter
        /// </summary>
        private class DomainEntityConverter : IDomainObjectMapper
        {
            /// <summary>
            /// Convert to DomainObject.
            /// </summary>
            public object ConvertToEntity(FluxRecord fluxRecord, Type type)
            {
                if (type != typeof(Sensor))
                {
                    throw new NotSupportedException($"This converter doesn't supports: {type}");
                }

                var customEntity = new Sensor
                {
                    Type = Convert.ToString(fluxRecord.GetValueByKey("type")),
                    Version = Convert.ToString(fluxRecord.GetValueByKey("version")),
                    Value = Convert.ToDouble(fluxRecord.GetValueByKey("data")),
                    Timestamp = fluxRecord.GetTime().GetValueOrDefault().ToDateTimeUtc(),
                };
                
                return Convert.ChangeType(customEntity, type);
            }
            
            /// <summary>
            /// Convert to DomainObject.
            /// </summary>
            public T ConvertToEntity<T>(FluxRecord fluxRecord)
            {
                return (T)ConvertToEntity(fluxRecord, typeof(T));
            }

            /// <summary>
            /// Convert to Point
            /// </summary>
            public PointData ConvertToPointData<T>(T entity, WritePrecision precision)
            {
                if (!(entity is Sensor sensor))
                {
                    throw new NotSupportedException($"This converter doesn't supports: {entity}");
                }

                var point = PointData
                    .Measurement("sensor")
                    .Tag("type", sensor.Type)
                    .Tag("version", sensor.Version)
                    .Field("data", sensor.Value)
                    .Timestamp(sensor.Timestamp, precision);

                return point;
            }
        }

        public static async Task Main(string[] args)
        {
            const string host = "http://localhost:9999";
            const string token = "my-token";
            const string bucket = "my-bucket";
            const string organization = "my-org";
            var options = new InfluxDBClientOptions(host)
            {
                Token = token,
                Org = organization,
                Bucket = bucket
            };

            var converter = new DomainEntityConverter();
            using var client = new InfluxDBClient(options);

            //
            // Prepare data to write
            //
            var time = new DateTimeOffset(2020, 11, 15, 8, 20, 15,
                new TimeSpan(3, 0, 0));

            var entity1 = new Sensor
            {
                Timestamp = time,
                Type = "temperature",
                Version = "v0.0.2",
                Value = 15
            };
            var entity2 = new Sensor
            {
                Timestamp = time.AddHours(1),
                Type = "temperature",
                Version = "v0.0.2",
                Value = 15
            };
            var entity3 = new Sensor
            {
                Timestamp = time.AddHours(2),
                Type = "humidity",
                Version = "v0.13",
                Value = 74
            };
            var entity4 = new Sensor
            {
                Timestamp = time.AddHours(3),
                Type = "humidity",
                Version = "v0.13",
                Value = 82
            };

            //
            // Write data
            //
            await client.GetWriteApiAsync(converter)
                .WriteMeasurementsAsync(new []{entity1, entity2, entity3, entity4}, WritePrecision.S);

            //
            // Query Data to Domain object
            //
            var queryApi = client.GetQueryApiSync(converter);

            //
            // Select ALL
            //
            var query = $"from(bucket:\"{bucket}\") " +
                        "|> range(start: 0) " +
                        "|> filter(fn: (r) => r[\"_measurement\"] == \"sensor\")" +
                        "|> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")";
           
            var sensors = queryApi.QuerySync<Sensor>(query);
            //
            // Print result
            //
            sensors.ForEach(it => Console.WriteLine(it.ToString()));
        }
    }
}

Client configuration file

A client can be configured via App.config file.

The following options are supported:

Property name default description
Url - the url to connect to InfluxDB
Org - default destination organization for writes and queries
Bucket - default destination bucket for writes
Token - the token to use for the authorization
LogLevel NONE rest client verbosity level
Timeout 10000 ms The timespan to wait before the HTTP request times out
AllowHttpRedirects false Configure automatically following HTTP 3xx redirects
VerifySsl true Ignore Certificate Validation Errors when false

The Timeout supports ms, s and m as unit. Default is milliseconds.

Configuration example
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="influx2" type="InfluxDB.Client.Configurations.Influx2, InfluxDB.Client" />
    </configSections>

    <influx2 url="http://localhost:8086"
             org="my-org"
             bucket="my-bucket"
             token="my-token"
             logLevel="BODY"
             timeout="10s">
    </influx2>
</configuration>

and then:

var client = InfluxDBClientFactory.Create();

Client connection string

A client can be constructed using a connection string that can contain the InfluxDBClientOptions parameters encoded into the URL.

var client = new InfluxDBClient("http://localhost:8086?timeout=5000&logLevel=BASIC");

The following options are supported:

Property name default description
org - default destination organization for writes and queries
bucket - default destination bucket for writes
token - the token to use for the authorization
logLevel NONE rest client verbosity level
timeout 10000 ms The timespan to wait before the HTTP request times out.
allowHttpRedirects false Configure automatically following HTTP 3xx redirects
verifySsl true Ignore Certificate Validation Errors when false

The timeout supports ms, s and m as unit. Default is milliseconds.

Gzip support

InfluxDBClient does not enable gzip compress for http requests by default. If you want to enable gzip to reduce transfer data's size, you can call:

influxDBClient.EnableGzip();

How to use WebProxy

You can configure the client to tunnel requests through an HTTP proxy. The WebProxy could be configured via InfluxDBClientOptions parameter WebProxy:

var options = new InfluxDBClientOptions("http://localhost:8086")
{
    Token = "my-token",
    WebProxy = new WebProxy("http://proxyserver:80/", true)
};

var client = new InfluxDBClient(options);

Redirects configuration

Client automatically doesn't follows HTTP redirects. You can enable redirects by AllowRedirects configuration option:

var options = new InfluxDBClientOptions("http://localhost:8086")
{
    Token = "my-token",
    AllowRedirects = true
};

using var client = new InfluxDBClient(options);

⚠️ Due to a security reason Authorization header is not forwarded when redirect leads to a different domain. You can create custom Authenticator which change this behaviour - see more.

Log HTTP Request and Response

The Requests and Responses can be logged by changing the LogLevel. LogLevel values are None, Basic, Headers, Body. Note that applying the Body LogLevel will disable chunking while streaming and will load the whole response into memory.

client.SetLogLevel(LogLevel.Body)
Check the server status and version

Server availability can be checked using the influxDBClient.PingAsync() endpoint.

Version

The latest package for .NET CLI:

dotnet add package InfluxDB.Client

Or when using with Package Manager:

Install-Package InfluxDB.Client
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 is compatible. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (31)

Showing the top 5 NuGet packages that depend on InfluxDB.Client:

Package Downloads
InfluxDB.Client.Linq

The library supports querying InfluxDB 2.x by LINQ expressions.

NBomber.Sinks.InfluxDB

NBomber sink that writes stats data to InfluxDB.

Serilog.Sinks.InfluxDB.Syslog

InfluxDB sink for Serilog with .NET standard 2.0 using syslog format for Influx 2.X

AspNetCore.HealthChecks.InfluxDB

HealthChecks.InfluxDB is the health check package for InfluxDB.

OpenTelemetry.Exporter.InfluxDB

An OpenTelemetry .NET exporter that exports to InfluxDB.

GitHub repositories (8)

Showing the top 5 popular GitHub repositories that depend on InfluxDB.Client:

Repository Stars
Xabaril/AspNetCore.Diagnostics.HealthChecks
Enterprise HealthChecks for ASP.NET Core Diagnostics Package
testcontainers/testcontainers-dotnet
A library to support tests with throwaway instances of Docker containers for all compatible .NET Standard versions.
IoTSharp/IoTSharp
IoTSharp is an open-source IoT platform for data collection, processing, visualization, and device management.
ConcreteMC/Alex
A Minecraft client written in C# aimed at compatibility with MC:Java & MC:Bedrock
melanchall/drywetmidi
.NET library to read, write, process MIDI files and to work with MIDI devices
Version Downloads Last updated
4.19.0-dev.15190 793 12/5/2024
4.19.0-dev.15189 58 12/5/2024
4.19.0-dev.15188 51 12/5/2024
4.19.0-dev.15178 51 12/5/2024
4.19.0-dev.15177 56 12/5/2024
4.19.0-dev.14906 1,776 10/2/2024
4.19.0-dev.14897 60 10/2/2024
4.19.0-dev.14896 63 10/2/2024
4.19.0-dev.14895 94 10/2/2024
4.19.0-dev.14811 246 9/13/2024
4.18.0 273,221 9/13/2024
4.18.0-dev.14769 137 9/4/2024
4.18.0-dev.14743 80 9/3/2024
4.18.0-dev.14694 75 9/3/2024
4.18.0-dev.14693 63 9/3/2024
4.18.0-dev.14692 66 9/3/2024
4.18.0-dev.14618 83 9/2/2024
4.18.0-dev.14609 67 9/2/2024
4.18.0-dev.14592 63 9/2/2024
4.18.0-dev.14446 619 8/19/2024
4.18.0-dev.14414 321 8/12/2024
4.17.0 93,997 8/12/2024
4.17.0-dev.headers.read.1 209 7/22/2024
4.17.0-dev.14350 53 8/5/2024
4.17.0-dev.14333 53 8/5/2024
4.17.0-dev.14300 52 8/5/2024
4.17.0-dev.14291 50 8/5/2024
4.17.0-dev.14189 98 7/23/2024
4.17.0-dev.14179 76 7/22/2024
4.17.0-dev.14101 276 7/1/2024
4.17.0-dev.14100 71 7/1/2024
4.17.0-dev.14044 113 6/24/2024
4.16.0 91,853 6/24/2024
4.16.0-dev.13990 3,323 6/3/2024
4.16.0-dev.13973 73 6/3/2024
4.16.0-dev.13972 68 6/3/2024
4.16.0-dev.13963 82 6/3/2024
4.16.0-dev.13962 71 6/3/2024
4.16.0-dev.13881 71 6/3/2024
4.16.0-dev.13775 178 5/17/2024
4.16.0-dev.13702 83 5/17/2024
4.15.0 58,471 5/17/2024
4.15.0-dev.13674 92 5/14/2024
4.15.0-dev.13567 1,491 4/2/2024
4.15.0-dev.13558 73 4/2/2024
4.15.0-dev.13525 71 4/2/2024
4.15.0-dev.13524 75 4/2/2024
4.15.0-dev.13433 267 3/7/2024
4.15.0-dev.13432 77 3/7/2024
4.15.0-dev.13407 107 3/7/2024
4.15.0-dev.13390 75 3/7/2024
4.15.0-dev.13388 73 3/7/2024
4.15.0-dev.13282 262 3/6/2024
4.15.0-dev.13257 87 3/6/2024
4.15.0-dev.13113 1,143 2/1/2024
4.15.0-dev.13104 79 2/1/2024
4.15.0-dev.13081 80 2/1/2024
4.15.0-dev.13040 143 2/1/2024
4.15.0-dev.13039 80 2/1/2024
4.15.0-dev.12863 2,084 1/8/2024
4.15.0-dev.12846 89 1/8/2024
4.15.0-dev.12837 87 1/8/2024
4.15.0-dev.12726 2,706 12/1/2023
4.15.0-dev.12725 95 12/1/2023
4.15.0-dev.12724 88 12/1/2023
4.15.0-dev.12691 94 12/1/2023
4.15.0-dev.12658 102 12/1/2023
4.15.0-dev.12649 88 12/1/2023
4.15.0-dev.12624 89 12/1/2023
4.15.0-dev.12471 1,054 11/7/2023
4.15.0-dev.12462 92 11/7/2023
4.14.0 516,891 11/7/2023
4.14.0-dev.12437 91 11/7/2023
4.14.0-dev.12343 137 11/2/2023
4.14.0-dev.12310 94 11/2/2023
4.14.0-dev.12284 365 11/1/2023
4.14.0-dev.12235 112 11/1/2023
4.14.0-dev.12226 91 11/1/2023
4.14.0-dev.11972 5,652 8/8/2023
4.14.0-dev.11915 156 7/31/2023
4.14.0-dev.11879 173 7/28/2023
4.13.0 302,745 7/28/2023
4.13.0-dev.11854 113 7/28/2023
4.13.0-dev.11814 372 7/21/2023
4.13.0-dev.11771 158 7/19/2023
4.13.0-dev.11770 117 7/19/2023
4.13.0-dev.11728 139 7/18/2023
4.13.0-dev.11686 215 7/17/2023
4.13.0-dev.11685 105 7/17/2023
4.13.0-dev.11676 118 7/17/2023
4.13.0-dev.11479 2,071 6/27/2023
4.13.0-dev.11478 115 6/27/2023
4.13.0-dev.11477 114 6/27/2023
4.13.0-dev.11396 473 6/19/2023
4.13.0-dev.11395 104 6/19/2023
4.13.0-dev.11342 360 6/15/2023
4.13.0-dev.11330 298 6/12/2023
4.13.0-dev.11305 113 6/12/2023
4.13.0-dev.11296 114 6/12/2023
4.13.0-dev.11217 387 6/6/2023
4.13.0-dev.11089 306 5/30/2023
4.13.0-dev.11064 139 5/30/2023
4.13.0-dev.10998 177 5/29/2023
4.13.0-dev.10989 131 5/29/2023
4.13.0-dev.10871 892 5/8/2023
4.13.0-dev.10870 110 5/8/2023
4.13.0-dev.10819 289 4/28/2023
4.12.0 186,400 4/28/2023
4.12.0-dev.10777 149 4/27/2023
4.12.0-dev.10768 132 4/27/2023
4.12.0-dev.10759 124 4/27/2023
4.12.0-dev.10742 107 4/27/2023
4.12.0-dev.10685 118 4/27/2023
4.12.0-dev.10684 120 4/27/2023
4.12.0-dev.10643 127 4/27/2023
4.12.0-dev.10642 113 4/27/2023
4.12.0-dev.10569 114 4/27/2023
4.12.0-dev.10193 1,766 2/23/2023
4.11.0 119,892 2/23/2023
4.11.0-dev.10176 196 2/23/2023
4.11.0-dev.10059 3,179 1/26/2023
4.10.0 72,499 1/26/2023
4.10.0-dev.10033 162 1/25/2023
4.10.0-dev.10032 138 1/25/2023
4.10.0-dev.10031 153 1/25/2023
4.10.0-dev.9936 3,637 12/26/2022
4.10.0-dev.9935 160 12/26/2022
4.10.0-dev.9881 199 12/21/2022
4.10.0-dev.9880 139 12/21/2022
4.10.0-dev.9818 630 12/16/2022
4.10.0-dev.9773 320 12/12/2022
4.10.0-dev.9756 137 12/12/2022
4.10.0-dev.9693 382 12/6/2022
4.9.0 219,539 12/6/2022
4.9.0-dev.9684 130 12/6/2022
4.9.0-dev.9666 140 12/6/2022
4.9.0-dev.9617 157 12/6/2022
4.9.0-dev.9478 223 12/5/2022
4.9.0-dev.9469 157 12/5/2022
4.9.0-dev.9444 122 12/5/2022
4.9.0-dev.9411 140 12/5/2022
4.9.0-dev.9350 178 12/1/2022
4.8.0 5,868 12/1/2022
4.8.0-dev.9324 222 11/30/2022
4.8.0-dev.9232 202 11/28/2022
4.8.0-dev.9223 139 11/28/2022
4.8.0-dev.9222 136 11/28/2022
4.8.0-dev.9117 425 11/21/2022
4.8.0-dev.9108 142 11/21/2022
4.8.0-dev.9099 140 11/21/2022
4.8.0-dev.9029 213 11/16/2022
4.8.0-dev.8971 144 11/15/2022
4.8.0-dev.8961 149 11/14/2022
4.8.0-dev.8928 155 11/14/2022
4.8.0-dev.8899 150 11/14/2022
4.8.0-dev.8898 160 11/14/2022
4.8.0-dev.8839 151 11/14/2022
4.8.0-dev.8740 262 11/7/2022
4.8.0-dev.8725 140 11/7/2022
4.8.0-dev.8648 381 11/3/2022
4.7.0 107,655 11/3/2022
4.7.0-dev.8625 288 11/2/2022
4.7.0-dev.8594 301 10/31/2022
4.7.0-dev.8579 138 10/31/2022
4.7.0-dev.8557 128 10/31/2022
4.7.0-dev.8540 147 10/31/2022
4.7.0-dev.8518 139 10/31/2022
4.7.0-dev.8517 139 10/31/2022
4.7.0-dev.8509 135 10/31/2022
4.7.0-dev.8377 834 10/26/2022
4.7.0-dev.8360 162 10/25/2022
4.7.0-dev.8350 198 10/24/2022
4.7.0-dev.8335 151 10/24/2022
4.7.0-dev.8334 149 10/24/2022
4.7.0-dev.8223 242 10/19/2022
4.7.0-dev.8178 262 10/17/2022
4.7.0-dev.8170 143 10/17/2022
4.7.0-dev.8148 149 10/17/2022
4.7.0-dev.8133 139 10/17/2022
4.7.0-dev.8097 131 10/17/2022
4.7.0-dev.8034 1,101 10/11/2022
4.7.0-dev.8025 175 10/11/2022
4.7.0-dev.8009 220 10/10/2022
4.7.0-dev.8001 155 10/10/2022
4.7.0-dev.7959 226 10/4/2022
4.7.0-dev.7905 350 9/30/2022
4.7.0-dev.7875 197 9/29/2022
4.6.0 50,070 9/29/2022
4.6.0-dev.7832 191 9/29/2022
4.6.0-dev.7817 154 9/29/2022
4.6.0-dev.7779 212 9/27/2022
4.6.0-dev.7778 167 9/27/2022
4.6.0-dev.7734 182 9/26/2022
4.6.0-dev.7733 151 9/26/2022
4.6.0-dev.7677 257 9/20/2022
4.6.0-dev.7650 251 9/16/2022
4.6.0-dev.7626 226 9/14/2022
4.6.0-dev.7618 206 9/14/2022
4.6.0-dev.7574 157 9/13/2022
4.6.0-dev.7572 138 9/13/2022
4.6.0-dev.7528 288 9/12/2022
4.6.0-dev.7502 183 9/9/2022
4.6.0-dev.7479 211 9/8/2022
4.6.0-dev.7471 165 9/8/2022
4.6.0-dev.7447 214 9/7/2022
4.6.0-dev.7425 152 9/7/2022
4.6.0-dev.7395 177 9/6/2022
4.6.0-dev.7344 355 8/31/2022
4.6.0-dev.7329 139 8/31/2022
4.6.0-dev.7292 154 8/30/2022
4.6.0-dev.7240 337 8/29/2022
4.5.0 69,692 8/29/2022
4.5.0-dev.7216 169 8/27/2022
4.5.0-dev.7147 327 8/22/2022
4.5.0-dev.7134 364 8/17/2022
4.5.0-dev.7096 202 8/15/2022
4.5.0-dev.7070 297 8/11/2022
4.5.0-dev.7040 210 8/10/2022
4.5.0-dev.7011 262 8/3/2022
4.5.0-dev.6987 170 8/1/2022
4.5.0-dev.6962 181 7/29/2022
4.4.0 50,150 7/29/2022
4.4.0-dev.6901 359 7/25/2022
4.4.0-dev.6843 399 7/19/2022
4.4.0-dev.6804 169 7/19/2022
4.4.0-dev.6789 161 7/19/2022
4.4.0-dev.6760 156 7/19/2022
4.4.0-dev.6705 244 7/14/2022
4.4.0-dev.6663 1,147 6/24/2022
4.4.0-dev.6655 175 6/24/2022
4.3.0 196,323 6/24/2022
4.3.0-dev.multiple.buckets3 314 6/21/2022
4.3.0-dev.multiple.buckets2 288 6/17/2022
4.3.0-dev.multiple.buckets1 157 6/17/2022
4.3.0-dev.6631 169 6/22/2022
4.3.0-dev.6623 151 6/22/2022
4.3.0-dev.6374 479 6/13/2022
4.3.0-dev.6286 1,013 5/20/2022
4.2.0 77,018 5/20/2022
4.2.0-dev.6257 633 5/13/2022
4.2.0-dev.6248 172 5/12/2022
4.2.0-dev.6233 260 5/12/2022
4.2.0-dev.6194 267 5/10/2022
4.2.0-dev.6193 182 5/10/2022
4.2.0-dev.6158 3,078 5/6/2022
4.2.0-dev.6135 222 5/6/2022
4.2.0-dev.6091 556 4/28/2022
4.2.0-dev.6048 193 4/28/2022
4.2.0-dev.6047 172 4/28/2022
4.2.0-dev.5966 524 4/25/2022
4.2.0-dev.5938 422 4/19/2022
4.1.0 48,038 4/19/2022
4.1.0-dev.5910 383 4/13/2022
4.1.0-dev.5888 179 4/13/2022
4.1.0-dev.5887 187 4/13/2022
4.1.0-dev.5794 879 4/6/2022
4.1.0-dev.5725 634 3/18/2022
4.0.0 61,044 3/18/2022
4.0.0-rc3 1,019 3/4/2022
4.0.0-rc2 746 2/25/2022
4.0.0-rc1 2,232 2/18/2022
4.0.0-dev.5709 178 3/18/2022
4.0.0-dev.5684 188 3/15/2022
4.0.0-dev.5630 177 3/4/2022
4.0.0-dev.5607 186 3/3/2022
4.0.0-dev.5579 189 2/25/2022
4.0.0-dev.5556 187 2/24/2022
4.0.0-dev.5555 188 2/24/2022
4.0.0-dev.5497 188 2/23/2022
4.0.0-dev.5489 175 2/23/2022
4.0.0-dev.5460 181 2/23/2022
4.0.0-dev.5444 189 2/22/2022
4.0.0-dev.5333 199 2/17/2022
4.0.0-dev.5303 192 2/16/2022
4.0.0-dev.5280 186 2/16/2022
4.0.0-dev.5279 186 2/16/2022
4.0.0-dev.5241 371 2/15/2022
4.0.0-dev.5225 194 2/15/2022
4.0.0-dev.5217 176 2/15/2022
4.0.0-dev.5209 178 2/15/2022
4.0.0-dev.5200 190 2/14/2022
4.0.0-dev.5188 743 2/10/2022
4.0.0-dev.5180 403 2/10/2022
4.0.0-dev.5172 403 2/10/2022
4.0.0-dev.5130 411 2/10/2022
4.0.0-dev.5122 418 2/9/2022
4.0.0-dev.5103 419 2/9/2022
4.0.0-dev.5097 415 2/9/2022
4.0.0-dev.5091 397 2/9/2022
4.0.0-dev.5084 391 2/8/2022
3.4.0-dev.5263 191 2/15/2022
3.4.0-dev.4986 425 2/7/2022
3.4.0-dev.4968 454 2/4/2022
3.3.0 161,051 2/4/2022
3.3.0-dev.4889 445 2/3/2022
3.3.0-dev.4865 444 2/1/2022
3.3.0-dev.4823 359 1/19/2022
3.3.0-dev.4691 1,465 1/7/2022
3.3.0-dev.4557 2,246 11/26/2021
3.2.0 100,460 11/26/2021
3.2.0-dev.4533 5,105 11/24/2021
3.2.0-dev.4484 389 11/11/2021
3.2.0-dev.4475 252 11/10/2021
3.2.0-dev.4387 319 10/26/2021
3.2.0-dev.4363 279 10/22/2021
3.2.0-dev.4356 228 10/22/2021
3.1.0 96,770 10/22/2021
3.1.0-dev.4303 474 10/18/2021
3.1.0-dev.4293 251 10/15/2021
3.1.0-dev.4286 233 10/15/2021
3.1.0-dev.4240 284 10/12/2021
3.1.0-dev.4202 242 10/11/2021
3.1.0-dev.4183 252 10/11/2021
3.1.0-dev.4131 225 10/8/2021
3.1.0-dev.3999 248 10/5/2021
3.1.0-dev.3841 360 9/29/2021
3.1.0-dev.3798 441 9/17/2021
3.0.0 62,939 9/17/2021
3.0.0-dev.3726 2,575 8/31/2021
3.0.0-dev.3719 205 8/31/2021
3.0.0-dev.3671 453 8/20/2021
2.2.0-dev.3652 210 8/20/2021
2.1.0 320,624 8/20/2021
2.1.0-dev.3605 249 8/17/2021
2.1.0-dev.3584 563 8/16/2021
2.1.0-dev.3558 215 8/16/2021
2.1.0-dev.3527 354 7/29/2021
2.1.0-dev.3519 272 7/29/2021
2.1.0-dev.3490 344 7/20/2021
2.1.0-dev.3445 299 7/12/2021
2.1.0-dev.3434 281 7/9/2021
2.0.0 68,684 7/9/2021
2.0.0-dev.3401 7,940 6/25/2021
2.0.0-dev.3368 284 6/23/2021
2.0.0-dev.3361 273 6/23/2021
2.0.0-dev.3330 295 6/17/2021
2.0.0-dev.3291 281 6/16/2021
1.20.0-dev.3218 558 6/4/2021
1.19.0 155,132 6/4/2021
1.19.0-dev.3204 251 6/3/2021
1.19.0-dev.3160 243 6/2/2021
1.19.0-dev.3159 213 6/2/2021
1.19.0-dev.3084 2,539 5/7/2021
1.19.0-dev.3051 294 5/5/2021
1.19.0-dev.3044 248 5/5/2021
1.19.0-dev.3008 283 4/30/2021
1.18.0 37,453 4/30/2021
1.18.0-dev.2973 276 4/27/2021
1.18.0-dev.2930 1,228 4/16/2021
1.18.0-dev.2919 271 4/13/2021
1.18.0-dev.2893 268 4/12/2021
1.18.0-dev.2880 240 4/12/2021
1.18.0-dev.2856 266 4/7/2021
1.18.0-dev.2830 1,869 4/1/2021
1.18.0-dev.2816 232 4/1/2021
1.17.0 48,069 4/1/2021
1.17.0-dev.linq.17 910 3/18/2021
1.17.0-dev.linq.16 281 3/16/2021
1.17.0-dev.linq.15 262 3/15/2021
1.17.0-dev.linq.14 278 3/12/2021
1.17.0-dev.linq.13 314 3/11/2021
1.17.0-dev.linq.12 241 3/10/2021
1.17.0-dev.linq.11 281 3/8/2021
1.17.0-dev.2776 251 3/26/2021
1.17.0-dev.2713 224 3/25/2021
1.17.0-dev.2707 220 3/25/2021
1.17.0-dev.2652 280 3/19/2021
1.17.0-dev.2619 218 3/18/2021
1.17.0-dev.2566 222 3/16/2021
1.17.0-dev.2549 228 3/15/2021
1.17.0-dev.2505 262 3/12/2021
1.17.0-dev.2446 249 3/11/2021
1.17.0-dev.2402 244 3/8/2021
1.17.0-dev.2371 241 3/5/2021
1.16.0 19,619 3/5/2021
1.16.0-dev.linq.10 1,679 2/4/2021
1.16.0-dev.linq.9 262 2/4/2021
1.16.0-dev.2359 275 3/4/2021
1.16.0-dev.2273 236 2/12/2021
1.16.0-dev.2255 240 2/11/2021
1.16.0-dev.2228 250 2/5/2021
1.16.0-dev.2147 279 1/29/2021
1.15.0 33,731 1/29/2021
1.15.0-dev.linq.8 245 1/28/2021
1.15.0-dev.linq.7 235 1/27/2021
1.15.0-dev.linq.6 309 1/20/2021
1.15.0-dev.linq.5 285 1/19/2021
1.15.0-dev.linq.4 419 1/15/2021
1.15.0-dev.linq.3 235 1/14/2021
1.15.0-dev.linq.2 247 1/13/2021
1.15.0-dev.linq.1 263 1/12/2021
1.15.0-dev.2135 237 1/28/2021
1.15.0-dev.2009 245 1/19/2021
1.15.0-dev.1793 253 1/11/2021
1.15.0-dev.1753 290 1/7/2021
1.15.0-dev.1752 278 1/7/2021
1.15.0-dev.1705 898 12/16/2020
1.15.0-dev.1677 602 12/4/2020
1.14.0 46,397 12/4/2020
1.14.0-dev.1665 296 12/3/2020
1.14.0-dev.1648 295 12/2/2020
1.14.0-dev.1632 356 11/27/2020
1.14.0-dev.1577 490 10/30/2020
1.14.0-dev.1571 353 10/30/2020
1.13.0 15,287 10/30/2020
1.13.0-dev.1545 442 10/15/2020
1.13.0-dev.1516 505 10/8/2020
1.13.0-dev.1489 606 10/2/2020
1.13.0-dev.1478 342 10/2/2020
1.12.0 40,057 10/2/2020
1.12.0-dev.1466 290 10/1/2020
1.12.0-dev.1421 589 9/23/2020
1.12.0-dev.1345 356 9/18/2020
1.12.0-dev.1306 358 9/15/2020
1.12.0-dev.1251 369 9/2/2020
1.12.0-dev.1216 1,982 8/14/2020
1.11.0 24,385 8/14/2020
1.11.0-dev.1205 326 8/14/2020
1.11.0-dev.1185 326 8/10/2020
1.11.0-dev.1166 380 7/28/2020
1.11.0-dev.1150 328 7/28/2020
1.11.0-dev.1144 342 7/28/2020
1.11.0-dev.1125 324 7/20/2020
1.11.0-dev.1111 327 7/17/2020
1.10.0 17,288 7/17/2020
1.10.0-dev.1098 308 7/15/2020
1.10.0-dev.1077 420 7/10/2020
1.10.0-dev.1049 434 6/29/2020
1.10.0-dev.1022 353 6/23/2020
1.10.0-dev.1021 336 6/23/2020
1.10.0-dev.990 338 6/19/2020
1.9.0 24,271 6/19/2020
1.9.0-dev.984 353 6/19/2020
1.9.0-dev.971 311 6/17/2020
1.9.0-dev.955 319 6/17/2020
1.9.0-dev.886 335 6/10/2020
1.9.0-dev.848 354 6/8/2020
1.9.0-dev.842 312 6/8/2020
1.9.0-dev.836 310 6/8/2020
1.9.0-dev.786 1,289 5/27/2020
1.9.0-dev.762 622 5/15/2020
1.8.0 18,671 5/15/2020
1.8.0-dev.748 329 5/12/2020
1.8.0-dev.669 583 4/22/2020
1.8.0-dev.668 322 4/21/2020
1.8.0-dev.661 317 4/20/2020
1.8.0-dev.650 313 4/20/2020
1.8.0-dev.639 327 4/20/2020
1.8.0-dev.620 321 4/17/2020
1.7.0 14,918 4/17/2020
1.7.0-dev.608 349 4/16/2020
1.7.0-dev.574 315 4/14/2020
1.7.0-dev.563 316 4/14/2020
1.7.0-dev.534 330 4/6/2020
1.7.0-dev.528 335 4/6/2020
1.7.0-dev.512 367 4/3/2020
1.7.0-dev.495 334 3/30/2020
1.7.0-dev.469 1,183 3/13/2020
1.6.0 2,967 3/13/2020
1.6.0-dev.458 355 3/13/2020
1.6.0-dev.443 348 3/9/2020
1.6.0-dev.422 360 2/28/2020
1.6.0-dev.410 362 2/27/2020
1.6.0-dev.404 364 2/27/2020
1.6.0-dev.356 359 2/14/2020
1.5.0 1,940 2/14/2020
1.5.0-dev.349 337 2/14/2020
1.5.0-dev.341 340 2/12/2020
1.5.0-dev.312 353 1/22/2020
1.4.0 4,108 1/17/2020
1.3.0 2,070 12/6/2019
1.2.0 6,233 11/8/2019
1.1.0 982 10/11/2019
1.0.0 5,052 8/23/2019