Compare commits
2 commits
3988a620a8
...
4f1c1226c3
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f1c1226c3 | |||
| a9e790eb94 |
6 changed files with 91 additions and 12 deletions
|
|
@ -6,7 +6,9 @@
|
||||||
+ Module `sqlalchemy`:
|
+ Module `sqlalchemy`:
|
||||||
* removed deprecated alias `entity_base()`. use `declarative_base()` instead.
|
* removed deprecated alias `entity_base()`. use `declarative_base()` instead.
|
||||||
* fix imports.
|
* fix imports.
|
||||||
+ Module `functools`: add `cooldown()`
|
+ Module `functools`: add `cooldown()`, `do_not_flood()`
|
||||||
|
+ Module `color`: add `ColorFormatter()`
|
||||||
|
+ Separated `suou[waiter]` dependency from `suou[quart]`
|
||||||
|
|
||||||
## 0.12.6
|
## 0.12.6
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,9 @@ markdown = [
|
||||||
]
|
]
|
||||||
quart = [
|
quart = [
|
||||||
"Quart",
|
"Quart",
|
||||||
"Quart-Schema",
|
"Quart-Schema"
|
||||||
|
]
|
||||||
|
waiter = [
|
||||||
"starlette>=0.47.2"
|
"starlette>=0.47.2"
|
||||||
]
|
]
|
||||||
quart_auth = [
|
quart_auth = [
|
||||||
|
|
@ -78,7 +80,8 @@ full = [
|
||||||
"suou[quart_auth]", # includes quart, sqlalchemy and quart_sqlalchemy
|
"suou[quart_auth]", # includes quart, sqlalchemy and quart_sqlalchemy
|
||||||
"suou[peewee]",
|
"suou[peewee]",
|
||||||
"suou[markdown]",
|
"suou[markdown]",
|
||||||
"suou[sass]"
|
"suou[sass]",
|
||||||
|
"suou[waiter]"
|
||||||
]
|
]
|
||||||
|
|
||||||
docs = [
|
docs = [
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,14 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
|
||||||
from .iding import Siq, SiqCache, SiqType, SiqGen
|
from .iding import Siq, SiqCache, SiqType, SiqGen
|
||||||
from .codecs import (StringCase, cb32encode, cb32decode, b32lencode, b32ldecode, b64encode, b64decode, b2048encode, b2048decode,
|
from .codecs import (StringCase, cb32encode, cb32decode, b32lencode, b32ldecode, b64encode, b64decode, b2048encode, b2048decode,
|
||||||
jsonencode, twocolon_list, want_bytes, want_str, ssv_list, want_urlsafe, want_urlsafe_bytes)
|
jsonencode, twocolon_list, want_bytes, want_str, ssv_list, want_urlsafe, want_urlsafe_bytes,
|
||||||
|
z85encode, z85decode)
|
||||||
from .bits import count_ones, mask_shift, split_bits, join_bits, mod_ceil, mod_floor
|
from .bits import count_ones, mask_shift, split_bits, join_bits, mod_ceil, mod_floor
|
||||||
from .calendar import want_datetime, want_isodate, want_timestamp, age_and_days
|
from .calendar import want_datetime, want_isodate, want_timestamp, age_and_days
|
||||||
from .configparse import MissingConfigError, MissingConfigWarning, ConfigOptions, ConfigParserConfigSource, ConfigSource, DictConfigSource, ConfigValue, EnvConfigSource
|
from .configparse import MissingConfigError, MissingConfigWarning, ConfigOptions, ConfigParserConfigSource, ConfigSource, DictConfigSource, ConfigValue, EnvConfigSource
|
||||||
from .collections import TimedDict
|
from .collections import TimedDict
|
||||||
from .dei import dei_args
|
from .dei import dei_args
|
||||||
from .functools import deprecated, not_implemented, timed_cache, none_pass, alru_cache, future
|
from .functools import deprecated, not_implemented, timed_cache, none_pass, alru_cache, future, cooldown, do_not_flood
|
||||||
from .classtools import Wanted, Incomplete
|
from .classtools import Wanted, Incomplete
|
||||||
from .itertools import makelist, kwargs_prefix, ltuple, rtuple, additem, addattr
|
from .itertools import makelist, kwargs_prefix, ltuple, rtuple, additem, addattr
|
||||||
from .i18n import I18n, JsonI18n, TomlI18n
|
from .i18n import I18n, JsonI18n, TomlI18n
|
||||||
|
|
@ -32,16 +33,18 @@ from .signing import UserSigner
|
||||||
from .snowflake import Snowflake, SnowflakeGen
|
from .snowflake import Snowflake, SnowflakeGen
|
||||||
from .lex import symbol_table, lex, ilex
|
from .lex import symbol_table, lex, ilex
|
||||||
from .strtools import PrefixIdentifier
|
from .strtools import PrefixIdentifier
|
||||||
from .validators import matches, not_less_than, not_greater_than, yesno
|
from .validators import matches, not_less_than, not_greater_than, yesno, must_be
|
||||||
from .redact import redact_url_password
|
from .redact import redact_url_password
|
||||||
from .http import WantsContentType
|
from .http import WantsContentType
|
||||||
from .color import OKLabColor, chalk, WebColor, RGBColor, LinearRGBColor, XYZColor, OKLCHColor
|
from .color import OKLabColor, chalk, WebColor, RGBColor, LinearRGBColor, \
|
||||||
|
XYZColor, OKLCHColor, ColorFormatter
|
||||||
from .mat import Matrix
|
from .mat import Matrix
|
||||||
from .argparse import LetterSubparsers
|
from .argparse import LetterSubparsers
|
||||||
|
|
||||||
__version__ = "0.13.0a2"
|
__version__ = "0.13.0a4"
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
|
'ColorFormatter',
|
||||||
'ConfigOptions', 'ConfigParserConfigSource', 'ConfigSource', 'ConfigValue',
|
'ConfigOptions', 'ConfigParserConfigSource', 'ConfigSource', 'ConfigValue',
|
||||||
'DictConfigSource', 'EnvConfigSource', 'I18n', 'Incomplete', 'JsonI18n',
|
'DictConfigSource', 'EnvConfigSource', 'I18n', 'Incomplete', 'JsonI18n',
|
||||||
'LetterSubparsers', 'LinearRGBColor',
|
'LetterSubparsers', 'LinearRGBColor',
|
||||||
|
|
@ -52,7 +55,7 @@ __all__ = (
|
||||||
'WebColor', 'XYZColor',
|
'WebColor', 'XYZColor',
|
||||||
'addattr', 'additem', 'age_and_days', 'alru_cache', 'b2048decode', 'b2048encode',
|
'addattr', 'additem', 'age_and_days', 'alru_cache', 'b2048decode', 'b2048encode',
|
||||||
'b32ldecode', 'b32lencode', 'b64encode', 'b64decode', 'cb32encode',
|
'b32ldecode', 'b32lencode', 'b64encode', 'b64decode', 'cb32encode',
|
||||||
'cb32decode', 'chalk', 'count_ones', 'dei_args', 'deprecated',
|
'cb32decode', 'chalk', 'cooldown', 'count_ones', 'dei_args', 'deprecated', 'do_not_flood',
|
||||||
'future', 'ilex', 'join_bits', 'jsonencode', 'kwargs_prefix',
|
'future', 'ilex', 'join_bits', 'jsonencode', 'kwargs_prefix',
|
||||||
'lex', 'ltuple', 'makelist', 'mask_shift',
|
'lex', 'ltuple', 'makelist', 'mask_shift',
|
||||||
'matches', 'mod_ceil', 'mod_floor', 'must_be', 'none_pass', 'not_implemented',
|
'matches', 'mod_ceil', 'mod_floor', 'must_be', 'none_pass', 'not_implemented',
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
from typing import Callable, Mapping
|
from typing import Callable
|
||||||
|
|
||||||
class LetterSubparsers(object):
|
class LetterSubparsers(object):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
import logging
|
||||||
import math
|
import math
|
||||||
|
|
||||||
from suou.functools import deprecated
|
from suou.functools import deprecated
|
||||||
|
|
@ -331,4 +332,48 @@ class OKLCHColor(namedtuple('_OKLCHColor', 'l c h')):
|
||||||
return sum(abs(i - j) / k for i, j, k in zip(self, other, (1, 1, 36)))
|
return sum(abs(i - j) / k for i, j, k in zip(self, other, (1, 1, 36)))
|
||||||
|
|
||||||
|
|
||||||
__all__ = ('chalk', 'WebColor', "RGBColor", 'LinearRGBColor', 'XYZColor', 'OKLabColor', 'OKLCHColor')
|
class ColorFormatter(logging.Formatter):
|
||||||
|
"""
|
||||||
|
Colored logging formatter.
|
||||||
|
|
||||||
|
Opinionated.
|
||||||
|
|
||||||
|
Taken from https://stackoverflow.com/questions/384076/how-can-i-color-python-logging-output
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _get_base_format(color):
|
||||||
|
return f"[%(asctime)s] {color('%(levelname)s')}{chalk.grey(': ')}{color('%(name)s')}{chalk.grey(': ')}%(message)s"
|
||||||
|
|
||||||
|
FORMATS = {
|
||||||
|
logging.DEBUG: _get_base_format(chalk.cyan),
|
||||||
|
logging.INFO: _get_base_format(chalk.green),
|
||||||
|
logging.WARNING: _get_base_format(chalk.yellow),
|
||||||
|
logging.ERROR: _get_base_format(chalk.red),
|
||||||
|
logging.CRITICAL: _get_base_format(chalk.bold.red)
|
||||||
|
}
|
||||||
|
|
||||||
|
del _get_base_format
|
||||||
|
|
||||||
|
def format(self, record: logging.LogRecord) -> str:
|
||||||
|
log_fmt = self.FORMATS.get(record.levelno)
|
||||||
|
formatter = logging.Formatter(log_fmt)
|
||||||
|
return formatter.format(record)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def apply_handler(cls, logger: logging.Logger, level = logging.INFO):
|
||||||
|
"""
|
||||||
|
Apply the colored formatter to a logger.
|
||||||
|
|
||||||
|
Use this with logging.root, instead of logging.basicConfig().
|
||||||
|
|
||||||
|
Should not be called more than once.
|
||||||
|
"""
|
||||||
|
logger.setLevel(level)
|
||||||
|
ch = logging.StreamHandler()
|
||||||
|
ch.setLevel(level)
|
||||||
|
ch.setFormatter(cls())
|
||||||
|
logger.addHandler(ch)
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = ('chalk', 'WebColor', "RGBColor", 'LinearRGBColor', 'XYZColor',
|
||||||
|
'OKLabColor', 'OKLCHColor', 'ColorFormatter')
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,32 @@ def cooldown(unit: int, /, exception: Exception | None = None):
|
||||||
return wrapper
|
return wrapper
|
||||||
return decorator
|
return decorator
|
||||||
|
|
||||||
|
def do_not_flood(unit = .25):
|
||||||
|
"""
|
||||||
|
Implement a calling cooldown for a function or procedure.
|
||||||
|
|
||||||
|
If the decorated function is called during the cooldown, the function
|
||||||
|
blocks before being called again.
|
||||||
|
|
||||||
|
This is blocking and uses time.sleep().
|
||||||
|
"""
|
||||||
|
def decorator(func):
|
||||||
|
@wraps(func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
now = time.time()
|
||||||
|
if wrapper.timeout_until is not None and wrapper.timeout_until > now:
|
||||||
|
wrapper.timeout_delay += unit
|
||||||
|
time.sleep(wrapper.timeout_until - now)
|
||||||
|
wrapper.timeout_until = now + wrapper.timeout_delay
|
||||||
|
else:
|
||||||
|
wrapper.timeout_delay = unit
|
||||||
|
wrapper.timeout_until = time.time() + unit
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
wrapper.timeout_until = None
|
||||||
|
wrapper.timeout_delay = unit
|
||||||
|
return wrapper
|
||||||
|
return decorator
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'deprecated', 'not_implemented', 'timed_cache', 'none_pass', 'alru_cache', 'cooldown'
|
'deprecated', 'not_implemented', 'timed_cache', 'none_pass', 'alru_cache', 'cooldown', 'do_not_flood'
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue