<?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: sirfuzzalot</title>
    <description>The latest articles on DEV Community by sirfuzzalot (@sirfuzzalot).</description>
    <link>https://dev.to/sirfuzzalot</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%2F350046%2F859d78ef-88b9-4999-a62b-e832f07c7027.jpg</url>
      <title>DEV Community: sirfuzzalot</title>
      <link>https://dev.to/sirfuzzalot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sirfuzzalot"/>
    <language>en</language>
    <item>
      <title>How to Protect Your Python Code Health 🐍🩺</title>
      <dc:creator>sirfuzzalot</dc:creator>
      <pubDate>Sun, 06 Jun 2021 22:25:53 +0000</pubDate>
      <link>https://dev.to/sirfuzzalot/how-to-protect-your-python-code-health-5c2e</link>
      <guid>https://dev.to/sirfuzzalot/how-to-protect-your-python-code-health-5c2e</guid>
      <description>&lt;p&gt;Code can be long and complex. Let's configure a few good tools to help keep our Python codebase healthy. Flake8, Black, and isort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Linting and Formatting
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://flake8.pycqa.org/en/latest/" rel="noopener noreferrer"&gt;Flake8&lt;/a&gt; is a &lt;a href="https://en.wikipedia.org/wiki/Lint_(software)" rel="noopener noreferrer"&gt;linter&lt;/a&gt;. It's designed to find mistakes in your code that can later become bugs when your code is run.&lt;/p&gt;

&lt;p&gt;A formatter arranges our code so that it's more readable on the screen, but does not change what our code does. &lt;a href="https://black.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;Black&lt;/a&gt; and &lt;a href="https://pycqa.github.io/isort/" rel="noopener noreferrer"&gt;isort&lt;/a&gt; are formatters.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;Let's install our linting and formatting tools. For a healthy coding environment use a virtual environment like &lt;code&gt;venv&lt;/code&gt; or &lt;code&gt;virtualenv&lt;/code&gt; (&lt;code&gt;venv&lt;/code&gt; comes with Python).&lt;/p&gt;

&lt;p&gt;Create a virtual environment and activate it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# bash
python3 -m venv venv
source venv/bin/activate

# pwsh
py -3 -m venv venv
venv\Scripts\activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Install the packages.&lt;br&gt;
&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;flake8 black isort
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuration
&lt;/h2&gt;

&lt;p&gt;You'll want to configure these tools a little to make them play nicely together.&lt;/p&gt;
&lt;h3&gt;
  
  
  Flake8 📋
&lt;/h3&gt;

