Promoted.DeliveryClient 0.2.0

dotnet add package Promoted.DeliveryClient --version 0.2.0
NuGet\Install-Package Promoted.DeliveryClient -Version 0.2.0
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="Promoted.DeliveryClient" Version="0.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Promoted.DeliveryClient --version 0.2.0
#r "nuget: Promoted.DeliveryClient, 0.2.0"
#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 Promoted.DeliveryClient as a Cake Addin
#addin nuget:?package=Promoted.DeliveryClient&version=0.2.0

// Install Promoted.DeliveryClient as a Cake Tool
#tool nuget:?package=Promoted.DeliveryClient&version=0.2.0

.NET (targeting netstandard2.0) client SDK for the Promoted.ai Delivery API

Features

  • Demonstrates and implements the recommended practices and data types for calling Promoted.ai's Delivery API.
  • Client-side position assignment and paging when not using results from Delivery API, for example when logging only or as part of an experiment control.

Creating a DeliveryClient

The Promoted.Lib.DeliveryClient is currently intended to have one instance per pair (Delivery and Metrics) of endpoints. It is thread-safe, but is built on top of System.Net.Http.HttpClient so it implements IDisposable.

var logger = new Your.Namespace.LogAdapter();
var options = new Promoted.Lib.DeliveryClientOptions(); // Optional.
var client = new Promoted.Lib.DeliveryClient(
    deliveryEndpoint, deliveryApiKey, deliveryTimeoutMillis,
    metricsEndpoint, metricsApiKey, metricsTimeoutMillis,
    logger, options);
...
client.Dispose();

DeliveryClient Constructor Parameters

Name Type Description
deliveryEndpoint string API endpoint for Promoted.ai's Delivery API.
deliveryApiKey string API key used in the x-api-key header for Promoted.ai's Delivery API.
deliveryTimeoutMillis int Timeout on the Delivery API call.
metricsEndpoint string API endpoint for Promoted.ai's Metrics API.
metricsApiKey string API key used in the x-api-key header for Promoted.ai's Metrics API.
metricsTimeoutMillis int Timeout on the Metrics API call.
logger Promoted.Lib.ILog This is an interface. You are responsible for implementing this interface. More details below.
options Promoted.Lib.DeliveryClientOptions? Optional. Specifies additional options, which are described below.

ILog interface

The methods which must be implemented for this interface are:

void Info(string message);
void Error(string message);

DeliveryClientOptions Properties

Name Type Description
ShadowTrafficRate float between 0 and 1 rate = [0,1] of traffic that gets directed to Delivery API as "shadow traffic". Only applies to cases where Delivery API is not called. Defaults to 0 (no shadow traffic). Throws an ArgumentException when trying to set a valid outside specified range.
Validate bool Performs some validation that request fields are filled properly. These checks take time so this should be turned off once a request is satisfactory.

DeliveryClient Methods

Method Input Output Description
Deliver Promoted.Delivery.Request, Promoted.Lib.DeliveryRequestOptions? Task<Promoted.Delivery.Response> Makes a request (subject to experimentation) to Delivery API for insertions, which are then returned. Second argument is optional. Specifies additional options, which are described below. When null, the default values below are used.
Dispose void Disposes of base HTTP clients.

DeliveryRequestOptions Properties

Name Type Description
OnlyLogToMetrics bool Defaults to false. Set to true to log the request as the CONTROL arm of an experiment, not call Delivery API, but rather deliver paged insertions from the request.
Experiment Promoted.Event.CohortMembership? Optional. A cohort to evaluation in experimentation.
RetrievalInsertionOffset int The offset the initial request insertion corresponds to in the list of ALL insertions. See Pages of Request Insertions for more details.

Calling the Delivery API

Let's say the previous code looks like this:

void async GetProducts(ProductRequest req):
    var products = ...; // Logic to get products from DB, apply filtering, etc.
    SendSuccessToClient(products)

We might modify to something like this:

