<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Carlos V.</title>
    <description>The latest articles on DEV Community by Carlos V. (@po5i).</description>
    <link>https://dev.to/po5i</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F344370%2F69f0f44e-eb5e-4fca-b663-efbf3503092e.png</url>
      <title>DEV Community: Carlos V.</title>
      <link>https://dev.to/po5i</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/po5i"/>
    <language>en</language>
    <item>
      <title>Parallelism in Python starter pack</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Wed, 06 Jul 2022 21:38:37 +0000</pubDate>
      <link>https://dev.to/po5i/parallelism-in-python-starter-pack-284k</link>
      <guid>https://dev.to/po5i/parallelism-in-python-starter-pack-284k</guid>
      <description>&lt;p&gt;I'm happy to share with you a post that I wrote for &lt;a href="https://medium.com/globant"&gt;Globant Medium&lt;/a&gt;. Enjoy!&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="https://medium.com/globant/parallelism-in-python-starter-pack-84cd6a3d5e6c" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--naAan3YY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/v2/resize:fill:96:96/1%2AjzS1FXvaH6tV7AMeHnDZ4w.png" alt="Carlos Villavicencio"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://medium.com/globant/parallelism-in-python-starter-pack-84cd6a3d5e6c" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Parallelism in Python starter pack | by Carlos Villavicencio | Globant | Medium&lt;/h2&gt;
      &lt;h3&gt;Carlos Villavicencio ・ &lt;time&gt;Jul 6, 2022&lt;/time&gt; ・ 
      &lt;div class="ltag__link__servicename"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YjpYcCMa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/medium-f709f79cf29704f9f4c2a83f950b2964e95007a3e311b77f686915c71574fef2.svg" alt="Medium Logo"&gt;
        Medium
      &lt;/div&gt;
    &lt;/h3&gt;
&lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>python</category>
      <category>multiprocessing</category>
      <category>asyncio</category>
      <category>concurrency</category>
    </item>
    <item>
      <title>GitHub Action to run mypy on changed files only</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Wed, 15 Jun 2022 20:13:52 +0000</pubDate>
      <link>https://dev.to/po5i/github-action-to-run-mypy-on-changed-files-only-3iip</link>
      <guid>https://dev.to/po5i/github-action-to-run-mypy-on-changed-files-only-3iip</guid>
      <description>&lt;p&gt;Recently, I needed a way to perform Python static type checking using mypy only on "changed" files for a GitHub Pull Request.&lt;/p&gt;

&lt;p&gt;So I googled a bit and found out this super useful action that you can use it in your workflow right away.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/tj-actions" rel="noopener noreferrer"&gt;
        tj-actions
      &lt;/a&gt; / &lt;a href="https://github.com/tj-actions/changed-files" rel="noopener noreferrer"&gt;
        changed-files
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      :octocat: Github action to retrieve all (added, copied, modified, deleted, renamed, type changed, unmerged, unknown) files and directories.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/dd44c065577f813a8d6c976fef88976f812eed4bfcfa20fa6b23ebb899a09531/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5562756e74752d4539353432303f7374796c653d666f722d7468652d6261646765266c6f676f3d7562756e7475266c6f676f436f6c6f723d7768697465" alt="Ubuntu"&gt;&lt;/a&gt;
&lt;a href="https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/04687ce3613669e12a6f991ece6c64a4e51067a44f041332d70c4f83a6141908/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6d61632532306f732d3030303030303f7374796c653d666f722d7468652d6261646765266c6f676f3d6d61636f73266c6f676f436f6c6f723d463046304630" alt="Mac OS"&gt;&lt;/a&gt;
&lt;a href="https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/1cc3ed014dbb3cc907789013096c44d0bc78875ee219d9455f619ff18059ac4a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f57696e646f77732d3030373844363f7374796c653d666f722d7468652d6261646765266c6f676f3d77696e646f7773266c6f676f436f6c6f723d7768697465" alt="Windows"&gt;&lt;/a&gt;
&lt;a href="https://github.com/search?o=desc&amp;amp;q=tj-actions+changed-files+language%3AYAML&amp;amp;s=&amp;amp;type=Code" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/b77f39c8be354893e702dc451d8f56d80230a37d457e4cd96fcbfdce6d86d3e1/68747470733a2f2f696d672e736869656c64732e696f2f656e64706f696e743f7374796c653d666f722d7468652d62616467652675726c3d6874747073253341253246253246757365642d62792e76657263656c2e6170702532466170692532466769746875622d616374696f6e73253246757365642d6279253346616374696f6e253344746a2d616374696f6e732532466368616e6765642d66696c65732532367061636b6167655f69642533445547466a6132466e5a5330794f5451794e5455344d446b35253236626164676525334474727565" alt="Public workflows that use this action."&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://app.codacy.com/gh/tj-actions/changed-files/dashboard?utm_source=gh&amp;amp;utm_medium=referral&amp;amp;utm_content=&amp;amp;utm_campaign=Badge_grade" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c764ba2dc6b982a1a7b35d50cf76764c978fb65d0b31eca2c5bdd3d57f60c8a2/68747470733a2f2f6170702e636f646163792e636f6d2f70726f6a6563742f62616467652f47726164652f3466653266343963336162313434623062626534656666633835613036316130" alt="Codacy Badge"&gt;&lt;/a&gt;
&lt;a href="https://github.com/tj-actions/changed-files/actions/workflows/test.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/tj-actions/changed-files/actions/workflows/test.yml/badge.svg" alt="CI"&gt;&lt;/a&gt;
&lt;a href="https://github.com/tj-actions/changed-files/actions/workflows/sync-release-version.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/tj-actions/changed-files/actions/workflows/sync-release-version.yml/badge.svg" alt="Update release version."&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/tj-actions/changed-files#contributors-" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/7df7abd7c16b8b71160a0b7cb8cd921cbb21bcb46241ba97d6f4efb71ab9c8cc/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f616c6c5f636f6e7472696275746f72732d32372d6f72616e67652e7376673f7374796c653d666c61742d737175617265" alt="All Contributors"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;changed-files&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Effortlessly track all changed files and directories relative to a target branch, the current branch (preceding commit or the last remote commit), multiple branches, or custom commits returning &lt;strong&gt;relative paths&lt;/strong&gt; from the project root using this GitHub action.&lt;/p&gt;
&lt;div class="markdown-alert markdown-alert-note"&gt;
&lt;p class="markdown-alert-title"&gt;Note&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;This action solely identifies files that have changed for events such as &lt;a href="https://github.com/tj-actions/changed-files#other-supported-events-electron" rel="noopener noreferrer"&gt;&lt;code&gt;pull_request*&lt;/code&gt;, &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;merge_group&lt;/code&gt;, &lt;code&gt;release&lt;/code&gt;, and many more&lt;/a&gt;. However, it doesn't detect pending uncommitted changes created during the workflow execution.&lt;/p&gt;
&lt;p&gt;See: &lt;a href="https://github.com/tj-actions/verify-changed-files" rel="noopener noreferrer"&gt;https://github.com/tj-actions/verify-changed-files&lt;/a&gt; instead.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of contents&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#features-" rel="noopener noreferrer"&gt;Features 🚀&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tj-actions/changed-files#usage-" rel="noopener noreferrer"&gt;Usage 💻&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/tj-actions/changed-files#on-pull_request-" rel="noopener noreferrer"&gt;On &lt;code&gt;pull_request&lt;/code&gt; 🔀&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#using-local-git-directory-" rel="noopener noreferrer"&gt;Using local .git directory 📁&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#using-githubs-api-octocat" rel="noopener noreferrer"&gt;Using Github's API &lt;img class="emoji" title=":octocat:" alt=":octocat:" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.githubassets.com%2Fimages%2Ficons%2Femoji%2Foctocat.png" height="20" width="20"&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#on-push-%EF%B8%8F" rel="noopener noreferrer"&gt;On &lt;code&gt;push&lt;/code&gt; ⬆️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#other-supported-events-electron" rel="noopener noreferrer"&gt;Other supported events &lt;img class="emoji" title=":electron:" alt=":electron:" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.githubassets.com%2Fimages%2Ficons%2Femoji%2Felectron.png" height="20" width="20"&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#inputs-%EF%B8%8F" rel="noopener noreferrer"&gt;Inputs ⚙️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#useful-acronyms-" rel="noopener noreferrer"&gt;Useful Acronyms 🧮&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#outputs-" rel="noopener noreferrer"&gt;Outputs 📤&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#versioning-%EF%B8%8F" rel="noopener noreferrer"&gt;Versioning 🏷️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#examples-" rel="noopener noreferrer"&gt;Examples 📄&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tj-actions/changed-files#real-world-usage-" rel="noopener noreferrer"&gt;Real-world usage 🌐&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#open-source-projects-" rel="noopener noreferrer"&gt;Open source projects 📦&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#scalability-example-" rel="noopener noreferrer"&gt;Scalability Example 📈&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#important-notice-%EF%B8%8F" rel="noopener noreferrer"&gt;Important Notice ⚠️&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#migration-guide-" rel="noopener noreferrer"&gt;Migration guide 🔄&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#credits-" rel="noopener noreferrer"&gt;Credits 👏&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#report-bugs-" rel="noopener noreferrer"&gt;Report Bugs 🐛&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tj-actions/changed-files#contributors-" rel="noopener noreferrer"&gt;Contributors ✨&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features 🚀&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Fast execution, averaging 0-10 seconds.&lt;/li&gt;
&lt;li&gt;Leverages either &lt;a href="https://docs.github.com/en/rest/reference/repos#list-commits" rel="noopener noreferrer"&gt;Github's REST API&lt;/a&gt; or…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/tj-actions/changed-files" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;And after customizing some options like filter only &lt;code&gt;*.py&lt;/code&gt; files, I was able to run &lt;code&gt;mypy&lt;/code&gt; passing the changed files as argument. &lt;/p&gt;

