utkit 0.9.0__tar.gz → 0.11.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {utkit-0.9.0 → utkit-0.11.0}/PKG-INFO +3 -1
- {utkit-0.9.0 → utkit-0.11.0}/pyproject.toml +4 -1
- utkit-0.11.0/src/utkit/documentation/.cache/10042715452264249772 +4 -0
- utkit-0.11.0/src/utkit/documentation/.cache/10986014347042203044 +4 -0
- utkit-0.11.0/src/utkit/documentation/.cache/11038628458439117958 +4 -0
- utkit-0.11.0/src/utkit/documentation/.cache/11306067049371264785 +4 -0
- utkit-0.11.0/src/utkit/documentation/.cache/13386297405578974681 +4 -0
- utkit-0.11.0/src/utkit/documentation/.cache/14061902412565698710 +4 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/15312684519617069940 +1 -1
- utkit-0.11.0/src/utkit/documentation/.cache/15724107283881488306 +129 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/16166828772222643061 +1 -1
- utkit-0.11.0/src/utkit/documentation/.cache/17695336329032716848 +4 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/17985671397626253671 +4 -4
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/2940665334038842907 +1 -1
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/326316130724058699 +1 -1
- utkit-0.11.0/src/utkit/documentation/.cache/3476900567878811119 +4 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/3541202890535126406 +1 -1
- utkit-0.11.0/src/utkit/documentation/.cache/360188204203718330 +4 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/403326901327389294 +1 -1
- utkit-0.11.0/src/utkit/documentation/.cache/4969546423033644587 +4 -0
- utkit-0.11.0/src/utkit/documentation/.cache/5530722400779903482 +4 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/5696925338617156769 +1 -1
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/5859600648538783245 +1 -1
- utkit-0.11.0/src/utkit/documentation/.cache/5974781288462474643 +4 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/5976522500417319979 +1 -1
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/6210600303880993421 +1 -1
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/6916343365748484443 +1 -1
- utkit-0.11.0/src/utkit/documentation/.cache/9033698058957892258 +4 -0
- utkit-0.11.0/src/utkit/documentation/.cache/9102534330981319844 +273 -0
- utkit-0.11.0/src/utkit/documentation/.cache/9811225078116513287 +4 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/index.md +1 -1
- utkit-0.11.0/src/utkit/documentation/docs/store/mongo.md +66 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/store/redis.md +10 -17
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/store/s3.md +46 -2
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/404.html +63 -61
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/api/rate-limit/index.html +75 -63
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/api/schema/index.html +75 -63
- utkit-0.9.0/src/utkit/documentation/site/assets/javascripts/bundle.dbc0afdc.min.js → utkit-0.11.0/src/utkit/documentation/site/assets/javascripts/bundle.6e5f0216.min.js +2 -2
- utkit-0.9.0/src/utkit/documentation/site/assets/stylesheets/modern/main.1e981d71.min.css → utkit-0.11.0/src/utkit/documentation/site/assets/stylesheets/modern/main.fba56155.min.css +1 -1
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/auth/index.html +64 -63
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/communication/mail/index.html +73 -63
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/core/logging/index.html +73 -63
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/index.html +64 -63
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/privacy/mask/index.html +75 -63
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/privacy/security/index.html +75 -63
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/search.json +1 -1
- utkit-0.11.0/src/utkit/documentation/site/store/mongo/index.html +1592 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/store/redis/index.html +97 -113
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/store/s3/index.html +128 -70
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/template/render/index.html +76 -66
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/utils/performance/index.html +73 -63
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/validators/data/index.html +73 -63
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/zensical.toml +1 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/store/aws/s3.py +34 -11
- utkit-0.11.0/src/utkit/store/mongo/__init__.py +9 -0
- utkit-0.9.0/src/utkit/documentation/.cache/10042715452264249772 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/10986014347042203044 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/11038628458439117958 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/11306067049371264785 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/13386297405578974681 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/17695336329032716848 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/3476900567878811119 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/360188204203718330 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/4969546423033644587 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/5530722400779903482 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/5974781288462474643 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/9033698058957892258 +0 -4
- utkit-0.9.0/src/utkit/documentation/.cache/9102534330981319844 +0 -273
- utkit-0.9.0/src/utkit/documentation/.cache/9811225078116513287 +0 -4
- {utkit-0.9.0 → utkit-0.11.0}/README.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/api/rate_limit/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/api/rate_limit/error.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/api/rate_limit/middleware.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/api/schema/query.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/auth/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/cli/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/communication/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/communication/mail/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/communication/mail/smtp.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/core/logging.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/.gitignore +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/15661711846603463071 +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.cache/3226154870166803660 +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.github/workflows/docs.yml +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/.gitignore +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/api/rate-limit.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/api/schema.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/auth.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/communication/mail.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/core/logging.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/images/logo-old.png +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/images/logo.png +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/privacy/mask.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/privacy/security.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/stylesheets/extra.css +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/template/render.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/utils/performance.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/docs/validators/data.md +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/assets/images/favicon.png +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/assets/javascripts/LICENSE +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/assets/javascripts/workers/search.e2d2d235.min.js +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/assets/stylesheets/classic/main.a2001754.min.css +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/assets/stylesheets/classic/palette.7dc9a0ad.min.css +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/assets/stylesheets/modern/palette.dfe2e883.min.css +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/images/logo-old.png +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/images/logo.png +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/objects.inv +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/sitemap.xml +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/documentation/site/stylesheets/extra.css +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/privacy/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/privacy/mask.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/privacy/security.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/store/aws/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/store/redis/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/template/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/template/render.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/utils/performance.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/validators/__init__.py +0 -0
- {utkit-0.9.0 → utkit-0.11.0}/src/utkit/validators/data.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: utkit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.0
|
|
4
4
|
Summary: core libraries for development
|
|
5
5
|
Author: TINS PJ
|
|
6
6
|
Author-email: TINS PJ <tinspj1997@gmail.com>
|
|
@@ -16,12 +16,14 @@ Requires-Dist: psutil>=7.2.2 ; extra == 'all'
|
|
|
16
16
|
Requires-Dist: jinja2>=3.1.6 ; extra == 'all'
|
|
17
17
|
Requires-Dist: redis>=7.4.0 ; extra == 'all'
|
|
18
18
|
Requires-Dist: boto3>=1.43.2 ; extra == 'all'
|
|
19
|
+
Requires-Dist: pymongo[srv]>=4.17.0 ; extra == 'all'
|
|
19
20
|
Requires-Dist: slowapi>=0.1.9 ; extra == 'api'
|
|
20
21
|
Requires-Dist: pydantic>=2.13.3 ; extra == 'api'
|
|
21
22
|
Requires-Dist: psutil>=7.2.2 ; extra == 'standard'
|
|
22
23
|
Requires-Dist: jinja2>=3.1.6 ; extra == 'standard'
|
|
23
24
|
Requires-Dist: redis>=7.4.0 ; extra == 'store'
|
|
24
25
|
Requires-Dist: boto3>=1.43.2 ; extra == 'store'
|
|
26
|
+
Requires-Dist: pymongo[srv]>=4.17.0 ; extra == 'store'
|
|
25
27
|
Requires-Python: >=3.12
|
|
26
28
|
Provides-Extra: all
|
|
27
29
|
Provides-Extra: api
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "utkit"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.11.0"
|
|
4
4
|
description = "core libraries for development"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -12,6 +12,7 @@ dependencies = [
|
|
|
12
12
|
"loguru>=0.7.3",
|
|
13
13
|
"pwdlib[argon2]>=0.3.0",
|
|
14
14
|
"pyjwt>=2.12.1",
|
|
15
|
+
|
|
15
16
|
"typer>=0.20.0",
|
|
16
17
|
"zensical>=0.0.37",
|
|
17
18
|
]
|
|
@@ -28,6 +29,7 @@ standard=[
|
|
|
28
29
|
store=[
|
|
29
30
|
"redis>=7.4.0",
|
|
30
31
|
"boto3>=1.43.2",
|
|
32
|
+
"pymongo[srv]>=4.17.0",
|
|
31
33
|
]
|
|
32
34
|
all=[
|
|
33
35
|
"slowapi>=0.1.9",
|
|
@@ -36,6 +38,7 @@ all=[
|
|
|
36
38
|
"jinja2>=3.1.6",
|
|
37
39
|
"redis>=7.4.0",
|
|
38
40
|
"boto3>=1.43.2",
|
|
41
|
+
"pymongo[srv]>=4.17.0",
|
|
39
42
|
]
|
|
40
43
|
|
|
41
44
|
[project.scripts]
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": "\n<!doctype html>\n<html lang=\"en\" class=\"no-js\">\n <head>\n \n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n \n <meta name=\"description\" content=\"Core libraries for development.\">\n \n \n <meta name=\"author\" content=\"TINS PJ\">\n \n \n \n <link rel=\"prev\" href=\"../../privacy/security/\">\n \n \n <link rel=\"next\" href=\"../../store/redis/\">\n \n \n \n \n \n <link rel=\"icon\" href=\"../../images/logo.png\">\n <meta name=\"generator\" content=\"zensical-0.0.42\">\n \n \n \n <title>Logging - Documentation</title>\n \n \n \n \n \n \n <link rel=\"stylesheet\" href=\"../../assets/stylesheets/modern/main.fba56155.min.css\">\n \n \n \n \n <link rel=\"stylesheet\" href=\"../../assets/stylesheets/modern/palette.dfe2e883.min.css\">\n \n \n\n\n \n \n \n \n \n \n \n \n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback\">\n <style>:root{--md-text-font:\"Inter\";--md-code-font:\"JetBrains Mono\"}</style>\n \n \n \n <link rel=\"stylesheet\" href=\"../../stylesheets/extra.css\">\n \n <script>__md_scope=new URL(\"../..\",location),__md_scope.pathname.endsWith(\"/\")||(__md_scope=new URL(__md_scope.pathname+\"/\",location)),__md_hash=e=>[...e].reduce(((e,t)=>(e<<5)-e+t.charCodeAt(0)),0),__md_get=(e,t=localStorage,_=__md_scope)=>JSON.parse(t.getItem(_.pathname+\".\"+e)),__md_set=(e,t,_=localStorage,a=__md_scope)=>{try{_.setItem(a.pathname+\".\"+e,JSON.stringify(t))}catch(e){}},document.documentElement.setAttribute(\"data-platform\",navigator.platform)</script>\n \n \n\n \n \n </head>\n \n \n \n \n \n \n \n \n \n <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"indigo\" data-md-color-accent=\"indigo\">\n \n \n <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n <label class=\"md-overlay\" for=\"__drawer\" aria-label=\"Navigation\"></label>\n <div data-md-component=\"skip\">\n \n \n <a href=\"#logging\" class=\"md-skip\">\n Skip to content\n </a>\n \n </div>\n <div data-md-component=\"announce\">\n \n </div>\n \n \n \n\n \n\n<header class=\"md-header md-header--shadow\" data-md-component=\"header\">\n <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n <a href=\"../..\" title=\"Documentation\" class=\"md-header__button md-logo\" aria-label=\"Documentation\" data-md-component=\"logo\">\n \n <img src=\"../../images/logo.png\" alt=\"Documentation\">\n\n </a>\n <label class=\"md-header__button md-icon\" for=\"__drawer\" aria-label=\"Navigation\">\n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-menu\" viewBox=\"0 0 24 24\"><path d=\"M4 5h16M4 12h16M4 19h16\"/></svg>\n </label>\n <div class=\"md-header__title\" data-md-component=\"header-title\">\n <div class=\"md-header__ellipsis\">\n <div class=\"md-header__topic\">\n <span class=\"md-ellipsis\">\n Documentation\n </span>\n </div>\n <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n <span class=\"md-ellipsis\">\n \n Logging\n \n </span>\n </div>\n </div>\n </div>\n \n \n <form class=\"md-header__option\" data-md-component=\"palette\">\n \n \n \n \n <input class=\"md-option\" data-md-color-media=\"none\" data-md-color-scheme=\"default\" data-md-color-primary=\"indigo\" data-md-color-accent=\"indigo\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n \n <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-sun\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"/></svg>\n </label>\n \n \n \n \n \n <input class=\"md-option\" data-md-color-media=\"none\" data-md-color-scheme=\"slate\" data-md-color-primary=\"indigo\" data-md-color-accent=\"indigo\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n \n <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-moon\" viewBox=\"0 0 24 24\"><path d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"/></svg>\n </label>\n \n \n</form>\n \n \n \n <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n \n \n \n \n \n <label class=\"md-header__button md-icon\" for=\"__search\" aria-label=\"Search\">\n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-search\" viewBox=\"0 0 24 24\"><path d=\"m21 21-4.34-4.34\"/><circle cx=\"11\" cy=\"11\" r=\"8\"/></svg>\n </label>\n <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\" aria-label=\"Search\">\n <button type=\"button\" class=\"md-search__button\">\n Search\n </button>\n</div>\n \n \n <div class=\"md-header__source\">\n \n </div>\n </nav>\n \n</header>\n \n <div class=\"md-container\" data-md-component=\"container\">\n \n \n \n \n \n \n <main class=\"md-main\" data-md-component=\"main\">\n <div class=\"md-main__inner md-grid\">\n \n \n \n <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\" >\n <div class=\"md-sidebar__scrollwrap\">\n <div class=\"md-sidebar__inner\">\n \n\n\n\n<nav class=\"md-nav md-nav--primary\" aria-label=\"Navigation\" data-md-level=\"0\">\n <label class=\"md-nav__title\" for=\"__drawer\">\n <a href=\"../..\" title=\"Documentation\" class=\"md-nav__button md-logo\" aria-label=\"Documentation\" data-md-component=\"logo\">\n \n <img src=\"../../images/logo.png\" alt=\"Documentation\">\n\n </a>\n Documentation\n </label>\n \n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../..\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-rocket\" viewBox=\"0 0 24 24\"><path d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09\"/><path d=\"M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z\"/><path d=\"M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Get started\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../auth/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-key-round\" viewBox=\"0 0 24 24\"><path d=\"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\".5\" fill=\"currentColor\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Auth\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_3\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_3\" id=\"__nav_3_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Communication\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_3_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_3\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Communication\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../communication/mail/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-mail\" viewBox=\"0 0 24 24\"><path d=\"m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"/><rect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Mail (SMTP)\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_4\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_4\" id=\"__nav_4_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n API\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_4_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_4\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n API\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../api/rate-limit/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-gauge\" viewBox=\"0 0 24 24\"><path d=\"m12 14 4-4M3.34 19a10 10 0 1 1 17.32 0\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Rate Limiting\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../api/schema/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-database\" viewBox=\"0 0 24 24\"><ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"/><path d=\"M3 5v14a9 3 0 0 0 18 0V5\"/><path d=\"M3 12a9 3 0 0 0 18 0\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Schema\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_5\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_5\" id=\"__nav_5_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Privacy\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_5_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_5\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Privacy\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../privacy/mask/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-eye-off\" viewBox=\"0 0 24 24\"><path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.8 10.8 0 0 1-1.444 2.49M14.084 14.158a3 3 0 0 1-4.242-4.242\"/><path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143M2 2l20 20\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Masking\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../privacy/security/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-lock\" viewBox=\"0 0 24 24\"><rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\" ry=\"2\"/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Security\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_6\" checked>\n \n \n <label class=\"md-nav__link\" for=\"__nav_6\" id=\"__nav_6_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Core\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_6_label\" aria-expanded=\"true\">\n <label class=\"md-nav__title\" for=\"__nav_6\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Core\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--active\">\n \n \n \n \n \n \n \n <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-scroll-text\" viewBox=\"0 0 24 24\"><path d=\"M15 12h-5M15 8h-5M19 17V5a2 2 0 0 0-2-2H4\"/><path d=\"M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Logging\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <a href=\"././\" class=\"md-nav__link md-nav__link--active\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-scroll-text\" viewBox=\"0 0 24 24\"><path d=\"M15 12h-5M15 8h-5M19 17V5a2 2 0 0 0-2-2H4\"/><path d=\"M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Logging\n\n \n </span>\n \n \n\n </a>\n \n \n\n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"On this page\">\n \n \n \n \n \n \n <label class=\"md-nav__title\" for=\"__toc\">\n <span class=\"md-nav__icon md-icon\"></span>\n On this page\n </label>\n <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n \n <li class=\"md-nav__item\">\n <a href=\"#quick-start\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Quick start\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#setup_logging\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>setup_logging</code>\n </span>\n </span>\n </a>\n \n <nav class=\"md-nav\" aria-label=\"setup_logging\">\n <ul class=\"md-nav__list\">\n \n <li class=\"md-nav__item\">\n <a href=\"#log-sinks\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Log sinks\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#log-format\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Log format\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#example\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Example\n </span>\n </span>\n </a>\n \n</li>\n \n </ul>\n </nav>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#custom-patchers\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Custom patchers\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#thread-safety\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Thread safety\n </span>\n </span>\n </a>\n \n</li>\n \n </ul>\n \n</nav>\n \n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_7\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_7\" id=\"__nav_7_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Store\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_7_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_7\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Store\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../store/redis/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-database\" viewBox=\"0 0 24 24\"><ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"/><path d=\"M3 5v14a9 3 0 0 0 18 0V5\"/><path d=\"M3 12a9 3 0 0 0 18 0\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Redis\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../store/s3/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-cloud\" viewBox=\"0 0 24 24\"><path d=\"M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n AWS S3\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../store/mongo/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-database\" viewBox=\"0 0 24 24\"><ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"/><path d=\"M3 5v14a9 3 0 0 0 18 0V5\"/><path d=\"M3 12a9 3 0 0 0 18 0\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n MongoDB\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_8\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_8\" id=\"__nav_8_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Template\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_8_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_8\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Template\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../template/render/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-layout-template\" viewBox=\"0 0 24 24\"><rect width=\"18\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"/><rect width=\"9\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"/><rect width=\"5\" height=\"7\" x=\"16\" y=\"14\" rx=\"1\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Rendering\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_9\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_9\" id=\"__nav_9_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Utils\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_9_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_9\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Utils\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../utils/performance/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-timer\" viewBox=\"0 0 24 24\"><path d=\"M10 2h4M12 14l3-3\"/><circle cx=\"12\" cy=\"14\" r=\"8\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Performance\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_10\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_10\" id=\"__nav_10_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Validators\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_10_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_10\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Validators\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../validators/data/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-check-circle\" viewBox=\"0 0 24 24\"><path d=\"M21.801 10A10 10 0 1 1 17 3.335\"/><path d=\"m9 11 3 3L22 4\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Data\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n </ul>\n</nav>\n </div>\n </div>\n </div>\n \n \n \n <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" >\n <div class=\"md-sidebar__scrollwrap\">\n \n \n \n \n \n \n \n <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n <div class=\"md-sidebar-button__wrapper\">\n <label class=\"md-sidebar-button\" for=\"__toc\"></label>\n </div>\n \n \n <div class=\"md-sidebar__inner\">\n \n\n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"On this page\">\n \n \n \n \n \n \n <label class=\"md-nav__title\" for=\"__toc\">\n <span class=\"md-nav__icon md-icon\"></span>\n On this page\n </label>\n <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n \n <li class=\"md-nav__item\">\n <a href=\"#quick-start\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Quick start\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#setup_logging\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>setup_logging</code>\n </span>\n </span>\n </a>\n \n <nav class=\"md-nav\" aria-label=\"setup_logging\">\n <ul class=\"md-nav__list\">\n \n <li class=\"md-nav__item\">\n <a href=\"#log-sinks\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Log sinks\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#log-format\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Log format\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#example\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Example\n </span>\n </span>\n </a>\n \n</li>\n \n </ul>\n </nav>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#custom-patchers\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Custom patchers\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#thread-safety\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Thread safety\n </span>\n </span>\n </a>\n \n</li>\n \n </ul>\n \n</nav>\n </div>\n </div>\n </div>\n \n \n \n <div class=\"md-content\" data-md-component=\"content\">\n \n \n\n\n\n \n\n\n <nav class=\"md-path\" aria-label=\"Navigation\" >\n <ol class=\"md-path__list\">\n \n \n \n \n <li class=\"md-path__item\">\n <a href=\"../..\" class=\"md-path__link\">\n \n \n <span class=\"md-ellipsis\">\n Get started\n </span>\n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-path__item\">\n <a href=\"././\" class=\"md-path__link\">\n \n \n <span class=\"md-ellipsis\">\n Core\n </span>\n\n </a>\n </li>\n \n \n\n \n </ol>\n </nav>\n\n \n <article class=\"md-content__inner md-typeset\">\n \n \n\n<h1 id=\"logging\">Logging<a class=\"headerlink\" href=\"#logging\" title=\"Permanent link\">¶</a></h1>\n<p>The <code>utkit.core.logging</code> module provides a structured, opinionated logging setup built on top of <a href=\"https://github.com/Delgan/loguru\">Loguru</a>. It configures console output, rotating application logs, and metering logs — all with a consistent format that includes timestamps, log levels, class/function context, and structured extras.</p>\n<p>No external dependencies beyond <code>loguru</code> are required.</p>\n<hr />\n<h2 id=\"quick-start\">Quick start<a class=\"headerlink\" href=\"#quick-start\" title=\"Permanent link\">¶</a></h2>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.core.logging</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">setup_logging</span>\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">loguru</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">logger</span>\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a>\n</span><span id=\"__span-0-4\"><a id=\"__codelineno-0-4\" name=\"__codelineno-0-4\" href=\"#__codelineno-0-4\"></a><span class=\"n\">setup_logging</span><span class=\"p\">(</span><span class=\"n\">log_base_path</span><span class=\"o\">=</span><span class=\"s2\">"logs"</span><span class=\"p\">)</span>\n</span><span id=\"__span-0-5\"><a id=\"__codelineno-0-5\" name=\"__codelineno-0-5\" href=\"#__codelineno-0-5\"></a>\n</span><span id=\"__span-0-6\"><a id=\"__codelineno-0-6\" name=\"__codelineno-0-6\" href=\"#__codelineno-0-6\"></a><span class=\"n\">logger</span><span class=\"o\">.</span><span class=\"n\">bind</span><span class=\"p\">(</span><span class=\"nb\">type</span><span class=\"o\">=</span><span class=\"s2\">"app"</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">info</span><span class=\"p\">(</span><span class=\"s2\">"Server started"</span><span class=\"p\">)</span>\n</span><span id=\"__span-0-7\"><a id=\"__codelineno-0-7\" name=\"__codelineno-0-7\" href=\"#__codelineno-0-7\"></a><span class=\"n\">logger</span><span class=\"o\">.</span><span class=\"n\">bind</span><span class=\"p\">(</span><span class=\"nb\">type</span><span class=\"o\">=</span><span class=\"s2\">"meter"</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">info</span><span class=\"p\">(</span><span class=\"s2\">"Request count: 42"</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<hr />\n<h2 id=\"setup_logging\"><code>setup_logging</code><a class=\"headerlink\" href=\"#setup_logging\" title=\"Permanent link\">¶</a></h2>\n<p>Configures Loguru with console, application, and metering log sinks.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">setup_logging</span><span class=\"p\">(</span>\n</span><span id=\"__span-1-2\"><a id=\"__codelineno-1-2\" name=\"__codelineno-1-2\" href=\"#__codelineno-1-2\"></a> <span class=\"n\">log_base_path</span><span class=\"p\">:</span> <span class=\"nb\">str</span> <span class=\"o\">=</span> <span class=\"s2\">"logs"</span><span class=\"p\">,</span>\n</span><span id=\"__span-1-3\"><a id=\"__codelineno-1-3\" name=\"__codelineno-1-3\" href=\"#__codelineno-1-3\"></a> <span class=\"n\">patchers</span><span class=\"p\">:</span> <span class=\"n\">List</span><span class=\"p\">[</span><span class=\"n\">Callable</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[],</span>\n</span><span id=\"__span-1-4\"><a id=\"__codelineno-1-4\" name=\"__codelineno-1-4\" href=\"#__codelineno-1-4\"></a> <span class=\"n\">rotation</span><span class=\"p\">:</span> <span class=\"nb\">str</span> <span class=\"o\">=</span> <span class=\"s2\">"1 day"</span><span class=\"p\">,</span>\n</span><span id=\"__span-1-5\"><a id=\"__codelineno-1-5\" name=\"__codelineno-1-5\" href=\"#__codelineno-1-5\"></a> <span class=\"n\">compression</span><span class=\"p\">:</span> <span class=\"nb\">str</span> <span class=\"o\">=</span> <span class=\"s2\">"zip"</span><span class=\"p\">,</span>\n</span><span id=\"__span-1-6\"><a id=\"__codelineno-1-6\" name=\"__codelineno-1-6\" href=\"#__codelineno-1-6\"></a> <span class=\"n\">level</span><span class=\"p\">:</span> <span class=\"nb\">str</span> <span class=\"o\">=</span> <span class=\"s2\">"INFO"</span><span class=\"p\">,</span>\n</span><span id=\"__span-1-7\"><a id=\"__codelineno-1-7\" name=\"__codelineno-1-7\" href=\"#__codelineno-1-7\"></a> <span class=\"n\">app_retention</span><span class=\"p\">:</span> <span class=\"nb\">str</span> <span class=\"o\">=</span> <span class=\"s2\">"7 days"</span><span class=\"p\">,</span>\n</span><span id=\"__span-1-8\"><a id=\"__codelineno-1-8\" name=\"__codelineno-1-8\" href=\"#__codelineno-1-8\"></a> <span class=\"n\">meter_retention</span><span class=\"p\">:</span> <span class=\"nb\">str</span> <span class=\"o\">=</span> <span class=\"s2\">"30 days"</span><span class=\"p\">,</span>\n</span><span id=\"__span-1-9\"><a id=\"__codelineno-1-9\" name=\"__codelineno-1-9\" href=\"#__codelineno-1-9\"></a> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">,</span>\n</span><span id=\"__span-1-10\"><a id=\"__codelineno-1-10\" name=\"__codelineno-1-10\" href=\"#__codelineno-1-10\"></a><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"kc\">None</span>\n</span></code></pre></div>\n<table>\n<thead>\n<tr>\n<th>Parameter</th>\n<th>Type</th>\n<th>Default</th>\n<th>Description</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code>log_base_path</code></td>\n<td><code>str</code></td>\n<td><code>\"logs\"</code></td>\n<td>Directory where log files are written. Created automatically if it does not exist.</td>\n</tr>\n<tr>\n<td><code>patchers</code></td>\n<td><code>List[Callable]</code></td>\n<td><code>[]</code></td>\n<td>Additional patcher callables applied to every log record before formatting. Each callable receives the <code>record</code> dict and may mutate it in place.</td>\n</tr>\n<tr>\n<td><code>rotation</code></td>\n<td><code>str</code></td>\n<td><code>\"1 day\"</code></td>\n<td>Loguru rotation policy for file sinks (e.g. <code>\"500 MB\"</code>, <code>\"1 week\"</code>).</td>\n</tr>\n<tr>\n<td><code>compression</code></td>\n<td><code>str</code></td>\n<td><code>\"zip\"</code></td>\n<td>Compression format applied to rotated log files (e.g. <code>\"gz\"</code>, <code>\"bz2\"</code>).</td>\n</tr>\n<tr>\n<td><code>level</code></td>\n<td><code>str</code></td>\n<td><code>\"INFO\"</code></td>\n<td>Minimum log level written to file sinks.</td>\n</tr>\n<tr>\n<td><code>app_retention</code></td>\n<td><code>str</code></td>\n<td><code>\"7 days\"</code></td>\n<td>Retention period for application log files.</td>\n</tr>\n<tr>\n<td><code>meter_retention</code></td>\n<td><code>str</code></td>\n<td><code>\"30 days\"</code></td>\n<td>Retention period for metering log files.</td>\n</tr>\n<tr>\n<td><code>**kwargs</code></td>\n<td></td>\n<td></td>\n<td>Any additional keyword arguments are forwarded to all file sinks (e.g. <code>enqueue=True</code> for thread-safe async logging).</td>\n</tr>\n</tbody>\n</table>\n<p><strong>Returns:</strong> <code>None</code></p>\n<h3 id=\"log-sinks\">Log sinks<a class=\"headerlink\" href=\"#log-sinks\" title=\"Permanent link\">¶</a></h3>\n<table>\n<thead>\n<tr>\n<th>Sink</th>\n<th>Filter</th>\n<th>Files</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>Console (<code>stderr</code>)</td>\n<td>All records at <code>INFO</code> and above</td>\n<td>—</td>\n</tr>\n<tr>\n<td>Application</td>\n<td><code>record[\"extra\"][\"type\"] == \"app\"</code></td>\n<td><code>logs/application_YYYY-MM-DD.log</code></td>\n</tr>\n<tr>\n<td>Metering</td>\n<td><code>record[\"extra\"][\"type\"] == \"meter\"</code></td>\n<td><code>logs/metering_YYYY-MM-DD.log</code></td>\n</tr>\n</tbody>\n</table>\n<p>Route a record to a specific sink by binding the <code>type</code> key:</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a><span class=\"n\">logger</span><span class=\"o\">.</span><span class=\"n\">bind</span><span class=\"p\">(</span><span class=\"nb\">type</span><span class=\"o\">=</span><span class=\"s2\">"app"</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">info</span><span class=\"p\">(</span><span class=\"s2\">"User signed in"</span><span class=\"p\">,</span> <span class=\"n\">user_id</span><span class=\"o\">=</span><span class=\"mi\">42</span><span class=\"p\">)</span>\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a><span class=\"n\">logger</span><span class=\"o\">.</span><span class=\"n\">bind</span><span class=\"p\">(</span><span class=\"nb\">type</span><span class=\"o\">=</span><span class=\"s2\">"meter"</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">info</span><span class=\"p\">(</span><span class=\"s2\">"API call"</span><span class=\"p\">,</span> <span class=\"n\">endpoint</span><span class=\"o\">=</span><span class=\"s2\">"/health"</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<p>Records without a <code>type</code> binding appear only in the console sink.</p>\n<h3 id=\"log-format\">Log format<a class=\"headerlink\" href=\"#log-format\" title=\"Permanent link\">¶</a></h3>\n<p>All sinks share a consistent format:</p>\n<div class=\"language-text highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a>YYYY-MM-DD HH:mm:ss | LEVEL | module:ClassName:function:line | message | Context: {extra}\n</span></code></pre></div>\n<h3 id=\"example\">Example<a class=\"headerlink\" href=\"#example\" title=\"Permanent link\">¶</a></h3>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.core.logging</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">setup_logging</span>\n</span><span id=\"__span-4-2\"><a id=\"__codelineno-4-2\" name=\"__codelineno-4-2\" href=\"#__codelineno-4-2\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">loguru</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">logger</span>\n</span><span id=\"__span-4-3\"><a id=\"__codelineno-4-3\" name=\"__codelineno-4-3\" href=\"#__codelineno-4-3\"></a>\n</span><span id=\"__span-4-4\"><a id=\"__codelineno-4-4\" name=\"__codelineno-4-4\" href=\"#__codelineno-4-4\"></a><span class=\"n\">setup_logging</span><span class=\"p\">(</span>\n</span><span id=\"__span-4-5\"><a id=\"__codelineno-4-5\" name=\"__codelineno-4-5\" href=\"#__codelineno-4-5\"></a> <span class=\"n\">log_base_path</span><span class=\"o\">=</span><span class=\"s2\">"var/logs"</span><span class=\"p\">,</span>\n</span><span id=\"__span-4-6\"><a id=\"__codelineno-4-6\" name=\"__codelineno-4-6\" href=\"#__codelineno-4-6\"></a> <span class=\"n\">rotation</span><span class=\"o\">=</span><span class=\"s2\">"500 MB"</span><span class=\"p\">,</span>\n</span><span id=\"__span-4-7\"><a id=\"__codelineno-4-7\" name=\"__codelineno-4-7\" href=\"#__codelineno-4-7\"></a> <span class=\"n\">compression</span><span class=\"o\">=</span><span class=\"s2\">"gz"</span><span class=\"p\">,</span>\n</span><span id=\"__span-4-8\"><a id=\"__codelineno-4-8\" name=\"__codelineno-4-8\" href=\"#__codelineno-4-8\"></a> <span class=\"n\">level</span><span class=\"o\">=</span><span class=\"s2\">"DEBUG"</span><span class=\"p\">,</span>\n</span><span id=\"__span-4-9\"><a id=\"__codelineno-4-9\" name=\"__codelineno-4-9\" href=\"#__codelineno-4-9\"></a> <span class=\"n\">app_retention</span><span class=\"o\">=</span><span class=\"s2\">"14 days"</span><span class=\"p\">,</span>\n</span><span id=\"__span-4-10\"><a id=\"__codelineno-4-10\" name=\"__codelineno-4-10\" href=\"#__codelineno-4-10\"></a> <span class=\"n\">meter_retention</span><span class=\"o\">=</span><span class=\"s2\">"60 days"</span><span class=\"p\">,</span>\n</span><span id=\"__span-4-11\"><a id=\"__codelineno-4-11\" name=\"__codelineno-4-11\" href=\"#__codelineno-4-11\"></a> <span class=\"n\">enqueue</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">,</span> <span class=\"c1\"># thread-safe async logging</span>\n</span><span id=\"__span-4-12\"><a id=\"__codelineno-4-12\" name=\"__codelineno-4-12\" href=\"#__codelineno-4-12\"></a><span class=\"p\">)</span>\n</span><span id=\"__span-4-13\"><a id=\"__codelineno-4-13\" name=\"__codelineno-4-13\" href=\"#__codelineno-4-13\"></a>\n</span><span id=\"__span-4-14\"><a id=\"__codelineno-4-14\" name=\"__codelineno-4-14\" href=\"#__codelineno-4-14\"></a><span class=\"n\">logger</span><span class=\"o\">.</span><span class=\"n\">bind</span><span class=\"p\">(</span><span class=\"nb\">type</span><span class=\"o\">=</span><span class=\"s2\">"app"</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">info</span><span class=\"p\">(</span><span class=\"s2\">"Application boot complete"</span><span class=\"p\">)</span>\n</span><span id=\"__span-4-15\"><a id=\"__codelineno-4-15\" name=\"__codelineno-4-15\" href=\"#__codelineno-4-15\"></a><span class=\"n\">logger</span><span class=\"o\">.</span><span class=\"n\">bind</span><span class=\"p\">(</span><span class=\"nb\">type</span><span class=\"o\">=</span><span class=\"s2\">"meter"</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">debug</span><span class=\"p\">(</span><span class=\"s2\">"Cache hit"</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"o\">=</span><span class=\"s2\">"user:123"</span><span class=\"p\">)</span>\n</span></code></pre></div>\n<hr />\n<h2 id=\"custom-patchers\">Custom patchers<a class=\"headerlink\" href=\"#custom-patchers\" title=\"Permanent link\">¶</a></h2>\n<p>Pass a list of callables to <code>patchers</code> to enrich every log record with additional context. Each callable receives the mutable <code>record</code> dict.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">add_request_id</span><span class=\"p\">(</span><span class=\"n\">record</span><span class=\"p\">):</span>\n</span><span id=\"__span-5-2\"><a id=\"__codelineno-5-2\" name=\"__codelineno-5-2\" href=\"#__codelineno-5-2\"></a> <span class=\"n\">record</span><span class=\"p\">[</span><span class=\"s2\">"extra"</span><span class=\"p\">][</span><span class=\"s2\">"request_id"</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">get_current_request_id</span><span class=\"p\">()</span>\n</span><span id=\"__span-5-3\"><a id=\"__codelineno-5-3\" name=\"__codelineno-5-3\" href=\"#__codelineno-5-3\"></a>\n</span><span id=\"__span-5-4\"><a id=\"__codelineno-5-4\" name=\"__codelineno-5-4\" href=\"#__codelineno-5-4\"></a><span class=\"n\">setup_logging</span><span class=\"p\">(</span><span class=\"n\">patchers</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">add_request_id</span><span class=\"p\">])</span>\n</span></code></pre></div>\n<p>The built-in <code>_add_class_name</code> patcher is always appended last. It walks the call stack to detect the calling class and stores its name in <code>record[\"extra\"][\"classname\"]</code>, which is rendered as part of the log format.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-6-1\"><a id=\"__codelineno-6-1\" name=\"__codelineno-6-1\" href=\"#__codelineno-6-1\"></a><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyService</span><span class=\"p\">:</span>\n</span><span id=\"__span-6-2\"><a id=\"__codelineno-6-2\" name=\"__codelineno-6-2\" href=\"#__codelineno-6-2\"></a> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">process</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n</span><span id=\"__span-6-3\"><a id=\"__codelineno-6-3\" name=\"__codelineno-6-3\" href=\"#__codelineno-6-3\"></a> <span class=\"n\">logger</span><span class=\"o\">.</span><span class=\"n\">bind</span><span class=\"p\">(</span><span class=\"nb\">type</span><span class=\"o\">=</span><span class=\"s2\">"app"</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">info</span><span class=\"p\">(</span><span class=\"s2\">"Processing"</span><span class=\"p\">)</span>\n</span><span id=\"__span-6-4\"><a id=\"__codelineno-6-4\" name=\"__codelineno-6-4\" href=\"#__codelineno-6-4\"></a> <span class=\"c1\"># → ... | MyService:process:42 | Processing | ...</span>\n</span></code></pre></div>\n<hr />\n<h2 id=\"thread-safety\">Thread safety<a class=\"headerlink\" href=\"#thread-safety\" title=\"Permanent link\">¶</a></h2>\n<p>Pass <code>enqueue=True</code> as a keyword argument to make all file sinks non-blocking and safe for multi-threaded or multi-process applications:</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-7-1\"><a id=\"__codelineno-7-1\" name=\"__codelineno-7-1\" href=\"#__codelineno-7-1\"></a><span class=\"n\">setup_logging</span><span class=\"p\">(</span><span class=\"n\">enqueue</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n</span></code></pre></div>\n\n\n\n\n\n\n\n\n\n \n \n\n\n\n\n\n\n \n </article>\n </div>\n \n \n <script>var tabs=__md_get(\"__tabs\");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(\".tabbed-set\")){var labels=set.querySelector(\".tabbed-labels\");for(var tab of tabs)for(var label of labels.getElementsByTagName(\"label\"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>\n\n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n </div>\n \n <button type=\"button\" class=\"md-top md-icon\" data-md-component=\"top\" hidden>\n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-circle-arrow-up\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"m16 12-4-4-4 4M12 16V8\"/></svg>\n Back to top\n</button>\n \n </main>\n \n <footer class=\"md-footer\">\n \n \n \n <nav class=\"md-footer__inner md-grid\" aria-label=\"Footer\" >\n \n \n <a href=\"../../privacy/security/\" class=\"md-footer__link md-footer__link--prev\" aria-label=\"Previous: Security\">\n <div class=\"md-footer__button md-icon\">\n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-arrow-left\" viewBox=\"0 0 24 24\"><path d=\"m12 19-7-7 7-7M19 12H5\"/></svg>\n </div>\n <div class=\"md-footer__title\">\n <span class=\"md-footer__direction\">\n Previous\n </span>\n <div class=\"md-ellipsis\">\n Security\n </div>\n </div>\n </a>\n \n \n \n <a href=\"../../store/redis/\" class=\"md-footer__link md-footer__link--next\" aria-label=\"Next: Redis\">\n <div class=\"md-footer__title\">\n <span class=\"md-footer__direction\">\n Next\n </span>\n <div class=\"md-ellipsis\">\n Redis\n </div>\n </div>\n <div class=\"md-footer__button md-icon\">\n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-arrow-right\" viewBox=\"0 0 24 24\"><path d=\"M5 12h14M12 5l7 7-7 7\"/></svg>\n </div>\n </a>\n \n </nav>\n \n \n <div class=\"md-footer-meta md-typeset\">\n <div class=\"md-footer-meta__inner md-grid\">\n <div class=\"md-copyright\">\n \n <div class=\"md-copyright__highlight\">\n Copyright © 2026 TINS PJ. All rights reserved.\n\n </div>\n \n \n Made with\n <a href=\"https://zensical.org/\" target=\"_blank\" rel=\"noopener\">\n Zensical\n </a>\n \n</div>\n \n </div>\n </div>\n</footer>\n \n </div>\n <div class=\"md-dialog\" data-md-component=\"dialog\">\n <div class=\"md-dialog__inner md-typeset\"></div>\n </div>\n \n \n \n \n \n <script id=\"__config\" type=\"application/json\">{\"annotate\":null,\"base\":\"../..\",\"features\":[\"announce.dismiss\",\"content.code.annotate\",\"content.code.copy\",\"content.code.select\",\"content.footnote.tooltips\",\"content.tabs.link\",\"content.tooltips\",\"navigation.footer\",\"navigation.indexes\",\"navigation.instant\",\"navigation.instant.prefetch\",\"navigation.path\",\"navigation.sections\",\"navigation.top\",\"navigation.tracking\",\"search.highlight\"],\"search\":\"../../assets/javascripts/workers/search.e2d2d235.min.js\",\"tags\":null,\"translations\":{\"clipboard.copied\":\"Copied to clipboard\",\"clipboard.copy\":\"Copy to clipboard\",\"search.result.more.one\":\"1 more on this page\",\"search.result.more.other\":\"# more on this page\",\"search.result.none\":\"No matching documents\",\"search.result.one\":\"1 matching document\",\"search.result.other\":\"# matching documents\",\"search.result.placeholder\":\"Type to start searching\",\"search.result.term.missing\":\"Missing\",\"select.version\":\"Select version\"},\"version\":null}</script>\n \n \n <script src=\"../../assets/javascripts/bundle.6e5f0216.min.js\"></script>\n \n \n </body>\n</html>",
|
|
3
|
+
"hash": 4138464489130172680
|
|
4
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
{
|
|
2
|
+
"data": "\n<!doctype html>\n<html lang=\"en\" class=\"no-js\">\n <head>\n \n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n \n <meta name=\"description\" content=\"Core libraries for development.\">\n \n \n <meta name=\"author\" content=\"TINS PJ\">\n \n \n \n <link rel=\"prev\" href=\"../../utils/performance/\">\n \n \n \n \n \n \n <link rel=\"icon\" href=\"../../images/logo.png\">\n <meta name=\"generator\" content=\"zensical-0.0.42\">\n \n \n \n <title>Validators - Documentation</title>\n \n \n \n \n \n \n <link rel=\"stylesheet\" href=\"../../assets/stylesheets/modern/main.fba56155.min.css\">\n \n \n \n \n <link rel=\"stylesheet\" href=\"../../assets/stylesheets/modern/palette.dfe2e883.min.css\">\n \n \n\n\n \n \n \n \n \n \n \n \n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n <link rel=\"stylesheet\" href=\"https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,500,500i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback\">\n <style>:root{--md-text-font:\"Inter\";--md-code-font:\"JetBrains Mono\"}</style>\n \n \n \n <link rel=\"stylesheet\" href=\"../../stylesheets/extra.css\">\n \n <script>__md_scope=new URL(\"../..\",location),__md_scope.pathname.endsWith(\"/\")||(__md_scope=new URL(__md_scope.pathname+\"/\",location)),__md_hash=e=>[...e].reduce(((e,t)=>(e<<5)-e+t.charCodeAt(0)),0),__md_get=(e,t=localStorage,_=__md_scope)=>JSON.parse(t.getItem(_.pathname+\".\"+e)),__md_set=(e,t,_=localStorage,a=__md_scope)=>{try{_.setItem(a.pathname+\".\"+e,JSON.stringify(t))}catch(e){}},document.documentElement.setAttribute(\"data-platform\",navigator.platform)</script>\n \n \n\n \n \n </head>\n \n \n \n \n \n \n \n \n \n <body dir=\"ltr\" data-md-color-scheme=\"default\" data-md-color-primary=\"indigo\" data-md-color-accent=\"indigo\">\n \n \n <input class=\"md-toggle\" data-md-toggle=\"drawer\" type=\"checkbox\" id=\"__drawer\" autocomplete=\"off\">\n <input class=\"md-toggle\" data-md-toggle=\"search\" type=\"checkbox\" id=\"__search\" autocomplete=\"off\">\n <label class=\"md-overlay\" for=\"__drawer\" aria-label=\"Navigation\"></label>\n <div data-md-component=\"skip\">\n \n \n <a href=\"#validators\" class=\"md-skip\">\n Skip to content\n </a>\n \n </div>\n <div data-md-component=\"announce\">\n \n </div>\n \n \n \n\n \n\n<header class=\"md-header md-header--shadow\" data-md-component=\"header\">\n <nav class=\"md-header__inner md-grid\" aria-label=\"Header\">\n <a href=\"../..\" title=\"Documentation\" class=\"md-header__button md-logo\" aria-label=\"Documentation\" data-md-component=\"logo\">\n \n <img src=\"../../images/logo.png\" alt=\"Documentation\">\n\n </a>\n <label class=\"md-header__button md-icon\" for=\"__drawer\" aria-label=\"Navigation\">\n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-menu\" viewBox=\"0 0 24 24\"><path d=\"M4 5h16M4 12h16M4 19h16\"/></svg>\n </label>\n <div class=\"md-header__title\" data-md-component=\"header-title\">\n <div class=\"md-header__ellipsis\">\n <div class=\"md-header__topic\">\n <span class=\"md-ellipsis\">\n Documentation\n </span>\n </div>\n <div class=\"md-header__topic\" data-md-component=\"header-topic\">\n <span class=\"md-ellipsis\">\n \n Validators\n \n </span>\n </div>\n </div>\n </div>\n \n \n <form class=\"md-header__option\" data-md-component=\"palette\">\n \n \n \n \n <input class=\"md-option\" data-md-color-media=\"none\" data-md-color-scheme=\"default\" data-md-color-primary=\"indigo\" data-md-color-accent=\"indigo\" aria-label=\"Switch to dark mode\" type=\"radio\" name=\"__palette\" id=\"__palette_0\">\n \n <label class=\"md-header__button md-icon\" title=\"Switch to dark mode\" for=\"__palette_1\" hidden>\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-sun\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41\"/></svg>\n </label>\n \n \n \n \n \n <input class=\"md-option\" data-md-color-media=\"none\" data-md-color-scheme=\"slate\" data-md-color-primary=\"indigo\" data-md-color-accent=\"indigo\" aria-label=\"Switch to light mode\" type=\"radio\" name=\"__palette\" id=\"__palette_1\">\n \n <label class=\"md-header__button md-icon\" title=\"Switch to light mode\" for=\"__palette_0\" hidden>\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-moon\" viewBox=\"0 0 24 24\"><path d=\"M20.985 12.486a9 9 0 1 1-9.473-9.472c.405-.022.617.46.402.803a6 6 0 0 0 8.268 8.268c.344-.215.825-.004.803.401\"/></svg>\n </label>\n \n \n</form>\n \n \n \n <script>var palette=__md_get(\"__palette\");if(palette&&palette.color){if(\"(prefers-color-scheme)\"===palette.color.media){var media=matchMedia(\"(prefers-color-scheme: light)\"),input=document.querySelector(media.matches?\"[data-md-color-media='(prefers-color-scheme: light)']\":\"[data-md-color-media='(prefers-color-scheme: dark)']\");palette.color.media=input.getAttribute(\"data-md-color-media\"),palette.color.scheme=input.getAttribute(\"data-md-color-scheme\"),palette.color.primary=input.getAttribute(\"data-md-color-primary\"),palette.color.accent=input.getAttribute(\"data-md-color-accent\")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute(\"data-md-color-\"+key,value)}</script>\n \n \n \n \n \n <label class=\"md-header__button md-icon\" for=\"__search\" aria-label=\"Search\">\n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-search\" viewBox=\"0 0 24 24\"><path d=\"m21 21-4.34-4.34\"/><circle cx=\"11\" cy=\"11\" r=\"8\"/></svg>\n </label>\n <div class=\"md-search\" data-md-component=\"search\" role=\"dialog\" aria-label=\"Search\">\n <button type=\"button\" class=\"md-search__button\">\n Search\n </button>\n</div>\n \n \n <div class=\"md-header__source\">\n \n </div>\n </nav>\n \n</header>\n \n <div class=\"md-container\" data-md-component=\"container\">\n \n \n \n \n \n \n <main class=\"md-main\" data-md-component=\"main\">\n <div class=\"md-main__inner md-grid\">\n \n \n \n <div class=\"md-sidebar md-sidebar--primary\" data-md-component=\"sidebar\" data-md-type=\"navigation\" >\n <div class=\"md-sidebar__scrollwrap\">\n <div class=\"md-sidebar__inner\">\n \n\n\n\n<nav class=\"md-nav md-nav--primary\" aria-label=\"Navigation\" data-md-level=\"0\">\n <label class=\"md-nav__title\" for=\"__drawer\">\n <a href=\"../..\" title=\"Documentation\" class=\"md-nav__button md-logo\" aria-label=\"Documentation\" data-md-component=\"logo\">\n \n <img src=\"../../images/logo.png\" alt=\"Documentation\">\n\n </a>\n Documentation\n </label>\n \n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../..\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-rocket\" viewBox=\"0 0 24 24\"><path d=\"M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09\"/><path d=\"M9 12a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.4 22.4 0 0 1-4 2z\"/><path d=\"M9 12H4s.55-3.03 2-4c1.62-1.08 5 .05 5 .05\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Get started\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../auth/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-key-round\" viewBox=\"0 0 24 24\"><path d=\"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z\"/><circle cx=\"16.5\" cy=\"7.5\" r=\".5\" fill=\"currentColor\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Auth\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_3\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_3\" id=\"__nav_3_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Communication\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_3_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_3\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Communication\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../communication/mail/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-mail\" viewBox=\"0 0 24 24\"><path d=\"m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7\"/><rect width=\"20\" height=\"16\" x=\"2\" y=\"4\" rx=\"2\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Mail (SMTP)\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_4\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_4\" id=\"__nav_4_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n API\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_4_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_4\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n API\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../api/rate-limit/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-gauge\" viewBox=\"0 0 24 24\"><path d=\"m12 14 4-4M3.34 19a10 10 0 1 1 17.32 0\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Rate Limiting\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../api/schema/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-database\" viewBox=\"0 0 24 24\"><ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"/><path d=\"M3 5v14a9 3 0 0 0 18 0V5\"/><path d=\"M3 12a9 3 0 0 0 18 0\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Schema\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_5\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_5\" id=\"__nav_5_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Privacy\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_5_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_5\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Privacy\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../privacy/mask/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-eye-off\" viewBox=\"0 0 24 24\"><path d=\"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.8 10.8 0 0 1-1.444 2.49M14.084 14.158a3 3 0 0 1-4.242-4.242\"/><path d=\"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143M2 2l20 20\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Masking\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../privacy/security/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-lock\" viewBox=\"0 0 24 24\"><rect width=\"18\" height=\"11\" x=\"3\" y=\"11\" rx=\"2\" ry=\"2\"/><path d=\"M7 11V7a5 5 0 0 1 10 0v4\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Security\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_6\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_6\" id=\"__nav_6_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Core\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_6_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_6\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Core\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../core/logging/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-scroll-text\" viewBox=\"0 0 24 24\"><path d=\"M15 12h-5M15 8h-5M19 17V5a2 2 0 0 0-2-2H4\"/><path d=\"M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Logging\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_7\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_7\" id=\"__nav_7_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Store\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_7_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_7\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Store\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../store/redis/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-database\" viewBox=\"0 0 24 24\"><ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"/><path d=\"M3 5v14a9 3 0 0 0 18 0V5\"/><path d=\"M3 12a9 3 0 0 0 18 0\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Redis\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../store/s3/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-cloud\" viewBox=\"0 0 24 24\"><path d=\"M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n AWS S3\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../store/mongo/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-database\" viewBox=\"0 0 24 24\"><ellipse cx=\"12\" cy=\"5\" rx=\"9\" ry=\"3\"/><path d=\"M3 5v14a9 3 0 0 0 18 0V5\"/><path d=\"M3 12a9 3 0 0 0 18 0\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n MongoDB\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_8\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_8\" id=\"__nav_8_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Template\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_8_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_8\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Template\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../template/render/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-layout-template\" viewBox=\"0 0 24 24\"><rect width=\"18\" height=\"7\" x=\"3\" y=\"3\" rx=\"1\"/><rect width=\"9\" height=\"7\" x=\"3\" y=\"14\" rx=\"1\"/><rect width=\"5\" height=\"7\" x=\"16\" y=\"14\" rx=\"1\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Rendering\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_9\" >\n \n \n <label class=\"md-nav__link\" for=\"__nav_9\" id=\"__nav_9_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Utils\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_9_label\" aria-expanded=\"false\">\n <label class=\"md-nav__title\" for=\"__nav_9\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Utils\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n <li class=\"md-nav__item\">\n <a href=\"../../utils/performance/\" class=\"md-nav__link\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-timer\" viewBox=\"0 0 24 24\"><path d=\"M10 2h4M12 14l3-3\"/><circle cx=\"12\" cy=\"14\" r=\"8\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Performance\n\n \n </span>\n \n \n\n </a>\n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested\">\n \n \n \n <input class=\"md-nav__toggle md-toggle \" type=\"checkbox\" id=\"__nav_10\" checked>\n \n \n <label class=\"md-nav__link\" for=\"__nav_10\" id=\"__nav_10_label\" tabindex=\"\">\n \n \n \n <span class=\"md-ellipsis\">\n \n \n Validators\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <nav class=\"md-nav\" data-md-level=\"1\" aria-labelledby=\"__nav_10_label\" aria-expanded=\"true\">\n <label class=\"md-nav__title\" for=\"__nav_10\">\n <span class=\"md-nav__icon md-icon\"></span>\n \n \n Validators\n\n </label>\n <ul class=\"md-nav__list\" data-md-scrollfix>\n \n \n \n \n \n \n \n \n \n <li class=\"md-nav__item md-nav__item--active\">\n \n \n \n \n \n \n \n <label class=\"md-nav__link md-nav__link--active\" for=\"__toc\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-check-circle\" viewBox=\"0 0 24 24\"><path d=\"M21.801 10A10 10 0 1 1 17 3.335\"/><path d=\"m9 11 3 3L22 4\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Data\n\n \n </span>\n \n \n\n <span class=\"md-nav__icon md-icon\"></span>\n </label>\n \n <a href=\"././\" class=\"md-nav__link md-nav__link--active\">\n \n \n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-check-circle\" viewBox=\"0 0 24 24\"><path d=\"M21.801 10A10 10 0 1 1 17 3.335\"/><path d=\"m9 11 3 3L22 4\"/></svg>\n \n <span class=\"md-ellipsis\">\n \n \n Data\n\n \n </span>\n \n \n\n </a>\n \n \n\n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"On this page\">\n \n \n \n \n \n \n <label class=\"md-nav__title\" for=\"__toc\">\n <span class=\"md-nav__icon md-icon\"></span>\n On this page\n </label>\n <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n \n <li class=\"md-nav__item\">\n <a href=\"#quick-start\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Quick start\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#validation-functions\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Validation Functions\n </span>\n </span>\n </a>\n \n <nav class=\"md-nav\" aria-label=\"Validation Functions\">\n <ul class=\"md-nav__list\">\n \n <li class=\"md-nav__item\">\n <a href=\"#is_alphanumeric\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_alphanumeric</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#is_numeric\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_numeric</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#is_alpha\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_alpha</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#is_empty\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_empty</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#is_palindrome\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_palindrome</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#is_title_case\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_title_case</code>\n </span>\n </span>\n </a>\n \n</li>\n \n </ul>\n </nav>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#transformation-functions\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Transformation Functions\n </span>\n </span>\n </a>\n \n <nav class=\"md-nav\" aria-label=\"Transformation Functions\">\n <ul class=\"md-nav__list\">\n \n <li class=\"md-nav__item\">\n <a href=\"#remove_whitespace\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>remove_whitespace</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#normalize_string\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>normalize_string</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#to_lowercase\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>to_lowercase</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#to_uppercase\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>to_uppercase</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#capitalize_string\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>capitalize_string</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#slugify\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>slugify</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#reverse_string\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>reverse_string</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#remove_duplicates\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>remove_duplicates</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#remove_numbers\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>remove_numbers</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#remove_vowels\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>remove_vowels</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#extract_numbers\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>extract_numbers</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#count_words\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>count_words</code>\n </span>\n </span>\n </a>\n \n</li>\n \n </ul>\n </nav>\n \n</li>\n \n </ul>\n \n</nav>\n \n </li>\n \n\n \n \n </ul>\n </nav>\n \n </li>\n \n\n \n </ul>\n</nav>\n </div>\n </div>\n </div>\n \n \n \n <div class=\"md-sidebar md-sidebar--secondary\" data-md-component=\"sidebar\" data-md-type=\"toc\" >\n <div class=\"md-sidebar__scrollwrap\">\n \n \n \n \n \n \n \n <input class=\"md-nav__toggle md-toggle\" type=\"checkbox\" id=\"__toc\">\n <div class=\"md-sidebar-button__wrapper\">\n <label class=\"md-sidebar-button\" for=\"__toc\"></label>\n </div>\n \n \n <div class=\"md-sidebar__inner\">\n \n\n\n<nav class=\"md-nav md-nav--secondary\" aria-label=\"On this page\">\n \n \n \n \n \n \n <label class=\"md-nav__title\" for=\"__toc\">\n <span class=\"md-nav__icon md-icon\"></span>\n On this page\n </label>\n <ul class=\"md-nav__list\" data-md-component=\"toc\" data-md-scrollfix>\n \n <li class=\"md-nav__item\">\n <a href=\"#quick-start\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Quick start\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#validation-functions\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Validation Functions\n </span>\n </span>\n </a>\n \n <nav class=\"md-nav\" aria-label=\"Validation Functions\">\n <ul class=\"md-nav__list\">\n \n <li class=\"md-nav__item\">\n <a href=\"#is_alphanumeric\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_alphanumeric</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#is_numeric\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_numeric</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#is_alpha\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_alpha</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#is_empty\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_empty</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#is_palindrome\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_palindrome</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#is_title_case\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>is_title_case</code>\n </span>\n </span>\n </a>\n \n</li>\n \n </ul>\n </nav>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#transformation-functions\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n Transformation Functions\n </span>\n </span>\n </a>\n \n <nav class=\"md-nav\" aria-label=\"Transformation Functions\">\n <ul class=\"md-nav__list\">\n \n <li class=\"md-nav__item\">\n <a href=\"#remove_whitespace\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>remove_whitespace</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#normalize_string\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>normalize_string</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#to_lowercase\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>to_lowercase</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#to_uppercase\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>to_uppercase</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#capitalize_string\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>capitalize_string</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#slugify\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>slugify</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#reverse_string\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>reverse_string</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#remove_duplicates\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>remove_duplicates</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#remove_numbers\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>remove_numbers</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#remove_vowels\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>remove_vowels</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#extract_numbers\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>extract_numbers</code>\n </span>\n </span>\n </a>\n \n</li>\n \n <li class=\"md-nav__item\">\n <a href=\"#count_words\" class=\"md-nav__link\">\n <span class=\"md-ellipsis\">\n <span class=\"md-typeset\">\n <code>count_words</code>\n </span>\n </span>\n </a>\n \n</li>\n \n </ul>\n </nav>\n \n</li>\n \n </ul>\n \n</nav>\n </div>\n </div>\n </div>\n \n \n \n <div class=\"md-content\" data-md-component=\"content\">\n \n \n\n\n\n \n\n\n <nav class=\"md-path\" aria-label=\"Navigation\" >\n <ol class=\"md-path__list\">\n \n \n \n \n <li class=\"md-path__item\">\n <a href=\"../..\" class=\"md-path__link\">\n \n \n <span class=\"md-ellipsis\">\n Get started\n </span>\n\n </a>\n </li>\n \n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n <li class=\"md-path__item\">\n <a href=\"././\" class=\"md-path__link\">\n \n \n <span class=\"md-ellipsis\">\n Validators\n </span>\n\n </a>\n </li>\n \n \n\n \n </ol>\n </nav>\n\n \n <article class=\"md-content__inner md-typeset\">\n \n \n\n<h1 id=\"validators\">Validators<a class=\"headerlink\" href=\"#validators\" title=\"Permanent link\">¶</a></h1>\n<p>The <code>utkit.validators.data</code> module provides lightweight string validation and transformation helpers. No external dependencies are required.</p>\n<hr />\n<h2 id=\"quick-start\">Quick start<a class=\"headerlink\" href=\"#quick-start\" title=\"Permanent link\">¶</a></h2>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-0-1\"><a id=\"__codelineno-0-1\" name=\"__codelineno-0-1\" href=\"#__codelineno-0-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">remove_whitespace</span><span class=\"p\">,</span> <span class=\"n\">is_numeric</span><span class=\"p\">,</span> <span class=\"n\">slugify</span>\n</span><span id=\"__span-0-2\"><a id=\"__codelineno-0-2\" name=\"__codelineno-0-2\" href=\"#__codelineno-0-2\"></a>\n</span><span id=\"__span-0-3\"><a id=\"__codelineno-0-3\" name=\"__codelineno-0-3\" href=\"#__codelineno-0-3\"></a><span class=\"n\">clean</span> <span class=\"o\">=</span> <span class=\"n\">remove_whitespace</span><span class=\"p\">(</span><span class=\"s2\">" hello world "</span><span class=\"p\">)</span>\n</span><span id=\"__span-0-4\"><a id=\"__codelineno-0-4\" name=\"__codelineno-0-4\" href=\"#__codelineno-0-4\"></a><span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">clean</span><span class=\"p\">)</span> <span class=\"c1\"># "hello world"</span>\n</span><span id=\"__span-0-5\"><a id=\"__codelineno-0-5\" name=\"__codelineno-0-5\" href=\"#__codelineno-0-5\"></a>\n</span><span id=\"__span-0-6\"><a id=\"__codelineno-0-6\" name=\"__codelineno-0-6\" href=\"#__codelineno-0-6\"></a><span class=\"n\">is_numeric</span><span class=\"p\">(</span><span class=\"s2\">"12345"</span><span class=\"p\">)</span> <span class=\"c1\"># True</span>\n</span><span id=\"__span-0-7\"><a id=\"__codelineno-0-7\" name=\"__codelineno-0-7\" href=\"#__codelineno-0-7\"></a><span class=\"n\">slug</span> <span class=\"o\">=</span> <span class=\"n\">slugify</span><span class=\"p\">(</span><span class=\"s2\">"Hello World!"</span><span class=\"p\">)</span>\n</span><span id=\"__span-0-8\"><a id=\"__codelineno-0-8\" name=\"__codelineno-0-8\" href=\"#__codelineno-0-8\"></a><span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">slug</span><span class=\"p\">)</span> <span class=\"c1\"># "hello-world"</span>\n</span></code></pre></div>\n<hr />\n<h2 id=\"validation-functions\">Validation Functions<a class=\"headerlink\" href=\"#validation-functions\" title=\"Permanent link\">¶</a></h2>\n<h3 id=\"is_alphanumeric\"><code>is_alphanumeric</code><a class=\"headerlink\" href=\"#is_alphanumeric\" title=\"Permanent link\">¶</a></h3>\n<p>Check if string contains only alphanumeric characters (letters and digits).</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-1-1\"><a id=\"__codelineno-1-1\" name=\"__codelineno-1-1\" href=\"#__codelineno-1-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">is_alphanumeric</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>bool</code> — True if all characters are alphanumeric, False otherwise.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-2-1\"><a id=\"__codelineno-2-1\" name=\"__codelineno-2-1\" href=\"#__codelineno-2-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">is_alphanumeric</span>\n</span><span id=\"__span-2-2\"><a id=\"__codelineno-2-2\" name=\"__codelineno-2-2\" href=\"#__codelineno-2-2\"></a>\n</span><span id=\"__span-2-3\"><a id=\"__codelineno-2-3\" name=\"__codelineno-2-3\" href=\"#__codelineno-2-3\"></a><span class=\"n\">is_alphanumeric</span><span class=\"p\">(</span><span class=\"s2\">"abc123"</span><span class=\"p\">)</span> <span class=\"c1\"># True</span>\n</span><span id=\"__span-2-4\"><a id=\"__codelineno-2-4\" name=\"__codelineno-2-4\" href=\"#__codelineno-2-4\"></a><span class=\"n\">is_alphanumeric</span><span class=\"p\">(</span><span class=\"s2\">"hello world"</span><span class=\"p\">)</span> <span class=\"c1\"># False (contains space)</span>\n</span><span id=\"__span-2-5\"><a id=\"__codelineno-2-5\" name=\"__codelineno-2-5\" href=\"#__codelineno-2-5\"></a><span class=\"n\">is_alphanumeric</span><span class=\"p\">(</span><span class=\"s2\">"hello-123"</span><span class=\"p\">)</span> <span class=\"c1\"># False (contains hyphen)</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"is_numeric\"><code>is_numeric</code><a class=\"headerlink\" href=\"#is_numeric\" title=\"Permanent link\">¶</a></h3>\n<p>Check if string contains only numeric characters (digits).</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-3-1\"><a id=\"__codelineno-3-1\" name=\"__codelineno-3-1\" href=\"#__codelineno-3-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">is_numeric</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>bool</code> — True if all characters are digits, False otherwise.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-4-1\"><a id=\"__codelineno-4-1\" name=\"__codelineno-4-1\" href=\"#__codelineno-4-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">is_numeric</span>\n</span><span id=\"__span-4-2\"><a id=\"__codelineno-4-2\" name=\"__codelineno-4-2\" href=\"#__codelineno-4-2\"></a>\n</span><span id=\"__span-4-3\"><a id=\"__codelineno-4-3\" name=\"__codelineno-4-3\" href=\"#__codelineno-4-3\"></a><span class=\"n\">is_numeric</span><span class=\"p\">(</span><span class=\"s2\">"12345"</span><span class=\"p\">)</span> <span class=\"c1\"># True</span>\n</span><span id=\"__span-4-4\"><a id=\"__codelineno-4-4\" name=\"__codelineno-4-4\" href=\"#__codelineno-4-4\"></a><span class=\"n\">is_numeric</span><span class=\"p\">(</span><span class=\"s2\">"123.45"</span><span class=\"p\">)</span> <span class=\"c1\"># False (contains decimal point)</span>\n</span><span id=\"__span-4-5\"><a id=\"__codelineno-4-5\" name=\"__codelineno-4-5\" href=\"#__codelineno-4-5\"></a><span class=\"n\">is_numeric</span><span class=\"p\">(</span><span class=\"s2\">"abc123"</span><span class=\"p\">)</span> <span class=\"c1\"># False (contains letters)</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"is_alpha\"><code>is_alpha</code><a class=\"headerlink\" href=\"#is_alpha\" title=\"Permanent link\">¶</a></h3>\n<p>Check if string contains only alphabetic characters.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-5-1\"><a id=\"__codelineno-5-1\" name=\"__codelineno-5-1\" href=\"#__codelineno-5-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">is_alpha</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>bool</code> — True if all characters are alphabetic, False otherwise.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-6-1\"><a id=\"__codelineno-6-1\" name=\"__codelineno-6-1\" href=\"#__codelineno-6-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">is_alpha</span>\n</span><span id=\"__span-6-2\"><a id=\"__codelineno-6-2\" name=\"__codelineno-6-2\" href=\"#__codelineno-6-2\"></a>\n</span><span id=\"__span-6-3\"><a id=\"__codelineno-6-3\" name=\"__codelineno-6-3\" href=\"#__codelineno-6-3\"></a><span class=\"n\">is_alpha</span><span class=\"p\">(</span><span class=\"s2\">"hello"</span><span class=\"p\">)</span> <span class=\"c1\"># True</span>\n</span><span id=\"__span-6-4\"><a id=\"__codelineno-6-4\" name=\"__codelineno-6-4\" href=\"#__codelineno-6-4\"></a><span class=\"n\">is_alpha</span><span class=\"p\">(</span><span class=\"s2\">"hello123"</span><span class=\"p\">)</span> <span class=\"c1\"># False (contains digits)</span>\n</span><span id=\"__span-6-5\"><a id=\"__codelineno-6-5\" name=\"__codelineno-6-5\" href=\"#__codelineno-6-5\"></a><span class=\"n\">is_alpha</span><span class=\"p\">(</span><span class=\"s2\">"hello-world"</span><span class=\"p\">)</span> <span class=\"c1\"># False (contains hyphen)</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"is_empty\"><code>is_empty</code><a class=\"headerlink\" href=\"#is_empty\" title=\"Permanent link\">¶</a></h3>\n<p>Check if string is empty or contains only whitespace.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-7-1\"><a id=\"__codelineno-7-1\" name=\"__codelineno-7-1\" href=\"#__codelineno-7-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">is_empty</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>bool</code> — True if empty or only whitespace, False otherwise.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-8-1\"><a id=\"__codelineno-8-1\" name=\"__codelineno-8-1\" href=\"#__codelineno-8-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">is_empty</span>\n</span><span id=\"__span-8-2\"><a id=\"__codelineno-8-2\" name=\"__codelineno-8-2\" href=\"#__codelineno-8-2\"></a>\n</span><span id=\"__span-8-3\"><a id=\"__codelineno-8-3\" name=\"__codelineno-8-3\" href=\"#__codelineno-8-3\"></a><span class=\"n\">is_empty</span><span class=\"p\">(</span><span class=\"s2\">""</span><span class=\"p\">)</span> <span class=\"c1\"># True</span>\n</span><span id=\"__span-8-4\"><a id=\"__codelineno-8-4\" name=\"__codelineno-8-4\" href=\"#__codelineno-8-4\"></a><span class=\"n\">is_empty</span><span class=\"p\">(</span><span class=\"s2\">" "</span><span class=\"p\">)</span> <span class=\"c1\"># True</span>\n</span><span id=\"__span-8-5\"><a id=\"__codelineno-8-5\" name=\"__codelineno-8-5\" href=\"#__codelineno-8-5\"></a><span class=\"n\">is_empty</span><span class=\"p\">(</span><span class=\"s2\">"</span><span class=\"se\">\\t\\n</span><span class=\"s2\">"</span><span class=\"p\">)</span> <span class=\"c1\"># True</span>\n</span><span id=\"__span-8-6\"><a id=\"__codelineno-8-6\" name=\"__codelineno-8-6\" href=\"#__codelineno-8-6\"></a><span class=\"n\">is_empty</span><span class=\"p\">(</span><span class=\"s2\">"hello"</span><span class=\"p\">)</span> <span class=\"c1\"># False</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"is_palindrome\"><code>is_palindrome</code><a class=\"headerlink\" href=\"#is_palindrome\" title=\"Permanent link\">¶</a></h3>\n<p>Check if string is a palindrome (ignoring spaces and case).</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-9-1\"><a id=\"__codelineno-9-1\" name=\"__codelineno-9-1\" href=\"#__codelineno-9-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">is_palindrome</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>bool</code> — True if the string reads the same forwards and backwards, False otherwise.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-10-1\"><a id=\"__codelineno-10-1\" name=\"__codelineno-10-1\" href=\"#__codelineno-10-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">is_palindrome</span>\n</span><span id=\"__span-10-2\"><a id=\"__codelineno-10-2\" name=\"__codelineno-10-2\" href=\"#__codelineno-10-2\"></a>\n</span><span id=\"__span-10-3\"><a id=\"__codelineno-10-3\" name=\"__codelineno-10-3\" href=\"#__codelineno-10-3\"></a><span class=\"n\">is_palindrome</span><span class=\"p\">(</span><span class=\"s2\">"racecar"</span><span class=\"p\">)</span> <span class=\"c1\"># True</span>\n</span><span id=\"__span-10-4\"><a id=\"__codelineno-10-4\" name=\"__codelineno-10-4\" href=\"#__codelineno-10-4\"></a><span class=\"n\">is_palindrome</span><span class=\"p\">(</span><span class=\"s2\">"A man a plan a canal Panama"</span><span class=\"p\">)</span> <span class=\"c1\"># True</span>\n</span><span id=\"__span-10-5\"><a id=\"__codelineno-10-5\" name=\"__codelineno-10-5\" href=\"#__codelineno-10-5\"></a><span class=\"n\">is_palindrome</span><span class=\"p\">(</span><span class=\"s2\">"hello"</span><span class=\"p\">)</span> <span class=\"c1\"># False</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"is_title_case\"><code>is_title_case</code><a class=\"headerlink\" href=\"#is_title_case\" title=\"Permanent link\">¶</a></h3>\n<p>Check if string is in title case format.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-11-1\"><a id=\"__codelineno-11-1\" name=\"__codelineno-11-1\" href=\"#__codelineno-11-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">is_title_case</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">bool</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>bool</code> — True if string is in title case, False otherwise.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-12-1\"><a id=\"__codelineno-12-1\" name=\"__codelineno-12-1\" href=\"#__codelineno-12-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">is_title_case</span>\n</span><span id=\"__span-12-2\"><a id=\"__codelineno-12-2\" name=\"__codelineno-12-2\" href=\"#__codelineno-12-2\"></a>\n</span><span id=\"__span-12-3\"><a id=\"__codelineno-12-3\" name=\"__codelineno-12-3\" href=\"#__codelineno-12-3\"></a><span class=\"n\">is_title_case</span><span class=\"p\">(</span><span class=\"s2\">"Hello World"</span><span class=\"p\">)</span> <span class=\"c1\"># True</span>\n</span><span id=\"__span-12-4\"><a id=\"__codelineno-12-4\" name=\"__codelineno-12-4\" href=\"#__codelineno-12-4\"></a><span class=\"n\">is_title_case</span><span class=\"p\">(</span><span class=\"s2\">"hello world"</span><span class=\"p\">)</span> <span class=\"c1\"># False</span>\n</span><span id=\"__span-12-5\"><a id=\"__codelineno-12-5\" name=\"__codelineno-12-5\" href=\"#__codelineno-12-5\"></a><span class=\"n\">is_title_case</span><span class=\"p\">(</span><span class=\"s2\">"HELLO WORLD"</span><span class=\"p\">)</span> <span class=\"c1\"># False</span>\n</span></code></pre></div>\n<hr />\n<h2 id=\"transformation-functions\">Transformation Functions<a class=\"headerlink\" href=\"#transformation-functions\" title=\"Permanent link\">¶</a></h2>\n<h3 id=\"remove_whitespace\"><code>remove_whitespace</code><a class=\"headerlink\" href=\"#remove_whitespace\" title=\"Permanent link\">¶</a></h3>\n<p>Remove leading and trailing whitespace from a string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-13-1\"><a id=\"__codelineno-13-1\" name=\"__codelineno-13-1\" href=\"#__codelineno-13-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">remove_whitespace</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — the string with leading and trailing whitespace removed.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-14-1\"><a id=\"__codelineno-14-1\" name=\"__codelineno-14-1\" href=\"#__codelineno-14-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">remove_whitespace</span>\n</span><span id=\"__span-14-2\"><a id=\"__codelineno-14-2\" name=\"__codelineno-14-2\" href=\"#__codelineno-14-2\"></a>\n</span><span id=\"__span-14-3\"><a id=\"__codelineno-14-3\" name=\"__codelineno-14-3\" href=\"#__codelineno-14-3\"></a><span class=\"n\">remove_whitespace</span><span class=\"p\">(</span><span class=\"s2\">" hello world "</span><span class=\"p\">)</span> <span class=\"c1\"># "hello world"</span>\n</span><span id=\"__span-14-4\"><a id=\"__codelineno-14-4\" name=\"__codelineno-14-4\" href=\"#__codelineno-14-4\"></a><span class=\"n\">remove_whitespace</span><span class=\"p\">(</span><span class=\"s2\">"</span><span class=\"se\">\\t</span><span class=\"s2\">value</span><span class=\"se\">\\n</span><span class=\"s2\">"</span><span class=\"p\">)</span> <span class=\"c1\"># "value"</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"normalize_string\"><code>normalize_string</code><a class=\"headerlink\" href=\"#normalize_string\" title=\"Permanent link\">¶</a></h3>\n<p>Normalize string by converting to lowercase and removing extra whitespace.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-15-1\"><a id=\"__codelineno-15-1\" name=\"__codelineno-15-1\" href=\"#__codelineno-15-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">normalize_string</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — the normalized string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-16-1\"><a id=\"__codelineno-16-1\" name=\"__codelineno-16-1\" href=\"#__codelineno-16-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">normalize_string</span>\n</span><span id=\"__span-16-2\"><a id=\"__codelineno-16-2\" name=\"__codelineno-16-2\" href=\"#__codelineno-16-2\"></a>\n</span><span id=\"__span-16-3\"><a id=\"__codelineno-16-3\" name=\"__codelineno-16-3\" href=\"#__codelineno-16-3\"></a><span class=\"n\">normalize_string</span><span class=\"p\">(</span><span class=\"s2\">" HELLO WORLD "</span><span class=\"p\">)</span> <span class=\"c1\"># "hello world"</span>\n</span><span id=\"__span-16-4\"><a id=\"__codelineno-16-4\" name=\"__codelineno-16-4\" href=\"#__codelineno-16-4\"></a><span class=\"n\">normalize_string</span><span class=\"p\">(</span><span class=\"s2\">"HeLLo WoRLd"</span><span class=\"p\">)</span> <span class=\"c1\"># "hello world"</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"to_lowercase\"><code>to_lowercase</code><a class=\"headerlink\" href=\"#to_lowercase\" title=\"Permanent link\">¶</a></h3>\n<p>Convert string to lowercase.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-17-1\"><a id=\"__codelineno-17-1\" name=\"__codelineno-17-1\" href=\"#__codelineno-17-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">to_lowercase</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — the lowercase string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-18-1\"><a id=\"__codelineno-18-1\" name=\"__codelineno-18-1\" href=\"#__codelineno-18-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">to_lowercase</span>\n</span><span id=\"__span-18-2\"><a id=\"__codelineno-18-2\" name=\"__codelineno-18-2\" href=\"#__codelineno-18-2\"></a>\n</span><span id=\"__span-18-3\"><a id=\"__codelineno-18-3\" name=\"__codelineno-18-3\" href=\"#__codelineno-18-3\"></a><span class=\"n\">to_lowercase</span><span class=\"p\">(</span><span class=\"s2\">"HELLO"</span><span class=\"p\">)</span> <span class=\"c1\"># "hello"</span>\n</span><span id=\"__span-18-4\"><a id=\"__codelineno-18-4\" name=\"__codelineno-18-4\" href=\"#__codelineno-18-4\"></a><span class=\"n\">to_lowercase</span><span class=\"p\">(</span><span class=\"s2\">"HeLLo WoRLd"</span><span class=\"p\">)</span> <span class=\"c1\"># "hello world"</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"to_uppercase\"><code>to_uppercase</code><a class=\"headerlink\" href=\"#to_uppercase\" title=\"Permanent link\">¶</a></h3>\n<p>Convert string to uppercase.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-19-1\"><a id=\"__codelineno-19-1\" name=\"__codelineno-19-1\" href=\"#__codelineno-19-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">to_uppercase</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — the uppercase string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-20-1\"><a id=\"__codelineno-20-1\" name=\"__codelineno-20-1\" href=\"#__codelineno-20-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">to_uppercase</span>\n</span><span id=\"__span-20-2\"><a id=\"__codelineno-20-2\" name=\"__codelineno-20-2\" href=\"#__codelineno-20-2\"></a>\n</span><span id=\"__span-20-3\"><a id=\"__codelineno-20-3\" name=\"__codelineno-20-3\" href=\"#__codelineno-20-3\"></a><span class=\"n\">to_uppercase</span><span class=\"p\">(</span><span class=\"s2\">"hello"</span><span class=\"p\">)</span> <span class=\"c1\"># "HELLO"</span>\n</span><span id=\"__span-20-4\"><a id=\"__codelineno-20-4\" name=\"__codelineno-20-4\" href=\"#__codelineno-20-4\"></a><span class=\"n\">to_uppercase</span><span class=\"p\">(</span><span class=\"s2\">"hello world"</span><span class=\"p\">)</span> <span class=\"c1\"># "HELLO WORLD"</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"capitalize_string\"><code>capitalize_string</code><a class=\"headerlink\" href=\"#capitalize_string\" title=\"Permanent link\">¶</a></h3>\n<p>Capitalize the first letter of string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-21-1\"><a id=\"__codelineno-21-1\" name=\"__codelineno-21-1\" href=\"#__codelineno-21-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">capitalize_string</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — the string with first letter capitalized.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-22-1\"><a id=\"__codelineno-22-1\" name=\"__codelineno-22-1\" href=\"#__codelineno-22-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">capitalize_string</span>\n</span><span id=\"__span-22-2\"><a id=\"__codelineno-22-2\" name=\"__codelineno-22-2\" href=\"#__codelineno-22-2\"></a>\n</span><span id=\"__span-22-3\"><a id=\"__codelineno-22-3\" name=\"__codelineno-22-3\" href=\"#__codelineno-22-3\"></a><span class=\"n\">capitalize_string</span><span class=\"p\">(</span><span class=\"s2\">"hello world"</span><span class=\"p\">)</span> <span class=\"c1\"># "Hello world"</span>\n</span><span id=\"__span-22-4\"><a id=\"__codelineno-22-4\" name=\"__codelineno-22-4\" href=\"#__codelineno-22-4\"></a><span class=\"n\">capitalize_string</span><span class=\"p\">(</span><span class=\"s2\">"HELLO"</span><span class=\"p\">)</span> <span class=\"c1\"># "Hello"</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"slugify\"><code>slugify</code><a class=\"headerlink\" href=\"#slugify\" title=\"Permanent link\">¶</a></h3>\n<p>Convert string to URL-safe slug format.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-23-1\"><a id=\"__codelineno-23-1\" name=\"__codelineno-23-1\" href=\"#__codelineno-23-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">slugify</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — the slugified string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-24-1\"><a id=\"__codelineno-24-1\" name=\"__codelineno-24-1\" href=\"#__codelineno-24-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">slugify</span>\n</span><span id=\"__span-24-2\"><a id=\"__codelineno-24-2\" name=\"__codelineno-24-2\" href=\"#__codelineno-24-2\"></a>\n</span><span id=\"__span-24-3\"><a id=\"__codelineno-24-3\" name=\"__codelineno-24-3\" href=\"#__codelineno-24-3\"></a><span class=\"n\">slugify</span><span class=\"p\">(</span><span class=\"s2\">"Hello World!"</span><span class=\"p\">)</span> <span class=\"c1\"># "hello-world"</span>\n</span><span id=\"__span-24-4\"><a id=\"__codelineno-24-4\" name=\"__codelineno-24-4\" href=\"#__codelineno-24-4\"></a><span class=\"n\">slugify</span><span class=\"p\">(</span><span class=\"s2\">"Product Name & Price"</span><span class=\"p\">)</span> <span class=\"c1\"># "product-name-price"</span>\n</span><span id=\"__span-24-5\"><a id=\"__codelineno-24-5\" name=\"__codelineno-24-5\" href=\"#__codelineno-24-5\"></a><span class=\"n\">slugify</span><span class=\"p\">(</span><span class=\"s2\">"Multiple Spaces"</span><span class=\"p\">)</span> <span class=\"c1\"># "multiple-spaces"</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"reverse_string\"><code>reverse_string</code><a class=\"headerlink\" href=\"#reverse_string\" title=\"Permanent link\">¶</a></h3>\n<p>Reverse the string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-25-1\"><a id=\"__codelineno-25-1\" name=\"__codelineno-25-1\" href=\"#__codelineno-25-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">reverse_string</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — the reversed string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-26-1\"><a id=\"__codelineno-26-1\" name=\"__codelineno-26-1\" href=\"#__codelineno-26-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">reverse_string</span>\n</span><span id=\"__span-26-2\"><a id=\"__codelineno-26-2\" name=\"__codelineno-26-2\" href=\"#__codelineno-26-2\"></a>\n</span><span id=\"__span-26-3\"><a id=\"__codelineno-26-3\" name=\"__codelineno-26-3\" href=\"#__codelineno-26-3\"></a><span class=\"n\">reverse_string</span><span class=\"p\">(</span><span class=\"s2\">"hello"</span><span class=\"p\">)</span> <span class=\"c1\"># "olleh"</span>\n</span><span id=\"__span-26-4\"><a id=\"__codelineno-26-4\" name=\"__codelineno-26-4\" href=\"#__codelineno-26-4\"></a><span class=\"n\">reverse_string</span><span class=\"p\">(</span><span class=\"s2\">"12345"</span><span class=\"p\">)</span> <span class=\"c1\"># "54321"</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"remove_duplicates\"><code>remove_duplicates</code><a class=\"headerlink\" href=\"#remove_duplicates\" title=\"Permanent link\">¶</a></h3>\n<p>Remove duplicate characters while preserving order.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-27-1\"><a id=\"__codelineno-27-1\" name=\"__codelineno-27-1\" href=\"#__codelineno-27-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">remove_duplicates</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — the string with duplicate characters removed.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-28-1\"><a id=\"__codelineno-28-1\" name=\"__codelineno-28-1\" href=\"#__codelineno-28-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">remove_duplicates</span>\n</span><span id=\"__span-28-2\"><a id=\"__codelineno-28-2\" name=\"__codelineno-28-2\" href=\"#__codelineno-28-2\"></a>\n</span><span id=\"__span-28-3\"><a id=\"__codelineno-28-3\" name=\"__codelineno-28-3\" href=\"#__codelineno-28-3\"></a><span class=\"n\">remove_duplicates</span><span class=\"p\">(</span><span class=\"s2\">"aabbcc"</span><span class=\"p\">)</span> <span class=\"c1\"># "abc"</span>\n</span><span id=\"__span-28-4\"><a id=\"__codelineno-28-4\" name=\"__codelineno-28-4\" href=\"#__codelineno-28-4\"></a><span class=\"n\">remove_duplicates</span><span class=\"p\">(</span><span class=\"s2\">"hello"</span><span class=\"p\">)</span> <span class=\"c1\"># "helo"</span>\n</span><span id=\"__span-28-5\"><a id=\"__codelineno-28-5\" name=\"__codelineno-28-5\" href=\"#__codelineno-28-5\"></a><span class=\"n\">remove_duplicates</span><span class=\"p\">(</span><span class=\"s2\">"mississippi"</span><span class=\"p\">)</span> <span class=\"c1\"># "misp"</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"remove_numbers\"><code>remove_numbers</code><a class=\"headerlink\" href=\"#remove_numbers\" title=\"Permanent link\">¶</a></h3>\n<p>Remove all numeric digits from string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-29-1\"><a id=\"__codelineno-29-1\" name=\"__codelineno-29-1\" href=\"#__codelineno-29-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">remove_numbers</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — the string with all digits removed.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-30-1\"><a id=\"__codelineno-30-1\" name=\"__codelineno-30-1\" href=\"#__codelineno-30-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">remove_numbers</span>\n</span><span id=\"__span-30-2\"><a id=\"__codelineno-30-2\" name=\"__codelineno-30-2\" href=\"#__codelineno-30-2\"></a>\n</span><span id=\"__span-30-3\"><a id=\"__codelineno-30-3\" name=\"__codelineno-30-3\" href=\"#__codelineno-30-3\"></a><span class=\"n\">remove_numbers</span><span class=\"p\">(</span><span class=\"s2\">"abc123def456"</span><span class=\"p\">)</span> <span class=\"c1\"># "abcdef"</span>\n</span><span id=\"__span-30-4\"><a id=\"__codelineno-30-4\" name=\"__codelineno-30-4\" href=\"#__codelineno-30-4\"></a><span class=\"n\">remove_numbers</span><span class=\"p\">(</span><span class=\"s2\">"test123"</span><span class=\"p\">)</span> <span class=\"c1\"># "test"</span>\n</span><span id=\"__span-30-5\"><a id=\"__codelineno-30-5\" name=\"__codelineno-30-5\" href=\"#__codelineno-30-5\"></a><span class=\"n\">remove_numbers</span><span class=\"p\">(</span><span class=\"s2\">"12345"</span><span class=\"p\">)</span> <span class=\"c1\"># ""</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"remove_vowels\"><code>remove_vowels</code><a class=\"headerlink\" href=\"#remove_vowels\" title=\"Permanent link\">¶</a></h3>\n<p>Remove all vowels from string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-31-1\"><a id=\"__codelineno-31-1\" name=\"__codelineno-31-1\" href=\"#__codelineno-31-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">remove_vowels</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — the string with vowels removed.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-32-1\"><a id=\"__codelineno-32-1\" name=\"__codelineno-32-1\" href=\"#__codelineno-32-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">remove_vowels</span>\n</span><span id=\"__span-32-2\"><a id=\"__codelineno-32-2\" name=\"__codelineno-32-2\" href=\"#__codelineno-32-2\"></a>\n</span><span id=\"__span-32-3\"><a id=\"__codelineno-32-3\" name=\"__codelineno-32-3\" href=\"#__codelineno-32-3\"></a><span class=\"n\">remove_vowels</span><span class=\"p\">(</span><span class=\"s2\">"hello"</span><span class=\"p\">)</span> <span class=\"c1\"># "hll"</span>\n</span><span id=\"__span-32-4\"><a id=\"__codelineno-32-4\" name=\"__codelineno-32-4\" href=\"#__codelineno-32-4\"></a><span class=\"n\">remove_vowels</span><span class=\"p\">(</span><span class=\"s2\">"programming"</span><span class=\"p\">)</span> <span class=\"c1\"># "prgrmmng"</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"extract_numbers\"><code>extract_numbers</code><a class=\"headerlink\" href=\"#extract_numbers\" title=\"Permanent link\">¶</a></h3>\n<p>Extract all numeric digits from string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-33-1\"><a id=\"__codelineno-33-1\" name=\"__codelineno-33-1\" href=\"#__codelineno-33-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">extract_numbers</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">str</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>str</code> — a string containing only the extracted digits.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-34-1\"><a id=\"__codelineno-34-1\" name=\"__codelineno-34-1\" href=\"#__codelineno-34-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">extract_numbers</span>\n</span><span id=\"__span-34-2\"><a id=\"__codelineno-34-2\" name=\"__codelineno-34-2\" href=\"#__codelineno-34-2\"></a>\n</span><span id=\"__span-34-3\"><a id=\"__codelineno-34-3\" name=\"__codelineno-34-3\" href=\"#__codelineno-34-3\"></a><span class=\"n\">extract_numbers</span><span class=\"p\">(</span><span class=\"s2\">"abc123def456"</span><span class=\"p\">)</span> <span class=\"c1\"># "123456"</span>\n</span><span id=\"__span-34-4\"><a id=\"__codelineno-34-4\" name=\"__codelineno-34-4\" href=\"#__codelineno-34-4\"></a><span class=\"n\">extract_numbers</span><span class=\"p\">(</span><span class=\"s2\">"test123"</span><span class=\"p\">)</span> <span class=\"c1\"># "123"</span>\n</span><span id=\"__span-34-5\"><a id=\"__codelineno-34-5\" name=\"__codelineno-34-5\" href=\"#__codelineno-34-5\"></a><span class=\"n\">extract_numbers</span><span class=\"p\">(</span><span class=\"s2\">"no digits"</span><span class=\"p\">)</span> <span class=\"c1\"># ""</span>\n</span></code></pre></div>\n<hr />\n<h3 id=\"count_words\"><code>count_words</code><a class=\"headerlink\" href=\"#count_words\" title=\"Permanent link\">¶</a></h3>\n<p>Count the number of words in string.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-35-1\"><a id=\"__codelineno-35-1\" name=\"__codelineno-35-1\" href=\"#__codelineno-35-1\"></a><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">count_words</span><span class=\"p\">(</span><span class=\"n\">value</span><span class=\"p\">:</span> <span class=\"nb\">str</span><span class=\"p\">)</span> <span class=\"o\">-></span> <span class=\"nb\">int</span>\n</span></code></pre></div>\n<p><strong>Returns:</strong> <code>int</code> — the number of words.</p>\n<div class=\"language-python highlight\"><pre><span></span><code><span id=\"__span-36-1\"><a id=\"__codelineno-36-1\" name=\"__codelineno-36-1\" href=\"#__codelineno-36-1\"></a><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">utkit.validators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">count_words</span>\n</span><span id=\"__span-36-2\"><a id=\"__codelineno-36-2\" name=\"__codelineno-36-2\" href=\"#__codelineno-36-2\"></a>\n</span><span id=\"__span-36-3\"><a id=\"__codelineno-36-3\" name=\"__codelineno-36-3\" href=\"#__codelineno-36-3\"></a><span class=\"n\">count_words</span><span class=\"p\">(</span><span class=\"s2\">"hello world"</span><span class=\"p\">)</span> <span class=\"c1\"># 2</span>\n</span><span id=\"__span-36-4\"><a id=\"__codelineno-36-4\" name=\"__codelineno-36-4\" href=\"#__codelineno-36-4\"></a><span class=\"n\">count_words</span><span class=\"p\">(</span><span class=\"s2\">"one"</span><span class=\"p\">)</span> <span class=\"c1\"># 1</span>\n</span><span id=\"__span-36-5\"><a id=\"__codelineno-36-5\" name=\"__codelineno-36-5\" href=\"#__codelineno-36-5\"></a><span class=\"n\">count_words</span><span class=\"p\">(</span><span class=\"s2\">"multiple spaces"</span><span class=\"p\">)</span> <span class=\"c1\"># 2</span>\n</span></code></pre></div>\n\n\n\n\n\n\n\n\n\n \n \n\n\n\n\n\n\n \n </article>\n </div>\n \n \n <script>var tabs=__md_get(\"__tabs\");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(\".tabbed-set\")){var labels=set.querySelector(\".tabbed-labels\");for(var tab of tabs)for(var label of labels.getElementsByTagName(\"label\"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>\n\n<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith(\"__tabbed_\"))</script>\n </div>\n \n <button type=\"button\" class=\"md-top md-icon\" data-md-component=\"top\" hidden>\n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-circle-arrow-up\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"m16 12-4-4-4 4M12 16V8\"/></svg>\n Back to top\n</button>\n \n </main>\n \n <footer class=\"md-footer\">\n \n \n \n <nav class=\"md-footer__inner md-grid\" aria-label=\"Footer\" >\n \n \n <a href=\"../../utils/performance/\" class=\"md-footer__link md-footer__link--prev\" aria-label=\"Previous: Performance\">\n <div class=\"md-footer__button md-icon\">\n \n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" class=\"lucide lucide-arrow-left\" viewBox=\"0 0 24 24\"><path d=\"m12 19-7-7 7-7M19 12H5\"/></svg>\n </div>\n <div class=\"md-footer__title\">\n <span class=\"md-footer__direction\">\n Previous\n </span>\n <div class=\"md-ellipsis\">\n Performance\n </div>\n </div>\n </a>\n \n \n </nav>\n \n \n <div class=\"md-footer-meta md-typeset\">\n <div class=\"md-footer-meta__inner md-grid\">\n <div class=\"md-copyright\">\n \n <div class=\"md-copyright__highlight\">\n Copyright © 2026 TINS PJ. All rights reserved.\n\n </div>\n \n \n Made with\n <a href=\"https://zensical.org/\" target=\"_blank\" rel=\"noopener\">\n Zensical\n </a>\n \n</div>\n \n </div>\n </div>\n</footer>\n \n </div>\n <div class=\"md-dialog\" data-md-component=\"dialog\">\n <div class=\"md-dialog__inner md-typeset\"></div>\n </div>\n \n \n \n \n \n <script id=\"__config\" type=\"application/json\">{\"annotate\":null,\"base\":\"../..\",\"features\":[\"announce.dismiss\",\"content.code.annotate\",\"content.code.copy\",\"content.code.select\",\"content.footnote.tooltips\",\"content.tabs.link\",\"content.tooltips\",\"navigation.footer\",\"navigation.indexes\",\"navigation.instant\",\"navigation.instant.prefetch\",\"navigation.path\",\"navigation.sections\",\"navigation.top\",\"navigation.tracking\",\"search.highlight\"],\"search\":\"../../assets/javascripts/workers/search.e2d2d235.min.js\",\"tags\":null,\"translations\":{\"clipboard.copied\":\"Copied to clipboard\",\"clipboard.copy\":\"Copy to clipboard\",\"search.result.more.one\":\"1 more on this page\",\"search.result.more.other\":\"# more on this page\",\"search.result.none\":\"No matching documents\",\"search.result.one\":\"1 matching document\",\"search.result.other\":\"# matching documents\",\"search.result.placeholder\":\"Type to start searching\",\"search.result.term.missing\":\"Missing\",\"select.version\":\"Select version\"},\"version\":null}</script>\n \n \n <script src=\"../../assets/javascripts/bundle.6e5f0216.min.js\"></script>\n \n \n </body>\n</html>",
|
|
3
|
+
"hash": 13675484727117734736
|
|
4
|
+
}
|