Skip to main content

ugly-code

[TOC]

安装

$ pip install ugly-code

Command 工具

  • 自动注入命令行参数到函数 (ugly_code.cmd.Command)

创建测试文件 cmd_debug.py

from ugly_code.cmd import Command
    
@Command
def main(x:int, y ,z=1023):
    """
    测试一下
    """
    print("{x} \t {y} \t {z}".format(**locals()))

if __name__ == '__main__':
    globals()['main']()

执行该文件

$ python cmd_debug.py  -x 1023 -y 333
1023     333     1023

有默认值的参数会被设置为可选参数,无默认值则设置为必选.

使用Type Hints的参数可自动进行类型检查.

使用 CMDHolder持有 Command

  • 创建命令行工具组

编辑文件cmd_debug.py

from ugly_code.cmd import CMDHolder


@CMDHolder.command("test", "测试")
def main(x: int, b: str, c: int=1):
    """
    测试一下
    """
    print("{x} \t {y} \t {z}".format(**locals()))


@CMDHolder.command("echo", "echo")
def echo(words):
    """echo"""
    print(words)


if __name__ == '__main__':
    CMDHolder(__name__).execute()

执行该文件:

$ python3 cmd_debug.py echo -words "测试"
测试
$ python3 cmd_debug.py test
usage: Command line create by ugly-code.

    测试一下
     [-h] -x X -b B [-c C]
Command line create by ugly-code.

    测试一下
    : error: the following arguments are required: -x, -b

由示例可发现,CMDHolder可以持有多个命令行工具,根据不同的参数调用不同的命令行对象。而且还可以自定义命令行工具的名称与介绍。

多进程管理工具(ugly_code.runit)

ugly_code.runit 多任务管理工具。使用 Runner和Worker管理多进程程序。支持XML-RPC控制任务启停。

一个Worker对应一个进程,各进程使用tag区分。

使用方式: 注册任务到Runner,启动Runner即可自动\手动启动任务或使用XML-RPC接口对任务进行调度管理。

示例

import threading
import time

from ugly_code.runit import Switch, Worker, Runner


class AWorker(Worker):
    def serve(self):
        while self.switch.on:
            print(f"{self.switch.name} {time.time()}")
            time.sleep(3.0)


def close_it(switch: Switch):
    time.sleep(10)
    switch.close()


if __name__ == '__main__':
    st = Switch('Runner')
    threading.Thread(target=close_it, args=(st,)).start()
    Runner(st, (("a", AWorker), ('b', AWorker)), m=('127.0.0.1', 0)).run()

使用xml-rpc管理进程

import threading
import time

from ugly_code.runit import Worker, Runner, RuntItMonitor


class AWorker(Worker):
    def serve(self):
        while self.switch.on:
            print(f"{self.switch.name} {time.time()}")
            time.sleep(3.0)


def start_and_close_task(m, tag):
    time.sleep(10)
    monitor = RuntItMonitor(m)
    monitor.start(tag)
    monitor.start(tag)
    time.sleep(3)
    print(monitor.stats())
    monitor.close(tag, True)
    time.sleep(3)
    monitor.prune()
    print(monitor.stats())
    monitor.shutdown()


if __name__ == '__main__':
    m = ('127.0.0.1', 65432)
    runner = Runner(None, (("a", AWorker, 0, 0, False), ('b', AWorker)), m=m)
    threading.Thread(target=start_and_close_task, args=("http://{}:{}".format(*m), "a",)).start()
    runner.run()

查看文档

扩展工具集

多进程简单异步任务处理

import queue
import threading
import time

from ugly_code.runit import Switch
from ugly_code.runit.extra import QueueInterface, MultiprocessQueueWorker


class TestQueue(QueueInterface[int]):

    def __init__(self):
        super().__init__()
        self.q = queue.Queue()

    def empty(self) -> bool:
        return self.q.empty()

    def pop(self, block: bool = True, timeout: float | None = None) -> int:
        return self.q.get(block, timeout)

    def put(self, t: int):
        return self.q.put(t)


def handle_sleep_time(sleep_time: float):
    time.sleep(sleep_time)
  
class TestMultiprocessQueueWorker:
    def run_it(self):
        on = Switch('test')
        q = TestQueue()
        threading.Thread(target=self.stop_it, args=(on,)).start()
        q.put(1)
        q.put(4)
        q.put(5)
        MultiprocessQueueWorker(on, q, handle_sleep_time, max_workers=1).serve()

    def stop_it(self, on: Switch, timeout: float = 15.0):
        time.sleep(timeout)
        on.close()

对象代理工具

from ugly_code.ex import ObjectProxy

obj = ObjectProxy(dict(a=1, b=2, c=3, d=dict(a=1, b=2)))
print(obj.d.a)

RabbitMQ监听工具

安装

$ pip install ugly-code[rabbit]

示例

import threading
import time

from pika import BasicProperties
from pika.adapters.blocking_connection import BlockingChannel
from pika.spec import Basic

from ugly_code.rabbit import ListenOpt, default_listen_ctx, RabbitListenCtx

opt = ListenOpt(
    queue='test',
    uri="amqp://guest:guest@127.0.0.1:5672/test",
    exchange='test',
    ext='direct',
    routing_key='test',
    durable=True,
    prefetch=1,
    retry_delay=1.0,
    retry=False
)


def handle_message(channel: BlockingChannel, deliver: Basic.Deliver, props: BasicProperties, body: bytes):
    print(body)
    channel.connection.process_data_events(3)


def close_it(val: RabbitListenCtx):
    time.sleep(10)
    val.shutdown()


with default_listen_ctx(opt).start(handle_message) as ctx:
    threading.Thread(target=close_it, args=(ctx,)).start()

更多说明

Metadata

Release files for ugly-code 0.0.13

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for ugly-code 0.0.13
File Interpreter ABI Platform Actions
ugly_code-0.0.13-py3-none-any.whl Python 3 none any Details for ugly_code-0.0.13-py3-none-any.whl

Release files / ugly_code-0.0.13-py3-none-any.whl

Download URL ugly_code-0.0.13-py3-none-any.whl
Size 16.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7ceb855985a0bbdc278521a2a7e37049c2e9ba71541da4605b4156446058c6d6
BLAKE2b-256 checksum
How to use checksums
9025ac79142b969e4d79d592375103cf605060b92da0f4d261db37926521fcdc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.0.0 CPython/3.12.0

Security for ugly-code 0.0.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page