{"id":13655189,"url":"https://github.com/nhumrich/toggle-meister","last_synced_at":"2025-04-12T12:24:15.396Z","repository":{"id":39540367,"uuid":"60117644","full_name":"nhumrich/toggle-meister","owner":"nhumrich","description":null,"archived":false,"fork":false,"pushed_at":"2024-05-09T16:22:39.000Z","size":5441,"stargazers_count":3,"open_issues_count":34,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-26T07:11:10.605Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nhumrich.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-31T19:31:59.000Z","updated_at":"2024-05-09T16:22:43.000Z","dependencies_parsed_at":"2024-08-02T03:12:32.322Z","dependency_job_id":null,"html_url":"https://github.com/nhumrich/toggle-meister","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhumrich%2Ftoggle-meister","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhumrich%2Ftoggle-meister/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhumrich%2Ftoggle-meister/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nhumrich%2Ftoggle-meister/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nhumrich","download_url":"https://codeload.github.com/nhumrich/toggle-meister/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248565570,"owners_count":21125520,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T03:00:59.308Z","updated_at":"2025-04-12T12:24:15.376Z","avatar_url":"https://github.com/nhumrich.png","language":"Python","funding_links":[],"categories":["Architecture"],"sub_categories":["Feature Flags"],"readme":"# Toggle Meister!\n\n![logo](https://raw.githubusercontent.com/nhumrich/toggle-meister/master/ToggleLogo.png)\n\nToggle-Meister is a Feature toggle service that fights the man.\n\nWhy Feature toggles as a service? When you have many micro services,\nsometimes a feature touches multiple services at a time.\nA single source of truth is needed so that features can be released\nall at once across services.\n\nThe main goal of this project is to provide a feature-toggle service\nthat doesnt suck by focusing on a couple key principles\n\n* Do not allow customer based toggles\n * Customer toggles get out of hand and create an impossible test scenario\n * Toggles can only be switched on/off per environment, not per person\n* Toggles must be short lived. \n * After a toggle is stable on production it needs to be removed from the codebase\n\nFor running this service please see [deployment.md](/deployment.md)\n\n## FAQ\n\n* What is a feature toggle service?\n\nA service that is the \"source of truth\" for if a service should be on or not.\nThe goal is to separate releases from deployments.\n\n* Do you support environments? \n\nYes, environments are an important part of a healthy pipeline. \nYou can add as many environments as you want.\n\n* What methods do you support for rolling out toggles?\n\nThere are only 4 states to a feature toggle. \nThe feature is either on, off, in a rolling state or paused. On and off is pretty self explanatory,\nrolling is a percentage rollout where the service rolls out the feature to a small percentage of users over time and ramps up to 100%.\nOnce a feature is at 100%, it's considered to be on. You can always go straight to ON at any time. \nPaused is a feature that is being rolled out, but you snooze the rollout for 48 hours. \nUser id based rollouts is not and will likely never be supported. The idea is to \"fight the man\", and never\nallow \"customer based toggles\", as it is a very bad practice. Other concepts for beta releases are worth discussing.\n\n* How do rollouts work?\n\nPhased rollouts use a hardcoded probability distribution, which is represented by the curve of \"at 50% of time complete, 30% of the users have the feature\".\nThis is represented in code by 24 distinct \"points\". These points are:\n```\n[1, 2, 3, 5, 8, 11, 14, 17, 20, 23, 26, 30, 35, 40, 45, 50, 55, 61, 67, 73, 79, 86, 93, 100]\n```\n\nThe rollout increases every hour. In other words, this is the percentage you will get during each hour in a 24 hour period.\nThe user is able to set any number of \"days\", when doing a rollout. So this distribution is just stretched to the appropriate number of hours.\nIn other words, if you pick 14 days, there will simply be 14 hours in between every rollout increment. You will be on 1% for the first 14 hours.\nThe users are randomly selected based on `enrollment_id` passed in as a query string. If you do not provide the enrollment_id, then it is \"off\".\n(The enrollment_id is saved, so once one user has it on, its always on)\n\n* Can I \"override\" a toggle?\n\nAt Canopy, we use toggle overrides heavily for developing. We do this via client side logic however, and this service\ndoesn't actually support any type of authentication/overrides. In other words, it's not global.\n\n## Running\n\nThe easiest way to run toggle meister is with docker-compose:\n\n```\ndocker-compose up\n```\n\nIf you have already ran it before, and there are some changes,\nyou might have to type\n\n```\ndocker-compose build\ndocker-compose up\n```\n\n## client endpoints\n\nTo use this service, the only endpoint you really have to know about is this one:\n\n`GET /api/envs/{environment}/toggles?feature={feature}`\n\nThis endpoint will tell you `true` or `false` for each toggle you want to know about. \nYou can only get toggles for one environment at a time, and can list however many features you need.\nFor example, if you wanted to get the features `use_feature_toggles`, and the feature, `closed_source`,\n on the `production` environment you would make the following request:\n\n`http mytoggleservice.example.com/api/envs/production/toggles?feature=use_feature_toggles\u0026feature=open_source`.\n\nYou would get the following response:\n\n```\n{\n    \"open_source\": false,\n    \"use_feature_toggles\": true\n}\n```  \n\nThis endpoint requires no authentication at all. In order to support rolling releases, you will also need to include `enrollment_id={x}` in your query string.\n\nThere is also an endpoint to get release notes if you decide to use that feature:\n\n`http mytoggleservice.example.com/api/envs/production/release_notes`\n\nyou would get the following response:\n\n```\n{\n    \"release_notes\": [\n        {\n            \"body\": \"Cool new feature!\",\n            \"date\": \"2019-6-4\",\n            \"feature\": null,\n            \"id\": 2,\n            \"title\": \"feature without toggle\"\n        },\n        {\n            \"body\": \"Really sweet feature\",\n            \"date\": \"2019-6-4\",\n            \"feature\": \"open_source\",\n            \"id\": 1,\n            \"title\": \"that one thing\"\n        }\n    ]\n}\n```\n\nIf you include the `enrollment_id` query string on this endpoint, it will include the release notes for features that are turned on for that enrollment id, much like the toggle api.\n\nIf you include the `all=true` query string on this endpoint, it will give you all features, making it so you dont have to specify which features you want.\nNote that this will turn metrics off, and be slightly slower. \n\n\n\n## list of all current endpoints\n\n`http :8445/api/envs/production/toggles`\n\n`http :8445/api/toggles`\n\n`http PATCH :8445/api/toggles toggle:='{\"env\": \"production\", \"feature\": \"foo\", \"state\": \"ON\"}'`\n\n`http :8445/api/features`\n\n`http POST :8445/api/features name=test_feature`\n\n`http DELETE :8445/api/features/test_feature`\n\n`http :8445/api/envs`\n\n`http POST :8445/api/envs name=my_env`\n\n`http DELETE :8445/api/envs/my_env`\n\n`http :8445/api/auditlog`\n\n`http :8445/api/metrics/myfeature`\n\n`http :8445/api/release_notes`\n\n`http :8445/api/envs/production/release_notes`\n\n`http POST :8445/api/release_notes title=mynote body=awesome feature=test_feature`\n\n`http PATCH :8445/api/release_notes/1 body='more awesome'`\n\n`http DELETE :8445/api/release_notes/1`\n\n`http :8445/api/employees`\n\n`http PATCH :8445/api/employees/my.user name='new name' role=admin`\n \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnhumrich%2Ftoggle-meister","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnhumrich%2Ftoggle-meister","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnhumrich%2Ftoggle-meister/lists"}