Python UCI绑定
项目描述
Python UCI (统一配置接口) 绑定
为名为UCI的OpenWRT配置接口及其特定库libuci提供的绑定。
您可以使用此库从UCI访问和设置配置。
需求
- Python3
- libuci
用法
该项目中有两个主要包。有一个uci和一个euci。在大多数情况下,您想使用euci,但因为它只是对uci的包装,所以也请阅读该文档,因为您可能在euci中缺少的功能可能已在该处实现。
uci
这是一个Python3模块,是对libuci的实际包装。其API设计为与官方Lua绑定相同,但由于两种语言之间的差异,并不完全相同。主要是一些在两者中都存在的操作在pyuci中更强大。
一般用法包括初始化Uci处理程序,调用方法来修改或接收配置值,然后提交。
from uci import Uci
u = Uci()
print(u.get("network"))
u.set("network", "lan", "type", "bridge")
u.commit("network")
Uci也可以在Python with语句中使用。这确保了所有对uci所做的更改都在with语句上下文退出时提交。
with uci.Uci() as u:
u.set("network", "lan", "type", "bridge")
uci.get(config, section, option)
如果您想获取配置值,请使用此方法。参数是识别您想要获取的内容。《config》是要读取的顶层配置文件的名称。《section》是节(请注意,这并不是节的类型,而是值)。《option》是选项或列表的名称。必需的参数是《config》。
此方法根据提供的参数数量返回不同的表示形式。
当只提供 config 时,返回的类型是字典的字典,其结构为第一级键是部分值,值是包含部分内容的字典。下一级字典键是选项和列表的名称。选项键的值是字符串,列表键的值是包含字符串的元组。
{'lan': {'ifname': ('lan0', 'lan1', 'lan2', 'lan3', 'lan4'),
'ipaddr': '192.168.1.1',
'netmask': '255.255.255.0',
'proto': 'static',
'type': 'bridge'},
'wan': {'ifname': 'eth2', 'proto': 'dhcp'}}
请注意,Python3 确保字典和这些字典的顺序与配置文件中的顺序相同。这对于使用顺序来指定优先级(例如规则)的部分非常重要。
当提供 section 和可选的 option 时,则仅返回该特定值。如果没有提供 option,则返回部分类型作为字符串。如果提供了 option,则它取决于它是指列表还是选项。如果是选项,则返回的值是字符串类型。如果是列表,则返回字符串的元组。
如果请求的配置、部分或选项未找到,则抛出 UciExceptionNotFound。
uci.get_all(config, section, option)
这几乎与 uci.get 相同,只有一个区别。那就是如果你只提供 config 和 section,则返回部分类型而不是获取部分类型。也就是说,它返回包含该部分中所有选项和列表的字典。
uci.set(config, section, option, value)
将给定的 value 设置为给定的选项。值必须是字符串或字符串的表/元组。如果你提供字符串,则值设置为选项。如果你提供表/元组,则将其设置为列表。请注意,它将替换先前的值。
请注意,如果部分不存在,则会抛出 UciException。
这也允许你设置部分的名称(以创建命名部分或更改名称)。此函数的格式用于此为:uci.set(config, section, value)。
uci.add(...)
这应该添加新的匿名部分。这目前尚未实现,因此使用 pyuci 添加匿名部分不受支持。
uci.delete(config, section, option)
此方法允许您从配置中删除部分和选项。config 和 section 是必需的。option 是可选的。
如果配置、部分或选项不存在,则不报告错误。
请注意,实际上也可以省略 section,在这种情况下,UCI 不执行任何操作,也不报告错误。
uci.rename(config, section, option, name)
此方法允许您将现有的选项、列表或部分重命名为不同的名称。option 是可选的,在这种情况下,修改部分类型。
uci.reorder(config, section, index)
将给定的部分移动到配置文件中的不同索引位置。所有参数都是必需的,且 index 从 0 开始。
uci.save(config, section, option)
将更改的增量保存到保存位置。这不会修改配置文件,但会将更改存储到特定的配置位置。使用这样的增量,您可以覆盖配置。有关如何设置此增量保存位置,请参阅 uci.savedir()、uci.set_savedir() 和 uci 初始化。
uci.commit(config, section, option)
将更改写入配置文件。您必须指定至少 config,但您还可以选择性地指定更精确的 section 和 option 的指定。这确保了超出该指定的任何内容都不会写入配置。
uci.revert(config, section, option)
删除指定配置上所做的所有更改。config 参数是必需的,而 section 和 option 是可选的,允许您限制要撤销的内容。
uci.list_configs()
返回所有加载并可供 Uci 使用的配置列表。
uci.confdir()
返回当前配置目录的路径。这是存储配置文件的目录,应该位于永久存储上。
要设置它,您可以调用 uci.set_confdir() 或在 Uci 初始化时传递关键字参数 confdir。
uci.set_confdir(path)
将给定的 path 设置为配置目录。这是用于从配置目录加载配置并将其存储的目录。
要获取当前配置目录,您可以调用 uci.confdir()。
uci.savedir()
返回当前保存目录的路径。这是存储delta文件的目录,这些是尚未提交到配置目录的配置更改。要更新此目录的内容,您可以调用 uci.save()。
要设置它,您可以调用 uci.set_savedir() 或在 Uci 初始化时传递关键字参数 savedir。
uci.set_savedir(path)
将给定的 path 设置为保存目录。这是用于存储delta文件的目录。这些是尚未写入配置目录中配置文件的配置更改文件。
要获取当前保存目录,您可以调用 uci.savedir()。
euci(扩展uci)
这是Python仅为 uci 模块提供的扩展。它将 Uci 扩展到 EUci 并添加了如类型等功能。
一般用法与 Uci 相同。在 Uci 中拥有的每个方法,您也可以通过 EUci 访问。唯一的区别是,某些方法被重载并提供在 Uci 之上的附加行为。
EUci 明确支持以下类型以及任何可以从字符串初始化的类型(如 int 或 float)
- str:这是默认和原生的UCI类型。
- bool:这是只有两个状态的布尔类型:
True或False。UCI定义了特殊字符串,这些字符串应被所有应用程序理解为布尔值。对于False是0、no、off、false和disabled,对于True是1、yes、on、true、enabled。配置中的任何其他值都视为无效。如果设置此类型,EUci使用0和1。
euci.bolean.VALUES
这是一个将布尔字符串映射到 True 或 False 的字典。当获取整个配置部分并逐个处理选项时很有用。
euci.get(config, section, option, dtype=str, convert=None, list=False, default=NoDefault)
这是重载的 uci.get 方法。三个初始位置参数与 uci.get 中的相同,但行为根据额外的关键字参数而变化。
dtype 是可以从字符串初始化的类型。它确保返回的值始终为给定类型。有关支持类型的列表,请参阅上一节。如果值无法转换为指定的类型,将引发 UciExceptionNotFound。
convert 可以是一个函数,用于执行自定义转换。如果您认为简单的 dtype 不够用,则可以使用此函数。使用它的原因是转换到自定义类型或提供如基数到整数之类的附加信息。该函数应接受要转换的值作为参数并返回结果。
list 是一个布尔值,用于指定 euci.get 是否应确保返回值被视为 UCI 选项或列表。这实际上是返回 dtype 或 dtype 值元组的区别。如果配置包含具有适当名称的 UCI 选项,但 list 设置为 True,则 euci.get 返回包含该选项值的元组。另一方面,如果配置包含具有适当名称的 UCI 列表,但 list 设置为 False,则 euci.get 总是返回类型为 dtype 的值。如果有多个 UCI 列表提供,则返回第一个。默认值是 False,因此在处理列表时,您应始终将其指定为 True。请注意,如果没有提供 section,则此关键字没有作用。这意味着在这种情况下,总是返回字典。
default 关键字参数可用于抑制异常 UciExceptionNotFound。而不是引发此异常,euci.get 返回提供的默认值。请注意,默认值永远不会经过转换处理,因此您必须确保它已经是正确的类型,或者预期它可能不是。如果未提供 section 参数,则此操作没有作用。这意味着返回的字典永远不会包含除了字符串以外的任何值。
euci.set(config, section, option, value)
这是重载的 uci.set 方法。它在调用方式上没有改变。您不应该看到任何区别,除了它处理 value 的方式。它检测提供的 value 参数的类型,如果它是支持的类型之一,则将其正确转换为适当的字符串表示形式。任何不受支持的类型都被视为字符串,并执行字符串转换。
value 可以是单个值,也可以是元组/列表,与 uci.set 的情况相同。在元组/列表的情况下,预期所有值都是相同的类型。这是通过使用索引零的值来检测类型,并将其余值转换为该类型来处理的。
示例
以下是 OpenWRT 系统上 uci 和 euci 的不同用法的示例。
获取配置的主机名
主机名位于 system 类型的匿名部分中。我们必须检查所有部分以获取该部分的正确名称。
from euci import EUci
hostname = next(
u.get("system", section, "hostname")
for section in u.get("system")
if u.get("system", section) == "system"))
测试
要运行测试,您还需要 pytest,这是基本要求。
您可以使用 Docker 来获取运行测试所需的适当环境(带有 pytest 和 libuci)。适当的 Docker 文件可以在此存储库中找到,名称为 .Dockerfile。
运行所有测试与运行: python3 -m pytest tests 一样简单。
项目详情
pyuci-0.9.0.tar.gz 的哈希值
| 算法 | 哈希摘要 | |
|---|---|---|
| SHA256 | 865a45d48fb5d363f1230e94fa2c5b01ae6487f02f2180b0a6f78193a70166e2 |
|
| MD5 | 91b0f7972c120191c441dbdd9febfa8e |
|
| BLAKE2b-256 | 3e848b9919bdbf3a8a579c2af1bf5ee412751f70e1ad0587551b8d9ecb38a703 |