没有项目描述

flipper-client的Python项目详细描述


鳍状肢

循环CI状态code style:black

flipper是一个轻量级的、易于使用的、灵活的python特性标志库。它旨在允许开发人员在禁用状态下将代码推送到生产环境中,并在不执行其他版本的情况下仔细控制代码是否已启用或禁用。

快速启动

PIP安装Flipper客户端

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()

API

功能标志客户端

已启用(功能名称:str,**条件)->;bool

检查功能是否已启用。还支持功能的条件启用。若要检查条件启用的功能,请将关键字参数与要提供的条件一起传递。有关详细信息,请参见"条件"部分。

示例:

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)

创建(功能名称:str,已启用:bool=false,客户端数据:dict=none)->;功能标志

创建新的功能标志和可选的设置值(如果启用,则为False/Disabled)。

对于高级实现,还可以通过client_data keyword参数将用户定义的键值对指定为dict。这些值应该是json可序列化的,并将存储在flag对象的元数据部分。

示例:

flag=features.create(MY_FEATURE)

存在(功能名称:str)->;bool

按名称检查功能标志是否已存在。功能标志名称必须唯一。

示例:

ifnotfeatures.exists(MY_FEATURE):features.create(MY_FEATURE)

获取(功能名称:str)->;功能标志

为请求的标志返回featureflag的实例。

示例:

flag=features.get(MY_FEATURE)

启用(功能名称:str)->;无效

启用指定的标志。对的后续调用已启用应返回true。

示例:

features.enable(MY_FEATURE)

禁用(功能名称:str)->;无效

禁用指定的标志。对的后续调用已启用应返回false。

示例:

features.disable(MY_FEATURE)

销毁(功能名称:str)->;无效

销毁指定的标志。对的后续调用已启用应返回false。

示例:

features.destroy(MY_FEATURE)

列表(限制:可选[int]=无,偏移量:int=0)->;迭代器[featureflag]

列出受您提供的限制和偏移量限制的所有标志。结果不能保证是正确的。订购取决于您选择的后端,因此请相应地计划。

示例:

forfeatureinfeatures.list(limit=100):print(feature.name,feature.is_enabled())

设置客户数据(功能名称:str,客户数据:dict)->;无效

设置要存储为带有标志的元数据的键值对。可使用获取客户机数据检索。这会将提供的值与任何已存在的值合并。

示例:

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()
0

获取客户数据(功能名称:str)->;dict

检索存储在此标志元数据中的任何键值对。

示例:

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()
1

获取元数据(功能名称:str)->;dict

类似于get_client_data但它不会只返回客户端提供的元数据,而是返回标志的所有元数据,包括如创建日期

示例:

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()
2

添加条件(功能名称:str,条件:condition)->;无效

为启用的检查添加一个条件,以便被启用只有在调用时满足所有条件时才会返回true。

示例:

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()
3

设置bucketer(功能名称:str,bucketer:bucketer)->;无效

设置用于根据传递给的检查进行bucket请求的bucketer是否已启用。如果您想根据百分比或其他无法使用条件强制执行的启发式方法来对流量进行分段,则这非常有用。有关详细信息,请参阅bucketing部分。

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()
4

功能标志

已启用->;bool

检查功能是否已启用。还支持功能的条件启用。若要检查条件启用的功能,请将关键字参数与要提供的条件一起传递。有关详细信息,请参见"条件"部分。

示例:

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()
5

enable()->;无效

启用标志。对的后续调用已启用应返回true。

示例:

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()
6

disable()->;无效

禁用指定的标志。对的后续调用已启用应返回false。

示例:

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()
7

destroy()->;无效

摧毁旗帜。对的后续调用已启用应返回false。

示例:

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()
8

设置客户数据(客户数据:dict)->;无效

设置要存储为带有标志的元数据的键值对。可使用获取客户机数据检索。这会将提供的值与任何已存在的值合并。

示例:

fromflipperimportFeatureFlagClient,MemoryFeatureFlagStorefeatures=FeatureFlagClient(MemoryFeatureFlagStore())MY_FEATURE='MY_FEATURE'features.create(MY_FEATURE)features.enable(MY_FEATURE)iffeatures.is_enabled(MY_FEATURE):run_my_feature()else:run_old_feature()
9

获取客户机数据->;dict

检索存储在此标志元数据中的任何键值对。

示例:

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)
0

获取meta()->;dict

get_client_data类似,但它不会只返回客户端提供的元数据,而是返回标志的所有元数据,包括系统设置值,例如created_date

示例:

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)
1

添加条件(条件:条件)->;无效

为启用的检查添加一个条件,以便被启用只有在调用时满足所有条件时才会返回true。

示例:

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)
2

设置bucketer(bucketer:bucketer)->;无效

设置用于根据传递给的检查进行bucket请求的bucketer是否已启用。如果您想根据百分比或其他无法使用条件强制执行的启发式方法来对流量进行分段,则这非常有用。有关详细信息,请参阅bucketing部分。

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)
3

装饰工

