SDSS 产品的小工具
项目描述
sdsstools
sdsstools提供了几种常用工具,用于日志记录、配置处理、版本解析、打包等。它的主要目的是整合一些最初在python_template中找到的实用程序,使它们成为可以更新的依赖项。
这并不打算成为天文工具的包罗万象的存储库。 sdsstools其本身旨在具有最小的依赖关系(即,主要是 Python 标准库和 setuptools)。
使用 sdsstools
要使用 sdsstools,只需安装它
pip install sdsstools
最有可能的是,您希望将 sdsstools 作为库的依赖项包含在内。为此,请添加到您的setup.cfg
[options]
install_requires =
sdsstools>=0.1.0
(这相当于传递install_requires=['sdsstools>=0.1.0']给setuptools.setup),或者如果您使用的是诗歌运行poetry add sdsstools,则应将此行添加到您的pyproject.toml
[tool.poetry.dependencies]
sdsstools = { version="^0.1.0" }
日志记录
sdsstools 包括sdsstools.logger.SDSSLogger类,它提供了标准 Python日志记录模块的包装器。SDSSLoger提供以下功能:
.sh具有漂亮着色的控制台处理程序(可通过属性访问)。- 自动捕获警告和异常,将其格式化并重定向到记录器。对于控制台处理程序,这意味着一旦创建了记录器,所有警告和异常都会正常输出,但更清晰、更美观。
- TimedRotatingFileHandler (可通过属性访问
.fh)在 UT 午夜旋转,具有良好的格式。
要为您的应用程序获取新的记录器,只需执行
from sdsstools.logger import get_logger
NAME = 'myrepo'
log = get_logger(NAME)
文件记录器默认是禁用的,可以通过调用来启动log.start_file_logger(path)。默认情况下TimedRotatingFileHandler会创建一个。如果你想正常FileHandler使用rotate=False。文件模式默认为mode='a'(附加)。
该SDSSLoger实例还包括一个asyncio_exception_handler方法,可以添加到 asyncio 事件循环中以处理异常;例如loop.set_exception_handler(log.asyncio_exception_handler)。
配置
该sdsstools.configuration模块包含几个处理配置文件的实用程序。最有用的是get_config,它允许读取 YAML 配置文件。例如
from sdsstools.configuration import get_config
NAME = 'myrepo'
config = get_config(NAME, allow_user=True)
get_config假定文件位于etc/<NAME>.yml调用文件的相对位置get_config,但可以通过传递来更改config_file=<config-file-path>。此外,如果allow_user=True和 中存在~/.config/sdss/<NAME>.yaml文件,则读取该文件并将其与默认配置合并,覆盖用户文件中存在的任何参数。这允许创建与库一起存在但可由用户覆盖的默认配置。
除了(推荐的)位置~/.config/sdss/<NAME>.yaml,get_config还在 、 和 中查找用户~/.config/sdss/<NAME>.yml配置~/.config/sdss/<NAME>/<NAME>.y(a)ml文件~/.<NAME>/<NAME>.y(a)ml。
get_config返回Configuration的实例,它的行为类似于字典,但允许通过调用从新用户文件动态重新加载配置load()。
sdsstools.configuration包括另外两个工具,merge_config允许递归地合并字典和read_yaml_file读取 YAML 文件。
扩展 YAML 文件
read_yaml_file提供了一种非标准功能,允许您使用另一个 YAML 文件扩展一个 YAML 文件。为此,您需要!extends <base-file>在要扩展的文件顶部添加标签。例如,如果您有一个文件base.yaml
cat1:
key1: value2
cat2:
key2: 1
您想用作模板的extendable.yaml
#!extends base.yaml
cat1:
key1: value1
你可以read_yaml_file用来解析结果
>>> read_yaml_file('extendable.yaml')
{'cat1': {'key1': 'value2'}, 'cat2': {'key2': 1}}
基本文件的路径必须是绝对的或相对于要扩展的文件的位置。
元数据
sdsscore 提供了定位和解析元数据文件(pyproject.toml, setup.cfg, setup.py)的工具。get_metadata_files定位元数据文件相对于给定path. get_package_version如果软件包已安装,则尝试通过在元数据文件或 egg/wheel 元数据文件中查找版本字符串来查找软件包的版本。使用它
from sdsstools.metadata import get_package_version
__version__ = get_package_version(path=__file__, package_name='sdss-camera') or 'dev'
这将尝试从元数据文件中查找并解析版本(我们传递__file__以指示从哪里开始查找);如果失败,它将尝试从已安装的包中获取版本sdss-camera。如果全部失败,它将设置回退版本'dev'。
命令行界面
sdsstools提供了命令行工具sdss,它只是一些常用调用任务的简单包装。sdsstools不会自动安装任务的所有依赖项,需要手动添加。
sdss提供以下任务
| 任务 | 选项 | 描述 |
|---|---|---|
| 干净的 | 删除在构建和打包过程中产生的文件。 | |
| 部署 | - 测试 | 构建并部署到 PyPI(或测试服务器)。需要twine和wheel。 |
| 安装-deps | --额外内容 | 从setup.cfg文件安装依赖项 |
| 文档.build | - 目标 | 构建 Sphinx 文档。需要Sphinx. |
| 文档显示 | - 目标 | 在浏览器中显示文档。需要Sphinx. |
| docs.clean | - 目标 | 清理文档构建。需要Sphinx. |
sdss假设文档docs/sphinx相对于存储库的根目录存在。这可以通过sphinx.target在文件中设置配置来更改invoke.yaml,例如
sphinx:
target: docs
单击守护程序命令
daemonizer模块实现了一个Click命令组,它允许产生一个守护进程,并停止和重新启动它。该模块在内部使用daemonocle(该软件包未安装,sdsstools需要手动安装)。
如何使用的一个简单示例daemonizer是
import time
import click
from sdsstools.daemonizer import DaemonGroup
@click.group(cls=DaemonGroup, prog='hello', pidfile='/var/tmp/hello.pid')
@click.argument('NAME', type=str)
@click.option('--file', type=str, default='hello.dat')
def daemon(name):
with open(file, 'w') as unit:
while True:
unit.write(f'Hi {name}!\n')
unit.flush()
time.sleep(1)
if __name__ == '__main__':
daemon()
这将创建一个hello包含四个子命令的新组
Usage: daemon [OPTIONS] NAME COMMAND [ARGS]...
Options:
--file
--help Show this message and exit.
Commands:
restart Restart the daemon.
start Start the daemon.
status Report if the daemon is running.
stop Stop the daemon.
现在我们可以运行daemon --file ~/hello.dat John start,一个新的后台进程将启动,每秒写入文件。我们可以用 来阻止它daemon stop。一般来说,行为与守护进程 Click 实现相同,但内部略有不同,以允许组回调接受参数。如果回调是协程,可以用cli_coro装饰器包裹
import asyncio
import signal
import click
from sdsstools.daemonizer import DaemonGroup, cli_coro
def shutdown(signal):
if signal == signal.SIGTERM:
cancel_something()
@click.group(cls=DaemonGroup, prog='hello', pidfile='/var/tmp/hello.pid')
@click.argument('NAME', type=str)
@click.option('--file', type=str, default='hello.dat')
@cli_coro(shutdown_func=shutdown, signals=(signal.SIGTERM, signal.SIGINT))
async def daemon(name):
with open(file, 'w') as unit:
while True:
unit.write(f'Hi {name}!\n')
unit.flush()
await asyncio.sleep(1)
cli_coro可以接受shutdown_func协程收到信号时调用的函数。处理的默认信号是(SIGHUP, SIGTERM, SIGINT).
守护一个命令
要将任何命令作为守护程序执行,您可以使用daemonize随sdsstools. 要将进程作为守护程序启动,请执行daemonize start NAME COMMANDwhenNAME是与守护程序关联的名称(以便以后可以停止)并且COMMAND是要运行的命令,例如:
daemonize start apoActor python ./apoActor_main.py
停止守护进程daemonize stop NAME。查看daemonize --help更多选项。
日期函数
该函数sdsstools.time.get_sjd()返回具有 SDSS 样式的修改儒略日的整数。该函数接受一个天文台('APO'或'LCO'),但否则将尝试从环境变量或完全限定的域名中确定当前位置。
捆绑包
为方便起见,sdsstools捆绑了以下产品:
- 修复了最新版本的一些问题的版本副本
semantic-version。 - 用于读取 TOML 文件的toml副本(由元数据子模块使用)。
您可以直接从顶级命名空间 , 访问sdsstools.toml它们sdsstools.releases。要releases与 sphinx 一起使用,只需将以下内容添加到您的config.py
extensions += ['sdsstools.releases']