&lt;p&gt;It's worth to mention that I needed to include &lt;code&gt;--ignore-missing-imports&lt;/code&gt; argument to &lt;code&gt;mypy&lt;/code&gt; because I'm not scanning the whole repo, only some files. The goal of course is to check them all. However, a lot of fixes should be made before it's ready.&lt;/p&gt;

&lt;p&gt;This solution can be very useful to you if you want to include static type checking for new files on a legacy project where existing files will be fixed little by little.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mypy&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;check"&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

  &lt;span class="na"&gt;static-type-check&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-python@v3&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.x'&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pip install mypy&lt;/span&gt;  &lt;span class="c1"&gt;# you can pin your preferred version&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get Python changed files&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;changed-py-files&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tj-actions/changed-files@v23&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;*.py&lt;/span&gt;
          &lt;span class="s"&gt;**/*.py&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run if any of the listed files above is changed&lt;/span&gt;
      &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;steps.changed-py-files.outputs.any_changed == 'true'&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mypy ${{ steps.changed-py-files.outputs.all_changed_files }} --ignore-missing-imports&lt;/span&gt;



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Happy type-safety!&lt;/p&gt;

</description>
      <category>python</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to add type annotations to SQLAlchemy models</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Mon, 21 Mar 2022 13:07:02 +0000</pubDate>
      <link>https://dev.to/po5i/how-to-add-type-annotations-to-sqlalchemy-models-376g</link>
      <guid>https://dev.to/po5i/how-to-add-type-annotations-to-sqlalchemy-models-376g</guid>
      <description>&lt;p&gt;For a long time, I’ve been advocating for using &lt;a href="https://www.stackbuilders.com/blog/using-types-in-python-with-mypy/" rel="noopener noreferrer"&gt;type annotations&lt;/a&gt; in languages like Python because of its benefits. To mention some we can improve the robustness, testability, and scalability of our applications.  Just as important, we can reduce the number of unit tests that we need to write. The goal is to reduce bugs at run-time. This technique can be used in languages with a strong type system.&lt;/p&gt;

&lt;p&gt;Does Python have a strong type system? Of course! This type-safety example is a simple demonstration of this statement:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;gt;&amp;gt;&amp;gt; foo = 5
&amp;gt;&amp;gt;&amp;gt; bar = 'hello'
&amp;gt;&amp;gt;&amp;gt; foo + bar
Traceback (most recent call last):
  File "&amp;lt;stdin&amp;gt;", line 1, in &amp;lt;module&amp;gt;
TypeError: unsupported operand type(s) for +: 'int' and 'str'
&amp;gt;&amp;gt;&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;People tend to think that while Python is a dynamic "interpreted" language (spoiler alert: it's not), the type system is weak, with similar behavior of JavaScript's implicit type coercion:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Welcome to Node.js v16.13.2.
Type ".help" for more information.
&amp;gt; foo = 5
5
&amp;gt; bar = 'hello'
'hello'
&amp;gt; foo + bar
'5hello'
&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Going back to Python and its type annotations feature, you might have a medium-sized project that needs to use database storage. However, it's common to leave that part out of our safe and sound type annotations. But fear not, you can also annotate your models. In this example, I'm going to show you a small example using &lt;a href="https://flask.palletsprojects.com/" rel="noopener noreferrer"&gt;Flask&lt;/a&gt; and &lt;a href="https://www.sqlalchemy.org/" rel="noopener noreferrer"&gt;SQLAlchemy&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Some time ago, I built a tiny &lt;a href="https://github.com/po5i/flask-mini-tests" rel="noopener noreferrer"&gt;sample project to demonstrate TDD on Flask&lt;/a&gt;. Let’s use it as a starting point for this tutorial. This example will have a small model for storing notifications in a database and a couple of endpoints to get/post some data.&lt;/p&gt;

&lt;p&gt;We’re going to use &lt;a href="https://flask-sqlalchemy.palletsprojects.com/en/2.x/" rel="noopener noreferrer"&gt;Flask-SQLAlchemy&lt;/a&gt;, which provides a quick integration between the framework and the ORM. So after setting up the initialization we can start writing a model:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask_sqlalchemy.model&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DefaultMeta&lt;/span&gt;


&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DefaultMeta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;__tablename__&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;notifications&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nullable&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;We can explain some details here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Why the &lt;code&gt;BaseModel&lt;/code&gt; definition? Answer: We're using &lt;a href="https://mypy.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;mypy&lt;/a&gt; for the static type checking. Defining a model as Flask-SQLAlchemy suggests causes an issue on that line because the declarative base &lt;code&gt;db.Model&lt;/code&gt; is defined dynamically (on runtime) contrary to what a static checker expects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flask-SQLAlchemy suggests that we can use &lt;code&gt;db.Column&lt;/code&gt; or &lt;code&gt;db.Integer&lt;/code&gt; to define our properties, but we won't follow that convention. The reason behind this decision is because Flask-SQLAlchemy does a lot of work dynamically on runtime that can confuse the static type checking system. To avoid that, we are using SQLAlchemy classes directly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;



&lt;p&gt;The static type checker combination will be &lt;code&gt;mypy&lt;/code&gt; and &lt;a href="https://github.com/dropbox/sqlalchemy-stubs" rel="noopener noreferrer"&gt;sqlalchemy-stubs plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Just install them with pip:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

pip &lt;span class="nb"&gt;install &lt;/span&gt;mypy
pip &lt;span class="nb"&gt;install &lt;/span&gt;sqlalchemy-stubs


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;And create a &lt;code&gt;mypy.ini&lt;/code&gt; file on the root of the project:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;

&lt;span class="nn"&gt;[mypy]&lt;/span&gt;
&lt;span class="py"&gt;python_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;3.9&lt;/span&gt;
&lt;span class="py"&gt;ignore_missing_imports&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;True&lt;/span&gt;
&lt;span class="py"&gt;plugins&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;sqlmypy&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Then you're ready to do some static type check analysis to the Python file:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

mypy app.py


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We're going to expand this model a bit. First, we need a method to "serialize" the model into a &lt;code&gt;dict&lt;/code&gt; so it can be returned in the endpoint. Also, we need a couple of methods to get all the records filtered by some criteria.&lt;/p&gt;

&lt;p&gt;We will define a &lt;code&gt;NotificationModel&lt;/code&gt; dictionary definition.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotificationModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TypedDict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Then, our basic serialization method for the &lt;code&gt;Notification&lt;/code&gt; model will look like this.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;NotificationModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;url&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;read&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Here you can see the type annotations in action. Either with a properly configured editor (like VSCode) or with the &lt;code&gt;mypy&lt;/code&gt; command, types should match between what &lt;code&gt;to_dict&lt;/code&gt; returns and the &lt;code&gt;NotificationModel&lt;/code&gt; definition, otherwise the analysis will fail.&lt;/p&gt;

&lt;p&gt;Example: if the &lt;code&gt;to_dict&lt;/code&gt; method returns a string value on the &lt;code&gt;id&lt;/code&gt; property&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;NotificationsModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;  &lt;span class="c1"&gt;# &amp;lt;-- should not be str
&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Then the error we get will be the following.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

app.py:38: error: Incompatible types (expression has type "Optional[str]", TypedDict item "id" has type "int")
Found 1 error in 1 file (checked 1 source file)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Next, we will implement a couple of class methods that will return all the records on the table and another to get only the unread notifications:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@classmethod&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@classmethod&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_unread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cls&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;A key point here in order for a method to return its same class is to have this line on top of the module. See &lt;a href="https://docs.python.org/3/whatsnew/3.7.html#pep-563-postponed-evaluation-of-annotations" rel="noopener noreferrer"&gt;postponed evaluation of annotations&lt;/a&gt; for more details.&lt;/p&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;annotations&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;
&lt;/blockquote&gt;

&lt;p&gt;At this point, we have our model ready to be used on a presentation layer.&lt;/p&gt;



&lt;p&gt;Let's implement a &lt;code&gt;/notifications&lt;/code&gt; endpoint that accepts two methods, &lt;code&gt;GET&lt;/code&gt; to list all notifications, and &lt;code&gt;POST&lt;/code&gt; to save a new one with form data:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/notifications&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;notifications&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;new_notification&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromisoformat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_notification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;notifications&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_dict&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;notification&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;notifications&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;We implemented another route to get all unread notifications but it's pretty similar to the &lt;code&gt;GET&lt;/code&gt; section of the above endpoint. You can review the entire sample project in this repository:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/po5i" rel="noopener noreferrer"&gt;
        po5i
      &lt;/a&gt; / &lt;a href="https://github.com/po5i/flask-mini-orm" rel="noopener noreferrer"&gt;
        flask-mini-orm
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      How to use type annotations on a SQLAlchemy project
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Mini example of Flask ORM with SQLAlchemy&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/po5i/flask-mini-orm/workflows/Flask/badge.svg"&gt;&lt;img src="https://github.com/po5i/flask-mini-orm/workflows/Flask/badge.svg" alt="Actions Workflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a example repository for &lt;a href="https://dev.to/po5i/how-to-add-type-annotations-to-sqlalchemy-models-376g" rel="nofollow"&gt;my article&lt;/a&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setup&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Create and activate the virtual environment&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;virtualenv venv
&lt;span class="pl-c1"&gt;source&lt;/span&gt; venv/bin/activate&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Run the server&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;python app.py&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Run the static type check&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;mypy app.py&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The server will be up on &lt;a href="http://localhost:5000" rel="nofollow noopener noreferrer"&gt;http://localhost:5000&lt;/a&gt; and a database file named &lt;code&gt;db.sqlite3&lt;/code&gt; is created.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How it works&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;The toy API has four endpoints:&lt;/p&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;GET /&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Returns hello world&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;GET /notifications&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Returns all notifications&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;POST /notifications&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Adds a notification on the DB&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;GET /notifications/unread&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Returns all unread notifications&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;&lt;/p&gt;

&lt;p&gt;If you want to add a notification on the DB, you can use this cURL command:&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;curl -X POST \
  &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;http://localhost:5000/notifications&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt; \
  --header &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;Accept: */*&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt; \
  --form &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;description="Foo"&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt; \
  --form &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;date="2022-03-20T18:09:22"&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt; \
  --form &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;url="http://foo.bar.com"&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt; \
  --form &lt;span class="pl-s"&gt;&lt;span class="pl-pds"&gt;'&lt;/span&gt;email="foo@bar.com"&lt;span class="pl-pds"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Python &amp;gt;= 3.9&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;License&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.opensource.org/licenses/mit-license.html" rel="nofollow noopener noreferrer"&gt;MIT&lt;/a&gt;&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/po5i/flask-mini-orm" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;The usage of these endpoints is beyond the scope of this post. They were only implemented to demonstrate and test the SQLAlchemy Notification model. I also like to point out that this example has everything implemented in a single module. We recommend you to (1) split your models and (2) use a migration tool such as &lt;a href="https://alembic.sqlalchemy.org/en/latest/" rel="noopener noreferrer"&gt;Alembic&lt;/a&gt;. Last but not least, (3) test your logic with unit tests. We didn’t add them but feel free to propose some as pull requests. In the meantime, we configured the CI workflow with the &lt;code&gt;mypy&lt;/code&gt; type checking.&lt;/p&gt;

