InfluxDB.Client 4.13.0-dev.11296

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.13.0-dev.11296
                    
NuGet\Install-Package InfluxDB.Client -Version 4.13.0-dev.11296
                    
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.13.0-dev.11296" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="InfluxDB.Client" Version="4.13.0-dev.11296" />
                    
Directory.Packages.props
<PackageReference Include="InfluxDB.Client" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add InfluxDB.Client --version 4.13.0-dev.11296
                    
#r "nuget: InfluxDB.Client, 4.13.0-dev.11296"
                    
#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.
#addin nuget:?package=InfluxDB.Client&version=4.13.0-dev.11296&prerelease
                    
Install InfluxDB.Client as a Cake Addin
#tool nuget:?package=InfluxDB.Client&version=4.13.0-dev.11296&prerelease
                    
Install InfluxDB.Client as a Cake Tool

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 (30)

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 8 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
open-telemetry/opentelemetry-dotnet-contrib
This repository contains set of components extending functionality of the OpenTelemetry .NET SDK. Instrumentation libraries, exporters, and other components can find their home here.
nickbabcock/OhmGraphite
Expose hardware sensor data to Graphite / InfluxDB / Prometheus / Postgres / Timescaledb
RapidScada/scada-v6
Contains Rapid SCADA 6 source code
Version Downloads Last updated
4.19.0-dev.15190 1,443 12/5/2024
4.19.0-dev.15189 61 12/5/2024
4.19.0-dev.15188 54 12/5/2024
4.19.0-dev.15178 54 12/5/2024
4.19.0-dev.15177 59 12/5/2024
4.19.0-dev.14906 1,802 10/2/2024
4.19.0-dev.14897 62 10/2/2024
4.19.0-dev.14896 66 10/2/2024
4.19.0-dev.14895 96 10/2/2024
4.19.0-dev.14811 263 9/13/2024
4.18.0 360,565 9/13/2024
4.18.0-dev.14769 138 9/4/2024
4.18.0-dev.14743 82 9/3/2024
4.18.0-dev.14694 76 9/3/2024
4.18.0-dev.14693 65 9/3/2024
4.18.0-dev.14692 68 9/3/2024
4.18.0-dev.14618 84 9/2/2024
4.18.0-dev.14609 69 9/2/2024
4.18.0-dev.14592 64 9/2/2024
4.18.0-dev.14446 695 8/19/2024
4.18.0-dev.14414 344 8/12/2024
4.17.0 105,121 8/12/2024
4.17.0-dev.headers.read.1 218 7/22/2024
4.17.0-dev.14350 54 8/5/2024
4.17.0-dev.14333 55 8/5/2024
4.17.0-dev.14300 53 8/5/2024
4.17.0-dev.14291 51 8/5/2024
4.17.0-dev.14189 104 7/23/2024
4.17.0-dev.14179 77 7/22/2024
4.17.0-dev.14101 277 7/1/2024
4.17.0-dev.14100 72 7/1/2024
4.17.0-dev.14044 115 6/24/2024
4.16.0 117,296 6/24/2024
4.16.0-dev.13990 3,464 6/3/2024
4.16.0-dev.13973 74 6/3/2024
4.16.0-dev.13972 68 6/3/2024
4.16.0-dev.13963 83 6/3/2024
4.16.0-dev.13962 72 6/3/2024
4.16.0-dev.13881 72 6/3/2024
4.16.0-dev.13775 181 5/17/2024
4.16.0-dev.13702 84 5/17/2024
4.15.0 64,789 5/17/2024
4.15.0-dev.13674 93 5/14/2024
4.15.0-dev.13567 1,496 4/2/2024
4.15.0-dev.13558 74 4/2/2024
4.15.0-dev.13525 72 4/2/2024
4.15.0-dev.13524 76 4/2/2024
4.15.0-dev.13433 277 3/7/2024
4.15.0-dev.13432 78 3/7/2024
4.15.0-dev.13407 108 3/7/2024
4.15.0-dev.13390 76 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,146 2/1/2024
4.15.0-dev.13104 80 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 81 2/1/2024
4.15.0-dev.12863 2,085 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,735 12/1/2023
4.15.0-dev.12725 96 12/1/2023
4.15.0-dev.12724 89 12/1/2023
4.15.0-dev.12691 95 12/1/2023
4.15.0-dev.12658 102 12/1/2023
4.15.0-dev.12649 89 12/1/2023
4.15.0-dev.12624 90 12/1/2023
4.15.0-dev.12471 1,063 11/7/2023
4.15.0-dev.12462 92 11/7/2023
4.14.0 529,613 11/7/2023
4.14.0-dev.12437 92 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 92 11/1/2023
4.14.0-dev.11972 5,662 8/8/2023
4.14.0-dev.11915 158 7/31/2023
4.14.0-dev.11879 175 7/28/2023
4.13.0 310,094 7/28/2023
4.13.0-dev.11854 114 7/28/2023
4.13.0-dev.11814 374 7/21/2023
4.13.0-dev.11771 161 7/19/2023
4.13.0-dev.11770 120 7/19/2023
4.13.0-dev.11728 142 7/18/2023
4.13.0-dev.11686 217 7/17/2023
4.13.0-dev.11685 107 7/17/2023
4.13.0-dev.11676 120 7/17/2023
4.13.0-dev.11479 2,079 6/27/2023
4.13.0-dev.11478 117 6/27/2023
4.13.0-dev.11477 116 6/27/2023
4.13.0-dev.11396 476 6/19/2023
4.13.0-dev.11395 107 6/19/2023
4.13.0-dev.11342 365 6/15/2023
4.13.0-dev.11330 302 6/12/2023
4.13.0-dev.11305 117 6/12/2023
4.13.0-dev.11296 119 6/12/2023
4.13.0-dev.11217 391 6/6/2023
4.13.0-dev.11089 310 5/30/2023
4.13.0-dev.11064 143 5/30/2023
4.13.0-dev.10998 181 5/29/2023
4.13.0-dev.10989 135 5/29/2023
4.13.0-dev.10871 898 5/8/2023
4.13.0-dev.10870 114 5/8/2023
4.13.0-dev.10819 293 4/28/2023
4.12.0 190,208 4/28/2023
4.12.0-dev.10777 153 4/27/2023
4.12.0-dev.10768 135 4/27/2023
4.12.0-dev.10759 128 4/27/2023
4.12.0-dev.10742 113 4/27/2023
4.12.0-dev.10685 121 4/27/2023
4.12.0-dev.10684 124 4/27/2023
4.12.0-dev.10643 131 4/27/2023
4.12.0-dev.10642 117 4/27/2023
4.12.0-dev.10569 117 4/27/2023
4.12.0-dev.10193 1,772 2/23/2023
4.11.0 121,741 2/23/2023
4.11.0-dev.10176 202 2/23/2023
4.11.0-dev.10059 3,186 1/26/2023
4.10.0 73,684 1/26/2023
4.10.0-dev.10033 166 1/25/2023
4.10.0-dev.10032 143 1/25/2023
4.10.0-dev.10031 157 1/25/2023
4.10.0-dev.9936 3,671 12/26/2022
4.10.0-dev.9935 164 12/26/2022
4.10.0-dev.9881 202 12/21/2022
4.10.0-dev.9880 143 12/21/2022
4.10.0-dev.9818 634 12/16/2022
4.10.0-dev.9773 325 12/12/2022
4.10.0-dev.9756 140 12/12/2022
4.10.0-dev.9693 386 12/6/2022
4.9.0 225,267 12/6/2022
4.9.0-dev.9684 134 12/6/2022
4.9.0-dev.9666 143 12/6/2022
4.9.0-dev.9617 161 12/6/2022
4.9.0-dev.9478 227 12/5/2022
4.9.0-dev.9469 161 12/5/2022
4.9.0-dev.9444 126 12/5/2022
4.9.0-dev.9411 145 12/5/2022
4.9.0-dev.9350 183 12/1/2022
4.8.0 5,884 12/1/2022
4.8.0-dev.9324 227 11/30/2022
4.8.0-dev.9232 205 11/28/2022
4.8.0-dev.9223 143 11/28/2022
4.8.0-dev.9222 140 11/28/2022
4.8.0-dev.9117 429 11/21/2022
4.8.0-dev.9108 145 11/21/2022
4.8.0-dev.9099 144 11/21/2022
4.8.0-dev.9029 218 11/16/2022
4.8.0-dev.8971 150 11/15/2022
4.8.0-dev.8961 153 11/14/2022
4.8.0-dev.8928 158 11/14/2022
4.8.0-dev.8899 153 11/14/2022
4.8.0-dev.8898 165 11/14/2022
4.8.0-dev.8839 154 11/14/2022
4.8.0-dev.8740 266 11/7/2022
4.8.0-dev.8725 144 11/7/2022
4.8.0-dev.8648 385 11/3/2022
4.7.0 108,718 11/3/2022
4.7.0-dev.8625 291 11/2/2022
4.7.0-dev.8594 305 10/31/2022
4.7.0-dev.8579 141 10/31/2022
4.7.0-dev.8557 132 10/31/2022
4.7.0-dev.8540 152 10/31/2022
4.7.0-dev.8518 142 10/31/2022
4.7.0-dev.8517 142 10/31/2022
4.7.0-dev.8509 139 10/31/2022
4.7.0-dev.8377 837 10/26/2022
4.7.0-dev.8360 166 10/25/2022
4.7.0-dev.8350 201 10/24/2022
4.7.0-dev.8335 155 10/24/2022
4.7.0-dev.8334 152 10/24/2022
4.7.0-dev.8223 246 10/19/2022
4.7.0-dev.8178 266 10/17/2022
4.7.0-dev.8170 148 10/17/2022
4.7.0-dev.8148 152 10/17/2022
4.7.0-dev.8133 144 10/17/2022
4.7.0-dev.8097 135 10/17/2022
4.7.0-dev.8034 1,104 10/11/2022
4.7.0-dev.8025 179 10/11/2022
4.7.0-dev.8009 224 10/10/2022
4.7.0-dev.8001 159 10/10/2022
4.7.0-dev.7959 230 10/4/2022
4.7.0-dev.7905 354 9/30/2022
4.7.0-dev.7875 200 9/29/2022
4.6.0 50,554 9/29/2022
4.6.0-dev.7832 194 9/29/2022
4.6.0-dev.7817 158 9/29/2022
4.6.0-dev.7779 215 9/27/2022
4.6.0-dev.7778 170 9/27/2022
4.6.0-dev.7734 186 9/26/2022
4.6.0-dev.7733 155 9/26/2022
4.6.0-dev.7677 261 9/20/2022
4.6.0-dev.7650 254 9/16/2022
4.6.0-dev.7626 229 9/14/2022
4.6.0-dev.7618 210 9/14/2022
4.6.0-dev.7574 161 9/13/2022
4.6.0-dev.7572 142 9/13/2022
4.6.0-dev.7528 291 9/12/2022
4.6.0-dev.7502 187 9/9/2022
4.6.0-dev.7479 215 9/8/2022
4.6.0-dev.7471 170 9/8/2022
4.6.0-dev.7447 219 9/7/2022
4.6.0-dev.7425 157 9/7/2022
4.6.0-dev.7395 181 9/6/2022
4.6.0-dev.7344 360 8/31/2022
4.6.0-dev.7329 144 8/31/2022
4.6.0-dev.7292 159 8/30/2022
4.6.0-dev.7240 341 8/29/2022
4.5.0 71,316 8/29/2022
4.5.0-dev.7216 172 8/27/2022
4.5.0-dev.7147 330 8/22/2022
4.5.0-dev.7134 367 8/17/2022
4.5.0-dev.7096 206 8/15/2022
4.5.0-dev.7070 301 8/11/2022
4.5.0-dev.7040 214 8/10/2022
4.5.0-dev.7011 266 8/3/2022
4.5.0-dev.6987 175 8/1/2022
4.5.0-dev.6962 185 7/29/2022
4.4.0 50,579 7/29/2022
4.4.0-dev.6901 364 7/25/2022
4.4.0-dev.6843 404 7/19/2022
4.4.0-dev.6804 174 7/19/2022
4.4.0-dev.6789 166 7/19/2022
4.4.0-dev.6760 162 7/19/2022
4.4.0-dev.6705 249 7/14/2022
4.4.0-dev.6663 1,157 6/24/2022
4.4.0-dev.6655 181 6/24/2022
4.3.0 203,627 6/24/2022
4.3.0-dev.multiple.buckets3 320 6/21/2022
4.3.0-dev.multiple.buckets2 292 6/17/2022
4.3.0-dev.multiple.buckets1 161 6/17/2022
4.3.0-dev.6631 174 6/22/2022
4.3.0-dev.6623 156 6/22/2022
4.3.0-dev.6374 485 6/13/2022
4.3.0-dev.6286 1,017 5/20/2022
4.2.0 78,445 5/20/2022
4.2.0-dev.6257 637 5/13/2022
4.2.0-dev.6248 177 5/12/2022
4.2.0-dev.6233 264 5/12/2022
4.2.0-dev.6194 273 5/10/2022
4.2.0-dev.6193 186 5/10/2022
4.2.0-dev.6158 3,083 5/6/2022
4.2.0-dev.6135 227 5/6/2022
4.2.0-dev.6091 561 4/28/2022
4.2.0-dev.6048 198 4/28/2022
4.2.0-dev.6047 177 4/28/2022
4.2.0-dev.5966 528 4/25/2022
4.2.0-dev.5938 428 4/19/2022
4.1.0 48,243 4/19/2022
4.1.0-dev.5910 389 4/13/2022
4.1.0-dev.5888 184 4/13/2022
4.1.0-dev.5887 192 4/13/2022
4.1.0-dev.5794 884 4/6/2022
4.1.0-dev.5725 660 3/18/2022
4.0.0 61,497 3/18/2022
4.0.0-rc3 1,024 3/4/2022
4.0.0-rc2 751 2/25/2022
4.0.0-rc1 2,236 2/18/2022
4.0.0-dev.5709 182 3/18/2022
4.0.0-dev.5684 193 3/15/2022
4.0.0-dev.5630 182 3/4/2022
4.0.0-dev.5607 191 3/3/2022
4.0.0-dev.5579 193 2/25/2022
4.0.0-dev.5556 191 2/24/2022
4.0.0-dev.5555 193 2/24/2022
4.0.0-dev.5497 193 2/23/2022
4.0.0-dev.5489 179 2/23/2022
4.0.0-dev.5460 186 2/23/2022
4.0.0-dev.5444 193 2/22/2022
4.0.0-dev.5333 203 2/17/2022
4.0.0-dev.5303 197 2/16/2022
4.0.0-dev.5280 190 2/16/2022
4.0.0-dev.5279 190 2/16/2022
4.0.0-dev.5241 377 2/15/2022
4.0.0-dev.5225 202 2/15/2022
4.0.0-dev.5217 183 2/15/2022
4.0.0-dev.5209 185 2/15/2022
4.0.0-dev.5200 196 2/14/2022
4.0.0-dev.5188 748 2/10/2022
4.0.0-dev.5180 409 2/10/2022
4.0.0-dev.5172 409 2/10/2022
4.0.0-dev.5130 416 2/10/2022
4.0.0-dev.5122 423 2/9/2022
4.0.0-dev.5103 424 2/9/2022
4.0.0-dev.5097 421 2/9/2022
4.0.0-dev.5091 403 2/9/2022
4.0.0-dev.5084 397 2/8/2022
3.4.0-dev.5263 197 2/15/2022
3.4.0-dev.4986 430 2/7/2022
3.4.0-dev.4968 460 2/4/2022
3.3.0 164,422 2/4/2022
3.3.0-dev.4889 452 2/3/2022
3.3.0-dev.4865 450 2/1/2022
3.3.0-dev.4823 365 1/19/2022
3.3.0-dev.4691 1,470 1/7/2022
3.3.0-dev.4557 2,251 11/26/2021
3.2.0 101,402 11/26/2021
3.2.0-dev.4533 5,112 11/24/2021
3.2.0-dev.4484 398 11/11/2021
3.2.0-dev.4475 258 11/10/2021
3.2.0-dev.4387 326 10/26/2021
3.2.0-dev.4363 287 10/22/2021
3.2.0-dev.4356 234 10/22/2021
3.1.0 97,245 10/22/2021
3.1.0-dev.4303 482 10/18/2021
3.1.0-dev.4293 257 10/15/2021
3.1.0-dev.4286 240 10/15/2021
3.1.0-dev.4240 290 10/12/2021
3.1.0-dev.4202 249 10/11/2021
3.1.0-dev.4183 258 10/11/2021
3.1.0-dev.4131 231 10/8/2021
3.1.0-dev.3999 255 10/5/2021
3.1.0-dev.3841 367 9/29/2021
3.1.0-dev.3798 448 9/17/2021
3.0.0 63,670 9/17/2021
3.0.0-dev.3726 2,582 8/31/2021
3.0.0-dev.3719 211 8/31/2021
3.0.0-dev.3671 460 8/20/2021
2.2.0-dev.3652 217 8/20/2021
2.1.0 331,815 8/20/2021
2.1.0-dev.3605 257 8/17/2021
2.1.0-dev.3584 569 8/16/2021
2.1.0-dev.3558 221 8/16/2021
2.1.0-dev.3527 361 7/29/2021
2.1.0-dev.3519 280 7/29/2021
2.1.0-dev.3490 351 7/20/2021
2.1.0-dev.3445 305 7/12/2021
2.1.0-dev.3434 288 7/9/2021
2.0.0 69,278 7/9/2021
2.0.0-dev.3401 8,028 6/25/2021
2.0.0-dev.3368 291 6/23/2021
2.0.0-dev.3361 281 6/23/2021
2.0.0-dev.3330 301 6/17/2021
2.0.0-dev.3291 287 6/16/2021
1.20.0-dev.3218 564 6/4/2021
1.19.0 160,806 6/4/2021
1.19.0-dev.3204 258 6/3/2021
1.19.0-dev.3160 250 6/2/2021
1.19.0-dev.3159 220 6/2/2021
1.19.0-dev.3084 2,547 5/7/2021
1.19.0-dev.3051 303 5/5/2021
1.19.0-dev.3044 258 5/5/2021
1.19.0-dev.3008 293 4/30/2021
1.18.0 37,730 4/30/2021
1.18.0-dev.2973 285 4/27/2021
1.18.0-dev.2930 1,236 4/16/2021
1.18.0-dev.2919 279 4/13/2021
1.18.0-dev.2893 277 4/12/2021
1.18.0-dev.2880 249 4/12/2021
1.18.0-dev.2856 274 4/7/2021
1.18.0-dev.2830 1,877 4/1/2021
1.18.0-dev.2816 241 4/1/2021
1.17.0 48,817 4/1/2021
1.17.0-dev.linq.17 920 3/18/2021
1.17.0-dev.linq.16 290 3/16/2021
1.17.0-dev.linq.15 271 3/15/2021
1.17.0-dev.linq.14 287 3/12/2021
1.17.0-dev.linq.13 324 3/11/2021
1.17.0-dev.linq.12 251 3/10/2021
1.17.0-dev.linq.11 291 3/8/2021
1.17.0-dev.2776 259 3/26/2021
1.17.0-dev.2713 233 3/25/2021
1.17.0-dev.2707 229 3/25/2021
1.17.0-dev.2652 288 3/19/2021
1.17.0-dev.2619 227 3/18/2021
1.17.0-dev.2566 232 3/16/2021
1.17.0-dev.2549 236 3/15/2021
1.17.0-dev.2505 270 3/12/2021
1.17.0-dev.2446 258 3/11/2021
1.17.0-dev.2402 255 3/8/2021
1.17.0-dev.2371 251 3/5/2021
1.16.0 19,671 3/5/2021
1.16.0-dev.linq.10 1,690 2/4/2021
1.16.0-dev.linq.9 273 2/4/2021
1.16.0-dev.2359 284 3/4/2021
1.16.0-dev.2273 247 2/12/2021
1.16.0-dev.2255 250 2/11/2021
1.16.0-dev.2228 262 2/5/2021
1.16.0-dev.2147 291 1/29/2021
1.15.0 33,888 1/29/2021
1.15.0-dev.linq.8 257 1/28/2021
1.15.0-dev.linq.7 246 1/27/2021
1.15.0-dev.linq.6 321 1/20/2021
1.15.0-dev.linq.5 296 1/19/2021
1.15.0-dev.linq.4 430 1/15/2021
1.15.0-dev.linq.3 246 1/14/2021
1.15.0-dev.linq.2 259 1/13/2021
1.15.0-dev.linq.1 274 1/12/2021
1.15.0-dev.2135 248 1/28/2021
1.15.0-dev.2009 256 1/19/2021
1.15.0-dev.1793 264 1/11/2021
1.15.0-dev.1753 301 1/7/2021
1.15.0-dev.1752 290 1/7/2021
1.15.0-dev.1705 909 12/16/2020
1.15.0-dev.1677 614 12/4/2020
1.14.0 46,471 12/4/2020
1.14.0-dev.1665 307 12/3/2020
1.14.0-dev.1648 305 12/2/2020
1.14.0-dev.1632 366 11/27/2020
1.14.0-dev.1577 500 10/30/2020
1.14.0-dev.1571 365 10/30/2020
1.13.0 15,380 10/30/2020
1.13.0-dev.1545 454 10/15/2020
1.13.0-dev.1516 515 10/8/2020
1.13.0-dev.1489 616 10/2/2020
1.13.0-dev.1478 354 10/2/2020
1.12.0 40,601 10/2/2020
1.12.0-dev.1466 301 10/1/2020
1.12.0-dev.1421 600 9/23/2020
1.12.0-dev.1345 367 9/18/2020
1.12.0-dev.1306 368 9/15/2020
1.12.0-dev.1251 380 9/2/2020
1.12.0-dev.1216 1,992 8/14/2020
1.11.0 24,401 8/14/2020
1.11.0-dev.1205 337 8/14/2020
1.11.0-dev.1185 337 8/10/2020
1.11.0-dev.1166 390 7/28/2020
1.11.0-dev.1150 338 7/28/2020
1.11.0-dev.1144 354 7/28/2020
1.11.0-dev.1125 336 7/20/2020
1.11.0-dev.1111 338 7/17/2020
1.10.0 17,308 7/17/2020
1.10.0-dev.1098 319 7/15/2020
1.10.0-dev.1077 431 7/10/2020
1.10.0-dev.1049 445 6/29/2020
1.10.0-dev.1022 366 6/23/2020
1.10.0-dev.1021 349 6/23/2020
1.10.0-dev.990 351 6/19/2020
1.9.0 25,588 6/19/2020
1.9.0-dev.984 366 6/19/2020
1.9.0-dev.971 325 6/17/2020
1.9.0-dev.955 332 6/17/2020
1.9.0-dev.886 347 6/10/2020
1.9.0-dev.848 367 6/8/2020
1.9.0-dev.842 325 6/8/2020
1.9.0-dev.836 323 6/8/2020
1.9.0-dev.786 1,301 5/27/2020
1.9.0-dev.762 634 5/15/2020
1.8.0 18,714 5/15/2020
1.8.0-dev.748 342 5/12/2020
1.8.0-dev.669 597 4/22/2020
1.8.0-dev.668 335 4/21/2020
1.8.0-dev.661 331 4/20/2020
1.8.0-dev.650 326 4/20/2020
1.8.0-dev.639 340 4/20/2020
1.8.0-dev.620 333 4/17/2020
1.7.0 15,156 4/17/2020
1.7.0-dev.608 363 4/16/2020
1.7.0-dev.574 329 4/14/2020
1.7.0-dev.563 329 4/14/2020
1.7.0-dev.534 343 4/6/2020
1.7.0-dev.528 350 4/6/2020
1.7.0-dev.512 380 4/3/2020
1.7.0-dev.495 347 3/30/2020
1.7.0-dev.469 1,196 3/13/2020
1.6.0 2,982 3/13/2020
1.6.0-dev.458 368 3/13/2020
1.6.0-dev.443 363 3/9/2020
1.6.0-dev.422 373 2/28/2020
1.6.0-dev.410 376 2/27/2020
1.6.0-dev.404 378 2/27/2020
1.6.0-dev.356 371 2/14/2020
1.5.0 2,049 2/14/2020
1.5.0-dev.349 350 2/14/2020
1.5.0-dev.341 353 2/12/2020
1.5.0-dev.312 366 1/22/2020
1.4.0 4,125 1/17/2020
1.3.0 2,083 12/6/2019
1.2.0 6,246 11/8/2019
1.1.0 997 10/11/2019
1.0.0 5,403 8/23/2019