Skip to main content

SDSS 产品的小工具

项目描述

sdsstools

版本 PyPI 版本 代码风格:黑色 建造 编解码器

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>.yamlget_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(或测试服务器)。需要twinewheel
安装-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).

守护一个命令

要将任何命令作为守护程序执行,您可以使用daemonizesdsstools. 要将进程作为守护程序启动,请执行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捆绑了以下产品:

您可以直接从顶级命名空间 , 访问sdsstools.toml它们sdsstools.releases。要releases与 sphinx 一起使用,只需将以下内容添加到您的config.py

extensions += ['sdsstools.releases']

项目详情