&lt;p&gt;I encourage you to use a better tool to implement REST APIs like I did on a previous post:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/po5i" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F344370%2F69f0f44e-eb5e-4fca-b663-efbf3503092e.png" alt="po5i"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/po5i/how-to-set-up-a-rest-api-in-flask-in-5-steps-5b7d" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to set up a REST API in Flask in 5 steps&lt;/h2&gt;
      &lt;h3&gt;Carlos V. ・ Nov 5 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#python&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#rest&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#api&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#flask&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Are you using Django? There are also some stubs ready to annotate your models: &lt;a href="https://github.com/typeddjango/django-stubs" rel="noopener noreferrer"&gt;django-stubs&lt;/a&gt; and &lt;a href="https://github.com/mkurnikov/djangorestframework-stubs" rel="noopener noreferrer"&gt;djangorestframework-stubs&lt;/a&gt; than can suit your needs. Let me know if you want to read some content about them.&lt;/p&gt;

&lt;p&gt;Thanks for reading 🙇&lt;/p&gt;

&lt;p&gt;Edit: Article also cross-posted &lt;a href="https://www.stackbuilders.com/blog/how-to-add-type-annotations-to-sqlalchemy-models/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>python</category>
      <category>orm</category>
      <category>flask</category>
      <category>typechecking</category>
    </item>
    <item>
      <title>How to generate a TypeScript client from a Swagger documented API</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Mon, 15 Nov 2021 22:04:32 +0000</pubDate>
      <link>https://dev.to/po5i/how-to-generate-a-typescript-client-from-a-swagger-documented-api-14d8</link>
      <guid>https://dev.to/po5i/how-to-generate-a-typescript-client-from-a-swagger-documented-api-14d8</guid>
      <description>&lt;p&gt;In my previous tutorial, I built a simple REST API with Swagger documentation. Check it out:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/po5i" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F344370%2F69f0f44e-eb5e-4fca-b663-efbf3503092e.png" alt="po5i"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/po5i/how-to-set-up-a-rest-api-in-flask-in-5-steps-5b7d" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to set up a REST API in Flask in 5 steps&lt;/h2&gt;
      &lt;h3&gt;Carlos V. ・ Nov 5 '21&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#python&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#rest&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#api&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#flask&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;In this tutorial, I will generate a TypeScript client code based on the Swagger documentation and use it on a simple React application (it can be any front-end application).&lt;/p&gt;