void async GetProducts(ProductRequest req):
    var products = ...; // Logic to get products from DB, apply filtering, etc.

    List<Promoted.Delivery.Insertion> insertions = new List<Promoted.Delivery.Insertion>();
    // Keep a dictionary for reordering.
    Dictionary<string, Product> productMap = new Dictionary<string, Product>();
    foreach (Product product in products)
    {
        var insertion = new Promoted.Delivery.Insertion();
        insertion.ContentId = product.ProductId;
        insertions.Add(insertion);
        productMap.Add(product.ProductId, product);
    }

    var req = new Promoted.Delivery.Request();
    req.UserInfo = new Promoted.Common.UserInfo();
    req.UserInfo.UserId = "abc";
    req.Paging = new Delivery.Paging();
    req.Paging.Offset = 0;
    req.Paging.Size = 100;
    req.Insertion.AddRange(insertions);

    Promoted.Delivery.Response resp = await client.Deliver(req);

    List<Product> rankedProducts = new List<Product>();
    foreach (var insertion in resp.Insertion)
    {
        rankedProducts.Add(productMap[insertion.ContentId]);
    }

    SendSuccessToClient(rankedProducts)

Note that await client.Deliver(req) can throw here.

Data Types

UserInfo

Basic information about the request user.

Field Name Type Optional? Description
UserId string Yes The authenticated user id. This is not a saved directly in long term logs. This gets pseudo anonymized.
AnonUserId string Yes A different user id (presumably a UUID) disconnected from the authenticated user id (e.g. an "anonymous user id"), good for working with unauthenticated users or implementing right-to-be-forgotten.
IsInternalUser bool Yes If this user is a test user or not, defaults to false.

CohortMembership

Useful fields for experimentation during the delivery phase.

Field Name Type Optional? Description
Arm string Yes 'CONTROL' or one of the TREATMENT values ('TREATMENT', 'TREATMENT1', etc.).
CohortId string Yes Name of the cohort (e.g. "LOCAL_HOLDOUT" etc.)

Properties

Properties bag. Has the JSON structure:

  "struct": {
    "product": {
      "id": "product3",
      "title": "Product 3",
      "url": "www.mymarket.com/p/3"
      // Other <key, value> pairs...
    }
  }

Promoted.Delivery.Insertion

Content being served at a certain position.

Field Name Type Optional? Description
UserInfo Promoted.Common.UserInfo Yes The user info structure.
InsertionId string Yes Generated by the SDK (do not set).
ContentId string No Identifier for the content to be ranked, must be set.
RetrievalRank int Yes Optional original ranking of this content item.
RetrievalScore float Yes Optional original quality score of this content item.
Properties Promoted.Common.Properties Yes Any additional custom properties to associate. For v1 integrations, it is fine not to fill in all the properties.

Promoted.Common.Size

User's screen dimensions.

Field Name Type Optional? Description
Width int No Screen width.
Height int No Screen height.

Promoted.Common.Screen

State of the screen including scaling.

Field Name Type Optional? Description
Size Promoted.Common.Size Yes Screen size.
Scale float Yes Current screen scaling factor.

Promoted.Common.ClientHints

Alternative to user-agent strings. See https://raw.githubusercontent.com/snowplow/iglu-central/master/schemas/org.ietf/http_client_hints/jsonschema/1-0-0.

Field Name Type Optional? Description
IsMobile bool Yes Mobile flag.
Brand Promoted.Common.ClientBrandHint (repeated) Yes
Architecture string Yes
Model string Yes
Platform string Yes
Platform_version string Yes
UaFullVersion string Yes

Promoted.Common.ClientBrandHint

See https://raw.githubusercontent.com/snowplow/iglu-central/master/schemas/org.ietf/http_client_hints/jsonschema/1-0-0.

Field Name Type Optional? Description
Brand string Yes
Version string Yes

Promoted.Common.Location

Information about the user's location.

Field Name Type Optional? Description
Latitude float No Location latitude.
Longitude float No Location longitude.
AccuracyInMeters int Yes Location accuracy if available.