已启用(功能:featureflagclient,功能名称:str,重定向:可选[可调用]=无)

这是一个可用于任何函数(包括django/flask视图)的decorator。如果启用了该功能,则将调用该函数。如果未启用该功能,则不会调用该函数。如果提供了可调用的重定向功能,则在功能未启用时将调用重定向功能。

示例:

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)
4

条件

Flipper支持条件启用的功能标志。如果要为用户子集启用功能或基于应用程序中的某些其他条件,这些功能非常有用。它的用法很简单。首先,导入条件类:

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)
5

然后使用featureflagclientfeatureflag接口。您可以添加任意多个条件,每个条件可以指定多个检查:

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)
6

然后,当调用被启用时,可以指定这些检查。不需要进行检查,如果未指定,则已启用将返回功能的基本已启用状态。

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)
7

支持条件运算符

除了相等条件之外,条件还支持以下运算符比较:

  • 大于
  • 大于或等于
  • lt小于
  • LTE小于或等于
  • \u ne不等于
  • 在中设置成员资格
  • \u不在设置非成员身份

运算符必须是参数名的后缀,并且必须包含/code>

屈曲

如果您希望的结果根据预定义的百分比值而变化,则bucketing非常有用。示例可能包括A/B测试或Canary发布。开箱即用,Flipper支持随机分配情况和一致分配情况下基于百分比的扣合。Flipper还支持可变百分比情况下的线性斜坡。

在一起应用时,条件始终优先于屈曲。

随机分配

这是最简单的bucketing场景,您希望使用固定百分比随机分段流量。

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)
8

一致分配

此机制的工作原理与基于百分比的桶分配类似,只是bucketer将始终返回与它提供的值相同的值。换言之,如果您将相同的关键字参数传递给is_enabled它将始终为这些参数返回相同的结果。这可以使用关键字参数的一致散列来工作。关键字参数被序列化为json并散列。然后将该散列修改为100,以给出0-100范围内的值。然后,无论是否启用该存储桶,都将此值与当前的真皮宁百分比进行比较。

什么时候有用?任何时候,您想随机化流量,但您希望每个客户/用户始终获得相同的体验。

这也许是最容易用示例来说明的:

features.is_enabled(MY_FEATURE)# With conditonsfeatures.is_enabled(FEATURE_IMPROVED_HORSE_SOUNDS,is_horse_lover=True)
9

结合条件

这些也可以与条件相结合。当bucketer与一个或多个条件组合时,这些条件优先。也就是说,如果任何条件的计算结果为false,则无论bucketing状态是什么,都将返回false。反之亦然:如果所有条件的计算结果均为true,则无论屈曲状态如何,都将返回true

但是,如果没有为提供匹配当前条件的关键字参数,则任何条件的计算结果都将为true

flag=features.create(MY_FEATURE)
0

关键白名单

如果希望bucketers检查已启用的接收的关键字参数的子集,请在初始化ConsistentHashPercentageBucketer时使用关键字白名单参数

flag=features.create(MY_FEATURE)
1

随时间变化的斜率百分比

如果要随时间增加或减少百分比值,可以使用linearrampPercentage类。此类采用以下参数:

  • 初始值:float=0.0:起始百分比
  • 最终值:float=1.0:结束百分比
  • 斜坡持续时间:int=3600:斜坡完成的时间(秒)
  • 初始时间:可选[int]=now():斜坡"开始"的时间戳。不常见。默认为现在。

这个类可以在任何使用百分比的地方使用

flag=features.create(MY_FEATURE)
2

它还可以与consistentHashPercentageBucketer一起工作。

初始化

flipper的设计目的是提供一个公共接口,它对您选择的存储后端是不可知的。要创建客户机,只需导入featureflagclient类和您选择的存储后端即可。