&lt;p&gt;Why we want to do something like this? First of all, it's better to have one a single source of truth for the contracts in our server-client architecture. Otherwise, one change can break all our consumers.&lt;/p&gt;

&lt;p&gt;For this process, I'm gonna use &lt;a href="https://github.com/acacode/swagger-typescript-api" rel="noopener noreferrer"&gt;swagger-typescript-api&lt;/a&gt;. I've seen this tool constantly evolving throughout the last year, its maintainers are doing an awesome job.&lt;/p&gt;

&lt;p&gt;First of all, I bootstrap a React app using &lt;a href="https://github.com/facebook/create-react-app" rel="noopener noreferrer"&gt;create-react-app&lt;/a&gt; (CRA) with a TypeScript template, of course 💅&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npx create-react-app react-mini-swagger-client &lt;span class="nt"&gt;--template&lt;/span&gt; typescript


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Somewhere else, I have my previous &lt;a href="https://github.com/po5i/flask-mini-rest" rel="noopener noreferrer"&gt;flask-mini-rest&lt;/a&gt; up and running in &lt;code&gt;localhost:5000&lt;/code&gt;. (Recently I pushed some changes in order to support CORS and improve the Swagger model documentation).&lt;/p&gt;

&lt;p&gt;CRA places all the source files inside &lt;code&gt;./src&lt;/code&gt; directory, so I will generate my TS client there.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npx swagger-typescript-api &lt;span class="nt"&gt;-p&lt;/span&gt; http://127.0.0.1:5000/api/v1/swagger.json &lt;span class="nt"&gt;-o&lt;/span&gt; ./src/apiClient &lt;span class="nt"&gt;--modular&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;swagger-typescript-api is pretty cool, it can be run with &lt;code&gt;npx&lt;/code&gt; and it support many flags documented in its repo. It generates 3 files for my API&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Items.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;It exports the main client to be used on our application. Each method of the &lt;code&gt;Items&lt;/code&gt; class is one public endpoint. Types were read from the Swagger docs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;data-contracts.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Are the API models or return types.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;http-client.ts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;This is the code responsible to actually fetch the data to the server.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Let's start the development server:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npm start


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now it comes the interesting part. How to use the generated TS client. I'm going to write some simple examples on how to use the TS client in the &lt;code&gt;src/App.tsx&lt;/code&gt; file which is the only one with the bootstrapped app logic.&lt;/p&gt;

&lt;p&gt;Let's initialize the API client which is declared in the &lt;code&gt;Items.ts&lt;/code&gt; module:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Items&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://localhost:5000/api/v1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;If your app is running a in a production server, the &lt;code&gt;baseUrl&lt;/code&gt; path should point to the appropriate API URL.&lt;/p&gt;

