Ajouter des événements facturables à un paquet d’application¶
Lorsque vous utilisez Custom Event Billing pour une Snowflake Native App, vous pouvez facturer des types spécifiques d’utilisation de l’application en plus des plans tarifaires existants basés sur l’utilisation. Pour mettre cela en place, vous devez effectuer deux étapes de haut niveau :
Configurez votre paquet d’application pour qu’il émette des événements facturables en suivant les étapes de cette rubrique.
Choisissez un plan de tarification basé sur l’utilisation avec des événements facturables pour l’annonce que vous utilisez pour publier votre Snowflake Native App auprès des consommateurs.
Cette rubrique décrit comment configurer votre paquet d’application pour qu’elle émette des événements facturables à l’aide de la fonction système SYSTEM$CREATE_BILLING_EVENT.
Aperçu des événements facturables dans un paquet d’application¶
Vous pouvez configurer votre paquet d’application pour qu’il émette des événements facturables en réponse à des événements d’utilisation spécifiques, de sorte que vous puissiez facturer les consommateurs en fonction de l’utilisation qu’ils font de votre Snowflake Native App.
Par exemple, vous pouvez ajouter un événement facturable pour facturer à un consommateur un montant spécifique pour chaque appel à une procédure stockée dans votre Snowflake Native App.
Pour ajouter des événements facturables à un paquet d’application, procédez comme suit :
Créez des procédures stockées pour définir les événements d’utilisation qui déclenchent des appels à la fonction système SYSTEM$CREATE_BILLING_EVENT.
Note
Vous ne pouvez pas tester la sortie de la fonction système à ce stade. Cette fonction système ne peut être appelée qu’à partir d’une Snowflake Native App installée sur un compte consommateur.
Ajoutez ces procédures stockées au script d’installation du paquet d’application.
Important
Snowflake prend en charge les événements facturables qui sont émis en appelant la fonction système au sein d’une procédure stockée dans l’application, comme indiqué dans les exemples de cette rubrique.
Snowflake ne prend pas en charge d’autres méthodes de calcul des frais de base pour les événements facturables, telles que les méthodes qui utilisent la sortie d’une table ou d’une fonction définie par l’utilisateur qui renvoie l’activité du consommateur ou les méthodes utilisant la télémétrie enregistrée dans un table d’événements.
Si vous ne savez pas si la mise en œuvre proposée sera prise en charge, contactez votre représentant de compte Snowflake.
Exemples d’événements facturables¶
Les exemples de cette section montrent comment créer des procédures stockées pour émettre des événements facturables dans le cadre de scénarios de facturation courants. Chacun de ces exemples appelle la fonction createBillingEvent
définie dans Appeler la fonction système SYSTEM$CREATE_BILLING_EVENT.
Appeler la fonction système SYSTEM$CREATE_BILLING_EVENT¶
L’exemple suivant montre comment créer une fonction wrapper dans une procédure stockée pour appeler la fonction système SYSTEM$CREATE_BILLING_EVENT.
Note
Vous pouvez appeler cette fonction système dans une procédure stockée écrite en JavaScript, Python ou Java.
Cet exemple crée une procédure stockée JavaScript nommée custom_event_billing
dans la base de données db_1
et le schéma public
. La procédure stockée crée une fonction d’aide appelée createBillingEvent
qui prend des arguments correspondant aux paramètres typés attendus par la fonction système SYSTEM$CREATE_BILLING_EVENT.
Pour plus de détails sur les paramètres et les types requis, voir SYSTEM$CREATE_BILLING_EVENT.
CREATE OR REPLACE PROCEDURE db_1.public.custom_event_billing()
RETURNS NULL
LANGUAGE JAVASCRIPT
AS
$$
/**
* Helper method to add a billable event
* Format timestamps as Unix timestamps in milliseconds
*/
function createBillingEvent(className, subclassName, startTimestampVal, timestampVal, baseCharge, objects, additionalInfo) {
try {
var res = snowflake.createStatement({
sqlText: `SELECT SYSTEM$CREATE_BILLING_EVENT('${className}',
'${subclassName}',
${startTimestampVal},
${timestampVal},
${baseCharge},
'${objects}',
'${additionalInfo}')`
}).execute();
res.next();
return res.getColumnValue(1);
} catch(err) {
return err.message;
}
}
$$;
Les exemples de cette rubrique font appel à cette fonction d’aide.
Exemple : facturation basée sur les appels à une procédure stockée¶
L’exemple suivant montre comment créer une procédure stockée qui émet un événement facturable lorsqu’un consommateur appelle cette procédure stockée dans une Snowflake Native App.
Ajoutez ce code d’exemple à votre script d’installation dans la même procédure stockée que celle qui définit la fonction d’aide :
...
//
// Send a billable event when a stored procedure is called.
//
var event_ts = Date.now();
var billing_quantity = 1.0;
var base_charge = billing_quantity;
var objects = "[ \"db_1.public.procedure_1\" ]";
var retVal = createBillingEvent("PROCEDURE_CALL", "", event_ts, event_ts, base_charge, objects, "");
// Run the rest of the procedure ...
$$;
Cet exemple de code crée une procédure stockée qui appelle la fonction createBillingEvent
pour émettre un événement facturable avec le nom de classe PROCEDURE_CALL
et des frais de base de 1.0
.
Note
Les types des arguments transmis à la fonction createBillingEvent
doivent correspondre aux paramètres typés attendus par la fonction du système SYSTEM$CREATE_BILLING_EVENT.
Exemple : facturation basée sur les lignes consommées par une application native Snowflake¶
L’exemple suivant montre comment créer une procédure stockée pour émettre un événement facturable basé sur le nombre de lignes consommées dans une table du compte consommateur.
Ajoutez ce code d’exemple à votre script d’installation dans la même procédure stockée que celle qui définit la fonction d’aide :
...
// Run a query and get the number of rows in the result
var select_query = "select i from db_1.public.t1";
res = snowflake.execute ({sqlText: select_query});
res.next();
//
// Send a billable event for rows returned from the select query
//
var event_ts = Date.now();
var billing_quantity = 2.5;
var base_charge = res.getRowcount() * billing_quantity;
var objects = "[ \"db_1.public.t1\" ]";
createBillingEvent("ROWS_CONSUMED", "", event_ts, event_ts, base_charge, objects, "");
// Run the rest of the procedure ...
$$;
Cet exemple de code crée une procédure stockée qui appelle la fonction createBillingEvent
pour émettre un événement facturable avec le nom de classe ROWS_CONSUMED
et des frais de base calculés de 2.5
multipliés par le nombre de lignes de la table db_1.public.t1
dans le compte consommateur.
Note
Les types des arguments transmis à la fonction createBillingEvent
doivent correspondre aux paramètres typés attendus par la fonction du système SYSTEM$CREATE_BILLING_EVENT.
Exemple : facturation basée sur le nombre de lignes ingérées¶
L’exemple suivant montre comment créer une procédure stockée pour émettre un événement facturable en fonction du nombre de lignes ingérées dans une table.
Ajoutez ce code d’exemple à votre script d’installation dans la même procédure stockée que celle qui définit la fonction d’aide :
...
// Run the merge query
var merge_query = "MERGE INTO target_table USING source_table ON target_table.i = source_table.i
WHEN MATCHED THEN UPDATE SET target_table.j = source_table.j
WHEN NOT MATCHED
THEN INSERT (i, j)
VALUES (source_table.i, source_table.j)";
res = snowflake.execute ({sqlText: merge_query});
res.next();
// rows ingested = rows inserted + rows updated
var numRowsIngested = res.getColumnValue(1) + res.getColumnValue(2);
//
// Send a billable event for rows changed by the merge query
//
var event_ts = Date.now();
var billing_quantity = 2.5;
var base_charge = numRowsIngested * billing_quantity;
var objects = "[ \"db_1.public.target_table\" ]";
createBillingEvent("ROWS_CHANGED", "", event_ts, event_ts, base_charge, objects, "");
// Run the rest of the procedure ...
$$;
Cet exemple de code crée une procédure stockée qui appelle la fonction createBillingEvent
pour émettre un événement facturable avec le nom de classe ROWS_CHANGED
et un tarif de base calculé de 2.5
multiplié par le nombre de lignes ingérées dans la table db_1.target_table
.
Note
Les types des arguments transmis à la fonction createBillingEvent
doivent correspondre aux paramètres typés attendus par la fonction du système SYSTEM$CREATE_BILLING_EVENT.
Exemple : facturation basée sur les lignes actives mensuelles¶
Les lignes actives mensuelles correspondent au nombre de lignes insérées ou mises à jour pour la première fois au cours d’un mois civil. Certains fournisseurs utilisent cette métrique pour ne facturer aux consommateurs que les lignes uniques mises à jour au cours d’un mois. Vous pouvez modifier cet exemple pour compter plutôt les utilisateurs uniques, ou identifier un emplacement unique de chargement de données pour déterminer un tarif de base.
L’exemple suivant montre comment créer une procédure stockée pour déclencher un événement facturable en fonction du nombre de lignes actives mensuelles. Ajoutez ce code d’exemple à votre script d’installation dans la même procédure stockée que celle qui définit la fonction d’aide :
...
//
// Get monthly active rows
//
var monthly_active_rows_query = "
SELECT
count(*)
FROM
source_table
WHERE
source_table.i not in
(
SELECT
i
FROM
target_table
WHERE
updated_on >= DATE_TRUNC('MONTH', CURRENT_TIMESTAMP)
)";
res = snowflake.execute ({sqlText: monthly_active_rows_query});
res.next();
var monthlyActiveRows = parseInt(res.getColumnValue(1));
//
// Run the merge query and update the updated_on values for the rows
//
var merge_query = "
MERGE INTO
target_table
USING
source_table
ON
target_table.i = source_table.i
WHEN MATCHED THEN
UPDATE SET target_table.j = source_table.j
,target_table.updated_on = current_timestamp
WHEN NOT MATCHED THEN
INSERT (i, j, updated_on) VALUES (source_table.i, source_table.j, current_timestamp)";
res = snowflake.execute ({sqlText: merge_query});
res.next();
//
// Emit a billable event for monthly active rows changed by the merge query
//
var event_ts = Date.now();
var billing_quantity = 0.02
var base_charge = monthlyActiveRows * billing_quantity;
var objects = "[ \"db_1.public.target_table\" ]";
createBillingEvent("MONTHLY_ACTIVE_ROWS", "", event_ts, event_ts, base_charge, objects, "");
// Run the rest of the procedure ...
$$;
Cet exemple de code crée une procédure stockée qui détermine le nombre de lignes actives mensuelles à l’aide d’une requête de fusion pour identifier les lignes uniques. L’exemple calcule ensuite le tarif de base en utilisant la valeur de la variable monthlyActiveRows
et la billing_quantity
. Le tarif de base est ensuite transmis à la fonction createBillingEvent
.
Note
Les types des arguments transmis à la fonction createBillingEvent
doivent correspondre aux paramètres typés attendus par la fonction du système SYSTEM$CREATE_BILLING_EVENT.
Dans votre script d’installation, ajoutez cette procédure stockée après la procédure stockée qui appelle la fonction système SYSTEM$CREATE_BILLING_EVENT.
Exemple Snowpark Python : facturation basée sur les lignes consommées¶
Si vous voulez écrire votre procédure stockée en Snowpark Python pour facturer en fonction des lignes consommées par votre Snowflake Native App, utilisez l’exemple suivant :
CREATE OR REPLACE PROCEDURE app_schema.billing_event_rows()
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = '3.9'
PACKAGES = ('snowflake-snowpark-python')
HANDLER = 'run'
EXECUTE AS OWNER
AS $$
import time
# Helper method that calls the system function for billing
def createBillingEvent(session, class_name, subclass_name, start_timestamp, timestamp, base_charge, objects, additional_info):
session.sql(f"SELECT SYSTEM$CREATE_BILLING_EVENT('{class_name}', '{subclass_name}', {start_timestamp}, {timestamp}, {base_charge}, '{objects}', '{additional_info}')").collect()
return "Success"
# Handler function for the stored procedure
def run(session):
# insert code to identify monthly active rows and calculate a charge
try:
# Run a query to select rows from a table
query = "select i from db_1.public.t1"
res = session.sql(query).collect()
# Define the price to charge per row
billing_quantity = 2.5
# Calculate the base charge based on number of rows in the result
charge = len(res) * billing_quantity
# Current time in Unix timestamp (epoch) time in milliseconds
current_time_epoch = int(time.time() * 1000)
return createBillingEvent(session, 'ROWS_CONSUMED', '', current_time_epoch, current_time_epoch, charge, '["billing_event_rows"]', '')
except Exception as ex:
return "Error " + ex
$$;
Cet exemple de code crée une procédure stockée qui définit une méthode d’aide qui appelle la fonction système SYSTEM$CREATE_BILLING_EVENT , ainsi qu’une méthode qui appelle cette méthode d’aide, createBillingEvent
, pour émettre un événement facturable avec le nom de classe ROWS_CONSUMED
et des frais de base calculés en multipliant un prix de 2.5
dollars US par le nombre de lignes de la table db_1.public.t1
dans le compte consommateur.
Note
Les types des arguments transmis à la fonction createBillingEvent
doivent correspondre aux paramètres typés attendus par la fonction du système SYSTEM$CREATE_BILLING_EVENT.
Test Custom Event Billing¶
Pour vous assurer que vous avez correctement configuré Custom Event Billing et que les événements facturables sont émis pour les événements d’utilisation comme vous le souhaitez, procédez comme suit :
Mettez à jour votre paquet d’application :
Mettez à jour votre script d’installation pour inclure les procédures stockées qui émettent des événements facturables.
Mettez à jour votre paquet d’application avec le nouveau script d’installation.
Mettez à jour la directive de version et à la publication de votre paquet d’application.
Partagez le paquet d’application avec un compte consommateur de votre organisation auquel vous avez accès :
Ajoutez Custom Event Billing comme plan tarifaire pour l’annonce.
Partagez-le avec le compte consommateur.
Connectez-vous au compte consommateur à l’aide de Snowsight.
Installez l”Snowflake Native App.
Confirmez que les procédures stockées émettent avec succès des événements facturables.
Confirmez que l’annonce est correctement établie.
Note
Lorsque vous testez Custom Event Billing, vous devez configurer une méthode de paiement mais vous ne serez pas facturé pour l’utilisation au sein de votre organisation.
Valider si les procédures stockées génèrent des événements facturables¶
Tout en étant connecté au compte consommateur avec lequel vous avez partagé votre annonce, appelez les procédures stockées que vous avez ajoutées à votre Snowflake Native App.
Par exemple, pour tester la procédure stockée créée pour la facturation sur la base des lignes actives mensuelles, procédez comme suit :
Connectez-vous au compte consommateur dans Snowsight.
Ouvrez une feuille de calcul et définissez le contexte sur
db_1.public
.Exécutez la instruction SQL suivante :
CALL merge_procedure()
Si la procédure stockée renvoie
Success
, votre code fonctionne.
Note
Si vous exécutez ces commandes SQL dans le compte fournisseur que vous avez utilisé pour créer le paquet d’application, une erreur apparaît.
Valider le plan tarifaire Custom Event Billing¶
Pour valider l’expérience consommateur d’une Snowflake Native App et confirmer que votre annonce et votre paquet d’application sont correctement configurés, vous pouvez interroger la vue MARKETPLACE_PAID_USAGE_DAILY dans le schéma DATA_SHARING_USAGE de la base de données partagée SNOWFLAKE.
Note
En raison du temps de latence dans la vue, exécutez ces requêtes au moins deux jours après avoir utilisé l”Snowflake Native App pour la première fois.
Pour confirmer que les événements facturables sont bien générés par une Snowflake Native App et une annonce, exécutez l’instruction SQL suivante sur le compte consommateur avec lequel vous avez partagé l’annonce :
Note
Remplacez les valeurs PROVIDER_ACCOUNT_NAME et PROVIDER_ORGANIZATION_NAME par celles du compte fournisseur.
SELECT listing_global_name,
listing_display_name,
charge_type,
charge
FROM SNOWFLAKE.DATA_SHARING_USAGE.MARKETPLACE_PAID_USAGE_DAILY
WHERE charge_type='MONETIZABLE_BILLING_EVENTS'
AND PROVIDER_ACCOUNT_NAME = <account_name>
AND PROVIDER_ORGANIZATION_NAME= <organization_name>;
+---------------------+------------------------+----------------------------+--------+
| LISTING_GLOBAL_NAME | LISTING_DISPLAY_NAME | CHARGE_TYPE | CHARGE |
+---------------------+------------------------+----------------------------+--------+
| AAAA0BBB1CC | Snowy Mountain Listing | MONETIZABLE_BILLING_EVENTS | 18.6 |
+---------------------+------------------------+----------------------------+--------+
Pour voir tous les détails associés au plan de tarification de l’annonce et valider que le plan correspond aux frais de l’application, exécutez l’instruction SQL suivante dans le compte consommateur avec lequel vous avez partagé l’annonce :
Note
Les champs précédés de pp
représentent les champs spécifiés uniquement dans l’annonce comme faisant partie du plan tarifaire.
SELECT
listing_display_name,
listing_global_name,
be.value:display_name::varchar as class_name,
be.value:class::varchar as class,
units,
be.value:billing_unit::varchar as billing_unit,
unit_price,
charge,
be.value:billing_quantity::float as pp_billing_quantity
FROM
SNOWFLAKE.DATA_SHARING_USAGE.MARKETPLACE_PAID_USAGE_DAILY,
LATERAL FLATTEN(INPUT => pricing_plan:billing_events) be
WHERE
charge_type = 'MONETIZABLE_BILLING_EVENTS'
AND PROVIDER_ACCOUNT_NAME = <account_name>
AND PROVIDER_ORGANIZATION_NAME= <organization_name>;
+------------------------+---------------------+-------------+---------------+-------+--------------+------------+--------+---------------------+
| LISTING_DISPLAY_NAME | LISTING_GLOBAL_NAME | CLASS_NAME | CLASS | UNITS | BILLING_UNIT | UNIT_PRICE | CHARGE | PP_BILLING_QUANTITY |
+------------------------+---------------------+-------------+---------------+-------+--------------+------------+--------+---------------------+
| Snowy Mountain Listing | AAAA0BBB1CC | Active Rows | ROWS_CONSUMED | 18.6 | ROW | 1 | 18.6 | 1 |
+------------------------+---------------------+-------------+---------------+-------+--------------+------------+--------+---------------------+