开箱即用,我们支持以下后端:

  • MemoryFeatureFlagstore(对开发和测试有用的内存存储)
  • consulfeatureflagstore(需要一个正在运行的consul集群。提供所有选项中最低的延迟)
  • redisfeatureflagstore(需要运行的redis集群。可以与cachedFeatureFlagStore结合使用以减少平均延迟。
  • thriftrpcfeatureflagstore(需要一个实现featureflagstorethrift服务的服务器)

与内存中后端一起使用

在不需要数据持久性的单元测试或开发环境中,此后端非常有用。这是最简单的商店。

flag=features.create(MY_FEATURE)
3

与consul后端一起使用

领事馆是一个关键价值存储系统,具有易于使用的界面。consul后端维护到consul集群的持久连接,并监视您指定的基密钥的更改。例如,如果您的基本键是features,则它将查找下面一级的任何键的更改。这意味着consul后端比其他受支持的后端具有更低的延迟。

flag=features.create(MY_FEATURE)
4

与redis后端一起使用

要将flipper连接到redis,只需创建strictredis的实例并将其提供给redisfeatureflagstore后端。功能将在您提供的基本键下跟踪(默认值为功能)。

请记住,这将在每次选中功能标志时进行网络调用,因此您可能需要添加本地内存缓存(请参见下文)。

flag=features.create(MY_FEATURE)
5

与redis后端和内存缓存一起使用

要减少与在远程redis集群中存储功能标志相关联的平均网络延迟,可以将redisfeatureflagstore包装在cachedfeatureflagstore中。此类在初始化时将featureflagstore作为参数。当客户机检查标志时,它将首先在本地缓存中查找,如果找不到指定功能的值,它将在redis中查找。当从redis中检索到一个值时,它将被插入到本地缓存中以便快速检索。缓存被实现为一个lru缓存,其默认过期时间为15分钟。要自定义过期或任何其他缓存属性,只需将它们作为keyworkd参数传递给cachedFeatureFlagstore构造函数即可。

flag=features.create(MY_FEATURE)
6

与旧式rpc服务器一起使用

如果要使用自定义服务管理功能标志,可以使用ThriftRpcFeatureFlagstore后端。为此,您需要实现thrift/feature\u flag\store.thrift中定义的featureflagstore服务。然后,当您初始化ThriftRpcFeatureFlagstore时,您需要传递一个兼容的ThriftClient实例。

首先,安装thrift软件包:

flag=features.create(MY_FEATURE)
7

示例:

flag=features.create(MY_FEATURE)
8

注意:这也可以通过cachedFeatureFlagstore进行优化。请参阅上面的redis示例。

您还需要实现服务器,如下所示:

flag=features.create(MY_FEATURE)
9

与复制的后端一起使用

replicatedFeatureFlagStore适用于具有主存储和一个或多个秒的情况要将写入内容复制到的二级存储。例如,如果您想写入redis,也可以将这些写入记录到其他地方的审核系统。

此存储采用主存储,它必须是AbstractFeatureFlagstore的实例,然后是0个或多个其他实例才能充当副本。

当您执行任何写操作时,例如createsetdeleteset-meta,这些操作首先在主存储上执行,然后在每个辅助存储上重复。重要信息:不试图在写操作之间提供事务样式一致性或回滚。读取操作将始终从主存储中提取。

默认情况下,写操作是异步复制的。要同步复制,请将asynch=false传递给任何方法。

ifnotfeatures.exists(MY_FEATURE):features.create(MY_FEATURE)
0

与S3后端一起使用

要在s3中存储标志数据,请使用s3featureflagstore。只需创建bucket,初始化一个boto3(不是boto)s3客户机,并启动一个s3featureflagstore实例,传递客户机和bucket名称。存储区将使用标志名作为对象键写入bucket的根目录。例如用法,查看测试。有关使用BOTO3的更多信息,请参见文档

请记住,与redis之类的东西相比,s3对于生产后端不是一个理想的选择,因为它具有更高的延迟。但是,如果将其用作冷存储和备份的副本,则它在与replicated featureflagstore一起使用时非常有用。这样,如果您的热存储空间被清空,您就有了备份,或者如果您需要一种简单的方法来复制所有功能标志数据,则可以从s3中检索它。

ifnotfeatures.exists(MY_FEATURE):features.create(MY_FEATURE)
1

创建自定义后端

看不到你喜欢的后端?你可以很容易地实现自己的目标。如果您定义了一个实现AbstractFeatureFlagStore接口的类,该接口位于Flipper.contrib.store中,那么您可以将其实例传递给FeatureFlagClient构造函数。

欢迎提出请求。

开发

克隆repo并运行make install dev以设置环境。使用pytest命令运行测试。

建立节俭文件

首先,安装节俭编译器。在Mac上,最简单的方法是使用自制:

ifnotfeatures.exists(MY_FEATURE):features.create(MY_FEATURE)
2

然后简单地运行make thrift。记住提交编译步骤的结果。

系统要求

此项目需要Python版本3或更高版本。

开源

此库在Apache2.0许可下作为开放源码提供。这不是官方支持的Carta产品。

开发状态

此项目由维护者文件中列出的维护者主动维护。目前项目路线图上没有主要项目,但是可能会不时添加错误修复和新功能。我们也欢迎社会各界的贡献。

联系人

可通过电子邮件联系项目维护人员,地址为:adam.savitzky@carta.com或luis.montiel@carta.com。

讨论

我们使用github问题来讨论功能、bug和其他与项目相关的问题。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
使用jaxb2annotateplugin和XJC工具的java自定义注释   java组织。xeustechnologies。jcl无法加载WstxInputFactory类   java JUnit在格式化字符串上比较失败   java Bukkit配置部分getKeys   如何关闭Java流?   java Struts2正则表达式配置   链式事务注释的java奇怪行为   java在两个JButton之间使用变量   java签署APK时内容会发生什么变化?   java LWJGL:Slick:3D世界中的绘图字体   如何分解Java数组?   在Java MySql中处理多个过滤器   java如何在Firebase数据库中跳过初始OnChildaded事件触发   java如何在PreviewView中使用CameraX?   在子类#中重写父类后访问父类原始方法的java已解决   java找不到类型的属性   游戏框架游戏!框架+Java