Promoted.Common.Browser

Information about the user's browser.

Field Name Type Optional? Description
UserAgent string Yes Browser user agent string.
ViewportSize Promoted.Common.Size Yes Size of the browser viewport.
ClientHints Promoted.Common.ClientHints Yes HTTP client hints structure.

Promoted.Common.Device

Information about the user's device.

Field Name Type Optional? Description
DeviceType one of (UNKNOWN_DEVICE_TYPE, DESKTOP, MOBILE, TABLET) Yes Type of device.
Brand string Yes "Apple, "google", Samsung", etc.
Manufacturer string Yes "Apple", "HTC", Motorola", "HUAWEI", etc.
Identifier string Yes Android: android.os.Build.MODEL; iOS: iPhoneXX,YY, etc.
Screen Promoted.CommonScreen Yes Screen dimensions.
IpAddress string Yes Originating IP address.
Location Promoted.CommonLocation Yes Location information.
Browser Promoted.CommonBrowser Yes Browser information.

Promoted.Common.Paging

Describes a page of insertions.

Field Name Type Optional? Description
Size int Yes Size of the page being requested.
Offset int Yes Page offset.

Promoted.Delivery.Request

A request for content insertions.

Field Name Type Optional? Description
Insertion Promoted.Delivery.Insertion (repeated) No The set of insertions to consider.
UserInfo Promoted.Common.UserInfo Yes The user info structure.
RequestId string Yes Generated by the SDK when needed (do not set).
UseCase string Yes One of the use case enum values or strings, i.e. 'FEED', 'SEARCH', etc.
Properties Promoted.Common.Properties Yes Any additional custom properties to associate.
Paging Promoted.Common.Paging Yes Paging parameters.
Device Promoted.Common.Device Yes Device information (as available).
DisablePersonalization bool Yes If true, disables personalized inputs to delivery.

Promoted.Delivery.Response

Output of Deliver(). Includes the ranked insertions for you to display.

Field Name Type Optional? Description
Insertion Promoted.Delivery.Insertion (repeated) No The ranked set of insertions (when Deliver() was called, i.e. we weren't either only-log or part of an experiment) or the input insertions (when the other conditions don't hold).
RequestId string No The ID from the corresponding request. Generated as part of processing. May be useful for logging and debugging.
PagingInfo Promoted.Delivery.PagingInfo Yes Information about the paging context for the corresponding request. Only populated if delivery service was successfully called.

Pages of Request Insertions

Clients can send a subset of all request insertions to Promoted in Delivery API's Request.Insertion array. The RetrievalInsertionOffset option specifies the start index of the array Request.Insertion in the list of ALL request insertions.

Request.Paging.Offset should be set to the zero-based position in ALL request insertions (not the relative position in the Request.Insertion array).

Examples

  • If there are 10 items and all 10 items are in Request.Insertion, then RetrievalInsertionOffset=0.
  • If there are 10,000 items and the first 500 items are on Request.Insertion, then RetrievalInsertionOffset=0.
  • If there are 10,000 items and we want to send items [500,1000) on Request.Insertion, then RetrievalInsertionOffset=500.
  • If there are 10,000 items and we want to send the last page [9500,10000) on Request.Insertion, then RetrievalInsertionOffset=9500.

RetrievalInsertionOffset is required to be less than Paging.Offset or else a ValueArgumentExceptionError will result.

Additional details: https://docs.promoted.ai/docs/ranking-requests#how-to-send-more-insertions-than-the-top-few-hundred

Position

  • Do not set the insertion Position field in client code. The SDK and Delivery API will set it when Deliver() is called.

Logging only

You can use Deliver() but enable the OnlyLogToMetrics option.

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. 
.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 was computed. 
.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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
0.2.0 2,248 11/16/2023
0.1.0 2,213 9/21/2023
0.0.1 109 9/19/2023
0.0.0 97 9/18/2023