diff --git a/website/docs/sdk-reference/python.md b/website/docs/sdk-reference/python.md
index 8188f9c9..1f1e3918 100644
--- a/website/docs/sdk-reference/python.md
+++ b/website/docs/sdk-reference/python.md
@@ -4,6 +4,8 @@ title: Python SDK Reference
description: ConfigCat Python SDK Reference. This is a step-by-step guide on how to use feature flags in your Python application.
---
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
export const PythonSchema = require('@site/src/schema-markup/sdk-reference/python.json');
@@ -134,16 +136,16 @@ details = client.get_value_details(
The details result contains the following information:
-| Property | Description |
-| ------------------------------------ | ----------------------------------------------------------------------------------------- |
-| `value` | The evaluated value of the feature flag or setting. |
-| `key` | The key of the evaluated feature flag or setting. |
-| `is_default_value` | True when the default value passed to get_value_details() is returned due to an error. |
-| `error` | In case of an error, this field contains the error message. |
-| `user` | The user object that was used for evaluation. |
-| `matched_evaluation_percentage_rule` | If the evaluation was based on a percentage rule, this field contains that specific rule. |
-| `matched_evaluation_rule` | If the evaluation was based on a targeting rule, this field contains that specific rule. |
-| `fetch_time` | The last download time (UTC _datetime_) of the current config. |
+| Property | Description |
+| ------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
+| `value` | The evaluated value of the feature flag or setting. |
+| `key` | The key of the evaluated feature flag or setting. |
+| `is_default_value` | True when the default value passed to get_value_details() is returned due to an error. |
+| `error` | In case of an error, this field contains the error message. |
+| `user` | The user object that was used for evaluation. |
+| `matched_targeting_rule` | The targeting rule (if any) that matched during the evaluation and was used to return the evaluated value. |
+| `matched_percentage_option` | The percentage option (if any) that was used to select the evaluated value. |
+| `fetch_time` | The last download time (UTC _datetime_) of the current config. |
## User Object
@@ -160,12 +162,12 @@ user_object = User('john@example.com')
### Customized user object creation
-| Parameters | Description |
-| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| `identifier` | **REQUIRED.** Unique identifier of a user in your application. Can be any `string` value, even an email address. |
-| `email` | Optional parameter for easier targeting rule definitions. |
-| `country` | Optional parameter for easier targeting rule definitions. |
-| `custom` | Optional `dictionary of strings` representing the custom attributes of a user for advanced targeting rule definitions. e.g. User role, Subscription type. |
+| Parameters | Description |
+| ------------ | --------------------------------------------------------------------------------------------------------------------------------- |
+| `identifier` | **REQUIRED.** Unique identifier of a user in your application. Can be any `string` value, even an email address. |
+| `email` | Optional parameter for easier targeting rule definitions. |
+| `country` | Optional parameter for easier targeting rule definitions. |
+| `custom` | Optional `dictionary` for custom attributes of a user for advanced targeting rule definitions. E.g. User role, Subscription type. |
```python
user_object = User(
@@ -176,6 +178,47 @@ user_object = User(
)
```
+The `custom` dictionary also allows attribute values other than `string` values:
+
+```python
+user_object = User(
+ '#UNIQUE-USER-IDENTIFIER#',
+ custom={
+ 'Rating': 4.5,
+ 'RegisteredAt': datetime.fromisoformat('2023-11-22 12:34:56 +00:00'),
+ 'Roles': [ 'Role1', 'Role2' ]
+ }
+)
+```
+
+### User Object Attribute Types
+
+All comparators support `string` values as User Object attribute (in some cases they need to be provided in a specific format though, see below), but some of them also support other types of values. It depends on the comparator how the values will be handled. The following rules apply:
+
+**Text-based comparators** (EQUALS, IS_ONE_OF, etc.)
+* accept `string` values,
+* all other values are automatically converted to `string` (a warning will be logged but evaluation will continue as normal).
+
+**SemVer-based comparators** (IS_ONE_OF_SEMVER, LESS_THAN_SEMVER, GREATER_THAN_SEMVER, etc.)
+* accept `string` values containing a properly formatted, valid semver value,
+* all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
+
+**Number-based comparators** (EQUALS_NUMBER, LESS_THAN_NUMBER, GREATER_THAN_OR_EQUAL_NUMBER, etc.)
+* accept `float` values and all other numeric values which can safely be converted to `float`,
+* accept `string` values containing a properly formatted, valid `float` value,
+* all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
+
+**Date time-based comparators** (BEFORE_DATETIME / AFTER_DATETIME)
+* accept `datetime` values, which are automatically converted to a second-based Unix timestamp (`datetime` values with naive timezone are considered to be in UTC),
+* accept `float` values representing a second-based Unix timestamp and all other numeric values which can safely be converted to `float`,
+* accept `string` values containing a properly formatted, valid `float` value,
+* all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
+
+**String array-based comparators** (ARRAY_CONTAINS_ANY_OF / ARRAY_NOT_CONTAINS_ANY_OF)
+* accept arrays of `string`,
+* accept `string` values containing a valid JSON string which can be deserialized to an array of `string`,
+* all other values are considered invalid (a warning will be logged and the currently evaluated targeting rule will be skipped).
+
### Default user
There's an option to set a default user object that will be used at feature flag and setting evaluation. It can be useful when your application has a single user only, or rarely switches users.
@@ -398,11 +441,173 @@ The SDK supports 2 types of JSON structures to describe feature flags & settings
##### 2. Complex (full-featured) structure
This is the same format that the SDK downloads from the ConfigCat CDN.
-It allows the usage of all features you can do on the ConfigCat Dashboard.
+It allows the usage of all features you can access on the ConfigCat Dashboard.
You can download your current config JSON from ConfigCat's CDN and use it as a baseline.
-The URL to your current config JSON is based on your [Data Governance](advanced/data-governance.md) settings:
+
+
+
+A convenient way to get the config JSON for a specific SDK Key is to install the [ConfigCat CLI](https://github.com/configcat/cli) tool
+and execute the following command:
+
+```bash
+configcat config-json get -f v6 -p {YOUR-SDK-KEY} > config.json
+```
+
+(Depending on your [Data Governance](advanced/data-governance.md) settings, you may need to add the `--eu` switch.)
+
+Alternatively, you can download the config JSON manually, based on your [Data Governance](advanced/data-governance.md) settings:
+
+- GLOBAL: `https://cdn-global.configcat.com/configuration-files/{YOUR-SDK-KEY}/config_v6.json`
+- EU: `https://cdn-eu.configcat.com/configuration-files/{YOUR-SDK-KEY}/config_v6.json`
+
+```json
+{
+ "p": {
+ // hash salt, required only when sensitive text comparator(s) are used
+ "s": "80xCU/SlDz1lCiWFaxIBjyJeJecWjq46T4eu6GtozkM="
+ },
+ "s": [ // array of segments
+ {
+ "n": "Beta Users", // segment name
+ "r": [ // array of user conditions (there is a logical AND relation between the elements)
+ {
+ "a": "Email", // comparison attribute
+ "c": 0, // comparator (see below)
+ "l": [ // comparison value (see below)
+ "john@example.com", "jane@example.com"
+ ]
+ }
+ ]
+ }
+ ],
+ "f": { // key-value map of feature flags & settings
+ "isFeatureEnabled": { // key of a particular flag / setting
+ "t": 0, // setting type, possible values:
+ // 0 -> on/off setting (feature flag)
+ // 1 -> text setting
+ // 2 -> whole number setting
+ // 3 -> decimal number setting
+ "r": [ // array of targeting rules (there is a logical OR relation between the elements)
+ {
+ "c": [ // array of conditions (there is a logical AND relation between the elements)
+ {
+ "u": { // user condition
+ "a": "Email", // comparison attribute
+ "c": 2, // comparator, possible values and required comparison value types:
+ // 0 -> IS ONE OF (cleartext) + string array comparison value ("l")
+ // 1 -> IS NOT ONE OF (cleartext) + string array comparison value ("l")
+ // 2 -> CONTAINS ANY OF (cleartext) + string array comparison value ("l")
+ // 3 -> NOT CONTAINS ANY OF (cleartext) + string array comparison value ("l")
+ // 4 -> IS ONE OF (semver) + semver string array comparison value ("l")
+ // 5 -> IS NOT ONE OF (semver) + semver string array comparison value ("l")
+ // 6 -> < (semver) + semver string comparison value ("s")
+ // 7 -> <= (semver + semver string comparison value ("s")
+ // 8 -> > (semver) + semver string comparison value ("s")
+ // 9 -> >= (semver + semver string comparison value ("s")
+ // 10 -> = (number) + number comparison value ("d")
+ // 11 -> <> (number + number comparison value ("d")
+ // 12 -> < (number) + number comparison value ("d")
+ // 13 -> <= (number + number comparison value ("d")
+ // 14 -> > (number) + number comparison value ("d")
+ // 15 -> >= (number) + number comparison value ("d")
+ // 16 -> IS ONE OF (hashed) + string array comparison value ("l")
+ // 17 -> IS NOT ONE OF (hashed) + string array comparison value ("l")
+ // 18 -> BEFORE (UTC datetime) + second-based Unix timestamp number comparison value ("d")
+ // 19 -> AFTER (UTC datetime) + second-based Unix timestamp number comparison value ("d")
+ // 20 -> EQUALS (hashed) + string comparison value ("s")
+ // 21 -> NOT EQUALS (hashed) + string comparison value ("s")
+ // 22 -> STARTS WITH ANY OF (hashed) + string array comparison value ("l")
+ // 23 -> NOT STARTS WITH ANY OF (hashed) + string array comparison value ("l")
+ // 24 -> ENDS WITH ANY OF (hashed) + string array comparison value ("l")
+ // 25 -> NOT ENDS WITH ANY OF (hashed) + string array comparison value ("l")
+ // 26 -> ARRAY CONTAINS ANY OF (hashed) + string array comparison value ("l")
+ // 27 -> ARRAY NOT CONTAINS ANY OF (hashed) + string array comparison value ("l")
+ // 28 -> EQUALS (cleartext) + string comparison value ("s")
+ // 29 -> NOT EQUALS (cleartext) + string comparison value ("s")
+ // 30 -> STARTS WITH ANY OF (cleartext) + string array comparison value ("l")
+ // 31 -> NOT STARTS WITH ANY OF (cleartext) + string array comparison value ("l")
+ // 32 -> ENDS WITH ANY OF (cleartext) + string array comparison value ("l")
+ // 33 -> NOT ENDS WITH ANY OF (cleartext + string array comparison value ("l")
+ // 34 -> ARRAY CONTAINS ANY OF (cleartext) + string array comparison value ("l")
+ // 35 -> ARRAY NOT CONTAINS ANY OF (cleartext) + string array comparison value ("l")
+ "l": [ // comparison value - depending on the comparator, another type of value may need
+ // to be specified (see above):
+ // "s": string
+ // "d": number
+ "@example.com"
+ ]
+ }
+ },
+ {
+ "p": { // prerequisite flag condition
+ "f": "mainIntFlag", // key of prerequisite flag
+ "c": 0, // comparator, possible values: 0 -> EQUALS, 1 -> NOT EQUALS
+ "v": { // comparison value (value's type must match the prerequisite flag's type)
+ "i": 42
+ }
+ }
+ },
+ {
+ "s": { // segment condition
+ "s": 0, // segment index, a valid index into the top-level segment array ("s")
+ "c": 1 // comparator, possible values: 0 -> IS IN SEGMENT, 1 -> IS NOT IN SEGMENT
+ }
+ }
+ ],
+ "s": { // alternatively, an array of percentage options ("p", see below) can also be specified
+ "v": { // the value served when the rule is selected during evaluation
+ "b": true
+ },
+ "i": "bcfb84a7"
+ }
+ }
+ ],
+ "p": [ // array of percentage options
+ {
+ "p": 10, // % value
+ "v": { // the value served when the percentage option is selected during evaluation
+ "b": true
+ },
+ "i": "bcfb84a7"
+ },
+ {
+ "p": 90,
+ "v": {
+ "b": false
+ },
+ "i": "bddac6ae"
+ }
+ ],
+ "v": { // fallback value, served when none of the targeting rules match,
+ // no percentage options are defined or evaluation of these is not possible
+ "b": false // depending on the setting type, another type of value may need to be specified:
+ // text setting -> "s": string
+ // whole number setting -> "i": number
+ // decimal number setting -> "d": number
+ },
+ "i": "430bded3" // variation id (for analytical purposes)
+ }
+ }
+}
+```
+
+For a more comprehensive specification of the config JSON v6 format, you may refer to [this JSON schema document](https://github.com/configcat/config-json/blob/main/V6/config.schema.json).
+
+
+
+
+A convenient way to get the config JSON for a specific SDK Key is to install the [ConfigCat CLI](https://github.com/configcat/cli) tool
+and execute the following command:
+
+```bash
+configcat config-json get -f v5 -p {YOUR-SDK-KEY} > config.json
+```
+
+(Depending on your [Data Governance](advanced/data-governance.md) settings, you may need to add the `--eu` switch.)
+
+Alternatively, you can download the config JSON manually, based on your [Data Governance](advanced/data-governance.md) settings:
- GLOBAL: `https://cdn-global.configcat.com/configuration-files/{YOUR-SDK-KEY}/config_v5.json`
- EU: `https://cdn-eu.configcat.com/configuration-files/{YOUR-SDK-KEY}/config_v5.json`
@@ -469,6 +674,9 @@ The URL to your current config JSON is based on your [Data Governance](advanced/
}
```
+
+
+
### Dictionary
You can set up the SDK to load your feature flag & setting overrides from a dictionary.
@@ -522,14 +730,11 @@ Available log levels:
Info level logging helps to inspect the feature flag evaluation process:
```bash
-INFO -- : Evaluating get_value('isPOCFeatureEnabled').
-User object:
-{
- "Identifier" : "#UNIQUE-USER-IDENTIFIER#",
- "Email" : "john@example.com"
-}
-Evaluating rule: [Email] [CONTAINS] [@something.com] => no match
-Evaluating rule: [Email] [CONTAINS] [@example.com] => match, returning: True
+INFO:configcat:[5000] Evaluating 'isPOCFeatureEnabled' for User '{"Identifier":"","Email":"configcat@example.com","Country":"US","SubscriptionType":"Pro","Role":"Admin","version":"1.0.0"}'
+ Evaluating targeting rules and applying the first match if any:
+ - IF User.Email CONTAINS ANY OF ['@something.com'] THEN 'False' => no match
+ - IF User.Email CONTAINS ANY OF ['@example.com'] THEN 'True' => MATCH, applying rule
+ Returning 'True'.
```
## `get_all_keys()`