&lt;p&gt;To get all the Items:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItemsApi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nf"&gt;setItems&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// This set the response to the `items` state&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Let's suppose we want to insert a new item in the API in a form button:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;
  &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// `Item` is imported from the data-contracts&lt;/span&gt;
      &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// this is a variable with the form input&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// this is a variable with the form input&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postItemsApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItems&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  Add
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;It's pretty similar with the &lt;code&gt;getItemApi&lt;/code&gt; which gets a simple  Item resource.&lt;/p&gt;

&lt;p&gt;As you can see, it's pretty simple to use, self-documented and strongly-typed. Having a well defined back-end contract you can ensure robustness and type-safety front-end communication. The types generated can be used in many ways, TypeScript &lt;a href="https://www.typescriptlang.org/docs/handbook/project-references.html" rel="noopener noreferrer"&gt;project references&lt;/a&gt; for example. Types can be shared among many consumers. My friend and mentor, Fernanda, presented a great talk in this topic called &lt;a href="https://www.youtube.com/watch?v=8bLYoLBhNI0" rel="noopener noreferrer"&gt;Don't Break the Contract: Keep Consistency with Full Stack Type Safety&lt;/a&gt;, please give it a look.&lt;/p&gt;

&lt;p&gt;Also, an automated job can generate the a new TS client triggered by some event. But still it's up to us to update the consumers. Hopefully the unit tests can detect breaking changes.&lt;/p&gt;

&lt;p&gt;Check out a full working code in my repo. Sorry that I didn't follow all the best practices as I only wanted to show how to use this TS client.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/po5i" rel="noopener noreferrer"&gt;
        po5i
      &lt;/a&gt; / &lt;a href="https://github.com/po5i/react-mini-swagger-client" rel="noopener noreferrer"&gt;
        react-mini-swagger-client
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Mini example of swagger-typescript-api&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;This project was bootstrapped with &lt;a href="https://github.com/facebook/create-react-app" rel="noopener noreferrer"&gt;Create React App&lt;/a&gt;.&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;npx create-react-app react-mini-swagger-client --template typescript
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And API client was generated with &lt;a href="https://github.com/acacode/swagger-typescript-api" rel="noopener noreferrer"&gt;swagger-typescript-api&lt;/a&gt;.&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;npx swagger-typescript-api -p http://127.0.0.1:5000/api/v1/swagger.json -o ./src/apiClient --modular
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;... while running &lt;a href="https://github.com/po5i/flask-mini-rest" rel="noopener noreferrer"&gt;flask-mini-rest&lt;/a&gt; app.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Run the app&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;In the project directory, you can run:&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Runs the app in the development mode.&lt;br&gt;
Open &lt;a href="http://localhost:3000" rel="nofollow noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; to view it in the browser.&lt;/p&gt;
&lt;p&gt;The page will reload if you make edits.&lt;br&gt;
You will also see any lint errors in the console.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;License&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.opensource.org/licenses/mit-license.html" rel="nofollow noopener noreferrer"&gt;MIT&lt;/a&gt;&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/po5i/react-mini-swagger-client" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


</description>
      <category>typescript</category>
      <category>api</category>
      <category>swagger</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to set up a REST API in Flask in 5 steps</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Fri, 05 Nov 2021 22:07:25 +0000</pubDate>
      <link>https://dev.to/po5i/how-to-set-up-a-rest-api-in-flask-in-5-steps-5b7d</link>
      <guid>https://dev.to/po5i/how-to-set-up-a-rest-api-in-flask-in-5-steps-5b7d</guid>
      <description>&lt;p&gt;This small tutorial was built on top of my previous code sample that configures a simple Flask app with testing:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/po5i" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F344370%2F69f0f44e-eb5e-4fca-b663-efbf3503092e.png" alt="po5i"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/po5i/how-to-add-basic-unit-test-to-a-python-flask-app-using-pytest-1m7a" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to add basic unit test to a Python Flask app using Pytest&lt;/h2&gt;
      &lt;h3&gt;Carlos V. ・ May 18 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#python&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#testing&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;There are many ways to build REST APIs, the most common is to have a Django app with DRF. Other people are trying FastAPI (I need to take a closer look at it, maybe in a future post).&lt;/p&gt;

&lt;p&gt;But if you are using a Flask based app, I recently tried &lt;a href="https://flask-restx.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Flask-RESTX&lt;/a&gt; library which includes some great features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Swagger documentation (Heck yes!)&lt;/li&gt;
&lt;li&gt;Response marshalling&lt;/li&gt;
&lt;li&gt;Request parsing&lt;/li&gt;
&lt;li&gt;Error handling, logging and blueprint support. Neat Flask integration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this demo, I'll show you how to set up a quick REST API, with Swagger documentation, request parsing and simple response formatting.&lt;/p&gt;




&lt;p&gt;Let's start by initializing the blueprint and defining the api object in a new module. I named this one as &lt;code&gt;api.py&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="n"&gt;blueprint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Blueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/v1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Api&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;blueprint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mini REST API&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A mini REST API&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;namespace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item operations&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_namespace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Flask-RESTX support Flask Blueprint and they are really &lt;a href="https://flask-restx.readthedocs.io/en/latest/scaling.html#use-with-blueprints" rel="noopener noreferrer"&gt;simple to implement&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My application is served at &lt;code&gt;http://localhost:5000&lt;/code&gt; but my API base URL will be &lt;code&gt;http://localhost:5000/api/v1&lt;/code&gt;. This is also the page where you can find the Swagger docs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc65hlxxmj6d8uya5y6gm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc65hlxxmj6d8uya5y6gm.png" alt="Swagger landing page sample"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Next, let's write the base models. My sample API will manage Items and Details objects, so I need to write the &lt;em&gt;models&lt;/em&gt; that will be in charge of presenting them in the API standard response.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="n"&gt;detail_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Detail&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="n"&gt;item_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;details&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Nested&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detail_model&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The idea of writing models is to use Flask-RESTX &lt;a href="https://flask-restx.readthedocs.io/en/latest/marshalling.html" rel="noopener noreferrer"&gt;response marshalling&lt;/a&gt;, so no matter if our objects scale, the response will always be as we document it on our models. Flask-RESTX includes a lot of tools for this such as renaming attributes, complex, custom, and nested fields, and more.&lt;/p&gt;

