<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Connexion on Haseeb Majid</title>
    <link>https://haseebmajid.dev/tags/connexion/</link>
    <description>Recent content in Connexion on Haseeb Majid</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Fri, 16 Aug 2019 00:00:00 +0000</lastBuildDate><atom:link href="https://haseebmajid.dev/tags/connexion/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Creating a Simple RESTful App using OpenAPI, Flask &amp; Connexions</title>
      <link>https://haseebmajid.dev/posts/2019-08-16-creating-a-simple-restful-app-using-openapi-flask-connexions/</link>
      <pubDate>Fri, 16 Aug 2019 00:00:00 +0000</pubDate>
      
      <guid>https://haseebmajid.dev/posts/2019-08-16-creating-a-simple-restful-app-using-openapi-flask-connexions/</guid>
      <description>&lt;p&gt;RESTful APIs are very popular at the moment and Python is a great language to develop
web APIs with. In this article we will go over a documentation first approach to building APIs.
We will be using Flask, Swagger Code-Gen (OpenAPI) and Connexions.
I will go over an API/documentation first approach to building a RESTful API in
Python. Which will try to minimise the differences between what&amp;rsquo;s defined in the API
specification and the actual API logic
itself.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>RESTful APIs are very popular at the moment and Python is a great language to develop
web APIs with. In this article we will go over a documentation first approach to building APIs.
We will be using Flask, Swagger Code-Gen (OpenAPI) and Connexions.
I will go over an API/documentation first approach to building a RESTful API in
Python. Which will try to minimise the differences between what&rsquo;s defined in the API
specification and the actual API logic
itself.</p>
<p>One of the main problems you&rsquo;ll find with using openapi is that every time you update your API
you have to update your documentation or your openapi yaml/json file. Now what happens if you
forget? Now your API is different to what&rsquo;s documented which can be a real pain for your users.
The aim of this approach is that you update your specification file first.</p>
<h2 id="toolslibraries">Tools/Libraries</h2>
<p>Let&rsquo;s very quickly go over the tools and libraries we will use.</p>
<h3 id="openapi">OpenAPI</h3>
<p>Openapi or the Openapi Specification (OAS), defines a standard language agnostic approach to
developing RESTful APIs, which are both human and machine readable.</p>
<h3 id="swagger">Swagger</h3>
<p>A set of open-source tools built around the OAS that help support development, including:</p>
<ul>
<li>Swagger Editor: Browser based editor where you can write (and view) OpenAPI specs.</li>
<li>Swagger UI: Renders OAS as interactive API documentation (also can be seen within Swagger Editor).</li>
<li>Swagger Codegen - generates server stubs and client libraries from an OpenAPI spec.</li>
</ul>
<h3 id="connexion">Connexion</h3>
<p>Is a Python library that &ldquo;automagically&rdquo; handles HTTP requests based on your OAS. It acts as a
simple wrapper around Flask reducing the boilerplate code you have to write as well. So we still
have access to all the functionality we would have when developing a normal Flask web API.</p>
<p><strong>NOTE:</strong> At the time of writing this article OAS3 support had just come out for codegen.
So this article is written using OAS2. However everything in this article should be applicable
to OAS2 and AOS3.</p>
<p>
  <img
    loading="lazy"
    src="https://synaptiklabs.com/wp-content/uploads/2019/02/javaee-swagger-screen-1.png"
    alt="Swagger UI"
    
  /></p>
