# FeatureGate
Featuregate is a simple feature flag API similar to [Flipper](https://github.com/flippercloud/flipper).
## Configuration
### PosthogAdapter
```bash
export POSTHOG_API_KEY="someapikey"
export POSTHOG_PROJECT_ID="someprojectid"
```
## Usage
```python
from feature_gate.client import Client
from feature_gate.adapters import PosthogAdapter
from feature_gate.feature import Feature
adapter = PosthogAdapter() # Or MemoryAdapter for testing
client = Client(adapter)
feature = Feature("Test flag", "test_flag", "This is a test flag")
client.features()
# => []
client.add(feature)
# => True
client.features()
# => ["test_flag"]
client.is_enabled("test_flag")
# => False
client.enable("test_flag")
# => True
client.is_enabled("test_flag")
# => True
client.disable("test_flag")
# => True
client.is_enabled("test_flag")
# => False
client.remove("test_flag")
# => True
client.features()
# => []
```
## Errors
### FeatureNotFound
If you try to run something that presumes the existence of a feature and it can't find it it'll throw a `FeatureNotFound`.
```python
from feature_gate.client import FeatureNotFound
try:
client.remove("some_feature_that_definitely_does_not_exist")
except FeatureNotFound as err:
# Do what we want to do when the feature doesn't exist
```
### PosthogApiClientError
For the `PosthogAdapter` in particular it will raise error if it was unable to reach the Posthog API. These get bubbled up as `PosthogAPIClientError`.
```python
from feature_gate.clients.posthog_api_client import PosthogAPIClientError
try:
client.features() #disable network connection
except PosthogAPIClientError as err:
# Handle the error -- define default behavior in outage
```
### RateLimitError
Again, specific to the `PosthogAdapter` it will raise an error if the account is rate limited by the Posthog API. These get bubbled up as `RateLimitError`.
```python
from feature_gate.clients.posthog_api_client import RateLimitError
try:
client.features() # receives response indicating a rate limit and retry time in seconds
except RateLimitError as err:
# Handle the error -- define default behavior during rate limiting
```
## Testing
The Memory Adapter can be used for writing tests. This creates an ephemeral memory only implementation of the feature_gate client API. This is non-suitable for production only for tests.
```python
from feature_gate.client import Client
from feature_gate.adapters.memory import MemoryAdapter
client = Client(MemoryAdapter())
```
## Developing this library
### Hot-reload the REPL
Hot-reload the client in the repl for development:
```
$ repl
>>> exec(open('reload.py').read())
```
Raw data
{
"_id": null,
"home_page": "https://github.com/deftinc/feature_gate",
"name": "feature_gate",
"maintainer": "Patrick Wiseman",
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": "patrick@deft.services",
"keywords": "feature flags, feature gate",
"author": "Patrick Wiseman",
"author_email": "patrick@deft.services",
"download_url": "https://files.pythonhosted.org/packages/2c/a9/f69cf8f93a7bee421eb912989b030a055425b4528b82bdc2e7f52f4f8d58/feature_gate-0.0.7.tar.gz",
"platform": null,
"description": "# FeatureGate\n\nFeaturegate is a simple feature flag API similar to [Flipper](https://github.com/flippercloud/flipper).\n\n## Configuration\n\n### PosthogAdapter\n\n```bash\nexport POSTHOG_API_KEY=\"someapikey\"\nexport POSTHOG_PROJECT_ID=\"someprojectid\"\n```\n\n## Usage\n\n```python\nfrom feature_gate.client import Client\nfrom feature_gate.adapters import PosthogAdapter\nfrom feature_gate.feature import Feature\n\nadapter = PosthogAdapter() # Or MemoryAdapter for testing\nclient = Client(adapter)\nfeature = Feature(\"Test flag\", \"test_flag\", \"This is a test flag\")\n\nclient.features()\n# => []\n\nclient.add(feature)\n# => True\n\nclient.features()\n# => [\"test_flag\"]\n\nclient.is_enabled(\"test_flag\")\n# => False\n\nclient.enable(\"test_flag\")\n# => True\n\nclient.is_enabled(\"test_flag\")\n# => True\n\nclient.disable(\"test_flag\")\n# => True\n\nclient.is_enabled(\"test_flag\")\n# => False\n\nclient.remove(\"test_flag\")\n# => True\n\nclient.features()\n# => []\n```\n\n## Errors\n\n### FeatureNotFound\nIf you try to run something that presumes the existence of a feature and it can't find it it'll throw a `FeatureNotFound`.\n\n```python\nfrom feature_gate.client import FeatureNotFound\n\ntry:\n client.remove(\"some_feature_that_definitely_does_not_exist\")\nexcept FeatureNotFound as err:\n # Do what we want to do when the feature doesn't exist\n```\n\n### PosthogApiClientError\nFor the `PosthogAdapter` in particular it will raise error if it was unable to reach the Posthog API. These get bubbled up as `PosthogAPIClientError`.\n\n```python\nfrom feature_gate.clients.posthog_api_client import PosthogAPIClientError\n\ntry:\n client.features() #disable network connection\nexcept PosthogAPIClientError as err:\n # Handle the error -- define default behavior in outage\n```\n\n### RateLimitError\nAgain, specific to the `PosthogAdapter` it will raise an error if the account is rate limited by the Posthog API. These get bubbled up as `RateLimitError`.\n\n```python\nfrom feature_gate.clients.posthog_api_client import RateLimitError\n\ntry:\n client.features() # receives response indicating a rate limit and retry time in seconds\nexcept RateLimitError as err:\n # Handle the error -- define default behavior during rate limiting\n```\n\n## Testing\n\nThe Memory Adapter can be used for writing tests. This creates an ephemeral memory only implementation of the feature_gate client API. This is non-suitable for production only for tests.\n\n```python\nfrom feature_gate.client import Client\nfrom feature_gate.adapters.memory import MemoryAdapter\n\nclient = Client(MemoryAdapter())\n```\n\n## Developing this library\n\n### Hot-reload the REPL\n\nHot-reload the client in the repl for development:\n\n```\n$ repl\n>>> exec(open('reload.py').read())\n```\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "An extensible feature flagging library for Python",
"version": "0.0.7",
"project_urls": {
"Homepage": "https://github.com/deftinc/feature_gate",
"Repository": "https://github.com/deftinc/feature_gate"
},
"split_keywords": [
"feature flags",
" feature gate"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "d122a1a36a9fc40f74ba6f3c8916b2d9add4c72ff9cf06ad06c238ee1e0f4f3b",
"md5": "d0453bd9faf8ee305b4a0e75708b386a",
"sha256": "891afb94c9fa761c61a03415f211be5b8937552cebc1810f08aa1e65b4abb54c"
},
"downloads": -1,
"filename": "feature_gate-0.0.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d0453bd9faf8ee305b4a0e75708b386a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 7468,
"upload_time": "2024-06-07T14:30:59",
"upload_time_iso_8601": "2024-06-07T14:30:59.952552Z",
"url": "https://files.pythonhosted.org/packages/d1/22/a1a36a9fc40f74ba6f3c8916b2d9add4c72ff9cf06ad06c238ee1e0f4f3b/feature_gate-0.0.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2ca9f69cf8f93a7bee421eb912989b030a055425b4528b82bdc2e7f52f4f8d58",
"md5": "31d06000b4e9d1a5c42e7801c1322472",
"sha256": "5f23bd26298f858c02427852dfe629ce57576cb463cef295bd04a52f580bef2e"
},
"downloads": -1,
"filename": "feature_gate-0.0.7.tar.gz",
"has_sig": false,
"md5_digest": "31d06000b4e9d1a5c42e7801c1322472",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 6205,
"upload_time": "2024-06-07T14:31:01",
"upload_time_iso_8601": "2024-06-07T14:31:01.203744Z",
"url": "https://files.pythonhosted.org/packages/2c/a9/f69cf8f93a7bee421eb912989b030a055425b4528b82bdc2e7f52f4f8d58/feature_gate-0.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-06-07 14:31:01",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "deftinc",
"github_project": "feature_gate",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "feature_gate"
}