<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>归档 on kutake小站</title><link>https://www.kutake.top/archives/</link><description>Recent content in 归档 on kutake小站</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Wed, 14 Oct 2026 04:21:21 +0800</lastBuildDate><atom:link href="https://www.kutake.top/archives/index.xml" rel="self" type="application/rss+xml"/><item><title>把 WordPress 博客搬进 Hugo：迁移、构建与发布全记录</title><link>https://www.kutake.top/archives/wordpress-to-hugo/</link><pubDate>Wed, 14 Oct 2026 04:21:21 +0800</pubDate><guid>https://www.kutake.top/archives/wordpress-to-hugo/</guid><description>&lt;p&gt;这个博客原来跑在 WordPress 上。前几天我把它整个搬到了 Hugo，静态托管在 Cloudflare
Pages 上，顺手把「写文章」这件事也重新做了一遍。这篇算是迁移完成后的第一篇，把整条流水线
从头到尾记一遍：数据怎么搬、Hugo 怎么构建、文章怎么写、发布怎么做，以及中间踩过的坑。&lt;/p&gt;</description></item><item><title>在有共同字段下的pydantic类转换不正确问题</title><link>https://www.kutake.top/archives/%E5%9C%A8%E6%9C%89%E5%85%B1%E5%90%8C%E5%AD%97%E6%AE%B5%E4%B8%8B%E7%9A%84pydantic%E7%B1%BB%E8%BD%AC%E6%8D%A2%E4%B8%8D%E6%AD%A3%E7%A1%AE%E9%97%AE%E9%A2%98/</link><pubDate>Sat, 10 Feb 2024 16:15:40 +0800</pubDate><guid>https://www.kutake.top/archives/%E5%9C%A8%E6%9C%89%E5%85%B1%E5%90%8C%E5%AD%97%E6%AE%B5%E4%B8%8B%E7%9A%84pydantic%E7%B1%BB%E8%BD%AC%E6%8D%A2%E4%B8%8D%E6%AD%A3%E7%A1%AE%E9%97%AE%E9%A2%98/</guid><description>&lt;p&gt;在使用 Pydantic 进行数据验证和设置时，你可能会遇到一个问题：当多个类有共同字段时，Pydantic 可能无法正确地区分这些类。让我通过一个简单的例子来解释这个问题。&lt;/p&gt;</description></item><item><title>基于Route来解决playwright的静态HTML资源加载问题</title><link>https://www.kutake.top/archives/%E5%9F%BA%E4%BA%8Eroute%E6%9D%A5%E8%A7%A3%E5%86%B3playwright%E7%9A%84%E9%9D%99%E6%80%81html%E8%B5%84%E6%BA%90%E5%8A%A0%E8%BD%BD%E9%97%AE%E9%A2%98/</link><pubDate>Sat, 10 Feb 2024 16:14:14 +0800</pubDate><guid>https://www.kutake.top/archives/%E5%9F%BA%E4%BA%8Eroute%E6%9D%A5%E8%A7%A3%E5%86%B3playwright%E7%9A%84%E9%9D%99%E6%80%81html%E8%B5%84%E6%BA%90%E5%8A%A0%E8%BD%BD%E9%97%AE%E9%A2%98/</guid><description>&lt;h2 id="前因"&gt;前因&lt;/h2&gt;
&lt;p&gt;由于python中没有方便快捷生成美观图片的方案，所以我使用了jinja2模板生成html后交给playwright生成网页图片，这其中，图片资源可以使用base64格式解决，而字体加载就难了。&lt;/p&gt;</description></item><item><title>使用Github Workflows构建Tauri应用</title><link>https://www.kutake.top/archives/%E4%BD%BF%E7%94%A8github-workflows%E6%9E%84%E5%BB%BAtauri%E5%BA%94%E7%94%A8/</link><pubDate>Thu, 28 Dec 2023 21:04:15 +0800</pubDate><guid>https://www.kutake.top/archives/%E4%BD%BF%E7%94%A8github-workflows%E6%9E%84%E5%BB%BAtauri%E5%BA%94%E7%94%A8/</guid><description>&lt;p&gt;下面这个例子是，当release分支有commit发生时，自动获取当前应用的版本信息，并使用缓存，分别构建前端和rust，并将构建好的包上传至指定tag的release上。在 &lt;code&gt;platform&lt;/code&gt;处定义平台，这里我只选定了Win&lt;/p&gt;</description></item><item><title>[Tauri]Uint8Array与 Vec&lt;u8&gt;的坑</title><link>https://www.kutake.top/archives/tauriuint8array%E4%B8%8E-vec%E7%9A%84%E5%9D%91/</link><pubDate>Thu, 28 Dec 2023 20:44:38 +0800</pubDate><guid>https://www.kutake.top/archives/tauriuint8array%E4%B8%8E-vec%E7%9A%84%E5%9D%91/</guid><description>&lt;h2 id="问题"&gt;问题&lt;/h2&gt;
&lt;p&gt;当尝试传递 &lt;code&gt;Uint8Array&lt;/code&gt;类型的图片数据给rust后端时，会发生 &lt;code&gt;invalid type: map, expected a sequence&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;原因在于，tauri将 &lt;code&gt;Uint8Array&lt;/code&gt;是作为对象而不是一个 &lt;code&gt;Vec&lt;/code&gt;，要接受它，需要使用 &lt;code&gt;HashMap&amp;lt;String, u8&amp;gt;&lt;/code&gt;来接收。&lt;/p&gt;</description></item><item><title>Tokio异步task控制并发数量</title><link>https://www.kutake.top/archives/tokio%E5%BC%82%E6%AD%A5task%E6%8E%A7%E5%88%B6%E5%B9%B6%E5%8F%91%E6%95%B0%E9%87%8F/</link><pubDate>Thu, 28 Dec 2023 20:30:29 +0800</pubDate><guid>https://www.kutake.top/archives/tokio%E5%BC%82%E6%AD%A5task%E6%8E%A7%E5%88%B6%E5%B9%B6%E5%8F%91%E6%95%B0%E9%87%8F/</guid><description>&lt;h3 id="使用tokiosyncsemaphore"&gt;使用tokio::sync::Semaphore&lt;/h3&gt;
&lt;p&gt;信号量可以保证在某一时刻最多运行指定数量的并发任务。&lt;/p&gt;
&lt;p&gt;使用信号量时，需在初始化时指定信号灯(tokio中的SemaphorePermit)的数量，每当任务要执行时，将从中取走一个信号灯，当任务完成时(信号灯被drop)会归还信号灯。当某个任务要执行时，如果此时信号灯数量为0，则该任务将等待，直到有信号灯被归还。因此，信号量通常用来提供类似于限量的功能。&lt;/p&gt;</description></item><item><title>Tauri 调用终端api</title><link>https://www.kutake.top/archives/tauri-%E8%B0%83%E7%94%A8%E7%BB%88%E7%AB%AFapi/</link><pubDate>Wed, 29 Nov 2023 22:25:50 +0800</pubDate><guid>https://www.kutake.top/archives/tauri-%E8%B0%83%E7%94%A8%E7%BB%88%E7%AB%AFapi/</guid><description>&lt;p&gt;当你想从Tauri调用终端并运行类似 &lt;code&gt;ls&lt;/code&gt;的命令的话，需要使用 &lt;code&gt;@tauri-apps/api/shell&lt;/code&gt;的api，步骤如下&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;编辑 &lt;code&gt;tauri.conf.json&lt;/code&gt;下的 &lt;code&gt;tauri.allowlist.shell&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tauri&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;allowlist&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;shell&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;all&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// enable all shell APIs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;execute&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// enable process spawn APIs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sidecar&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// enable spawning sidecars
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;open&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="c1"&gt;// enable opening files/URLs using the default program
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;其他api暂时不讨论，只说 &lt;code&gt;execute&lt;/code&gt;，假设我们需要使用git命令（案例来自官网）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;编辑 &lt;code&gt;scope&lt;/code&gt;定义好需要用到的命令，要是没有定义则无法调用&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;scope&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;run-git-commit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;cmd&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;git&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;commit&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;-m&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nt"&gt;&amp;#34;validator&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;\\S+&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开始调用该命令&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Command&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@tauri-apps/api/shell&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;run-git-commit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;commit&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;-m&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;the commit message&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;std&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;std&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stderr&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;std&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;std&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;std&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;你可以将 &lt;code&gt;args&lt;/code&gt;设置为 &lt;code&gt;true&lt;/code&gt;来使js端可以传入任意参数&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Tauri 文件访问api</title><link>https://www.kutake.top/archives/tauri-%E6%96%87%E4%BB%B6%E8%AE%BF%E9%97%AEapi/</link><pubDate>Wed, 29 Nov 2023 22:07:56 +0800</pubDate><guid>https://www.kutake.top/archives/tauri-%E6%96%87%E4%BB%B6%E8%AE%BF%E9%97%AEapi/</guid><description>&lt;p&gt;tauri支持从&lt;a href="https://tauri.app/zh-cn/v1/api/js/path#appconfigdir"&gt;&lt;code&gt;$APPCONFIG&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#appdatadir"&gt;&lt;code&gt;$APPDATA&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#applocaldatadir"&gt;&lt;code&gt;$APPLOCALDATA&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#appcachedir"&gt;&lt;code&gt;$APPCACHE&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#applogdir"&gt;&lt;code&gt;$APPLOG&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#audiodir"&gt;&lt;code&gt;$AUDIO&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#cachedir"&gt;&lt;code&gt;$CACHE&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#configdir"&gt;&lt;code&gt;$CONFIG&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#datadir"&gt;&lt;code&gt;$DATA&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#localdatadir"&gt;&lt;code&gt;$LOCALDATA&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#desktopdir"&gt;&lt;code&gt;$DESKTOP&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#documentdir"&gt;&lt;code&gt;$DOCUMENT&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#downloaddir"&gt;&lt;code&gt;$DOWNLOAD&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#executabledir"&gt;&lt;code&gt;$EXE&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#fontdir"&gt;&lt;code&gt;$FONT&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#homedir"&gt;&lt;code&gt;$HOME&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#picturedir"&gt;&lt;code&gt;$PICTURE&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#publicdir"&gt;&lt;code&gt;$PUBLIC&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#runtimedir"&gt;&lt;code&gt;$RUNTIME&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#templatedir"&gt;&lt;code&gt;$TEMPLATE&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#videodir"&gt;&lt;code&gt;$VIDEO&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#resourcedir"&gt;&lt;code&gt;$RESOURCE&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#appdir"&gt;&lt;code&gt;$APP&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/path#logdir"&gt;&lt;code&gt;$LOG&lt;/code&gt;&lt;/a&gt;, &lt;a href="https://tauri.app/zh-cn/v1/api/js/os#tempdir"&gt;&lt;code&gt;$TEMP&lt;/code&gt;&lt;/a&gt; 访问并读或文件夹和文件，具体措施如下&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;编辑 &lt;code&gt;tauri.conf.json&lt;/code&gt;内的&lt;a href="https://tauri.app/v1/api/config/#allowlistconfig.fs"&gt;&lt;code&gt;tauri.allowlist.fs&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tauri&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;allowlist&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;fs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;all&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// enable all FS APIs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;readFile&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;writeFile&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;readDir&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;copyFile&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;createDir&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;removeDir&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;removeFile&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;renameFile&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;exists&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;可以直接 &lt;code&gt;all: true&lt;/code&gt; 来开放所有tauri文件api，也可以单独开放某个api&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;编辑 &lt;code&gt;scope&lt;/code&gt;开放具体访问权限&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;tauri&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;allowlist&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;fs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;scope&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;$APPDATA/img/*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意，这里开放了 &lt;code&gt;$APPDATA&lt;/code&gt;下的 &lt;code&gt;database&lt;/code&gt;访问权限，这样可以阻止程序访问任何路径，除了 &lt;code&gt;database&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;从js中访问&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;readBinaryFile&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;BaseDirectory&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;@tauri-apps/api/fs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 可以是任何api
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// Read the image file in the `$APPDATA/avatar.png` path
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;readBinaryFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;img/avatar.png&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AppData&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 注意！一定要加上BaseDirectory.AppData
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;开放了哪个目录权限，就用 &lt;code&gt;dir: BaseDirectory&lt;/code&gt;来指定访问路径，至少用绝对路径访问的方法我还没有找到，当然，这种相对路径访问的方式更加安全&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>从创建项目到测试打包上传Pypi</title><link>https://www.kutake.top/archives/%E4%BB%8E%E5%88%9B%E5%BB%BA%E9%A1%B9%E7%9B%AE%E5%88%B0%E6%B5%8B%E8%AF%95%E6%89%93%E5%8C%85%E4%B8%8A%E4%BC%A0pypi/</link><pubDate>Mon, 30 Oct 2023 20:16:30 +0800</pubDate><guid>https://www.kutake.top/archives/%E4%BB%8E%E5%88%9B%E5%BB%BA%E9%A1%B9%E7%9B%AE%E5%88%B0%E6%B5%8B%E8%AF%95%E6%89%93%E5%8C%85%E4%B8%8A%E4%BC%A0pypi/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;这是一次从创建项目到测试打包上传Pypi的过程，记录一下。&lt;/p&gt;
&lt;h2 id="创建项目"&gt;创建项目&lt;/h2&gt;
&lt;p&gt;这里我是用的是&lt;code&gt;pdm&lt;/code&gt;这个包管理工具，创建项目的命令是&lt;code&gt;pdm init&lt;/code&gt;，跟着引导一步步走，之后会生成一个&lt;code&gt;pyproject.toml&lt;/code&gt;文件，里面有项目的一些基本信息，比如作者、版本号等。下面是一个示例：&lt;/p&gt;</description></item><item><title>更优雅的包可用性检测</title><link>https://www.kutake.top/archives/%E6%9B%B4%E4%BC%98%E9%9B%85%E7%9A%84%E5%8C%85%E5%8F%AF%E7%94%A8%E6%80%A7%E6%A3%80%E6%B5%8B/</link><pubDate>Sun, 06 Aug 2023 03:32:54 +0800</pubDate><guid>https://www.kutake.top/archives/%E6%9B%B4%E4%BC%98%E9%9B%85%E7%9A%84%E5%8C%85%E5%8F%AF%E7%94%A8%E6%80%A7%E6%A3%80%E6%B5%8B/</guid><description>&lt;h2 id="一般"&gt;一般&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;ImportError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;numpy is not installed&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="更推荐"&gt;更推荐&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;importlib.util&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;find_spec&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;find_spec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;numpy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;numpy is installed&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;numpy is not installed&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Rich 使用PY在终端上展示富文本界面</title><link>https://www.kutake.top/archives/rich-%E4%BD%BF%E7%94%A8py%E5%9C%A8%E7%BB%88%E7%AB%AF%E4%B8%8A%E5%B1%95%E7%A4%BA%E5%AF%8C%E6%96%87%E6%9C%AC%E7%95%8C%E9%9D%A2/</link><pubDate>Fri, 28 Jul 2023 02:15:54 +0800</pubDate><guid>https://www.kutake.top/archives/rich-%E4%BD%BF%E7%94%A8py%E5%9C%A8%E7%BB%88%E7%AB%AF%E4%B8%8A%E5%B1%95%E7%A4%BA%E5%AF%8C%E6%96%87%E6%9C%AC%E7%95%8C%E9%9D%A2/</guid><description>&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;rich&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# PDM&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pdm&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;rich&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://rich.readthedocs.io/en/latest/introduction.html"&gt;文档&lt;/a&gt; &amp;amp; &lt;a href="https://github.com/Textualize/rich"&gt;源码&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="基础"&gt;基础&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rich&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nb"&gt;print&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Hello World&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Rich功能非常丰富，从日志处理到富文本显示甚至动态的终端界面。&lt;/p&gt;
&lt;p&gt;要使用Rich用做界面的话，一般是这样的：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rich.console&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rich.layout&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Layout&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;rich.panel&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;console&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;panel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Panel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;panel_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;layout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;panel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;layout_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;界面&lt;code&gt;Layout&lt;/code&gt;和面板&lt;code&gt;Panel&lt;/code&gt;是经常要用到的东西，&lt;code&gt;Layout&lt;/code&gt;作为界面布局，&lt;code&gt;Panel&lt;/code&gt;内展示元素并风格化，比如经常使用的表格&lt;code&gt;Table&lt;/code&gt;；要实现动态变化而不是print需要用到&lt;code&gt;Live&lt;/code&gt;。&lt;/p&gt;</description></item><item><title>一个PY多数据源的统一入口思路</title><link>https://www.kutake.top/archives/%E4%B8%80%E4%B8%AApy%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90%E7%9A%84%E7%BB%9F%E4%B8%80%E5%85%A5%E5%8F%A3%E6%80%9D%E8%B7%AF/</link><pubDate>Fri, 21 Apr 2023 22:41:27 +0800</pubDate><guid>https://www.kutake.top/archives/%E4%B8%80%E4%B8%AApy%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90%E7%9A%84%E7%BB%9F%E4%B8%80%E5%85%A5%E5%8F%A3%E6%80%9D%E8%B7%AF/</guid><description>&lt;h2 id="需求"&gt;需求&lt;/h2&gt;
&lt;p&gt;以我的bot来说：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Bot:
├─config
├─core
├─modules
│ ├─required
│ │ ├─BotManager
│ │ ├─BotStatus
│ │ ├─ExceptionCatch
│ │ ├─...
│ └─self
│ ├─Modules1
│ ├─Modules2
│ ├─...
├─resources
├─service
└─utils
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;模块统一放在&lt;code&gt;modules&lt;/code&gt;下，&lt;code&gt;required&lt;/code&gt;是bot运行必须的模块，&lt;code&gt;self&lt;/code&gt;是可卸载安装的模块。&lt;/p&gt;</description></item><item><title>Redis持久化策略</title><link>https://www.kutake.top/archives/redis%E6%8C%81%E4%B9%85%E5%8C%96%E7%AD%96%E7%95%A5/</link><pubDate>Fri, 14 Apr 2023 15:35:44 +0800</pubDate><guid>https://www.kutake.top/archives/redis%E6%8C%81%E4%B9%85%E5%8C%96%E7%AD%96%E7%95%A5/</guid><description>&lt;p&gt;Redis是一种高性能的内存数据库，它支持多种数据结构，如字符串、列表、集合、散列、有序集合等。Redis的优点是速度快，操作简单，功能丰富，但是它也有一个缺点，就是数据都存储在内存中，一旦服务器宕机或者重启，数据就会丢失。为了解决这个问题，Redis提供了两种持久化机制，分别是RDB（快照）和AOF（追加文件）。&lt;/p&gt;</description></item><item><title>docker多阶段构建</title><link>https://www.kutake.top/archives/docker%E5%A4%9A%E9%98%B6%E6%AE%B5%E6%9E%84%E5%BB%BA/</link><pubDate>Sat, 11 Mar 2023 10:11:37 +0800</pubDate><guid>https://www.kutake.top/archives/docker%E5%A4%9A%E9%98%B6%E6%AE%B5%E6%9E%84%E5%BB%BA/</guid><description>&lt;h2 id="非多阶段"&gt;非多阶段&lt;/h2&gt;
&lt;p&gt;以node项目为例：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-dockerfile" data-lang="dockerfile"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;alpine&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; mkdir -p /opt/app&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/opt/app&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; package.json package-lock.json ./&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; apk add --no-cache --update nodejs npm&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; apk add --no-cache &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; gcc &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; g++ &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;python3&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3.10.10-r0 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;make&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4.3-r1 &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; pkgconf &lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;COPY&lt;/span&gt; . .&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;RUN&lt;/span&gt; npm install --production&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;8080&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;CMD&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;main.js&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;这样虽然可以使用，但是很多依赖是生产环境下不需要受用的，比如build阶段的&lt;code&gt;gcc&lt;/code&gt;以及&lt;code&gt;npm&lt;/code&gt;等等&lt;/p&gt;</description></item><item><title>sqlalchemy&amp;sqlmodel的commit后数据丢失问题</title><link>https://www.kutake.top/archives/sqlalchemysqlmodel%E7%9A%84commit%E5%90%8E%E6%95%B0%E6%8D%AE%E4%B8%A2%E5%A4%B1%E9%97%AE%E9%A2%98/</link><pubDate>Sat, 11 Mar 2023 01:50:07 +0800</pubDate><guid>https://www.kutake.top/archives/sqlalchemysqlmodel%E7%9A%84commit%E5%90%8E%E6%95%B0%E6%8D%AE%E4%B8%A2%E5%A4%B1%E9%97%AE%E9%A2%98/</guid><description>&lt;h2 id="描述"&gt;描述&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# name=user,age=18, ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# empty&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="原因"&gt;原因&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;sqlalchemy&lt;/code&gt;为了保持&lt;code&gt;session&lt;/code&gt;内的数据同步，默认了&lt;code&gt;expire_on_commit&lt;/code&gt;为&lt;code&gt;True&lt;/code&gt;，它表现在：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 查询&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 更改数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;user_b&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# commit后再次访问，其实是重新进行了select操作&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# user_b&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;expire_on_commit&lt;/code&gt;可以用来更改 SQLAlchemy 的对象刷新机制，默认值为&lt;code&gt;True&lt;/code&gt;即在&lt;code&gt;session&lt;/code&gt;调用&lt;code&gt;commit&lt;/code&gt;之后会主动将同一个&lt;code&gt;session&lt;/code&gt;在&lt;code&gt;commit&lt;/code&gt;之前查询得到的 ORM 对象的&lt;code&gt;_sa_instance_state.expire&lt;/code&gt;属性设置为&lt;code&gt;Flase&lt;/code&gt;，再次读取该对象属性时将重载这个对象，方法是重新调用之前的查询语句。&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>sqlmodel单与多数据库连接</title><link>https://www.kutake.top/archives/sqlmodel%E5%8D%95%E4%B8%8E%E5%A4%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5/</link><pubDate>Sat, 11 Mar 2023 01:48:02 +0800</pubDate><guid>https://www.kutake.top/archives/sqlmodel%E5%8D%95%E4%B8%8E%E5%A4%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E8%BF%9E%E6%8E%A5/</guid><description>&lt;h2 id="连接单个数据库"&gt;连接单个数据库&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlmodel&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SQLModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hero&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SQLModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;secret_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 连接&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sqlite:///database.db&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 建表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;SQLModel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="连接多个数据库"&gt;连接多个数据库&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlmodel&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SQLModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlmodel.main&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 表1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;table1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hero1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SQLModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;table1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;secret_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 表2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;table2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hero2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SQLModel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;table2&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;secret_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 连接1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;engine1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sqlite:///database1.db&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 连接2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;engine2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sqlite:///database2.db&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 建表1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Hero1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;engine1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 建表2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Hero2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;engine2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="一点优化"&gt;一点优化&lt;/h2&gt;
&lt;p&gt;显然这样建多表会很麻烦，一种优化方案是：&lt;/p&gt;</description></item><item><title>sqlalchemy异步与同步方式获取自增id</title><link>https://www.kutake.top/archives/sqlalchemy%E5%BC%82%E6%AD%A5%E4%B8%8E%E5%90%8C%E6%AD%A5%E6%96%B9%E5%BC%8F%E8%8E%B7%E5%8F%96%E8%87%AA%E5%A2%9Eid/</link><pubDate>Thu, 05 Jan 2023 00:19:10 +0800</pubDate><guid>https://www.kutake.top/archives/sqlalchemy%E5%BC%82%E6%AD%A5%E4%B8%8E%E5%90%8C%E6%AD%A5%E6%96%B9%E5%BC%8F%E8%8E%B7%E5%8F%96%E8%87%AA%E5%A2%9Eid/</guid><description>&lt;h2 id="同步"&gt;同步&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# sync_session&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# example(id, name)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# id = 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="异步"&gt;异步&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# async_session&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# example(id, name)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;example&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;flush&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# id = 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>[myabtis-plus]XML中返回的id顺序问题</title><link>https://www.kutake.top/archives/myabtis-plusxml%E4%B8%AD%E8%BF%94%E5%9B%9E%E7%9A%84id%E9%A1%BA%E5%BA%8F%E9%97%AE%E9%A2%98/</link><pubDate>Thu, 22 Dec 2022 02:25:25 +0800</pubDate><guid>https://www.kutake.top/archives/myabtis-plusxml%E4%B8%AD%E8%BF%94%E5%9B%9E%E7%9A%84id%E9%A1%BA%E5%BA%8F%E9%97%AE%E9%A2%98/</guid><description>&lt;h2 id="问题"&gt;问题&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;insert&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;insertListIfNotExists&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;useGeneratedKeys=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;keyProperty=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; INSERT IGNORE INTO
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; `tag` (name, create_time)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; VALUES
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;foreach&lt;/span&gt; &lt;span class="na"&gt;collection=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;list&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;item=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;item&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;separator=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (#{item.name}, #{item.createTime})
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/foreach&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/insert&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;useGeneratedKeys&lt;/code&gt;与&lt;code&gt;INSERT IGNORE&lt;/code&gt;配合后，若插入顺序是&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;id:1 name: name1
id: null name: name2
id: null name: name3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;返回的id会变成&lt;/p&gt;</description></item><item><title>[myabtis-plus]xml中的字段注入不生效</title><link>https://www.kutake.top/archives/myabtis-plusxml%E4%B8%AD%E7%9A%84%E5%AD%97%E6%AE%B5%E6%B3%A8%E5%85%A5%E4%B8%8D%E7%94%9F%E6%95%88/</link><pubDate>Thu, 22 Dec 2022 02:23:17 +0800</pubDate><guid>https://www.kutake.top/archives/myabtis-plusxml%E4%B8%AD%E7%9A%84%E5%AD%97%E6%AE%B5%E6%B3%A8%E5%85%A5%E4%B8%8D%E7%94%9F%E6%95%88/</guid><description>&lt;h2 id="未声明则不插入"&gt;未声明则不插入&lt;/h2&gt;
&lt;p&gt;create_time是自动注入字段&lt;/p&gt;
&lt;p&gt;xml是最终执行的sql命令，未声明加入则不会插入&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;insert&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;insertListIfNotExists&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;useGeneratedKeys=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;keyProperty=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; INSERT IGNORE INTO
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; `tag` (name)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; VALUES
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;foreach&lt;/span&gt; &lt;span class="na"&gt;collection=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;list&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;item=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;item&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;separator=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (#{item.name})
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/foreach&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/insert&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;修改：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;insert&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;insertListIfNotExists&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;useGeneratedKeys=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;true&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;keyProperty=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; INSERT IGNORE INTO
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; `tag` (name, create_time)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; VALUES
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;foreach&lt;/span&gt; &lt;span class="na"&gt;collection=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;list&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;item=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;item&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;separator=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;,&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (#{item.name}, #{item.createTime})
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/foreach&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/insert&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>bot的一些反思</title><link>https://www.kutake.top/archives/bot%E7%9A%84%E4%B8%80%E4%BA%9B%E5%8F%8D%E6%80%9D/</link><pubDate>Sun, 25 Sep 2022 15:50:04 +0800</pubDate><guid>https://www.kutake.top/archives/bot%E7%9A%84%E4%B8%80%E4%BA%9B%E5%8F%8D%E6%80%9D/</guid><description>&lt;h2 id="模块化"&gt;模块化&lt;/h2&gt;
&lt;p&gt;我现在是这样的&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Bot&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;└─&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;└─&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;└─&lt;/span&gt;&lt;span class="n"&gt;modules&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;└─&lt;/span&gt;&lt;span class="n"&gt;utils&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;config&lt;/code&gt;内包含所有模块用到的配置项&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;db&lt;/code&gt;内是实体类和业务语句的集合&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;utils&lt;/code&gt;内是一些公共工具&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现在问题是，&lt;code&gt;config&lt;/code&gt;与&lt;code&gt;db&lt;/code&gt;非常难维护，一打开就是几百行语句，找起来都麻烦，数据库和配置项有一点不对整个bot就无法启动&lt;/p&gt;</description></item><item><title>PDM-更现代的python包管理器</title><link>https://www.kutake.top/archives/pdm-%E6%9B%B4%E7%8E%B0%E4%BB%A3%E7%9A%84python%E5%8C%85%E7%AE%A1%E7%90%86%E5%99%A8/</link><pubDate>Tue, 31 May 2022 15:57:23 +0800</pubDate><guid>https://www.kutake.top/archives/pdm-%E6%9B%B4%E7%8E%B0%E4%BB%A3%E7%9A%84python%E5%8C%85%E7%AE%A1%E7%90%86%E5%99%A8/</guid><description>&lt;h2 id="pdm介绍"&gt;PDM介绍&lt;/h2&gt;
&lt;p&gt;一个现代的 Python 包管理器，支持 &lt;a href="https://www.python.org/dev/peps/pep-0582"&gt;PEP 582&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;跟pipenv与poetry有着相同功能&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;抛弃传统包管理器所需的虚拟环境 - &lt;a href="https://www.python.org/dev/peps/pep-0582"&gt;PEP 582&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;比poetry更快的依赖解析&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;类似pnpm的中心化安装缓存&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;插件系统&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.python.org/dev/peps/pep-0621"&gt;PEP 621&lt;/a&gt; 元数据格式&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;兼容 &lt;a href="https://www.python.org/dev/peps/pep-0517"&gt;PEP 517&lt;/a&gt; 的构建后端，用于构建发布包(源码格式与 wheel 格式)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Python中便捷的上下文管理器contextmanager</title><link>https://www.kutake.top/archives/python%E4%B8%AD%E4%BE%BF%E6%8D%B7%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87%E7%AE%A1%E7%90%86%E5%99%A8contextmanager/</link><pubDate>Sat, 14 May 2022 20:36:57 +0800</pubDate><guid>https://www.kutake.top/archives/python%E4%B8%AD%E4%BE%BF%E6%8D%B7%E7%9A%84%E4%B8%8A%E4%B8%8B%E6%96%87%E7%AE%A1%E7%90%86%E5%99%A8contextmanager/</guid><description>&lt;h2 id="基本的上下文管理器"&gt;基本的上下文管理器&lt;/h2&gt;
&lt;p&gt;需要定义：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-Python" data-lang="Python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ContextM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__enter__&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dosomethings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__exit__&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dosometings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AsyncContextM&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__aenter__&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;dosometings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__aexit__&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;dosometings&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;调用时使用&lt;code&gt;with ContextM()&lt;/code&gt;或&lt;code&gt;async with AsyncContextM&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="contextmanager"&gt;ContextManager&lt;/h2&gt;
&lt;p&gt;Python内置的一个很方便的生成上下文管理器的装饰器&lt;/p&gt;</description></item><item><title>在fastapi中使用loguru记录日志</title><link>https://www.kutake.top/archives/%E5%9C%A8fastapi%E4%B8%AD%E4%BD%BF%E7%94%A8loguru%E8%AE%B0%E5%BD%95%E6%97%A5%E5%BF%97/</link><pubDate>Sat, 12 Mar 2022 17:54:22 +0800</pubDate><guid>https://www.kutake.top/archives/%E5%9C%A8fastapi%E4%B8%AD%E4%BD%BF%E7%94%A8loguru%E8%AE%B0%E5%BD%95%E6%97%A5%E5%BF%97/</guid><description>&lt;h2 id="日志重写"&gt;日志重写&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;logging&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pprint&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pformat&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;loguru&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;InterceptHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Get corresponding Loguru level if it exists&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;levelname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;levelno&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Find caller from where originated the logged message&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;currentframe&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_code&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_filename&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="vm"&gt;__file__&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;frame&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_back&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;depth&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;opt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exc_info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;format_record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;format_string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LOG_FORMAT&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;extra&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;payload&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;extra&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;payload&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pformat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;record&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;extra&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;payload&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;compact&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;88&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;format_string&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;level&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{extra[payload]}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/level&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;format_string&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{exception}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;format_string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# it requires app init or won&amp;#39;t be work&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;logger_init&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;log_path_all&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LOG_FILE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;log_path_error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log_error_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LOG_FILE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;InterceptHandler&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;handlers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sink&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;format&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;format_record&lt;/span&gt;&lt;span class="p"&gt;}])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# logger.add(config.LOG_DIR, encoding=&amp;#39;utf-8&amp;#39;, rotation=&amp;#34;9:46&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_path_all&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;00:00&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retention&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2 week&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;enqueue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;diagnose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;DEBUG&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;format_record&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_path_error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;rotation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;00:00&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;retention&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;3 week&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;enqueue&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;backtrace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;diagnose&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ERROR&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;format_record&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;日志系统已加载&lt;/span&gt;&lt;span class="se"&gt;\n\n\n&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getLogger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;uvicorn.access&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;handlers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;InterceptHandler&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="在app中调用"&gt;在app中调用&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEBUG&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# app create frist, then init logger&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;logger_init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;origins&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;http://127.0.0.1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;http://127.0.0.1:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;http://localhost&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;http://localhost:&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# &amp;#34;*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;include_router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scraper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;include_router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;works&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;include_router&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;router&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;CORSMiddleware&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;allow_origins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;origins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;allow_credentials&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;allow_methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;allow_headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;__main__&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;uvicorn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;main:app&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;0.0.0.0&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;reload&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# should be False at production&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;access_log&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ws_ping_interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ws_ping_timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>FastApi使用jwt-token进行验证</title><link>https://www.kutake.top/archives/fastapi%E4%BD%BF%E7%94%A8jwt-token%E8%BF%9B%E8%A1%8C%E9%AA%8C%E8%AF%81/</link><pubDate>Sat, 12 Mar 2022 17:48:58 +0800</pubDate><guid>https://www.kutake.top/archives/fastapi%E4%BD%BF%E7%94%A8jwt-token%E8%BF%9B%E8%A1%8C%E9%AA%8C%E8%AF%81/</guid><description>&lt;h2 id="以depends的方式定义jwt"&gt;以Depends的方式定义jwt&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;jose&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;JWTError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;passlib.context&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;CryptContext&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fastapi.security&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OAuth2PasswordBearer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Curd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;pwd_context&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CryptContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;schemes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;bcrypt&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;deprecated&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;auto&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;oauth2_schema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OAuth2PasswordBearer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/users/login&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hash_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plain_password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pwd_context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plain_password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verity_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plain_password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hashed_password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pwd_context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plain_password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hashed_password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;jwt_authenticate_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Curd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_user_by_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__anext__&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;verity_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;created_access_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expires_delta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;to_encode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;expires_delta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;expire&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;expires_delta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;expire&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utcnow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;timedelta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ACCESS_TOKEN_EXPIRE_MINUTES&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;to_encode&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;exp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;expire&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;encoded_jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;claims&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;to_encode&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;algorithm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;HS256&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;encoded_jwt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;jwt_verity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oauth2_schema&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;credentials_exception&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTP_401_UNAUTHORIZED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Could not validate credentials&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;WWW-Authenticate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Bearer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;playload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SECRET_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;algorithms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;HS256&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;JWTError&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;验证出现错误:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;credentials_exception&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;playload&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;jwt_get_current_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;playload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwt_verity&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;playload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sub&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Curd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_user_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__anext__&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;jwt_verity_admin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;playload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwt_verity&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;playload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sub&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;is_admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;playload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;is_admin&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;is_admin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Curd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_user_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="fm"&gt;__anext__&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_admin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTP_401_UNAUTHORIZED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Could not validate credentials&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;WWW-Authenticate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Bearer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="需要分发token的url"&gt;需要分发token的url&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;APIRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/users&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# it defind at dependencies.jwt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# oauth2_schema = OAuth2PasswordBearer(tokenUrl=&amp;#34;/users/token&amp;#34;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@router.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/register&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response_model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UserToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;user_register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OAuth2PasswordRequestForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AsyncSession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Curd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_user_name_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTP_400_BAD_REQUEST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;username already exists&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;hashed_password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hash_password&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;new_user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;UserCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_id&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;hashed_password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Curd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@router.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/login&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response_model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UserToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;user_login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OAuth2PasswordRequestForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;()):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;jwt_authenticate_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTP_401_UNAUTHORIZED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Incorrect username or password&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;WWW-Authenticate&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Bearer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;access_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;created_access_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;sub&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;UserToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;access_token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;token_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;bearer&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user_token&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="需要token进行访问限制的url"&gt;需要token进行访问限制的url&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;APIRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/works&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;works&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@router.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/get&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response_model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;Works&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;nsfw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jwt_get_current_user&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AsyncSession&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;works&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Curd&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_works&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nsfw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;works&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Sqlalchemy-关于PyhtonORM的各种事</title><link>https://www.kutake.top/archives/sqlalchemy-%E5%85%B3%E4%BA%8Epyhtonorm%E7%9A%84%E5%90%84%E7%A7%8D%E4%BA%8B/</link><pubDate>Sat, 12 Mar 2022 17:27:57 +0800</pubDate><guid>https://www.kutake.top/archives/sqlalchemy-%E5%85%B3%E4%BA%8Epyhtonorm%E7%9A%84%E5%90%84%E7%A7%8D%E4%BA%8B/</guid><description>&lt;h2 id="orm"&gt;ORM&lt;/h2&gt;
&lt;p&gt;ORM：对象关系映射（Object Relational Mapping，简称ORM，或O/RM，或O/R mapping)，用于实现面向对象编程语言里不同类型系统的数据之间的转换&lt;/p&gt;</description></item><item><title>数据结构复习</title><link>https://www.kutake.top/archives/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%A4%8D%E4%B9%A0/</link><pubDate>Mon, 27 Dec 2021 00:41:50 +0800</pubDate><guid>https://www.kutake.top/archives/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84%E5%A4%8D%E4%B9%A0/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="1什么是算法"&gt;1.什么是算法？&lt;/h2&gt;
&lt;p&gt;算法是计算机科学中的基本概念，是对特定问题的求解步骤&lt;/p&gt;
&lt;h2 id="2什么是算法的复杂度"&gt;2.什么是算法的复杂度？&lt;/h2&gt;
&lt;p&gt;分为时间复杂度和空间复杂度，前者一般是指程序运行从开始到结束所需的时间，后者一般是指对应的程序从运行开始到结束所需的储存空间&lt;/p&gt;</description></item><item><title>JetBrains 系列关于登录验证的屏蔽方法</title><link>https://www.kutake.top/archives/jetbrains-%E7%B3%BB%E5%88%97%E5%85%B3%E4%BA%8E%E7%99%BB%E5%BD%95%E9%AA%8C%E8%AF%81%E7%9A%84%E5%B1%8F%E8%94%BD%E6%96%B9%E6%B3%95/</link><pubDate>Sun, 26 Dec 2021 00:05:54 +0800</pubDate><guid>https://www.kutake.top/archives/jetbrains-%E7%B3%BB%E5%88%97%E5%85%B3%E4%BA%8E%E7%99%BB%E5%BD%95%E9%AA%8C%E8%AF%81%E7%9A%84%E5%B1%8F%E8%94%BD%E6%96%B9%E6%B3%95/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;Pycharm好像是3.X版本上的登录验证，IEDA应该是2.3，登录验证已经无法使用插件来绕过，这里记录一下新的方法。&lt;/p&gt;
&lt;p&gt;此方法来源依旧是eval-reset插件的作者，使用到的开源项目地址或网站：&lt;/p&gt;</description></item><item><title>考试相关</title><link>https://www.kutake.top/archives/%E8%80%83%E8%AF%95%E7%9B%B8%E5%85%B3/</link><pubDate>Fri, 17 Dec 2021 23:24:56 +0800</pubDate><guid>https://www.kutake.top/archives/%E8%80%83%E8%AF%95%E7%9B%B8%E5%85%B3/</guid><description>&lt;h2 id="linux"&gt;Linux&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.kutake.top/2021/12/15/ftp%e7%9a%84%e9%85%8d%e7%bd%ae%e4%b8%8e%e9%81%87%e5%88%b0%e7%9a%84%e9%97%ae%e9%a2%98/"&gt;FTP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.kutake.top/2021/12/13/docker-2021-12-10/"&gt;Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.kutake.top/2021/12/17/centos%e7%9a%84apache%e9%83%a8%e7%bd%b2web/"&gt;Apache&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="基本的排错"&gt;基本的排错&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;检查端口是否打开&lt;/li&gt;
&lt;li&gt;检查服务/容器是否启动&lt;/li&gt;
&lt;li&gt;检查防火墙是否关闭&lt;/li&gt;
&lt;li&gt;ftp中检查配置文件中的 ip 是否替换为了自己的ip&lt;/li&gt;
&lt;li&gt;docker中注意容器的命名冲突&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Centos的Apache部署web</title><link>https://www.kutake.top/archives/centos%E7%9A%84apache%E9%83%A8%E7%BD%B2web/</link><pubDate>Fri, 17 Dec 2021 22:28:33 +0800</pubDate><guid>https://www.kutake.top/archives/centos%E7%9A%84apache%E9%83%A8%E7%BD%B2web/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Apache&lt;/strong&gt;程序是目前拥有很高市场占有率的Web服务程序之一，这里演示如何安装，并访问一个简单的index.html&lt;/p&gt;
&lt;h2 id="开整"&gt;开整&lt;/h2&gt;
&lt;p&gt;首先安装apache的软件包：&lt;/p&gt;</description></item><item><title>FTP的配置与遇到的问题</title><link>https://www.kutake.top/archives/ftp%E7%9A%84%E9%85%8D%E7%BD%AE%E4%B8%8E%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/</link><pubDate>Wed, 15 Dec 2021 22:59:06 +0800</pubDate><guid>https://www.kutake.top/archives/ftp%E7%9A%84%E9%85%8D%E7%BD%AE%E4%B8%8E%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# 安装
yum install vsftpd -y
yum install ftp -y
# 启用
systemctl restart vsftpd
systemctl enable vsftpd
# 处理配置文件
mv /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak
grep -v &amp;#34;#&amp;#34; /etc/vsftpd/vsftpd.conf.bak &amp;gt; /etc/vsftpd/vsftpd.conf
# 关闭SELinux
setenforce 0
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;修改配置文件：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;vim /etc/vsftpd/vsftpd.conf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将以下内容复制进去（&lt;strong&gt;注意！将18行 pasv_address 等号后面的ip改为你自己云服务器的ip地址！！&lt;/strong&gt;）&lt;/p&gt;</description></item><item><title>Docker-2021/12/10</title><link>https://www.kutake.top/archives/docker-2021-12-10/</link><pubDate>Mon, 13 Dec 2021 20:02:55 +0800</pubDate><guid>https://www.kutake.top/archives/docker-2021-12-10/</guid><description>&lt;!-- toc --&gt;
&lt;blockquote&gt;
&lt;p&gt;Docker 是一个用于开发，交付和运行应用程序的开放平台。Docker 使您能够将应用程序与基础架构分开，从而可以快速交付软件。借助 Docker，您可以与管理应用程序相同的方式来管理基础架构。通过利用 Docker 的方法来快速交付，测试和部署代码，您可以大大减少编写代码和在生产环境中运行代码之间的延迟。&lt;/p&gt;
&lt;p&gt;菜鸟教程--docker的优点&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Note: 数据库原理与应用P113 sql表创建</title><link>https://www.kutake.top/archives/note-%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%E4%B8%8E%E5%BA%94%E7%94%A8p113-sql%E8%A1%A8%E5%88%9B%E5%BB%BA/</link><pubDate>Mon, 06 Dec 2021 11:28:11 +0800</pubDate><guid>https://www.kutake.top/archives/note-%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%E4%B8%8E%E5%BA%94%E7%94%A8p113-sql%E8%A1%A8%E5%88%9B%E5%BB%BA/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;CREATE TABLE Student(
Sno Char(3) NOT NULL PRIMARY KEY,
Sname CHAR(3) NOT NULL,
Ssex CHAR(2) NOT NULL,
Sbirthday datetime,
Class CHAR(5)
)
CREATE TABLE Teacher(
Tno CHAR(3) PRIMARY KEY,
Tname CHAR(4) NOT NULL,
Tsex CHAR(2) NOT NULL,
Tbirthday datetime,
Prof CHAR(6),
Depart VARCHAR(10) NOT NULL
)
CREATE TABLE Course(
Cno CHAR(5) NOT NULL PRIMARY KEY,
Cname VARCHAR(10) NOT NULL,
Tno CHAR(3) NOT NULL,
FOREIGN KEY (Tno) REFERENCES Teacher(Tno)
)
CREATE TABLE Score(
Sno CHAR(3) NOT NULL,
Cno CHAR(5) NOT NULL,
Degree Decimal(4,1)
FOREIGN KEY (Sno) REFERENCES Student(Sno),
FOREIGN KEY (Cno) REFERENCES Course(Cno)
)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>哈夫曼编码的实现(python)</title><link>https://www.kutake.top/archives/%E5%93%88%E5%A4%AB%E6%9B%BC%E7%BC%96%E7%A0%81%E7%9A%84%E5%AE%9E%E7%8E%B0python/</link><pubDate>Sun, 21 Nov 2021 21:31:23 +0800</pubDate><guid>https://www.kutake.top/archives/%E5%93%88%E5%A4%AB%E6%9B%BC%E7%BC%96%E7%A0%81%E7%9A%84%E5%AE%9E%E7%8E%B0python/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="思路"&gt;思路&lt;/h2&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://www.kutake.top/media/2021/11/%E5%93%88%E5%A4%AB%E6%9B%BC%E7%BC%96%E7%A0%81%E5%AE%9E%E7%8E%B0%EF%BC%88python%EF%BC%89-1024x332.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;del&gt;C++实在是弄不懂&lt;/del&gt;&lt;/p&gt;
&lt;h2 id="代码"&gt;代码&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;from typing import List, Optional
class Node:
&amp;#34;&amp;#34;&amp;#34;
结点
&amp;#34;&amp;#34;&amp;#34;
def __init__(self):
self.name: Optional[str] = None
self.weight: Optional[int] = None
self.left_child: Optional[Node] = None
self.right_child: Optional[Node] = None
self.parent: Optional[Node] = None
class NodeCode:
&amp;#34;&amp;#34;&amp;#34;
结点的编码
&amp;#34;&amp;#34;&amp;#34;
def __init__(self, name: str, code: str):
self.name = name
self.code = code
def __str__(self):
return f&amp;#34;{self.name}:{self.code}&amp;#34;
class HaffumanTreeCode:
&amp;#34;&amp;#34;&amp;#34;
哈夫曼树的编码
&amp;#34;&amp;#34;&amp;#34;
def __init__(self):
self.code_list: List[NodeCode] = []
def append(self, code: NodeCode):
self.code_list.append(code)
def code(self, massage: str):
&amp;#34;&amp;#34;&amp;#34;
针对编码表编码
:param massage: 需要编码的信息
:return:
&amp;#34;&amp;#34;&amp;#34;
code = &amp;#34;&amp;#34;
for i in massage:
for n in self.code_list:
if n.name == i:
code += n.code
break
# raise ValueError(f&amp;#34;&amp;#39;{i}&amp;#39;不存在&amp;#34;)
return code
def decode(self, code: str):
&amp;#34;&amp;#34;&amp;#34;
针对编码表解码
:param code:需要解码的哈夫曼码
:return:
&amp;#34;&amp;#34;&amp;#34;
out = &amp;#34;&amp;#34;
i = 0
while code:
code_need_match = code[0:i+1]
for n in self.code_list:
if n.code == code_need_match:
out += n.name
code = code[i+1:]
i = 0
break
i += 1
return out
def __str__(self):
&amp;#34;&amp;#34;&amp;#34;
打印
:return:
&amp;#34;&amp;#34;&amp;#34;
out = &amp;#34;&amp;#34;
for i in self.code_list:
out += i.__str__() + &amp;#34;\n&amp;#34;
return out.strip()
class HaffumanTree:
&amp;#34;&amp;#34;&amp;#34;
哈夫曼树
&amp;#34;&amp;#34;&amp;#34;
def __init__(self):
self.root = Node()
self.nodes: List[Node] = []
self.nodes_raw: List[Node] = []
self.codes: HaffumanTreeCode = HaffumanTreeCode()
def inser(self, newnode: Node):
for i in range(len(self.nodes)):
if self.nodes[i].weight &amp;lt; newnode.weight:
self.nodes.insert(i, newnode)
return
self.nodes.append(newnode)
def build_tree(self, name_list: List[str], weight_list: List[int]):
&amp;#34;&amp;#34;&amp;#34;
创建哈夫曼树
:param name_list: 字符列表
:param weight_list: 权重列表
:return:
&amp;#34;&amp;#34;&amp;#34;
# 队每个字符生成结点
while len(name_list) &amp;gt; 0:
max_weight = max(weight_list)
max_index = weight_list.index(max_weight)
max_name = name_list[max_index]
newnode = Node()
newnode.name = max_name
newnode.weight = max_weight
self.nodes.append(newnode)
name_list.remove(max_name)
weight_list.remove(max_weight)
# 保存源结点
self.nodes_raw = self.nodes[:]
# 创建新结点并生成树
while len(self.nodes) &amp;gt; 2:
left = self.nodes.pop()
right = self.nodes.pop()
newnode = Node()
newnode.weight = left.weight + right.weight
newnode.left_child = left
newnode.right_child = right
left.parent = newnode
right.parent = newnode
# 根据权重插入
self.inser(newnode)
left = self.nodes.pop()
right = self.nodes.pop()
self.root.weight = left.weight + right.weight
self.root.left_child = left
self.root.right_child = right
left.parent = self.root
right.parent = self.root
def make_code(self):
&amp;#34;&amp;#34;&amp;#34;
生成编码表
:return:
&amp;#34;&amp;#34;&amp;#34;
while len(self.nodes_raw):
node = self.nodes_raw.pop()
name = node.name
code = &amp;#34;&amp;#34;
while node.parent != self.root:
parent = node.parent
if parent.left_child == node:
code = &amp;#34;0&amp;#34; + code
elif parent.right_child == node:
code = &amp;#34;1&amp;#34; + code
node = parent
if self.root.left_child == node:
code = &amp;#34;0&amp;#34; + code
elif self.root.right_child == node:
code = &amp;#34;1&amp;#34; + code
self.codes.append(NodeCode(name, code))
def decode(self, code: str):
return self.codes.decode(code)
def code(self, massage: str):
return self.codes.code(massage)
if __name__ == &amp;#39;__main__&amp;#39;:
h = HaffumanTree()
name_list = [&amp;#34;a&amp;#34;, &amp;#34;b&amp;#34;, &amp;#34;c&amp;#34;, &amp;#34;d&amp;#34;, &amp;#34;e&amp;#34;]
wight_list = [5, 11, 6, 21, 19]
h.build_tree(name_list, wight_list)
h.make_code()
print(f&amp;#34;编码表：\n{h.codes}&amp;#34;)
print(f&amp;#39;bcacce编码为：{h.code(&amp;#34;bcacce&amp;#34;)}&amp;#39;)
print(f&amp;#39;01001000001001解码为： {h.decode(&amp;#34;0100100000100110&amp;#34;)}&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Real-ESRGAN腾讯的类WIAFU2X二次元图片放大算法</title><link>https://www.kutake.top/archives/real-esrgan%E8%85%BE%E8%AE%AF%E7%9A%84%E7%B1%BBwiafu2x%E4%BA%8C%E6%AC%A1%E5%85%83%E5%9B%BE%E7%89%87%E6%94%BE%E5%A4%A7%E7%AE%97%E6%B3%95/</link><pubDate>Wed, 17 Nov 2021 21:45:51 +0800</pubDate><guid>https://www.kutake.top/archives/real-esrgan%E8%85%BE%E8%AE%AF%E7%9A%84%E7%B1%BBwiafu2x%E4%BA%8C%E6%AC%A1%E5%85%83%E5%9B%BE%E7%89%87%E6%94%BE%E5%A4%A7%E7%AE%97%E6%B3%95/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;项目地址：&lt;a href="https://github.com/xinntao/Real-ESRGAN"&gt;xinntao/Real-ESRGAN: Real-ESRGAN aims at developing Practical Algorithms for General Image Restoration. (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;中文介绍：&lt;a href="https://github.com/xinntao/Real-ESRGAN/blob/master/README_CN.md"&gt;Real-ESRGAN/README_CN.md at master · xinntao/Real-ESRGAN (github.com)&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="使用方法"&gt;使用方法&lt;/h2&gt;
&lt;p&gt;先进行&lt;a href="https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.2.4/realesrgan-ncnn-vulkan-20210901-windows.zip"&gt;下载&lt;/a&gt;，后解压缩，解压后文件如图&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://www.kutake.top/media/2021/11/image.png"&gt;&lt;/p&gt;
&lt;p&gt;在这个文件夹路径内输入&lt;code&gt;cmd&lt;/code&gt;，回车&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://www.kutake.top/media/2021/11/image-1.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;输入cmd后回车&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;就来到了命令终端：&lt;/p&gt;
&lt;p&gt;&lt;img loading="lazy" src="https://www.kutake.top/media/2021/11/image-2.png"&gt;&lt;/p&gt;
&lt;p&gt;之后把要放大的图片放在这个文件夹内，比如我这里是test.jpg&lt;/p&gt;</description></item><item><title>Nginx反向代理中涉及Websocket的问题</title><link>https://www.kutake.top/archives/nginx%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E4%B8%AD%E6%B6%89%E5%8F%8Awebsocket%E7%9A%84%E9%97%AE%E9%A2%98/</link><pubDate>Fri, 10 Sep 2021 11:37:42 +0800</pubDate><guid>https://www.kutake.top/archives/nginx%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E4%B8%AD%E6%B6%89%E5%8F%8Awebsocket%E7%9A%84%E9%97%AE%E9%A2%98/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="也许是我这种小白在反向代理中最常面临的问题"&gt;也许是我这种小白在反向代理中最常面临的问题&lt;/h2&gt;
&lt;p&gt;Nas上挂载过很多自用的站点，提供包括影音、docker管理、qB客户端之类的服务，在穿透到云端并使用Nginx进行反向代理时经常会遇到各种各样无法访问的问题：&lt;/p&gt;</description></item><item><title>Win下挂载Webdav卡顿问题的解决方法</title><link>https://www.kutake.top/archives/win%E4%B8%8B%E6%8C%82%E8%BD%BDwebdav%E5%8D%A1%E9%A1%BF%E9%97%AE%E9%A2%98%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/</link><pubDate>Sun, 05 Sep 2021 00:07:46 +0800</pubDate><guid>https://www.kutake.top/archives/win%E4%B8%8B%E6%8C%82%E8%BD%BDwebdav%E5%8D%A1%E9%A1%BF%E9%97%AE%E9%A2%98%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="远程文件访问需求"&gt;远程文件访问需求&lt;/h2&gt;
&lt;p&gt;家里的Nas里面有音乐、电影、动漫啥的需要在外面进行访问，如果是单纯的视听，那么解决方法非常多，docker就可以部署很多成品的影音娱乐应用，再对端口进行穿透即可访问。但我这里有个需求，有些动漫需要用第三方客户端加载弹幕才看的输出，这个第三方客户端也没有对远程视频文件进行支持，所以还是选择了将文件挂载到本地环境的方法。&lt;/p&gt;</description></item><item><title>Openwrt-从安装到插件设置记录</title><link>https://www.kutake.top/archives/openwrt-%E4%BB%8E%E5%AE%89%E8%A3%85%E5%88%B0%E6%8F%92%E4%BB%B6%E8%AE%BE%E7%BD%AE%E8%AE%B0%E5%BD%95/</link><pubDate>Sun, 15 Aug 2021 01:43:07 +0800</pubDate><guid>https://www.kutake.top/archives/openwrt-%E4%BB%8E%E5%AE%89%E8%A3%85%E5%88%B0%E6%8F%92%E4%BB%B6%E8%AE%BE%E7%BD%AE%E8%AE%B0%E5%BD%95/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="openwrt"&gt;Openwrt&lt;/h2&gt;
&lt;p&gt;按照我浅显的了解，这是一个开源的路由系统，本质就是个用在路由器上的linux，具体的作用非常多，上网管控、广告屏蔽、dns管理、KMS破解、网易云灰色歌曲解锁、内网穿肉、游戏加速、分流分拨等等等等非常多的功能就不一一介绍。&lt;/p&gt;</description></item><item><title>PyMySQL基础使用</title><link>https://www.kutake.top/archives/pymysql%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8/</link><pubDate>Fri, 13 Aug 2021 13:56:12 +0800</pubDate><guid>https://www.kutake.top/archives/pymysql%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pip install PyMySQL
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="连接"&gt;连接&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;db = pymysql.connect(host=&amp;#34;192.168.1.1&amp;#34;, port=3306, user=&amp;#34;root&amp;#34;, password=&amp;#34;password&amp;#34;, database=&amp;#34;database_name&amp;#34;)
cursor = db.cursor()
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="查增"&gt;查/增&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sql_insert = &amp;#34;&amp;#34;&amp;#34;
INSERT INTO 表名(id, name, path)
VALUES (%s, %s, %s)
&amp;#34;&amp;#34;&amp;#34;
# 无论数据库数据类型为int或date，全部使用py的字符串形式插入，所以使用%s
cursor.execute(sql_insert, (user_id, name, path)) # 这种可以有效避免因敏感字符而导致出现语法错误
db.commit() # 进行提交，否则无效
# 当数据源为http相关时，注意转义
import html
from pymysql.converters import escape_string
safe_data = escape_string(html.unescape(unsafe_data)) # unescape转义html字符，escape转义为可直接插入数据库的安全字符串
# 多数据一次插入
cursor.executemany(sql, info) # info可为list，循环按顺序进行插入
db.commit()
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="以及"&gt;以及&lt;/h2&gt;
&lt;p&gt;因为图库已经快20g了，为了管理方便，顺便就上了mysql做数据管理，但有个问题，pymysql非异步，可能会造成bot的io堵塞，现在的数据量查询速度还算快，但要是时间久了就不一定；&lt;/p&gt;</description></item><item><title>Gogs-0.13Dev版本邮件服务设置失败方法</title><link>https://www.kutake.top/archives/gogs-0-13dev%E7%89%88%E6%9C%AC%E9%82%AE%E4%BB%B6%E6%9C%8D%E5%8A%A1%E8%AE%BE%E7%BD%AE%E5%A4%B1%E8%B4%A5%E6%96%B9%E6%B3%95/</link><pubDate>Sat, 24 Jul 2021 21:27:34 +0800</pubDate><guid>https://www.kutake.top/archives/gogs-0-13dev%E7%89%88%E6%9C%AC%E9%82%AE%E4%BB%B6%E6%9C%8D%E5%8A%A1%E8%AE%BE%E7%BD%AE%E5%A4%B1%E8%B4%A5%E6%96%B9%E6%B3%95/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="起因"&gt;起因&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;因为Gitlab各种设置实在是繁琐+奇怪&lt;/strong&gt;，受不鸟还是转回gogs了，秒重启+秒开真的舒服，Gitlab的消耗我的小Nas实在是受不起。&lt;/p&gt;</description></item><item><title>无语的折腾记录-Gitlab的STMP服务设置</title><link>https://www.kutake.top/archives/%E6%97%A0%E8%AF%AD%E7%9A%84%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95-gitlab%E7%9A%84stmp%E6%9C%8D%E5%8A%A1%E8%AE%BE%E7%BD%AE/</link><pubDate>Tue, 20 Jul 2021 14:39:06 +0800</pubDate><guid>https://www.kutake.top/archives/%E6%97%A0%E8%AF%AD%E7%9A%84%E6%8A%98%E8%85%BE%E8%AE%B0%E5%BD%95-gitlab%E7%9A%84stmp%E6%9C%8D%E5%8A%A1%E8%AE%BE%E7%BD%AE/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="自建git---gogsgitlab"&gt;自建Git - Gogs/Gitlab&lt;/h2&gt;
&lt;p&gt;代码修修改改多了，就有了版本控制的需求，Github是最好的选择，但对于个人来说，代码里面有非常重要的隐私信息，又需要方便的进行分享，于是就转到了自建git服务器。&lt;/p&gt;</description></item><item><title>FastApi应用-bot中挂载web服务</title><link>https://www.kutake.top/archives/fastapi%E5%BA%94%E7%94%A8-bot%E4%B8%AD%E6%8C%82%E8%BD%BDweb%E6%9C%8D%E5%8A%A1/</link><pubDate>Tue, 15 Jun 2021 19:34:04 +0800</pubDate><guid>https://www.kutake.top/archives/fastapi%E5%BA%94%E7%94%A8-bot%E4%B8%AD%E6%8C%82%E8%BD%BDweb%E6%9C%8D%E5%8A%A1/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="轻量web服务"&gt;轻量web服务&lt;/h2&gt;
&lt;h3 id="介绍"&gt;介绍&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;FastAPI 是一个用于构建 API 的现代、快速（高性能）的 web 框架，使用 Python 3.6+ 并基于标准的 Python 类型提示。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;FastAPI 框架，高性能，易于学习，高效编码，生产可用&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>《18岁的流水线》</title><link>https://www.kutake.top/archives/18%E5%B2%81%E7%9A%84%E6%B5%81%E6%B0%B4%E7%BA%BF/</link><pubDate>Mon, 07 Jun 2021 13:07:04 +0800</pubDate><guid>https://www.kutake.top/archives/18%E5%B2%81%E7%9A%84%E6%B5%81%E6%B0%B4%E7%BA%BF/</guid><description>&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=T3FpwfUlUnc"&gt;https://www.youtube.com/watch?v=T3FpwfUlUnc&lt;/a&gt;&lt;/p&gt;</description></item><item><title>记录-软路由今天翻车了</title><link>https://www.kutake.top/archives/%E8%AE%B0%E5%BD%95-%E8%BD%AF%E8%B7%AF%E7%94%B1%E4%BB%8A%E5%A4%A9%E7%BF%BB%E8%BD%A6%E4%BA%86/</link><pubDate>Mon, 07 Jun 2021 09:46:40 +0800</pubDate><guid>https://www.kutake.top/archives/%E8%AE%B0%E5%BD%95-%E8%BD%AF%E8%B7%AF%E7%94%B1%E4%BB%8A%E5%A4%A9%E7%BF%BB%E8%BD%A6%E4%BA%86/</guid><description>&lt;!-- toc --&gt;
&lt;h2 id="起不动的主板"&gt;起不动的主板&lt;/h2&gt;
&lt;p&gt;这玩意是去年十一月淘宝入手的，到手上差不多半年，中间开过穿透，开过docker，还用了AD guard和smart DNS，替代我之前N1的软路由工作，运行的也很稳，J1900的cpu占用都很少上40%，直到现在......&lt;/p&gt;</description></item><item><title>Mediawiki - 更专业的wiki网站程序</title><link>https://www.kutake.top/archives/mediawiki-%E6%9B%B4%E4%B8%93%E4%B8%9A%E7%9A%84wiki%E7%BD%91%E7%AB%99%E7%A8%8B%E5%BA%8F/</link><pubDate>Tue, 01 Jun 2021 20:35:25 +0800</pubDate><guid>https://www.kutake.top/archives/mediawiki-%E6%9B%B4%E4%B8%93%E4%B8%9A%E7%9A%84wiki%E7%BD%91%E7%AB%99%E7%A8%8B%E5%BA%8F/</guid><description>&lt;h2 id="介绍"&gt;介绍&lt;/h2&gt;
&lt;!-- toc --&gt;
&lt;p&gt;&lt;a href="https://www.mediawiki.org/wiki/MediaWiki"&gt;Mediawiki&lt;/a&gt;是非常著名的开源wiki程序，比起之前的Dokuwiki功能要更完善，也更专业，使用PHP+SQL开发，适合用于构建百科、知识库、在线文档、个人笔记之类的应用。它的优点如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;美观的界面和可视化编辑器&lt;/li&gt;
&lt;li&gt;拥有丰富的官方插件支持&lt;/li&gt;
&lt;li&gt;官方文档非常完善，对中文支持也很友好&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="部署"&gt;部署&lt;/h2&gt;
&lt;p&gt;我依旧是使用docker部署的，手动部署环境本次不介绍~~（不会）~~&lt;/p&gt;</description></item><item><title>Dokuwiki搭建个人wiki</title><link>https://www.kutake.top/archives/dokuwiki%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BAwiki/</link><pubDate>Mon, 31 May 2021 03:13:49 +0800</pubDate><guid>https://www.kutake.top/archives/dokuwiki%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BAwiki/</guid><description>&lt;h2 id="起因需求"&gt;起因&amp;amp;需求&lt;/h2&gt;
&lt;!-- toc --&gt;
&lt;p&gt;挺早之前有个整跑团的群友需要个地方存剧本和设定，也就是个小wiki，刚好最近用开源框架撘站也变得熟练了，于是到处搜索了一下，决定使用Dokuwiki来完成&lt;/p&gt;</description></item><item><title>Nginx反向代理和SSL部署</title><link>https://www.kutake.top/archives/nginx%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E5%92%8Cssl%E9%83%A8%E7%BD%B2/</link><pubDate>Sun, 30 May 2021 18:32:53 +0800</pubDate><guid>https://www.kutake.top/archives/nginx%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E5%92%8Cssl%E9%83%A8%E7%BD%B2/</guid><description>&lt;h2 id="需求"&gt;需求&lt;/h2&gt;
&lt;!-- toc --&gt;
&lt;p&gt;我有几个小网站需要穿透出去，为了方便使用和安全，选择了直接使用Nginx实现反向代理和ssl的部署，另外还有一些简单的Nginx防护&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;反代实现&lt;/li&gt;
&lt;li&gt;加密访问（仅本人访问）&lt;/li&gt;
&lt;li&gt;SSL部署&lt;/li&gt;
&lt;li&gt;Nginx防护恶意请求&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="反代实现"&gt;反代实现&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;server
{
listen 80;
server_name www.your_url.com;
location / {
proxy_pass http://local456:port/;
}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这样就在80端口实现了对&lt;code&gt;server_name &lt;/code&gt;的反代操作，&lt;code&gt;server_name&lt;/code&gt;填写外部请求的url，&lt;code&gt;proxy_pass&lt;/code&gt;填写内部你需要反代出去的url&lt;/p&gt;</description></item><item><title>博客迁移至香港腾讯轻量应用云的记录</title><link>https://www.kutake.top/archives/%E5%8D%9A%E5%AE%A2%E8%BF%81%E7%A7%BB%E8%87%B3%E9%A6%99%E6%B8%AF%E8%85%BE%E8%AE%AF%E8%BD%BB%E9%87%8F%E5%BA%94%E7%94%A8%E4%BA%91%E7%9A%84%E8%AE%B0%E5%BD%95/</link><pubDate>Wed, 26 May 2021 00:36:59 +0800</pubDate><guid>https://www.kutake.top/archives/%E5%8D%9A%E5%AE%A2%E8%BF%81%E7%A7%BB%E8%87%B3%E9%A6%99%E6%B8%AF%E8%85%BE%E8%AE%AF%E8%BD%BB%E9%87%8F%E5%BA%94%E7%94%A8%E4%BA%91%E7%9A%84%E8%AE%B0%E5%BD%95/</guid><description>&lt;h2 id="原因"&gt;原因&lt;/h2&gt;
&lt;!-- toc --&gt;
&lt;ol&gt;
&lt;li&gt;申请不到公网ip，短期内也不考虑换宽带&lt;/li&gt;
&lt;li&gt;就算申请到了也封80/443，我这个菜鸡无法解决这种高难度问题&lt;/li&gt;
&lt;li&gt;将Nas上的wordpress穿透到云上的方案折腾而且不好用，现在考虑直接部署至云上&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="过程"&gt;过程&lt;/h2&gt;
&lt;p&gt;看别人推荐，用了腾讯的香港轻量云，体验非常不错&lt;/p&gt;</description></item><item><title>all() 一个便利的多条件判断方法</title><link>https://www.kutake.top/archives/all-%E4%B8%80%E4%B8%AA%E4%BE%BF%E5%88%A9%E7%9A%84%E5%A4%9A%E6%9D%A1%E4%BB%B6%E5%88%A4%E6%96%AD%E6%96%B9%E6%B3%95/</link><pubDate>Tue, 04 May 2021 13:43:48 +0800</pubDate><guid>https://www.kutake.top/archives/all-%E4%B8%80%E4%B8%AA%E4%BE%BF%E5%88%A9%E7%9A%84%E5%A4%9A%E6%9D%A1%E4%BB%B6%E5%88%A4%E6%96%AD%E6%96%B9%E6%B3%95/</guid><description>&lt;h2 id="一般的多条件判断"&gt;一般的多条件判断&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;if 判断1 and 判断2 and 判断3:
run()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当语句非常长的时候，就显得难懂且不美观&lt;/p&gt;
&lt;h2 id="all方法多条件判断"&gt;all()方法多条件判断&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;if all([条件1, 条件2, 条件3]):
run()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;all()传入一个可迭代对象，当所有条件为True时，返回True&lt;/p&gt;</description></item><item><title>CUAVbot--一个python构成的qq机器人</title><link>https://www.kutake.top/archives/cuavbot-%E4%B8%80%E4%B8%AApython%E6%9E%84%E6%88%90%E7%9A%84qq%E6%9C%BA%E5%99%A8%E4%BA%BA/</link><pubDate>Mon, 03 May 2021 01:39:59 +0800</pubDate><guid>https://www.kutake.top/archives/cuavbot-%E4%B8%80%E4%B8%AApython%E6%9E%84%E6%88%90%E7%9A%84qq%E6%9C%BA%E5%99%A8%E4%BA%BA/</guid><description>&lt;p&gt;这个bot写了有段小时间了，一直没有做个总结之类的，正好最近使用了&lt;a href="https://github.com/GraiaProject/Saya"&gt;saya&lt;/a&gt;, &lt;del&gt;代码算是可以看了点&lt;/del&gt;，于是就准备做个小总结。&lt;/p&gt;
&lt;!-- toc --&gt;
&lt;h2 id="bot是什么"&gt;Bot是什么&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;输入 - 处理 - 结果&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;大致上就是如此，发送一句话，bot根据这句话进行处理，然后得到预期结果。很明显，bot就是IO密集型程序，使用异步的方式是最便捷也是最高效的，这里就要说下开发框架&lt;/p&gt;</description></item><item><title>pip 换源与临时换源</title><link>https://www.kutake.top/archives/pip-set%E6%8D%A2%E6%BA%90/</link><pubDate>Fri, 19 Mar 2021 18:52:42 +0800</pubDate><guid>https://www.kutake.top/archives/pip-set%E6%8D%A2%E6%BA%90/</guid><description>&lt;h2 id="永久换源"&gt;永久换源&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pip config set global.index-url https://
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="临时换源"&gt;临时换源&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;pip install --index-url https:// module
pip install module -i https://
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="常用源"&gt;常用源&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;清华大学 &lt;a href="https://pypi.tuna.tsinghua.edu.cn/simple/"&gt;https://pypi.tuna.tsinghua.edu.cn/simple/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;阿里云 &lt;a href="http://mirrors.aliyun.com/pypi/simple/"&gt;http://mirrors.aliyun.com/pypi/simple/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;中国科技大学 &lt;a href="https://pypi.mirrors.ustc.edu.cn/simple/"&gt;https://pypi.mirrors.ustc.edu.cn/simple/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;豆瓣(douban) &lt;a href="http://pypi.douban.com/simple/"&gt;http://pypi.douban.com/simple/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;中国科学技术大学 &lt;a href="http://pypi.mirrors.ustc.edu.cn/simple/"&gt;http://pypi.mirrors.ustc.edu.cn/simple/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其中中国科技大学还挺好&lt;/p&gt;</description></item><item><title>模拟登录相关</title><link>https://www.kutake.top/archives/%E6%A8%A1%E6%8B%9F%E7%99%BB%E5%BD%95%E7%9B%B8%E5%85%B3/</link><pubDate>Wed, 05 Aug 2020 00:26:05 +0800</pubDate><guid>https://www.kutake.top/archives/%E6%A8%A1%E6%8B%9F%E7%99%BB%E5%BD%95%E7%9B%B8%E5%85%B3/</guid><description>&lt;p&gt;一个网页不需要登录，就可以随意访问网站的所有具体信息的话，那就好比是一个敞开了大门的网站，摆好酒桌好吃好喝招待爬虫脚本们，数据提取的成本非常低。于是比较常规的网站，都会使用账号登录来提高网站对于每个想要查看网站数据的门槛，所以模拟登陆的问题就是必修课&lt;/p&gt;</description></item><item><title>Scrapy+随机User-Again+随机高匿代理ip爬取全球最大的同人网站上万条信息</title><link>https://www.kutake.top/archives/scrapy%E9%9A%8F%E6%9C%BAuser-again%E9%9A%8F%E6%9C%BA%E9%AB%98%E5%8C%BF%E4%BB%A3%E7%90%86ip%E7%88%AC%E5%8F%96%E5%85%A8%E7%90%83%E6%9C%80%E5%A4%A7%E7%9A%84%E5%90%8C%E4%BA%BA%E7%BD%91%E7%AB%99%E4%B8%8A/</link><pubDate>Thu, 30 Jul 2020 00:48:22 +0800</pubDate><guid>https://www.kutake.top/archives/scrapy%E9%9A%8F%E6%9C%BAuser-again%E9%9A%8F%E6%9C%BA%E9%AB%98%E5%8C%BF%E4%BB%A3%E7%90%86ip%E7%88%AC%E5%8F%96%E5%85%A8%E7%90%83%E6%9C%80%E5%A4%A7%E7%9A%84%E5%90%8C%E4%BA%BA%E7%BD%91%E7%AB%99%E4%B8%8A/</guid><description>&lt;h2 id="确定需求"&gt;确定需求&lt;/h2&gt;
&lt;!-- toc --&gt;
&lt;p&gt;DLsite是全球最大的同人贩卖网站，里面包括漫画、音声、动画、游戏等等来自不同国家不同地区不同语言以及不同形式的二次元创作作品，这个项目暂定是爬取home下的所有漫画信息作为统计数据，链接为：&lt;/p&gt;</description></item><item><title>scrapy+mysql:2006错误解决方法</title><link>https://www.kutake.top/archives/scrapymysql2006%E9%94%99%E8%AF%AF%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/</link><pubDate>Tue, 28 Jul 2020 16:27:34 +0800</pubDate><guid>https://www.kutake.top/archives/scrapymysql2006%E9%94%99%E8%AF%AF%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/</guid><description>&lt;p&gt;首先放上piplines的代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;from itemadapter import ItemAdapter
import MySQLdb
import logging
class TestRjPipeline:
def __init__(self):
host = (&amp;#39;localhost&amp;#39;)
user = (&amp;#39;root&amp;#39;)
pass_ = (&amp;#39;123456&amp;#39;)
db = (&amp;#39;sqlforpy&amp;#39;)
self.connect = MySQLdb.connect(host,user,pass_,db,charset=&amp;#39;utf8mb4&amp;#39;)
self.cursor = self.connect.cursor()
def process_item(self, item, spider):
def get_data(items_):
data = dict(items_)
rj={&amp;#39;ID&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;title&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;circle&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;keyword_creater&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;data&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;sname&amp;#39;:&amp;#39;无&amp;#39;\
,&amp;#39;GEN&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;type_&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;category&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;other&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;pages&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;genre&amp;#39;:&amp;#39;无&amp;#39;,\
&amp;#39;file_&amp;#39;:&amp;#39;无&amp;#39;,&amp;#39;event&amp;#39;:&amp;#39;无&amp;#39;}
for k in data.items():
rj[k[0]] = k[1]
return rj
rj = get_data(item)
sql = r&amp;#34;&amp;#34;&amp;#34;insert into dlsite_cg_copy1(RJ,标题,社团,作者,发售日,系列名,年龄指定,文件形式,作品类型,其他,页数,分类,文件容量,活动)VALUES(&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;,&amp;#34;%s&amp;#34;)&amp;#34;&amp;#34;&amp;#34;% (rj[&amp;#39;ID&amp;#39;],rj[&amp;#39;title&amp;#39;],rj[&amp;#39;circle&amp;#39;],rj[&amp;#39;keyword_creater&amp;#39;],rj[&amp;#39;data&amp;#39;],rj[&amp;#39;sname&amp;#39;],rj[&amp;#39;GEN&amp;#39;],rj[&amp;#39;type_&amp;#39;],rj[&amp;#39;category&amp;#39;],rj[&amp;#39;other&amp;#39;],rj[&amp;#39;pages&amp;#39;],rj[&amp;#39;genre&amp;#39;],rj[&amp;#39;file_&amp;#39;],rj[&amp;#39;event&amp;#39;])
try:
self.cursor.execute(sql)
self.connect.commit()
except:
logging.debug(&amp;#39;%s写入数据库出现错误！&amp;#39;%rj[&amp;#39;ID&amp;#39;])
logging.debug(&amp;#39;内容为:\n{}\n&amp;#39;.format(rj))
self.connect.rollback()
logging.debug(&amp;#39;此次保存操作结束&amp;#39;)
def close_spider(self, spider):
self.cursor.close()
self.connect.close()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;start之后，总是只能&lt;strong&gt;保存第一条信息&lt;/strong&gt;，然后一直显示&lt;strong&gt;2006&lt;/strong&gt;错误&lt;/p&gt;</description></item><item><title>关于ValueError: too many values to unpack错误</title><link>https://www.kutake.top/archives/%E5%85%B3%E4%BA%8Evalueerror-too-many-values-to-unpack%E9%94%99%E8%AF%AF/</link><pubDate>Mon, 27 Jul 2020 14:38:07 +0800</pubDate><guid>https://www.kutake.top/archives/%E5%85%B3%E4%BA%8Evalueerror-too-many-values-to-unpack%E9%94%99%E8%AF%AF/</guid><description>&lt;p&gt;在写scrapy的时候遇到的一个坑，准备了一个由“无”元素作为value的字典作为蓝本，遍历从scrapy上得到的items字典数据，把其中有的元素放到第一个作为蓝本的字典中，于是这里就有两个操作，读取第二个字典，修改第一个字典&lt;/p&gt;</description></item><item><title>实战：comic walker漫画多章节爬虫</title><link>https://www.kutake.top/archives/python%E5%AE%9E%E6%88%98comic-walker%E6%BC%AB%E7%94%BB%E5%A4%9A%E7%AB%A0%E8%8A%82%E7%88%AC%E8%99%AB/</link><pubDate>Wed, 15 Jul 2020 10:57:00 +0800</pubDate><guid>https://www.kutake.top/archives/python%E5%AE%9E%E6%88%98comic-walker%E6%BC%AB%E7%94%BB%E5%A4%9A%E7%AB%A0%E8%8A%82%E7%88%AC%E8%99%AB/</guid><description>&lt;h2 id="为什么要做"&gt;为什么要做&lt;/h2&gt;
&lt;p&gt;还在做汉化组的扒图的时候，一直觉得comic walker这个站点的漫画拔起来非常麻烦，因为它自带一个阅读器界面，异步加载图片，而且无法右键，甚至在网页元素中，也无法直接保存图片（这应该是漫画网站的常见配置了），只能一个个在控制台中拖动图片至新的标签页才能加载图片并保存，十分麻烦，正好学习python中，就写了这个小工具。&lt;/p&gt;</description></item><item><title>json文件转xls文件</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%989json%E6%96%87%E4%BB%B6%E8%BD%ACxls%E6%96%87%E4%BB%B6/</link><pubDate>Sat, 27 Jun 2020 14:26:12 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%989json%E6%96%87%E4%BB%B6%E8%BD%ACxls%E6%96%87%E4%BB%B6/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;#写成json的文本文件内容，转换为xls文件
import xlwt
import os
import json
def get_(path):
with open(path,&amp;#39;r&amp;#39;,encoding=&amp;#39;utf-8&amp;#39;) as f:
content=f.read()
return content
def json_(str):
d=json.loads(str)
d=sorted(d.items(),key=lambda item:item[0],reverse=False)
return d
def json_16(str):
d=json.loads(str)
return d
def save_(d,path):
workbook=xlwt.Workbook(encoding=&amp;#39;utf-8&amp;#39;)
sheet1=workbook.add_sheet(&amp;#39;sheet1&amp;#39;)
r=0
c=1
for key,value in d:
sheet1.write(r,0,key)
for i in value:
sheet1.write(r,c,i)
c+=1
r+=1
c=1
workbook.save(path)
def save_16(d,path):
workbook=xlwt.Workbook(encoding=&amp;#39;utf-8&amp;#39;)
sheet1=workbook.add_sheet(&amp;#39;sheet1&amp;#39;)
for a,b in enumerate(d):
for c,v in enumerate(b):
sheet1.write(a,c,v)
workbook.save(path)
if __name__ == &amp;#34;__main__&amp;#34;:
p1=r&amp;#39;E:\vscode\code\testwork\txtfile\5.txt&amp;#39;
p2=r&amp;#39;E:\vscode\code\testwork\txtfile\5.xls&amp;#39;
save_16(json_16(get_(p1)),p2)
print(&amp;#39;END&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>实战：词云生成</title><link>https://www.kutake.top/archives/python%E5%AE%9E%E6%88%98%E8%AF%8D%E4%BA%91%E7%94%9F%E6%88%90/</link><pubDate>Sat, 27 Jun 2020 14:21:00 +0800</pubDate><guid>https://www.kutake.top/archives/python%E5%AE%9E%E6%88%98%E8%AF%8D%E4%BA%91%E7%94%9F%E6%88%90/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;import re
import jieba
import collections
import numpy as np
import wordcloud # 词云展示库
from PIL import Image # 图像处理库
import matplotlib.pyplot as plt # 图像展示库
def remove():
with open(&amp;#39;remove_words.txt&amp;#39;,&amp;#39;r&amp;#39;,encoding=&amp;#39;utf-8&amp;#39;) as f:
txt=f.read()
words = re.findall(r&amp;#39;[^\s]+&amp;#39;,txt)
list_=[]
for i in words:
if i in list_:
continue
else:
list_.append(i)
return list_
def get_words(path):
f=open(path,encoding=&amp;#39;utf-8&amp;#39;)
txt=f.read()
f.close()
words = jieba.lcut(txt)
remove_word=remove()
reword = []
for word in words:
if len(word) == 1:
continue
elif word in remove_word:
continue
else:
reword.append(word)
word_counts=collections.Counter(reword)
return word_counts
#统计词频
def wordcount(word_counts):
top=word_counts.most_common(20)
print(top)
def wordc(impath,words):
mask=np.array(Image.open(impath))
wc = wordcloud.WordCloud(
font_path=&amp;#39;C:/Windows/Fonts/simhei.ttf&amp;#39;, # 设置字体格式
mask=mask, # 设置背景图
max_words=600, # 最多显示词数
max_font_size=130 # 字体最大值
)
wc.generate_from_frequencies(words) # 从字典生成词云
image_colors = wordcloud.ImageColorGenerator(mask) # 从背景图建立颜色方案
wc.recolor(color_func=image_colors) # 将词云颜色设置为背景图方案
plt.imshow(wc) # 显示词云
plt.axis(&amp;#39;off&amp;#39;) # 关闭坐标轴
plt.show() # 显示图像
wc.to_file(&amp;#39;ff.png&amp;#39;)
if __name__ == &amp;#34;__main__&amp;#34;:
path=r&amp;#39;E:\vscode\code\ff.txt&amp;#39;
impath=r&amp;#39;E:\vscode\code\topdodo_2.jpg&amp;#39;
wordc(impath,get_words(path))
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>实战：RJ爬虫并上传本地SQL</title><link>https://www.kutake.top/archives/rj%E7%88%AC%E8%99%AB%E4%B8%8A%E4%BC%A0%E6%9C%AC%E5%9C%B0sql/</link><pubDate>Sat, 27 Jun 2020 14:18:00 +0800</pubDate><guid>https://www.kutake.top/archives/rj%E7%88%AC%E8%99%AB%E4%B8%8A%E4%BC%A0%E6%9C%AC%E5%9C%B0sql/</guid><description>&lt;p&gt;下载了上百个RJ后，如何根据声优或分类喜好来找到自己喜欢的作品就成了个问题，于是诞生出了这个代码&lt;/p&gt;
&lt;h2 id="问题拆分"&gt;&lt;strong&gt;问题拆分&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="定位需求"&gt;定位需求&lt;/h3&gt;
&lt;p&gt;查询RJ主要是在对该RJ文件夹对应网页中的标题、声优、制作社团与分类，拿到具体数据后，对数据进行查询操作。&lt;/p&gt;</description></item><item><title>生成四位验证码并验证</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%987%E7%94%9F%E6%88%90%E5%9B%9B%E4%BD%8D%E9%AA%8C%E8%AF%81%E7%A0%81%E5%B9%B6%E9%AA%8C%E8%AF%81/</link><pubDate>Sat, 27 Jun 2020 14:15:00 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%987%E7%94%9F%E6%88%90%E5%9B%9B%E4%BD%8D%E9%AA%8C%E8%AF%81%E7%A0%81%E5%B9%B6%E9%AA%8C%E8%AF%81/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;#四位数数字字母验证码，显示进行输入判断验证
from PIL import Image, ImageFilter, ImageFont,ImageDraw
import os
import random
import string
import matplotlib.pyplot as plt
# ImageFilter:Python中的图像滤波，主要对图像进行平滑、锐化、边界增强等滤波处理。
#随机选取一个数字字母，含大小写
def get_word():
word = string.ascii_letters+string.digits
return random.choice(word)
#字体像素随机颜色
def font_color():
#random.randint()在范围内取随机数
return(random.randint(32,255),random.randint(23,255),random.randint(32,255))
#背景像素随机颜色
def b_color():
return(random.randint(64,255),random.randint(64,255),random.randint(64,255))
#生成验证码图像，返回一个字符串，表示验证码
def imag(path):
w = 60*4
h = 60
d_word=&amp;#39;&amp;#39;
#新建图像对象
img = Image.new(&amp;#39;RGB&amp;#39;,(w,h),(255,255,255))
#字体对象
font = ImageFont.truetype(r&amp;#39;H:\gay化\汉化\字体\4书法 - 2\FZ宋s刻d本r秀d楷繁.ttf&amp;#39;,60)
#类似于画笔
draw = ImageDraw.Draw(img)
for i in range(w):
for j in range(h):
#画背景，用随机颜色填充每个像素
draw.point((i,j),fill=b_color())
for i in range(4):
word=get_word()
#draw.text方法进行字符绘图，()内：绘图位置，字符，字体，颜色
draw.text((i*60+10,5),word,font=font,fill=font_color())
#单个验证码相加
d_word = d_word + word
#保存验证码图像
img.save(path,&amp;#39;jpeg&amp;#39;)
#返回验证码
return d_word
#一个输入函数，调用时返回输入内容
def get_input():
return str(input(&amp;#39;请输入验证码:\n&amp;#39;))
#运行
if __name__ == &amp;#34;__main__&amp;#34;:
path = (&amp;#39;test.jpg&amp;#39;)
str_=imag(path)
test_img=Image.open(path)
plt.figure(&amp;#39;test&amp;#39;)
plt.imshow(test_img)
plt.show()
#四次机会
for i in range(4):
if str.lower(str_) == str.lower(get_input()):
print(&amp;#39;验证成功&amp;#39;)
break
else:
if i == 3:
print(&amp;#39;错误次数已用完！&amp;#39;)
else:
print(&amp;#39;错误！还有%d次机会&amp;#39;%(3-i))
#结束后删除验证码图像
os.remove(path)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>图片等比例缩放实现</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%984%E5%9B%BE%E7%89%87%E7%AD%89%E6%AF%94%E4%BE%8B%E7%BC%A9%E6%94%BE/</link><pubDate>Sat, 27 Jun 2020 14:11:00 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%984%E5%9B%BE%E7%89%87%E7%AD%89%E6%AF%94%E4%BE%8B%E7%BC%A9%E6%94%BE/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;#设定一个分辨率，使一个文件夹内所有大于该分辨率的图像都进行等比例缩放
import os
import re
from PIL import Image
#设置目录
f_path = &amp;#39;E:/vscode/code/testwork/testFile&amp;#39;
#设置iPhone5的分辨率
i_high = 640
i_width = 1136
#使用os.listdir()方法，将目录内的图像文件名，以列表的形式存入list
list=os.listdir(f_path)
#设置计数初始值
count = 0
#对每个文件进行判断
for pic in list:
#path为完整的图像文件路径
path=f_path+&amp;#39;/&amp;#39;+pic
#使用Image.open()方法，打开图像文件
im=Image.open(path)
#im.size方法获得图像的宽高，分别存入w,h
w,h=im.size
#当宽度大于i5
if w &amp;gt; i_width:
#这里判断：原图像哪边大则依据哪边作为等比缩放比例
if w&amp;gt;h:
w_new = i_width
h_new = int(h*i_width/w)
else:
w_new = int(w*i_high/h)
h_new = i_high
print(&amp;#39;%s被修改&amp;#39; %pic)
#使用resize()方法修改分辨率，((w,h),此处Image.ANTIALIAS表示高质量)
out = im.resize((w_new,h_new),Image.ANTIALIAS)
#使用re.sub方法，在字符串pic中，开头至倒数第四位字符替换为添加_new的字符串
newpic = re.sub(pic[:-4],pic[:-4]+&amp;#39;_new&amp;#39;,pic)
#处理后的图像的完整保存路径
new_path = f_path+&amp;#39;/&amp;#39;+newpic
#save方法保存
out.save(new_path)
#处理完毕计数+1
count = count + 1
elif h &amp;gt; i_high:
if w&amp;gt;h:
w_new = i_width
h_new = int(h*i_width/w)
else:
w_new = int(w*i_high/h)
h_new = i_high
print(&amp;#39;%s被修改&amp;#39; %pic)
out = im.resize((w_new,h_new),Image.ANTIALIAS)
newpic = re.sub(pic[:-4],pic[:-4]+&amp;#39;_new&amp;#39;,pic)
new_path = f_path+&amp;#39;/&amp;#39;+newpic
out.save(new_path)
count = count + 1
print(&amp;#39;处理结束\n总共有%d个文件被处理&amp;#39; %count)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>实战：通话统计及简易图表制作</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%80%9A%E8%AF%9D%E7%BB%9F%E8%AE%A1%E5%8F%8A%E7%AE%80%E6%98%93%E5%9B%BE%E8%A1%A8%E5%88%B6%E4%BD%9C/</link><pubDate>Sat, 27 Jun 2020 14:08:00 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%80%9A%E8%AF%9D%E7%BB%9F%E8%AE%A1%E5%8F%8A%E7%AE%80%E6%98%93%E5%9B%BE%E8%A1%A8%E5%88%B6%E4%BD%9C/</guid><description>&lt;p&gt;最开始的看到的python基础习题之一，现在顺便扩展一点，练习xlrd、pandas以及matplotlib的练习&lt;/p&gt;
&lt;h2 id="数据来源"&gt;数据来源&lt;/h2&gt;
&lt;p&gt;来自于联通官网的通话数据下载，文件为某年某月的通话记录详情，格式为xls**[图片缺失: 2020/06/QQ截图20200627215145.png]**&lt;!-- broken-image: 2020/06/QQ截图20200627215145.png --&gt;&lt;/p&gt;</description></item><item><title>文本识别屏蔽词转换</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%988%E6%96%87%E6%9C%AC%E8%AF%86%E5%88%AB%E5%B1%8F%E8%94%BD%E8%AF%8D%E8%BD%AC%E6%8D%A2/</link><pubDate>Sat, 27 Jun 2020 14:01:00 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%988%E6%96%87%E6%9C%AC%E8%AF%86%E5%88%AB%E5%B1%8F%E8%94%BD%E8%AF%8D%E8%BD%AC%E6%8D%A2/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;#2020/3/10
#设置一个屏蔽词文本，输入一段字符串，将其中的屏蔽词转换成*
import re
#参数为路径，返回整个屏蔽词文本
def get_f(path):
f = open(path,&amp;#39;r&amp;#39;,encoding=&amp;#39;utf-8&amp;#39;)
art=f.read()
f.close()
return art
#参数为字符串，返回一个屏蔽词列表
def get_list(str):
list_=[]
word = re.findall(r&amp;#39;[^\s]+&amp;#39;,str)
for i in word:
list_.append(i.lower())
return list_
#参数i为输入，b为屏蔽词列表
def pri(i,b):
ww=[]
ww.append(i)
h=0
for n in b:
if re.findall(n,ww[h]) != []:
s=&amp;#39;*&amp;#39;*len(n)
p = re.sub(n,s,ww[h])
h+=1
ww.append(p)
if h != 0:
#print(&amp;#39;共替换了%d个词&amp;#39;%h)
return ww[h]
else:
return i
#run
if __name__ == &amp;#34;__main__&amp;#34;:
path=r&amp;#39;E:\vscode\code\ban.txt&amp;#39;
b=get_list(get_f(path))
#print(b)
i=str(input(&amp;#39;输入：\n&amp;#39;))
print(pri(i,b))
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>随机码生成</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%982%E9%9A%8F%E6%9C%BA%E7%A0%81%E7%94%9F%E6%88%90/</link><pubDate>Fri, 26 Jun 2020 14:16:19 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%982%E9%9A%8F%E6%9C%BA%E7%A0%81%E7%94%9F%E6%88%90/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;#生成自定义数量由大小写字母与数字随机组成的号码/激活码，然后存入mysql数据库
import random
import string
import MySQLdb
#获取号码
def GenKey(length): #length为号码长度
chars = string.ascii_letters + string.digits #string.ascii.letters是26个英文字母的大小写[a-z A-Z],string.digits为[0-9]相加作为字典
return &amp;#39;&amp;#39;.join([random.choice(chars) for i in range(length)])
#拿出chars内的一个字符并重复进行length次，将得到的字符与空字符串相加，得到长度为length的号码
#保存号码
def SaveKey(content):
f = open(&amp;#39;Result Key.txt&amp;#39;, &amp;#39;a&amp;#39;)
#打开Result Key.txt，a表示“打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。”
f.write(content)
#写入一个content，此处为号码
f.write(&amp;#39;\n&amp;#39;)
#换行
f.close()
#关闭
#保存至mysql数据库
def save_sql(code_nu):
host = (&amp;#34;localhost&amp;#34;)
user = (&amp;#34;root&amp;#34;)
pass_ = (&amp;#34;123456&amp;#34;)
db = (&amp;#34;sqlforpy&amp;#34;)
#建立连接
connect = MySQLdb.connect(host,user,pass_,db)
#使用cursor()方法获取操作游标 （在操作游标中才可进行数据库操作
cursor = connect.cursor()
#使用insert into进行插入数据
sql = &amp;#34;insert into code(code)VALUES(&amp;#39;%s&amp;#39;)&amp;#34; % code_nu
#执行sql语句
cursor.execute(sql)
#使用commit提交到数据库执行保存
connect.commit()
#关闭连接
connect.close()
if __name__ == &amp;#39;__main__&amp;#39;:
length=int(input(&amp;#34;\n请输入需要的号码个数：&amp;#34;))
for i in range(length):
value = GenKey(20)
print (value)
#SaveKey(value)
save_sql(value)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>统计英文单词词频</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%983%E7%BB%9F%E8%AE%A1%E8%8B%B1%E6%96%87%E5%8D%95%E8%AF%8D%E8%AF%8D%E9%A2%91/</link><pubDate>Wed, 24 Jun 2020 14:18:03 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%983%E7%BB%9F%E8%AE%A1%E8%8B%B1%E6%96%87%E5%8D%95%E8%AF%8D%E8%AF%8D%E9%A2%91/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;#读取一个纯英文的文本文件，统计其中每个单词的出现次数，并将次数和其单词本身存入mysql数据库
import re
import MySQLdb
#读取文件信息
filename=&amp;#34;word.txt&amp;#34;
#使用open方法操作文本文件，r表示以只读方式打开文件。文件的指针将会放在文件的开头
f=open(filename,&amp;#39;r&amp;#39;)
#使用f.read方法返回整个文本文件给article，
artical=f.read()
#使用f.close关闭文件
f.close()
#将文本中的所有英文单词筛选出来 去掉标点和其他文本符号 并且将单词都小写保存在数组List中
List=[]
#&amp;#39;[a-zA-Z]+&amp;#39;正则表达式，表示大小写a-z出现一次或连续出现，这里表达一个单词
#使用re.findall方法，从article中获取单词，作为list存入word中
word=re.findall(&amp;#39;[a-zA-Z]+&amp;#39;,artical)
for i in word:
List.append(i.lower())
#把单词与出现的次数存入数据库（我也不知道为什么要存进去:)
def save_sql(word,numbers):
host = (&amp;#34;localhost&amp;#34;)
user = (&amp;#34;root&amp;#34;)
pass_ = (&amp;#34;123456&amp;#34;)
db = (&amp;#34;sqlforpy&amp;#34;)
#建立连接
connect = MySQLdb.connect(host,user,pass_,db)
#使用cursor()方法获取操作游标 （在操作游标中才可进行数据库操作
cursor = connect.cursor()
#使用insert into进行插入数据
sql = &amp;#34;insert into count_word(word,numbers)VALUES(&amp;#39;%s&amp;#39;,&amp;#39;%d&amp;#39;)&amp;#34; % (word,numbers)
#执行sql语句
try:
cursor.execute(sql)
#使用commit提交到数据库执行保存
connect.commit()
except:
#发生错误时回滚
connect.rollback()
#关闭连接
connect.close()
#统计单词数目
print(&amp;#34;%s总共有%d个单词&amp;#34; %(filename,List.__len__()))
#统计各个单词出现的频率，并且按照字典顺序输出并将内容写入文件中
#f=open(&amp;#34;result.txt&amp;#34;,&amp;#39;w&amp;#39;)
List=sorted(List)
i=0
for i in range(0,List.__len__()-1):
#使用count方法获得字符串出现的次数
count=List.count(List[i])
if(List[i]!=List[i+1]):
#print(List[i]+&amp;#34; &amp;#34;+str(count)+&amp;#34;\n&amp;#34;)
#f.write(List[i]+&amp;#34; &amp;#34;+str(count)+&amp;#34;\n&amp;#34;)
save_sql(List[i],count)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>统计文件夹内所有文件的词频</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%985%E7%BB%9F%E8%AE%A1%E6%96%87%E4%BB%B6%E5%A4%B9%E5%86%85%E6%89%80%E6%9C%89%E6%96%87%E4%BB%B6%E7%9A%84%E8%AF%8D%E9%A2%91/</link><pubDate>Tue, 23 Jun 2020 14:20:22 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%985%E7%BB%9F%E8%AE%A1%E6%96%87%E4%BB%B6%E5%A4%B9%E5%86%85%E6%89%80%E6%9C%89%E6%96%87%E4%BB%B6%E7%9A%84%E8%AF%8D%E9%A2%91/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;#在一个文件夹内存放着几个纯英文文本，统计其中出现次数最多的单词
import os
import re
f_dir=&amp;#39;E:/vscode/code/testwork/txtfile&amp;#39;
f_list=os.listdir(f_dir)
List=[]
dict={}
#传入文件名，返回文本文件路径
def get_f(name):
return f_dir+&amp;#39;/&amp;#39;+name
#传入文件路径，返回文件内文本（字符串
def open_f(fdir):
f = open(fdir,&amp;#39;r&amp;#39;,encoding=&amp;#39;UTF-8&amp;#39;)
artical=f.read()
f.close()
return artical
#传入字符串，找出其中的单词统一小写，并以list形式添加到List中
def get_w(file):
word=re.findall(&amp;#39;[a-zA-Z]+&amp;#39;,file)
for i in word:
List.append(i.lower())
#传入一个list，将其排序后，提取每个单词与其出现的次数，以字典形式存放于dict
def get_c(w_list):
s_list=sorted(w_list)
i = 0
for i in range(0,s_list.__len__()-1):
count=s_list.count(s_list[i])
if(s_list[i]!=s_list[i+1]):
dict[s_list[i]]=count
if __name__ == &amp;#34;__main__&amp;#34;:
art=&amp;#39;&amp;#39;
for i in f_list:
f_path=get_f(i)
art=art+open_f(f_path)
get_w(art)
get_c(List)
#用max方法找出字典内values最大的值
highest=max(dict.values())
print(&amp;#39;所有文件共有%d个单词&amp;#39;%List.__len__())
print(&amp;#39;出现最多次的单词：&amp;#39;)
#用最大值去提取与其相匹配的key，得到一个或多个出现次数最高的单词
print([k for k,v in dict.items() if v == highest])
print(&amp;#39;总共出现了%d次&amp;#39;%highest)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>统计文件夹内所有代码文件的代码行、注释行和空行</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%986%E7%BB%9F%E8%AE%A1%E6%96%87%E4%BB%B6%E5%A4%B9%E5%86%85%E6%89%80%E6%9C%89%E4%BB%A3%E7%A0%81%E6%96%87%E4%BB%B6%E7%9A%84%E4%BB%A3%E7%A0%81%E8%A1%8C/</link><pubDate>Mon, 22 Jun 2020 14:22:01 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%986%E7%BB%9F%E8%AE%A1%E6%96%87%E4%BB%B6%E5%A4%B9%E5%86%85%E6%89%80%E6%9C%89%E4%BB%A3%E7%A0%81%E6%96%87%E4%BB%B6%E7%9A%84%E4%BB%A3%E7%A0%81%E8%A1%8C/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;#有一个文件夹内存放着代码文件，统计所有文件的代码行，注释行和空行的总数
import os
def j_anno(line):
if line.strip().startswith(&amp;#34;#&amp;#34;):
return True
else:
return False
def j_annos(line):
if line.strip().startswith(&amp;#34;&amp;#39;&amp;#39;&amp;#39;&amp;#34;) or line.strip().startswith(&amp;#39;&amp;#34;&amp;#34;&amp;#34;&amp;#39;):
return True
else:
return False
path=&amp;#39;E:/vscode/code/testwork&amp;#39;
code_line=0
comm_line=0
space_line=0
for root,dirs,files in os.walk(path):
for item in files:
f_path=os.path.join(root,item)
f_exten=os.path.splitext(f_path)[1]
if f_exten == &amp;#39;.py&amp;#39;:
with open(f_path,&amp;#39;r&amp;#39;,encoding=&amp;#39;utf-8&amp;#39;) as fp:
#print(&amp;#39;key:&amp;#39;,key)
#print(&amp;#39;value:&amp;#39;,value)
while True:
line=fp.readline()
if not line:
break
elif j_anno(line):
comm_line +=1
elif j_annos(line):
while True:
line=fp.readline()
if j_annos(line):
break
else:
comm_line +=1
elif line.strip():
code_line+=1
else:
space_line+=1
#test
print(&amp;#39;目录：%s总共有:\n%d行代码\n%d行注释\n%d个空行&amp;#39;%(path,code_line,comm_line,space_line))
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>哈希加密验证尝试</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%9810%E5%93%88%E5%B8%8C%E5%8A%A0%E5%AF%86%E9%AA%8C%E8%AF%81/</link><pubDate>Sun, 21 Jun 2020 14:27:06 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%9810%E5%93%88%E5%B8%8C%E5%8A%A0%E5%AF%86%E9%AA%8C%E8%AF%81/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;#加入随机salt的哈希运算验证
import random
from hashlib import sha256
from hmac import HMAC
#意义在于，随机halt哈希混淆运算后的数据极难被反推出密码原文，彩虹字典的暴力破解难度极大
#参数r_pass为密码原文，salt可选，返回一个带slat与加密后的字符串
def get_pass(r_pass,salt=None):
if salt == None:
salt=sha256(str(random.random()).encode(&amp;#39;utf-8&amp;#39;)).hexdigest()[-8:]
#先生成一个HMAC()对象，然后再调用digest()生成hash之后的结果
password=HMAC(salt.encode(&amp;#39;utf-8&amp;#39;),r_pass.encode(&amp;#39;utf-8&amp;#39;),sha256).hexdigest()
return (&amp;#39;%s$%s&amp;#39;%(salt,password))
#参数r_pass为再次输入的原文密码，password为第一次哈希后的字符串
def check_pass(r_pass,password):
salt=password.split(&amp;#39;$&amp;#39;)[0]
return password == get_pass(r_pass,salt)
#run
if __name__ == &amp;#34;__main__&amp;#34;:
password=input(&amp;#39;请输入密码：\n&amp;#39;)
p=get_pass(password)
while True:
pass_=input(&amp;#39;请再次输入密码：\n&amp;#39;)
if check_pass(pass_,p):
print(&amp;#39;密码正确&amp;#39;)
break
else:
print(&amp;#39;密码错误&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>未读消息图标模拟</title><link>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%981%E6%9C%AA%E8%AF%BB%E6%B6%88%E6%81%AF%E5%9B%BE%E6%A0%87%E6%A8%A1%E6%8B%9F/</link><pubDate>Fri, 29 May 2020 14:15:00 +0800</pubDate><guid>https://www.kutake.top/archives/python%E7%BB%83%E4%B9%A0%E9%A2%981%E6%9C%AA%E8%AF%BB%E6%B6%88%E6%81%AF%E5%9B%BE%E6%A0%87%E6%A8%A1%E6%8B%9F/</guid><description>&lt;pre tabindex="0"&gt;&lt;code&gt;from PIL import Image,ImageFont,ImageDraw
import sys
reload(sys) #必须要reload
sys.setdefaultencoding(&amp;#39;utf-8&amp;#39;) #字符编码改为utf8
headPath=r&amp;#34;&amp;#34;
#头像图片路径
output=r&amp;#34;&amp;#34;
#处理后输出路径
fontPath=r&amp;#34;&amp;#34;
#字体路径
headFile=&amp;#34;&amp;#34; #头像文件
outFile=&amp;#34;&amp;#34; #输出文件
#打开图片建立画布
image=Image.open(headPath+headFile,r)
draw=ImageDraw.Draw(image)
#由图片大小确定字体大小
fontsize=min(image.size)/4
#增加文字
fontobj=ImageFont.truetype(font=fontPath+&amp;#34;AdobeHeisistd-Regular.otf&amp;#34;,size=fontsize,index=0,encoding=&amp;#34;,filename=None)#
&amp;#34;&amp;#34;&amp;#34;
&amp;#34;&amp;#34;&amp;#34;
from PIL import Image,ImageFont,ImageDraw#从PIL库导入所需模块
import sys
reload(sys) #必须要reload
sys.setdefaultencoding(&amp;#39;utf-8&amp;#39;)#字符编码改为utf8
headPath=r&amp;#34;E:\\vscode\\code\\testwork\\testFile\\&amp;#34;
#头像图片路径
outputPath=r&amp;#34;C:E:\\vscode\\code\\testwork\\testFile\\output\\&amp;#34;
#处理后输出路径
fontPath=r&amp;#34;C:\\Windows\\Fonts\\&amp;#34;
#字体路径
headFile=&amp;#34;head.jpg&amp;#34; #头像文件
outFile=&amp;#34;output.jpg&amp;#34; #输出文件
#打开图片，建立画布
image=Image.open(headPath+headFile,&amp;#39;r&amp;#39;)
draw=ImageDraw.Draw(image)
#由图片大小确定字体大小
fontsize=min(image.size)/4
#增加文字
fontobj=ImageFont.truetype(font=fontPath+&amp;#34;AdobeHeitiStd-Regular.otf&amp;#34;,size=fontsize,index=0,encoding=&amp;#39;&amp;#39;,filename=None)#实例字体对象
draw.text((image.size[0]-fontsize,0),text=&amp;#34;5&amp;#34;,fill=(255,0,0),font=fontobj,anchor=None)#用draw对象的text()方法添加文字
image.save(outputPath+outFile)#保存图片
&amp;#34;&amp;#34;&amp;#34;
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2016/12/12 上午10:13
# @Author : hukezhu
# @Site :
# @File : 0000:添加未读消息.py
# @Software: PyCharm
from PIL import Image, ImageDraw, ImageFont
#创建图片对象
headImage = Image.open(&amp;#39;E:/vscode/code/testwork/testFile/head.jpg&amp;#39;)
#获取图片对象的宽高
w,h = headImage.size
#创建字体对象
font = ImageFont.truetype(&amp;#39;C:/Windows/Fonts/Arial.ttf&amp;#39;,int(h/4))
#绘制圆形
ImageDraw.Draw(headImage).pieslice([(w/3*2,0),(w,h/3)],0,360,fill=&amp;#39;red&amp;#39;)
ImageDraw.Draw(headImage).text((w*0.76,h*0.02),&amp;#39;3&amp;#39;,font = font, fill = &amp;#39;white&amp;#39;)
#展示绘制结果(使用系统默认的图片浏览器)
#headImage.show()
#保存绘制结果
headImage.save(&amp;#39;E:/vscode/code/testwork/testFile/wode.jpg&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>SQL笔记</title><link>https://www.kutake.top/archives/sql%E7%AC%94%E8%AE%B0/</link><pubDate>Sun, 23 Feb 2020 05:51:45 +0800</pubDate><guid>https://www.kutake.top/archives/sql%E7%AC%94%E8%AE%B0/</guid><description>&lt;h2 id="sql简介"&gt;&lt;strong&gt;SQL简介&lt;/strong&gt;&lt;/h2&gt;
&lt;p&gt;SQL = Structured Query Language&lt;/p&gt;
&lt;p&gt;总的来说，SQL语言定义了这么几种操作数据库的能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DDL：Data Definition Language
&lt;ul&gt;
&lt;li&gt;DDL允许用户定义数据，也就是创建表、删除表、修改表结构这些操作。通常，DDL由数据库管理员执行。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DML：Data Manipulation Language
&lt;ul&gt;
&lt;li&gt;DML为用户提供添加、删除、更新数据的能力，这些是应用程序对数据库的日常操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DQL：Data Query Language
&lt;ul&gt;
&lt;li&gt;DQL允许用户查询数据，这也是通常最频繁的数据库日常操作&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="数据库类别"&gt;&lt;strong&gt;数据库类别&lt;/strong&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;关系型数据库(SQL)&lt;/li&gt;
&lt;li&gt;非关系型数据库(NoSQL) - MongoDB, Cassandra, Dynamo&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="关系模型"&gt;&lt;strong&gt;关系模型&lt;/strong&gt;&lt;/h2&gt;
&lt;h3 id="主键"&gt;&lt;strong&gt;主键&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;主键是关系表中记录的唯一标识。选取主键的一个基本原则是：不使用任何业务相关的字段作为主键。&lt;/p&gt;</description></item></channel></rss>