&lt;p&gt;The final set up step is to write the request parser.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="n"&gt;item_parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;item_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;form&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;item_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;form&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;detail_parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;detail_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;form&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;detail_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_argument&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;form&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;In a similar way as before, we make use of Flask-RESTX &lt;a href="https://flask-restx.readthedocs.io/en/latest/parsing.html" rel="noopener noreferrer"&gt;request parser&lt;/a&gt; to read and validate values that we expect to receive in our endpoints. In this case I plan to implement two object APIs that will append elements to our &lt;em&gt;database&lt;/em&gt; objects. (Our database is a simple in-memory object 😅)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="n"&gt;memory_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item 1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;details&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Detail 1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Detail 2&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now it's time to implement our APIs. The first API I want to build is the one that manages the items. I will call this &lt;code&gt;ItemApi&lt;/code&gt; and the route will be &lt;code&gt;/&lt;/code&gt; which means the root of the namespace &lt;code&gt;items&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@ns.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ItemsApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    API for handling the Item list resource
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="nd"&gt;@api.response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTTPStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Get the item list&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@api.marshal_list_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item_model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        Returns the memory object
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;memory_object&lt;/span&gt;

    &lt;span class="nd"&gt;@api.response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTTPStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Object added&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@api.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item_parser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        Simple append something to the memory object
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;memory_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This will enable two endpoints:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Parameters&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/items/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;list of &lt;code&gt;item_model&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/items/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;As defined on &lt;code&gt;item_parser&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All decorators are provided by Flask-RESTX. &lt;code&gt;HTTPStatus&lt;/code&gt; class is provided by the &lt;code&gt;http&lt;/code&gt; module. Pretty simple huh?, let's build the second one.&lt;/p&gt;



&lt;p&gt;This one will manage a single item resource. So, to get its data and add details we need the following implementation:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="nd"&gt;@ns.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&amp;lt;int:item_id&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ItemApi&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Resource&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    API for handling the single Item resource
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;

    &lt;span class="nd"&gt;@api.response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTTPStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OK&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Get the item list&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@api.response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTTPStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@api.marshal_with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item_model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Item&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        Returns the memory object
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTTPStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;memory_object&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;item_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nd"&gt;@api.response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTTPStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NO_CONTENT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Object added&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@api.response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTTPStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nd"&gt;@api.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;detail_parser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        Simple append details to the memory object
        &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
        &lt;span class="n"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse_args&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_lookup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;details&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
        &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;StopIteration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HTTPStatus&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This will enable two more endpoints:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Parameters&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/items/&amp;lt;item_id&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;GET&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;a single &lt;code&gt;item_model&lt;/code&gt; resource.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/v1/items/&amp;lt;item_id&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;POST&lt;/td&gt;
&lt;td&gt;As defined on &lt;code&gt;detail_parser&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;To wrap up our application, you only need to import the module at &lt;code&gt;app.py&lt;/code&gt; and register the Blueprint.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;blueprint&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# This line already exists
&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register_blueprint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;blueprint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can fork and play with this example using this repo:&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/po5i" rel="noopener noreferrer"&gt;
        po5i
      &lt;/a&gt; / &lt;a href="https://github.com/po5i/flask-mini-rest" rel="noopener noreferrer"&gt;
        flask-mini-rest
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Mini example of Flask and Flask-RESTX&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/po5i/flask-mini-rest/workflows/Flask/badge.svg"&gt;&lt;img src="https://github.com/po5i/flask-mini-rest/workflows/Flask/badge.svg" alt="Actions Workflow"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a examle repository for &lt;a href="https://dev.to/po5i/how-to-set-up-a-rest-api-in-flask-in-5-steps-5b7d" rel="nofollow"&gt;my article&lt;/a&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setup&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Create and activate the virtual environment&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;virtualenv venv
&lt;span class="pl-c1"&gt;source&lt;/span&gt; venv/bin/activate&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Run the server&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;FLASK_ENV=development flask run&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Check out the Swagger documentation and playground at&lt;/p&gt;
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;http://localhost:5000/api/v1/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Run the tests&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;python -m pytest&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The server will be up on &lt;a href="http://localhost:5000" rel="nofollow noopener noreferrer"&gt;http://localhost:5000&lt;/a&gt;
and the API landing page will be available on &lt;a href="http://127.0.0.1:5000/api/v1/" rel="nofollow noopener noreferrer"&gt;http://127.0.0.1:5000/api/v1/&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Requirements&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Python &amp;gt;= 3.9&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;License&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="http://www.opensource.org/licenses/mit-license.html" rel="nofollow noopener noreferrer"&gt;MIT&lt;/a&gt;&lt;/p&gt;

&lt;/div&gt;
&lt;br&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/po5i/flask-mini-rest" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;I also added some unit tests and type annotations for your delight 😉.&lt;/p&gt;

&lt;p&gt;Any feedback or suggestions are welcome and I'll be happy to answer any question you may have.&lt;/p&gt;

</description>
      <category>python</category>
      <category>rest</category>
      <category>api</category>
      <category>flask</category>
    </item>
    <item>
      <title>Functional Programming inside OOP? It’s possible with Python</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Tue, 28 Sep 2021 14:30:59 +0000</pubDate>
      <link>https://dev.to/po5i/functional-programming-inside-oop-it-s-possible-with-python-1m04</link>
      <guid>https://dev.to/po5i/functional-programming-inside-oop-it-s-possible-with-python-1m04</guid>
      <description>&lt;p&gt;I'm sharing my &lt;a href="https://ep2021.europython.eu/talks/5SQrJC4-functional-programming-inside-oop-its-possible-with-python/"&gt;EuroPython 2021 talk&lt;/a&gt; today. &lt;/p&gt;

&lt;p&gt;Please enjoy!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/43yNp4D2UKo"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>python</category>
      <category>community</category>
      <category>conference</category>
      <category>talk</category>
    </item>
    <item>
      <title>Manage technical debt as a project</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Wed, 27 Jan 2021 19:58:46 +0000</pubDate>
      <link>https://dev.to/po5i/manage-technical-debt-as-a-project-4154</link>
      <guid>https://dev.to/po5i/manage-technical-debt-as-a-project-4154</guid>
      <description>&lt;p&gt;Imagine you spot &lt;a href="https://en.wikipedia.org/wiki/Technical_debt"&gt;technical debt&lt;/a&gt; items in your project that you need to work on anytime. Sometimes is confusing to manage them all in the PM tool of choice, specially when there will be temporary team members that get access to the repository only.&lt;/p&gt;

&lt;p&gt;My suggestion is to use &lt;a href="https://github.com/features/project-management/"&gt;Github Project&lt;/a&gt; boards. This is a powerful tool to manage repository issues, assign them to developers, keep track of their work status and create discussion spaces.&lt;/p&gt;

&lt;p&gt;Give them a try!&lt;/p&gt;

