# Bitip.Client A .NET client library for integrating with the [Bitip GeoIP Service](https://lab.code-rove.com/bitip/). This library provides a simple and efficient way to perform IP geolocation lookups, retrieve health status, and get version information from your Bitip API instance. [Bitip](https://lab.code-rove.com/gitea/tudor.stanciu/bitip#readme) is a high-performance GeoIP lookup service designed to provide accurate geolocation data for IP addresses. ## Features - ✅ Simple IP geolocation lookup - ✅ Detailed IP geolocation with ASN information - ✅ Batch IP geolocation for multiple addresses - ✅ Health check endpoint - ✅ Version information retrieval - ✅ Built-in IP address validation - ✅ Async/await support with CancellationToken - ✅ Dependency injection ready - ✅ Type-safe models with modern C# records ## Installation Install the package via NuGet Package Manager: ```bash dotnet add package Bitip.Client ``` Or via Package Manager Console: ```powershell Install-Package Bitip.Client ``` The package is available on the [public NuGet server](https://lab.code-rove.com/public-nuget-server/packages/bitip.client). ## Quick Start ### 1. Register the Service In your `Program.cs` or `Startup.cs`, register the Bitip client with dependency injection: ```csharp using Bitip.Client; // Register Bitip client services.UseBitipClient( baseUrl: "https://your-bitip-instance.com/api/", apiKey: "your-api-key-here" ); ``` ### 2. Inject and Use Inject `IBitipClient` into your services or controllers: ```csharp using Bitip.Client.Services; using Bitip.Client.Models; public class MyService { private readonly IBitipClient _bitipClient; public MyService(IBitipClient bitipClient) { _bitipClient = bitipClient; } public async Task GetLocationAsync(string ipAddress) { return await _bitipClient.GetIpLocation(ipAddress); } } ``` ## Usage Examples ### Simple IP Lookup Get basic geolocation information for an IP address: ```csharp var location = await _bitipClient.GetIpLocation("8.8.8.8"); Console.WriteLine($"IP: {location.Ip}"); Console.WriteLine($"Country: {location.Country} ({location.CountryCode})"); Console.WriteLine($"City: {location.City}"); Console.WriteLine($"Region: {location.Region}"); Console.WriteLine($"Coordinates: {location.Latitude}, {location.Longitude}"); Console.WriteLine($"Timezone: {location.Timezone}"); Console.WriteLine($"EU Member: {location.IsInEuropeanUnion}"); ``` **Response Model (`IpLocation`):** - `Ip` - The queried IP address - `Country` - Full country name - `CountryCode` - ISO country code (e.g., "US") - `IsInEuropeanUnion` - Boolean flag - `Region` - Region/state name - `RegionCode` - Region code (optional) - `City` - City name - `Latitude` / `Longitude` - Geographic coordinates (optional) - `Timezone` - IANA timezone (optional) - `PostalCode` - Postal/ZIP code (optional) - `ContinentCode` / `ContinentName` - Continent information (optional) - `Organization` - ISP/organization name (optional) ### Detailed IP Lookup Get comprehensive geolocation data including ASN information: ```csharp var detailedLocation = await _bitipClient.GetDetailedIpLocation("1.1.1.1"); Console.WriteLine($"IP: {detailedLocation.Ip}"); Console.WriteLine($"Country: {detailedLocation.Location.Country?.Names?["en"]}"); Console.WriteLine($"City: {detailedLocation.Location.City?.Names?["en"]}"); Console.WriteLine($"Latitude: {detailedLocation.Location.Location?.Latitude}"); Console.WriteLine($"Longitude: {detailedLocation.Location.Location?.Longitude}"); Console.WriteLine($"Timezone: {detailedLocation.Location.Location?.TimeZone}"); Console.WriteLine($"ASN: {detailedLocation.Asn.AutonomousSystemNumber}"); Console.WriteLine($"ISP: {detailedLocation.Asn.AutonomousSystemOrganization}"); ``` **Response Model (`DetailedIpLocation`):** - `Ip` - The queried IP address - `Location` - Nested geolocation data - `Country` - Country info with ISO code and localized names - `City` - City with localized names - `Subdivisions` - State/province information - `Location` - Latitude, longitude, timezone - `Postal` - Postal code - `Continent` - Continent code and names - `RegisteredCountry` - Registered country info - `Traits` - Proxy and satellite provider flags - `Asn` - Autonomous System Number information - `AutonomousSystemNumber` - ASN number - `AutonomousSystemOrganization` - ISP name - `IpAddress` - IP address - `Network` - Network range ### Batch IP Lookup Query multiple IP addresses in a single request. Results are separated into succeeded and failed: ```csharp var ips = new List { "8.8.8.8", "invalid-ip", "1.1.1.1" }; var batchResult = await _bitipClient.GetBatchIpLocation(ips); // Process successful lookups foreach (var location in batchResult.Succeeded) { Console.WriteLine($"{location.Ip}: {location.Country} ({location.CountryCode}), {location.City}"); } // Handle failures foreach (var error in batchResult.Failed) { Console.WriteLine($"Error for {error.Ip}: {error.Error}"); } ``` **Response Model (`BatchIpLookupResponse`):** - `Succeeded` - Collection of `IpLocation` objects for successful lookups - Same structure as single IP lookup response - All location data available - `Failed` - Collection of `BatchIpLookupError` objects for failed lookups - `Ip` - The IP address that failed - `Error` - Error message (e.g., "Invalid IP address format", "Private IP addresses are not supported") **Note:** Invalid IPs are validated client-side before sending to the API. The API may return additional errors for private IPs or IPs not found in the database. ### Health Check Check the health status of the Bitip API: ```csharp var health = await _bitipClient.GetHealth(); Console.WriteLine($"Status: {health.Status}"); Console.WriteLine($"Service: {health.Service}"); Console.WriteLine($"Timestamp: {health.Timestamp}"); if (!string.IsNullOrEmpty(health.Error)) { Console.WriteLine($"Error: {health.Error}"); } ``` ### Version Information Retrieve the API version and build details: ```csharp var version = await _bitipClient.GetVersion(); Console.WriteLine($"Version: {version.Version}"); Console.WriteLine($"Commit: {version.CommitHash}"); Console.WriteLine($"Build Date: {version.BuildDate}"); ``` ## Error Handling The client throws standard exceptions that you should handle appropriately: ```csharp try { var location = await _bitipClient.GetIpLocation("invalid-ip"); } catch (ArgumentException ex) { // Invalid IP format (single lookup methods only) Console.WriteLine($"Invalid IP: {ex.Message}"); } catch (HttpRequestException ex) { // API error (404 not found, 503 service unavailable, etc.) Console.WriteLine($"API Error: {ex.Message}"); } catch (TaskCanceledException ex) { // Request timeout Console.WriteLine($"Timeout: {ex.Message}"); } ``` **Note:** `GetBatchIpLocation` does not throw exceptions for invalid IPs. Instead, it returns error results for each invalid IP in the response. ### Common API Error Responses - **400 Bad Request** - Invalid IP address format or private IP (single lookups) - **404 Not Found** - IP address not found in database - **429 Too Many Requests** - Rate limit exceeded - **503 Service Unavailable** - Service under maintenance ## Cancellation Support All methods support `CancellationToken` for request cancellation: ```csharp var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); try { var location = await _bitipClient.GetIpLocation("8.8.8.8", cts.Token); } catch (OperationCanceledException) { Console.WriteLine("Request cancelled or timed out"); } ``` ## Configuration ### Base URL Format The base URL should point to your Bitip API instance. The library automatically ensures proper URL formatting: ```csharp // All of these work correctly: services.UseBitipClient("https://bitip.example.com/api", "your-api-key"); services.UseBitipClient("https://bitip.example.com/api/", "your-api-key"); ``` ### API Key The API key is sent via the `X-API-Key` header in all requests. Make sure your Bitip API is configured to accept your key. ## Requirements - **.NET 9.0** or higher - **Microsoft.Extensions.DependencyInjection.Abstractions** (9.0.9+) - **Microsoft.Extensions.Http** (9.0.9+) ## API Endpoints Used This client interacts with the following Bitip API endpoints: | Method | Endpoint | Description | | --------------------------- | ------------------------------ | --------------- | | `GetHealth()` | `GET /health` | Health check | | `GetVersion()` | `GET /version` | Version info | | `GetIpLocation(ip)` | `GET /lookup?ip={ip}` | Simple lookup | | `GetDetailedIpLocation(ip)` | `GET /lookup/detailed?ip={ip}` | Detailed lookup | | `GetBatchIpLocation(ips)` | `POST /lookup/batch` | Batch lookup | ## Best Practices 1. **Reuse IBitipClient instances** - They are registered as scoped services by default 2. **Use cancellation tokens** for requests that may take time 3. **Handle exceptions appropriately** - Network calls can fail 4. **Validate IPs before calling** (optional, the library validates internally) 5. **Consider caching results** - IP geolocation data doesn't change frequently ## License This project is licensed under the terms specified in the LICENSE file. ## Support For issues, questions, or contributions, please visit: - **Repository**: https://lab.code-rove.com/gitea/tudor.stanciu/bitip - **Package**: https://lab.code-rove.com/public-nuget-server/packages/bitip.client --- **Copyright © 2025 Tudor Stanciu**