2.1.X
Introduction
SDK overview
Welcome to the Flagship Python SDK documentation!
The following article will guide you through the steps to get Flagship up and running on your Python servers or scripts using our client library with preconfigured methods to implement the Decision API.
SDK features
That SDK version helps you :
Set a visitor ID
Update user context
Assign campaigns via the Decision API or the Bucketing
Get modifications
Activate campaigns
Send hits to our Universal Collect
Prerequisites
Python: version 2.7.18 or later
Your server/device must have access to the internet.
You need the pip package installer in your Python environment.
Good to know
Github repository: https://github.com/abtasty/flagship-python-sdk
Weight: 22.6 ko
Python code supported
Open source demo app: https://github.com/abtasty/flagship-python-sdk/blob/master/examples/ecommerce
Getting Started
Installation
Our Python SDK is available on pypi.org. To install it, simply run the following command in your Python environment in a terminal:
pip install flagship
You can also install the library from other sources by running this command:
pip install -e path_to_flagship_repository"
Replace path_to_flagship_repository with the path to the directory with the cloned Flagship repository.
📘 Info Installing the library from its sources should automatically install its dependencies. If this isn't the case, execute the following command in your environment:
pip install -r requirements.txt
Initialization
Once the library is installed in your python environment, take your python source file:
First import the Flagship, Config class from flagship.app and flagship.config.
Get the Flagship install by calling Flagship.instance().
Then call the start() function passing a Config object as parameter.
from flagship.app import Flagship\nfrom flagship.config import Config\n\n#Start with default config\nFlagship.instance().start(\"your_env_id\", \"your_api_key\", Config())\n\n#Start in bucketing mode\nFlagship.instance().start(\"your_env_id\", \"your_api_key\",Config(event_handler=t, mode=Config.Mode.BUCKETING, polling_interval=5, timeout=0.1)```
Parameter | Type | Description
--------- | ------- | -----------
env_id | str | Environment id provided by Flagship.
api_key | str | Api authentication key provided by Flagship.
config | Config | configure the flagship SDK.
> 📘 Info
> You can find your `apiKey` and your `environmentId` on your Flagship account, in Parameters > Environment & Security. **[Find this ID](doc:getting-started)**
#### Configuration
The **Config** class lets you configure the SDK.
```python
from flagship.app import Flagship\nfrom flagship.config import Config\nfrom flagship.handler import FlagshipEventHandler\n\nclass CustomEventHandler(FlagshipEventHandler):\n def __init__(self):\n FlagshipEventHandler.__init__(self)\n\n def on_log(self, level, message):\n print(\"Log >> \" + message)\n pass\n\n def on_exception_raised(self, exception, traceback):\n FlagshipEventHandler.on_exception_raised(self, exception, traceback)\n print(\"Exception >> \" + str(exception))\n pass\n\n\n Flagship.instance().start(\"your_env_id\", \"your_api_key\"\n Config(event_handler=CustomEventHandler())```
**`Config.__init__(self, **kwargs):`**
Parameter | Type | Description
------------- | -------------------- | -----------
**kwargs | |
mode | Mode | Lets you start the Flagship SDK in `BUCKETING` mode (decision logic is executed sdk-side) or `DECISION_API` mode (decision logic is executed server-side). The decision mode is set to `DECISION_API` by default. **[Learn more](#decision-mode)**
event_handler | FlagshipEventHandler | Custom `FlagshipEventHandler` implementation to provide logs and error handling.
polling_interval | int or float | Bucketing polling interval in seconds. Default is 60 seconds. Min is 1 second. If <= 0 is given, polling will be disabled. In api mode, panic status will be updated at each call of synchronize_modifications. In Bucketing mode, panic status will be updated at each polling interval, or at start time if polling is disabled.
timeout | int or float | set a custom timeout in seconds for campaign requests. Default is 2 seconds.
#### Decision Mode
**`DECISION_API` Mode**
When the SDK is running in `DECISION_API` mode, the campaign assignments and targeting validation take place server-side. In this mode, each call to the `synchronizeModifications` method to refresh the modifications will create an HTTP request.
**`BUCKETING` Mode**
When the SDK is running in `BUCKETING` mode, the SDK downloads all the campaigns configurations at once in a single bucketing file so that variation assignment can be computed client-side by the SDK. This bucketing file is stored in cache and will only be downloaded again when campaign configurations are modified in the Flagship interface. It is possible to configure the interval of polling refresh with the polling_interval configuration. **[Learn more](doc:bucketing)**
#### Create a visitor
The `visitor` instance is a helper object that lets you manage the context and campaigns for a user identified by a unique ID.
The user context is a property dataset that defines the current user of your app. This dataset is sent and used by the Flagship Decision API as targeting criteria for campaign assignment.
For example, if you want to enable or disable a specific feature based on VIP status, you would pass this attribute as a key-value pair in the user context so that the Decision API can enable or disable the corresponding feature flag for the user.
> 📘 Info
> User context values are used for targetings.
```python
context = {\n\t'isVipUser':True,\n\t'name':'visitor',\n\t'age':30\n}\n\nvisitor = Flagship.instance().create_visitor(\"user_#1234\", True, context)
To create a new user use the function `create_visitor()'.
def create_visitor(self, visitor_id, authenticated=False, context={})"
visitor_id
str
Unique identifier for the current user. This can be an ID from your database or a session ID. If no value is passed, the SDK will automatically generate a unique ID. Learn more
authenticated
bool
Specify if the current visitor is authenticated or anonymous
context
dict
Optional. Dictionary of key-value pairs describing the user and device context. Learn more
🚧 Caution User context keys must have a type of
str
\n- User context values must have a type ofstr
,bool
,int
, orfloat
Updating the user context
The user context is a property dataset that defines the current user of your app. This dataset is sent and used by the Flagship Decision API as targeting criteria for campaign assignment.
The following method from the visitor
instance allows you to set new context values matching the given keys.
context = {\n\t'isVipUser':True,\n\t'name':'visitor',\n\t'age':30\n}\n\nvisitor = Flagship.instance().create_visitor(\"user_#1234\")\n\nvisitor.update_context(context)\nvisitor.update_context(('age', 31), True)\n
def update_context(self, context, synchronize=False)
context
dict, tuple
Dictionary {key: value}
or tuple (key, value)
describing the user and device context. Learn more
synchronize
bool
Optional. Set to False
by default. If set to True
, it will automatically call synchronize_modifications()
and then update the modifications from the server for all campaigns in accordance with the latest user context. You can also update them manually at any time with synchronize_modifications()
.
🚧 Caution User context keys must have a type of
str
\n- User context values must have a type ofstr
,bool
,int
, orfloat
Campaign synchronization
Synchronizing campaigns
The synchronize_modifications()
method of the visitor
instance automatically calls the Flagship Decision API to run campaign assignments according to the current user context and retrieve applicable modifications.
These modifications are then stored in the SDK and updated asynchronously when synchronizeModifications()
is called.
You can also synchronize campaigns by passing synchronize=True
parameter in the update_context
function.
visitor = Flagship.instance().create_visitor(\"user_#1234\", True, {'isVip':True})\n\n#Synchronize by passing True to update context.\nvisitor.update_context(('age', 31), True)\n\n#Synchronize with stand alone function\nvisitor.synchronize_modifications()\n
def synchronize_modifications(self)
Once the campaign has been assigned and synchronized, all the modifications are stored in the SDK. You can retrieve these modifications using the following functions from the visitor
instance:
visitor = Flagship.instance().create_visitor(\"user_#1234\", True, {'isVip':True})\nvisitor.synchronize_modifications()\n\nvip_feature_enabled = visitor.get_modification('vip_feature', False)\n
def get_modification(self, key, default_value, activate=False)
key
str
Key associated with the modification.
default_value
int, bool, float, str, dict, list
Default value returned when the key does not match any modification value.
activate
bool
Optional. Set to False
by default. Set this parameter to True
to automatically report on our server that the current visitor has seen this modification. If False
, call the activate_modification() later.
It returns the current modification or the default value.
Getting campaign information
You may need to send campaign IDs to a third-party for reporting and/or analytics purposes. It is now possible to retrieve campaign IDs for a specific modification key.
visitor = Flagship.instance().create_visitor(\"visitor_id\")\nvisitor.get_modification_info(\"modification_key\")\n
fun get_modification_info(key: String) : dict
key
str
Key associated with the modification.
It returns a dictionary containing campaignId
, variationGroupId
, variationId
and isReference
values or none if the modification is not found (i.e. user does not belong to the campaign).
Activating modifications
Once a modification is displayed on the screen for a user, you must send an activate event to tell Flagship that the user has seen this specific variation.
There are two options for activating a modification:
Pass an
activate=True
parameter to the get_modification() functionUse the following activate_modification() method from the visitor instance.
visitor = Flagship.instance().create_visitor(\"user_#1234\", True, {'isVip':True})\nvisitor.synchronize_modifications()\n\n#Activation during get_modification\nvip_feature_enabled = visitor.get_modification('vip_feature', True)\n\n#Activation from stand alone activate_modification\nmenu_order = visitor.get_modification('menu_order', False)\nvisitor.activate_modification('menu_order')\n\n
def activate_modification(self, key)
key
str
Key associated with the modification.
Experience Continuity
Dealing with anonymous and logged-in users, experience continuity allows you to maintain consistency between sessions and devices.
🚧 Warning Make sure that the experience continuity option is enabled on the flagship platform before using those methods.
Authenticate
def authenticate(self, visitor_id, context=None, synchronize=False)
visitor_id
string
new ID of the new authenticated visitor.
context
dict
(optional) Replace the current visitor context. Passing nil won't replace context and will ensure consistency with the previous visitor context.
synchronize
bool
(optional) if true, the SDK will automatically update the campaign's modifications. You also have the possibility to update it manually by calling synchronizeModifications()
Unauthenticate
def unauthenticate(self, context=None, synchronize=False)
context
map[string]interface{}
(optional) Replace the current visitor context. Passing nil won't replace context and will ensure consistency with the previous visitor context.
synchronize
bool
if true, the SDK will automatically update the campaign's modifications. You also have the possibility to update it manually by calling synchronizeModifications()
Code example
//When visitor log in.\nvisitor.authenticate(\"new_visitor_id\")\n\n//When visitor log out.\nvisitor.unauthenticate()
Hit Tracking
This section helps you track your users in your application and learn how to build hits in order to feed campaign goals. For more information about our measurement protocol, read our Universal Collect documentation.
There are four different types of Hits available:
Page
Transaction
Item
Event
They must all be built and sent with the following function from the visitor
instance:
def send_hit(self, hit)
Common parameters
visitor.send_hit(Page(\"https://www.mydomain.com/page\")\n .with_ip(\"133.3.223.1\")\n .with_locale(\"fr-fr\")\n .with_resolution(640, 480)\n .with_session_number(3))
userIp
str
Optional. User IP
screenResolution
str
Optional. Screen resolution.
userLanguage
str
Optional. User language
currentSessionTimeStamp
int64
Optional. Current Session Timestamp
sessionNumber
int
Optional. Session number
Page
This hit should be sent each time a visitor arrives on a new page on the server-side.
visitor.send_hit(Page(\"https://www.mydomain.com/page\"))
Page.__init__(self, location):
location
str
Required. valid URL.
Screen
This hit should be sent each time a visitor arrives on an interface on the client-side.
visitor.send_hit(Screen(\"python_interface_name\"))
Page.__init__(self, location):
location
str
Required. Interface name.
Transaction
This hit should be sent when a user completes a Transaction.
visitor.send_hit(Transaction(\"#309830\", \"purchases\")\n .with_currency(\"EUR\")\n .with_item_count(3)\n .with_payment_method(\"cb\")\n .with_shipping_cost(4.99)\n .with_shipping_method(\"1d\")\n .with_taxes(9.99)\n .with_total_revenue(420.00)\n .with_coupon_code(\"#SAVE10\"))
Transaction.__init__(self, transaction_id, affiliation)
transaction_id
str
Required. Unique identifier for your transaction.
Methods are provided to set the following values:
totalRevenue
float
Optional. Specifies the total revenue associated with the transaction. This value should include any shipping and/or tax amounts.
shippingCost
float
Optional. The total shipping cost of your transaction.
withShippingMethod
str
Optional. The shipping method for your transaction.
taxes
float
Optional. Specifies the total amount of taxes in your transaction.
currency
str
Optional. Specifies the currency of your transaction. NOTE: This value should be a valid ISO 4217 currency code.
paymentMethod
str
Optional. Specifies the payment method used for your transaction.
itemCount
int
Optional. Specifies the number of items in your transaction.
couponCode
str
Optional. Specifies the coupon code used by the customer in your transaction.
Item
This hit is used to link an item with a transaction. It must be sent after the corresponding transaction hit.
visitor.send_hit(Item(\"#309830\", \"ATX2080\", \"cg_atx_20802020\")\n .with_item_category(\"hardware\")\n .with_item_quantity(2)\n .with_price(210.00))\n
Item.__init__(self, transaction_id, product_name, productSku)
transaction_id
str
Required. Unique identifier for your transaction.
product_name
str
Required. The name of your item.
product_sku
str
Specifies the SKU or item code.
Methods are provided to set the following values:
price
float
Optional. Specifies the price for a single item/unit.
itemCategory
str
Optional. Specifies the category that the item belongs to.
itemQuantity
int
Optional. Specifies the number of items purchased.
📘 Info The
Item
hit isn't available yet in the Flagship reporting view.
Event
This hit can be used for any event (e.g. Add To Cart click, newsletter subscription).
visitor.send_hit(Event(EventCategory.USER_ENGAGEMENT, \"click_basket\")\n .with_event_label('basket button')\n .with_event_value(420))
Event.__init__(self, category, action)
category
EventCategory
Required. Specifies the category of your event. NOTE: This value must be either 'ACTION_TRACKING'
or 'USER_ENGAGEMENT'
.
action
str
Required. Event name that will also serve as the KPI that you will have inside your reporting. Learn more
Methods are provided to set the following values:
label
str
Optional. Additional description of your event.
value
int
Optional. Specifies the monetary value associated with an event (e.g. you earn 10 to 100 euros depending on the quality of lead generated). NOTE: this value must be non-negative integer > 0.
Caching visitor assignations
In some situations, you may need to cache visitor assignations. To do so, the Python SDK provides a useful class called VisitorCacheManager. This interface class should be implemented and passed at configuration time, in order to get callbacks with the information to save or to load.
class CustomVisitorCacheManager(VisitorCacheManager):\n\n def save(self, visitor_id, visitor_data):\n # Save visitor_data in your database.\n pass\n\n def lookup(self, visitor_id):\n # Load and return visitor_data from your database, with the expected format.\n pass\n\n\n Flagship.instance().start(\n \"_my_env_id\",\n \"_my_api_key_\",\n Config(event_handler=t, mode=Config.Mode.BUCKETING, polling_interval=5, timeout=0.1, visitor_cache_manager=CustomVisitorCacheManager()))\n
save(self, visitor_id, visitor_data)
Will be triggered after each call to synchronizationModification in order for you to save visitor assignations in your database.
visitor_id
str
Visitor identifier from which the data is coming from.
visitor_data
dict
Dictionary containing the assignations to save.
lookup(self, visitor_id)
Will be triggered before each call to synchronizationModification in order for you to load visitor assignations from your database.
visitor_id
str
Visitor identifier whose previous assignations must be loaded.
Expected json format to return from lookup function.
"version": 1,
"data": {
"vId": "toto",
"vaIds": [
"bmsor064jaeg0gm41het",
"bmsor064jaeg0gm4xxxx"
]
}
}
version
int
format version
vId
str
Visitor identifier who belongs the assignations.
vaIds
array
Array of variationId (assignations).
🚧 Warning Any other format will be ignored.
Release notes
2.1.5
Fixed
Prevent conflicts with Typing dependency
Removed:
Pytest dependency from requirements
2.1.1 (Latest version)
Fixed
Event hit value type: must be integer > 0
2.1.1
Added
Add headers in campaign request
Visitor authenticate() method for experience continuity.
Visitor unauthenticate() method for experience continuity.
Fixed
Fix package build
2.0.3
Added
Visitor Cache Manager
New Screen Hit for client side.
2.0.2
Fixed
Remove header from api call to events and activate endpoints.
2.0.1
Fixed
Targeting on lists
Added
isReference
value in getModificationInfo().
2.0.0
Changed
New api endpoints for better performance.
Murmur hash allocation improvements in bucketing mode.
Added
JSONArray / JSONObject modifications management.
Bucketing pollin refresh at regular intervals.
Timeout configuration.
1.1.0
Add bucketing mode
Add
get_modification_info
methodItem Hit product SKU is now required
Appendix
Sources
SDK library sources are available here.
Last updated
Was this helpful?