diff options
author | Ben Sima <ben@bsima.me> | 2024-04-10 19:56:46 -0400 |
---|---|---|
committer | Ben Sima <ben@bsima.me> | 2024-04-10 19:56:46 -0400 |
commit | 2c09c7f73e2fc770f42b5dd2588aa9634b4e7c6e (patch) | |
tree | a6c49dddb7b1735a0f8de2a9a5f4efb605f16f36 /Biz/Que/Client.py | |
parent | 051973aba8953ebde51eb1436fb3994e7ae699dc (diff) |
Switch from black to ruff format
Ruff is faster and if it supports everything that black supports than why not? I
did have to pull in a more recent version from unstable, but that's easy to do
now. And I decided to just go ahead and configure ruff by turning on almost all
checks, which meant I had to fix a whole bunch of things, but I did that and
everything is okay now.
Diffstat (limited to 'Biz/Que/Client.py')
-rw-r--r--[-rwxr-xr-x] | Biz/Que/Client.py | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/Biz/Que/Client.py b/Biz/Que/Client.py index 20349b6..53f14e4 100755..100644 --- a/Biz/Que/Client.py +++ b/Biz/Que/Client.py @@ -1,22 +1,20 @@ -#!/usr/bin/env python3 # : out que -""" -simple client for que.run -""" +# ruff: noqa: PERF203 +"""simple client for que.run.""" import argparse import configparser import functools import http.client import logging -import os +import pathlib import subprocess import sys import textwrap import time -import urllib.parse -import urllib.request as request import typing +import urllib.parse +from urllib import request MAX_TIMEOUT = 9999999 RETRIES = 10 @@ -24,14 +22,14 @@ DELAY = 3 BACKOFF = 1 -def auth(args: argparse.Namespace) -> typing.Union[str, None]: - "Returns the auth key for the given ns from ~/.config/que.conf" +def auth(args: argparse.Namespace) -> str | None: + """Return the auth key for the given ns from ~/.config/que.conf.""" logging.debug("auth") namespace = args.target.split("/")[0] if namespace == "pub": return None - conf_file = os.path.expanduser("~/.config/que.conf") - if not os.path.exists(conf_file): + conf_file = pathlib.Path("~/.config/que.conf").expanduser() + if not conf_file.exists(): sys.exit("you need a ~/.config/que.conf") cfg = configparser.ConfigParser() cfg.read(conf_file) @@ -39,8 +37,11 @@ def auth(args: argparse.Namespace) -> typing.Union[str, None]: def autodecode(bytestring: bytes) -> typing.Any: - """Attempt to decode bytes into common codecs, preferably utf-8. If no - decoding is available, just return the raw bytes. + """ + Automatically decode bytes into common codecs. + + Or at least make an attempt. Output is preferably utf-8. If no decoding is + available, just return the raw bytes. For all available codecs, see: <https://docs.python.org/3/library/codecs.html#standard-encodings> @@ -63,7 +64,7 @@ def retry( delay: typing.Any = DELAY, backoff: typing.Any = BACKOFF, ) -> typing.Any: - "Decorator for retrying an action." + """Retry an action.""" def decorator(func: typing.Any) -> typing.Any: @functools.wraps(func) @@ -90,7 +91,7 @@ def retry( @retry(http.client.IncompleteRead) @retry(http.client.RemoteDisconnected) def send(args: argparse.Namespace) -> None: - "Send a message to the que." + """Send a message to the que.""" logging.debug("send") key = auth(args) data = args.infile @@ -108,13 +109,13 @@ def send(args: argparse.Namespace) -> None: def then(args: argparse.Namespace, msg: str) -> None: - "Perform an action when passed `--then`." + """Perform an action when passed `--then`.""" if args.then: logging.debug("then") subprocess.run( args.then.format(msg=msg, que=args.target), check=False, - shell=True, + shell=True, # noqa: S602 ) @@ -123,7 +124,7 @@ def then(args: argparse.Namespace, msg: str) -> None: @retry(http.client.IncompleteRead) @retry(http.client.RemoteDisconnected) def recv(args: argparse.Namespace) -> None: - "Receive a message from the que." + """Receive a message from the que.""" logging.debug("recv on: %s", args.target) if args.poll: req = request.Request(f"{args.host}/{args.target}/stream") @@ -133,6 +134,9 @@ def recv(args: argparse.Namespace) -> None: key = auth(args) if key: req.add_header("Authorization", key) + if not req.startswith(("http:", "https:")): + msg = "URL must start with 'http:' or 'https:'" + raise ValueError(msg) with request.urlopen(req) as _req: if args.poll: logging.debug("polling") @@ -141,29 +145,31 @@ def recv(args: argparse.Namespace) -> None: if reply: msg = autodecode(reply) logging.debug("read") - print(msg, end="") + sys.stdout.write(msg) then(args, msg) else: continue else: msg = autodecode(_req.readline()) - print(msg) + sys.stdout.write(msg) then(args, msg) def get_args() -> argparse.Namespace: - "Command line parser" + """Command line parser.""" cli = argparse.ArgumentParser( description=__doc__, epilog=textwrap.dedent( f"""Requests will retry up to {RETRIES} times, with {DELAY} seconds - between attempts.""" + between attempts.""", ), ) cli.add_argument("test", action="store_true", help="run tests") cli.add_argument("--debug", action="store_true", help="log to stderr") cli.add_argument( - "--host", default="http://que.run", help="where que-server is running" + "--host", + default="http://que.run", + help="where que-server is running", ) cli.add_argument( "--poll", @@ -171,7 +177,7 @@ def get_args() -> argparse.Namespace: action="store_true", help=textwrap.dedent( """keep the connection open to stream data from the que. without - this flag, the program will exit after receiving a message""" + this flag, the program will exit after receiving a message""", ), ) cli.add_argument( @@ -179,7 +185,7 @@ def get_args() -> argparse.Namespace: help=textwrap.dedent( """when polling, run this shell command after each response, presumably for side effects, replacing '{que}' with the target and - '{msg}' with the body of the response""" + '{msg}' with the body of the response""", ), ) cli.add_argument( @@ -188,22 +194,18 @@ def get_args() -> argparse.Namespace: action="store_true", help=textwrap.dedent( """when posting to the que, do so continuously in a loop. this can - be used for serving a webpage or other file continuously""" + be used for serving a webpage or other file continuously""", ), ) cli.add_argument( - "target", help="namespace and path of the que, like 'ns/path'" + "target", + help="namespace and path of the que, like 'ns/path'", ) cli.add_argument( "infile", nargs="?", type=argparse.FileType("rb"), - help=" ".join( - [ - "data to put on the que.", - "use '-' for stdin, otherwise should be a readable file", - ] - ), + help="file of data to put on the que. use '-' for stdin", ) return cli.parse_args() @@ -211,7 +213,7 @@ def get_args() -> argparse.Namespace: if __name__ == "__main__": ARGV = get_args() if ARGV.test: - print("ok") + sys.stdout.write("ok\n") sys.exit() if ARGV.debug: logging.basicConfig( |