<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>YONGFEIUALL</title>
  <subtitle>izheyi.com</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://izheyi.com/"/>
  <updated>2022-02-21T02:22:45.008Z</updated>
  <id>http://izheyi.com/</id>
  
  <author>
    <name>唐胡璐</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>Python给Jenkins Job批量修改权限</title>
    <link href="http://izheyi.com/2022/02/21/Python%E7%BB%99Jenkins-Job%E6%89%B9%E9%87%8F%E4%BF%AE%E6%94%B9%E6%9D%83%E9%99%90/"/>
    <id>http://izheyi.com/2022/02/21/Python给Jenkins-Job批量修改权限/</id>
    <published>2022-02-21T01:16:09.000Z</published>
    <updated>2022-02-21T02:22:45.008Z</updated>
    
    <content type="html">&lt;p&gt;开发老是不自觉的更新UAT的Job，对测试造成一定的影响。查看了一下，Jenkins上的用户是通过第三方系统引入的，没有更合理的分组，用Role Based Strategy不能够实现对特定Job的权限控制。&lt;/p&gt;
&lt;p&gt;采用项目矩阵授权策略来实现：目前的权限不受影响，只有UAT View下的Job只有测试能访问执行。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;全局配置，设置Admin和Authenticated User权限&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;项目设置，选择不继承权限策略，并对特定用户加进来设置相应权限&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这种方式，View下有很多个Job，每来一个人都要一个一个加，可以利用代码方式批量的来添加用户权限：&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;s = jenkins.Jenkins(url=URL, username=USERNAME, password=PASSWORD)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;jobs = s.get_jobs(view_name=VIEW_NAME)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; job &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; jobs:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name = job[&lt;span class=&quot;string&quot;&gt;&#39;name&#39;&lt;/span&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    config = s.get_job_config(name)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    content = f&lt;span class=&quot;string&quot;&gt;&#39;&#39;&#39;&amp;lt;/permission&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;lt;permission&amp;gt;hudson.model.Item.Build:&amp;#123;USER&amp;#125;&amp;lt;/permission&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;lt;permission&amp;gt;hudson.model.Item.Cancel:&amp;#123;USER&amp;#125;&amp;lt;/permission&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;lt;permission&amp;gt;hudson.model.Item.Configure:&amp;#123;USER&amp;#125;&amp;lt;/permission&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;lt;permission&amp;gt;hudson.model.Item.Delete:&amp;#123;USER&amp;#125;&amp;lt;/permission&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;lt;permission&amp;gt;hudson.model.Item.Move:&amp;#123;USER&amp;#125;&amp;lt;/permission&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;lt;permission&amp;gt;hudson.model.Item.Read:&amp;#123;USER&amp;#125;&amp;lt;/permission&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;lt;permission&amp;gt;hudson.model.Item.Workspace:&amp;#123;USER&amp;#125;&amp;lt;/permission&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &#39;&#39;&#39;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    new = config.replace(&lt;span class=&quot;string&quot;&gt;&#39;&amp;lt;/permission&amp;gt;&#39;&lt;/span&gt;, content, &lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    s.reconfig_job(name, new)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;开发老是不自觉的更新UAT的Job，对测试造成一定的影响。查看了一下，Jenkins上的用户是通过第三方系统引入的，没有更合理的分组，用Role Based Strategy不能够实现对特定Job的权限控制。&lt;/p&gt;
&lt;p&gt;采用项目矩阵授权策略来实现：目前的权限不受影响，只
    
    </summary>
    
      <category term="Automation Testing" scheme="http://izheyi.com/categories/Automation-Testing/"/>
    
    
      <category term="自动化测试" scheme="http://izheyi.com/tags/%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95/"/>
    
  </entry>
  
  <entry>
    <title>Python给Gogs项目批量打Tag</title>
    <link href="http://izheyi.com/2021/10/21/Python%E7%BB%99Gogs%E9%A1%B9%E7%9B%AE%E6%89%B9%E9%87%8F%E6%89%93Tag/"/>
    <id>http://izheyi.com/2021/10/21/Python给Gogs项目批量打Tag/</id>
    <published>2021-10-21T03:03:54.000Z</published>
    <updated>2021-11-01T05:53:28.265Z</updated>
    
    <content type="html">&lt;p&gt;Gogs的Rest API不能用，就用下面的方式来实现：&lt;/p&gt;
&lt;p&gt;通过csv文件配置要打Tag的项目&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;Project Name,Release,Tag Name,Tag Branch,Title,Content&amp;#10;t1,Y,v1.1.0,master,,test1&amp;#10;t2,Y,v1.1.0,master,v1.1.0,test2&amp;#10;t3,Y,v1.1.0,master,v1.1.0,test3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;实现&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;42&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;43&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;44&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;45&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;session = HTMLSession()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Get crsf token&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;r = session.get(url=f&lt;span class=&quot;string&quot;&gt;&#39;&amp;#123;URL&amp;#125;/user/login&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;csrf = r.html.xpath(&lt;span class=&quot;string&quot;&gt;&#39;//input[@name=&quot;_csrf&quot;]/@value&#39;&lt;/span&gt;, first=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Login&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;data = &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&#39;_csrf&#39;&lt;/span&gt;: csrf,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&#39;user_name&#39;&lt;/span&gt;: USERNAME,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&#39;password&#39;&lt;/span&gt;: PASSWORD,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&#39;login_source&#39;&lt;/span&gt;: &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;session.post(url=f&lt;span class=&quot;string&quot;&gt;&#39;&amp;#123;URL&amp;#125;/user/login&#39;&lt;/span&gt;, data=data)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Get login crsf token&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;r = session.get(url=f&lt;span class=&quot;string&quot;&gt;&#39;&amp;#123;URL&amp;#125;&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;login_csrf = r.html.xpath(&lt;span class=&quot;string&quot;&gt;&#39;//meta[@name=&quot;_csrf&quot;]/@content&#39;&lt;/span&gt;, first=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Set tag for project from csv file&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;projects = get_test_csv_data(&lt;span class=&quot;string&quot;&gt;&#39;build.csv&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; project &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; projects:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; project[&lt;span class=&quot;number&quot;&gt;1&lt;/span&gt;] == &lt;span class=&quot;string&quot;&gt;&#39;Y&#39;&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        build_data = &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;string&quot;&gt;&#39;tag_name&#39;&lt;/span&gt;: project[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;],&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;string&quot;&gt;&#39;tag_target&#39;&lt;/span&gt;: project[&lt;span class=&quot;number&quot;&gt;3&lt;/span&gt;],&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;string&quot;&gt;&#39;title&#39;&lt;/span&gt;: project[&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;],&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;string&quot;&gt;&#39;content&#39;&lt;/span&gt;: project[&lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;],&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;string&quot;&gt;&#39;_csrf&#39;&lt;/span&gt;: login_csrf&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        print(f&lt;span class=&quot;string&quot;&gt;&#39;===== set tag &amp;#123;project[2]&amp;#125; for &amp;#123;project[0]&amp;#125; =====&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        print(build_data)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        r = session.post(url=f&lt;span class=&quot;string&quot;&gt;&#39;&amp;#123;URL&amp;#125;/&amp;#123;OWNER&amp;#125;/&amp;#123;project[0]&amp;#125;/releases/new&#39;&lt;/span&gt;, data=build_data)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;comment&quot;&gt;# Verify set correctly&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            res = session.get(f&lt;span class=&quot;string&quot;&gt;&#39;&amp;#123;URL&amp;#125;/&amp;#123;OWNER&amp;#125;/&amp;#123;project[0]&amp;#125;/releases&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            version = res.html.xpath(&lt;span class=&quot;string&quot;&gt;&#39;//ul[@id=&quot;release-list&quot;]//a&#39;&lt;/span&gt;, first=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;).text&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; version == project[&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;]:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                print(f&lt;span class=&quot;string&quot;&gt;&#39;===== set tag &amp;#123;project[2]&amp;#125; for &amp;#123;project[0]&amp;#125; successfully =====&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;except&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            print(f&lt;span class=&quot;string&quot;&gt;&#39;===== set tag &amp;#123;project[2]&amp;#125; for &amp;#123;project[0]&amp;#125; failed =====&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        print()&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;结果&lt;/p&gt;
&lt;figure class=&quot;highlight asciidoc&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;header&quot;&gt;===== set tag v1.1.0 for t1 =====&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#123;&lt;span class=&quot;emphasis&quot;&gt;&#39;tag_name&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;v1.1.0&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;tag_target&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;master&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;title&#39;&lt;/span&gt;: &#39;&lt;span class=&quot;emphasis&quot;&gt;&#39;, &#39;&lt;/span&gt;content&#39;: &lt;span class=&quot;emphasis&quot;&gt;&#39;test1&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;_csrf&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;iE2XUTv0z4jDvjr6HuPYTiFvOrc6MTYzNTUwMDA3OTgyNjgxNTU5Mw==&#39;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;header&quot;&gt;===== set tag v1.1.0 for t1 failed =====&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;header&quot;&gt;===== set tag v1.1.0 for t2 =====&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#123;&lt;span class=&quot;emphasis&quot;&gt;&#39;tag_name&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;v1.1.0&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;tag_target&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;master&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;title&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;v1.1.0&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;content&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;test2&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;_csrf&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;iE2XUTv0z4jDvjr6HuPYTiFvOrc6MTYzNTUwMDA3OTgyNjgxNTU5Mw==&#39;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;header&quot;&gt;===== set tag v1.1.0 for t2 successfully =====&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;header&quot;&gt;===== set tag v1.1.0 for t3 =====&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#123;&lt;span class=&quot;emphasis&quot;&gt;&#39;tag_name&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;v1.1.0&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;tag_target&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;master&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;title&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;v1.1.0&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;content&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;test3&#39;&lt;/span&gt;, &lt;span class=&quot;emphasis&quot;&gt;&#39;_csrf&#39;&lt;/span&gt;: &lt;span class=&quot;emphasis&quot;&gt;&#39;iE2XUTv0z4jDvjr6HuPYTiFvOrc6MTYzNTUwMDA3OTgyNjgxNTU5Mw==&#39;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;header&quot;&gt;===== set tag v1.1.0 for t3 successfully =====&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;Gogs的Rest API不能用，就用下面的方式来实现：&lt;/p&gt;
&lt;p&gt;通过csv文件配置要打Tag的项目&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;
    
    </summary>
    
      <category term="Automation Testing" scheme="http://izheyi.com/categories/Automation-Testing/"/>
    
    
      <category term="自动化测试" scheme="http://izheyi.com/tags/%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95/"/>
    
  </entry>
  
  <entry>
    <title>Python获得Gogs里项目最新发布版本Version</title>
    <link href="http://izheyi.com/2021/10/10/Python%E8%8E%B7%E5%BE%97Gogs%E9%87%8C%E9%A1%B9%E7%9B%AE%E6%9C%80%E6%96%B0%E5%8F%91%E5%B8%83%E7%89%88%E6%9C%ACVersion/"/>
    <id>http://izheyi.com/2021/10/10/Python获得Gogs里项目最新发布版本Version/</id>
    <published>2021-10-10T05:59:01.000Z</published>
    <updated>2021-10-11T06:09:21.198Z</updated>
    
    <content type="html">&lt;p&gt;现在每个大版本号对应的各个项目的小版本号是不一致的，要快速的获得每次发布所对应的版本号。写个脚本来实现。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;session = HTMLSession()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Get crsf token&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;r = session.get(url=URL)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;csrf = r.html.xpath(&lt;span class=&quot;string&quot;&gt;&#39;//input[@name=&quot;_csrf&quot;]&#39;&lt;/span&gt;, first=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Login&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;data = &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&#39;_csrf&#39;&lt;/span&gt;: csrf.attrs.get(&lt;span class=&quot;string&quot;&gt;&#39;value&#39;&lt;/span&gt;),&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&#39;user_name&#39;&lt;/span&gt;: USERNAME,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&#39;password&#39;&lt;/span&gt;: PASSWORD,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&#39;login_source&#39;&lt;/span&gt;: &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;session.post(url=URL, data=data)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Get project latest release version&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;release_version = &amp;#123;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; p &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; PROJECT_LIST:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    res = session.get(f&lt;span class=&quot;string&quot;&gt;&#39;https://&amp;#123;URL&amp;#125;/&amp;#123;p&amp;#125;/releases&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    version = res.html.xpath(&lt;span class=&quot;string&quot;&gt;&#39;//ul[@id=&quot;release-list&quot;]//a&#39;&lt;/span&gt;, first=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;).text&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    release_version[p] = version&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;print(json.dumps(release_version, indent=&lt;span class=&quot;number&quot;&gt;4&lt;/span&gt;))&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;并通过API的方式，直接把相关信息填写到Confluence上。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;con = Confluence(url=URL, username=USERNAME, password=PASSWORD)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;body = &lt;span class=&quot;string&quot;&gt;&#39;&amp;lt;div class=&quot;table-wrap&quot;&amp;gt;&amp;lt;table class=&quot;relative-table wrapped confluenceTable&quot;&amp;gt;版本信息&amp;lt;/table&amp;gt;&amp;lt;/div&amp;gt;&#39;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;con.create_page(space=&lt;span class=&quot;string&quot;&gt;&#39;BDP&#39;&lt;/span&gt;, title=&lt;span class=&quot;string&quot;&gt;&#39;testtesttest&#39;&lt;/span&gt;, parent_id=&lt;span class=&quot;number&quot;&gt;85295571&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                body=body)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;最后，把脚本集成到Jenkins上，每次只要运行一下Job就可以快速完整版本号的整理工作。&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;现在每个大版本号对应的各个项目的小版本号是不一致的，要快速的获得每次发布所对应的版本号。写个脚本来实现。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=
    
    </summary>
    
      <category term="Automation Testing" scheme="http://izheyi.com/categories/Automation-Testing/"/>
    
    
      <category term="自动化测试" scheme="http://izheyi.com/tags/%E8%87%AA%E5%8A%A8%E5%8C%96%E6%B5%8B%E8%AF%95/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: JWT登录认证（20）</title>
    <link href="http://izheyi.com/2021/10/06/FastAPI-%E7%99%BB%E5%BD%95%E8%AE%A4%E8%AF%81%EF%BC%8820%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/06/FastAPI-登录认证（20）/</id>
    <published>2021-10-06T13:30:11.000Z</published>
    <updated>2021-10-06T08:25:29.385Z</updated>
    
    <content type="html">&lt;p&gt;至此，FastAPI的基本使用和整个流程都过完了。接下来看一下登录认证，是一个系统里最基本的功能，有些页面只能登录之后才能够访问。&lt;/p&gt;
&lt;p&gt;有Session和Token两种方式实现，目前最流行的下面token方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用户登录后，返回一个token给前端，后台不存储该token&lt;/li&gt;
&lt;li&gt;前端再带着这个token去访问需要登录的页面&lt;/li&gt;
&lt;li&gt;&lt;p&gt;后端根据token去判断用户，确定当前登录用户&lt;/p&gt;
&lt;p&gt;Bearer的简单OAuth2，前面已聊过&lt;a href=&quot;2021/10/03/FastAPI-Security（14）/&quot;&gt;FastAPI: Security（14）&lt;/a&gt;，当时还没有生成token，OAuth2不能生成token，我们一般用&lt;code&gt;JWT&lt;/code&gt;来实现&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;JWT&quot;&gt;&lt;a href=&quot;#JWT&quot; class=&quot;headerlink&quot; title=&quot;JWT&quot;&gt;&lt;/a&gt;JWT&lt;/h4&gt;&lt;p&gt;JWT全称是&lt;code&gt;Json Web Token&lt;/code&gt;，JWT认证目前是前后端分离中非常流行的一种认证方式，生成的token分为三个部分: HEADER.PAYLOAD.SIGNATURE, 这三个部分都是可逆算法base64加密后的字符串, 最后用&lt;code&gt;.&lt;/code&gt;拼接&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;HEADER&lt;/p&gt;
&lt;p&gt;通常是加密算法&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PAYLOAD&lt;/p&gt;
&lt;p&gt;存储的自定义信息和token的过期时间&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SIGNATURE&lt;/p&gt;
&lt;p&gt;这个签证信息由三部分组成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;header (base64后的)&lt;/li&gt;
&lt;li&gt;payload (base64后的)&lt;/li&gt;
&lt;li&gt;secret （盐值(salt): 指的是加密时加入的自定义的字符串, 最好是随机或者杂乱的字符串, 这样更能够确定加密后字符串的唯一性, 可以使用settings中的SECRET_KEY）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个部分需要base64加密后的header和base64加密后的payload使用&lt;code&gt;.&lt;/code&gt;连接组成的字符串，然后通过header中声明的加密方式进行加盐&lt;code&gt;secret&lt;/code&gt;组合加密，然后就构成了jwt的第三部分。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;   python中有好几多库可以实现JWT认证，这里也用官网使用的&lt;code&gt;python-jose&lt;/code&gt;，Python-jose需要一个额外的加密后端。这里我们使用的是推荐的后端:&lt;code&gt;pyca/cryptography&lt;/code&gt;&lt;/p&gt;
   &lt;figure class=&quot;highlight accesslog&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;pip install python-jose&lt;span class=&quot;string&quot;&gt;[cryptography]&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h6 id=&quot;生成token&quot;&gt;&lt;a href=&quot;#生成token&quot; class=&quot;headerlink&quot; title=&quot;生成token&quot;&gt;&lt;/a&gt;生成token&lt;/h6&gt;   &lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; jose &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; jwt&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; datetime &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; datetime, timedelta&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 加密密钥&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;SECRET_KEY = &lt;span class=&quot;string&quot;&gt;&quot;testjwt&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 设置过期时间 示例5分钟&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;expire = datetime.utcnow() + timedelta(minutes=&lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# exp 是固定写法必须得传  username和uid是自己存的值&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;to_encode = &amp;#123;&lt;span class=&quot;string&quot;&gt;&quot;exp&quot;&lt;/span&gt;: expire, &lt;span class=&quot;string&quot;&gt;&quot;username&quot;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;admin&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;uid&quot;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;12345&quot;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 生成token&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;token = jwt.encode(to_encode, SECRET_KEY, algorithm=&lt;span class=&quot;string&quot;&gt;&quot;HS256&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h6 id=&quot;解密token&quot;&gt;&lt;a href=&quot;#解密token&quot; class=&quot;headerlink&quot; title=&quot;解密token&quot;&gt;&lt;/a&gt;解密token&lt;/h6&gt;   &lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; jose.exceptions &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; ExpiredSignatureError, JWTError&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    payload = jwt.decode(token, SECRET_KEY, algorithms=&lt;span class=&quot;string&quot;&gt;&quot;HS256&quot;&lt;/span&gt; )&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    print(payload)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;except&lt;/span&gt; ExpiredSignatureError &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; e:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    print(&lt;span class=&quot;string&quot;&gt;&quot;token过期&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;except&lt;/span&gt; JWTError &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; e:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    print(&lt;span class=&quot;string&quot;&gt;&quot;token验证失败&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;FastAPI实现JWT认证&quot;&gt;&lt;a href=&quot;#FastAPI实现JWT认证&quot; class=&quot;headerlink&quot; title=&quot;FastAPI实现JWT认证&quot;&gt;&lt;/a&gt;FastAPI实现JWT认证&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;&lt;p&gt;加密解密的公共方法&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;create_jwt_token&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(data: dict, expires_delta: Optional[timedelta] = None)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    to_encode = data.copy()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; expires_delta:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        expire = datetime.utcnow() + expires_delta&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;else&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        expire = datetime.utcnow() + timedelta(minutes=config.ACCESS_TOKEN_EXPIRE_MINUTES)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    to_encode.update(&amp;#123;&lt;span class=&quot;string&quot;&gt;&quot;exp&quot;&lt;/span&gt;: expire&amp;#125;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    token = jwt.encode(claims=to_encode, key=config.SECRET_KEY, algorithm=config.ALGORITHM)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; token&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;decode_jwt_token&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(token: str)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        payload = jwt.decode(token=token, key=config.SECRET_KEY, algorithms=config.ALGORITHM)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; payload&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;except&lt;/span&gt; (jwt.JWTError, jwt.ExpiredSignatureError, AttributeError) &lt;span class=&quot;keyword&quot;&gt;as&lt;/span&gt; e:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                            detail=f&lt;span class=&quot;string&quot;&gt;&#39;access token failed: &amp;#123;e&amp;#125;&#39;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                            &lt;span class=&quot;comment&quot;&gt;# 根据OAuth2规范, 认证失败需要在响应头中添加如下键值对&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                            headers=&amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;WWW-Authenticate&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;Bearer&quot;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                            )&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;登录生成Token&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;31&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;oauth2_scheme = OAuth2PasswordBearer(tokenUrl=&lt;span class=&quot;string&quot;&gt;&quot;/api/login&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@router.post(&#39;/api/login&#39;, tags=[&#39;users&#39;])&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;user_login&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(username: str = Form&lt;span class=&quot;params&quot;&gt;(...)&lt;/span&gt;, password: str = Form&lt;span class=&quot;params&quot;&gt;(...)&lt;/span&gt;, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db_user = crud.get_user_by_mail(db, username)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; db_user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;404&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&quot;User not found&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; password != db_user.hash_password:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;passwod incorrect&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    data = &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;email&#39;&lt;/span&gt;: db_user.email, &lt;span class=&quot;string&quot;&gt;&#39;user_id&#39;&lt;/span&gt;: db_user.id&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    token = jwttoken.create_jwt_token(data)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&quot;token&quot;&lt;/span&gt;: token, &lt;span class=&quot;string&quot;&gt;&quot;token_type&quot;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;bearer&quot;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@router.get(&#39;/current/user&#39;, tags=[&#39;users&#39;])&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_current_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(token: Optional[str] = Header&lt;span class=&quot;params&quot;&gt;(...)&lt;/span&gt;, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    payload = jwttoken.decode_jwt_token(token)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    email: str = payload.get(&lt;span class=&quot;string&quot;&gt;&quot;email&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; email &lt;span class=&quot;keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                            detail=f&lt;span class=&quot;string&quot;&gt;&#39;access token failed&#39;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                            &lt;span class=&quot;comment&quot;&gt;# 根据OAuth2规范, 认证失败需要在响应头中添加如下键值对&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                            headers=&amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;WWW-Authenticate&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;Bearer&quot;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;                            )&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    user = crud.get_user_by_mail(db, email=email)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; user &lt;span class=&quot;keyword&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;404&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&quot;User not found&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; user&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;验证Token&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/jwt.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;至此，FastAPI的基本使用和整个流程都过完了。接下来看一下登录认证，是一个系统里最基本的功能，有些页面只能登录之后才能够访问。&lt;/p&gt;
&lt;p&gt;有Session和Token两种方式实现，目前最流行的下面token方式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用户登录后，返回一个tok
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: Docker部署（19）</title>
    <link href="http://izheyi.com/2021/10/06/FastAPI-Docker%E9%83%A8%E7%BD%B2%EF%BC%8819%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/06/FastAPI-Docker部署（19）/</id>
    <published>2021-10-06T09:10:27.000Z</published>
    <updated>2021-10-04T09:51:53.666Z</updated>
    
    <content type="html">&lt;p&gt;用Docker去部署应用已是目前最流行和通用的方式。现在把之前的项目部署到Docker上去。&lt;/p&gt;
&lt;h4 id=&quot;准备Dockerfile&quot;&gt;&lt;a href=&quot;#准备Dockerfile&quot; class=&quot;headerlink&quot; title=&quot;准备Dockerfile&quot;&gt;&lt;/a&gt;准备Dockerfile&lt;/h4&gt;&lt;p&gt;项目根目录下创建&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight dockerfile&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;FROM&lt;/span&gt; python:&lt;span class=&quot;number&quot;&gt;3.7&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;WORKDIR&lt;/span&gt; &lt;span class=&quot;bash&quot;&gt;/fastapi&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;COPY&lt;/span&gt; &lt;span class=&quot;bash&quot;&gt;./requirements.txt /fastapi/requirements.txt&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;RUN&lt;/span&gt; &lt;span class=&quot;bash&quot;&gt;pip install --no-cache-dir --upgrade -r /fastapi/requirements.txt&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;COPY&lt;/span&gt; &lt;span class=&quot;bash&quot;&gt;. /fastapi/&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;built_in&quot;&gt;CMD&lt;/span&gt; &lt;span class=&quot;bash&quot;&gt;[&lt;span class=&quot;string&quot;&gt;&quot;uvicorn&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;main:app&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;--host&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;0.0.0.0&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;--port&quot;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&quot;80&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;Build-Docker-Image&quot;&gt;&lt;a href=&quot;#Build-Docker-Image&quot; class=&quot;headerlink&quot; title=&quot;Build Docker Image&quot;&gt;&lt;/a&gt;Build Docker Image&lt;/h4&gt;&lt;p&gt;去到项目根目录下，执行下面命令&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker build -t myfastapi:user .&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;验证&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;PS E:\fastapi&amp;#62; docker image ls&amp;#10;REPOSITORY   TAG       IMAGE ID       CREATED          SIZE&amp;#10;myfastapi    user      0790ae3493a3   14 seconds ago   972MB&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;Start-Docker-Container&quot;&gt;&lt;a href=&quot;#Start-Docker-Container&quot; class=&quot;headerlink&quot; title=&quot;Start Docker Container&quot;&gt;&lt;/a&gt;Start Docker Container&lt;/h4&gt;&lt;p&gt;执行下面命令，部署应用到Container&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker run -d --name fastapiservice -p 80:80 myfastapi:user&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;验证&lt;/p&gt;
&lt;figure class=&quot;highlight cpp&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;PS E:\fastapi&amp;gt; docker container ls&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;CONTAINER ID   IMAGE            COMMAND                  CREATED              STATUS              PORTS                NAMES&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;number&quot;&gt;7&lt;/span&gt;b550b5a7ebb   myfastapi:user   &lt;span class=&quot;string&quot;&gt;&quot;uvicorn main:app --…&quot;&lt;/span&gt;   About a minute ago   Up About a minute   &lt;span class=&quot;number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;.0&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;.0&lt;/span&gt;:&lt;span class=&quot;number&quot;&gt;80&lt;/span&gt;-&amp;gt;&lt;span class=&quot;number&quot;&gt;80&lt;/span&gt;/tcp   fastapiservice&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;验证部署成功&quot;&gt;&lt;a href=&quot;#验证部署成功&quot; class=&quot;headerlink&quot; title=&quot;验证部署成功&quot;&gt;&lt;/a&gt;验证部署成功&lt;/h4&gt;&lt;p&gt;&lt;img src=&quot;/images/fastapi/docker.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;用Docker去部署应用已是目前最流行和通用的方式。现在把之前的项目部署到Docker上去。&lt;/p&gt;
&lt;h4 id=&quot;准备Dockerfile&quot;&gt;&lt;a href=&quot;#准备Dockerfile&quot; class=&quot;headerlink&quot; title=&quot;准备Dockerfile&quot;&gt;
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: 项目结构（18）</title>
    <link href="http://izheyi.com/2021/10/05/FastAPI-%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84%EF%BC%8817%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/05/FastAPI-项目结构（17）/</id>
    <published>2021-10-05T07:16:39.000Z</published>
    <updated>2021-10-05T03:27:08.570Z</updated>
    
    <content type="html">&lt;p&gt;如前言所述，开发一个项目，不可能所所有的文件都放到一个文件里，是需要有结构化的目录。&lt;/p&gt;
&lt;p&gt;简单结构如下：&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;E:.&amp;#10;&amp;#9474;  config.py&amp;#10;&amp;#9474;  dependencies.py&amp;#10;&amp;#9474;  main.py&amp;#10;&amp;#9474;  requirements.txt&amp;#10;&amp;#9474;&amp;#10;&amp;#9500;&amp;#9472;models&amp;#10;&amp;#9474;  &amp;#9474;  crud.py&amp;#10;&amp;#9474;  &amp;#9474;  database.py&amp;#10;&amp;#9474;  &amp;#9474;  models.py&amp;#10;&amp;#9474;  &amp;#9474;  schemas.py&amp;#10;&amp;#9474;  &amp;#9474;  __init__.py&amp;#10;&amp;#9474;&amp;#10;&amp;#9500;&amp;#9472;routers&amp;#10;&amp;#9474;  &amp;#9474;  users.py&amp;#10;&amp;#9474;  &amp;#9474;  __init__.py&amp;#10;&amp;#9474;&amp;#10;&amp;#9500;&amp;#9472;static&amp;#10;&amp;#9474;      fastapi.jpg&amp;#10;&amp;#9474;&amp;#10;&amp;#9500;&amp;#9472;templates&amp;#10;&amp;#9474;  &amp;#9474;  index.html&amp;#10;&amp;#9474;&amp;#10;&amp;#9500;&amp;#9472;utils&amp;#10;&amp;#9474;  &amp;#9474;  __init__.py&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;models&lt;/p&gt;
&lt;p&gt;对数据库和数据的定义操作&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;routers&lt;/p&gt;
&lt;p&gt;路由控制，更好的按模块化划分系统功能实现&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;static&lt;/p&gt;
&lt;p&gt;引用的静态资源文件，js,css&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;templates&lt;/p&gt;
&lt;p&gt;前面页面的模板文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;dependencies&lt;/p&gt;
&lt;p&gt;系统所需的依赖项&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;main&lt;/p&gt;
&lt;p&gt;系统启动入口&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;config&lt;/p&gt;
&lt;p&gt;配置参数，连接数据等&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;utils&lt;/p&gt;
&lt;p&gt;公共的方法，E.g., JWT token的处理&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;requirements&lt;/p&gt;
&lt;p&gt;系统所依赖的外部库&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;项目请参见：&lt;a href=&quot;https://github.com/yongfeiuall/fastapi&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;github-fastapi&lt;/a&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;如前言所述，开发一个项目，不可能所所有的文件都放到一个文件里，是需要有结构化的目录。&lt;/p&gt;
&lt;p&gt;简单结构如下：&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;l
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: APIRouter（17）</title>
    <link href="http://izheyi.com/2021/10/05/FastAPI-APIRouter%EF%BC%8817%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/05/FastAPI-APIRouter（17）/</id>
    <published>2021-10-05T06:59:41.000Z</published>
    <updated>2021-10-04T07:55:30.854Z</updated>
    
    <content type="html">&lt;p&gt;从前面的例子看，所有的Views操作都放在一个文件里，代码不易维护。为了更好的管理路径和代码，可以通过&lt;code&gt;APIRouter&lt;/code&gt;来为该模块创建路径操作，给我们提供了在多个文件中注册路由的功能。&lt;/p&gt;
&lt;h4 id=&quot;使用Router&quot;&gt;&lt;a href=&quot;#使用Router&quot; class=&quot;headerlink&quot; title=&quot;使用Router&quot;&gt;&lt;/a&gt;使用Router&lt;/h4&gt;&lt;p&gt;在项目下创建&lt;code&gt;routers -&amp;gt; users.py&lt;/code&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;42&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;43&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;44&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; fastapi &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; APIRouter, Depends, HTTPException&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; sqlalchemy.orm &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; Session&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; typing &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; List&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; models &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; crud,schemas&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; dependencies &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; get_db&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;router = APIRouter()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 新建用户&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@router.post(&quot;/users/&quot;, response_model=schemas.User, tags=[&#39;users&#39;])&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;create_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user: schemas.UserCreate, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; crud.create_user(db, user=user)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 通过id查询用户&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@router.get(&quot;/user/&amp;#123;user_id&amp;#125;&quot;, response_model=schemas.User, tags=[&#39;users&#39;])&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;read_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user_id: int, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db_user = crud.get_user(db, user_id=user_id)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; db_user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;404&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&quot;User not found&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; db_user&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 所有用户&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@router.get(&#39;/users/&#39;, response_model=List[schemas.User], tags=[&#39;users&#39;])&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;read_users&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(start: int=&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, limit: int=&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; crud.get_users(db, start, limit)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Delete user&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@router.delete(&#39;/user/&amp;#123;user_id&amp;#125;&#39;, response_model=schemas.User, tags=[&#39;users&#39;])&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;delete_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user_id: int, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db_user = crud.delete_user(db, user_id=user_id)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; db_user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;User not found&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; db_user&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Update User&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@router.put(&#39;/user/&amp;#123;user_id&amp;#125;&#39;, response_model=schemas.User, tags=[&#39;users&#39;])&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;update_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user_id: int, update_user: schemas.UserUpdate, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db_user = crud.update_user(db, user_id=user_id, update_user=update_user)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; db_user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;User not found&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; db_user&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;注册Router&quot;&gt;&lt;a href=&quot;#注册Router&quot; class=&quot;headerlink&quot; title=&quot;注册Router&quot;&gt;&lt;/a&gt;注册Router&lt;/h4&gt;&lt;p&gt;将我们的 APIRouter 注册到核心对象上去。&lt;code&gt;main.py&lt;/code&gt;&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 导入 FastAPI&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; fastapi &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; FastAPI&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; routers &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; users&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; uvicorn&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; config&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 实例化 FastAPI&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app = FastAPI()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app.include_router(users.router)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/router.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;从前面的例子看，所有的Views操作都放在一个文件里，代码不易维护。为了更好的管理路径和代码，可以通过&lt;code&gt;APIRouter&lt;/code&gt;来为该模块创建路径操作，给我们提供了在多个文件中注册路由的功能。&lt;/p&gt;
&lt;h4 id=&quot;使用Router&quot;&gt;&lt;a href=&quot;
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: static file &amp; template（16）</title>
    <link href="http://izheyi.com/2021/10/04/FastAPI-static-template%EF%BC%8816%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/04/FastAPI-static-template（16）/</id>
    <published>2021-10-04T12:32:18.000Z</published>
    <updated>2021-10-04T08:05:25.210Z</updated>
    
    <content type="html">&lt;p&gt;合理的使用静态资源和页面模板，更好的来实现网站前后端分离。&lt;/p&gt;
&lt;p&gt;静态资源通过&lt;code&gt;aiofiles&lt;/code&gt;来实现。&lt;/p&gt;
&lt;p&gt;简单理解，模板就是 &lt;code&gt;web&lt;/code&gt; 后端向前端发送的 &lt;code&gt;html&lt;/code&gt; 模型，还是&lt;code&gt;jinia2&lt;/code&gt;来实现。&lt;/p&gt;
&lt;h4 id=&quot;安装&quot;&gt;&lt;a href=&quot;#安装&quot; class=&quot;headerlink&quot; title=&quot;安装&quot;&gt;&lt;/a&gt;安装&lt;/h4&gt;&lt;figure class=&quot;highlight cmake&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;pip &lt;span class=&quot;keyword&quot;&gt;install&lt;/span&gt; aiofiles&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;pip &lt;span class=&quot;keyword&quot;&gt;install&lt;/span&gt; jinja2&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;验证&quot;&gt;&lt;a href=&quot;#验证&quot; class=&quot;headerlink&quot; title=&quot;验证&quot;&gt;&lt;/a&gt;验证&lt;/h4&gt;&lt;ol&gt;
&lt;li&gt;&lt;p&gt;在项目根目录下，创建&lt;code&gt;static&lt;/code&gt;和&lt;code&gt;templates&lt;/code&gt;文件夹。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;在static下添加一个图片&lt;code&gt;fastapi.jpg&lt;/code&gt;。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;在templates下添加一个页面模板。&lt;/p&gt;
&lt;figure class=&quot;highlight html&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;doctype&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;title&quot;&gt;html&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;title&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;title&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;Welcome&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;title&quot;&gt;title&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;title&quot;&gt;link&lt;/span&gt; &lt;span class=&quot;attribute&quot;&gt;href&lt;/span&gt;=&lt;span class=&quot;value&quot;&gt;&quot;&amp;#123;&amp;#123; url_for(&#39;static&#39;, path=&#39;/fastapi.jpg&#39;) &amp;#125;&amp;#125;&quot;&lt;/span&gt; &lt;span class=&quot;attribute&quot;&gt;rel&lt;/span&gt;=&lt;span class=&quot;value&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;title&quot;&gt;head&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;title&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;tag&quot;&gt;&amp;lt;&lt;span class=&quot;title&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;Welcome: &amp;#123;&amp;#123; username &amp;#125;&amp;#125;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;title&quot;&gt;h1&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;title&quot;&gt;body&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;tag&quot;&gt;&amp;lt;/&lt;span class=&quot;title&quot;&gt;html&lt;/span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;接口返回html页面。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; fastapi.responses &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; HTMLResponse&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; fastapi.staticfiles &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; StaticFiles&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; fastapi.templating &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; Jinja2Templates&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app.mount(&lt;span class=&quot;string&quot;&gt;&quot;/static&quot;&lt;/span&gt;, StaticFiles(directory=&lt;span class=&quot;string&quot;&gt;&quot;static&quot;&lt;/span&gt;), name=&lt;span class=&quot;string&quot;&gt;&quot;static&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;templates = Jinja2Templates(directory=&lt;span class=&quot;string&quot;&gt;&quot;templates&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Return html page&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&quot;/user/&amp;#123;user_id&amp;#125;&quot;, response_class=HTMLResponse)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;read_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(request: Request, user_id: int, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db_user = crud.get_user(db, user_id=user_id)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; db_user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;404&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&quot;User not found&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; templates.TemplateResponse(&lt;span class=&quot;string&quot;&gt;&#39;index.html&#39;&lt;/span&gt;, &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;request&#39;&lt;/span&gt;: request, &lt;span class=&quot;string&quot;&gt;&#39;username&#39;&lt;/span&gt;: db_user.email&amp;#125;)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;结果&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/response_html.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;合理的使用静态资源和页面模板，更好的来实现网站前后端分离。&lt;/p&gt;
&lt;p&gt;静态资源通过&lt;code&gt;aiofiles&lt;/code&gt;来实现。&lt;/p&gt;
&lt;p&gt;简单理解，模板就是 &lt;code&gt;web&lt;/code&gt; 后端向前端发送的 &lt;code&gt;html&lt;/code&gt; 模型，还是&lt;c
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: Mysql数据库操作（15）</title>
    <link href="http://izheyi.com/2021/10/04/FastAPI-%E6%95%B0%E6%8D%AE%E5%BA%93%E6%93%8D%E4%BD%9C%EF%BC%8815%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/04/FastAPI-数据库操作（15）/</id>
    <published>2021-10-04T09:24:50.000Z</published>
    <updated>2021-10-04T07:55:58.576Z</updated>
    
    <content type="html">&lt;p&gt;FastAPI可以通过SQLAlchemy将其轻松的适应于任何的数据库。SQLAlchemy是一个ORM（object-relational mapping）的框架。在ORM中，你创建一个类就会通过SQLAlchemy将其自动转成一张表，在类中的每一个属性就会将其转成表中的字段。&lt;/p&gt;
&lt;p&gt;需要安装&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;pip install sqlalchemy&amp;#10;pip install pymysql&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;统一来管理数据库相关：&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;├─db&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;│      crud.py&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;│      database.py&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;│      models.py&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;│      schemas.py&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;│      __init__.py&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;database-py-数据库配置相关&quot;&gt;&lt;a href=&quot;#database-py-数据库配置相关&quot; class=&quot;headerlink&quot; title=&quot;database.py 数据库配置相关&quot;&gt;&lt;/a&gt;database.py 数据库配置相关&lt;/h4&gt;&lt;p&gt;在数据库相关的配置文件中，首先创建一个SQLAlchemy的”engine”，然后创建SessionLocal实例进行会话，最后创建模型类的基类。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; sqlalchemy &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; create_engine&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; sqlalchemy.ext.declarative &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; declarative_base&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; sqlalchemy.orm &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; sessionmaker&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;SQLALCHEMY_DATABASE_URL = &lt;span class=&quot;string&quot;&gt;&quot;mysql+pymysql://root:123456@127.0.0.1:3306/test&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;engine = create_engine(&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    SQLALCHEMY_DATABASE_URL, encoding=&lt;span class=&quot;string&quot;&gt;&#39;utf8&#39;&lt;/span&gt;, echo=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# SQLAlchemy中，CRUD是通过会话进行管理的，所以需要先创建会话，&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;SessionLocal = sessionmaker(autocommit=&lt;span class=&quot;keyword&quot;&gt;False&lt;/span&gt;, autoflush=&lt;span class=&quot;keyword&quot;&gt;False&lt;/span&gt;, bind=engine)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 创建基本映射类&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;Base = declarative_base()&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;models-py-数据库模型表&quot;&gt;&lt;a href=&quot;#models-py-数据库模型表&quot; class=&quot;headerlink&quot; title=&quot;models.py 数据库模型表&quot;&gt;&lt;/a&gt;models.py 数据库模型表&lt;/h4&gt;&lt;p&gt;通过数据库配置文件中的基类来创建模型类。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; sqlalchemy &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; Boolean, Column, Integer, String&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; database &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; Base&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(Base)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    __tablename__ = &lt;span class=&quot;string&quot;&gt;&quot;users&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    id = Column(Integer, primary_key=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;, index=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    email = Column(String(&lt;span class=&quot;number&quot;&gt;32&lt;/span&gt;), unique=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;, index=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    hash_password = Column(String(&lt;span class=&quot;number&quot;&gt;32&lt;/span&gt;))&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    is_active = Column(Boolean, default=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;schemas-py-模型验证&quot;&gt;&lt;a href=&quot;#schemas-py-模型验证&quot; class=&quot;headerlink&quot; title=&quot;schemas.py 模型验证&quot;&gt;&lt;/a&gt;schemas.py 模型验证&lt;/h4&gt;&lt;p&gt;定义请求参数模型验证与响应模型验证的Pydantic模型，其中响应模型中设置orm_mode=True参数，表示与ORM模型兼容，因为后续中返回的数据库查询是orm模型，通过设置这个参数可以将orm模型通过pydantic模型进行验证。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;31&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; pydantic &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; BaseModel&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;UserBase&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    email: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;UserCreate&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(UserBase)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    请求模型验证：&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    email:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    password:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    password: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;UserUpdate&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(UserBase)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    is_active: bool&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(UserBase)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    响应模型：&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    id:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    email:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    is_active&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    并且设置orm_mode与之兼容&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    id: int&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    is_active: bool&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Config&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        orm_mode = &lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;crud-py-数据库操作相关&quot;&gt;&lt;a href=&quot;#crud-py-数据库操作相关&quot; class=&quot;headerlink&quot; title=&quot;crud.py 数据库操作相关&quot;&gt;&lt;/a&gt;crud.py 数据库操作相关&lt;/h4&gt;&lt;p&gt;通过传入数据库连接以及参数等进行数据库操作，包括创建用户、查询用户等，返回的是orm模型对象。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;42&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;from&lt;/span&gt; sqlalchemy.orm &lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; Session&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;import&lt;/span&gt; models, schemas&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Get user by id&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(db: Session, user_id: int)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; db.query(models.User).filter(models.User.id == user_id).first()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Get all users&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_users&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(db: Session, start: int=&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, limit: int=&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; db.query(models.User).offset(start).limit(limit).all()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# creae user&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;create_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(db: Session, user: schemas.UserCreate)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    fake_hashed_password = user.password + &lt;span class=&quot;string&quot;&gt;&quot;notreallyhashed&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    user = models.User(email=user.email, hash_password=fake_hashed_password)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db.add(user)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db.commit()  &lt;span class=&quot;comment&quot;&gt;# 提交保存到数据库中&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db.refresh(user)  &lt;span class=&quot;comment&quot;&gt;# 刷新&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; user&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Delete user&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;delete_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(db: Session, user_id: int)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    user = db.query(models.User).filter(models.User.id == user_id).first()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        db.delete(user)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        db.commit()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        db.flush()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; user&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Update user&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;update_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(db: Session, user_id: int, update_user: schemas.UserUpdate)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    user = db.query(models.User).filter(models.User.id == user_id).first()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        update_user = update_user.dict(exclude_unset=&lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; k, v &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; update_user.items():&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;            setattr(user, k, v)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        db.commit()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        db.flush()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        db.refresh(user)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; user&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;调用验证&quot;&gt;&lt;a href=&quot;#调用验证&quot; class=&quot;headerlink&quot; title=&quot;调用验证&quot;&gt;&lt;/a&gt;调用验证&lt;/h4&gt;&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;33&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;34&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;35&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;36&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;37&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;38&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;39&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;40&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;41&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;42&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;43&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;44&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;45&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;46&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;47&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;48&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;49&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;50&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;51&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;52&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;Base.metadata.create_all(bind=engine) &lt;span class=&quot;comment&quot;&gt;#数据库初始化，如果没有库或者表，会自动创建&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 实例化 FastAPI&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app = FastAPI()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Dependency&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;get_db&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    每一个请求处理完毕后会关闭当前连接，不同的请求使用不同的连接&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    :return:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db = SessionLocal()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;try&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;yield&lt;/span&gt; db&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;finally&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        db.close()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 新建用户&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&quot;/users/&quot;, response_model=schemas.User)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;create_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user: schemas.UserCreate, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; crud.db_create_user(db=db, user=user)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 通过id查询用户&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&quot;/user/&amp;#123;user_id&amp;#125;&quot;, response_model=schemas.User)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;read_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user_id: int, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db_user = crud.get_user(db, user_id=user_id)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; db_user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;404&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&quot;User not found&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; db_user&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# 所有用户&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&#39;, response_model=List[schemas.User])&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;read_users&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(start: int=&lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, limit: int=&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; crud.get_users(db, start, limit)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Delete user&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.delete(&#39;/user/&amp;#123;user_id&amp;#125;&#39;, response_model=schemas.User)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;delete_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user_id: int, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db_user = crud.delete_user(db, user_id=user_id)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; db_user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;User not found&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; db_user&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;comment&quot;&gt;# Update User&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.put(&#39;/user/&amp;#123;user_id&amp;#125;&#39;, response_model=schemas.User)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;update_user&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user_id: int, update_user: schemas.UserUpdate, db: Session = Depends&lt;span class=&quot;params&quot;&gt;(get_db)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    db_user = crud.update_user(db, user_id=user_id, update_user=update_user)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; db_user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;User not found&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; db_user&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;DB:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;mysql&amp;gt; desc users;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;+---------------+-------------+------+-----+---------+----------------+&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;| Field         | Type        | Null | Key | Default | Extra          |&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;+---------------+-------------+------+-----+---------+----------------+&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;| id            | int(11)     | NO   | PRI | NULL    | auto_increment |&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;| email         | varchar(32) | YES  | UNI | NULL    |                |&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;| hash_password | varchar(32) | YES  |     | NULL    |                |&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;| is_active     | tinyint(1)  | YES  |     | NULL    |                |&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;+---------------+-------------+------+-----+---------+----------------+&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4 rows in set (0.00 sec)&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/db_add.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/db_search.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/db_update.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/db_delete.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;FastAPI可以通过SQLAlchemy将其轻松的适应于任何的数据库。SQLAlchemy是一个ORM（object-relational mapping）的框架。在ORM中，你创建一个类就会通过SQLAlchemy将其自动转成一张表，在类中的每一个属性就会将其转成表中的
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: Security（14）</title>
    <link href="http://izheyi.com/2021/10/03/FastAPI-Security%EF%BC%8814%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/03/FastAPI-Security（14）/</id>
    <published>2021-10-03T01:58:29.000Z</published>
    <updated>2021-10-05T01:47:22.879Z</updated>
    
    <content type="html">&lt;p&gt;安全，权限对于任何一个系统是不可避免的。&lt;/p&gt;
&lt;p&gt;FastAPI提供了多种工具，可帮助你以标准的方式轻松、快速地处理安全性，而无需研究和学习所有的安全规范。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;oauth2_scheme = OAuth2PasswordBearer(tokenUrl=&lt;span class=&quot;string&quot;&gt;&quot;token&quot;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(token: str = Depends&lt;span class=&quot;params&quot;&gt;(oauth2_scheme)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;token&#39;&lt;/span&gt;: token&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/security_np.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h5 id=&quot;简单-Bear-OAuth2实现完整流程&quot;&gt;&lt;a href=&quot;#简单-Bear-OAuth2实现完整流程&quot; class=&quot;headerlink&quot; title=&quot;简单 Bear OAuth2实现完整流程&quot;&gt;&lt;/a&gt;简单 Bear OAuth2实现完整流程&lt;/h5&gt;&lt;p&gt;在FastAPI中, 提供了多种认证解决方案工具, 其中也包括了OAuth2, 可以使用&lt;code&gt;OAuth2PasswordBearer&lt;/code&gt;类来实现OAuth2的功能, 使用的是OAuth2中的一种认证方案, 通过&lt;code&gt;bearer token&lt;/code&gt;来携带&lt;code&gt;token&lt;/code&gt;, 具体做法就是:&lt;/p&gt;
&lt;p&gt;在请求头中添加参数&lt;code&gt;Authorization&lt;/code&gt;, 其值为&lt;code&gt;Bearer&lt;/code&gt;和&lt;code&gt;token&lt;/code&gt;中间使用&lt;code&gt;空格&lt;/code&gt;连接形成的字符串, 如&lt;code&gt;Bearer your_token_string&lt;/code&gt;, 注意, &lt;code&gt;Authorization&lt;/code&gt;和&lt;code&gt;Bearer&lt;/code&gt;都是规范中固定的写法, 不可修改&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;20&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;21&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;22&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;23&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;24&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;25&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;26&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;27&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;28&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;29&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;30&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;31&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;32&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;33&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;fake_user = &amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;string&quot;&gt;&#39;admin&#39;&lt;/span&gt;:&amp;#123;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;string&quot;&gt;&#39;username&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;admin&#39;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;string&quot;&gt;&#39;hash_password&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;fakehashadmin&#39;&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;string&quot;&gt;&#39;enabled&#39;&lt;/span&gt;: &lt;span class=&quot;keyword&quot;&gt;True&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;oauth2_scheme = OAuth2PasswordBearer(tokenUrl=&lt;span class=&quot;string&quot;&gt;&quot;token&quot;&lt;/span&gt;)&lt;span class=&quot;comment&quot;&gt;# 这个参数的作用是当输入完用户密码后, 点击Authorize按钮后, 会请求127.0.0.1:8000/token这个网址, 把用户密码通过Form表单的形式传递给这个请求, 即这个/token就是我们网站的后台登录接口.&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;fake_hash_password&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(password: str)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;string&quot;&gt;&quot;fakehash&quot;&lt;/span&gt; + password&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    username: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    enbaled: Optional[bool] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;UserPwd&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(User)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    hash_password: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/login&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(form: OAuth2PasswordRequestForm = Depends&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    user = fake_user.get(form.username)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;not&lt;/span&gt; user:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;user incorrect&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    u = UserPwd(**user)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    hashpwd = fake_hash_password(form.password)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; hashpwd != u.hash_password:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;passwod incorrect&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&quot;access_token&quot;&lt;/span&gt;: u.username, &lt;span class=&quot;string&quot;&gt;&quot;token_type&quot;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&quot;bearer&quot;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/security_username.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/security_password.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/security_correct.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;安全，权限对于任何一个系统是不可避免的。&lt;/p&gt;
&lt;p&gt;FastAPI提供了多种工具，可帮助你以标准的方式轻松、快速地处理安全性，而无需研究和学习所有的安全规范。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td cla
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: Dependencies（13）</title>
    <link href="http://izheyi.com/2021/10/03/FastAPI-Dependencies%EF%BC%8813%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/03/FastAPI-Dependencies（13）/</id>
    <published>2021-10-03T00:35:43.000Z</published>
    <updated>2021-10-04T07:56:52.990Z</updated>
    
    <content type="html">&lt;p&gt;FastAPI 提供了简单易用，但功能强大的&lt;strong&gt;依赖注入&lt;/strong&gt;系统，可以让开发人员轻松地把组件集成至 &lt;strong&gt;FastAPI&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;编程中的&lt;strong&gt;「依赖注入」&lt;/strong&gt;是声明代码（本文中为&lt;em&gt;路径操作函数&lt;/em&gt; ）运行所需的，或要使用的「依赖」的一种方式。&lt;/p&gt;
&lt;h4 id=&quot;基本示例&quot;&gt;&lt;a href=&quot;#基本示例&quot; class=&quot;headerlink&quot; title=&quot;基本示例&quot;&gt;&lt;/a&gt;基本示例&lt;/h4&gt;&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(start: int = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, limit: int = &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;start&#39;&lt;/span&gt;: start, &lt;span class=&quot;string&quot;&gt;&#39;limit&#39;&lt;/span&gt;: limit&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(res: dict = Depends&lt;span class=&quot;params&quot;&gt;(result)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; res&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/books/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;books&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(res: dict = Depends&lt;span class=&quot;params&quot;&gt;(result)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; res&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;这里只能传给 Depends 一个参数。&lt;/p&gt;
&lt;p&gt;接收到新的请求时，&lt;strong&gt;FastAPI&lt;/strong&gt; 执行如下操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用正确的参数调用依赖项函数（「可依赖项」）&lt;/li&gt;
&lt;li&gt;获取函数返回的结果&lt;/li&gt;
&lt;li&gt;把函数返回的结果赋值给&lt;em&gt;路径操作函数&lt;/em&gt;的参数&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;Class-依赖注入&quot;&gt;&lt;a href=&quot;#Class-依赖注入&quot; class=&quot;headerlink&quot; title=&quot;Class 依赖注入&quot;&gt;&lt;/a&gt;Class 依赖注入&lt;/h4&gt;&lt;p&gt;也可以用Python Class来实现依赖注入。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(self, start: int = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;, limit: int = &lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        self.start = start&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        self.limit = limit&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(res: Result = Depends&lt;span class=&quot;params&quot;&gt;(Result)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; res&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;引用时，也可以用下边方式：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;res: Result = Depends()&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&quot;子依赖注入&quot;&gt;&lt;a href=&quot;#子依赖注入&quot; class=&quot;headerlink&quot; title=&quot;子依赖注入&quot;&gt;&lt;/a&gt;子依赖注入&lt;/h4&gt;&lt;p&gt;FastAPI 支持创建含任意深度的子依赖项。类似于函数调用：fun1 -&amp;gt; fun2 -&amp;gt; fun3&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;result1&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(start: int = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; start&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;result2&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(start: int = Depends&lt;span class=&quot;params&quot;&gt;(result1)&lt;/span&gt;, limit: int = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; limit:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; limit&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; start&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(res: dict = Depends&lt;span class=&quot;params&quot;&gt;(result2)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; res&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;结果&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;http://127.0.0.1:8000/users/?start=2&amp;#10;2&amp;#10;&amp;#10;http://127.0.0.1:8000/users/?limit=5&amp;#10;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;多次使用同一个依赖项&quot;&gt;&lt;a href=&quot;#多次使用同一个依赖项&quot; class=&quot;headerlink&quot; title=&quot;多次使用同一个依赖项&quot;&gt;&lt;/a&gt;多次使用同一个依赖项&lt;/h4&gt;&lt;p&gt;如果在同一个&lt;em&gt;路径操作&lt;/em&gt; 多次声明了同一个依赖项，例如，多个依赖项共用一个子依赖项，FastAPI 在处理同一请求时，只调用一次该子依赖项。&lt;/p&gt;
&lt;p&gt;FastAPI 不会为同一个请求多次调用同一个依赖项，而是把依赖项的返回值进行「缓存」，并把它传递给同一请求中所有需要使用该返回值的「依赖项」。&lt;/p&gt;
&lt;p&gt;在高级使用场景中，如果不想使用「缓存」值，而是为需要在同一请求的每一步操作（多次）中都实际调用依赖项，可以把 &lt;code&gt;Depends&lt;/code&gt; 的参数 &lt;code&gt;use_cache&lt;/code&gt; 的值设置为 &lt;code&gt;False&lt;/code&gt;&lt;/p&gt;
&lt;h4 id=&quot;路径依赖&quot;&gt;&lt;a href=&quot;#路径依赖&quot; class=&quot;headerlink&quot; title=&quot;路径依赖&quot;&gt;&lt;/a&gt;路径依赖&lt;/h4&gt;&lt;p&gt;以在&lt;em&gt;路径操作装饰器&lt;/em&gt;中添加一个由 &lt;code&gt;dependencies&lt;/code&gt; 组成的 &lt;code&gt;list&lt;/code&gt;来注入多个引用。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;result1&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(start: int)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; start != &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;start not == 2&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;result2&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(limit: int)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; limit != &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;limit not == 5&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&#39;, dependencies=[Depends(result1), Depends(result2)])&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;status&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;ok&#39;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/injection_path_1.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/injection_path_2.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/injection_path_3.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;全局依赖&quot;&gt;&lt;a href=&quot;#全局依赖&quot; class=&quot;headerlink&quot; title=&quot;全局依赖&quot;&gt;&lt;/a&gt;全局依赖&lt;/h4&gt;&lt;p&gt;有时，我们要为整个应用添加依赖项。&lt;/p&gt;
&lt;p&gt;可以把依赖项添加至整个 &lt;code&gt;FastAPI&lt;/code&gt; 应用。后续就可以为所有&lt;em&gt;路径操作&lt;/em&gt;应用该依赖项。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;result1&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(start: int)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; start != &lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;start not == 2&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;result2&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(limit: int)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; limit != &lt;span class=&quot;number&quot;&gt;5&lt;/span&gt;:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;raise&lt;/span&gt; HTTPException(status_code=&lt;span class=&quot;number&quot;&gt;400&lt;/span&gt;, detail=&lt;span class=&quot;string&quot;&gt;&#39;limit not == 5&#39;&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app = FastAPI(dependencies=[Depends(result1), Depends(result2)])&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;status&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;ok&#39;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/books/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;users&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;()&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;status&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;ok&#39;&lt;/span&gt;&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/injection_path_3.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/injection_path_4.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;FastAPI 提供了简单易用，但功能强大的&lt;strong&gt;依赖注入&lt;/strong&gt;系统，可以让开发人员轻松地把组件集成至 &lt;strong&gt;FastAPI&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;编程中的&lt;strong&gt;「依赖注入」&lt;/strong&gt;是声明代码（本文中为&lt;em&gt;
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: 响应模型（12）</title>
    <link href="http://izheyi.com/2021/10/02/FastAPI-%E5%93%8D%E5%BA%94%E6%A8%A1%E5%9E%8B%EF%BC%8812%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/02/FastAPI-响应模型（12）/</id>
    <published>2021-10-02T01:27:24.000Z</published>
    <updated>2021-10-04T07:57:44.180Z</updated>
    
    <content type="html">&lt;p&gt;在前面的操作中也看到，请求响应返回的就是请求体的内容，比如，要是登记注册就是返回用户名和密码，这种行为是不行的。&lt;/p&gt;
&lt;p&gt;可以使用 &lt;code&gt;response_model&lt;/code&gt; 参数来声明用于响应的模型。&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;li&gt;在 OpenAPI 的&lt;em&gt;路径操作&lt;/em&gt;中为响应添加一个 JSON Schema。&lt;/li&gt;
&lt;li&gt;并在自动生成文档系统中使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    username: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    password: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    email: EmailStr&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    adress: Optional[str] = &lt;span class=&quot;string&quot;&gt;&#39;beijing&#39;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;UserRes&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    username: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    email: EmailStr&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    address: Optional[str] = &lt;span class=&quot;string&quot;&gt;&#39;beijing&#39;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/user/register/&#39;, response_model=UserRes)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user: User)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; user&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/response_model.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;上面的例子中，可以看到响应里会自动的返回请求体里默认的字段。如果请求体中不传，就不要返回带默认值的字段，可以用&lt;code&gt;response_model_exclude_unset&lt;/code&gt;来实现&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    username: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    password: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    email: EmailStr&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    adress: Optional[str] = &lt;span class=&quot;string&quot;&gt;&#39;beijing&#39;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;UserRes&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    username: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    email: EmailStr&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    address: Optional[str] = &lt;span class=&quot;string&quot;&gt;&#39;beijing&#39;&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/user/register/&#39;, response_model=UserRes, response_model_exclude_unset=True)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user: User)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; user&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/response_model_default.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;在前面的操作中也看到，请求响应返回的就是请求体的内容，比如，要是登记注册就是返回用户名和密码，这种行为是不行的。&lt;/p&gt;
&lt;p&gt;可以使用 &lt;code&gt;response_model&lt;/code&gt; 参数来声明用于响应的模型。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将输出数据转换为其声明的类
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: 响应状态码（11）</title>
    <link href="http://izheyi.com/2021/10/02/FastAPI-%E5%93%8D%E5%BA%94%E7%8A%B6%E6%80%81%E7%A0%81%EF%BC%8811%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/02/FastAPI-响应状态码（11）/</id>
    <published>2021-10-02T01:27:09.000Z</published>
    <updated>2021-10-04T08:00:14.471Z</updated>
    
    <content type="html">&lt;p&gt;可以使用 &lt;code&gt;status_code&lt;/code&gt; 参数来声明用于响应的 HTTP 状态码。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/uploads/&#39;, status_code=201)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(files: List[UploadFile] = File&lt;span class=&quot;params&quot;&gt;(...)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;filename&#39;&lt;/span&gt;: [file.filename &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; file &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; files]&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;默认返回的状态码是200，修改后返回201。&lt;/p&gt;
&lt;p&gt;HTTP的状态码很多，也不容易 记住所有状态码的意思，FastAPI提供了更方便的方式。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/response_code.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;可以使用 &lt;code&gt;status_code&lt;/code&gt; 参数来声明用于响应的 HTTP 状态码。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;l
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: 请求Form&amp;File（10）</title>
    <link href="http://izheyi.com/2021/10/02/FastAPI-%E8%AF%B7%E6%B1%82Form-File%EF%BC%8810%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/02/FastAPI-请求Form-File（10）/</id>
    <published>2021-10-02T00:29:35.000Z</published>
    <updated>2021-10-04T08:00:58.245Z</updated>
    
    <content type="html">&lt;p&gt;Form表单和File Upload是避免不了的操作。&lt;/p&gt;
&lt;p&gt;要使用表单，需预先安装 python-multipart&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;pip install python-multipart&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;Form&quot;&gt;&lt;a href=&quot;#Form&quot; class=&quot;headerlink&quot; title=&quot;Form&quot;&gt;&lt;/a&gt;Form&lt;/h4&gt;&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/login/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(username : str = Form&lt;span class=&quot;params&quot;&gt;(...)&lt;/span&gt;, password: str = Form&lt;span class=&quot;params&quot;&gt;(...)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;username&#39;&lt;/span&gt;: username, &lt;span class=&quot;string&quot;&gt;&#39;password&#39;&lt;/span&gt;: password&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_form.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;File&quot;&gt;&lt;a href=&quot;#File&quot; class=&quot;headerlink&quot; title=&quot;File&quot;&gt;&lt;/a&gt;File&lt;/h4&gt;&lt;p&gt;文件上传也是以Form形式发送。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/upload/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(file: UploadFile = File&lt;span class=&quot;params&quot;&gt;(...)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;filename&#39;&lt;/span&gt;: file.filename&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_file.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;也支持多个文件上传&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/uploads/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(files: List[UploadFile] = File&lt;span class=&quot;params&quot;&gt;(...)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;filename&#39;&lt;/span&gt;: [file.filename &lt;span class=&quot;keyword&quot;&gt;for&lt;/span&gt; file &lt;span class=&quot;keyword&quot;&gt;in&lt;/span&gt; files]&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_files.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;Form表单和File Upload是避免不了的操作。&lt;/p&gt;
&lt;p&gt;要使用表单，需预先安装 python-multipart&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span cl
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: 请求Header&amp;Cookie（9）</title>
    <link href="http://izheyi.com/2021/10/02/FastAPI-%E8%AF%B7%E6%B1%82Header-Cookie%EF%BC%889%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/02/FastAPI-请求Header-Cookie（9）/</id>
    <published>2021-10-01T23:26:40.000Z</published>
    <updated>2021-10-04T08:05:55.476Z</updated>
    
    <content type="html">&lt;h4 id=&quot;Header&quot;&gt;&lt;a href=&quot;#Header&quot; class=&quot;headerlink&quot; title=&quot;Header&quot;&gt;&lt;/a&gt;Header&lt;/h4&gt;&lt;p&gt;请求自定义Header。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user_agent: Optional[str] = Header&lt;span class=&quot;params&quot;&gt;(None)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;User-Agent&#39;&lt;/span&gt;: user_agent&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_header.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;Cookie&quot;&gt;&lt;a href=&quot;#Cookie&quot; class=&quot;headerlink&quot; title=&quot;Cookie&quot;&gt;&lt;/a&gt;Cookie&lt;/h4&gt;&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(user_agent: Optional[str] = Header&lt;span class=&quot;params&quot;&gt;(None)&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         sid: Optional[str] = Cookie&lt;span class=&quot;params&quot;&gt;(None)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;User-Agent&#39;&lt;/span&gt;: user_agent&amp;#125;, &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;sid&#39;&lt;/span&gt;: sid&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_cookie.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;h4 id=&quot;Header&quot;&gt;&lt;a href=&quot;#Header&quot; class=&quot;headerlink&quot; title=&quot;Header&quot;&gt;&lt;/a&gt;Header&lt;/h4&gt;&lt;p&gt;请求自定义Header。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;tab
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: 请求体嵌套模型（8）</title>
    <link href="http://izheyi.com/2021/10/01/FastAPI-%E8%AF%B7%E6%B1%82%E4%BD%93%E5%B5%8C%E5%A5%97%E6%A8%A1%E5%9E%8B%EF%BC%888%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/01/FastAPI-请求体嵌套模型（8）/</id>
    <published>2021-10-01T06:53:17.000Z</published>
    <updated>2021-10-04T08:01:43.129Z</updated>
    
    <content type="html">&lt;p&gt;可以将一个模型属性定义为有多子元素的类型。&lt;code&gt;List&lt;/code&gt;来实现&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name: str = Field(..., min_length=&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, max_length=&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    price: float&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    description: Optional[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    tag: List[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app = FastAPI()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/books/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(book: Book = Body&lt;span class=&quot;params&quot;&gt;(..., embed=True)&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         query: Optional[str] = None)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; book, query&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_list.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;还可以在模型里嵌套模型，可以做到任意深度嵌套，来实现更复杂的结构。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Author&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    address: Optional[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    price: float&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    description: Optional[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    author: Author&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app = FastAPI()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/authors/&amp;#123;id&amp;#125;&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(*,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         id: int = Path&lt;span class=&quot;params&quot;&gt;(..., gt=&lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;)&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         book: Book)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; id, book&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_model.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;可以将一个模型属性定义为有多子元素的类型。&lt;code&gt;List&lt;/code&gt;来实现&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/s
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: 请求体Query-Path-Body-Field（7）</title>
    <link href="http://izheyi.com/2021/10/01/FastAPI-%E8%AF%B7%E6%B1%82%E4%BD%93Query-Path-Body-Field%EF%BC%887%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/01/FastAPI-请求体Query-Path-Body-Field（7）/</id>
    <published>2021-10-01T03:22:52.000Z</published>
    <updated>2021-10-04T08:01:47.717Z</updated>
    
    <content type="html">&lt;h4 id=&quot;多参数混用Path和Query&quot;&gt;&lt;a href=&quot;#多参数混用Path和Query&quot; class=&quot;headerlink&quot; title=&quot;多参数混用Path和Query&quot;&gt;&lt;/a&gt;多参数混用Path和Query&lt;/h4&gt;&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    price: float&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    description: Optional[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Author&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    address: Optional[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app = FastAPI()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/authors/&amp;#123;id&amp;#125;&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(*,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         id: int = Path&lt;span class=&quot;params&quot;&gt;(..., gt=&lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;)&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         author: Author,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         book: Book,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         query: Optional[str] = Query&lt;span class=&quot;params&quot;&gt;(None)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; id, author, book, query&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_path_query.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;Body实现请求体中单一值&quot;&gt;&lt;a href=&quot;#Body实现请求体中单一值&quot; class=&quot;headerlink&quot; title=&quot;Body实现请求体中单一值&quot;&gt;&lt;/a&gt;Body实现请求体中单一值&lt;/h4&gt;&lt;p&gt;在设定好的模型之外，想在发送请求时另外加一个字段进去，如果单独定义就会把它当成一个查询参数，可以利用&lt;code&gt;Body&lt;/code&gt;来实现。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;12&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;13&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;14&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;15&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;16&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;17&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;18&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;19&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    price: float&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    description: Optional[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Author&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    address: Optional[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app = FastAPI()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/authors/&amp;#123;id&amp;#125;&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(*,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         id: int = Path&lt;span class=&quot;params&quot;&gt;(..., gt=&lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;)&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         author: Author,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         book: Book,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         publisher: str = Body&lt;span class=&quot;params&quot;&gt;(...)&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         query: Optional[str] = Query&lt;span class=&quot;params&quot;&gt;(None)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; id, author, book, publisher, query&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_body.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;嵌入请求体参数&quot;&gt;&lt;a href=&quot;#嵌入请求体参数&quot; class=&quot;headerlink&quot; title=&quot;嵌入请求体参数&quot;&gt;&lt;/a&gt;嵌入请求体参数&lt;/h4&gt;&lt;p&gt;如果想把请求体外边再加一个字段来标识，也可以通过&lt;code&gt;Body&lt;/code&gt;来实现&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    price: float&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    description: Optional[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app = FastAPI()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/books/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(book: Book = Body&lt;span class=&quot;params&quot;&gt;(..., embed=True)&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         query: Optional[str] = None)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; book, query&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_embed.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;Field校验模型里字段&quot;&gt;&lt;a href=&quot;#Field校验模型里字段&quot; class=&quot;headerlink&quot; title=&quot;Field校验模型里字段&quot;&gt;&lt;/a&gt;Field校验模型里字段&lt;/h4&gt;&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;11&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name: str = Field(..., min_length=&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, max_length=&lt;span class=&quot;number&quot;&gt;10&lt;/span&gt;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    price: float&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    description: Optional[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app = FastAPI()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/books/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(book: Book = Body&lt;span class=&quot;params&quot;&gt;(..., embed=True)&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         query: Optional[str] = None)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; book, query&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_field.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;h4 id=&quot;多参数混用Path和Query&quot;&gt;&lt;a href=&quot;#多参数混用Path和Query&quot; class=&quot;headerlink&quot; title=&quot;多参数混用Path和Query&quot;&gt;&lt;/a&gt;多参数混用Path和Query&lt;/h4&gt;&lt;figure class=&quot;highli
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: 请求体基础（6）</title>
    <link href="http://izheyi.com/2021/10/01/FastAPI-%E8%AF%B7%E6%B1%82%E4%BD%93%E5%9F%BA%E7%A1%80%EF%BC%886%EF%BC%89/"/>
    <id>http://izheyi.com/2021/10/01/FastAPI-请求体基础（6）/</id>
    <published>2021-10-01T03:22:10.000Z</published>
    <updated>2021-10-04T08:02:16.354Z</updated>
    
    <content type="html">&lt;p&gt;这个不多说，就是客户端发送给 API 的数据。通过Pydantic来声明请求体。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;10&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;class&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;Book&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(BaseModel)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    name: str&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    price: float&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    description: Optional[str] = &lt;span class=&quot;keyword&quot;&gt;None&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;app = FastAPI()&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.post(&#39;/books/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(book: Book)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; book&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;&lt;img src=&quot;/images/fastapi/request_basic.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;这个不多说，就是客户端发送给 API 的数据。通过Pydantic来声明请求体。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/sp
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: 请求路径参数的校验（5）</title>
    <link href="http://izheyi.com/2021/09/29/FastAPI-%E8%AF%B7%E6%B1%82%E8%B7%AF%E5%BE%84%E5%8F%82%E6%95%B0%E7%9A%84%E6%A0%A1%E9%AA%8C%EF%BC%885%EF%BC%89/"/>
    <id>http://izheyi.com/2021/09/29/FastAPI-请求路径参数的校验（5）/</id>
    <published>2021-09-29T01:48:23.000Z</published>
    <updated>2021-10-04T08:03:06.101Z</updated>
    
    <content type="html">&lt;p&gt;可以通过 &lt;code&gt;Path&lt;/code&gt; 对路径参数做校验。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;9&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;books = [&amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;name&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;python&#39;&lt;/span&gt;&amp;#125;, &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;name&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;fastapi&#39;&lt;/span&gt;&amp;#125;, &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;name&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;java&#39;&lt;/span&gt;&amp;#125;, ]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&amp;#123;id&amp;#125;&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(id: int = Path&lt;span class=&quot;params&quot;&gt;(..., gt=&lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;)&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         start: int = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         limit: Optional[int] = None)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; limit:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;id: books[start : limit]&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;id: books[start: ]&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;gt：大于（greater than）&lt;/li&gt;
&lt;li&gt;ge：大于等于（greater than or equal）&lt;/li&gt;
&lt;li&gt;lt：小于（less than）&lt;/li&gt;
&lt;li&gt;le：小于等于（less than or equal）&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;http://&lt;span class=&quot;number&quot;&gt;127.0&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;.0&lt;/span&gt;&lt;span class=&quot;number&quot;&gt;.1&lt;/span&gt;:&lt;span class=&quot;number&quot;&gt;8000&lt;/span&gt;/users/&lt;span class=&quot;number&quot;&gt;11&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#123;&lt;span class=&quot;string&quot;&gt;&quot;detail&quot;&lt;/span&gt;:[&amp;#123;&lt;span class=&quot;string&quot;&gt;&quot;loc&quot;&lt;/span&gt;:[&lt;span class=&quot;string&quot;&gt;&quot;path&quot;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&quot;id&quot;&lt;/span&gt;],&lt;span class=&quot;string&quot;&gt;&quot;msg&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;ensure this value is greater than 12&quot;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&quot;type&quot;&lt;/span&gt;:&lt;span class=&quot;string&quot;&gt;&quot;value_error.number.not_gt&quot;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&quot;ctx&quot;&lt;/span&gt;:&amp;#123;&lt;span class=&quot;string&quot;&gt;&quot;limit_value&quot;&lt;/span&gt;:&lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;&amp;#125;&amp;#125;]&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;参数排序&quot;&gt;&lt;a href=&quot;#参数排序&quot; class=&quot;headerlink&quot; title=&quot;参数排序&quot;&gt;&lt;/a&gt;参数排序&lt;/h4&gt;&lt;p&gt;有默认值参数和必填参数值都存在时，有默认值参数必须放到必填参数后边。&lt;/p&gt;
&lt;p&gt;传递 &lt;code&gt;*&lt;/code&gt; 作为函数的第一个参数。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/users/&amp;#123;id&amp;#125;&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(*, id: int = Path&lt;span class=&quot;params&quot;&gt;(..., gt=&lt;span class=&quot;number&quot;&gt;12&lt;/span&gt;)&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         start: int = &lt;span class=&quot;number&quot;&gt;0&lt;/span&gt;,&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;         limit: Optional[int] = None)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; limit:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;id: books[start : limit]&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; &amp;#123;id: books[start: ]&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;Python 不会对该 &lt;code&gt;*&lt;/code&gt; 做任何事情，它将之后的所有参数都作为关键字参数来调用。&lt;/p&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;可以通过 &lt;code&gt;Path&lt;/code&gt; 对路径参数做校验。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
  <entry>
    <title>FastAPI: 请求查询参数的校验（4）</title>
    <link href="http://izheyi.com/2021/09/28/FastAPI-%E8%AF%B7%E6%B1%82%E6%9F%A5%E8%AF%A2%E5%8F%82%E6%95%B0%E7%9A%84%E6%A0%A1%E9%AA%8C%EF%BC%884%EF%BC%89/"/>
    <id>http://izheyi.com/2021/09/28/FastAPI-请求查询参数的校验（4）/</id>
    <published>2021-09-28T01:48:10.000Z</published>
    <updated>2021-10-04T08:02:48.077Z</updated>
    
    <content type="html">&lt;p&gt;可以通过Query来实现对字符串查询参数的校验。&lt;/p&gt;
&lt;h4 id=&quot;常规校验&quot;&gt;&lt;a href=&quot;#常规校验&quot; class=&quot;headerlink&quot; title=&quot;常规校验&quot;&gt;&lt;/a&gt;常规校验&lt;/h4&gt;&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;books = [&amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;name&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;python&#39;&lt;/span&gt;&amp;#125;, &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;name&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;fastapi&#39;&lt;/span&gt;&amp;#125;, &amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;name&#39;&lt;/span&gt;: &lt;span class=&quot;string&quot;&gt;&#39;java&#39;&lt;/span&gt;&amp;#125;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/books/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(book: str = Query&lt;span class=&quot;params&quot;&gt;(&lt;span class=&quot;string&quot;&gt;&#39;Java Script&#39;&lt;/span&gt;, min_length=&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; book:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        books.append(&amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;name&#39;&lt;/span&gt;: book&amp;#125;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; books&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;参数的默认值是Java Script，最小长度是2。&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;http://127.0.0.1:8000/books/&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;[&amp;#123;&quot;name&quot;:&quot;python&quot;&amp;#125;,&amp;#123;&quot;name&quot;:&quot;fastapi&quot;&amp;#125;,&amp;#123;&quot;name&quot;:&quot;java&quot;&amp;#125;,&amp;#123;&quot;name&quot;:&quot;Java Script&quot;&amp;#125;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;http://127.0.0.1:8000/books/?book=c&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&amp;#123;&quot;detail&quot;:[&amp;#123;&quot;loc&quot;:[&quot;query&quot;,&quot;book&quot;],&quot;msg&quot;:&quot;ensure this value has at least 2 characters&quot;,&quot;type&quot;:&quot;value_error.any_str.min_length&quot;,&quot;ctx&quot;:&amp;#123;&quot;limit_value&quot;:2&amp;#125;&amp;#125;]&amp;#125;&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;甚至可以直接用正则表达式来做检验，一般应该也用不到。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/books/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(book: Optional[str] = Query&lt;span class=&quot;params&quot;&gt;(&lt;span class=&quot;string&quot;&gt;&#39;Java Script&#39;&lt;/span&gt;, min_length=&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, regex=&lt;span class=&quot;string&quot;&gt;&#39;^J&#39;&lt;/span&gt;)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; book:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        books.append(&amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;name&#39;&lt;/span&gt;: book&amp;#125;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; books&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;必填参数&quot;&gt;&lt;a href=&quot;#必填参数&quot; class=&quot;headerlink&quot; title=&quot;必填参数&quot;&gt;&lt;/a&gt;必填参数&lt;/h4&gt;&lt;p&gt;可以将 &lt;code&gt;...&lt;/code&gt; 用作第一个参数值，在声明必填参数。&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/books/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(book: str = Query&lt;span class=&quot;params&quot;&gt;(..., min_length=&lt;span class=&quot;number&quot;&gt;2&lt;/span&gt;, regex=&lt;span class=&quot;string&quot;&gt;&#39;^J&#39;&lt;/span&gt;)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; book:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        books.append(&amp;#123;&lt;span class=&quot;string&quot;&gt;&#39;name&#39;&lt;/span&gt;: book&amp;#125;)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; books&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;h4 id=&quot;参数列表多个值&quot;&gt;&lt;a href=&quot;#参数列表多个值&quot; class=&quot;headerlink&quot; title=&quot;参数列表多个值&quot;&gt;&lt;/a&gt;参数列表多个值&lt;/h4&gt;&lt;p&gt;查询参数可以声明时接受多个值&lt;/p&gt;
&lt;figure class=&quot;highlight python&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;6&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;7&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;8&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;books = [&lt;span class=&quot;string&quot;&gt;&#39;python&#39;&lt;/span&gt;, &lt;span class=&quot;string&quot;&gt;&#39;fastapi&#39;&lt;/span&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;decorator&quot;&gt;@app.get(&#39;/books/&#39;)&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;function&quot;&gt;&lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;title&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;params&quot;&gt;(book: Optional[list] = Query&lt;span class=&quot;params&quot;&gt;(None)&lt;/span&gt;)&lt;/span&gt;:&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;if&lt;/span&gt; book:&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;        books.extend(book)&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;    &lt;span class=&quot;keyword&quot;&gt;return&lt;/span&gt; books&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;结果&lt;/p&gt;
&lt;figure class=&quot;highlight less&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;2&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;3&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;4&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;5&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;http&lt;/span&gt;:&lt;span class=&quot;comment&quot;&gt;//127.0.0.1:8000/books/&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;[&lt;span class=&quot;string&quot;&gt;&quot;python&quot;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&quot;fastapi&quot;&lt;/span&gt;]&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;&lt;span class=&quot;attribute&quot;&gt;http&lt;/span&gt;:&lt;span class=&quot;comment&quot;&gt;//127.0.0.1:8000/books/?book=java&amp;amp;book=c&lt;/span&gt;&lt;/span&gt;&lt;br&gt;&lt;span class=&quot;line&quot;&gt;[&lt;span class=&quot;string&quot;&gt;&quot;python&quot;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&quot;fastapi&quot;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&quot;java&quot;&lt;/span&gt;,&lt;span class=&quot;string&quot;&gt;&quot;c&quot;&lt;/span&gt;]&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/figure&gt;
&lt;p&gt;还有下面的校验，用到再说&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;alia&lt;/li&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;description&lt;/li&gt;
&lt;li&gt;deprecated&lt;/li&gt;
&lt;/ul&gt;
</content>
    
    <summary type="html">
    
      &lt;p&gt;可以通过Query来实现对字符串查询参数的校验。&lt;/p&gt;
&lt;h4 id=&quot;常规校验&quot;&gt;&lt;a href=&quot;#常规校验&quot; class=&quot;headerlink&quot; title=&quot;常规校验&quot;&gt;&lt;/a&gt;常规校验&lt;/h4&gt;&lt;figure class=&quot;highlight python&quot;&gt;
    
    </summary>
    
      <category term="FastAPI" scheme="http://izheyi.com/categories/FastAPI/"/>
    
    
      <category term="FastAPI" scheme="http://izheyi.com/tags/FastAPI/"/>
    
  </entry>
  
</feed>