&lt;p&gt;There's a lot you can configure with &lt;strong&gt;Flake8&lt;/strong&gt;, but you don't have to. Add the bare minimum first to get &lt;strong&gt;Black&lt;/strong&gt; and &lt;strong&gt;Flake8&lt;/strong&gt; to cooperate (also we'll exclude a few directories from linting). In the root of your project create a file called &lt;code&gt;.flake8&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# .flake8&lt;/span&gt;

&lt;span class="nn"&gt;[flake8]&lt;/span&gt;
&lt;span class="py"&gt;max-line-length&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;88&lt;/span&gt;
&lt;span class="py"&gt;extend-ignore&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="err"&gt;E&lt;/span&gt;&lt;span class="mi"&gt;203&lt;/span&gt;
&lt;span class="py"&gt;exclude&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="err"&gt;.git,&lt;/span&gt;
    &lt;span class="err"&gt;__pycache__,&lt;/span&gt;
    &lt;span class="err"&gt;build,&lt;/span&gt;
    &lt;span class="err"&gt;dist,&lt;/span&gt;
    &lt;span class="err"&gt;venv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Black 🖊️
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Black&lt;/strong&gt; is famous as a highly opinionated "uncompromising code formatter". While there are a few settings you can configure, nearly all of the formatting choices are made for you. That's actually half of its appeal. The other half is getting back all the time you previously used to tweak where this comma was or that spacing. Embrace the way &lt;strong&gt;Black&lt;/strong&gt; will do it all for you and you'll thank me later.&lt;/p&gt;

&lt;p&gt;In the root of your project create a file called &lt;code&gt;pyproject.toml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# pyproject.toml

[tool.black]
exclude = 'venv'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  isort 🗂️
&lt;/h3&gt;

&lt;p&gt;Short for "import sort" or just "I Sort", this utility will arrange your module's imports in a consistent opinionated way, much like &lt;strong&gt;Black&lt;/strong&gt; does for the rest of your code.&lt;/p&gt;

&lt;p&gt;Let's configure &lt;strong&gt;isort&lt;/strong&gt; to play nicely with &lt;strong&gt;Black&lt;/strong&gt;. Add the following to our &lt;code&gt;pyproject.toml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# pyproject.toml&lt;/span&gt;

&lt;span class="nn"&gt;[tool.isort]&lt;/span&gt;
&lt;span class="py"&gt;profile&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"black"&lt;/span&gt;
&lt;span class="py"&gt;multi_line_output&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="py"&gt;skip&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"venv"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Checking Your Code's Health 🩺
&lt;/h2&gt;

&lt;p&gt;Let's run our tools individually first.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m flake8

python -m black .

python -m isort .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now let's make this a little easier for ourselves by setting up a &lt;strong&gt;pre-commit hook&lt;/strong&gt;. In your project create a file called &lt;code&gt;.git/hooks/pre-commit&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"----------------------"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"--- Pre-Commit Hook --"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"----------------------"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"📋 Flake8 📋"&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; flake8 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"No Errors"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🖊️  Black 🖊️"&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; black &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🗂️  isort 🗂️"&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; isort &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Imports Sorted"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"----------------------"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When you run &lt;code&gt;git commit&lt;/code&gt; this script will run and check your code health before a commit is made. It will show you what issues &lt;strong&gt;Flake8&lt;/strong&gt; has found and it will format your code. You'll then get to go back and fix the issues. Finally, you'll run &lt;code&gt;git commit&lt;/code&gt; again.&lt;/p&gt;

&lt;p&gt;Here's what it looks like with errors.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;----------------------&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt; Pre-Commit Hook &lt;span class="nt"&gt;--&lt;/span&gt;
&lt;span class="nt"&gt;----------------------&lt;/span&gt;
📋 Flake8 📋
.&lt;span class="se"&gt;\s&lt;/span&gt;rc&lt;span class="se"&gt;\p&lt;/span&gt;ackagecake&lt;span class="se"&gt;\_&lt;/span&gt;_main__.py:2:1: F401 &lt;span class="s1"&gt;'sys'&lt;/span&gt; imported but unused
.&lt;span class="se"&gt;\s&lt;/span&gt;rc&lt;span class="se"&gt;\p&lt;/span&gt;ackagecake&lt;span class="se"&gt;\_&lt;/span&gt;_main__.py:6:1: E302 expected 2 blank lines, found 1

🖊️  Black 🖊️
reformatted src&lt;span class="se"&gt;\p&lt;/span&gt;ackagecake&lt;span class="se"&gt;\_&lt;/span&gt;_main__.py
All &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; ✨ 🍰 ✨
1 file reformatted, 4 files left unchanged.

🗂️  isort 🗂️
Skipped 1 files
Imports Sorted

&lt;span class="nt"&gt;-----------------&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Here's what it will look like when you're code is healthy.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;----------------------&lt;/span&gt;
&lt;span class="nt"&gt;---&lt;/span&gt; Pre-Commit Hook &lt;span class="nt"&gt;--&lt;/span&gt;
&lt;span class="nt"&gt;----------------------&lt;/span&gt;
📋 Flake8 📋
No Errors

🖊️  Black 🖊️
All &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; ✨ 🍰 ✨
5 files left unchanged.

🗂️  isort 🗂️
Skipped 1 files
Imports Sorted

&lt;span class="nt"&gt;-----------------&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automation 🤖
&lt;/h2&gt;

&lt;p&gt;With code health, the more often you can check it the better. You've seen how to setup a &lt;strong&gt;Git hook&lt;/strong&gt;. Here's a few other ways to run &lt;strong&gt;Flake8&lt;/strong&gt;, &lt;strong&gt;Black&lt;/strong&gt;, and &lt;strong&gt;isort&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  IDE
&lt;/h3&gt;

&lt;p&gt;Your code editor likely integrates with these tools using only some light configuration. You'll benefit from spellcheck-like behavior from &lt;strong&gt;Flake8&lt;/strong&gt;, and format on save from &lt;strong&gt;Black&lt;/strong&gt; and &lt;strong&gt;isort&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Some info on setting up &lt;a href="https://code.visualstudio.com/docs/python/linting" rel="noopener noreferrer"&gt;VSCode&lt;/a&gt; for linting and formatting.&lt;/p&gt;
&lt;h3&gt;
  
  
  Pre-Commit
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://pre-commit.com/" rel="noopener noreferrer"&gt;Pre-Commit Framework&lt;/a&gt; is &lt;strong&gt;Git hooks&lt;/strong&gt; with super powers. Its easy setup and configuration give you access to an &lt;a href="https://pre-commit.com/hooks.html" rel="noopener noreferrer"&gt;extensive list of shared Git hooks&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  CI/CD Pipelines
&lt;/h3&gt;

&lt;p&gt;While a Git hook is great for catching errors before they go to GitHub/GitLab you still want the safety of your CI/CD Pipeline running these tools again. That's because sometimes people forget to configure their Git hooks 🙃.&lt;/p&gt;

&lt;p&gt;For our formatters, there is a special CI/CD mode that will throw an error when the formatting is incorrect.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; black &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--check&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; isort &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--check&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Source Code Example 💻
&lt;/h2&gt;

&lt;p&gt;You're all set with the tools you'll need to keep your code healthy. Remember the goal is to make our code bug free, and easy to maintain. &lt;strong&gt;Flake8&lt;/strong&gt;, &lt;strong&gt;Black&lt;/strong&gt;, and &lt;strong&gt;isort&lt;/strong&gt; can help you get there.&lt;/p&gt;

&lt;p&gt;Check out &lt;strong&gt;packagecake&lt;/strong&gt; for an example of what we've covered here.&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/sirfuzzalot" rel="noopener noreferrer"&gt;
        sirfuzzalot
      &lt;/a&gt; / &lt;a href="https://github.com/sirfuzzalot/packagecake" rel="noopener noreferrer"&gt;
        packagecake
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Turn your Python package into a delicious cake 🎂
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Find out what type of cake your Python package is by running the following:&lt;br&gt;
&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; python -m pip install packagecake
&amp;gt;&amp;gt;&amp;gt; python -m packagecake bake [your package name]
🍰
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Cover Photo Credit: &lt;a href="https://unsplash.com/@swimstaralex" rel="noopener noreferrer"&gt;Alexander Sinn&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>python</category>
      <category>tutorial</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Take Control of Your VSCode Workspaces 🛠️</title>
      <dc:creator>sirfuzzalot</dc:creator>
      <pubDate>Sat, 08 May 2021 23:02:51 +0000</pubDate>
      <link>https://dev.to/sirfuzzalot/take-control-of-your-vscode-workspaces-1f4k</link>
      <guid>https://dev.to/sirfuzzalot/take-control-of-your-vscode-workspaces-1f4k</guid>
      <description>&lt;p&gt;I work on a lot of different projects. You probably do too.&lt;/p&gt;

&lt;p&gt;Back in 2018, I created an extension for VSCode to help solve the problem of managing many different projects, using many different workspaces. It's called &lt;a href="https://marketplace.visualstudio.com/items?itemName=tomsaunders-code.workspace-explorer" rel="noopener noreferrer"&gt;&lt;strong&gt;Workspace Explorer&lt;/strong&gt;&lt;/a&gt;.&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%2F0nrkbeiwkpbn89f76ij7.gif" 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%2F0nrkbeiwkpbn89f76ij7.gif" alt="Opening a Workspace"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workspace Explorer&lt;/strong&gt; provides a file-browser-like experience for your workspaces. Some of the things you can do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workspaces

&lt;ul&gt;
&lt;li&gt;Create Workspaces&lt;/li&gt;
&lt;li&gt;Delete Workspaces&lt;/li&gt;
&lt;li&gt;Rename Workspaces&lt;/li&gt;
&lt;li&gt;Open a Workspace in Another Window&lt;/li&gt;
&lt;li&gt;Open a Workspace in the Same Window&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Sub-Folders

&lt;ul&gt;
&lt;li&gt;Organize Workspaces in Sub-folders&lt;/li&gt;
&lt;li&gt;Delete Sub-folders&lt;/li&gt;
&lt;li&gt;Rename Sub-Folders&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Custom Icons

&lt;ul&gt;
&lt;li&gt;Set Custom Icons for Workspaces and Sub-folders&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  Workspace Explorer 2.0.0
&lt;/h2&gt;

&lt;p&gt;Today I'm releasing version &lt;code&gt;2.0.0&lt;/code&gt; of &lt;strong&gt;Workspace Explorer&lt;/strong&gt;. This release brings support for &lt;code&gt;jpg&lt;/code&gt; icons, environment variables in config paths, and patches several bugs. I've incremented the major version as support for SVG icons has been removed, due to an issue in VSCode.&lt;/p&gt;

&lt;p&gt;Icon Format Support&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;del&gt;svg&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;png&lt;/li&gt;
&lt;li&gt;jpg (new)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Environment Variable Support&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;${env:NAME_OF_ENV_VAR}/remainder/of/your/path

/root/of/my/path/${env:NAME_OF_ENV_VAR}/remainder/of/your/path

${env:USERPROFILE}\my\windows\path
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Ffzmi40v4eypicwxym4u1.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%2Ffzmi40v4eypicwxym4u1.png" alt="Workspace Explorer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workspace Explorer&lt;/strong&gt; is developed open source on GitHub. Special thanks to all the contributors and issue reporters over the years.&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/sirfuzzalot" rel="noopener noreferrer"&gt;
        sirfuzzalot
      &lt;/a&gt; / &lt;a href="https://github.com/sirfuzzalot/workspace-explorer" rel="noopener noreferrer"&gt;
        workspace-explorer
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Organize, iconize and open your collection of VSCode workspaces
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;



</description>
      <category>vscode</category>
      <category>news</category>
      <category>showdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to Bake A Python Package Cake🐍+📦=🎂</title>
      <dc:creator>sirfuzzalot</dc:creator>
      <pubDate>Mon, 19 Apr 2021 00:12:34 +0000</pubDate>
      <link>https://dev.to/sirfuzzalot/how-to-bake-a-python-package-cake-46l5</link>
      <guid>https://dev.to/sirfuzzalot/how-to-bake-a-python-package-cake-46l5</guid>
      <description>&lt;p&gt;Let's bake a package cake 🎂! You will need...&lt;/p&gt;

&lt;h2&gt;
  
  
  Ingredients
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Location&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;library or application&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./src/[name of library or application]/[your code]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your code that does something useful or fun&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pyproject.toml&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./pyproject.toml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build configuration information&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setup.cfg&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./setup.cfg&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Package metadata for PyPI (name of your project, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;README.md or README.rst&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;./README.md&lt;/code&gt; or &lt;code&gt;./README.rst&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Brief docs for your package to display on PyPI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;.gitignore&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./.gitignore&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Things you don't want in Git, including some build artifacts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LICENSE or LICENSE.txt&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;./LICENSE&lt;/code&gt; or &lt;code&gt;./LICENSE.txt&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Project's license telling others how they can use your work&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;setup.py&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./setup.py&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Technically optional, you'll want this so you can better develop locally&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Package Cake Recipe 📋
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add one &lt;code&gt;LICENSE&lt;/code&gt; or &lt;code&gt;LICENSE.txt&lt;/code&gt; file. Picking a license can be tough, but there are tools to help like &lt;a href="https://choosealicense.com/" rel="noopener noreferrer"&gt;Choose A License&lt;/a&gt;.
&lt;/li&gt;
&lt;/ul&gt;

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

Copyright (c) 2021 Cake Packaging Foundation.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add one &lt;code&gt;pyproject.toml&lt;/code&gt; file. Unless you're building native code or using an alternative build system (i.e. poetry), you can copy and paste this.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[build-system]&lt;/span&gt;
&lt;span class="py"&gt;requires&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="py"&gt;"setuptools&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="s"&gt;",&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;    &lt;span class="s"&gt;"wheel"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="py"&gt;build-backend&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"setuptools.build_meta"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add one &lt;code&gt;setup.cfg&lt;/code&gt;. This is where you will specify the information that appears on PyPI and what is essential for your package to work.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# This is essentially a static version of setuptools.setup() and is the
# preferred method of indicating package metadata.
# https://packaging.python.org/guides/distributing-packages-using-setuptools/#setup-args
&lt;/span&gt;
&lt;span class="nn"&gt;[metadata]&lt;/span&gt;
&lt;span class="c"&gt;# A unique name for your package. Search through PyPI for duplicates.
&lt;/span&gt;&lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;packagecake&lt;/span&gt;

&lt;span class="c"&gt;# Here you use SemVer for versioning - https://semver.org/
# You can also get fancy and pull this value from a file
# like so attr: packagecake.__version__
&lt;/span&gt;&lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1.0.0&lt;/span&gt;

&lt;span class="c"&gt;# Your name or the organization's name. You can actually leave out the
# email and PyPI will still accept your package.
&lt;/span&gt;&lt;span class="py"&gt;author&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;Example Author&lt;/span&gt;
&lt;span class="py"&gt;author_email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;author@example.com&lt;/span&gt;

&lt;span class="c"&gt;# This is your sales pitch, your one-liner, your logline. Make it count
&lt;/span&gt;&lt;span class="py"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;Turn your package into a delicious cake in less than 100ms&lt;/span&gt;

&lt;span class="c"&gt;# Set this to the file you want displayed on PyPI.
# content-type can also be text/x-rst, or text/plain
&lt;/span&gt;&lt;span class="py"&gt;long_description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;file: README.md&lt;/span&gt;
&lt;span class="py"&gt;long_description_content_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;text/markdown&lt;/span&gt;

&lt;span class="c"&gt;# This will show in PyPI as your package's Homepage link
&lt;/span&gt;&lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;https://github.com/pypa/sampleproject&lt;/span&gt;

&lt;span class="c"&gt;# These links will show up in PyPI under the Homepage link.
# Include at least Tracker.
&lt;/span&gt;&lt;span class="py"&gt;project_urls&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="py"&gt;Tracker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;https://github.com/pypa/sampleproject/issues&lt;/span&gt;
    &lt;span class="py"&gt;Documentation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;https://example.com/docs&lt;/span&gt;
    &lt;span class="py"&gt;Source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;https://github.com/pypa/sampleproject/&lt;/span&gt;
    &lt;span class="py"&gt;Funding&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;https://example.com/funding&lt;/span&gt;
    &lt;span class="err"&gt;Custom&lt;/span&gt; &lt;span class="py"&gt;URL&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;https://example.com/&lt;/span&gt;

&lt;span class="c"&gt;# Classifiers - https://pypi.org/classifiers/
# Make sure to include your license
&lt;/span&gt;&lt;span class="py"&gt;classifiers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="err"&gt;Development&lt;/span&gt; &lt;span class="err"&gt;Status&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt; &lt;span class="err"&gt;-&lt;/span&gt; &lt;span class="err"&gt;Alpha&lt;/span&gt;
    &lt;span class="err"&gt;Intended&lt;/span&gt; &lt;span class="err"&gt;Audience&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;Developers&lt;/span&gt;
    &lt;span class="err"&gt;License&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;OSI&lt;/span&gt; &lt;span class="err"&gt;Approved&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;GNU&lt;/span&gt; &lt;span class="err"&gt;General&lt;/span&gt; &lt;span class="err"&gt;Public&lt;/span&gt; &lt;span class="err"&gt;License&lt;/span&gt; &lt;span class="err"&gt;v3&lt;/span&gt; &lt;span class="err"&gt;(GPLv3)&lt;/span&gt;
    &lt;span class="err"&gt;Programming&lt;/span&gt; &lt;span class="err"&gt;Language&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;Python&lt;/span&gt;
    &lt;span class="err"&gt;Programming&lt;/span&gt; &lt;span class="err"&gt;Language&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;Python&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt;
    &lt;span class="err"&gt;Programming&lt;/span&gt; &lt;span class="err"&gt;Language&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;Python&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;3&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;Only&lt;/span&gt;
    &lt;span class="err"&gt;Programming&lt;/span&gt; &lt;span class="err"&gt;Language&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;Python&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;3.8&lt;/span&gt;
    &lt;span class="err"&gt;Programming&lt;/span&gt; &lt;span class="err"&gt;Language&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;Python&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;3.9&lt;/span&gt;
    &lt;span class="err"&gt;Operating&lt;/span&gt; &lt;span class="err"&gt;System&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;OS&lt;/span&gt; &lt;span class="err"&gt;Independent&lt;/span&gt;
    &lt;span class="err"&gt;Topic&lt;/span&gt; &lt;span class="err"&gt;::&lt;/span&gt; &lt;span class="err"&gt;Utilities&lt;/span&gt;

&lt;span class="nn"&gt;[options]&lt;/span&gt;
&lt;span class="c"&gt;# Path to our libary/application
&lt;/span&gt;&lt;span class="py"&gt;package_dir&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;src&lt;/span&gt;
&lt;span class="py"&gt;packages&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;find:&lt;/span&gt;

&lt;span class="c"&gt;# Version of Python needed to use the package
&lt;/span&gt;&lt;span class="py"&gt;python_requires&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;gt;=3.8&lt;/span&gt;

&lt;span class="c"&gt;# Our package depends on these other external packages
&lt;/span&gt;&lt;span class="py"&gt;install_requires&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="py"&gt;requests&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;= 2.25.1&lt;/span&gt;

&lt;span class="nn"&gt;[options.packages.find]&lt;/span&gt;
&lt;span class="py"&gt;where&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;src&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add one &lt;code&gt;README.md&lt;/code&gt; or &lt;code&gt;README.rst&lt;/code&gt;. Briefly document your tool, giving users a taste of what they can do with it. Then point to your full length docs with a link. You'll want to save full length docs for another site as PyPI does have some limitations particularly with links to section headers. Alternatively, you can make a file just for PyPI and leave your README nice and detailed for your GitHub repo.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Package Cake 🎂&lt;/span&gt;

&lt;span class="gs"&gt;**Package Cake**&lt;/span&gt; is a simple utility that takes your package and turns it
into a cake 🍰.

Checkout the &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;documentation&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="sx"&gt;https://example.com/docs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;.

-&amp;gt; Add installation example here &amp;lt;-

-&amp;gt; Usage example here &amp;lt;-
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add one &lt;code&gt;.gitignore&lt;/code&gt;. You'll want to update your &lt;code&gt;.gitignore&lt;/code&gt; file to exclude some of the build artifacts.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Packaging
dist
build
*.egg-info/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add one &lt;code&gt;setup.py&lt;/code&gt;. While &lt;code&gt;setup.cfg&lt;/code&gt; handles static values, &lt;code&gt;setup.py&lt;/code&gt; is for dynamic metadata. Favor &lt;code&gt;setup.cfg&lt;/code&gt; whenever possible. You will however, want to use &lt;code&gt;setup.py&lt;/code&gt; to help you
test your package locally. Read on to see how you can test.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;setuptools&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;setup&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;version_info&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Python 3.8.0+ Required&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add one library or application. This is why you're publishing and you'll want to put this in a specific spot.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./src/[python package name]
    /__init__.py &amp;lt;- control your package's namespace
    /__main__.py &amp;lt;- optionally allow your package to be invoked from the command line
    /[your modules]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Bake Until Built 🔥
&lt;/h2&gt;

&lt;p&gt;Next you're going to build the package into a &lt;strong&gt;wheel&lt;/strong&gt; and a &lt;strong&gt;source archive&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;wheel&lt;/strong&gt; is a built distribution. If you have any binaries there will be pre-compiled copies in the wheel. This makes it a much faster process for users to get up and running with your package.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;source archive&lt;/strong&gt; contains the raw source code of the package and let's pip or the user do any compilation locally instead. Wheels are generally preferred in most use cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a virtual environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unix/MacOS&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;your project]
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;span class="nb"&gt;source &lt;/span&gt;venv/bin/activate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Windows&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;your&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;venv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;venv&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;\venv\Scripts\activate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Install and run &lt;strong&gt;build&lt;/strong&gt;. This will generate a &lt;code&gt;./build&lt;/code&gt; and &lt;code&gt;./dist&lt;/code&gt; directory in your project's root, along with creating a &lt;code&gt;.whl&lt;/code&gt; and &lt;code&gt;.tar.gz&lt;/code&gt; distribution package. Finally, you will also see a &lt;code&gt;.egg-info&lt;/code&gt; directory in your &lt;code&gt;./src/[my project]&lt;/code&gt; directory.
&lt;/li&gt;
&lt;/ul&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;build
python &lt;span class="nt"&gt;-m&lt;/span&gt; build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./build
./dist
    /packagecake-1.0.0-py3-none-any.whl
    /packagecake-1.0.0.tar.gz
./src/[python package name]
    /packagecake.egg-info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Publish Your Package Cake 🌐
&lt;/h2&gt;

&lt;p&gt;Now that our package cake is built you'll want to upload it to PyPI. I highly recommend testing your package configuration by first publishing to &lt;a href="https://packaging.python.org/tutorials/packaging-projects/#uploading-the-distribution-archives" rel="noopener noreferrer"&gt;Test PyPI&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In your virtual environment install &lt;strong&gt;twine&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&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;twine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Ensure the version number is properly incremented. You might keep the version number in &lt;code&gt;setup.cfg&lt;/code&gt;, &lt;code&gt;setup.py&lt;/code&gt;, or as &lt;code&gt;__version__&lt;/code&gt; in one of your other files. Make sure they all get updated.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;   &lt;span class="c"&gt;# setup.cfg
&lt;/span&gt;   &lt;span class="nn"&gt;[metadata]&lt;/span&gt;
   &lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;packagecake&lt;/span&gt;
   &lt;span class="py"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1.0.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a &lt;a href="https://pypi.org/account/register/" rel="noopener noreferrer"&gt;PyPI account&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create an API token from PyPI. Optionally setup a credentials file to store your API token.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# [user home directory]/.pypirc
&lt;/span&gt;&lt;span class="nn"&gt;[testpypi]&lt;/span&gt;
&lt;span class="py"&gt;username&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;__token__&lt;/span&gt;
&lt;span class="py"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;my API token&amp;gt;&lt;/span&gt;

&lt;span class="nn"&gt;[pypi]&lt;/span&gt;
&lt;span class="py"&gt;username&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;__token__&lt;/span&gt;
&lt;span class="py"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;my API token&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Publish the package
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;twine upload dist/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# For Test PyPI&lt;/span&gt;
twine upload &lt;span class="nt"&gt;--repository&lt;/span&gt; testpypi dist/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Taste the Package Cake 🍽️
&lt;/h2&gt;

&lt;p&gt;You'll want to download and test the package now. Let's also look at how you can test before publishing.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download and Verify the publish.
&lt;/li&gt;
&lt;/ul&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;packagecake

&lt;span class="c"&gt;# For Test PyPI. No deps is safer, though you can only verify package contents&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--index-url&lt;/span&gt; https://test.pypi.org/simple/ &lt;span class="nt"&gt;--no-deps&lt;/span&gt; packagecake
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; import packagecake
🥮

&lt;span class="c"&gt;# or if running from command-line&lt;/span&gt;

python &lt;span class="nt"&gt;-m&lt;/span&gt; packagecake
🍰
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And now what you can do before you publish. This let's you import and run your package as though it was downloaded with &lt;strong&gt;pip&lt;/strong&gt;. It's called an &lt;strong&gt;editable&lt;/strong&gt; package. You can then perform the steps you did above to verify the package.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  My First Python Package 🐣
&lt;/h2&gt;

&lt;p&gt;I hope this helps you publish your package. A few quick resources I want to point out that helped me and of course a link to a package I built/baked 😊.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://packaging.python.org/guides/distributing-packages-using-setuptools/" rel="noopener noreferrer"&gt;Python Packaging Authority (PyPA) Docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://packaging.python.org/tutorials/packaging-projects/" rel="noopener noreferrer"&gt;PyPA Packaging Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/classifiers/" rel="noopener noreferrer"&gt;PyPI Classifiers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://packaging.python.org/glossary/" rel="noopener noreferrer"&gt;PyPA Glossary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://test.pypi.org/" rel="noopener noreferrer"&gt;Test PyPI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/pywhoami/" rel="noopener noreferrer"&gt;pywhoami on PyPI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&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/sirfuzzalot" rel="noopener noreferrer"&gt;
        sirfuzzalot
      &lt;/a&gt; / &lt;a href="https://github.com/sirfuzzalot/pywhoami" rel="noopener noreferrer"&gt;
        pywhoami
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A Simple HTTP Request Analysis Server
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/sirfuzzalot/pywhoami./images/pywhoami-logo.jpg"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fsirfuzzalot%2Fpywhoami.%2Fimages%2Fpywhoami-logo.jpg" width="60%" alt="pywhoami logo"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;A Simple HTTP Request Analysis Server&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://pypi.python.org/pypi/pywhoami" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/cb8586c97d1c3c4da1db9d83502e5dfdf4808f026324f5adcb7d6b16829fb92e/68747470733a2f2f696d672e736869656c64732e696f2f707970692f762f707977686f616d692e737667" alt="PyPI Version"&gt;&lt;/a&gt;
&lt;a href="https://github.com/sirfuzzalot/pywhoami" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/265015f27268d18bf02b5b00fc7e2c9a06ec2150010362bc401da4bdbe6b1da0/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f63732d70617373696e672d627269676874677265656e2e737667" alt="Docs"&gt;&lt;/a&gt;
&lt;a href="https://opensource.org/licenses/MIT" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/6581c31c16c1b13ddc2efb92e2ad69a93ddc4a92fd871ff15d401c4c6c9155a4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a href="https://www.python.org/downloads/" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/41f6fff9299ba65b16ed1661888f0a26f2a31e9e13215de4ddef8b468f86206c/68747470733a2f2f736869656c64732e696f2f707970692f707976657273696f6e732f707977686f616d69" alt="Python Versions"&gt;&lt;/a&gt;
&lt;a href="https://github.com/psf/black" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5bf9e9fa18966df7cb5fac7715bef6b72df15e01a6efa9d616c83f9fcb527fe2/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f636f64652532307374796c652d626c61636b2d3030303030302e737667" alt="Code style: black"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Pywhoami is inspired by the &lt;a href="https://github.com/containous/whoami" rel="noopener noreferrer"&gt;whoami&lt;/a&gt;
Go server by &lt;a href="https://traefik.io/" rel="nofollow noopener noreferrer"&gt;Traefik Labs&lt;/a&gt;. Send a request to one
of the endpoints to get back details from your HTTP request. With
&lt;strong&gt;pywhoami&lt;/strong&gt; you can help answer questions like, what headers were added
to my original request by a proxy server.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/sirfuzzalot/pywhoami#using-the-pypi-package" rel="noopener noreferrer"&gt;Using the PyPI Package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sirfuzzalot/pywhoami#using-the-docker-image" rel="noopener noreferrer"&gt;Using the Docker Image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sirfuzzalot/pywhoami#http-api-reference" rel="noopener noreferrer"&gt;HTTP API Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/sirfuzzalot/pywhoami#contributing" rel="noopener noreferrer"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Using the PyPI Package&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Installation&lt;/h3&gt;
&lt;/div&gt;
&lt;p&gt;bash&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;python3 -m pip install pywhoami&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;powershell&lt;/p&gt;
&lt;div class="highlight highlight-source-powershell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;py &lt;span class="pl-k"&gt;-&lt;/span&gt;m pip install pywhoami&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Running the Server&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;bash&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&amp;gt;&amp;gt;&amp;gt; python3 -m pywhoami
[2021-04-17 15:00:25 -0700] [4400] [INFO] Running on http://127.0.0.1:8080 (CTRL + C to quit)&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;powershell&lt;/p&gt;
&lt;div class="highlight highlight-source-powershell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; py &lt;span class="pl-k"&gt;-&lt;/span&gt;m pywhoami
[&lt;span class="pl-c1"&gt;2021&lt;/span&gt;&lt;span class="pl-k"&gt;-&lt;/span&gt;&lt;span class="pl-c1"&gt;04&lt;/span&gt;&lt;span class="pl-k"&gt;-&lt;/span&gt;&lt;span class="pl-c1"&gt;17&lt;/span&gt; &lt;span class="pl-c1"&gt;15&lt;/span&gt;:&lt;span class="pl-c1"&gt;00&lt;/span&gt;:&lt;span class="pl-c1"&gt;25&lt;/span&gt; &lt;span class="pl-c1"&gt;-0700&lt;/span&gt;] [&lt;span class="pl-c1"&gt;4400&lt;/span&gt;] [&lt;span class="pl-k"&gt;INFO&lt;/span&gt;] Running on http:&lt;span class="pl-k"&gt;//&lt;/span&gt;&lt;span class="pl-c1"&gt;127.0&lt;/span&gt;.&lt;span class="pl-c1"&gt;0.1&lt;/span&gt;:&lt;span class="pl-c1"&gt;8080&lt;/span&gt; (CTRL &lt;span class="pl-k"&gt;+&lt;/span&gt; C to quit)&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Send it a test HTTP request.&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sirfuzzalot/pywhoami" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Cover Photo Credit: &lt;a href="https://unsplash.com/@domonique94" rel="noopener noreferrer"&gt;Domonique Davenport&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>todayilearned</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
