From a69577fcae87e3938a95aab0d96dc3615e0e56c2 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Wed, 30 Sep 2026 12:42:22 +0300 Subject: [PATCH 1/2] feat: list jwks-client and release-scope, with brand marks --- brand/build/projects.py | 2 ++ brand/build/symbols.py | 29 +++++++++++++++++++ brand/projects/jwks-client/lockup-dark.svg | 1 + brand/projects/jwks-client/lockup-light.svg | 1 + brand/projects/jwks-client/mark.svg | 1 + brand/projects/release-scope/lockup-dark.svg | 1 + brand/projects/release-scope/lockup-light.svg | 1 + brand/projects/release-scope/mark.svg | 1 + docs/index.md | 2 ++ profile/README.md | 2 ++ scripts/check_site_content.sh | 4 +-- tests/test_projects.py | 2 ++ 12 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 brand/projects/jwks-client/lockup-dark.svg create mode 100644 brand/projects/jwks-client/lockup-light.svg create mode 100644 brand/projects/jwks-client/mark.svg create mode 100644 brand/projects/release-scope/lockup-dark.svg create mode 100644 brand/projects/release-scope/lockup-light.svg create mode 100644 brand/projects/release-scope/mark.svg diff --git a/brand/build/projects.py b/brand/build/projects.py index 752b969..f11fdab 100644 --- a/brand/build/projects.py +++ b/brand/build/projects.py @@ -40,11 +40,13 @@ "faststream-redis-timers": lambda: sym.stopwatch(_CX, _CY, R), "faststream-concurrent-aiokafka": lambda: sym.lanes(_CX, _CY, R), "faststream-outbox": lambda: sym.outbox(_CX, _CY, R), + "jwks-client": lambda: sym.key(_CX, _CY, R), # utilities "db-retry": lambda: sym.db_retry(_CX, _CY, R), "eof-fixer": lambda: sym.eof_fixer(_CX, _CY, R), "semvertag": lambda: sym.tag(_CX, _CY, R), "compose2pod": lambda: sym.pod(_CX, _CY, R), + "release-scope": lambda: sym.scope(_CX, _CY, R), } diff --git a/brand/build/symbols.py b/brand/build/symbols.py index 9225b60..55e9b57 100644 --- a/brand/build/symbols.py +++ b/brand/build/symbols.py @@ -562,3 +562,32 @@ def rpc_arrow(cx: float, cy: float, r: float) -> str: f'stroke-width="{w:.1f}" stroke-linecap="round" stroke-linejoin="round"/>' ) return out + + +def key(cx: float, cy: float, r: float) -> str: + """jwks-client: a key, the signing key a JWKS publishes.""" + sw = r * 0.2 + bow_x = cx - 0.45 * r + shaft_x = bow_x + 0.32 * r + return ( + f'' + f'' + f'' + f'' + ) + + +def scope(cx: float, cy: float, r: float) -> str: + """release-scope: a magnifier over a list of pending changes.""" + lx, ly, lr = cx - 0.15 * r, cy - 0.15 * r, 0.55 * r + edge = lr / math.sqrt(2) + lines = "".join( + f'' + for dy, w in ((-0.2, 0.6), (0.0, 0.46), (0.2, 0.32)) + ) + return ( + f'' + f'' + lines + ) diff --git a/brand/projects/jwks-client/lockup-dark.svg b/brand/projects/jwks-client/lockup-dark.svg new file mode 100644 index 0000000..9c88543 --- /dev/null +++ b/brand/projects/jwks-client/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/jwks-client/lockup-light.svg b/brand/projects/jwks-client/lockup-light.svg new file mode 100644 index 0000000..6227bda --- /dev/null +++ b/brand/projects/jwks-client/lockup-light.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/jwks-client/mark.svg b/brand/projects/jwks-client/mark.svg new file mode 100644 index 0000000..315d616 --- /dev/null +++ b/brand/projects/jwks-client/mark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/release-scope/lockup-dark.svg b/brand/projects/release-scope/lockup-dark.svg new file mode 100644 index 0000000..6dc8306 --- /dev/null +++ b/brand/projects/release-scope/lockup-dark.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/release-scope/lockup-light.svg b/brand/projects/release-scope/lockup-light.svg new file mode 100644 index 0000000..ef9bf3b --- /dev/null +++ b/brand/projects/release-scope/lockup-light.svg @@ -0,0 +1 @@ + diff --git a/brand/projects/release-scope/mark.svg b/brand/projects/release-scope/mark.svg new file mode 100644 index 0000000..3be2459 --- /dev/null +++ b/brand/projects/release-scope/mark.svg @@ -0,0 +1 @@ + diff --git a/docs/index.md b/docs/index.md index 3f3edf4..81816e2 100644 --- a/docs/index.md +++ b/docs/index.md @@ -127,6 +127,7 @@ Every project is built with the same tooling - [`lite-bootstrap`](https://github.com/modern-python/lite-bootstrap) — lightweight package for bootstrapping new microservices. - [`httpware`](https://github.com/modern-python/httpware) — HTTP client framework with sync/async clients, middleware chain, and built-in resilience (retry, bulkhead). +- [`jwks-client`](https://github.com/modern-python/jwks-client) — async JWKS client for verifying JWTs, with key caching, resilient fetching, and Litestar and FastAPI integrations. - [`faststream-redis-timers`](https://github.com/modern-python/faststream-redis-timers) — FastStream broker integration for Redis-backed distributed timer scheduling. - [`faststream-concurrent-aiokafka`](https://github.com/modern-python/faststream-concurrent-aiokafka) — concurrent message processing middleware for FastStream with `aiokafka`. - [`faststream-outbox`](https://github.com/modern-python/faststream-outbox) — FastStream broker integration for the transactional outbox pattern with Postgres. @@ -136,6 +137,7 @@ Every project is built with the same tooling - [`compose2pod`](https://github.com/modern-python/compose2pod) — convert a Docker Compose file into a script that runs its services as a single Podman pod. - [`db-retry`](https://github.com/modern-python/db-retry) — retry helpers for database operations. - [`eof-fixer`](https://github.com/modern-python/eof-fixer) — automatically fix newlines at the end of files. +- [`release-scope`](https://github.com/modern-python/release-scope) — collect what sits between production and the default branch across GitLab services: tags, MRs, Jira keys, failed jobs. - [`semvertag`](https://github.com/modern-python/semvertag) — auto-tag your GitHub/GitLab repo with semantic version tags from CI.

Built with uv, diff --git a/profile/README.md b/profile/README.md index 0bc460c..5779085 100644 --- a/profile/README.md +++ b/profile/README.md @@ -49,6 +49,7 @@ Open-source templates and libraries for building production-ready Python applica |---|---|---|---| | [`lite-bootstrap`](https://github.com/modern-python/lite-bootstrap) | Lightweight bootstrap for production-ready Python microservices | [![Stars](https://img.shields.io/github/stars/modern-python/lite-bootstrap)](https://github.com/modern-python/lite-bootstrap/stargazers) | [![Downloads](https://static.pepy.tech/badge/lite-bootstrap/month)](https://pepy.tech/projects/lite-bootstrap) | | [`httpware`](https://github.com/modern-python/httpware) | Python HTTP client framework with sync & async clients and built-in resilience | [![Stars](https://img.shields.io/github/stars/modern-python/httpware)](https://github.com/modern-python/httpware/stargazers) | [![Downloads](https://static.pepy.tech/badge/httpware/month)](https://pepy.tech/projects/httpware) | +| [`jwks-client`](https://github.com/modern-python/jwks-client) | Async JWKS client for verifying JWTs, with key caching, resilient fetching, and Litestar and FastAPI integrations | [![Stars](https://img.shields.io/github/stars/modern-python/jwks-client)](https://github.com/modern-python/jwks-client/stargazers) | [![Downloads](https://static.pepy.tech/badge/jwks-client/month)](https://pepy.tech/projects/jwks-client) | | [`faststream-redis-timers`](https://github.com/modern-python/faststream-redis-timers) | FastStream integration for Redis-backed distributed timer scheduling | [![Stars](https://img.shields.io/github/stars/modern-python/faststream-redis-timers)](https://github.com/modern-python/faststream-redis-timers/stargazers) | [![Downloads](https://static.pepy.tech/badge/faststream-redis-timers/month)](https://pepy.tech/projects/faststream-redis-timers) | | [`faststream-concurrent-aiokafka`](https://github.com/modern-python/faststream-concurrent-aiokafka) | Concurrent message-processing middleware for FastStream + aiokafka | [![Stars](https://img.shields.io/github/stars/modern-python/faststream-concurrent-aiokafka)](https://github.com/modern-python/faststream-concurrent-aiokafka/stargazers) | [![Downloads](https://static.pepy.tech/badge/faststream-concurrent-aiokafka/month)](https://pepy.tech/projects/faststream-concurrent-aiokafka) | | [`faststream-outbox`](https://github.com/modern-python/faststream-outbox) | FastStream transactional-outbox integration backed by a Postgres table | [![Stars](https://img.shields.io/github/stars/modern-python/faststream-outbox)](https://github.com/modern-python/faststream-outbox/stargazers) | [![Downloads](https://static.pepy.tech/badge/faststream-outbox/month)](https://pepy.tech/projects/faststream-outbox) | @@ -60,6 +61,7 @@ Open-source templates and libraries for building production-ready Python applica | [`compose2pod`](https://github.com/modern-python/compose2pod) | Convert a Docker Compose file into a script that runs its services as a single Podman pod | [![Stars](https://img.shields.io/github/stars/modern-python/compose2pod)](https://github.com/modern-python/compose2pod/stargazers) | [![Downloads](https://static.pepy.tech/badge/compose2pod/month)](https://pepy.tech/projects/compose2pod) | | [`db-retry`](https://github.com/modern-python/db-retry) | Retry helpers for PostgreSQL / SQLAlchemy database operations | [![Stars](https://img.shields.io/github/stars/modern-python/db-retry)](https://github.com/modern-python/db-retry/stargazers) | [![Downloads](https://static.pepy.tech/badge/db-retry/month)](https://pepy.tech/projects/db-retry) | | [`eof-fixer`](https://github.com/modern-python/eof-fixer) | CLI tool that ensures text files end with exactly one newline | [![Stars](https://img.shields.io/github/stars/modern-python/eof-fixer)](https://github.com/modern-python/eof-fixer/stargazers) | [![Downloads](https://static.pepy.tech/badge/eof-fixer/month)](https://pepy.tech/projects/eof-fixer) | +| [`release-scope`](https://github.com/modern-python/release-scope) | Collect what sits between production and the default branch across GitLab services: tags, MRs, Jira keys, failed jobs | [![Stars](https://img.shields.io/github/stars/modern-python/release-scope)](https://github.com/modern-python/release-scope/stargazers) | [![Downloads](https://static.pepy.tech/badge/release-scope/month)](https://pepy.tech/projects/release-scope) | | [`semvertag`](https://github.com/modern-python/semvertag) | Auto-tag GitHub & GitLab repos with semantic version tags from CI | [![Stars](https://img.shields.io/github/stars/modern-python/semvertag)](https://github.com/modern-python/semvertag/stargazers) | [![Downloads](https://static.pepy.tech/badge/semvertag/month)](https://pepy.tech/projects/semvertag) | ### Support diff --git a/scripts/check_site_content.sh b/scripts/check_site_content.sh index 8ec16dd..68fbcd5 100755 --- a/scripts/check_site_content.sh +++ b/scripts/check_site_content.sh @@ -9,9 +9,9 @@ REPOS=( fastapi-sqlalchemy-template litestar-sqlalchemy-template modern-di modern-di-fastapi modern-di-litestar modern-di-faststream modern-di-typer modern-di-pytest that-depends - lite-bootstrap httpware faststream-redis-timers + lite-bootstrap httpware jwks-client faststream-redis-timers faststream-concurrent-aiokafka faststream-outbox - db-retry eof-fixer semvertag + db-retry eof-fixer release-scope semvertag ) missing=0 diff --git a/tests/test_projects.py b/tests/test_projects.py index 583a2bb..bee515e 100644 --- a/tests/test_projects.py +++ b/tests/test_projects.py @@ -45,6 +45,8 @@ def test_project_frame_parses_and_uses_tokens() -> None: "modern-di-taskiq", "modern-di-flask", "modern-di-grpc", + "jwks-client", + "release-scope", } From 0c2c38e87e2dae6033934a792ec1df095fe42dd2 Mon Sep 17 00:00:00 2001 From: Artur Shiriev Date: Wed, 30 Sep 2026 12:44:01 +0300 Subject: [PATCH 2/2] feat: render PNG marks and lockups for jwks-client and release-scope --- brand/projects/jwks-client/lockup.png | Bin 0 -> 1426 bytes brand/projects/jwks-client/mark-1024.png | Bin 0 -> 6061 bytes brand/projects/jwks-client/mark-512.png | Bin 0 -> 2385 bytes brand/projects/release-scope/lockup.png | Bin 0 -> 1757 bytes brand/projects/release-scope/mark-1024.png | Bin 0 -> 7824 bytes brand/projects/release-scope/mark-512.png | Bin 0 -> 3337 bytes 6 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 brand/projects/jwks-client/lockup.png create mode 100644 brand/projects/jwks-client/mark-1024.png create mode 100644 brand/projects/jwks-client/mark-512.png create mode 100644 brand/projects/release-scope/lockup.png create mode 100644 brand/projects/release-scope/mark-1024.png create mode 100644 brand/projects/release-scope/mark-512.png diff --git a/brand/projects/jwks-client/lockup.png b/brand/projects/jwks-client/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..9bacd1b77b27fd6121ab9c713d1b28ec7daf5931 GIT binary patch literal 1426 zcmZWpdonARY5 zMv+G}X{4B08zav&veOcIm4=FJXgzk?bN1}%>^=9~&*yXRJ@?$dKAA_{52z~ZDFXmh z2?w1?0KiZ(9-s)9)iWKVcV$33LL|G$&@#kRlnE?@NndLS$s&X#>-`Nwj3`KQbHmWVe*RbuYUrt<@|`1y!u3)5XO5wK~0Jfq^58N^9b=mnjmpJJp_0GtMpNiawz zs*%XF!s`ae6l|0sd;kB&fX!{V1Bj+Y2`aRNrn7*!e+w`dAOy$=7z95Fy1`c&h-Wuw z<#%Ls=S=y6_UIJ~v^Xb}-_u4zF?HGD?XR?mV-1z*riV@;Ty3nDsH}1iV_&%njyXe( zJwb0CMPKo~*~cHTDLFKmhGtK zYhni)*?5P@@BfndVkA)f_HeHmYTUbmQ*$nivnuLQ))CH0x?WGNgKoRHyps9STK!;_ z=Y4iP%-S)E^`&x>KYV)hgua_w9pfFMZ4D}JrC{Q>ySoYACRuA_7-&UK2%%frS+Vgn z{VjpJ$AgU>`l$mJg&B0BaW0;nUxk@kZF}lCd)O!{)gcypW+&$CZg!cNw|hVPqMpa; zVW0hyPObn7&MB4q(mF=Ce6Ze{YJf_+7wLVomyBMS8XmilXod2INi%b5%ZIoS%~l^2%)eDqLX` zc1Rz}VSQ++RUa&`T~ZOSKjP*!Y<(VGdVs0^kr+BC4QHe95)`#dZ3Gtt$ennK~u^iEku=yUx^^&>xEITa1=7V z+q^Pk4)@4U(>GTN$&rjw_(dshbXY;{ab8v5!2!ZE5mLL+lyGZMuFdBWi2{06v5B)0 zCi`eQ_vOpoqqF+?nK6i0ms8)Vcl^0+p+)T7kpW4r&cODj5YXh<{PSv1%c<9%n7#Kz zOfJZ6|GB}_CeFlTJGH_NNT2?>DFG#j3 zioccRt!enlvZxhCvTk}hkYYJ=Tn{S_^CQ_fT*Tp>79%j~8teXy#kodTJ7mWOf|zW* z^~r_D&Ar?qGW4XlRooZX+Wy$vFBF#Fms6HZFK_mNv9lBGU~Pv+-s7bp|I@my!t?%u z)jZ9q>4k28@`{6G-%;{Z$p;TsxR;jn*qK5rwIGJeUuas?n{;)UQ^T7cby&XdzpnA0 zg&1Hu-PV)^TJw2TqNll}4NJ&e{#%CuZ1pfDOr>%N#=(C5?kc=W_@fIxh}Z#SL2z+* Ju63lP{0*EJZ-@W@ literal 0 HcmV?d00001 diff --git a/brand/projects/jwks-client/mark-1024.png b/brand/projects/jwks-client/mark-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..888b0f7d56ee7a3f4fda6f0445362758150ef496 GIT binary patch literal 6061 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 literal 0 HcmV?d00001 diff --git a/brand/projects/jwks-client/mark-512.png b/brand/projects/jwks-client/mark-512.png new file mode 100644 index 0000000000000000000000000000000000000000..d4911c7ca2508def3f367c287980e607d556f2fb GIT binary patch literal 2385 zcmdT`ZA?>V6h8O1(5`$G1ex0Mv4M*dP!ttq6*>VCrj$Wdq9SERVXV+1A`qaxItL0{ zz%dYEhU&(LLtv8WL#1Si}GTi=a*ZVF0Lci2|Ksr0W$fw~ZtS-OLX#@|_%59UJx_8&(MUcaFj8 z55sTg%!$T%RZN&snG<8fjMjufbv2L}v=qXs*f5eb>hE(gE>|E}78z+w^=F(`-Y_w$ zP6xt5!hs-cZM`{ngX#iAdGdG~1*I1ucd2x<-@=qHSAPva$AbLd<)?N(S3cWcx(z;g z-{mmk=XUR4n}RIpDA@g0(4HH1f%CE(6(@=3pVn=sUUMqh__<5aoc&av{xV}*3p2%` z!Qwu-S1Kv9u4>FSeB;15vQ^ihvQewZGb8IieKhr9)EVFP`EnW-%tXty=ik(iHXZSq zc%t$_@|E`RSUGn~|0&YFK0^hgmlMl@(;Hu{Z)61~%*sc+GMAz1h1ibzdmI#6zi3F; z`cb%bnFe+$fV!TDSgM|Og=Af=#stqSlzM_M=e1s6={k{NNMBQ8}H~|#{D?neV z^F}fc{70KULXP%1VlNB`UG@JY>5$@3PptRrTpIi}R`p0-Q%lQCE-5`8OmGy0*A_n= zm1~I|EY_2TLc`kRJPk=IO9ac zCehei%I{5Ksi~OgC+oLUfNv)If#|W$r^)UUrPfw7Sv#?F9di? zKs_NLF;R21E!PjZYWTT7d*^NkOYTdiKUfhqE8qyZ$rk#3ZD@F~WXZVrE5{tFIu5$G z5_~s!Hhobu)$5q+1GUG?az!;{(iof@&a%G6RC#>x`1}CSoA#PRzp;Ec&0bCfzGUF` zX#_vN2N6%iLYzEvw&8;QCMu2x-axgY+zhWnY&q8KMaH9tZpPaobTPI8tr%>B?*7Uh z(BUkITV^RsynZzIwFRB~3+=!QX=N8RE^ z)YY+vzHr4v+$UFSyP$SH)Z~%0JW5jflW=Rez>uwz9KpLHiCwnXGc?ukC{H)9xaXsW z1&F#E`gBUw*virCXe|S3cogMX5#&9*u`ex7`jn2l!>r-)z2#Qgfp+^+cN(6@xE5V9 znD*sRT1nPOtI!9&uU~@ICn1~#rhxpu%%! z-TqxRaAM%m#rkiFJ_*|r_)LK&#jIpER4u{>8g_Pcp`o5w;+0Edz-@#I<@i3RHfbFR zZbw30F*zNx#&#gu02t0n2;Z^-?y?cSJJ!7KF_@PA;UWIkfqw?<=9aG@ws(ysR*}UD zygbwKUP0=p#-eY%cjX%GN#5cp+GdBFIi+l%M_eX<+!K+ayec3R6Of?hi%V{OTXKK- euPua2(1R%5ak_*R^ZNR^4Fv^+_+Qu{IQ$EJ!*>q= literal 0 HcmV?d00001 diff --git a/brand/projects/release-scope/lockup.png b/brand/projects/release-scope/lockup.png new file mode 100644 index 0000000000000000000000000000000000000000..ab2e7edbf011e824f8cd0e5e7e242b07bffcd392 GIT binary patch literal 1757 zcmZWqdpr{i7am@B5^_n&5>nXoE`5cm)tFyd}h714zkaxM{hyVaY zphAq55);<5+}T}W3vh#ZItjZ)sCzFNU=f1oBMC9WJQN|s!ZZto3#I;aKracezNf7|3XEkpDSd*>j+m5z@FgV z-FM+IBPE9FP`CjDF8Z5nLVo|2Hhj$Z=k=a}lRxryeLonFvOhp`np&r9Df zpNG?@^9a@icT={zX~g`fx$jkueIH1R_x2Wc@jz4=mZspN?*gy7t*pyT>Zrgs>-mkW zJ@V;k*e@t=JIS_o`#Yf_vNK{&6@o+e=FJb?Ry5w|H#HNo^b!Mh#Yet)1?5W_hSo*2 zD|O75#98H3n6Y0tL&~)#BlB;-p%ZsLt7~D9^rseMA1R0ct9<$?IX`--&M_o%nkd@2(L0 z$R|tI5xfln?T{QXu{4&w-7{JEIIKrK>G$=shQ7A+&M#^WHmW(gn%`y7HG--~^`kfJ z+0oxUvDqT-3-#E*No5k(fM_E!9LZg>dEYb_v_?X_{Mo6 zYdHzt(Qq!eH@gBTgR?{+F5Z{M7`IsTTmifr@Ud~gNHPL# z*>f$YD55uthB7*mT5*Ccem|arhdl7CCrL@FhkW3l2z9BD2tP8 z=P@v?f4ZtC({!CAygR5{N&`f2V#&>uHa8)7dKJ8THYkOU7{je5I+87*<4ciN^&c(NCan zB)ow~-nu%-ZqHhioMsi`^Vd;Ry1$cdKMhk#d5s3weh?=uAwQo#Nt&`6Eg%i<=*1D! zht!C7sn8AFIH&P+T^-B^TG06ETEZaSP<4Dx?B;7;Q)ZmfoDEHV6h%LZ#o}Aq8MfVi zV2Bc=cY)Pf8M|HlOi%p&*y<9|0HYY4p6yUwqk$y6wB;C$P!zAcrNTdC$Eb(25Q;;U z=3umIP`y~))d;TdzZj)v;GiNdRqw&BLPP!#0!)rH;?+_lp9_{E*_x+Hbw3ST(>e)} z9wyTP(hk|5il46%)t(qDkUokYc~W}3C^z=yO9<&NUX9`9_Se@>%_7o0=a0>=GPC8= zHcLVue1ulk{^tIEGmz3rG2}|;|FJ#1Pe_PB8lyWvt@9>y9_)d#30-$!BuQeO#k?n8 zqd0dTji50uo$2`A4KjnGP|FMWfs!{$s@_Kq1PKIwpw4Z6FbLz+y4Mp;_=;N(e*S$z z;^|QR^0W%Gs{$PEJIe`fYBl*~xw1b!H}#hT-zh!1h|fI1^f^InPmA}^zHsh4yPbvKL<3G4KxjNQ41f={I^36?- literal 0 HcmV?d00001 diff --git a/brand/projects/release-scope/mark-1024.png b/brand/projects/release-scope/mark-1024.png new file mode 100644 index 0000000000000000000000000000000000000000..b3d694643d291596c46e5309be0739a854366b5c GIT binary patch literal 7824 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