flagly-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flagly_sdk-0.1.0/PKG-INFO +9 -0
- flagly_sdk-0.1.0/flagly/__init__.py +4 -0
- flagly_sdk-0.1.0/flagly/client.py +93 -0
- flagly_sdk-0.1.0/flagly/models.py +54 -0
- flagly_sdk-0.1.0/flagly_sdk.egg-info/PKG-INFO +9 -0
- flagly_sdk-0.1.0/flagly_sdk.egg-info/SOURCES.txt +8 -0
- flagly_sdk-0.1.0/flagly_sdk.egg-info/dependency_links.txt +1 -0
- flagly_sdk-0.1.0/flagly_sdk.egg-info/top_level.txt +1 -0
- flagly_sdk-0.1.0/pyproject.toml +20 -0
- flagly_sdk-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flagly-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for the Flagly feature-flag API
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/useflagly/backend
|
|
7
|
+
Project-URL: Repository, https://github.com/useflagly/backend
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"""HTTP client for the Flagly feature-flag API."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import urllib.parse
|
|
7
|
+
import urllib.request
|
|
8
|
+
from typing import Any, Dict, Optional
|
|
9
|
+
|
|
10
|
+
from .models import ValidateBody, ReceiveMessage
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class FlaglyClient:
|
|
14
|
+
"""Client for the Flagly /validate API."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, base_url: str, token: Optional[str] = None, timeout: float = 10.0) -> None:
|
|
17
|
+
self._base_url = base_url.rstrip("/")
|
|
18
|
+
self._token = token
|
|
19
|
+
self._timeout = timeout
|
|
20
|
+
|
|
21
|
+
def _headers(self, environment: Optional[str] = None) -> Dict[str, str]:
|
|
22
|
+
h = {"Content-Type": "application/json"}
|
|
23
|
+
if self._token:
|
|
24
|
+
h["Authorization"] = f"Bearer {self._token}"
|
|
25
|
+
if environment:
|
|
26
|
+
h["environment"] = environment
|
|
27
|
+
return h
|
|
28
|
+
|
|
29
|
+
def _request(self, method: str, path: str, body: Any = None, environment: Optional[str] = None) -> Any:
|
|
30
|
+
url = self._base_url + path
|
|
31
|
+
data = json.dumps(body).encode() if body is not None else None
|
|
32
|
+
req = urllib.request.Request(url, data=data, headers=self._headers(environment), method=method)
|
|
33
|
+
with urllib.request.urlopen(req, timeout=self._timeout) as resp:
|
|
34
|
+
raw = resp.read()
|
|
35
|
+
if not raw:
|
|
36
|
+
return None
|
|
37
|
+
return json.loads(raw)
|
|
38
|
+
|
|
39
|
+
def health_check(self) -> Dict[str, Any]:
|
|
40
|
+
"""GET /validate/health"""
|
|
41
|
+
return self._request("GET", "/validate/health")
|
|
42
|
+
|
|
43
|
+
def validate_flag(self, slug: str, body: ValidateBody, environment: Optional[str] = None) -> Dict[str, Any]:
|
|
44
|
+
"""POST /validate/flag/:slug"""
|
|
45
|
+
return self._request("POST", f"/validate/flag/{urllib.parse.quote(slug)}", body.to_dict(), environment)
|
|
46
|
+
|
|
47
|
+
def get_flag_cache(self, slug: str, identifier: Optional[str] = None) -> Dict[str, Any]:
|
|
48
|
+
"""GET /validate/flag/:slug"""
|
|
49
|
+
path = f"/validate/flag/{urllib.parse.quote(slug)}"
|
|
50
|
+
if identifier:
|
|
51
|
+
path += f"?identifier={urllib.parse.quote(identifier)}"
|
|
52
|
+
return self._request("GET", path)
|
|
53
|
+
|
|
54
|
+
def validate_flow(self, slug: str, body: ValidateBody, environment: Optional[str] = None) -> Dict[str, Any]:
|
|
55
|
+
"""POST /validate/flow/:slug"""
|
|
56
|
+
return self._request("POST", f"/validate/flow/{urllib.parse.quote(slug)}", body.to_dict(), environment)
|
|
57
|
+
|
|
58
|
+
def get_flow_cache(self, slug: str, identifier: Optional[str] = None) -> Dict[str, Any]:
|
|
59
|
+
"""GET /validate/flow/:slug"""
|
|
60
|
+
path = f"/validate/flow/{urllib.parse.quote(slug)}"
|
|
61
|
+
if identifier:
|
|
62
|
+
path += f"?identifier={urllib.parse.quote(identifier)}"
|
|
63
|
+
return self._request("GET", path)
|
|
64
|
+
|
|
65
|
+
def validate_flow_part(self, slug: str, body: ValidateBody, environment: Optional[str] = None) -> Dict[str, Any]:
|
|
66
|
+
"""POST /validate/flow-part/:slug"""
|
|
67
|
+
return self._request("POST", f"/validate/flow-part/{urllib.parse.quote(slug)}", body.to_dict(), environment)
|
|
68
|
+
|
|
69
|
+
def get_flow_part_cache(self, slug: str, identifier: Optional[str] = None) -> Dict[str, Any]:
|
|
70
|
+
"""GET /validate/flow-part/:slug"""
|
|
71
|
+
path = f"/validate/flow-part/{urllib.parse.quote(slug)}"
|
|
72
|
+
if identifier:
|
|
73
|
+
path += f"?identifier={urllib.parse.quote(identifier)}"
|
|
74
|
+
return self._request("GET", path)
|
|
75
|
+
|
|
76
|
+
def validate_scenario(self, slug: str, body: ValidateBody, environment: Optional[str] = None) -> Dict[str, Any]:
|
|
77
|
+
"""POST /validate/scenario/:slug"""
|
|
78
|
+
return self._request("POST", f"/validate/scenario/{urllib.parse.quote(slug)}", body.to_dict(), environment)
|
|
79
|
+
|
|
80
|
+
def get_scenario_cache(self, slug: str, identifier: Optional[str] = None) -> Dict[str, Any]:
|
|
81
|
+
"""GET /validate/scenario/:slug"""
|
|
82
|
+
path = f"/validate/scenario/{urllib.parse.quote(slug)}"
|
|
83
|
+
if identifier:
|
|
84
|
+
path += f"?identifier={urllib.parse.quote(identifier)}"
|
|
85
|
+
return self._request("GET", path)
|
|
86
|
+
|
|
87
|
+
def initialize(self, body: ReceiveMessage, environment: Optional[str] = None) -> Optional[Dict[str, Any]]:
|
|
88
|
+
"""POST /validate/initialize"""
|
|
89
|
+
return self._request("POST", "/validate/initialize", body.to_dict(), environment)
|
|
90
|
+
|
|
91
|
+
def get_result(self, identifier: str) -> Dict[str, Any]:
|
|
92
|
+
"""GET /validate/result/:identifier"""
|
|
93
|
+
return self._request("GET", f"/validate/result/{urllib.parse.quote(identifier)}")
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Code generated from JSON Schema. DO NOT EDIT.
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ValidateBody:
|
|
7
|
+
identifier: Optional[str]
|
|
8
|
+
context: Optional[Dict[str, Any]]
|
|
9
|
+
|
|
10
|
+
def __init__(self, identifier: Optional[str] = None, context: Optional[Dict[str, Any]] = None) -> None:
|
|
11
|
+
self.identifier = identifier
|
|
12
|
+
self.context = context
|
|
13
|
+
|
|
14
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
15
|
+
result: Dict[str, Any] = {}
|
|
16
|
+
if self.identifier is not None:
|
|
17
|
+
result["identifier"] = self.identifier
|
|
18
|
+
if self.context is not None:
|
|
19
|
+
result["context"] = self.context
|
|
20
|
+
return result
|
|
21
|
+
|
|
22
|
+
@staticmethod
|
|
23
|
+
def from_dict(d: Dict[str, Any]) -> "ValidateBody":
|
|
24
|
+
return ValidateBody(identifier=d.get("identifier"), context=d.get("context"))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ReceiveMessage:
|
|
28
|
+
identifier: str
|
|
29
|
+
slug: str
|
|
30
|
+
company_id: Optional[float]
|
|
31
|
+
context: Optional[Dict[str, Any]]
|
|
32
|
+
|
|
33
|
+
def __init__(self, identifier: str, slug: str, company_id: Optional[float] = None, context: Optional[Dict[str, Any]] = None) -> None:
|
|
34
|
+
self.identifier = identifier
|
|
35
|
+
self.slug = slug
|
|
36
|
+
self.company_id = company_id
|
|
37
|
+
self.context = context
|
|
38
|
+
|
|
39
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
40
|
+
result: Dict[str, Any] = {"identifier": self.identifier, "slug": self.slug}
|
|
41
|
+
if self.company_id is not None:
|
|
42
|
+
result["companyId"] = self.company_id
|
|
43
|
+
if self.context is not None:
|
|
44
|
+
result["context"] = self.context
|
|
45
|
+
return result
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def from_dict(d: Dict[str, Any]) -> "ReceiveMessage":
|
|
49
|
+
return ReceiveMessage(
|
|
50
|
+
identifier=d["identifier"],
|
|
51
|
+
slug=d["slug"],
|
|
52
|
+
company_id=d.get("companyId"),
|
|
53
|
+
context=d.get("context"),
|
|
54
|
+
)
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flagly-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for the Flagly feature-flag API
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/useflagly/backend
|
|
7
|
+
Project-URL: Repository, https://github.com/useflagly/backend
|
|
8
|
+
Requires-Python: >=3.8
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
flagly
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "flagly-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python SDK for the Flagly feature-flag API"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.8"
|
|
12
|
+
dependencies = []
|
|
13
|
+
|
|
14
|
+
[project.urls]
|
|
15
|
+
Homepage = "https://github.com/useflagly/backend"
|
|
16
|
+
Repository = "https://github.com/useflagly/backend"
|
|
17
|
+
|
|
18
|
+
[tool.setuptools.packages.find]
|
|
19
|
+
where = ["."]
|
|
20
|
+
include = ["flagly*"]
|