Skip to content

Commit 31d0805

Browse files
authored
chore: upgrade to Python SDK v3 (#3)
1 parent 8def938 commit 31d0805

3 files changed

Lines changed: 74 additions & 38 deletions

File tree

‎README.md‎

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,50 @@
11
# featurevisor-example-python
22

3-
Tiny example application using the [Featurevisor Python SDK](https://github.com/featurevisor/featurevisor-python).
3+
A small Python application showing how to use the [Featurevisor Python SDK](https://github.com/featurevisor/featurevisor-python).
44

5-
Learn more about Featurevisor at [featurevisor.com](https://featurevisor.com).
5+
Learn more about Featurevisor [here](https://featurevisor.com).
6+
7+
It fetches a production datafile, creates a Featurevisor instance with customer context, then evaluates a flag, a variation, feature variables, and global variables.
68

79
## Requirements
810

9-
- Python 3.10+
11+
Python 3.10 or newer.
1012

1113
## Installation
1214

13-
```bash
15+
```sh
1416
python3 -m venv .venv
1517
source .venv/bin/activate
1618
pip install -r requirements.txt
1719
```
1820

19-
## Usage
21+
## Run the example
2022

21-
```bash
23+
```sh
2224
python main.py
2325
```
2426

25-
## What It Does
27+
The application evaluates `commerce_platform`, `checkout_experience`, `max_items`, `payment_methods`, `serviceEndpoints`, and `supportContact` from this datafile:
28+
29+
```text
30+
https://featurevisor-example-cloudflare.pages.dev/production/featurevisor-sdk-v3.json
31+
```
2632

27-
The script fetches the remote datafile, builds a Featurevisor instance, sets this default context, and evaluates a feature:
33+
Expected output:
2834

29-
```json
30-
{
31-
"userId": "123",
32-
"deviceId": "device-23456",
33-
"country": "nl"
34-
}
35+
```text
36+
Commerce platform enabled: true
37+
Checkout variation: express
38+
Maximum checkout items: 25
39+
Payment methods: ['card', 'wallet']
40+
Service endpoint: https://api.eu.example.com (timeout: 1200 ms, retries: 4)
41+
Support contact: support-nl@example.com
3542
```
3643

37-
It evaluates `my_feature`, which exists in the sample datafile.
44+
Change the context in `main.py` to see how Featurevisor selects different rules, variations, and global variable overrides.
3845

3946
## Featurevisor project
4047

41-
Uses this Featurevisor project to fetch the configuration from: https://github.com/featurevisor/featurevisor-example-cloudflare
48+
The datafile is generated by the [Featurevisor Cloudflare example](https://github.com/featurevisor/featurevisor-example-cloudflare).
49+
50+
Learn more in the [Featurevisor Python SDK documentation](https://featurevisor.com/docs/sdks/python/).

‎main.py‎

100755100644
Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,26 @@
77

88
from featurevisor import create_featurevisor
99

10-
DATAFILE_URL = "https://featurevisor-example-cloudflare.pages.dev/production/featurevisor-tag-all.json"
11-
FEATURE_KEY = "my_feature"
10+
DATAFILE_URL = "https://featurevisor-example-cloudflare.pages.dev/production/featurevisor-sdk-v3.json"
1211
CONTEXT = {
13-
"userId": "123",
14-
"deviceId": "device-23456",
12+
"userId": "customer-123",
1513
"country": "nl",
14+
"locale": "nl-NL",
15+
"accountPlan": "pro",
1616
}
1717

1818

1919
def fetch_datafile(url: str) -> dict:
20+
request = Request(
21+
url,
22+
headers={
23+
"User-Agent": "featurevisor-example-python/1.0",
24+
"Accept": "application/json",
25+
},
26+
)
27+
2028
try:
21-
request = Request(
22-
url,
23-
headers={
24-
"User-Agent": "featurevisor-example-python/1.0",
25-
"Accept": "application/json",
26-
},
27-
)
28-
with urlopen(request) as response:
29+
with urlopen(request, timeout=10) as response:
2930
return json.load(response)
3031
except HTTPError as exc:
3132
raise RuntimeError(f"failed to fetch datafile: HTTP {exc.code}") from exc
@@ -34,20 +35,46 @@ def fetch_datafile(url: str) -> dict:
3435

3536

3637
def main() -> int:
38+
f = None
39+
3740
try:
38-
datafile = fetch_datafile(DATAFILE_URL)
39-
f = create_featurevisor({"datafile": datafile, "logLevel": "error"})
40-
f.set_context(CONTEXT)
41-
enabled = f.is_enabled(FEATURE_KEY)
41+
f = create_featurevisor(
42+
{
43+
"datafile": fetch_datafile(DATAFILE_URL),
44+
"context": CONTEXT,
45+
"logLevel": "error",
46+
}
47+
)
48+
49+
commerce_enabled = f.is_enabled("commerce_platform")
50+
checkout_variation = f.get_variation("checkout_experience")
51+
max_items = f.get_variable_integer("checkout_experience", "max_items")
52+
payment_methods = f.get_variable_array(
53+
"checkout_experience", "payment_methods"
54+
)
55+
endpoints = f.get_variable_object("serviceEndpoints")
56+
support_contact = f.get_variable_string("supportContact")
57+
58+
print(f"Commerce platform enabled: {str(commerce_enabled).lower()}")
59+
print(f"Checkout variation: {value_or_unavailable(checkout_variation)}")
60+
print(f"Maximum checkout items: {value_or_unavailable(max_items)}")
61+
print(f"Payment methods: {payment_methods or []}")
62+
print(
63+
f"Service endpoint: {endpoints['baseUrl']} "
64+
f"(timeout: {endpoints['timeoutMs']} ms, retries: {endpoints['retries']})"
65+
)
66+
print(f"Support contact: {value_or_unavailable(support_contact)}")
67+
return 0
4268
except Exception as exc:
4369
print(f"Error: {exc}", file=sys.stderr)
4470
return 1
71+
finally:
72+
if f is not None:
73+
f.close()
74+
4575

46-
print(f"Datafile revision: {f.get_revision()}")
47-
print(f"Context: {json.dumps(CONTEXT)}")
48-
print(f"Feature '{FEATURE_KEY}' enabled: {enabled}")
49-
print(f"All evaluations: {json.dumps(f.get_all_evaluations(), sort_keys=True)}")
50-
return 0
76+
def value_or_unavailable(value: object) -> object:
77+
return "unavailable" if value is None else value
5178

5279

5380
if __name__ == "__main__":

‎requirements.txt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
featurevisor==2.0.0
1+
featurevisor==3.0.0

0 commit comments

Comments
 (0)