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.
@@ -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,4 @@
1
+ from .client import FlaglyClient
2
+ from .models import ValidateBody, ReceiveMessage
3
+
4
+ __all__ = ["FlaglyClient", "ValidateBody", "ReceiveMessage"]
@@ -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,8 @@
1
+ pyproject.toml
2
+ flagly/__init__.py
3
+ flagly/client.py
4
+ flagly/models.py
5
+ flagly_sdk.egg-info/PKG-INFO
6
+ flagly_sdk.egg-info/SOURCES.txt
7
+ flagly_sdk.egg-info/dependency_links.txt
8
+ flagly_sdk.egg-info/top_level.txt
@@ -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*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+