<h2 id="api">API</h2>
<p>Now onto actually developing our API.</p>
<h3 id="project-structure">Project Structure</h3>
<p>In this article our code will be using the following structure.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">test-api/
</span></span><span class="line"><span class="cl">├── openapi/
</span></span><span class="line"><span class="cl">├── src/
</span></span><span class="line"><span class="cl">|   └── test_api
</span></span><span class="line"><span class="cl">|   |  ├── wsgi.py
</span></span><span class="line"><span class="cl">|   |  ├──__init__.py
</span></span><span class="line"><span class="cl">|   |  ├── core/
</span></span><span class="line"><span class="cl">|   |  └── web/
</span></span><span class="line"><span class="cl">└── setup.py
</span></span></code></pre></div><hr>
<h3 id="define-specification">Define Specification</h3>
<p>First thing we do is define our OAS. We will use YAML to do this because I think it&rsquo;s much easier to read
and almost all specifications you see will be written in YAML (not JSON). However you can write the
specification in JSON if you so wish. There are a few tools that can make this a bit easier.</p>
<p>We can use the <a href="https://editor.swagger.io/">online swagger editor</a>, which allows us to edit the
OAS and you can see the OAS as an interactive document (half the screen for the editor and half
for the interactive document). You can also run the editor locally as a
<a href="https://hub.docker.com/r/swaggerapi/swagger-editor/">Docker container</a></p>
<p><strong>NOTE</strong>: If you use the editor to generate models (using swagger-codegn), it makes an API call to
a remote server. Run the swagger-codegen manually to generate the models locally, if you&rsquo;re using
this for work and confidentality matters.</p>
<p>My preferred way of writing an OAS is using VSCode with the
<a href="https://marketplace.visualstudio.com/items?itemName=Arjun.swagger-viewer">Swagger Viewer</a>
plugin, which allows you to write the OAS and preview the interactive document at the same time.
I prefer this approach because I have all my plugins setup (colour scheme, vim bindings etc).</p>
<p>Now we have to define our specification. We will be using OAS version 2 because swagger-codegen
at the moment cannot generate models for flask for OAS version 3. Now I&rsquo;ve created a very simple
specification for an imaginary pet store.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">swagger</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;2.0&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">info</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;1.0.0&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Pet Store&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">basePath</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/api/v1&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">tags</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">schemes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="s2">&#34;https&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">consumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="s2">&#34;application/json&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">produces</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="s2">&#34;application/json&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">paths</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="l">/pet/{pet_id}:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">get</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">tags</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="s2">&#34;pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Get a pet in the store&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">operationId</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;get_pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">parameters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;pet_id&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">in</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;path&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;The id of the pet to retrieve&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">required</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;string&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">responses</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">200</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Successfully retrived pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">schema</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">$ref</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#/definitions/Pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">404</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Pet doesn&#39;t exist&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">x-swagger-router-controller</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;test_api.web.controllers.pets_controller&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">delete</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">tags</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="s2">&#34;pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Remove a pet in the store&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">operationId</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;remove_pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">parameters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;pet_id&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">in</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;path&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;The id of the pet to remove from the store&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">required</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;string&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">responses</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">202</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Successfully deleted pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">404</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Pet doesn&#39;t exist&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">x-swagger-router-controller</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;test_api.web.controllers.pets_controller&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">put</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">tags</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="s2">&#34;pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Update and replace a pet in the store&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">operationId</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;update_pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">parameters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;pet_id&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">in</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;path&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;The id of the pet to update from the store&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">required</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;string&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">in</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;body&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">required</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">schema</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">$ref</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#/definitions/Pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">responses</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">200</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Successfully updated pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">404</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Pet doesn&#39;t exist&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">x-swagger-router-controller</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;test_api.web.controllers.pets_controller&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">/pet</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">get</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">tags</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="s2">&#34;pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Gets all pets in the store&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">operationId</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;get_all_pets&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">responses</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">200</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Successfully received all pets.&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">schema</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">$ref</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#/definitions/Pets&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">x-swagger-router-controller</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;test_api.web.controllers.pets_controller&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">post</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">tags</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="s2">&#34;pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Add a new pet to the store&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">operationId</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;add_pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">parameters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">in</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;body&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;body&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Pet to add to the store&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">required</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">schema</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">$ref</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#/definitions/Pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">responses</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">201</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Pet added&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">x-swagger-router-controller</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;test_api.web.controllers.pets_controller&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">definitions</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">Pets</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">array</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">items</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">$ref</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#/definitions/Pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">Pet</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;object&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">required</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;name&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;breed&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;price&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">properties</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">id</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;integer&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">format</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;int32&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;string&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">breed</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;string&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">price</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;number&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">format</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;float&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">example</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;doggie&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">breed</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;German Shepherd&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">price</span><span class="p">:</span><span class="w"> </span><span class="m">100.00</span><span class="w">
</span></span></span></code></pre></div><p>The specification defines several endpoints for our API. Essentially I&rsquo;ve defined one endpoint
for each of the main CRUD verbs (GET, POST, PUT and DELETE). Some things to note:
the <code>operation_id</code>, will be the function name in our Python code. In a production,
you should also look at using <code>OAuth2</code> for securing your API this can also be defined within in
the specification.</p>
<p><strong>Note</strong> the extra field <code>x-swagger-router-controller</code> is very important. It is used by <code>Connexion</code> to
map which module (and function) to send requests to. For example a GET request send to <code>/api/v1/pets</code>,
will go to <code>test_api.web.controllers.pets_controller</code> and function called <code>get_pet</code> (<code>operation_id</code>)
so it looks like <code>test_api.web.controllers.pets_controller:get_pet</code>. Which means we call the function
in the folder <code>src/test_api/web/controllers/pets_controller</code> we call the <code>get_pet</code> function.</p>
<h3 id="server-stubs">Server Stubs</h3>
<p>Now we want to generate some server stubs from this specification we can do this by either using the <code>codegen</code> tool or
in the <code>editor</code> we can go to <code>Generate Server &gt; python-flask</code>. This will download a zip file, after you decompress it.
We want to copy the <code>controllers, models, encoder.py, __init__.py and util.py</code> files into the <code>web</code> folder. The models
are the classes of objects that we expect as input and output such as a <code>Pet</code> class. The controllers contain the actual
webserver logic. There is one function for every endpoint (and CRUD method) we defined above, there is also one file for
every tag we defined. In this example we only have one controller file because we only have <code>tag</code> called pet. Then in the
controller we have 4 functions (named after the <code>operation_id</code>).</p>
<p>We have to make some changes to the codegen generated files. The imports will be wrong when we move the files. We have to change them from
<code>swagger_server</code>. So for example <code>controllers/pet_controller.py</code> and <code>models/pets.py</code> would become:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">connexion</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">six</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">..models.pet</span> <span class="kn">import</span> <span class="n">Pet</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">..models.pets</span> <span class="kn">import</span> <span class="n">Pets</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">..</span> <span class="kn">import</span> <span class="n">util</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">test_api.core</span> <span class="kn">import</span> <span class="n">pets</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">add_pet</span><span class="p">(</span><span class="n">body</span><span class="p">):</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Add a new pet to the store
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">     # noqa: E501
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :param body: Pet to add to the store
</span></span></span><span class="line"><span class="cl"><span class="s2">    :type body: dict | bytes
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :rtype: None
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">connexion</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">is_json</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">body</span> <span class="o">=</span> <span class="n">Pet</span><span class="o">.</span><span class="n">from_dict</span><span class="p">(</span><span class="n">connexion</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">get_json</span><span class="p">())</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="n">pets</span><span class="o">.</span><span class="n">add_pet</span><span class="p">(</span><span class="n">body</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">{},</span> <span class="mi">201</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_all_pets</span><span class="p">():</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Gets all pets in the store
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">     # noqa: E501
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :rtype: Pets
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span> <span class="o">=</span> <span class="n">pets</span><span class="o">.</span><span class="n">get_all_pets</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets_in_store</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">pet</span> <span class="ow">in</span> <span class="n">pets</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">current_pet</span> <span class="o">=</span> <span class="n">Pet</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">pet</span><span class="p">[</span><span class="s2">&#34;id&#34;</span><span class="p">],</span> <span class="n">breed</span><span class="o">=</span><span class="n">pet</span><span class="p">[</span><span class="s2">&#34;breed&#34;</span><span class="p">],</span> <span class="n">name</span><span class="o">=</span><span class="n">pet</span><span class="p">[</span><span class="s2">&#34;name&#34;</span><span class="p">],</span> <span class="n">price</span><span class="o">=</span><span class="n">pet</span><span class="p">[</span><span class="s2">&#34;price&#34;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">        <span class="n">pets_in_store</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">current_pet</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">pets_in_store</span><span class="p">,</span> <span class="mi">200</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_pet</span><span class="p">(</span><span class="n">pet_id</span><span class="p">):</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Get a pet in the store
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">     # noqa: E501
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :param pet_id: The id of the pet to retrieve
</span></span></span><span class="line"><span class="cl"><span class="s2">    :type pet_id: str
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :rtype: Pet
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">pet</span> <span class="o">=</span> <span class="n">pets</span><span class="o">.</span><span class="n">get_pet</span><span class="p">(</span><span class="n">pet_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">Pet</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">pet</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">breed</span><span class="o">=</span><span class="n">pet</span><span class="o">.</span><span class="n">breed</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">pet</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">price</span><span class="o">=</span><span class="n">pet</span><span class="o">.</span><span class="n">price</span><span class="p">),</span> <span class="mi">200</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="p">{},</span> <span class="mi">404</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">response</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">remove_pet</span><span class="p">(</span><span class="n">pet_id</span><span class="p">):</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Remove a pet in the store
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">     # noqa: E501
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :param pet_id: The id of the pet to remove from the store
</span></span></span><span class="line"><span class="cl"><span class="s2">    :type pet_id: str
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :rtype: None
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">pets</span><span class="o">.</span><span class="n">remove_pet</span><span class="p">(</span><span class="n">pet_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="p">{},</span> <span class="mi">200</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="p">{},</span> <span class="mi">404</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">response</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">update_pet</span><span class="p">(</span><span class="n">pet_id</span><span class="p">,</span> <span class="n">Pet</span><span class="p">):</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Update and replace a pet in the store
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">     # noqa: E501
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :param pet_id: The id of the pet to update from the store
</span></span></span><span class="line"><span class="cl"><span class="s2">    :type pet_id: str
</span></span></span><span class="line"><span class="cl"><span class="s2">    :param Pet: 
</span></span></span><span class="line"><span class="cl"><span class="s2">    :type Pet: dict | bytes
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :rtype: None
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">connexion</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">is_json</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">Pet</span> <span class="o">=</span> <span class="n">Pet</span><span class="o">.</span><span class="n">from_dict</span><span class="p">(</span><span class="n">connexion</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">get_json</span><span class="p">())</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">pets</span><span class="o">.</span><span class="n">update_pet</span><span class="p">(</span><span class="n">pet_id</span><span class="p">,</span> <span class="n">Pet</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="p">{},</span> <span class="mi">200</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="p">{},</span> <span class="mi">404</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">response</span>
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">json</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_all_pets</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span> <span class="o">=</span> <span class="n">read_from_file</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets_in_store</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">k</span><span class="p">,</span> <span class="n">v</span> <span class="ow">in</span> <span class="n">pets</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">        <span class="n">current_pet</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;id&#34;</span><span class="p">:</span> <span class="n">k</span><span class="p">,</span> <span class="o">**</span><span class="n">v</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="n">pets_in_store</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">current_pet</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">pets</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">remove_pet</span><span class="p">(</span><span class="nb">id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span> <span class="o">=</span> <span class="n">read_from_file</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">del</span> <span class="n">pets</span><span class="p">[</span><span class="nb">id</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">write_to_file</span><span class="p">(</span><span class="n">pets</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">update_pet</span><span class="p">(</span><span class="nb">id</span><span class="p">,</span> <span class="n">pet</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span> <span class="o">=</span> <span class="n">read_from_file</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">ids</span> <span class="o">=</span> <span class="n">pets</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span><span class="p">[</span><span class="nb">id</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;name&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s2">&#34;breed&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">breed</span><span class="p">,</span> <span class="s2">&#34;price&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">price</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">write_to_file</span><span class="p">(</span><span class="n">pets</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">add_pet</span><span class="p">(</span><span class="n">pet</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span> <span class="o">=</span> <span class="n">read_from_file</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">ids</span> <span class="o">=</span> <span class="n">pets</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">new_id</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ids</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span><span class="p">[</span><span class="n">new_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;name&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s2">&#34;breed&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">breed</span><span class="p">,</span> <span class="s2">&#34;price&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">price</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">write_to_file</span><span class="p">(</span><span class="n">pets</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_pet</span><span class="p">(</span><span class="nb">id</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span> <span class="o">=</span> <span class="n">read_from_file</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">pet</span> <span class="o">=</span> <span class="n">pets</span><span class="p">[</span><span class="nb">id</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">pet</span><span class="p">[</span><span class="s2">&#34;id&#34;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">id</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">pet</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">write_to_file</span><span class="p">(</span><span class="n">content</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&#34;./pets.json&#34;</span><span class="p">,</span> <span class="s2">&#34;w&#34;</span><span class="p">)</span> <span class="k">as</span> <span class="n">pets</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">pets</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">content</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">read_from_file</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">&#34;./pets.json&#34;</span><span class="p">,</span> <span class="s2">&#34;r&#34;</span><span class="p">)</span> <span class="k">as</span> <span class="n">pets</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">pets</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
</span></span></code></pre></div><p>In this case I&rsquo;m using relative imports but you could also use absolute imports. For example <code>..models.patch_request</code> would
become <code>test_api.models.patch_request</code>. It&rsquo;s all personal preference. <a href="https://realpython.com/absolute-vs-relative-python-imports/">This article</a>
goes into more detail on the issue.</p>
<p><strong>Note:</strong> Some imports aren&rsquo;t required and can always be removed later, this will vary project to project. You can use a linter to help you determine
unused imports.</p>
<p>So now we have generated some models and controllers from our openapi specification we can write the logic for our application. I usually
write all of my core logic in a folder called <code>core</code> which is a sibling of <code>test_api</code>. Then I import the modules into the controllers. This
adds a nice layer of abstraction, let&rsquo;s say tomorrow you wanted to turn into a cli we can keep the <code>core</code> folder and delete the <code>web</code> folder
and add a cli library such as <code>click</code>. This involves minimal code change.</p>
<p><strong>Note</strong> Some import maybe unnecessary you can use a linter (such as <code>flask8</code>) to help you remove them from the <code>models</code>.</p>
<h3 id="core-logic">Core Logic</h3>
<p>I&rsquo;ve created a file called <code>pets.py</code> in <code>core</code>. In this example we just write and read from a JSON
file. This isn&rsquo;t the best code I&rsquo;ve written but should be enough to show what we&rsquo;re trying to achieve.
In reality this data would likely be stored in a database but I don&rsquo;t want to overcomplicate this
example. As far as you&rsquo;re concerned data is being stored and retrieve from a file as if it were a
database.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">...</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">add_pet</span><span class="p">(</span><span class="n">pet</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span> <span class="o">=</span> <span class="n">read_from_file</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">ids</span> <span class="o">=</span> <span class="n">pets</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">new_id</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ids</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span><span class="p">[</span><span class="n">new_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;name&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s2">&#34;breed&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">breed</span><span class="p">,</span> <span class="s2">&#34;price&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">price</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">write_to_file</span><span class="p">(</span><span class="n">pets</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">...</span>
</span></span></code></pre></div><h3 id="controllers">Controllers</h3>
<p>Now we have our core logic, let&rsquo;s looks at how we interact with it in our controllers, first
<code>import test_api.core import pets</code> import our new file into the controllers (<code>pet_controller</code>).</p>
<p>Then let&rsquo;s look at <code>get_pet</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">get_pet</span><span class="p">(</span><span class="n">pet_id</span><span class="p">):</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Get a pet in the store
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">     # noqa: E501
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :param pet_id: The id of the pet to retrieve
</span></span></span><span class="line"><span class="cl"><span class="s2">    :type pet_id: str
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :rtype: Pet
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">pet</span> <span class="o">=</span> <span class="n">pets</span><span class="o">.</span><span class="n">get_pet</span><span class="p">(</span><span class="n">pet_id</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="n">Pet</span><span class="p">(</span><span class="nb">id</span><span class="o">=</span><span class="n">pet</span><span class="o">.</span><span class="n">id</span><span class="p">,</span> <span class="n">breed</span><span class="o">=</span><span class="n">pet</span><span class="o">.</span><span class="n">breed</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="n">pet</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">price</span><span class="o">=</span><span class="n">pet</span><span class="o">.</span><span class="n">price</span><span class="p">),</span> <span class="mi">200</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">response</span> <span class="o">=</span> <span class="p">{},</span> <span class="mi">404</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">response</span>
</span></span></code></pre></div><p>As you can see we call our <code>get_pet()</code> function from our <code>core.pets</code> module. Then if the pets exist
we turn the dict that is returned, into a Python object of class <code>Pet</code> as per <code>rtype</code> we defined in
our OAS. Connexion will handle converting this object into JSON. One other thing we do is if a
<code>KeyError</code> exception was thrown, that must mean we don&rsquo;t have a pet with that id in the pet store. Say we have the following</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;1&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;ginger&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;breed&#34;</span><span class="p">:</span> <span class="s2">&#34;bengal&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;price&#34;</span><span class="p">:</span> <span class="mi">100</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;2&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;sam&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;breed&#34;</span><span class="p">:</span> <span class="s2">&#34;husky&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;price&#34;</span><span class="p">:</span> <span class="mi">10</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;3&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;guido&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;breed&#34;</span><span class="p">:</span> <span class="s2">&#34;python&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;price&#34;</span><span class="p">:</span> <span class="mi">518</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>If we try to retrieve a pet of id 4, Python will throw a KeyError saying this doesn&rsquo;t exist (when we load
the JSON file we convert into a dict). So in this case as per our OAS we want to return a 404 pet doesn&rsquo;t
exist.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">responses</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">200</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Successfully retrived pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">schema</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">$ref</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#/definitions/Pet&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">404</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Pet doesn&#39;t exist&#34;</span><span class="w">
</span></span></span></code></pre></div><p>One very important thing to note is that when we receive a HTTP request with JSON, say for
the <code>add_pet()</code> function Connexion will convert this into a Python object for us and when we
return a Python object it will convert that Python object into JSON. So within our controllers
and core logic we don&rsquo;t actually need to interact with JSON at all. It&rsquo;s all abstracted away
with the Connexion library. We also don&rsquo;t need to use Swagger codegen to generate the models
and controllers we could&rsquo;ve done ourselves, Connexions can run on it&rsquo;s own without them.</p>
<p>Let&rsquo;s see an example of this.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># pets_controller.py</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">add_pet</span><span class="p">(</span><span class="n">body</span><span class="p">):</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;Add a new pet to the store
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">     # noqa: E501
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :param body: Pet to add to the store
</span></span></span><span class="line"><span class="cl"><span class="s2">    :type body: dict | bytes
</span></span></span><span class="line"><span class="cl"><span class="s2">
</span></span></span><span class="line"><span class="cl"><span class="s2">    :rtype: None
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">connexion</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">is_json</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">body</span> <span class="o">=</span> <span class="n">Pet</span><span class="o">.</span><span class="n">from_dict</span><span class="p">(</span><span class="n">connexion</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">get_json</span><span class="p">())</span>  <span class="c1"># noqa: E501</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">pets</span><span class="o">.</span><span class="n">add_pet</span><span class="p">(</span><span class="n">body</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">{},</span> <span class="mi">201</span>
</span></span></code></pre></div><p>The body variable will be a Python object of class Pet. We can then pass this as an argument
to our other <code>add_pet</code> function in our core folder. As you can see we access attributes
because it&rsquo;s an object not a dict i.e. <code>pets[&quot;name&quot;]</code> vs <code>pets.name</code>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># pets.py</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">add_pet</span><span class="p">(</span><span class="n">pet</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span> <span class="o">=</span> <span class="n">read_from_file</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">ids</span> <span class="o">=</span> <span class="n">pets</span><span class="o">.</span><span class="n">keys</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">new_id</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ids</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl">    <span class="n">pets</span><span class="p">[</span><span class="n">new_id</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="s2">&#34;name&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="s2">&#34;breed&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">breed</span><span class="p">,</span> <span class="s2">&#34;price&#34;</span><span class="p">:</span> <span class="n">pet</span><span class="o">.</span><span class="n">price</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="n">write_to_file</span><span class="p">(</span><span class="n">pets</span><span class="p">)</span>
</span></span></code></pre></div><h3 id="swagger-codegen-vs-connexion">Swagger Codegen vs Connexion</h3>
<p>So Connexion does all the routing and validation for us but Swagger codegen is what converts
our input and output into Python classes. Connexions only deals with JSON, it will convert
the JSON into it&rsquo;s equivalent Python object such as lists, strings and dictionary. Swagger
codegen will take this input (a dictionary) and convert that into a Python class.
One example of this in the <code>add_pet</code> function in the <code>pets_controller</code> file. It converts our
dictionary into a <code>Pet</code> object (as shown below). So rather than accessing data using normal
dictionary notation <code>body[&quot;id&quot;]</code> we can now use <code>body.id</code>.
<code>body = Pet.from_dict(connexion.request.get_json()) # noqa: E501</code></p>
<p>For Codegen to convert our Python objects back into a dictionary, so that Connexion can then
convert this into JSON so respond back we use the JSON encoder that codegen provides us
(<code>test_api.web.encoder</code>). To use it all we need to add is to set it as our default encoder
for our flask app <code>flask_app.json_encoder = encoder.JSONEncoder</code>, usually this is done in the
app setup (shown below).</p>
<h2 id="run-a-server">Run a Server</h2>
<p>Now that we have our code how do we actually start up our web application so we can test it. To do this we will create a file which in turn
will create our Connexion/Flask app and start the server, called <code>run.py</code> inside of our <code>test_api</code> folder.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">os</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">connexion</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">.web</span> <span class="kn">import</span> <span class="n">encoder</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">create_app</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">    <span class="n">abs_file_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">abspath</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">dirname</span><span class="p">(</span><span class="vm">__file__</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="n">openapi_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">abs_file_path</span><span class="p">,</span> <span class="s2">&#34;../&#34;</span><span class="p">,</span> <span class="s2">&#34;../&#34;</span><span class="p">,</span> <span class="s2">&#34;openapi&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">app</span> <span class="o">=</span> <span class="n">connexion</span><span class="o">.</span><span class="n">FlaskApp</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="vm">__name__</span><span class="p">,</span> <span class="n">specification_dir</span><span class="o">=</span><span class="n">openapi_path</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;swagger_ui&#34;</span><span class="p">:</span> <span class="kc">False</span><span class="p">,</span> <span class="s2">&#34;serve_spec&#34;</span><span class="p">:</span> <span class="kc">False</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">app</span><span class="o">.</span><span class="n">add_api</span><span class="p">(</span><span class="s2">&#34;specification.yml&#34;</span><span class="p">,</span> <span class="n">strict_validation</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">flask_app</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">app</span>
</span></span><span class="line"><span class="cl">    <span class="n">flask_app</span><span class="o">.</span><span class="n">json_encoder</span> <span class="o">=</span> <span class="n">encoder</span><span class="o">.</span><span class="n">JSONEncoder</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">flask_app</span>
</span></span></code></pre></div><p>You can run the application like a normal flask app from the project root(running from folder where <code>openapi/</code> and <code>src/</code> exist.)</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">FLASK_APP</span><span class="o">=</span>./src/test_api/run.py <span class="nv">FLASK_DEBUG</span><span class="o">=</span><span class="m">1</span> flask run
</span></span></code></pre></div><h2 id="turn-on-swagger-ui">Turn on Swagger UI</h2>
<p>You can also access Swagger UI from within Connexion. We can access it <code>http://127.0.0.1:5000/api/v1/ui/</code>. To do this we need to update <code>run.py</code> so it looks like this:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">app</span> <span class="o">=</span> <span class="n">connexion</span><span class="o">.</span><span class="n">FlaskApp</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="vm">__name__</span><span class="p">,</span> <span class="n">specification_dir</span><span class="o">=</span><span class="n">openapi_path</span><span class="p">,</span> <span class="n">options</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;swagger_ui&#34;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span> <span class="s2">&#34;serve_spec&#34;</span><span class="p">:</span> <span class="kc">True</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span></code></pre></div><h3 id="example-project">Example Project</h3>
<p>Related to this article there is an example project which you can take a look at, to get it running do the following.
Voila we have built a Flask web service with Connexion and OpenAPI.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone https://gitlab.com/hmajid2301/articles.git
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> articles/13.<span class="se">\ </span>REST<span class="se">\ </span>API<span class="se">\ </span>using<span class="se">\ </span>OpenAPI<span class="se">\,\ </span>Flask<span class="se">\ \&amp;\ </span>Connexions/source_code/test-api
</span></span><span class="line"><span class="cl">virtualenv .venv
</span></span><span class="line"><span class="cl"><span class="nb">source</span> .venv/bin/activate
</span></span><span class="line"><span class="cl">pip install -r requirements.txt
</span></span><span class="line"><span class="cl"><span class="nv">FLASK_APP</span><span class="o">=</span>./src/test_api/run.py <span class="nv">FLASK_DEBUG</span><span class="o">=</span><span class="m">1</span> flask run
</span></span></code></pre></div><h2 id="final-thoughts">Final Thoughts</h2>
<p>So as you can see we&rsquo;ve built an web API using Connexion and Flask, where all our code is generated
based of our OAS. So now we are sure our API documentation is accurate. We&rsquo;ve also managed to reduce
some of the boilerplate using Flask, Connexions handles which functions should be called depending on the
CRUD (Create Read Update Delete) operation and endpoints defined in the OAS.</p>
<h2 id="appendix">Appendix</h2>
<ul>
<li><a href="https://gitlab.com/hmajid2301/blog/-/tree/main/content/posts/2019-03-04-drawernavigator-tabnavigator-and-stacknavigator-with-react-navigation/source_code">Example source code</a></li>
<li><a href="https://swagger.io/docs/specification/about/">OpenAPI</a></li>
<li><a href="https://github.com/swagger-api/swagger-codegen">Swagger Codegen</a></li>
<li><a href="https://editor.swagger.io/">Swagger Editor</a></li>
<li><a href="https://github.com/zalando/connexion">Connexion</a></li>
</ul>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