</description>
      <category>techdebt</category>
    </item>
    <item>
      <title>Always use semantic HTML inputs</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Fri, 08 Jan 2021 13:29:40 +0000</pubDate>
      <link>https://dev.to/po5i/always-use-semantic-html-inputs-4k5c</link>
      <guid>https://dev.to/po5i/always-use-semantic-html-inputs-4k5c</guid>
      <description>&lt;p&gt;I know sometimes is tedious to use a correct component for requesting a user input in HTML. But using the proper component will significatively enhance the user experience and it's easier to see it in action while in mobile devices.&lt;/p&gt;

&lt;p&gt;Today I Learned that you can step x decimal in an input &lt;code&gt;type="number"&lt;/code&gt;. Let's say you want to ask for a price:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input type="number" required name="price" min="0" value="0" step="any"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you omit the &lt;code&gt;step="any"&lt;/code&gt; part, the input will validate only for integer values.&lt;/p&gt;

&lt;p&gt;But if you use instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;step=".01"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, every time you click on the arrows, the value will be updated to ±0.01. Pretty handy isn't it?&lt;/p&gt;

</description>
      <category>html</category>
    </item>
    <item>
      <title>Python decorator to measure function's execution time</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Fri, 18 Dec 2020 20:03:36 +0000</pubDate>
      <link>https://dev.to/po5i/python-decorator-to-measure-function-s-execution-time-4d26</link>
      <guid>https://dev.to/po5i/python-decorator-to-measure-function-s-execution-time-4d26</guid>
      <description>&lt;p&gt;I know we do some manual debugging from time to time. I got inspired from some Stack Overflow answers and blogposts to write this decorator&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Now, you just need to import it in your code and write something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;measure&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;some_large_computation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Total execution time foo: 15 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want a smaller time unit, use &lt;code&gt;1000000&lt;/code&gt; instead of &lt;code&gt;1000&lt;/code&gt; factor to get microseconds (&lt;code&gt;μ&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;I hope this can be any help.&lt;/p&gt;

</description>
      <category>python</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Hacktoberfest in Ecuador</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Wed, 14 Oct 2020 21:10:38 +0000</pubDate>
      <link>https://dev.to/po5i/hacktoberfest-in-ecuador-216n</link>
      <guid>https://dev.to/po5i/hacktoberfest-in-ecuador-216n</guid>
      <description>&lt;h2&gt;
  
  
  How am I supporting the open-source collaboration?
&lt;/h2&gt;

&lt;p&gt;Last year, I had the initiative of celebrating a small Hacktoberfest with our teammates. We merged around 28 contributions to open source projects and everyone was happy because our company rewarded them with nice gifts.&lt;/p&gt;

&lt;p&gt;For this year we wanted to encourage the Ecuadorian community to support open source projects by creating a one-month agenda full of talks, catch-ups, communication channels, and prizes. We called it &lt;a href="https://www.facebook.com/stacktoberfest"&gt;Stacktoberfest&lt;/a&gt;! Fingers crossed 🤞 for the open-source projects to get a lot of contributions. &lt;/p&gt;

&lt;p&gt;Sadly, there are communities that cheer their members to contribute their own repos and give them stars, which are not open source projects (e.g. their website's readmes 😒). Let's remember that open source is a way to reuse, modify, and redistribute code.&lt;/p&gt;

&lt;p&gt;Anyways, this is an open call to end spam and do true contributions. Don't do it (only) for the shirt. And remember, you can opt to plant a tree. Check this cool article:&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/vaibhavkhulbe" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h4X1lQk3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://res.cloudinary.com/practicaldev/image/fetch/s--Yf6PWT-t--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/107614/ed59e3ee-6488-4af8-b0e1-7bb38dd2e74c.jpg" alt="vaibhavkhulbe"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/vaibhavkhulbe/hacktoberfest-through-a-different-lens-8o0" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Hacktoberfest - through a different lens. 🌳&lt;/h2&gt;
      &lt;h3&gt;Vaibhav Khulbe ・ Oct 9 '20 ・ 8 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#hacktoberfest&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#opensource&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#github&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#discuss&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>Exploring Pyright</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Fri, 11 Sep 2020 22:18:48 +0000</pubDate>
      <link>https://dev.to/po5i/exploring-pyright-3o0</link>
      <guid>https://dev.to/po5i/exploring-pyright-3o0</guid>
      <description>&lt;p&gt;Are you using Python type annotations? Having fun with &lt;code&gt;mypy&lt;/code&gt;? Microsoft created some years ago yet another static type checker called Pyright.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/microsoft"&gt;
        microsoft
      &lt;/a&gt; / &lt;a href="https://github.com/microsoft/pyright"&gt;
        pyright
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Static Type Checker for Python
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://github.com/microsoft/pyright/blob/main/docs/img/PyrightLarge.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HTBBHh6g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://github.com/microsoft/pyright/raw/main/docs/img/PyrightLarge.png" alt="Pyright"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
Static Type Checker for Python&lt;/h1&gt;
&lt;p&gt;Pyright is a full-featured, standards-based static type checker for Python. It is designed for high performance and can be used with large Python source bases.&lt;/p&gt;
&lt;p&gt;Pyright includes both a &lt;a href="https://microsoft.github.io/pyright/#/command-line" rel="nofollow"&gt;command-line tool&lt;/a&gt; and an &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-pyright.pyright" rel="nofollow"&gt;extension for Visual Studio Code&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
Documentation&lt;/h2&gt;
&lt;p&gt;Refer to &lt;a href="https://microsoft.github.io/pyright" rel="nofollow"&gt;the documentation&lt;/a&gt; for installation, configuration, and usage details.&lt;/p&gt;
&lt;h2&gt;
Community&lt;/h2&gt;
&lt;p&gt;Do you have questions about Pyright or Python type annotations in general? Post your questions in &lt;a href="https://github.com/microsoft/pyright/discussions"&gt;the discussion section&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you would like to report a bug or request an enhancement, file a new issue in either the &lt;a href="https://github.com/microsoft/pyright/issues"&gt;pyright&lt;/a&gt; or &lt;a href="https://github.com/microsoft/pylance-release/issues"&gt;pylance-release&lt;/a&gt; issue tracker. In general, core type checking functionality is associated with Pyright while language service functionality is associated with Pylance, but the same contributors monitor both repos. For best results, provide the information requested in the issue template.&lt;/p&gt;
&lt;h2&gt;
Contributing&lt;/h2&gt;
&lt;p&gt;This project welcomes contributions and suggestions. For feature and complex bug fix contributions…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/microsoft/pyright"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Some devs said it has a very great speed compared to mypy. I haven't used for any of my project's CI pipeline yet but I have this &lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-pyright.pyright"&gt;VSCode extension&lt;/a&gt; which, if you use this editor for your Python projects, you will be grateful on how it catches bugs caused by typing issues. So far it catches more issues than &lt;code&gt;mypy&lt;/code&gt; and its messages are somehow clearer.&lt;/p&gt;

&lt;p&gt;Being both VSCode and Pyright built with JavaScript (yes, Pyright was written in JS), their integration is pretty sweet. Although you can integrate to your favorite editor (vim, emacs, etc...).&lt;/p&gt;

&lt;p&gt;The CLI is pretty similar to &lt;code&gt;mypy&lt;/code&gt;. I'd suggest to give it a try and let me know how was your experience using it.&lt;/p&gt;

&lt;p&gt;Wanna know how to start using type annotations in Python? Check out &lt;a href="https://www.stackbuilders.com/tutorials/python/using-types-in-python-with-mypy/"&gt;my tutorial&lt;/a&gt; published by Stack Builders.&lt;/p&gt;

</description>
      <category>python</category>
      <category>vscode</category>
    </item>
    <item>
      <title>Do we need more than NPM?</title>
      <dc:creator>Carlos V.</dc:creator>
      <pubDate>Tue, 09 Jun 2020 20:43:23 +0000</pubDate>
      <link>https://dev.to/po5i/do-we-need-more-than-npm-2i8o</link>
      <guid>https://dev.to/po5i/do-we-need-more-than-npm-2i8o</guid>
      <description>&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A9-wwsHG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/ekalinin"&gt;
        ekalinin
      &lt;/a&gt; / &lt;a href="https://github.com/ekalinin/nodeenv"&gt;
        nodeenv
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Virtual environment for Node.js &amp;amp; integrator with virtualenv
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="rst"&gt;
&lt;h2&gt;
Node.js virtual environment&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;nodeenv&lt;/code&gt; (node.js virtual environment) is a tool to create
isolated node.js environments.&lt;/p&gt;
&lt;p&gt;It creates an environment that has its own installation directories
that doesn't share libraries with other node.js virtual environments.&lt;/p&gt;
&lt;p&gt;Also the new environment can be integrated with the environment which was built
by &lt;a href="https://github.com/pypa/virtualenv"&gt;virtualenv&lt;/a&gt; (python).&lt;/p&gt;
&lt;p&gt;If you use nodeenv feel free to add your project on wiki: &lt;a href="https://github.com/ekalinin/nodeenv/wiki/Who-Uses-Nodeenv"&gt;Who-Uses-Nodeenv&lt;/a&gt;.&lt;/p&gt;
&lt;a href="https://travis-ci.org/ekalinin/nodeenv" rel="nofollow"&gt;&lt;img alt="https://travis-ci.org/ekalinin/nodeenv.svg?branch=master" src="https://camo.githubusercontent.com/64fd8cba7481e40ec8744ed19603a17af91ba794ef8d9fa52a8cb545b6792363/68747470733a2f2f7472617669732d63692e6f72672f656b616c696e696e2f6e6f6465656e762e7376673f6272616e63683d6d6173746572"&gt;&lt;/a&gt;
&lt;div id="user-content-contents"&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/ekalinin/nodeenv#install" id="user-content-id2"&gt;Install&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ekalinin/nodeenv#global-installation" id="user-content-id3"&gt;Global installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ekalinin/nodeenv#local-installation" id="user-content-id4"&gt;Local installation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ekalinin/nodeenv#dependency" id="user-content-id5"&gt;Dependency&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ekalinin/nodeenv#for-nodeenv" id="user-content-id6"&gt;For nodeenv&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ekalinin/nodeenv#for-node-js" id="user-content-id7"&gt;For node.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ekalinin/nodeenv#usage" id="user-content-id8"&gt;Usage&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ekalinin/nodeenv#basic" id="user-content-id9"&gt;Basic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ekalinin/nodeenv#advanced" id="user-content-id10"&gt;Advanced&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ekalinin/nodeenv#configuration" id="user-content-id11"&gt;Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ekalinin/nodeenv#alternatives" id="user-content-id12"&gt;Alternatives&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h3&gt;
&lt;a href="https://github.com/ekalinin/nodeenv#id2"&gt;Install&lt;/a&gt;
&lt;/h3&gt;
&lt;h4&gt;
&lt;a href="https://github.com/ekalinin/nodeenv#id3"&gt;Global installation&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;You can install nodeenv globally with &lt;a href="http://pypi.python.org/pypi/setuptools" rel="nofollow"&gt;easy_install&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;$ sudo easy_install nodeenv
&lt;/pre&gt;
&lt;p&gt;or with &lt;a href="http://pypi.python.org/pypi/pip" rel="nofollow"&gt;pip&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;$ sudo pip install nodeenv
&lt;/pre&gt;
&lt;p&gt;or on Debian using &lt;a href="https://www.debian.org/doc/manuals/debian-faq/ch-pkgtools.en.html" rel="nofollow"&gt;dpkg&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;$ ln -s debian-upstream debian
$ dpkg-buildpackage -uc -us -b
$ sudo dpkg -i $(ls -1rt ../nodeenv_*.deb | tail -n1)
&lt;/pre&gt;

&lt;h4&gt;
&lt;a href="https://github.com/ekalinin/nodeenv#id4"&gt;Local installation&lt;/a&gt;
&lt;/h4&gt;
&lt;p&gt;If you're using &lt;a href="https://github.com/pypa/virtualenv"&gt;virtualenv&lt;/a&gt; then you can install nodeenv via
&lt;a href="http://pypi.python.org/pypi/pip" rel="nofollow"&gt;pip&lt;/a&gt;/&lt;a href="http://pypi.python.org/pypi/setuptools" rel="nofollow"&gt;easy_install&lt;/a&gt; inside any virtual environment built with…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/ekalinin/nodeenv"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Why things like these exist, if we can create deterministic isolated environment by just using NPM?&lt;/p&gt;

&lt;p&gt;This reminds me of this funny meme:&lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;
      &lt;div class="ltag__twitter-tweet__media"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cmuCaMf8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://pbs.twimg.com/media/EZ8Ky0qX0AEX_7g.jpg" alt="unknown tweet media content"&gt;
      &lt;/div&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--Vu0uJTP4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://pbs.twimg.com/profile_images/1265383669113458688/F8WoNBOv_normal.jpg" alt="po5i profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        po5i
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/po5i"&gt;@po5i&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kDgU_xDI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      Why? 
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      21:38 PM - 07 Jun 2020
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=1269745494559002625" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OXOJJiQT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=1269745494559002625" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--foTp-unf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=1269745494559002625" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SFHqU4bF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


</description>
      <category>node</category>
      <category>npm</category>
    </item>
  </channel>
</rss>
