<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Real Python</title>
  <link href="https://realpython.com/atom.xml" rel="self"/>
  <link href="https://realpython.com/"/>
  <updated>2026-08-11T14:00:00+00:00</updated>
  <id>https://realpython.com/</id>
  <author>
    <name>Real Python</name>
  </author>

  
    <entry>
      <title>Coding With OpenCode: AI-Assisted Python</title>
      <id>https://realpython.com/courses/coding-with-opencode-ai/</id>
      <link href="https://realpython.com/courses/coding-with-opencode-ai/"/>
      <updated>2026-08-11T14:00:00+00:00</updated>
      <summary>Learn how to use OpenCode for AI-assisted Python coding, using a free Gemini API key to analyze and refactor code right in your terminal.</summary>
      <content type="html">
        &lt;p&gt;OpenCode is an open-source AI coding agent that runs in your terminal and lets you analyze and refactor a Python project through conversational commands. In this video course, you&amp;rsquo;ll install it on your system, set it up with a free Google Gemini API key, and learn the basics of how to use it in your daily programming work.&lt;/p&gt;
&lt;p&gt;OpenCode works as a conversational assistant you explicitly direct. Ask it to analyze functions, refactor code, or explain issues. Press Enter to send your query, and you&amp;rsquo;ll get a response with full awareness of your project context. It supports more than seventy-five AI providers, including Anthropic, OpenAI, and Google Gemini.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;re a Python developer who prefers working in the terminal, OpenCode offers deliberate, context-aware assistance and a customizable &lt;code&gt;AGENTS.md&lt;/code&gt; configuration file.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: Coding With OpenCode: AI-Assisted Python</title>
      <id>https://realpython.com/quizzes/coding-with-opencode-ai-assisted-python/</id>
      <link href="https://realpython.com/quizzes/coding-with-opencode-ai-assisted-python/"/>
      <updated>2026-08-11T12:00:00+00:00</updated>
      <summary>Learn to install OpenCode, connect it to a free Gemini API key, and refactor a Python project from your terminal using Plan and Build modes.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of the concepts covered in &lt;a href=&quot;https://realpython.com/courses/coding-with-opencode-ai-assisted-python/&quot;&gt;Coding With OpenCode: AI-Assisted Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how to install OpenCode, connect it to a free Google Gemini API key, and use &lt;em&gt;Plan&lt;/em&gt; and &lt;em&gt;Build&lt;/em&gt; modes to analyze and refactor a Python project without leaving your terminal.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll also check what you know about OpenCode sessions, the command palette, and switching between AI models on the fly.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Qt Designer and Python: Build Your GUI Applications Faster</title>
      <id>https://realpython.com/qt-designer-python/</id>
      <link href="https://realpython.com/qt-designer-python/"/>
      <updated>2026-08-10T14:00:00+00:00</updated>
      <summary>Learn how to use Qt Designer to build Python GUIs with PyQt6. Create your main windows and dialogs visually, then load them in your app.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;Qt Designer is a tool that lets you build the graphical user interface (GUI) of a PyQt application visually, by dragging and dropping widgets onto a form instead of writing layout code by hand. In Python, you save those designs as &lt;code&gt;.ui&lt;/code&gt; files and load them into your apps, which can speed up your GUI development considerably.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Qt Designer&lt;/strong&gt; produces XML-based &lt;code&gt;.ui&lt;/code&gt; files that don’t depend on a particular Qt binding, so you build your GUI visually and then use it from &lt;strong&gt;PyQt6&lt;/strong&gt; code.&lt;/li&gt;
&lt;li&gt;You install the &lt;strong&gt;PyQt6&lt;/strong&gt; bindings with &lt;code&gt;pip install pyqt6&lt;/code&gt; and get the Qt Designer app from &lt;strong&gt;PySide6&lt;/strong&gt;, your system package manager, or the official Qt installer.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;pyuic6&lt;/code&gt; command turns a &lt;code&gt;.ui&lt;/code&gt; file into a Python module, while &lt;code&gt;uic.loadUi()&lt;/code&gt; reads the same file at &lt;strong&gt;runtime&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A single Qt Designer form can hold a complete &lt;strong&gt;main window&lt;/strong&gt; with menus, toolbars, and a status bar, or a standalone &lt;strong&gt;dialog&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You connect a widget’s &lt;strong&gt;signals&lt;/strong&gt; to &lt;strong&gt;slots&lt;/strong&gt; visually in Qt Designer, without hand-writing the connection code.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You’ll also see when it makes sense to reach for Qt Designer instead of hand coding your GUIs in plain Python.&lt;/p&gt;
&lt;p&gt;For a better understanding of the topics in this tutorial, you can check out the following resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://realpython.com/python-pyqt-gui-calculator/&quot;&gt;Python and PyQt: Building a GUI Desktop Calculator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://realpython.com/python-menus-toolbars/&quot;&gt;Python and PyQt: Creating Menus, Toolbars, and Status Bars&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://realpython.com/python-pyqt-layout/&quot;&gt;PyQt Layouts: Create Professional-Looking GUI Applications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You’ll put all this knowledge together by using the GUIs that you’ll build with Qt Designer in a sample text editor application. You can get the code and all the required resources to build this application by clicking the link below:&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get the Source Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/qt-designer-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-qt-designer-code&quot; markdown&gt;Click here to get the source code you’ll use&lt;/a&gt; to learn about creating Python GUI applications with Qt Designer in this tutorial.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Qt Designer and Python: Build Your GUI Applications Faster” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/qt-designer-python/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #abe5b2;&quot; alt=&quot;Qt Designer and Python: Build Your GUI Applications Faster&quot; src=&quot;https://files.realpython.com/media/Creating-Python-GUI-Applications-with-Qt-Designer_Watermarked.a557daee0374.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Creating-Python-GUI-Applications-with-Qt-Designer_Watermarked.a557daee0374.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Creating-Python-GUI-Applications-with-Qt-Designer_Watermarked.a557daee0374.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Creating-Python-GUI-Applications-with-Qt-Designer_Watermarked.a557daee0374.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Creating-Python-GUI-Applications-with-Qt-Designer_Watermarked.a557daee0374.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/qt-designer-python/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Qt Designer and Python: Build Your GUI Applications Faster&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Test your knowledge of Qt Designer for Python. Build PyQt GUIs visually with drag-and-drop, signals and slots, and .ui files.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;getting-started-with-qt-designer&quot;&gt;Getting Started With Qt Designer&lt;a class=&quot;headerlink&quot; href=&quot;#getting-started-with-qt-designer&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Qt Designer&lt;/strong&gt; is a &lt;a href=&quot;https://www.qt.io/&quot;&gt;Qt&lt;/a&gt; tool that provides you with a &lt;a href=&quot;https://en.wikipedia.org/wiki/WYSIWYG&quot;&gt;what-you-see-is-what-you-get (WYSIWYG)&lt;/a&gt; user interface to create GUIs for your PyQt applications productively and efficiently. With this tool, you create GUIs by dragging and dropping &lt;a href=&quot;https://doc.qt.io/qt-6/qtwidgets-index.html&quot;&gt;&lt;code&gt;QWidget&lt;/code&gt;&lt;/a&gt; objects on an empty form. After that, you can arrange them into a coherent GUI using different layout managers.&lt;/p&gt;
&lt;p&gt;Qt Designer also allows you to preview your GUIs using different styles and resolutions, connect &lt;a href=&quot;https://www.riverbankcomputing.com/static/Docs/PyQt6/signals_slots.html&quot;&gt;signals and slots&lt;/a&gt;, create menus and toolbars, and more.&lt;/p&gt;
&lt;p&gt;Qt Designer is platform and programming language independent. It doesn’t produce code in any particular programming language, but it creates &lt;a href=&quot;https://doc.qt.io/qt-6/designer-ui-file-format.html&quot;&gt;&lt;code&gt;.ui&lt;/code&gt; files&lt;/a&gt;. These files are &lt;code&gt;XML&lt;/code&gt; files with detailed descriptions of how to generate Qt-based GUIs.&lt;/p&gt;
&lt;p&gt;You can translate the content of &lt;code&gt;.ui&lt;/code&gt; files into Python code with &lt;a href=&quot;https://www.riverbankcomputing.com/static/Docs/PyQt6/designer.html#pyuic6&quot;&gt;&lt;code&gt;pyuic6&lt;/code&gt;&lt;/a&gt;, which is a command-line tool that comes with PyQt. Then you can use this Python code in your GUI applications. You can also read &lt;code&gt;.ui&lt;/code&gt; files directly and load their content to generate the associated GUI.&lt;/p&gt;
&lt;h3 id=&quot;installing-and-running-qt-designer&quot;&gt;Installing and Running Qt Designer&lt;a class=&quot;headerlink&quot; href=&quot;#installing-and-running-qt-designer&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;There are several ways to install Qt Designer, and the right one depends on your platform. Qt Designer is a separate application, so you’ll set up two separate pieces: the &lt;strong&gt;PyQt6&lt;/strong&gt; bindings that your code will use, and the Qt Designer application itself.&lt;/p&gt;
&lt;p&gt;First, create and activate a &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;Python virtual environment&lt;/a&gt; and install &lt;a href=&quot;https://pypi.org/project/PyQt6/&quot;&gt;PyQt6&lt;/a&gt; with &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python3&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;venv&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;./venv
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;venv/bin/activate
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(venv)&lt;/span&gt; &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pyqt6
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;This installs PyQt6 along with a private copy of the required Qt libraries. It also gives you &lt;code&gt;pyuic6&lt;/code&gt;, a command-line tool that you’ll use later to turn your &lt;code&gt;.ui&lt;/code&gt; files into Python code.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In PyQt5, you installed Qt Designer through the &lt;code&gt;pyqt5-tools&lt;/code&gt; package. In PyQt6, &lt;code&gt;pyqt6-tools&lt;/code&gt; is no longer maintained and won’t install on current Python versions, so you’ll install Qt Designer on its own instead.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Next, install the Qt Designer application. Because Qt Designer saves its work in binding-agnostic &lt;code&gt;.ui&lt;/code&gt; files, you can get the tool in whatever way is most convenient for your platform.&lt;/p&gt;
&lt;p&gt;Even though your application code uses PyQt6, the quickest cross-platform way to get Qt Designer is to install &lt;a href=&quot;https://pypi.org/project/PySide6/&quot;&gt;PySide6&lt;/a&gt;, which ships with a ready-to-run copy of the tool:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(venv)&lt;/span&gt; &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pyside6
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(venv)&lt;/span&gt; &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;pyside6-designer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;The &lt;code&gt;pyside6-designer&lt;/code&gt; command launches the same Qt Designer that you’d get directly from Qt. You design your GUI here and then load the resulting &lt;code&gt;.ui&lt;/code&gt; file from PyQt6.&lt;/p&gt;
&lt;p&gt;You can also install Qt Designer in a few platform-specific ways:&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/qt-designer-python/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/qt-designer-python/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #306: Programmatically Developing LLM Prompts With DSPy</title>
      <id>https://realpython.com/podcasts/rpp/306/</id>
      <link href="https://realpython.com/podcasts/rpp/306/"/>
      <updated>2026-08-07T12:00:00+00:00</updated>
      <summary>How can you move from manually writing prompts for an LLM application toward defining them programmatically? This week on the show, Brett Kennedy returns to discuss his new book &quot;Building LLM Applications with DSPy.&quot;</summary>
      <content type="html">
        &lt;p&gt;How can you move from manually writing prompts for an LLM application toward defining them programmatically? This week on the show, Brett Kennedy returns to discuss his new book &quot;Building LLM Applications with DSPy.&quot;&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: How to Use Type Hints for Multiple Return Types in Python</title>
      <id>https://realpython.com/quizzes/python-type-hints-multiple-types/</id>
      <link href="https://realpython.com/quizzes/python-type-hints-multiple-types/"/>
      <updated>2026-08-07T12:00:00+00:00</updated>
      <summary>Test your understanding of type hints for multiple return types in Python. Practice unions, tuples, callables, generators, and type aliases.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/python-type-hints-multiple-types/&quot;&gt;How to Use Type Hints for Multiple Return Types in Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how to annotate a function that returns one
value of alternative types, and how to describe several pieces of data at once with a
tuple.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll also practice annotating callbacks, factory functions, and generators, defining
type aliases to keep long annotations readable, and checking your work with a static
type checker.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: Python&#x27;s Assignment Operator: Write Robust Assignments</title>
      <id>https://realpython.com/quizzes/python-assignment-operator/</id>
      <link href="https://realpython.com/quizzes/python-assignment-operator/"/>
      <updated>2026-08-06T12:00:00+00:00</updated>
      <summary>Practice using Python&#x27;s assignment operator to create, initialize, and update variables, plus augmented assignments and the walrus operator.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of &lt;a href=&quot;https://realpython.com/python-assignment-operator/&quot;&gt;Python&amp;rsquo;s Assignment Operator: Write Robust Assignments&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how to write assignment statements, work with parallel assignment and iterable unpacking, use augmented assignments, and explore variants like the walrus operator and managed attributes.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Validating Data With Pointblank in Python</title>
      <id>https://realpython.com/python-pointblank/</id>
      <link href="https://realpython.com/python-pointblank/"/>
      <updated>2026-08-05T14:00:00+00:00</updated>
      <summary>Learn how to validate data in Python with Pointblank: declare quality checks, split clean from failing rows, and rerun validation plans from YAML.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;At 3 a.m., a scheduled data pipeline fails with an &lt;code&gt;AssertionError&lt;/code&gt;, and the traceback can’t tell you whether the cause is one stray row or a systematic bleed that should halt the entire run. Pointblank, a Python data-validation library, sharpens that decision: it checks a Polars or pandas DataFrame against rules you declare, and each rule accumulates failures until it crosses a threshold you set.&lt;/p&gt;
&lt;p&gt;When a rule trips, you learn its name, the offending column, and the fraction of rows that failed, and Pointblank’s &lt;code&gt;pb&lt;/code&gt; command-line tool wires that signal into a &lt;a href=&quot;https://realpython.com/python-continuous-integration/&quot;&gt;continuous integration&lt;/a&gt; step.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A validation plan chains &lt;strong&gt;&lt;code&gt;col_vals_*()&lt;/code&gt;&lt;/strong&gt; checks onto &lt;strong&gt;&lt;code&gt;pb.Validate&lt;/code&gt;&lt;/strong&gt; and runs when you call &lt;strong&gt;&lt;code&gt;.interrogate()&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Thresholds&lt;/code&gt;&lt;/strong&gt; turn a pass/fail check into &lt;strong&gt;warning&lt;/strong&gt;, &lt;strong&gt;error&lt;/strong&gt;, and &lt;strong&gt;critical&lt;/strong&gt; tiers based on the fraction of failing rows.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Actions&lt;/code&gt;&lt;/strong&gt; trigger messages or callbacks when a step crosses a threshold, letting a &lt;strong&gt;policy&lt;/strong&gt; decide the outcome.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;get_sundered_data()&lt;/code&gt;&lt;/strong&gt; routes the passing or failing rows out of an interrogated plan, depending on its &lt;strong&gt;&lt;code&gt;type&lt;/code&gt;&lt;/strong&gt; argument.&lt;/li&gt;
&lt;li&gt;A plan stored as &lt;strong&gt;YAML&lt;/strong&gt; runs through the &lt;strong&gt;&lt;code&gt;pb&lt;/code&gt;&lt;/strong&gt; command-line tool, where &lt;strong&gt;&lt;code&gt;--fail-on critical&lt;/code&gt;&lt;/strong&gt; returns a nonzero exit code for &lt;strong&gt;CI&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pointblank can also validate SQL tables in &lt;a href=&quot;https://realpython.com/python-duckdb/&quot;&gt;DuckDB&lt;/a&gt; or PostgreSQL directly, so it complements parse-time schema tools such as &lt;a href=&quot;https://realpython.com/python-pydantic/&quot;&gt;Pydantic&lt;/a&gt; rather than replacing them. In this tutorial, you’ll see where Pointblank overlaps with &lt;a href=&quot;https://pandera.readthedocs.io/&quot;&gt;Pandera&lt;/a&gt; and &lt;a href=&quot;https://greatexpectations.io/&quot;&gt;Great Expectations&lt;/a&gt;, two other Python data-validation libraries, and when to choose each one.&lt;/p&gt;
&lt;p&gt;To get the most out of this tutorial, you should feel comfortable reading basic &lt;a href=&quot;https://realpython.com/polars-python/&quot;&gt;Polars&lt;/a&gt; or &lt;a href=&quot;https://realpython.com/pandas-dataframe/&quot;&gt;pandas DataFrame&lt;/a&gt; code, &lt;a href=&quot;https://realpython.com/run-python-scripts/&quot;&gt;running Python scripts&lt;/a&gt; from the command line, and working in a terminal with a package manager like &lt;a href=&quot;https://realpython.com/python-uv/&quot;&gt;&lt;code&gt;uv&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt;. A &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;virtual environment&lt;/a&gt; helps keep those installs isolated.&lt;/p&gt;
&lt;p&gt;To follow along, you’ll validate a small built-in dataset, add thresholds and actions, sunder a messier table of atom data, and finally move the whole plan into YAML.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/pointblank-python-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-pointblank-python-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; you’ll use to validate DataFrames with Pointblank, from severity thresholds and row sundering to YAML-driven checks.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Validating Data With Pointblank in Python” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/python-pointblank/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #e5c6aa;&quot; alt=&quot;A worker kneels at a Python-branded validation machine labeled VALIDATING, sorting boxes from a conveyor belt into two stacks marked PASS and REVIEW alongside wooden crates.&quot; src=&quot;https://files.realpython.com/media/Validating-Data-with-Pointblank-in-Python_Watermarked.e361acd055a3.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Validating-Data-with-Pointblank-in-Python_Watermarked.e361acd055a3.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Validating-Data-with-Pointblank-in-Python_Watermarked.e361acd055a3.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Validating-Data-with-Pointblank-in-Python_Watermarked.e361acd055a3.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Validating-Data-with-Pointblank-in-Python_Watermarked.e361acd055a3.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/python-pointblank/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Validating Data With Pointblank in Python&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Validate data in Python with Pointblank. Declare quality checks, split clean rows from failing ones, and rerun validation plans from YAML.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;get-started-with-pointblank-in-python&quot;&gt;Get Started With Pointblank in Python&lt;a class=&quot;headerlink&quot; href=&quot;#get-started-with-pointblank-in-python&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Start by running one validation plan against a built-in dataset.
The examples use &lt;a href=&quot;https://realpython.com/python-uv/&quot;&gt;&lt;code&gt;uv&lt;/code&gt;&lt;/a&gt; because it runs &lt;a href=&quot;https://realpython.com/python-script-structure/&quot;&gt;self-contained scripts&lt;/a&gt; that declare and manage their own dependencies through &lt;a href=&quot;https://packaging.python.org/en/latest/specifications/inline-script-metadata/#inline-script-metadata&quot;&gt;inline script metadata&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you don’t already have &lt;code&gt;uv&lt;/code&gt;, you can install it using the standalone installer by running the command below:&lt;/p&gt;
&lt;ul class=&quot;nav nav-tabs justify-content-end js-platform-widget-tabs&quot; role=&quot;tablist&quot;&gt;

  &lt;li class=&quot;nav-item mb-0 js-platform-widget-tab-windows&quot; role=&quot;presentation&quot;&gt;
    &lt;a class=&quot;nav-link link-unstyled text-body active small&quot; id=&quot;windows-tab-1&quot; data-bs-toggle=&quot;tab&quot; href=&quot;#windows-1&quot; role=&quot;tab&quot; aria-controls=&quot;windows-1&quot; aria-selected=&quot;true&quot;&gt;&lt;span class=&quot;icon baseline text-muted me-1&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#brands--windows&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;Windows&lt;/a&gt;
  &lt;/li&gt;




  &lt;li class=&quot;nav-item mb-0 js-platform-widget-tab-linuxmacos&quot; role=&quot;presentation&quot;&gt;
    &lt;a class=&quot;nav-link link-unstyled text-body small&quot; id=&quot;macos-tab-1&quot; data-bs-toggle=&quot;tab&quot; href=&quot;#linux-macos-1&quot; role=&quot;tab&quot; aria-controls=&quot;linux-macos-1&quot; aria-selected=&quot;false&quot;&gt;&lt;span class=&quot;icon baseline text-muted&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#v4--linux&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;icon baseline text-muted me-1&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#v4--apple&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;Linux + macOS&lt;/a&gt;
  &lt;/li&gt;

&lt;/ul&gt;
&lt;div class=&quot;tab-content mt-2 mb-0 js-platform-widget-content&quot;&gt;
&lt;div aria-labelledby=&quot;windows-tab-1&quot; class=&quot;tab-pane fade show active&quot; id=&quot;windows-1&quot; role=&quot;tabpanel&quot;&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pscon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Windows PowerShell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;PS&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;powershell&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-ExecutionPolicy&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ByPass&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;irm https://astral.sh/uv/install.ps1 | iex&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;/div&gt;
&lt;div aria-labelledby=&quot;linux-macos-tab-1&quot; class=&quot;tab-pane fade &quot; id=&quot;linux-macos-1&quot; role=&quot;tabpanel&quot;&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;curl&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-LsSf&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;https://astral.sh/uv/install.sh&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;If you don’t have &lt;code&gt;curl&lt;/code&gt; installed on your system, then you can use &lt;code&gt;wget&lt;/code&gt; as shown below:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;wget&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-qO-&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;https://astral.sh/uv/install.sh&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now that you have &lt;code&gt;uv&lt;/code&gt;, the script below declares &lt;code&gt;pointblank[pl]&lt;/code&gt; as a dependency.
The &lt;code&gt;[pl]&lt;/code&gt; suffix is a &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt; extra&lt;/a&gt; that pulls in &lt;a href=&quot;https://realpython.com/polars-python/&quot;&gt;Polars&lt;/a&gt; alongside Pointblank, so &lt;code&gt;uv run pointblank_quickstart.py&lt;/code&gt; builds an isolated environment and runs the file in one step.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you’d rather not use &lt;code&gt;uv&lt;/code&gt;, install the dependencies with &lt;code&gt;python -m pip install &#x27;pointblank[pl]&#x27;&lt;/code&gt; in a &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;virtual environment&lt;/a&gt; and run each script with &lt;code&gt;python&lt;/code&gt; instead.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Pointblank ships a small example table named &lt;code&gt;small_table&lt;/code&gt; with thirteen rows and eight columns.
Its columns carry deliberately generic names, &lt;code&gt;a&lt;/code&gt; through &lt;code&gt;f&lt;/code&gt; alongside two date columns, which keeps the focus on the validation mechanics rather than any one domain.&lt;/p&gt;
&lt;p&gt;The first script validates three of them, one for each common kind of check.
Since &lt;code&gt;small_table&lt;/code&gt; has only thirteen rows, you can print the whole thing from the &lt;a href=&quot;https://realpython.com/python-repl/&quot;&gt;Python REPL&lt;/a&gt; and see every value before you run anything.&lt;/p&gt;
&lt;p&gt;The scripts in this tutorial declare their own dependencies, but a bare REPL doesn’t, so launch one with Pointblank and Polars already available:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;uv&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;run&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--with&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#x27;pointblank[pl]&#x27;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;python
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Then load the dataset and print the three columns you’ll validate:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;pointblank&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;pb&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;polars&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;pl&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;small_table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;load_dataset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;small_table&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tbl_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;polars&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tbl_rows&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;... &lt;/span&gt;    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;small_table&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;select&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;c&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;f&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;shape: (13, 3)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;┌──────┬─────────┬──────┐&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ c    ┆ d       ┆ f    │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ ---  ┆ ---     ┆ ---  │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ i64  ┆ f64     ┆ str  │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;╞══════╪═════════╪══════╡&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 3    ┆ 3423.29 ┆ high │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 8    ┆ 9999.99 ┆ low  │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 3    ┆ 2343.23 ┆ high │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ null ┆ 3892.4  ┆ mid  │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 7    ┆ 283.94  ┆ low  │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 4    ┆ 3291.03 ┆ mid  │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 3    ┆ 843.34  ┆ high │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 2    ┆ 1035.64 ┆ low  │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 9    ┆ 837.93  ┆ high │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 9    ┆ 837.93  ┆ high │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 7    ┆ 833.98  ┆ low  │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ 8    ┆ 108.34  ┆ low  │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;│ null ┆ 2230.09 ┆ high │&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;└──────┴─────────┴──────┘&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;You’ll write one rule for each of these three columns, listed in the same order as the table, with bounds chosen to illustrate the check rather than to describe real measurements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;c&lt;/code&gt;&lt;/strong&gt; is an integer column that the plan requires to be non-null, and two of its rows are null.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;d&lt;/code&gt;&lt;/strong&gt; is a numeric column that the plan requires to fall between &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;5000&lt;/code&gt;, and one row, &lt;code&gt;9999.99&lt;/code&gt;, falls outside that range.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;f&lt;/code&gt;&lt;/strong&gt; is a categorical column that the plan limits to the labels &lt;code&gt;low&lt;/code&gt;, &lt;code&gt;mid&lt;/code&gt;, and &lt;code&gt;high&lt;/code&gt;, and every row already matches.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the whole table in view, the failure counts you’ll see in a moment are no surprise: two null &lt;code&gt;c&lt;/code&gt; values, one out-of-range &lt;code&gt;d&lt;/code&gt; value, and a clean &lt;code&gt;f&lt;/code&gt; column.
When you validate your own data, you’d swap these for your real columns and the thresholds your &lt;a href=&quot;/ref/software-engineering-glossary/pipeline/&quot; class=&quot;ref-link&quot;&gt;pipeline&lt;/a&gt; expects.&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/python-pointblank/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/python-pointblank/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: Validating Data With Pointblank in Python</title>
      <id>https://realpython.com/quizzes/python-pointblank/</id>
      <link href="https://realpython.com/quizzes/python-pointblank/"/>
      <updated>2026-08-05T12:00:00+00:00</updated>
      <summary>Validate data in Python with Pointblank. Declare quality checks, split clean rows from failing ones, and rerun validation plans from YAML.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/python-pointblank/&quot;&gt;Validating Data With Pointblank in Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how to declare validation rules,
set severity thresholds, sunder clean rows from dirty ones, and rerun a
validation plan from YAML with the &lt;code&gt;pb&lt;/code&gt; command-line tool.&lt;/p&gt;
&lt;p&gt;Data validation keeps a bad row from quietly breaking the rest of your pipeline,
so it&amp;rsquo;s worth getting comfortable with these checks.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Sending Emails Using Python</title>
      <id>https://realpython.com/courses/sending-emails-using-python/</id>
      <link href="https://realpython.com/courses/sending-emails-using-python/"/>
      <updated>2026-08-04T14:00:00+00:00</updated>
      <summary>Learn how to send emails with Python using SMTP and smtplib, attach files, format HTML messages, and personalize bulk emails.</summary>
      <content type="html">
        &lt;p&gt;You probably found this video course because you want to send emails with Python to automate confirmation messages, password resets, or scheduled notifications. Python&amp;rsquo;s standard library covers the whole pipeline, from making a server connection to building the message and sending it to one or many recipients. This course walks through every step in working code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A safe testing setup uses a &lt;strong&gt;throwaway Gmail account&lt;/strong&gt; with an &lt;strong&gt;app password&lt;/strong&gt;, a local &lt;code&gt;aiosmtpd&lt;/code&gt; debug server, or a privacy-focused provider like Posteo or Proton Mail.&lt;/li&gt;
&lt;li&gt;A secure SMTP session uses &lt;code&gt;.SMTP_SSL()&lt;/code&gt; with &lt;code&gt;ssl.create_default_context()&lt;/code&gt;, which &lt;strong&gt;validates the server certificate&lt;/strong&gt; and &lt;strong&gt;encrypts&lt;/strong&gt; your credentials and message content.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;EmailMessage&lt;/code&gt; class from the &lt;code&gt;email&lt;/code&gt; package assembles &lt;strong&gt;plain text&lt;/strong&gt;, &lt;strong&gt;HTML alternatives&lt;/strong&gt;, &lt;strong&gt;file attachments&lt;/strong&gt;, and &lt;strong&gt;personalized fields&lt;/strong&gt; through &lt;code&gt;.set_content()&lt;/code&gt;, &lt;code&gt;.add_alternative()&lt;/code&gt;, and &lt;code&gt;.add_attachment()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Setting &lt;code&gt;msg[&quot;reply-to&quot;]&lt;/code&gt; or any other RFC 5322 header on an &lt;code&gt;EmailMessage&lt;/code&gt; routes &lt;strong&gt;replies&lt;/strong&gt; to a different mailbox than the sender address.&lt;/li&gt;
&lt;li&gt;For high-volume sending, &lt;strong&gt;transactional email services&lt;/strong&gt; like SendGrid, Mailgun, and Brevo provide deliverability, statistics, and &lt;strong&gt;API libraries&lt;/strong&gt; that go beyond what &lt;code&gt;smtplib&lt;/code&gt; alone offers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before you jump into the code, you&amp;rsquo;ll set up a throwaway email account or a local debug server so you can experiment freely without spamming real inboxes.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: K-Means Clustering in Python: A Practical Guide</title>
      <id>https://realpython.com/quizzes/k-means-clustering-python/</id>
      <link href="https://realpython.com/quizzes/k-means-clustering-python/"/>
      <updated>2026-08-04T12:00:00+00:00</updated>
      <summary>Check how well you know k-means clustering in Python, from picking the number of clusters to building and tuning a scikit-learn pipeline.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of &lt;a href=&quot;https://realpython.com/k-means-clustering-python/&quot;&gt;K-Means Clustering in Python: A Practical Guide&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how &lt;em&gt;k&lt;/em&gt;-means groups data into clusters, how the main clustering categories compare, and how to build and tune a &lt;em&gt;k&lt;/em&gt;-means pipeline with scikit-learn.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;k&lt;/em&gt;-means is one of the oldest and most approachable clustering methods, which makes it a great entry point into &lt;a href=&quot;https://realpython.com/tutorials/machine-learning/&quot;&gt;unsupervised machine learning&lt;/a&gt; with Python.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: Sending Emails Using Python</title>
      <id>https://realpython.com/quizzes/sending-emails-using-python/</id>
      <link href="https://realpython.com/quizzes/sending-emails-using-python/"/>
      <updated>2026-08-04T12:00:00+00:00</updated>
      <summary>Test what you know about sending email from Python with smtplib, building messages with EmailMessage, and connecting to real servers over SSL.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of the concepts covered in &lt;a href=&quot;https://realpython.com/courses/sending-emails-using-python/&quot;&gt;Sending Emails Using Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how SMTP carries a message from your code to a mail server, how the &lt;code&gt;EmailMessage&lt;/code&gt; class assembles plain text, HTML alternatives, and file attachments, and how &lt;code&gt;SMTP_SSL&lt;/code&gt; secures a connection to a real provider.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll also check what you know about CC, BCC, and reply-to headers, base64 encoding for binary attachments, and when a transactional email service beats sending mail yourself.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>MCP Gets Its Biggest Rewrite and Other Python News for August 2026</title>
      <id>https://realpython.com/python-news-august-2026/</id>
      <link href="https://realpython.com/python-news-august-2026/"/>
      <updated>2026-08-03T14:00:00+00:00</updated>
      <summary>MCP drops sessions and renames FastMCP, Claude Opus 5 turns thinking on by default, and Python 3.15 ships its final beta.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;Some months, the &lt;a href=&quot;/ref/ai-coding-glossary/ai/&quot; class=&quot;ref-link&quot;&gt;AI&lt;/a&gt; news is just a trickle of point releases. But this past month was like a firehose. The protocol that connects &lt;a href=&quot;/ref/ai-coding-glossary/agent/&quot; class=&quot;ref-link&quot;&gt;agents&lt;/a&gt; to your tools got its biggest rewrite since inception, and Anthropic, OpenAI, Google, Meta, Moonshot, and a brand-new lab founded by a former OpenAI CTO all shipped new models in a single month.&lt;/p&gt;
&lt;p&gt;Besides the models, the rest of the Python ecosystem was equally active. The major scientific libraries dropped support for 3.13t and settled on 3.14t as their free-threaded target. Python 3.15 shipped its final beta, the JIT team responded to the Steering Council’s ultimatum, the PSF opened nominations for its board and the first-ever Packaging Council, and Astral shipped breaking minors of &lt;code&gt;uv&lt;/code&gt; and Ruff. The MCP rewrite comes first.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Join Now:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/newsletter/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-newsletter&quot; markdown&gt;Click here to join the Real Python Newsletter&lt;/a&gt; and you’ll never miss another Python tutorial, course, or news update.&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id=&quot;mcp-drops-sessions-and-goes-stateless&quot;&gt;MCP Drops Sessions and Goes Stateless&lt;a class=&quot;headerlink&quot; href=&quot;#mcp-drops-sessions-and-goes-stateless&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Two things landed on July 28, and together they make this the most disruptive month &lt;a href=&quot;/ref/ai-coding-glossary/mcp/&quot; class=&quot;ref-link&quot;&gt;MCP&lt;/a&gt; has had since it launched. The &lt;a href=&quot;https://blog.modelcontextprotocol.io/posts/2026-07-28/&quot;&gt;2026-07-28 specification&lt;/a&gt; was finalized with a revision that changes how servers are deployed, and the &lt;a href=&quot;https://github.com/modelcontextprotocol/python-sdk&quot;&gt;Python SDK&lt;/a&gt; shipped a 2.0 the same day, renaming the class most Python servers are built on.&lt;/p&gt;
&lt;h3 id=&quot;what-the-new-spec-changes&quot;&gt;What the New Spec Changes&lt;a class=&quot;headerlink&quot; href=&quot;#what-the-new-spec-changes&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The main change is that the &lt;a href=&quot;https://modelcontextprotocol.io/&quot;&gt;protocol&lt;/a&gt; is now &lt;strong&gt;stateless&lt;/strong&gt;. A client used to open with a handshake and then carry a session ID through the rest of the conversation. Both are gone. Protocol version and client capabilities now ride along on every request, and a new &lt;code&gt;server/discover&lt;/code&gt; call fetches what a server can do.&lt;/p&gt;
&lt;p&gt;Under the new specification, any request can land on any instance, and a plain round-robin load balancer is enough. If you only &lt;a href=&quot;https://realpython.com/python-mcp-client/&quot;&gt;&lt;em&gt;call&lt;/em&gt; MCP servers&lt;/a&gt;, then the stateless switch is what affects you the most.&lt;/p&gt;
&lt;p&gt;If you &lt;a href=&quot;https://realpython.com/python-mcp/&quot;&gt;ship an MCP server&lt;/a&gt;, then your migration list looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Remove the session machinery:&lt;/strong&gt; The handshake and the session header are both gone, so anything you built to track a client between requests goes with them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Validate the &lt;code&gt;Mcp-Method&lt;/code&gt; and &lt;code&gt;Mcp-Name&lt;/code&gt; headers:&lt;/strong&gt; Clients now send them so gateways can route without cracking open the request body, and your server has to check that they match the request.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Change your missing-resource error:&lt;/strong&gt; Use the standard JSON-RPC invalid-params code, &lt;code&gt;-32602&lt;/code&gt;, instead of MCP’s own &lt;code&gt;-32002&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rework your server-initiated requests:&lt;/strong&gt; Roots, Sampling, and Elicitation no longer call back to the client. Instead, your server returns a result that the client uses to make a follow-up request, which is the biggest rewrite on this list.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Move off the experimental Tasks &lt;a href=&quot;/ref/glossary/api/&quot; class=&quot;ref-link&quot;&gt;API&lt;/a&gt;:&lt;/strong&gt; Tasks have graduated from the core spec to &lt;a href=&quot;https://tasks.extensions.modelcontextprotocol.io/&quot;&gt;an extension&lt;/a&gt; and have gained a new lifecycle along the way.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Roots, Sampling, and Logging all entered formal deprecation, and all three keep working for now. The spec also adopted a deprecation policy promising at least a year’s notice before anything is removed, with a 90-day floor reserved for active security risks. That’s more warning than this ecosystem has offered before.&lt;/p&gt;
&lt;p&gt;Authorization also hardened, picking up issuer validation and issuer-bound credentials on top of its OAuth 2.0 foundation.&lt;/p&gt;
&lt;p&gt;Extensions, which existed before without any process around them, finally got one: namespaced identities and independent release cycles. That’s what let Tasks move out of the core without dragging the whole protocol along, and &lt;a href=&quot;https://modelcontextprotocol.io/extensions/apps/overview&quot;&gt;MCP Apps&lt;/a&gt; now arrives as an official extension under that process. A server can send interactive HTML that the host renders in a sandboxed iframe, so a tool call returns a real interface instead of a wall of text.&lt;/p&gt;
&lt;p&gt;Treat third-party MCP servers with the same scrutiny you’d give any &lt;a href=&quot;/ref/glossary/dependency/&quot; class=&quot;ref-link&quot;&gt;dependency&lt;/a&gt;. The official registry verifies &lt;em&gt;who&lt;/em&gt; published a server through GitHub or DNS ownership, but there’s still no code-signing requirement and no review of what a server actually does, and a server you install gets to describe its own tools to your agent.&lt;/p&gt;
&lt;h3 id=&quot;the-python-sdk-renames-fastmcp&quot;&gt;The Python SDK Renames FastMCP&lt;a class=&quot;headerlink&quot; href=&quot;#the-python-sdk-renames-fastmcp&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The spec is only part of the story if you write Python. The &lt;a href=&quot;https://github.com/modelcontextprotocol/python-sdk/releases/tag/v2.0.0&quot;&gt;MCP Python SDK reached 2.0.0&lt;/a&gt; alongside it, and &lt;code&gt;pip install mcp&lt;/code&gt; now provides the 2.x line.&lt;/p&gt;
&lt;p&gt;The first change you’ll notice is a rename. &lt;code&gt;FastMCP&lt;/code&gt; is now &lt;code&gt;MCPServer&lt;/code&gt;, with no alias and no deprecation shim:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;python&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Before, on mcp 1.x&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;mcp.server.fastmcp&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FastMCP&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;mcp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FastMCP&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Demo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# After, on mcp 2.x&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;mcp.server.mcpserver&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MCPServer&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;mcp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MCPServer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Demo&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;The rest of 2.0 is broader than the rename suggests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Wire types are snake_case now:&lt;/strong&gt; &lt;code&gt;result.isError&lt;/code&gt; is now &lt;code&gt;result.is_error&lt;/code&gt;, and &lt;code&gt;tool.inputSchema&lt;/code&gt; is now &lt;code&gt;tool.input_schema&lt;/code&gt;. These types have also moved into a separate &lt;code&gt;mcp-types&lt;/code&gt; &lt;a href=&quot;/ref/glossary/package/&quot; class=&quot;ref-link&quot;&gt;package&lt;/a&gt;, although &lt;code&gt;mcp.types&lt;/code&gt; stays as a permanent alias.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;One &lt;code&gt;Client&lt;/code&gt; replaces three layers:&lt;/strong&gt; The old arrangement of a transport, a &lt;code&gt;ClientSession&lt;/code&gt;, and an &lt;code&gt;initialize()&lt;/code&gt; call now collapses into a single object that connects to a URL, a stdio subprocess, or an in-memory server object for tests.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;httpx&lt;/code&gt; is now &lt;code&gt;httpx2&lt;/code&gt;:&lt;/strong&gt; The &lt;a href=&quot;/ref/computer-science-glossary/software-development-kit/&quot; class=&quot;ref-link&quot;&gt;SDK&lt;/a&gt; moved to the next-generation HTTP client, which is worth knowing if you pin &lt;code&gt;httpx&lt;/code&gt; elsewhere in your dependency tree.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Synchronous handlers run on worker &lt;a href=&quot;/ref/glossary/thread/&quot; class=&quot;ref-link&quot;&gt;threads&lt;/a&gt;:&lt;/strong&gt; They no longer block the event loop. Your handler code doesn’t change, but &lt;code&gt;asyncio.get_running_loop()&lt;/code&gt; now raises inside them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;McpError&lt;/code&gt; is now &lt;code&gt;MCPError&lt;/code&gt;:&lt;/strong&gt; It’s the same acronym capitalization as &lt;code&gt;MCPServer&lt;/code&gt;, so any &lt;code&gt;except McpError&lt;/code&gt; clause needs the new spelling.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One &lt;code&gt;MCPServer&lt;/code&gt; serves both protocol eras, so 2025-era clients keep working against a migrated server with nothing to configure. The 1.x line moves to maintenance mode with security fixes only, so if you’re not ready this month, then pin &lt;code&gt;mcp&amp;gt;=1.28,&amp;lt;2&lt;/code&gt; and come back to it.&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/python-news-august-2026/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/python-news-august-2026/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: Bypassing the GIL for Parallel Processing in Python</title>
      <id>https://realpython.com/quizzes/python-parallel-processing/</id>
      <link href="https://realpython.com/quizzes/python-parallel-processing/"/>
      <updated>2026-08-03T12:00:00+00:00</updated>
      <summary>Test your understanding of the GIL, process-based parallelism, and the ways to run Python threads in parallel across multiple CPU cores.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/python-parallel-processing/&quot;&gt;Bypassing the GIL for Parallel Processing in Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The global interpreter lock stops your threads from executing Python bytecode at the same
time, which caps the speed of CPU-bound code no matter how many cores you have on hand.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how CPU-bound and I/O-bound tasks differ, how
process-based parallelism sidesteps the lock entirely, and which strategies finally let
your threads spread across every core.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #305: Should You Understand Your Entire Python Codebase?</title>
      <id>https://realpython.com/podcasts/rpp/305/</id>
      <link href="https://realpython.com/podcasts/rpp/305/"/>
      <updated>2026-07-31T12:00:00+00:00</updated>
      <summary>Should you understand the entirety of your codebase? How familiar are you with Python&#x27;s built-in functions? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.</summary>
      <content type="html">
        &lt;p&gt;Should you understand the entirety of your codebase? How familiar are you with Python&#x27;s built-in functions? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: 11 Beginner Tips for Learning Python Programming</title>
      <id>https://realpython.com/quizzes/python-beginner-tips/</id>
      <link href="https://realpython.com/quizzes/python-beginner-tips/"/>
      <updated>2026-07-31T12:00:00+00:00</updated>
      <summary>Test your knowledge of the habits that help you learn Python, from coding daily to asking good questions and building your first project.</summary>
      <content type="html">
        &lt;p&gt;Test your understanding of &lt;a href=&quot;https://realpython.com/python-beginner-tips/&quot;&gt;11 Beginner Tips for Learning Python Programming&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll revisit the habits that make new concepts stick, the people and communities that speed up your progress, and the projects that turn what you know into what you can build.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: NumPy Tutorial: Your First Steps Into Data Science in Python</title>
      <id>https://realpython.com/quizzes/numpy-tutorial/</id>
      <link href="https://realpython.com/quizzes/numpy-tutorial/"/>
      <updated>2026-07-30T12:00:00+00:00</updated>
      <summary>Test your NumPy knowledge of arrays, axes, broadcasting, indexing, masks, and data types, the foundation of data science in Python.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/numpy-tutorial/&quot;&gt;NumPy Tutorial: Your First Steps Into Data Science in Python&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through these questions, you&amp;rsquo;ll revisit how NumPy arrays work, including axes, broadcasting, indexing, Boolean masks, and data types. These are the building blocks that most of Python&amp;rsquo;s data science ecosystem relies on.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>CrewAI in Python: Coordinating Teams of AI Agents</title>
      <id>https://realpython.com/crewai-python/</id>
      <link href="https://realpython.com/crewai-python/"/>
      <updated>2026-07-29T14:00:00+00:00</updated>
      <summary>Learn how to use CrewAI to build teams of AI agents in Python, define roles and tools, and coordinate multi-agent workflows that solve complex tasks.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;Have you ever asked ChatGPT to research something, analyze the findings, and then write a polished report, all in one prompt? You probably got &lt;em&gt;something&lt;/em&gt; back, but it wasn’t great. That’s because you’re asking a single model to wear way too many hats at once. CrewAI is a Python framework that solves this by letting you build a crew of specialized AI agents, each focusing on one part of the job.&lt;/p&gt;
&lt;p&gt;For example, instead of cramming research, validation, and writing into a single prompt, you create a team. One agent researches, another validates, and a third writes. Each focuses on what it does best, working together to complete the task.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;CrewAI&lt;/strong&gt; coordinates teams where each agent has a specific &lt;strong&gt;role&lt;/strong&gt;, &lt;strong&gt;goal&lt;/strong&gt;, and &lt;strong&gt;backstory&lt;/strong&gt; that influence its behavior.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sequential workflows&lt;/strong&gt; automatically pass outputs from one agent to the next, making &lt;strong&gt;coordinated pipelines&lt;/strong&gt; straightforward.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;context&lt;/code&gt; parameter&lt;/strong&gt; gives you fine-grained control over which task outputs feed into other tasks.&lt;/li&gt;
&lt;li&gt;You can equip agents with &lt;strong&gt;tools&lt;/strong&gt; like web scraping to expand what they can do beyond text generation.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;API costs&lt;/strong&gt; multiply quickly since each agent makes separate LLM calls, and &lt;strong&gt;verbose logging&lt;/strong&gt; helps you debug agent behavior.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Before you invest time learning CrewAI, you should understand when it’s the right tool for your project. This comparison highlights the key trade-offs:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th class=&quot;text-center&quot;&gt;Pick CrewAI&lt;/th&gt;
&lt;th class=&quot;text-center&quot;&gt;Pick LangGraph&lt;/th&gt;
&lt;th class=&quot;text-center&quot;&gt;Pick AG2 / AutoGen&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;You need structured, role-based workflows&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;✅&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;-&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You want minimal boilerplate to go from prototype to production&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;✅&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;-&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;You need complex state machines with conditional branching&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;-&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;✅&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Your agents need conversational, chat-driven coordination&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;-&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;-&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;CrewAI’s sweet spot is workflows where agents have clear responsibilities and work in a predictable sequence. If you need fine-grained state management with branching logic, LangGraph gives you more control. If your agents need conversational back-and-forth, AG2—the community fork of AutoGen—supports chat-driven coordination patterns and may be a better fit.&lt;/p&gt;
&lt;p&gt;Microsoft AutoGen is now in maintenance mode, so new projects typically choose &lt;a href=&quot;https://www.ag2.ai/product&quot;&gt;AG2&lt;/a&gt; or &lt;a href=&quot;https://learn.microsoft.com/en-us/agent-framework/overview/&quot;&gt;Microsoft Agent Framework&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/crewai-python-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-crewai-python-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; you’ll use to build and coordinate teams of AI agents with CrewAI in Python.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “CrewAI in Python: Coordinating Teams of AI Agents” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/crewai-python/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #ffc973;&quot; alt=&quot;Coordinating Teams of AI Agents with CrewAI in Python&quot; src=&quot;https://files.realpython.com/media/Coordinating-Teams-of-AI-Agents-with-CrewAI-in-Python_Watermarked.d44efee0c44f.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Coordinating-Teams-of-AI-Agents-with-CrewAI-in-Python_Watermarked.d44efee0c44f.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Coordinating-Teams-of-AI-Agents-with-CrewAI-in-Python_Watermarked.d44efee0c44f.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Coordinating-Teams-of-AI-Agents-with-CrewAI-in-Python_Watermarked.d44efee0c44f.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Coordinating-Teams-of-AI-Agents-with-CrewAI-in-Python_Watermarked.d44efee0c44f.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/crewai-python/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;CrewAI in Python: Coordinating Teams of AI Agents&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Check your understanding of CrewAI in Python. Review how to define agent roles, assign tasks, add tools, and coordinate multi-agent workflows.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;get-started-with-crewai-in-python&quot;&gt;Get Started With CrewAI in Python&lt;a class=&quot;headerlink&quot; href=&quot;#get-started-with-crewai-in-python&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before you dive into building multi-agent systems with CrewAI, you’ll need to install it and set up an &lt;a href=&quot;/ref/glossary/api/&quot; class=&quot;ref-link&quot;&gt;API&lt;/a&gt; key for your chosen language model provider. This tutorial uses Google’s &lt;a href=&quot;/ref/ai-coding-tools/gemini/&quot; class=&quot;ref-link&quot;&gt;Gemini&lt;/a&gt; model, which you can access for free through Google AI Studio.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; CrewAI is model-agnostic, so you’re not locked into Gemini. It also works with OpenAI, Anthropic’s &lt;a href=&quot;/ref/ai-coding-tools/claude/&quot; class=&quot;ref-link&quot;&gt;Claude&lt;/a&gt;, Mistral, Groq, and &lt;a href=&quot;/ref/ai-coding-tools/ollama/&quot; class=&quot;ref-link&quot;&gt;Ollama&lt;/a&gt; for local models, among others. Check the &lt;a href=&quot;https://docs.crewai.com/&quot;&gt;CrewAI documentation&lt;/a&gt; for the full list of supported providers.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;You can install CrewAI from &lt;a href=&quot;/ref/glossary/pypi/&quot; class=&quot;ref-link&quot;&gt;PyPI&lt;/a&gt; using &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt;. Before running the command below, you should create and activate a &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;virtual environment&lt;/a&gt;. CrewAI requires &lt;strong&gt;Python 3.10 to 3.13&lt;/strong&gt;, so run &lt;code&gt;python --version&lt;/code&gt; first—installing on Python 3.14 or later will silently resolve to a much older CrewAI release and then fail to build:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#x27;crewai[tools,google-genai]&#x27;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;This installs CrewAI’s core framework, the native Google Gemini provider, and prebuilt tools like &lt;a href=&quot;https://realpython.com/python-web-scraping-practical-introduction/&quot;&gt;web scraping&lt;/a&gt; that agents can use during their work.&lt;/p&gt;
&lt;p&gt;You’ll need a Gemini API key to run the examples in this tutorial. If you don’t have one yet, then head over to &lt;a href=&quot;https://aistudio.google.com/welcome&quot;&gt;Google AI Studio&lt;/a&gt; to sign in with your Google account and generate an API key for free.&lt;/p&gt;
&lt;p&gt;Once you have your API key, set it as an environment variable:&lt;/p&gt;
&lt;ul class=&quot;nav nav-tabs justify-content-end js-platform-widget-tabs&quot; role=&quot;tablist&quot;&gt;

  &lt;li class=&quot;nav-item mb-0 js-platform-widget-tab-windows&quot; role=&quot;presentation&quot;&gt;
    &lt;a class=&quot;nav-link link-unstyled text-body active small&quot; id=&quot;windows-tab-1&quot; data-bs-toggle=&quot;tab&quot; href=&quot;#windows-1&quot; role=&quot;tab&quot; aria-controls=&quot;windows-1&quot; aria-selected=&quot;true&quot;&gt;&lt;span class=&quot;icon baseline text-muted me-1&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#brands--windows&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;Windows&lt;/a&gt;
  &lt;/li&gt;




  &lt;li class=&quot;nav-item mb-0 js-platform-widget-tab-linuxmacos&quot; role=&quot;presentation&quot;&gt;
    &lt;a class=&quot;nav-link link-unstyled text-body small&quot; id=&quot;macos-tab-1&quot; data-bs-toggle=&quot;tab&quot; href=&quot;#linux-macos-1&quot; role=&quot;tab&quot; aria-controls=&quot;linux-macos-1&quot; aria-selected=&quot;false&quot;&gt;&lt;span class=&quot;icon baseline text-muted&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#v4--linux&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;icon baseline text-muted me-1&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#v4--apple&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;Linux + macOS&lt;/a&gt;
  &lt;/li&gt;

&lt;/ul&gt;
&lt;div class=&quot;tab-content mt-2 mb-0 js-platform-widget-content&quot;&gt;
&lt;div aria-labelledby=&quot;windows-tab-1&quot; class=&quot;tab-pane fade show active&quot; id=&quot;windows-1&quot; role=&quot;tabpanel&quot;&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pscon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Windows PowerShell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;PS&amp;gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ENV:GEMINI_API_KEY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;your-gemini-api-key-here&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;/div&gt;
&lt;div aria-labelledby=&quot;linux-macos-tab-1&quot; class=&quot;tab-pane fade &quot; id=&quot;linux-macos-1&quot; role=&quot;tabpanel&quot;&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;export&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;GEMINI_API_KEY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;your-gemini-api-key-here&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With your environment variable set, CrewAI is ready to connect to Gemini in your projects.&lt;/p&gt;
&lt;p&gt;To get started with CrewAI, you can create a single &lt;a href=&quot;/ref/ai-coding-glossary/agent/&quot; class=&quot;ref-link&quot;&gt;agent&lt;/a&gt; that acts as a travel advisor:&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/crewai-python/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/crewai-python/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Managing Imports With Python&#x27;s __all__</title>
      <id>https://realpython.com/courses/managing-imports-dunder-all/</id>
      <link href="https://realpython.com/courses/managing-imports-dunder-all/"/>
      <updated>2026-07-28T14:00:00+00:00</updated>
      <summary>Learn how Python&#x27;s dunder all variable controls wildcard imports and shapes the public API your packages and modules expose.</summary>
      <content type="html">
        &lt;p&gt;Python has something called &lt;strong&gt;wildcard imports&lt;/strong&gt;, which look like &lt;code&gt;from module import *&lt;/code&gt;. This type of import allows you to quickly get all the objects from a module into your namespace. However, using this import on a package can be confusing because it&amp;rsquo;s not clear what you want to import: subpackages, modules, objects? Python has the &lt;strong&gt;&lt;code&gt;__all__&lt;/code&gt;&lt;/strong&gt; variable to work around this issue.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;__all__&lt;/code&gt; variable is a list of strings where each string represents the name of a variable, function, class, or module that you want to expose to wildcard imports.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this video course, you&amp;rsquo;ll:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Understand &lt;strong&gt;wildcard imports&lt;/strong&gt; in Python&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;&lt;code&gt;__all__&lt;/code&gt;&lt;/strong&gt; to control the modules that you &lt;strong&gt;expose&lt;/strong&gt; to wildcard imports&lt;/li&gt;
&lt;li&gt;Control the &lt;strong&gt;names&lt;/strong&gt; that you expose in &lt;strong&gt;modules&lt;/strong&gt; and &lt;strong&gt;packages&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Explore &lt;strong&gt;other use cases&lt;/strong&gt; of the &lt;code&gt;__all__&lt;/code&gt; variable&lt;/li&gt;
&lt;li&gt;Learn some &lt;strong&gt;benefits&lt;/strong&gt; and &lt;strong&gt;best practices&lt;/strong&gt; of using &lt;code&gt;__all__&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To get the most out of this course, you should be familiar with a few Python concepts, including &lt;a href=&quot;https://realpython.com/python-modules-packages/&quot;&gt;modules and packages&lt;/a&gt;, and the &lt;a href=&quot;https://realpython.com/python-import/&quot;&gt;import&lt;/a&gt; system.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Quiz: Managing Imports With Python&#x27;s __all__</title>
      <id>https://realpython.com/quizzes/managing-imports-dunder-all/</id>
      <link href="https://realpython.com/quizzes/managing-imports-dunder-all/"/>
      <updated>2026-07-28T12:00:00+00:00</updated>
      <summary>Check your understanding of wildcard imports, the dunder all variable, and how to control the public APIs of your Python modules and packages.</summary>
      <content type="html">
        &lt;p&gt;In this quiz, you&amp;rsquo;ll test your understanding of
&lt;a href=&quot;https://realpython.com/courses/managing-imports-dunder-all/&quot;&gt;Managing Imports With Python&amp;rsquo;s __all__&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By working through this quiz, you&amp;rsquo;ll revisit how wildcard imports work, what role the &lt;code&gt;__all__&lt;/code&gt; variable plays in modules and packages, and how to define a clean public API for your Python code.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>How to Use Google&#x27;s Antigravity CLI for AI Code Assistance</title>
      <id>https://realpython.com/antigravity-cli/</id>
      <link href="https://realpython.com/antigravity-cli/"/>
      <updated>2026-07-27T14:00:00+00:00</updated>
      <summary>Get started with Google&#x27;s Antigravity CLI, a terminal-based AI coding agent, and use it to read, review, and refactor your Python code.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;Antigravity CLI is a terminal-based AI coding tool that brings Google’s agent assistance into your workflow. After installing it and signing in with your Google account, you can ask questions about your code, add new features, track down bugs, and even dispatch multiple subagents to work on separate tasks in parallel, all without leaving your shell:&lt;/p&gt;
&lt;figure&gt;





&lt;video-player-next class=&quot;video-player-next rounded mb-3&quot; style=&quot;aspect-ratio: 1920/1080;&quot; data-src=&quot;https://stream.realpython.com/3a3373df-3e7b-4fdc-b006-bf4559924dc8/playlist.m3u8&quot; data-thumbnails-url=&quot;/video-thumbnails/05f42aa2-eb3b-4907-bdae-2b1595065faf.vtt&quot; data-thumbnails-cols=&quot;6&quot; data-thumbnails-rows=&quot;6&quot; data-title=&quot;Antigravity CLI&quot;&gt;

    &lt;img class=&quot;video-player-next__poster&quot; src=&quot;https://stream.realpython.com/3a3373df-3e7b-4fdc-b006-bf4559924dc8/thumbnail.jpg?width=1280&quot; srcset=&quot;https://stream.realpython.com/3a3373df-3e7b-4fdc-b006-bf4559924dc8/thumbnail.jpg?width=480 480w, https://stream.realpython.com/3a3373df-3e7b-4fdc-b006-bf4559924dc8/thumbnail.jpg?width=640 640w, https://stream.realpython.com/3a3373df-3e7b-4fdc-b006-bf4559924dc8/thumbnail.jpg?width=960 960w, https://stream.realpython.com/3a3373df-3e7b-4fdc-b006-bf4559924dc8/thumbnail.jpg?width=1920 1920w&quot; alt=&quot;Antigravity CLI&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot;&gt;

&lt;/video-player-next&gt;


  &lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Antigravity CLI&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Antigravity CLI replaced &lt;a href=&quot;/ref/ai-coding-tools/gemini-cli/&quot; class=&quot;ref-link&quot;&gt;Gemini CLI&lt;/a&gt;, which Google retired in June 2026. If you’ve used Gemini CLI, then a lot of this will feel familiar. Your skills, hooks, subagents, and plugins carry over, and the tool still reads its configuration from &lt;code&gt;~/.gemini/&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You don’t need any of that history to follow along, though. This is a hands-on guide to using Antigravity CLI, not a migration manual. But if you’re switching, then the &lt;a href=&quot;#coming-from-gemini-cli&quot;&gt;&lt;em&gt;Coming From Gemini CLI?&lt;/em&gt;&lt;/a&gt; section rounds up what changed and what to watch out for.&lt;/p&gt;
&lt;p&gt;You’re about to install Antigravity CLI, sign in with your Google account, and put it to work on a Python project. It’ll read an unfamiliar &lt;a href=&quot;/ref/glossary/module/&quot; class=&quot;ref-link&quot;&gt;module&lt;/a&gt;, review it against your conventions, and &lt;a href=&quot;/ref/best-practices/refactoring/&quot; class=&quot;ref-link&quot;&gt;refactor&lt;/a&gt; the code while the &lt;a href=&quot;/ref/ai-coding-glossary/agent/&quot; class=&quot;ref-link&quot;&gt;agent&lt;/a&gt; verifies its own work.&lt;/p&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “How to Use Google&#x27;s Antigravity CLI for AI Code Assistance” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/antigravity-cli/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #b9abe6;&quot; alt=&quot;A floating scientist in a lab coat operates a control panel with a lever, a terminal screen reading prompt, a Python logo, and drawers labeled FLOW, DATA, and LOGS, beside a waving robot.&quot; src=&quot;https://files.realpython.com/media/Use-Antigravity-CLI-for-Code-Assistance_Watermarked.5eb983b3713c.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Use-Antigravity-CLI-for-Code-Assistance_Watermarked.5eb983b3713c.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Use-Antigravity-CLI-for-Code-Assistance_Watermarked.5eb983b3713c.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Use-Antigravity-CLI-for-Code-Assistance_Watermarked.5eb983b3713c.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Use-Antigravity-CLI-for-Code-Assistance_Watermarked.5eb983b3713c.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/antigravity-cli/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;How to Use Google&#x27;s Antigravity CLI for AI Code Assistance&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Test your knowledge of Google&#x27;s Antigravity CLI, a terminal-based AI coding agent, and how to use it to read, review, and refactor Python code.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;a class=&quot;headerlink&quot; href=&quot;#prerequisites&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To follow along with this tutorial, you’ll need the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Google Account:&lt;/strong&gt; A &lt;a href=&quot;https://www.google.com/account/about/&quot;&gt;Google account&lt;/a&gt; lets you sign in to Antigravity CLI. A free account is enough to finish this tutorial, although the free tier’s usage limits are tight and have shifted since launch, so expect to bump into them on longer sessions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python 3.12 or higher:&lt;/strong&gt; You’ll work with a small Python &lt;a href=&quot;https://realpython.com/command-line-interfaces-python-argparse/&quot;&gt;command-line application&lt;/a&gt;. If you haven’t already, &lt;a href=&quot;https://realpython.com/installing-python/&quot;&gt;install Python&lt;/a&gt;, making sure the minimum version is &lt;a href=&quot;https://realpython.com/python312-new-features/&quot;&gt;Python 3.12&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because Antigravity CLI is a command-line tool, you should feel comfortable navigating your &lt;a href=&quot;https://realpython.com/terminal-commands/&quot;&gt;terminal&lt;/a&gt; and running basic shell commands. The tool ships as a single binary for macOS, Linux, and Windows, so any of these platforms will work. Unlike Gemini CLI, it doesn’t depend on &lt;a href=&quot;https://nodejs.org/&quot;&gt;Node.js&lt;/a&gt;, which means there’s no separate runtime to install first.&lt;/p&gt;
&lt;p&gt;Go ahead and download the supporting materials for the Python project you’ll work with throughout this tutorial:&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/antigravity-cli-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-antigravity-cli-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; you’ll use to follow along as Antigravity CLI reads, reviews, and refactors a small Python command-line tool.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Once you’ve extracted the files, you’ll find an &lt;code&gt;expense-report/&lt;/code&gt; directory with a tiny command-line tool that &lt;a href=&quot;https://realpython.com/python-csv/&quot;&gt;reads a CSV&lt;/a&gt; of transactions and &lt;a href=&quot;https://realpython.com/python-print/&quot;&gt;prints&lt;/a&gt; a per-category spending summary. To get the most out of this tutorial, initialize a new &lt;a href=&quot;/ref/tools/git/&quot; class=&quot;ref-link&quot;&gt;Git&lt;/a&gt; repository in that directory and make an initial commit so you have a clean baseline to diff against later:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;expense-report/
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;init
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;add&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;.
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;commit&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Initial commit&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;This project is the kind of small, undocumented &lt;a href=&quot;https://realpython.com/run-python-scripts/&quot;&gt;script&lt;/a&gt; you might inherit from a teammate, which makes it a good testing ground for Antigravity CLI’s code-reading and &lt;a href=&quot;https://realpython.com/python-refactoring/&quot;&gt;refactoring&lt;/a&gt; features.&lt;/p&gt;
&lt;h2 id=&quot;step-1-install-and-set-up-antigravity-cli&quot;&gt;Step 1: Install and Set Up Antigravity CLI&lt;a class=&quot;headerlink&quot; href=&quot;#step-1-install-and-set-up-antigravity-cli&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Before you can use &lt;a href=&quot;https://antigravity.google/product/antigravity-cli&quot;&gt;Antigravity CLI&lt;/a&gt;, you need to install it and sign in with your Google account. In this step, you’ll run the official installer, verify the freshly installed &lt;code&gt;agy&lt;/code&gt; command, authenticate, and pick a capable model.&lt;/p&gt;
&lt;h3 id=&quot;install-the-binary&quot;&gt;Install the Binary&lt;a class=&quot;headerlink&quot; href=&quot;#install-the-binary&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Antigravity CLI is distributed as a self-contained &lt;a href=&quot;/ref/glossary/binary-file/&quot; class=&quot;ref-link&quot;&gt;binary file&lt;/a&gt; that ships with the entire &lt;a href=&quot;https://go.dev/&quot;&gt;Go&lt;/a&gt; runtime, so you can download and install it using a single command. Here’s how you can run the official installer script for your platform:&lt;/p&gt;
&lt;ul class=&quot;nav nav-tabs justify-content-end js-platform-widget-tabs&quot; role=&quot;tablist&quot;&gt;

  &lt;li class=&quot;nav-item mb-0 js-platform-widget-tab-windows&quot; role=&quot;presentation&quot;&gt;
    &lt;a class=&quot;nav-link link-unstyled text-body active small&quot; id=&quot;windows-tab-1&quot; data-bs-toggle=&quot;tab&quot; href=&quot;#windows-1&quot; role=&quot;tab&quot; aria-controls=&quot;windows-1&quot; aria-selected=&quot;true&quot;&gt;&lt;span class=&quot;icon baseline text-muted me-1&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#brands--windows&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;Windows&lt;/a&gt;
  &lt;/li&gt;




  &lt;li class=&quot;nav-item mb-0 js-platform-widget-tab-linuxmacos&quot; role=&quot;presentation&quot;&gt;
    &lt;a class=&quot;nav-link link-unstyled text-body small&quot; id=&quot;macos-tab-1&quot; data-bs-toggle=&quot;tab&quot; href=&quot;#linux-macos-1&quot; role=&quot;tab&quot; aria-controls=&quot;linux-macos-1&quot; aria-selected=&quot;false&quot;&gt;&lt;span class=&quot;icon baseline text-muted&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#v4--linux&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;icon baseline text-muted me-1&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#v4--apple&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;Linux + macOS&lt;/a&gt;
  &lt;/li&gt;

&lt;/ul&gt;
&lt;div class=&quot;tab-content mt-2 mb-0 js-platform-widget-content&quot;&gt;
&lt;div aria-labelledby=&quot;windows-tab-1&quot; class=&quot;tab-pane fade show active&quot; id=&quot;windows-1&quot; role=&quot;tabpanel&quot;&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pscon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Windows PowerShell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;PS&amp;gt; &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;irm &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;https&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;://&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;antigravity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;google&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cli&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;install&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ps1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;iex&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;/div&gt;
&lt;div aria-labelledby=&quot;linux-macos-tab-1&quot; class=&quot;tab-pane fade &quot; id=&quot;linux-macos-1&quot; role=&quot;tabpanel&quot;&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;curl&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-fsSL&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;https://antigravity.google/cli/install.sh&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;bash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The installer places the &lt;code&gt;agy&lt;/code&gt; executable in a local &lt;code&gt;bin/&lt;/code&gt; directory, which is &lt;code&gt;~/.local/bin/&lt;/code&gt; on macOS and Linux. As part of the same run, the installer’s setup step also tries to wire up your &lt;a href=&quot;https://realpython.com/add-python-to-path/&quot;&gt;&lt;code&gt;PATH&lt;/code&gt;&lt;/a&gt; and shell profile for you.&lt;/p&gt;
&lt;p&gt;Open a new terminal session, or reload your shell profile, and then confirm that the installation worked by checking the version:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;agy&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--version
&lt;span class=&quot;go&quot;&gt;1.0.12&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;If you see a version number, then you’re ready to authenticate. Because it’s a single Go binary, Antigravity CLI updates itself in place whenever a newer release is available. But you can trigger that manually at any time with &lt;code&gt;agy update&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/antigravity-cli/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/antigravity-cli/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #304: Configuring a Versatile LLM Harness &amp; Scraping the Web With Scrapy</title>
      <id>https://realpython.com/podcasts/rpp/304/</id>
      <link href="https://realpython.com/podcasts/rpp/304/"/>
      <updated>2026-07-24T12:00:00+00:00</updated>
      <summary>Which is more important, the model or the &quot;harness&quot; around an LLM? What are ways to assemble an efficient agentic developer workflow? This week on the show, Ayan Pahwa joins us to discuss harnessing, web scraping, and self-hosting Python applications.</summary>
      <content type="html">
        &lt;p&gt;Which is more important, the model or the &quot;harness&quot; around an LLM? What are ways to assemble an efficient agentic developer workflow? This week on the show, Ayan Pahwa joins us to discuss harnessing, web scraping, and self-hosting Python applications.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Tool-Agnostic Python Lock Files With PEP 751 and pylock.toml</title>
      <id>https://realpython.com/python-lock-file-pylock-toml/</id>
      <link href="https://realpython.com/python-lock-file-pylock-toml/"/>
      <updated>2026-07-22T14:00:00+00:00</updated>
      <summary>Learn how PEP 751 standardizes Python lock files with pylock.toml: generate one with pip or uv, install it with uv or pdm, and retire requirements.txt.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;The Python lock file, &lt;code&gt;pylock.toml&lt;/code&gt;, records exact dependencies your project needs so installs come out the same every time. It isn’t the first of its kind, though—most modern package tools already define their own lock formats. This has led to a fragmented landscape where reproducibility is often limited to a single tool’s workflow, with each ecosystem effectively speaking its own lock file dialect.&lt;/p&gt;
&lt;p&gt;From this fragmentation comes a shared standard: &lt;code&gt;pylock.toml&lt;/code&gt;. Defined in &lt;a href=&quot;https://peps.python.org/pep-0751/&quot;&gt;PEP 751&lt;/a&gt;, &lt;code&gt;pylock.toml&lt;/code&gt; standardizes reproducible dependency management across different tools, eliminating vendor lock-in and fragmented &lt;code&gt;requirements.txt&lt;/code&gt; workflows. Its purpose is to capture a fully resolved set of dependencies in a format that every tool can understand.&lt;/p&gt;
&lt;p&gt;But doesn’t &lt;code&gt;requirements.txt&lt;/code&gt; already do this? Not exactly. &lt;code&gt;requirements.txt&lt;/code&gt; isn’t so much a &lt;em&gt;standardized specification&lt;/em&gt; as an implementation detail of &lt;code&gt;pip&lt;/code&gt;. The &lt;a href=&quot;https://pip.pypa.io/en/stable/reference/requirements-file-format/&quot;&gt;Requirements File Format&lt;/a&gt; specifies that “requirements files serve as a list of items to be installed by pip, when using pip install.”&lt;/p&gt;
&lt;p&gt;Still, both files exist to enumerate dependencies that should end up in an environment. The difference lies in how that information is represented, either as tool-specific instructions or as a structured, tool-agnostic record of a resolved state:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;If you…&lt;/strong&gt;&lt;/th&gt;
&lt;th class=&quot;text-center&quot;&gt;&lt;strong&gt;&lt;code&gt;pylock.toml&lt;/code&gt;&lt;/strong&gt;&lt;/th&gt;
&lt;th class=&quot;text-center&quot;&gt;&lt;strong&gt;&lt;code&gt;requirements.txt&lt;/code&gt;&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Want to share a single lock file with teammates who use different tools (&lt;code&gt;uv&lt;/code&gt;, &lt;code&gt;pip&lt;/code&gt;, &lt;code&gt;pdm&lt;/code&gt;)&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;✅&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need reproducible, hash-verified installs in CI&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;✅&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Want to install without resolving dependencies on the machine&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;✅&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need to pass &lt;code&gt;pip&lt;/code&gt; flags like &lt;code&gt;--index-url&lt;/code&gt; or &lt;code&gt;--no-deps&lt;/code&gt; from the file&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;—&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Want to jot down a couple of dependencies for a quick script by hand&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;—&lt;/td&gt;
&lt;td class=&quot;text-center&quot;&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;This means &lt;code&gt;pylock.toml&lt;/code&gt; is the better choice when you care about reproducibility across tools, the integrity of installed artifacts, or a single shared source of truth that can be consumed in different workflows. It’s especially useful in team settings or &lt;a href=&quot;https://realpython.com/python-continuous-integration/&quot;&gt;continuous integration (CI)&lt;/a&gt; pipelines where consistency matters more than manual control.&lt;/p&gt;
&lt;p&gt;In contrast, &lt;code&gt;requirements.txt&lt;/code&gt; remains a good fit for lightweight workflows, quick experiments, or cases where direct control over &lt;code&gt;pip&lt;/code&gt; behavior and flags is more important than cross-tool interoperability or strict locking guarantees.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-lock-file-pylock-toml-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-python-lock-file-pylock-toml-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; you’ll use to generate, inspect, and reuse pylock.toml lock files across pip, uv, and pdm.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Tool-Agnostic Python Lock Files With PEP 751 and pylock.toml” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/python-lock-file-pylock-toml/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #ffc973;&quot; alt=&quot;A person triumphantly raises a key in front of a vault labeled pylock.toml, with a rack of colored keys, wooden crates marked with hashes, and a Python chip alongside.&quot; src=&quot;https://files.realpython.com/media/Manage-Dependencies-with-Pythons-pylock.toml-Lock-File_Watermarked.94f86fd67ee8.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Manage-Dependencies-with-Pythons-pylock.toml-Lock-File_Watermarked.94f86fd67ee8.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Manage-Dependencies-with-Pythons-pylock.toml-Lock-File_Watermarked.94f86fd67ee8.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Manage-Dependencies-with-Pythons-pylock.toml-Lock-File_Watermarked.94f86fd67ee8.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Manage-Dependencies-with-Pythons-pylock.toml-Lock-File_Watermarked.94f86fd67ee8.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/python-lock-file-pylock-toml/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Tool-Agnostic Python Lock Files With PEP 751 and pylock.toml&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Test your understanding of Python lock files and PEP 751, from generating a pylock.toml with pip to installing it across uv and pdm.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;generating-a-python-lock-file-with-pip&quot;&gt;Generating a Python Lock File With &lt;code&gt;pip&lt;/code&gt;&lt;a class=&quot;headerlink&quot; href=&quot;#generating-a-python-lock-file-with-pip&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;With &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt; &lt;a href=&quot;https://pip.pypa.io/en/stable/news/#v25-1&quot;&gt;version 25.1&lt;/a&gt; or newer, you can generate a &lt;code&gt;pylock.toml&lt;/code&gt; file from a &lt;code&gt;requirements.txt&lt;/code&gt; file using the experimental &lt;a href=&quot;https://pip.pypa.io/en/stable/cli/pip_lock/&quot;&gt;&lt;code&gt;pip lock&lt;/code&gt;&lt;/a&gt; command. At its core, the &lt;code&gt;pylock.toml&lt;/code&gt; will serve as a snapshot of every &lt;a href=&quot;/ref/glossary/dependency/&quot; class=&quot;ref-link&quot;&gt;dependency&lt;/a&gt; &lt;code&gt;pip&lt;/code&gt; would install.&lt;/p&gt;
&lt;p&gt;Before you can use &lt;code&gt;pip lock&lt;/code&gt;, you’ll need to define a small set of explicit dependencies in a standard requirements file:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pyreq&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--grey&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python Requirements&lt;/span&gt;
    &lt;span class=&quot;me-2&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Filename: &lt;/span&gt;&lt;code style=&quot;color: inherit; background: inherit;&quot;&gt;requirements.txt&lt;/code&gt;&lt;/span&gt;
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;pandas&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;scipy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;This file expresses only the top-level &lt;a href=&quot;/ref/glossary/package/&quot; class=&quot;ref-link&quot;&gt;packages&lt;/a&gt; to be installed in your environment. It doesn’t describe how &lt;code&gt;pip&lt;/code&gt; resolves those packages or what additional dependencies they need to work.&lt;/p&gt;
&lt;p&gt;From here, you can have &lt;code&gt;pip&lt;/code&gt; produce a fully resolved lock file:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;lock&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;--requirement&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;requirements.txt
&lt;span class=&quot;go&quot;&gt;WARNING: pip lock is currently an experimental command. It may be&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;⮑ removed/changed in a future release without prior warning.&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Collecting pandas (from -r requirements.txt)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  Downloading pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Collecting scipy (from -r requirements.txt)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  Downloading scipy-1.17.1-cp314-cp314-manylinux_2_27_x86_64...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Collecting numpy&amp;gt;=2.3.3 (from pandas-&amp;gt;-r requirements.txt)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  Downloading numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Collecting python-dateutil&amp;gt;=2.8.2 (from pandas-&amp;gt;-r requirements.txt)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  Downloading python_dateutil-2.9.0.post0-py2.py3-none-any...&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;Collecting six&amp;gt;=1.5 (from python-dateutil&amp;gt;=2.8.2-&amp;gt;pandas-&amp;gt;-r requirements.txt)&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;  Downloading six-1.17.0-py2.py3-none-any.whl.metadata (1.7 kB)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;This triggers the resolution process. &lt;code&gt;pip&lt;/code&gt; builds a complete dependency graph starting from the explicit packages (&lt;code&gt;pandas&lt;/code&gt;, &lt;code&gt;scipy&lt;/code&gt;), resolves all required &lt;a href=&quot;/ref/glossary/transitive-dependency/&quot; class=&quot;ref-link&quot;&gt;transitive dependencies&lt;/a&gt;, and downloads compatible versions for the current Python environment and platform.&lt;/p&gt;
&lt;p&gt;This means the result contains both:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Explicit dependencies:&lt;/strong&gt; What you specified directly, like &lt;code&gt;pandas&lt;/code&gt; and &lt;code&gt;scipy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transitive dependencies:&lt;/strong&gt; What those packages require to function, like &lt;code&gt;numpy&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can explore that split for yourself in the interactive graph below. Start with only &lt;code&gt;pandas&lt;/code&gt; declared to see the full set it resolves to, then toggle &lt;code&gt;scipy&lt;/code&gt; on and watch your two requested packages expand into a larger set of pinned dependencies:&lt;/p&gt;
&lt;div&gt;
  &lt;widget-embed src=&quot;/widgets/pylock-resolve-graph/1782413260/&quot; slug=&quot;pylock-resolve-graph&quot; class=&quot;border rounded&quot; title=&quot;Where a Lock File&#x27;s Packages Come From&quot;&gt;
    &lt;div class=&quot;widget-embed__fallback&quot; data-widget-fallback&gt;
      Interactive diagram — enable JavaScript to view.
    &lt;/div&gt;
  &lt;/widget-embed&gt;
&lt;/div&gt;

&lt;p&gt;Pay attention to &lt;code&gt;numpy&lt;/code&gt; as you toggle &lt;code&gt;scipy&lt;/code&gt; on and off. The install log above attributes &lt;code&gt;numpy&lt;/code&gt; to &lt;code&gt;pandas&lt;/code&gt;, but &lt;code&gt;scipy&lt;/code&gt; depends on it too, so the resolver doesn’t lock it twice—it records a single, shared &lt;code&gt;numpy&lt;/code&gt; entry that satisfies both. That’s exactly what a lock file does for you: it turns the short list of packages you asked for into the complete, deduplicated set that will actually be installed.&lt;/p&gt;
&lt;p&gt;By capturing the complete dependency graph, &lt;code&gt;pylock.toml&lt;/code&gt; enables reproducible and verifiable installations across environments.&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/python-lock-file-pylock-toml/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/python-lock-file-pylock-toml/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: FastAPI: Python API Development With Light Speed</title>
      <id>https://realpython.com/learning-paths/fastapi/</id>
      <link href="https://realpython.com/learning-paths/fastapi/"/>
      <updated>2026-07-22T12:00:00+00:00</updated>
      <summary>Learn FastAPI from the ground up. Build REST APIs, serve web pages with Jinja2 templates, and create a complete URL shortener project in Python.</summary>
      <content type="html">
        &lt;p&gt;Learn FastAPI from the ground up. Build REST APIs, serve web pages with Jinja2 templates, and create a complete URL shortener project in Python.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Exploring Python&#x27;s Built-in Functions</title>
      <id>https://realpython.com/courses/exploring-pythons-built-in-functions/</id>
      <link href="https://realpython.com/courses/exploring-pythons-built-in-functions/"/>
      <updated>2026-07-21T14:00:00+00:00</updated>
      <summary>Learn Python&#x27;s built-in functions for math, data types, iterables, and I/O, and when to use each to write more Pythonic code.</summary>
      <content type="html">
        &lt;p&gt;Python&amp;rsquo;s &lt;strong&gt;built-in functions&lt;/strong&gt; are predefined functions you can use anywhere in your code without any imports. They handle common tasks across math, data type creation, iterable processing, and input and output. Knowing which ones to reach for makes your code shorter and more &lt;strong&gt;Pythonic&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In this video course, you&amp;rsquo;ll:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Recognize Python&amp;rsquo;s &lt;strong&gt;built-in functions&lt;/strong&gt; and the &lt;strong&gt;built-in scope&lt;/strong&gt; they live in&lt;/li&gt;
&lt;li&gt;Use the right built-in for &lt;strong&gt;tasks&lt;/strong&gt; involving &lt;strong&gt;math&lt;/strong&gt;, &lt;strong&gt;data types&lt;/strong&gt;, &lt;strong&gt;iterables&lt;/strong&gt;, and &lt;strong&gt;I/O&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Distinguish &lt;strong&gt;real functions&lt;/strong&gt; from &lt;strong&gt;classes&lt;/strong&gt; that only look like them&lt;/li&gt;
&lt;li&gt;Apply built-ins to solve &lt;strong&gt;practical problems&lt;/strong&gt; with less code you have to write yourself&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To get the most out of this video course, you&amp;rsquo;ll need to be familiar with Python programming, including topics like working with built-in &lt;a href=&quot;https://realpython.com/python-data-types/&quot;&gt;data types&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/defining-your-own-python-function/&quot;&gt;functions&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/python-classes/&quot;&gt;classes&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/primer-on-python-decorators/&quot;&gt;decorators&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/python-scope-legb-rule/&quot;&gt;scopes&lt;/a&gt;, and the &lt;a href=&quot;https://realpython.com/python-import/&quot;&gt;import&lt;/a&gt; system.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Using NumPy reshape() to Change the Shape of an Array</title>
      <id>https://realpython.com/numpy-reshape/</id>
      <link href="https://realpython.com/numpy-reshape/"/>
      <updated>2026-07-20T14:00:00+00:00</updated>
      <summary>Learn how to use NumPy reshape() in Python to change an array&#x27;s shape, add or remove dimensions, and control how the data is rearranged.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;The main data structure you’ll use in &lt;a href=&quot;https://realpython.com/numpy-tutorial/&quot;&gt;NumPy&lt;/a&gt;, Python’s core library for numerical computing, is the &lt;a href=&quot;https://numpy.org/doc/stable/reference/arrays.ndarray.html&quot;&gt;N-dimensional array&lt;/a&gt;. Sometimes you need to reorganize the values in a NumPy array into a different layout. That’s what NumPy’s &lt;strong&gt;&lt;code&gt;reshape()&lt;/code&gt;&lt;/strong&gt; is for. It changes an array’s shape without changing its data, so you can fit the same values into whatever configuration your program needs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You &lt;strong&gt;reshape a NumPy array&lt;/strong&gt; by passing a compatible shape to &lt;code&gt;.reshape()&lt;/code&gt;, which rearranges the data without changing its values.&lt;/li&gt;
&lt;li&gt;A new shape is &lt;strong&gt;compatible&lt;/strong&gt; only when its total number of elements matches the original array.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;reshape()&lt;/code&gt; can &lt;strong&gt;add or remove dimensions&lt;/strong&gt;, so the new array doesn’t need the same number of dimensions as the original.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;order&lt;/code&gt; parameter&lt;/strong&gt; sets whether the data is read in row-major (&lt;code&gt;&quot;C&quot;&lt;/code&gt;) or column-major (&lt;code&gt;&quot;F&quot;&lt;/code&gt;) order.&lt;/li&gt;
&lt;li&gt;Passing &lt;strong&gt;&lt;code&gt;-1&lt;/code&gt;&lt;/strong&gt; for one dimension lets &lt;code&gt;reshape()&lt;/code&gt; infer that dimension’s length automatically.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;a href=&quot;https://numpy.org/doc/stable/glossary.html#term-shape&quot;&gt;shape&lt;/a&gt; of an array describes the number of dimensions in the array and the length of each dimension. In this tutorial, you’ll learn how to reshape a NumPy array to place all its data in a different configuration. When you complete this tutorial, you’ll be able to alter the shape of any array to suit your application’s needs.&lt;/p&gt;
&lt;p&gt;For this tutorial, you should be familiar with the basics of NumPy and N-dimensional arrays. You can read &lt;a href=&quot;https://realpython.com/numpy-tutorial/&quot;&gt;NumPy Tutorial: Your First Steps Into Data Science in Python&lt;/a&gt; to learn more about NumPy before diving in.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Supplemental Material:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/numpy-reshape-repository/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-numpy-reshape-repository&quot; markdown&gt;Click here to download the supporting materials&lt;/a&gt; that you’ll use with NumPy &lt;code&gt;reshape()&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “Using NumPy reshape() to Change the Shape of an Array” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/numpy-reshape/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #abe5b2;&quot; alt=&quot;Using NumPy reshape() to Change the Shape of an Array&quot; src=&quot;https://files.realpython.com/media/How-to-Use-NumPys-reshape_Watermarked.88dac560fd74.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/How-to-Use-NumPys-reshape_Watermarked.88dac560fd74.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/How-to-Use-NumPys-reshape_Watermarked.88dac560fd74.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/How-to-Use-NumPys-reshape_Watermarked.88dac560fd74.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/How-to-Use-NumPys-reshape_Watermarked.88dac560fd74.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/numpy-reshape/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;Using NumPy reshape() to Change the Shape of an Array&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Practice NumPy reshape() by changing an array&#x27;s shape, adding or removing dimensions, and controlling how the data gets rearranged.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;install-numpy&quot;&gt;Install NumPy&lt;a class=&quot;headerlink&quot; href=&quot;#install-numpy&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You’ll need to install NumPy to your environment to run the code in this tutorial and explore &lt;code&gt;reshape()&lt;/code&gt;. You can install the package using &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt; within a &lt;a href=&quot;https://realpython.com/python-virtual-environments-a-primer/&quot;&gt;virtual environment&lt;/a&gt;. Select either the Windows or Linux + macOS tab below to see instructions for your operating system:&lt;/p&gt;
&lt;ul class=&quot;nav nav-tabs justify-content-end js-platform-widget-tabs&quot; role=&quot;tablist&quot;&gt;

  &lt;li class=&quot;nav-item mb-0 js-platform-widget-tab-windows&quot; role=&quot;presentation&quot;&gt;
    &lt;a class=&quot;nav-link link-unstyled text-body active small&quot; id=&quot;windows-tab-1&quot; data-bs-toggle=&quot;tab&quot; href=&quot;#windows-1&quot; role=&quot;tab&quot; aria-controls=&quot;windows-1&quot; aria-selected=&quot;true&quot;&gt;&lt;span class=&quot;icon baseline text-muted me-1&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#brands--windows&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;Windows&lt;/a&gt;
  &lt;/li&gt;




  &lt;li class=&quot;nav-item mb-0 js-platform-widget-tab-linuxmacos&quot; role=&quot;presentation&quot;&gt;
    &lt;a class=&quot;nav-link link-unstyled text-body small&quot; id=&quot;macos-tab-1&quot; data-bs-toggle=&quot;tab&quot; href=&quot;#linux-macos-1&quot; role=&quot;tab&quot; aria-controls=&quot;linux-macos-1&quot; aria-selected=&quot;false&quot;&gt;&lt;span class=&quot;icon baseline text-muted&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#v4--linux&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;span class=&quot;icon baseline text-muted me-1&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#v4--apple&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;Linux + macOS&lt;/a&gt;
  &lt;/li&gt;

&lt;/ul&gt;
&lt;div class=&quot;tab-content mt-2 mb-0 js-platform-widget-content&quot;&gt;
&lt;div aria-labelledby=&quot;windows-tab-1&quot; class=&quot;tab-pane fade show active&quot; id=&quot;windows-1&quot; role=&quot;tabpanel&quot;&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pscon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Windows PowerShell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;PS&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;venv&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;venv&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;PS&amp;gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.\&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;venv&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Scripts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;\&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;activate&lt;/span&gt;
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(venv)&lt;/span&gt; &lt;span class=&quot;gp&quot;&gt;PS&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;python&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pip&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;numpy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;/div&gt;
&lt;div aria-labelledby=&quot;linux-macos-tab-1&quot; class=&quot;tab-pane fade &quot; id=&quot;linux-macos-1&quot; role=&quot;tabpanel&quot;&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;venv&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;venv
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;venv/bin/activate
&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(venv)&lt;/span&gt; &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;numpy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;It’s a convention to use the alias &lt;code&gt;np&lt;/code&gt; when you import NumPy. To get started, you can import NumPy in the &lt;a href=&quot;https://realpython.com/python-repl/&quot;&gt;Python REPL&lt;/a&gt;:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;np&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Now that you’ve installed NumPy and imported the package in a REPL environment, you’re ready to start working with NumPy arrays.&lt;/p&gt;
&lt;h2 id=&quot;understand-the-shape-of-numpy-arrays&quot;&gt;Understand the Shape of NumPy Arrays&lt;a class=&quot;headerlink&quot; href=&quot;#understand-the-shape-of-numpy-arrays&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;You’ll use NumPy’s &lt;a href=&quot;https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html&quot;&gt;&lt;code&gt;ndarray&lt;/code&gt;&lt;/a&gt; in this tutorial. In this section, you’ll review the key features of this data structure, including an array’s overall &lt;a href=&quot;https://numpy.org/doc/stable/glossary.html#term-shape&quot;&gt;shape&lt;/a&gt; and number of &lt;a href=&quot;https://numpy.org/doc/stable/glossary.html#term-axis&quot;&gt;dimensions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can create an array from a list of lists:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;numpy&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;np&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;np&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]])&lt;/span&gt;
&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;array([[1, 2, 3, 4],&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;       [5, 6, 7, 8]])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;The function &lt;a href=&quot;https://numpy.org/doc/stable/reference/generated/numpy.array.html&quot;&gt;&lt;code&gt;np.array()&lt;/code&gt;&lt;/a&gt; returns an object of type &lt;a href=&quot;https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html&quot;&gt;&lt;code&gt;np.ndarray&lt;/code&gt;&lt;/a&gt;. This data structure is the main data type in NumPy.&lt;/p&gt;
&lt;p&gt;You can describe the shape of an array using the length of each dimension of the array. NumPy represents this as a tuple of integers. The array &lt;code&gt;numbers&lt;/code&gt; has two rows and four columns. Therefore, this array has a &lt;code&gt;(2, 4)&lt;/code&gt; shape:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;(2, 4)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;You can represent the same data using a different shape:&lt;/p&gt;
&lt;figure class=&quot;js-lightbox&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/numpy-reshape-24-42.679add5e8d11.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/numpy-reshape-24-42.679add5e8d11.png&quot; width=&quot;800&quot; height=&quot;800&quot; srcset=&quot;/cdn-cgi/image/width=200,format=auto/https://files.realpython.com/media/numpy-reshape-24-42.679add5e8d11.png 200w, /cdn-cgi/image/width=266,format=auto/https://files.realpython.com/media/numpy-reshape-24-42.679add5e8d11.png 266w, /cdn-cgi/image/width=400,format=auto/https://files.realpython.com/media/numpy-reshape-24-42.679add5e8d11.png 400w, /cdn-cgi/image/width=800,format=auto/https://files.realpython.com/media/numpy-reshape-24-42.679add5e8d11.png 800w&quot; sizes=&quot;(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)&quot; alt=&quot;Visual representation of NumPy arrays with different shapes&quot; data-asset=&quot;4894&quot;&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;p&gt;Both of these arrays contain the same data. The array with the shape &lt;code&gt;(2, 4)&lt;/code&gt; has two rows and four columns, and the array with the shape &lt;code&gt;(4, 2)&lt;/code&gt; has four rows and two columns. You can check the number of dimensions of an array using &lt;code&gt;.ndim&lt;/code&gt;:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;numbers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ndim&lt;/span&gt;
&lt;span class=&quot;go&quot;&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/numpy-reshape/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/numpy-reshape/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #303: Free-Threaded Python&#x27;s History &amp; uv in Production</title>
      <id>https://realpython.com/podcasts/rpp/303/</id>
      <link href="https://realpython.com/podcasts/rpp/303/"/>
      <updated>2026-07-17T12:00:00+00:00</updated>
      <summary>How many attempts have been made to remove Python&#x27;s Global Interpreter Lock (GIL)? How do they compare to the current approach? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.</summary>
      <content type="html">
        &lt;p&gt;How many attempts have been made to remove Python&#x27;s Global Interpreter Lock (GIL)? How do they compare to the current approach? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>How to Write a CLAUDE.md File for Claude Code</title>
      <id>https://realpython.com/python-claude-md/</id>
      <link href="https://realpython.com/python-claude-md/"/>
      <updated>2026-07-15T14:00:00+00:00</updated>
      <summary>Learn how to write a CLAUDE.md file for Claude Code, with global, project, and local examples that capture your Python commands and conventions.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;In this tutorial, you’ll write &lt;code&gt;CLAUDE.md&lt;/code&gt; files for Claude Code that capture your Python workflow, project commands, and coding rules. You’ll create a global file for personal defaults, a project-level file for repository guidance, and one for local notes that shouldn’t be committed to version control.&lt;/p&gt;
&lt;p&gt;To make these ideas concrete, you’ll work through a realistic example: steering Claude Code away from incorrect suggestions for AWS Bedrock global cross-region &lt;a href=&quot;/ref/ai-coding-glossary/inference/&quot; class=&quot;ref-link&quot;&gt;inference&lt;/a&gt;. You’ll turn that recurring correction into &lt;a href=&quot;https://code.claude.com/docs/en/best-practices#write-an-effective-claude-md&quot;&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;&lt;/a&gt; guidance and learn how to apply the same pattern to your project-specific rules, commands, and preferences that matter in your own codebase:&lt;/p&gt;
&lt;figure&gt;





&lt;div class=&quot;ratio rounded overflow-hidden mb-3 bg-body-tertiary&quot; style=&quot;aspect-ratio: 1920/1080;&quot;&gt;
  &lt;video-animation data-src=&quot;https://stream.realpython.com/0a55ebb7-2486-4991-8ba5-aab6b74452d8/playlist.m3u8&quot;&gt;
    &lt;video muted loop playsinline preload=&quot;none&quot; poster=&quot;https://stream.realpython.com/0a55ebb7-2486-4991-8ba5-aab6b74452d8/thumbnail.jpg?width=1280&quot; disablepictureinpicture disableremoteplayback&gt;&lt;/video&gt;
  &lt;/video-animation&gt;
&lt;/div&gt;


  &lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Claude Code Making Changes With Access to CLAUDE.md Instructions&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;A good &lt;code&gt;CLAUDE.md&lt;/code&gt; file doesn’t document everything about your project. Instead, it records commands, constraints, and workflow preferences that &lt;a href=&quot;/ref/ai-coding-tools/claude-code/&quot; class=&quot;ref-link&quot;&gt;Claude Code&lt;/a&gt; can’t easily infer from the repository. The aim is to prevent repeated corrections. You’re &lt;em&gt;not&lt;/em&gt; trying to teach Claude Code every detail of Python or your codebase.&lt;/p&gt;
&lt;p&gt;You can always use the &lt;code&gt;/init&lt;/code&gt; command as a starting point, but &lt;a href=&quot;https://arxiv.org/abs/2602.11988&quot;&gt;recent research&lt;/a&gt; found that unnecessarily large and redundant &lt;a href=&quot;/ref/ai-coding-glossary/context-engineering/&quot; class=&quot;ref-link&quot;&gt;context&lt;/a&gt; files often hurt &lt;a href=&quot;/ref/ai-coding-glossary/agent/&quot; class=&quot;ref-link&quot;&gt;agent&lt;/a&gt; performance and recommended keeping them minimal. This means the auto-generated &lt;code&gt;CLAUDE.md&lt;/code&gt; should usually be trimmed as it tends to repeat what Claude Code can already discover from the repo and can waste &lt;a href=&quot;/ref/ai-coding-glossary/token/&quot; class=&quot;ref-link&quot;&gt;tokens&lt;/a&gt; without gain.&lt;/p&gt;
&lt;p&gt;With that in mind, you can now build your &lt;code&gt;CLAUDE.md&lt;/code&gt; files: first your global defaults, then the project-specific rules, and finally any local notes you may have. Before you start writing, review the prerequisites below to prepare your environment to follow along.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Cheat Sheet:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-claude-md-cheatsheet/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-python-claude-md-cheatsheet&quot; markdown&gt;Click here to download a free PDF&lt;/a&gt; summarizing the patterns, pitfalls, and prompts for writing CLAUDE.md files that steer Claude Code through your Python projects.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “How to Write a CLAUDE.md File for Claude Code” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/python-claude-md/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #fe7e73;&quot; alt=&quot;A person and a robot beside a filing cabinet with drawers labeled GLOBAL, PROJECT, and LOCAL, next to a Python logo, a CLAUDE.md tag, and a screen labeled MEMORY with checklist items.&quot; src=&quot;https://files.realpython.com/media/How-to-Write-a-CLAUDE.md-File-for-Claude-Code_Watermarked.ea7aeffdb75e.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/How-to-Write-a-CLAUDE.md-File-for-Claude-Code_Watermarked.ea7aeffdb75e.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/How-to-Write-a-CLAUDE.md-File-for-Claude-Code_Watermarked.ea7aeffdb75e.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/How-to-Write-a-CLAUDE.md-File-for-Claude-Code_Watermarked.ea7aeffdb75e.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/How-to-Write-a-CLAUDE.md-File-for-Claude-Code_Watermarked.ea7aeffdb75e.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/python-claude-md/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;How to Write a CLAUDE.md File for Claude Code&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Practice writing CLAUDE.md files for Claude Code across global, project, and local layers that capture your Python commands and conventions.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;a class=&quot;headerlink&quot; href=&quot;#prerequisites&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;To follow along, you’ll need &lt;a href=&quot;https://realpython.com/courses/getting-started-claude-code/&quot;&gt;Claude Code installed and configured&lt;/a&gt;, a &lt;a href=&quot;/ref/code-editors-ides/&quot; class=&quot;ref-link&quot;&gt;text editor&lt;/a&gt; for creating Markdown files, plus a Python project or script that you can safely modify. You should also be familiar with how that project handles dependencies, tests, and any &lt;a href=&quot;/ref/glossary/linter/&quot; class=&quot;ref-link&quot;&gt;linting&lt;/a&gt; or formatting it uses.&lt;/p&gt;
&lt;p&gt;A concrete Python project or script makes this tutorial more useful. If you don’t already have one, then you can download the sample script below before continuing:&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/python-claude-md-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-python-claude-md-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; you’ll use to follow along as you write CLAUDE.md rules that steer Claude Code toward correct AWS Bedrock cross-region inference.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The example Python script uses &lt;a href=&quot;https://docs.aws.amazon.com/bedrock/&quot;&gt;AWS Bedrock&lt;/a&gt; with &lt;a href=&quot;https://docs.aws.amazon.com/boto3/latest/guide/quickstart.html&quot;&gt;&lt;code&gt;boto3&lt;/code&gt;&lt;/a&gt;, which requires Python 3.10 or higher. It also relies on &lt;a href=&quot;https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html&quot;&gt;configured AWS CLI credentials&lt;/a&gt; to generate output. That said, you don’t have to run the script to follow along. It’s enough to read the &lt;a href=&quot;/ref/ai-coding-glossary/prompt/&quot; class=&quot;ref-link&quot;&gt;prompt&lt;/a&gt; and Claude’s responses. Set up AWS only if you want to run it and play with it yourself.&lt;/p&gt;
&lt;p&gt;Later on in the tutorial, you’ll see a Bedrock-specific mistake made by Claude regarding the proper way to enable global cross-region inference for AWS Bedrock models. It’s a mistake where the code produced still works but isn’t entirely correct or what you intended. This type of error generalizes to any quirks or project-specific conventions in your own Python project or repo.&lt;/p&gt;
&lt;h2 id=&quot;step-1-audit-claude-codes-mistakes&quot;&gt;Step 1: Audit Claude Code’s Mistakes&lt;a class=&quot;headerlink&quot; href=&quot;#step-1-audit-claude-codes-mistakes&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Start by observing where Claude actually needs guidance. Don’t write &lt;code&gt;CLAUDE.md&lt;/code&gt; from a long list of your favorite Python rules, as that’s mostly unnecessary context. Run Claude Code on a small task in your project and watch for the repeated mistakes it makes.&lt;/p&gt;
&lt;p&gt;A short audit can often give you better instructions than a long checklist of rules or directives you think Claude Code needs. Try using this workflow before creating any instruction file for Claude Code:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Temporarily move existing global and project-level &lt;code&gt;CLAUDE.md&lt;/code&gt; and &lt;code&gt;CLAUDE.local.md&lt;/code&gt; files out of the way. You can rename them or move them out of their respective directories so Claude Code doesn’t pick them up. You can verify Claude Code hasn’t loaded them with the &lt;code&gt;/memory&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;Ask Claude Code to make a small change to your project.&lt;/li&gt;
&lt;li&gt;Record each correction you have to give.&lt;/li&gt;
&lt;li&gt;Sort each correction into global, project-level, or local guidance.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Look for knowledge that Claude Code can’t &lt;strong&gt;readily&lt;/strong&gt; and &lt;strong&gt;reliably&lt;/strong&gt; infer from reading your codebase. Build commands, test commands, environment variables, and team conventions are good starting points. Standard Python advice—apart from preferred defaults Claude may not follow—usually isn’t necessary because Anthropic models are already proficient at writing Python code, and such advice generally wastes tokens in a &lt;code&gt;CLAUDE.md&lt;/code&gt; file.&lt;/p&gt;
&lt;div class=&quot;alert alert-primary&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; What does &lt;strong&gt;readily&lt;/strong&gt; mean in this context? If Claude has to read numerous &lt;a href=&quot;/ref/glossary/source-code/&quot; class=&quot;ref-link&quot;&gt;source code&lt;/a&gt; files to figure out how to run the project or understand a particular repo convention, this is typically not considered to be “readily” discoverable and could warrant a line in &lt;code&gt;CLAUDE.md&lt;/code&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;It can still be beneficial to add your preferred Python defaults to &lt;code&gt;CLAUDE.md&lt;/code&gt;, but they should only be a small part of it.&lt;/p&gt;
&lt;p&gt;When auditing, note the correction, the scope, and the instruction you want Claude Code to follow. For example, you might notice the following corrections in a typical Python repo:&lt;/p&gt;
&lt;div class=&quot;table-responsive&quot;&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Repeated Correction&lt;/th&gt;
&lt;th&gt;Better Instruction&lt;/th&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code installed &lt;a href=&quot;/ref/glossary/package/&quot; class=&quot;ref-link&quot;&gt;packages&lt;/a&gt; imperatively with &lt;a href=&quot;/ref/glossary/pip/&quot; class=&quot;ref-link&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt; &lt;code&gt;install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add project dependencies with &lt;code&gt;uv add&lt;/code&gt;; use &lt;code&gt;uv pip install&lt;/code&gt; only for ad hoc env installs&lt;/td&gt;
&lt;td&gt;Global or project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code skipped the test command&lt;/td&gt;
&lt;td&gt;Run &lt;code&gt;uv run pytest&lt;/code&gt; before finishing a task&lt;/td&gt;
&lt;td&gt;Project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code added &lt;code&gt;print()&lt;/code&gt; debugging&lt;/td&gt;
&lt;td&gt;Use the configured logger&lt;/td&gt;
&lt;td&gt;Project&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code edited or created unrelated files&lt;/td&gt;
&lt;td&gt;Touch only files needed for the task&lt;/td&gt;
&lt;td&gt;Global&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Code opened broad files too early&lt;/td&gt;
&lt;td&gt;Use &lt;code&gt;rg&lt;/code&gt; to find relevant files before opening source files&lt;/td&gt;
&lt;td&gt;Global&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p&gt;While doing this exercise, use the following flowchart to decide when and where to add a rule:&lt;/p&gt;
&lt;figure class=&quot;js-lightbox&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/v3-claude-md-flowchart11.75cd97ace1fa.jpg&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block &quot; src=&quot;https://files.realpython.com/media/v3-claude-md-flowchart11.75cd97ace1fa.jpg&quot; width=&quot;3440&quot; height=&quot;1489&quot; srcset=&quot;/cdn-cgi/image/width=860,format=auto/https://files.realpython.com/media/v3-claude-md-flowchart11.75cd97ace1fa.jpg 860w, /cdn-cgi/image/width=1146,format=auto/https://files.realpython.com/media/v3-claude-md-flowchart11.75cd97ace1fa.jpg 1146w, /cdn-cgi/image/width=1720,format=auto/https://files.realpython.com/media/v3-claude-md-flowchart11.75cd97ace1fa.jpg 1720w, /cdn-cgi/image/width=3440,format=auto/https://files.realpython.com/media/v3-claude-md-flowchart11.75cd97ace1fa.jpg 3440w&quot; sizes=&quot;(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)&quot; alt=&quot;A flowchart showing whether or not to add a rule to CLAUDE.md&quot; data-asset=&quot;7065&quot;&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;Decision Chart for Adding Rules&lt;/figcaption&gt;&lt;/figure&gt;

&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/python-claude-md/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/python-claude-md/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Understanding Mixin Classes in Python</title>
      <id>https://realpython.com/courses/understanding-mixin-classes-in-python/</id>
      <link href="https://realpython.com/courses/understanding-mixin-classes-in-python/"/>
      <updated>2026-07-14T14:00:00+00:00</updated>
      <summary>Learn how to write reusable Python mixin classes, distinguish them from abstract base classes, and steer clear of common pitfalls.</summary>
      <content type="html">
        &lt;p&gt;Mixins offer a powerful way to reuse code across multiple Python classes without forcing them into a rigid inheritance hierarchy. Instead of building deep and brittle class trees, you can use mixins to share common behaviors in a modular and flexible way. Learn when and how to implement mixin classes effectively in your Python projects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this video course, you&amp;rsquo;ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mixins&lt;/strong&gt; allow you to add isolated, reusable functionalities to classes without enforcing a strict type hierarchy.&lt;/li&gt;
&lt;li&gt;Python has &lt;strong&gt;no dedicated syntax&lt;/strong&gt; for declaring mixins. You create mixins by defining &lt;strong&gt;classes&lt;/strong&gt; with specific behaviors that other classes can inherit without forming an &lt;em&gt;is-a&lt;/em&gt; relationship.&lt;/li&gt;
&lt;li&gt;Mixins rely on &lt;strong&gt;multiple inheritance&lt;/strong&gt; to combine features from different classes, enhancing flexibility and code reuse.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stateful mixins&lt;/strong&gt; require careful design to manage instance attributes and avoid conflicts with other classes.&lt;/li&gt;
&lt;li&gt;Python&amp;rsquo;s &lt;strong&gt;method resolution order (MRO)&lt;/strong&gt; determines the order in which classes are inherited, affecting how mixins are applied.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To get the most out of this video course, you should have a good understanding of &lt;a href=&quot;https://realpython.com/python3-object-oriented-programming/&quot;&gt;object-oriented programming (OOP)&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/solid-principles-python/&quot;&gt;SOLID principles&lt;/a&gt;, &lt;a href=&quot;https://realpython.com/inheritance-composition-python/&quot;&gt;inheritance&lt;/a&gt;, and &lt;a href=&quot;https://realpython.com/python-classes/&quot;&gt;Python classes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, what is a Python mixin, and when should you use one?&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>LangGraph Tutorial: Build Stateful AI Agents in Python</title>
      <id>https://realpython.com/langgraph-python/</id>
      <link href="https://realpython.com/langgraph-python/"/>
      <updated>2026-07-13T14:00:00+00:00</updated>
      <summary>Learn LangGraph in Python with hands-on examples and build stateful, multi-agent AI agents that manage memory, cycles, and complex LLM workflows.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;LangGraph is a versatile Python framework designed for stateful, cyclic, and multi-actor Large Language Model (LLM) applications. LangGraph builds upon its parent library, LangChain, and allows you to build sophisticated workflows that can handle the complexities of real-world LLM applications. Throughout this LangGraph tutorial, you’ll build a complete email-processing agent from the ground up.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this tutorial, you’ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can use LangGraph to build LLM workflows by &lt;strong&gt;defining state graphs with nodes and edges&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;LangGraph expands LangChain’s capabilities by providing tools to build complex LLM workflows with &lt;strong&gt;state, conditional edges, and cycles&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM agents&lt;/strong&gt; in LangGraph autonomously process tasks using state graphs to make decisions and interact with tools or APIs.&lt;/li&gt;
&lt;li&gt;You can use LangGraph independently of LangChain, although they’re often used together to complement each other.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Explore the full tutorial to gain hands-on experience with LangGraph, including setting up workflows and building a LangGraph agent that can autonomously parse emails, send emails, and interact with API services.&lt;/p&gt;
&lt;p&gt;While you’ll get a brief primer on &lt;a href=&quot;https://realpython.com/build-llm-rag-chatbot-with-langchain/&quot;&gt;LangChain&lt;/a&gt; in this tutorial, you’ll benefit from having prior knowledge of LangChain fundamentals. You’ll also want to ensure you have intermediate Python knowledge, specifically in &lt;a href=&quot;https://realpython.com/python3-object-oriented-programming/&quot;&gt;object-oriented programming&lt;/a&gt; concepts like classes and methods.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/langgraph-python-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-langgraph-python-code&quot; markdown&gt;Click here to download the free sample code &lt;/a&gt; that you’ll use to build stateful AI agents with LangGraph in Python.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “LangGraph: Build Stateful AI Agents in Python” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/langgraph-python/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #abe5b2;&quot; alt=&quot;LangGraph: Build Stateful AI Agents in Python&quot; src=&quot;https://files.realpython.com/media/Showcase-Langgraph_Watermarked.6435fda68bc4.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/Showcase-Langgraph_Watermarked.6435fda68bc4.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/Showcase-Langgraph_Watermarked.6435fda68bc4.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/Showcase-Langgraph_Watermarked.6435fda68bc4.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/Showcase-Langgraph_Watermarked.6435fda68bc4.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/langgraph-python/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;LangGraph: Build Stateful AI Agents in Python&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Test your understanding of LangGraph, the Python library for building stateful, cyclic, and multi-actor LLM workflows and agents built on LangChain.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;what-is-langgraph&quot;&gt;What Is LangGraph?&lt;a class=&quot;headerlink&quot; href=&quot;#what-is-langgraph&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;LangGraph is an open-source Python framework for building &lt;strong&gt;stateful&lt;/strong&gt;, &lt;strong&gt;cyclic&lt;/strong&gt;, and &lt;strong&gt;multi-agent&lt;/strong&gt; applications powered by large language models (LLMs). It gives you a low-level orchestration layer that represents an LLM application as a &lt;strong&gt;graph&lt;/strong&gt;: each step is a node, and the connections between steps are edges. Because the graph can branch and loop, you can model decision-making and repeated actions that a simple, linear pipeline can’t express.&lt;/p&gt;
&lt;p&gt;LangGraph is part of the LangChain ecosystem and integrates closely with &lt;a href=&quot;https://realpython.com/build-llm-rag-chatbot-with-langchain/&quot;&gt;LangChain&lt;/a&gt;, but it’s a standalone framework that you can also use on its own.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is LangGraph used for?&lt;/strong&gt; It shines whenever an LLM application needs to do more than answer a single prompt, including tasks like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Stateful workflows&lt;/strong&gt; that carry information forward from one step to the next&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Conditional logic&lt;/strong&gt; that routes the application down different paths depending on the data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cycles&lt;/strong&gt; that repeat a step until some condition is met&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AI agents&lt;/strong&gt; that decide which tools to call and act autonomously&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-agent systems&lt;/strong&gt; in which several agents coordinate to complete a larger task&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Throughout this tutorial, you’ll build these capabilities from the ground up as you create an email-processing agent. Before you start coding, you’ll install LangGraph and set up a few example emails to test your work.&lt;/p&gt;
&lt;h2 id=&quot;install-langgraph&quot;&gt;Install LangGraph&lt;a class=&quot;headerlink&quot; href=&quot;#install-langgraph&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;LangGraph is available on &lt;a href=&quot;https://pypi.org/&quot;&gt;PyPI&lt;/a&gt;, and you can install it with &lt;a href=&quot;https://realpython.com/what-is-pip/&quot;&gt;&lt;code&gt;pip&lt;/code&gt;&lt;/a&gt;. Open a terminal or command prompt, create a new virtual environment, and then run the following command:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(venv)&lt;/span&gt; &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;langgraph
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;This command will install the latest version of LangGraph from PyPI onto your machine. This tutorial was written for LangGraph 1.2, and the graph-building API that you’ll use here has been stable since the 1.0 long-term support release. To verify that the installation was successful, start a &lt;a href=&quot;https://realpython.com/python-repl/&quot;&gt;Python REPL&lt;/a&gt; and import LangGraph:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;pycon&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;langgraph&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;If the import runs without error, then you’ve successfully installed LangGraph. You’ll also need a few more libraries for this tutorial:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp gp-VirtualEnv&quot;&gt;(venv)&lt;/span&gt; &lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;python&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;-m&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;pip&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;install&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;langchain-openai&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;pydantic[email]&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;You’ll use &lt;code&gt;langchain-openai&lt;/code&gt; to interact with OpenAI LLMs, but keep in mind that you can use any LLM provider you like with LangGraph and LangChain. You’ll use &lt;a href=&quot;https://realpython.com/python-pydantic/&quot;&gt;&lt;code&gt;pydantic&lt;/code&gt;&lt;/a&gt; to validate the information your agent parses from emails.&lt;/p&gt;
&lt;p&gt;Before moving forward, if you choose to use OpenAI, make sure you’re signed up for an OpenAI account and that you have a valid &lt;a href=&quot;https://platform.openai.com/api-keys&quot;&gt;API key&lt;/a&gt;. You’ll need to set the following &lt;a href=&quot;https://en.wikipedia.org/wiki/Environment_variable&quot;&gt;environment variable&lt;/a&gt; before running any examples in this tutorial:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;dotenv&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--grey&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;.env&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;lt;YOUR-OPENAI-API-KEY&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Note that while LangGraph was made by the creators of LangChain and the two libraries are highly compatible, it’s possible to use LangGraph without LangChain. However, it’s more common to use LangChain and LangGraph together, and you’ll see throughout this tutorial how they complement each other.&lt;/p&gt;
&lt;p&gt;With that, you’ve installed all the dependencies you’ll need for this tutorial, and you’re ready to create your LangGraph email processor. Before diving in, you’ll take a brief detour to set up quick sanity tests for your app. Then, you’ll go through an overview of LangChain chains and explore LangGraph’s core concept, the state graph.&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/langgraph-python/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/langgraph-python/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #302: Constructing and Judging Modern Agentic Workflows</title>
      <id>https://realpython.com/podcasts/rpp/302/</id>
      <link href="https://realpython.com/podcasts/rpp/302/"/>
      <updated>2026-07-10T12:00:00+00:00</updated>
      <summary>How can you improve your LLM agent systems through specification enrichment? What are the advantages of having an LLM act as a judge within an agent system? This week on the show, Senior IEEE Member and Quality Engineer Suneet Malhotra joins us to discuss building and evaluating agentic architecture.</summary>
      <content type="html">
        &lt;p&gt;How can you improve your LLM agent systems through specification enrichment? What are the advantages of having an LLM act as a judge within an agent system? This week on the show, Senior IEEE Member and Quality Engineer Suneet Malhotra joins us to discuss building and evaluating agentic architecture.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>How to Use GitHub</title>
      <id>https://realpython.com/how-to-use-github/</id>
      <link href="https://realpython.com/how-to-use-github/"/>
      <updated>2026-07-08T14:00:00+00:00</updated>
      <summary>Learn how to use GitHub step by step to create a remote repository, push your local Python project, and collaborate with others using GitHub Issues.</summary>
      <content type="html">
        &lt;div&gt;&lt;p&gt;When you work on a local Python project, tracking your changes with Git is a great way to maintain a history of your code. However, keeping your repository only on your computer leaves your work vulnerable to hardware failures and makes collaboration difficult. By learning how to use GitHub, you can back up your work, share your code with the public, and work alongside other developers.&lt;/p&gt;
&lt;p&gt;By following this guide, you’ll learn how to create a GitHub repository, connect it to your local project, and collaborate with others online.&lt;/p&gt;
&lt;p&gt;Here’s a preview of what a successfully connected and active GitHub repository looks like:&lt;/p&gt;
&lt;figure class=&quot;js-lightbox&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/github-repository-added-screen.f0a878c30454.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/github-repository-added-screen.f0a878c30454.png&quot; width=&quot;1371&quot; height=&quot;903&quot; srcset=&quot;/cdn-cgi/image/width=342,format=auto/https://files.realpython.com/media/github-repository-added-screen.f0a878c30454.png 342w, /cdn-cgi/image/width=457,format=auto/https://files.realpython.com/media/github-repository-added-screen.f0a878c30454.png 457w, /cdn-cgi/image/width=685,format=auto/https://files.realpython.com/media/github-repository-added-screen.f0a878c30454.png 685w, /cdn-cgi/image/width=1371,format=auto/https://files.realpython.com/media/github-repository-added-screen.f0a878c30454.png 1371w&quot; sizes=&quot;(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)&quot; alt=&quot;GitHub repo pushed&quot; data-asset=&quot;6876&quot;&gt;&lt;/a&gt;&lt;figcaption class=&quot;figure-caption text-center&quot;&gt;GitHub Repository Pushed&lt;/figcaption&gt;&lt;/figure&gt;

&lt;p&gt;The screenshot above is your destination. In the rest of this tutorial, you’ll build that result one step at a time, starting from your local project.&lt;/p&gt;
&lt;div class=&quot;alert alert-warning&quot; role=&quot;alert&quot;&gt;
&lt;p&gt;&lt;strong markdown&gt;Get Your Code:&lt;/strong&gt; &lt;a href=&quot;https://realpython.com/bonus/how-to-use-github-code/&quot; class=&quot;alert-link&quot; data-bs-toggle=&quot;modal&quot; data-bs-target=&quot;#modal-how-to-use-github-code&quot; markdown&gt;Click here to download the free sample code&lt;/a&gt; you’ll use to follow along as you put a weather CLI app on GitHub and practice core workflows like commits, branches, pull requests, and issues.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;container border rounded text-wrap-pretty my-3&quot;&gt;

  &lt;p class=&quot;my-3&quot;&gt;&lt;mark class=&quot;marker-highlight&quot;&gt;&lt;strong&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt; Take the Quiz:&lt;/strong&gt;&lt;/mark&gt; Test your knowledge with our interactive “How to Use GitHub” quiz. You’ll receive a score upon completion to help you track your learning progress:&lt;/p&gt;

  &lt;hr&gt;

  &lt;div class=&quot;row my-3&quot;&gt;
    &lt;div class=&quot;col-12 col-sm-4 col-md-3 align-self-center&quot;&gt;

      &lt;a href=&quot;/quizzes/how-to-use-github/&quot; tabindex=&quot;-1&quot;&gt;
        &lt;div class=&quot;ratio ratio-16x9&quot;&gt;

            &lt;img class=&quot;card-img-top m-0 p-0 rounded&quot; style=&quot;object-fit: contain; background: #e5c6aa;&quot; alt=&quot;How to Use GitHub&quot; src=&quot;https://files.realpython.com/media/How-to-Use-GitHub.2542b35787ba.jpg&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/How-to-Use-GitHub.2542b35787ba.jpg 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/How-to-Use-GitHub.2542b35787ba.jpg 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/How-to-Use-GitHub.2542b35787ba.jpg 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/How-to-Use-GitHub.2542b35787ba.jpg 1920w&quot; sizes=&quot;(min-width: 1200px) 142px, (min-width: 1000px) 122px, (min-width: 780px) 112px, (min-width: 580px) 139px, calc(100vw - 62px)&quot;&gt;


          &lt;div class=&quot;card-img-overlay d-flex align-items-center&quot;&gt;
            &lt;div class=&quot;mx-auto&quot;&gt;
              &lt;span class=&quot;text-light&quot; style=&quot;opacity: 0.90;&quot;&gt;&lt;span class=&quot;icon baseline scale2x&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@quiz&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/a&gt;

    &lt;/div&gt;

    &lt;div class=&quot;col position-relative&quot;&gt;
      &lt;div class=&quot;mt-3 d-md-none&quot;&gt;&lt;/div&gt; 
      &lt;p class=&quot;small text-muted mb-0&quot;&gt;&lt;strong&gt;Interactive Quiz&lt;/strong&gt;&lt;/p&gt;
      &lt;a href=&quot;/quizzes/how-to-use-github/&quot; class=&quot;stretched-link&quot;&gt;&lt;span class=&quot;my-0 h4&quot;&gt;How to Use GitHub&lt;/span&gt;&lt;/a&gt; 
      &lt;p class=&quot;text-muted mb-0 small&quot;&gt;Practice putting a Python project on GitHub by creating a remote repository, pushing your local code, and collaborating with others.&lt;/p&gt;
    &lt;/div&gt;
  &lt;/div&gt;

&lt;/div&gt;

&lt;h2 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;a class=&quot;headerlink&quot; href=&quot;#prerequisites&quot; title=&quot;Permanent link&quot;&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;This guide is designed for developers who already have a basic understanding of the &lt;a href=&quot;/ref/glossary/command-line-interface/&quot; class=&quot;ref-link&quot;&gt;command line&lt;/a&gt; and local &lt;a href=&quot;/ref/best-practices/version-control/&quot; class=&quot;ref-link&quot;&gt;version control&lt;/a&gt;. To follow along with the steps, you’ll need:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A GitHub account:&lt;/strong&gt; A free account registered on &lt;a href=&quot;https://github.com/signup&quot;&gt;GitHub&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Git installed:&lt;/strong&gt; The &lt;a href=&quot;/ref/tools/git/&quot; class=&quot;ref-link&quot;&gt;Git&lt;/a&gt; command-line tools installed on your operating system.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A local Git repository:&lt;/strong&gt; A folder on your computer that contains some files and has been initialized with &lt;code&gt;git init&lt;/code&gt;. You should also have at least one saved commit in this local repository.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you need help setting up your local environment before moving forward, you can review the &lt;a href=&quot;https://realpython.com/how-to-use-git/&quot;&gt;How to Use Git: A Beginner’s Guide&lt;/a&gt; tutorial to get your local repository ready.&lt;/p&gt;
&lt;p&gt;If you prefer to learn by watching, Real Python’s &lt;a href=&quot;https://realpython.com/courses/python-git-github-intro/&quot;&gt;Introduction to Git and GitHub for Python&lt;/a&gt; video course walks through both tools from the ground up and pairs well with the hands-on steps in this guide.&lt;/p&gt;
&lt;p&gt;To work through the steps that follow, you can set up a sample Python project locally. Open your terminal, create a new folder called &lt;code&gt;weather-data-parser&lt;/code&gt;, and navigate inside it:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;mkdir&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;weather-data-parser
&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;weather-data-parser
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Create a new file named &lt;code&gt;weather.py&lt;/code&gt; and paste the Python code below into it. This weather app is adapted from Real Python’s &lt;a href=&quot;https://realpython.com/build-a-python-weather-app-cli/&quot;&gt;Raining Outside? Build a Weather CLI App With Python&lt;/a&gt; tutorial, which provides additional background and a full step-by-step walkthrough of the original project.&lt;/p&gt;
&lt;div class=&quot;card mb-3&quot; id=&quot;collapse_card02e9a2&quot;&gt;
&lt;div class=&quot;card-header border-0&quot;&gt;
&lt;p class=&quot;m-0&quot;&gt;
    &lt;button class=&quot;btn w-100&quot; data-bs-toggle=&quot;collapse&quot; data-bs-target=&quot;#collapse02e9a2&quot; aria-expanded=&quot;false&quot; aria-controls=&quot;collapse02e9a2&quot; markdown&gt;&lt;span class=&quot;float-start&quot; markdown&gt;Expand to View the &lt;code&gt;weather.py&lt;/code&gt; Source Code&lt;/span&gt;&lt;span class=&quot;float-end text-muted&quot;&gt;Show/Hide&lt;/span&gt;&lt;/button&gt;
  &lt;/p&gt;
&lt;/div&gt;
&lt;div class=&quot;collapse js-collapsible-section&quot; data-bs-parent=&quot;#collapse_card02e9a2&quot; id=&quot;collapse02e9a2&quot;&gt;
&lt;div class=&quot;card-body&quot;&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;python&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--blue&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Python&lt;/span&gt;
    &lt;span class=&quot;me-2&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Filename: &lt;/span&gt;&lt;code style=&quot;color: inherit; background: inherit;&quot;&gt;weather.py&lt;/code&gt;&lt;/span&gt;
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;argparse&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;json&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;configparser&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfigParser&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;urllib&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# =========================&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Styling / Colors&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =========================&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;PADDING&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;RED&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[1;31m&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;BLUE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[1;34m&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CYAN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[1;36m&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;GREEN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0;32m&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;YELLOW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[33m&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;WHITE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[37m&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;REVERSE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[;7m&quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;RESET&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[0m&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;change_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# =========================&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Weather Config&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =========================&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;BASE_WEATHER_API_URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;http://api.openweathermap.org/data/2.5/weather&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Weather Condition Codes&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;THUNDERSTORM&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;DRIZZLE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;RAIN&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;SNOW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;600&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;700&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ATMOSPHERE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;700&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CLEAR&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;801&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;CLOUDY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;801&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;900&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;read_user_cli_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&quot;&quot;Handles the CLI user interactions.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Returns:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        argparse.Namespace: Populated namespace object&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argparse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;gets weather and temperature information for a city&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nargs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;+&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;enter the city name&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_argument&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;-i&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;--imperial&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;store_true&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;display the temperature in imperial units&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;build_weather_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imperial&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&quot;&quot;Builds the URL for an API request to OpenWeather&#x27;s Weather API.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Args:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        city_input (List[str]): Name of a city as collected by argparse&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        imperial (bool): Whether or not to use imperial units for temperature&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Returns:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        str: URL formatted for a call to OpenWeather&#x27;s city name endpoint&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;api_key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_get_api_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;city_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city_input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;url_encoded_city_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;quote_plus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;units&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;imperial&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imperial&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;metric&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BASE_WEATHER_API_URL&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;?q=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url_encoded_city_name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;amp;units=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;units&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;amp;appid=&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;api_key&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;_get_api_key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&quot;&quot;Fetch the API key from your configuration file.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Expects a configuration file named &quot;secrets.ini&quot; with structure:&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;        [openweather]&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        api_key=&amp;lt;YOUR-OPENWEATHER-API-KEY&amp;gt;&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConfigParser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;secrets.ini&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;openweather&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;api_key&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;get_weather_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&quot;&quot;Makes an API request to a URL and returns the data as a Python object.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Args:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        query_url (str): URL formatted for OpenWeather&#x27;s city name endpoint&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Returns:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        dict: Weather information for a specific city&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;urlopen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HTTPError&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http_error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http_error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;401&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 401 - Unauthorized&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Access denied. Check your API key.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;http_error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;404&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# 404 - Not Found&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Can&#x27;t find weather data for this city.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Something went wrong... (&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;http_error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;code&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;loads&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;JSONDecodeError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Couldn&#x27;t read the server response.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;display_weather_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weather_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imperial&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&quot;&quot;Prints formatted weather information about a city.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Args:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        weather_data (dict): API response from OpenWeather by city name&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        imperial (bool): Whether or not to use imperial units for temperature&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    More information at https://openweathermap.org/current#name&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;city&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;weather_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;weather&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;weather_description&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;weather&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;temperature&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;][&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;temp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;change_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;REVERSE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PADDING&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;change_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RESET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;weather_symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_select_weather_display_params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weather_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;change_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weather_symbol&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weather_description&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;^&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PADDING&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;change_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RESET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temperature&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;°&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#x27;F&#x27;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imperial&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&#x27;C&#x27;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;)&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;_select_weather_display_params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weather_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
&lt;span class=&quot;w&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&quot;&quot;Selects a weather symbol and a display color for a weather state.&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Args:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        weather_id (int): Weather condition code from the OpenWeather API&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;    Returns:&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;        tuple[str]: Contains a weather symbol and a display color&lt;/span&gt;
&lt;span class=&quot;sd&quot;&gt;    &quot;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;THUNDERSTORM&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;display_params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;💥&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DRIZZLE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;display_params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;💧&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CYAN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RAIN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;display_params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;💦&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BLUE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SNOW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;display_params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;⛄️&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WHITE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ATMOSPHERE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;display_params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;🌀&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BLUE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CLEAR&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;display_params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;🔆&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;YELLOW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;weather_id&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CLOUDY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;display_params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;💨&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;WHITE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;# In case the API adds new weather codes&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;display_params&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;🌈&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RESET&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;display_params&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;vm&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;__main__&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;user_args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;read_user_cli_args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;query_url&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;build_weather_query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user_args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imperial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;weather_data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;get_weather_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;display_weather_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;weather_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user_args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;imperial&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Because this is a Python project, it’s best practice to include a &lt;code&gt;.gitignore&lt;/code&gt; file to avoid accidentally uploading sensitive information like &lt;a href=&quot;/ref/glossary/api/&quot; class=&quot;ref-link&quot;&gt;API&lt;/a&gt; keys or unnecessary files like &lt;code&gt;__pycache__&lt;/code&gt; directories to GitHub. Create a file named &lt;code&gt;.gitignore&lt;/code&gt; and add the following lines:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;config&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--grey&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Configuration File&lt;/span&gt;
    &lt;span class=&quot;me-2&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Filename: &lt;/span&gt;&lt;code style=&quot;color: inherit; background: inherit;&quot;&gt;.gitignore&lt;/code&gt;&lt;/span&gt;
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;__pycache__/
secrets.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Now initialize the Git repository:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;init
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;Before making your first commit, it’s often helpful to check what files Git is tracking and what changes will be included. You can do this with the &lt;code&gt;git status&lt;/code&gt; command:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;console&quot; data-is-repl=&quot;true&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--yellow&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Shell&lt;/span&gt;
    
    &lt;div class=&quot;noselect&quot;&gt;
      
        &lt;span class=&quot;codeblock__output-toggle&quot; title=&quot;Toggle prompts and output&quot; aria-label=&quot;Toggle prompts and output&quot; role=&quot;button&quot; tabindex=&quot;0&quot;&gt;&lt;span class=&quot;icon baseline js-codeblock-output-on codeblock__header--icon-lower&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#regular--rectangle-terminal&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/span&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class=&quot;gp&quot;&gt;$ &lt;/span&gt;git&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;status
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;This command shows the current state of your working directory, including any new or modified files that will be part of the next commit. At this point, you should see your project files, including &lt;code&gt;weather.py&lt;/code&gt; and &lt;code&gt;.gitignore&lt;/code&gt;, listed as untracked files:&lt;/p&gt;
&lt;code-block class=&quot;mb-3&quot; data-syntax-language=&quot;text&quot;&gt;
  &lt;div class=&quot;codeblock__header codeblock--grey&quot;&gt;
    &lt;span class=&quot;me-2 noselect&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Language: &lt;/span&gt;Text&lt;/span&gt;
    &lt;span class=&quot;me-2&quot;&gt;&lt;span class=&quot;visually-hidden&quot;&gt;Filename: &lt;/span&gt;&lt;code style=&quot;color: inherit; background: inherit;&quot;&gt;Output&lt;/code&gt;&lt;/span&gt;
    &lt;div class=&quot;noselect&quot;&gt;
      
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div class=&quot;codeblock__contents&quot;&gt;
    &lt;div class=&quot;highlight highlight--with-header&quot;&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;On branch master

No commits yet

Untracked files:
  (use &quot;git add &amp;lt;file&amp;gt;...&quot; to include in what will be committed)
        .gitignore
        weather.py

nothing added to commit but untracked files present (use &quot;git add&quot; to track)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
    
    &lt;button class=&quot;codeblock__copy btn btn-outline-secondary border m-1 px-1 d-hover-only&quot; title=&quot;Copy to clipboard&quot; aria-label=&quot;Copy to clipboard&quot;&gt;&lt;span class=&quot;icon baseline&quot; aria-hidden=&quot;true&quot;&gt;&lt;svg aria-hidden=&quot;true&quot;&gt;&lt;use href=&quot;/static/icons.769d3e9e5a0b.svg#@copy&quot;&gt;&lt;/use&gt;&lt;/svg&gt;&lt;/span&gt;&lt;/button&gt;
    
  &lt;/div&gt;
&lt;/code-block&gt;
&lt;p&gt;You can now stage your files and create the initial commit:&lt;/p&gt;
&lt;/div&gt;&lt;h2&gt;&lt;a href=&quot;https://realpython.com/how-to-use-github/?utm_source=realpython&amp;utm_medium=rss&quot;&gt;Read the full article at https://realpython.com/how-to-use-github/ »&lt;/a&gt;&lt;/h2&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Testing MCP Servers With a Python MCP Client</title>
      <id>https://realpython.com/courses/testing-mcp-servers-with-a-python-mcp-client/</id>
      <link href="https://realpython.com/courses/testing-mcp-servers-with-a-python-mcp-client/"/>
      <updated>2026-07-07T14:00:00+00:00</updated>
      <summary>Learn how to build a Python MCP client that tests MCP servers from your terminal. List their tools, prompts, and resources, then call each one.</summary>
      <content type="html">
        &lt;p&gt;Building an MCP client in Python is a great way to test MCP servers directly from your terminal. In this video course, you&amp;rsquo;ll build a minimal MCP client for the command line. It can connect to an MCP server through the standard input/output (stdio) transport, list the server&amp;rsquo;s capabilities, and interact with the server&amp;rsquo;s tools, prompts, and resources directly and deterministically.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You can build an &lt;strong&gt;MCP client&lt;/strong&gt; app for the command line using the &lt;strong&gt;MCP Python SDK&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You can connect a client to an MCP server through the &lt;strong&gt;stdio transport&lt;/strong&gt; and point it at any server from the command line.&lt;/li&gt;
&lt;li&gt;You can list a server&amp;rsquo;s capabilities by calling &lt;code&gt;.list_tools()&lt;/code&gt;, &lt;code&gt;.list_prompts()&lt;/code&gt;, and &lt;code&gt;.list_resources()&lt;/code&gt; on a &lt;code&gt;ClientSession&lt;/code&gt; instance.&lt;/li&gt;
&lt;li&gt;You can call &lt;strong&gt;tools&lt;/strong&gt;, get &lt;strong&gt;prompts&lt;/strong&gt;, and fetch &lt;strong&gt;resources&lt;/strong&gt; from an MCP server through dedicated CLI subcommands.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Next, you&amp;rsquo;ll move through setup, client structure, server connection, and capability discovery to test MCP servers from your terminal.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #301: Running Python Locally in a Sandbox</title>
      <id>https://realpython.com/podcasts/rpp/301/</id>
      <link href="https://realpython.com/podcasts/rpp/301/"/>
      <updated>2026-07-03T12:00:00+00:00</updated>
      <summary>How do you avoid the risk of running a Python application locally that could be malicious, break your code, or leak private data? How can you create a sandboxed local environment using WASM and MicroPython? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.</summary>
      <content type="html">
        &lt;p&gt;How do you avoid the risk of running a Python application locally that could be malicious, break your code, or leak private data? How can you create a sandboxed local environment using WASM and MicroPython? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Managing and Measuring Python Code Quality</title>
      <id>https://realpython.com/courses/managing-and-measuring-python-code-quality/</id>
      <link href="https://realpython.com/courses/managing-and-measuring-python-code-quality/"/>
      <updated>2026-06-30T14:00:00+00:00</updated>
      <summary>Master Python code quality tools like linters, formatters, type checkers, and profilers to measure, manage, and improve the code you write.</summary>
      <content type="html">
        &lt;p&gt;Producing high-quality Python code involves using appropriate &lt;strong&gt;tools&lt;/strong&gt; and consistently applying &lt;strong&gt;best practices&lt;/strong&gt;. High-quality code is functional, readable, maintainable, efficient, and secure. It adheres to established standards and has excellent documentation.&lt;/p&gt;
&lt;p&gt;You can achieve these qualities by following best practices such as descriptive naming, consistent coding style, modular design, and robust error handling. To help you with all this, you can use tools such as linters, formatters, and profilers.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Checking the quality of Python code&lt;/strong&gt; involves using tools like linters and static type checkers to ensure adherence to coding standards and detect potential errors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Writing quality code in Python&lt;/strong&gt; requires following best practices, such as clear naming conventions, modular design, and comprehensive testing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Good Python code&lt;/strong&gt; is characterized by readability, maintainability, efficiency, and adherence to standards like PEP 8.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Making Python code look good&lt;/strong&gt; involves using formatters to ensure consistent styling and readability, aligning with established coding styles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Making Python code readable&lt;/strong&gt; means using descriptive names for variables, functions, classes, modules, and packages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Enjoy working through this course as you learn more about the strategies, tools, and best practices that will help you write high-quality Python code.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #300: Maintaining Your Python Developer Instincts While Using LLM Tools</title>
      <id>https://realpython.com/podcasts/rpp/300/</id>
      <link href="https://realpython.com/podcasts/rpp/300/"/>
      <updated>2026-06-26T12:00:00+00:00</updated>
      <summary>Do you feel like your Python skills are atrophying after using LLM coding tools? How do you add the right kind of friction into your coding routine to keep your developer instincts sharp? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.</summary>
      <content type="html">
        &lt;p&gt;Do you feel like your Python skills are atrophying after using LLM coding tools? How do you add the right kind of friction into your coding routine to keep your developer instincts sharp? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Using LlamaIndex for RAG in Python</title>
      <id>https://realpython.com/courses/using-llamaindex-for-rag-in-python/</id>
      <link href="https://realpython.com/courses/using-llamaindex-for-rag-in-python/"/>
      <updated>2026-06-23T14:00:00+00:00</updated>
      <summary>Learn how to set up LlamaIndex, load your data, build and persist an index, and run queries to get grounded answers with RAG in Python.</summary>
      <content type="html">
        &lt;p&gt;Discover how to use LlamaIndex with practical examples. This framework helps you build retrieval-augmented generation (RAG) apps using Python. LlamaIndex lets you load your data and documents, create and persist searchable indexes, and query an LLM using your data as context.&lt;/p&gt;
&lt;p&gt;In this course, you&amp;rsquo;ll learn the basics of installing the package, setting AI providers, spinning up a query engine, and running queries against remote or local models.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll understand that:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You use &lt;strong&gt;LlamaIndex&lt;/strong&gt; to &lt;strong&gt;connect your data to LLMs&lt;/strong&gt;, allowing you to &lt;strong&gt;build AI agents&lt;/strong&gt;, &lt;strong&gt;workflows&lt;/strong&gt;, &lt;strong&gt;query engines&lt;/strong&gt;, and &lt;strong&gt;chat engines&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You can perform &lt;strong&gt;RAG&lt;/strong&gt; with LlamaIndex to retrieve relevant context at query time, helping the LLM generate &lt;strong&gt;grounded answers&lt;/strong&gt; and &lt;strong&gt;minimize hallucinations&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You&amp;rsquo;ll start by preparing your environment and installing LlamaIndex. From there, you&amp;rsquo;ll learn how to load your own files, build and save an index, choose different AI providers, and run targeted queries over your data through a query engine.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Building Python Skills for the Job Market</title>
      <id>https://realpython.com/courses/building-python-skills-for-the-job-market/</id>
      <link href="https://realpython.com/courses/building-python-skills-for-the-job-market/"/>
      <updated>2026-06-16T14:00:00+00:00</updated>
      <summary>Learn which Python skills employers value most and how to build them, using a skill roadmap worksheet, weekly practice plan, and interview prep tips.</summary>
      <content type="html">
        &lt;p&gt;When you&amp;rsquo;re learning Python, the sheer volume of topics to explore can feel overwhelming because there&amp;rsquo;s &lt;em&gt;so much&lt;/em&gt; you could focus on. Should you dive into web frameworks before exploring data science? Is test-driven development something you need right away? And which skills actually matter to employers in the age of AI-assisted software development?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;By the end of this course, you&amp;rsquo;ll have:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A clear understanding of which &lt;strong&gt;Python skills&lt;/strong&gt; employers consistently look for&lt;/li&gt;
&lt;li&gt;A personalized &lt;strong&gt;Python developer roadmap&lt;/strong&gt; showing where you are and where you need to go&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;weekly practice plan&lt;/strong&gt; that makes consistent progress feel achievable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Python itself is relatively beginner-friendly, but its versatility makes it easy to wander without direction. Without a clear plan, you can spend months studying topics that won&amp;rsquo;t help you land your first developer job.&lt;/p&gt;
&lt;p&gt;This course will show you how to build a focused learning strategy that aligns with real job market demands. You&amp;rsquo;ll learn how to research what employers value, assess your current strengths and gaps, and structure a practice routine that turns scattered study sessions into steady progress.&lt;/p&gt;
&lt;p&gt;Instead of guessing what to learn next, you&amp;rsquo;ll have a concrete document that shows you exactly where to focus:&lt;/p&gt;
&lt;figure class=&quot;js-lightbox&quot;&gt;&lt;a href=&quot;https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png&quot; target=&quot;_blank&quot;&gt;&lt;img loading=&quot;lazy&quot; class=&quot;img-fluid mx-auto d-block border &quot; src=&quot;https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png&quot; width=&quot;1920&quot; height=&quot;1080&quot; srcset=&quot;/cdn-cgi/image/width=480,format=auto/https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png 480w, /cdn-cgi/image/width=640,format=auto/https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png 640w, /cdn-cgi/image/width=960,format=auto/https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png 960w, /cdn-cgi/image/width=1920,format=auto/https://files.realpython.com/media/python-skills-worksheet-link.4e0ad67920ee.png 1920w&quot; sizes=&quot;(min-width: 1200px) 690px, (min-width: 780px) calc(-5vw + 669px), (min-width: 580px) 510px, calc(100vw - 30px)&quot; alt=&quot;The Python skills worksheet as a table with one row filled out and a link showing on hover&quot; data-asset=&quot;6692&quot;/&gt;&lt;/a&gt;&lt;/figure&gt;

&lt;p&gt;Work through this course to identify the skills you need and set yourself up for success.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #299: EuroPython 2026: Celebrating 25 Years</title>
      <id>https://realpython.com/podcasts/rpp/299/</id>
      <link href="https://realpython.com/podcasts/rpp/299/"/>
      <updated>2026-06-12T12:00:00+00:00</updated>
      <summary>What&#x27;s happening at EuroPython 2026? The conference celebrates its 25th anniversary this year in Kraków, Poland. This week on the show, organizers Mia Bajić and Daria Linhart Grudzien join me to discuss this year&#x27;s conference.</summary>
      <content type="html">
        &lt;p&gt;What&#x27;s happening at EuroPython 2026? The conference celebrates its 25th anniversary this year in Kraków, Poland. This week on the show, organizers Mia Bajić and Daria Linhart Grudzien join me to discuss this year&#x27;s conference.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Accessing Multiple AI Models With the OpenRouter API</title>
      <id>https://realpython.com/courses/multiple-ai-models-openrouter-api/</id>
      <link href="https://realpython.com/courses/multiple-ai-models-openrouter-api/"/>
      <updated>2026-06-09T14:00:00+00:00</updated>
      <summary>Access models from popular AI providers in Python through OpenRouter&#x27;s unified API with smart routing, fallbacks, and cost controls.</summary>
      <content type="html">
        &lt;p&gt;One of the quickest ways to call multiple AI models from a single Python script is to use OpenRouter&amp;rsquo;s API, which acts as a unified routing layer between your code and multiple AI providers. By the end of this course, you&amp;rsquo;ll be able to access models from several providers through one unified API.&lt;/p&gt;
&lt;p&gt;This convenience matters because the AI ecosystem is highly fragmented: each provider exposes its own API, authentication scheme, rate limits, and model lineup. Working with multiple providers often requires additional setup and integration effort, especially when you want to experiment with different models, compare outputs, or evaluate trade-offs for a specific task.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://openrouter.ai/&quot;&gt;OpenRouter&lt;/a&gt; gives you access to thousands of models from leading providers like OpenAI, Anthropic, Mistral, Google, and Meta. You can switch between them without changing your application code.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #298: Reducing the Size of Python Docker Containers</title>
      <id>https://realpython.com/podcasts/rpp/298/</id>
      <link href="https://realpython.com/podcasts/rpp/298/"/>
      <updated>2026-06-05T12:00:00+00:00</updated>
      <summary>How can you easily reduce the size of a Python Docker container? What are the exceptions you should catch in your code? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.</summary>
      <content type="html">
        &lt;p&gt;How can you easily reduce the size of a Python Docker container? What are the exceptions you should catch in your code? Christopher Trudeau is back on the show this week with another batch of PyCoder&#x27;s Weekly articles and projects.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>The Real Python Podcast – Episode #297: Improving Python Through PEPs and Protocols</title>
      <id>https://realpython.com/podcasts/rpp/297/</id>
      <link href="https://realpython.com/podcasts/rpp/297/"/>
      <updated>2026-05-29T12:00:00+00:00</updated>
      <summary>Have you ever been confused by the naming of modules you&#x27;re importing from a package? Is there a standard way to organize and name your Python virtual environments? This week on the show, Brett Cannon returns to discuss the Python Enhancement Proposals (PEPs) he&#x27;s been working on recently.</summary>
      <content type="html">
        &lt;p&gt;Have you ever been confused by the naming of modules you&#x27;re importing from a package? Is there a standard way to organize and name your Python virtual environments? This week on the show, Brett Cannon returns to discuss the Python Enhancement Proposals (PEPs) he&#x27;s been working on recently.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Python Game Development</title>
      <id>https://realpython.com/learning-paths/python-game-development/</id>
      <link href="https://realpython.com/learning-paths/python-game-development/"/>
      <updated>2026-04-16T12:00:00+00:00</updated>
      <summary>Build Python games from command-line projects to 2D graphical games with turtle, Tkinter, Pygame, and Arcade.</summary>
      <content type="html">
        &lt;p&gt;Build Python games from command-line projects to 2D graphical games with turtle, Tkinter, Pygame, and Arcade.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: LLM Application Development With Python</title>
      <id>https://realpython.com/learning-paths/llm-application-development-python/</id>
      <link href="https://realpython.com/learning-paths/llm-application-development-python/"/>
      <updated>2026-03-19T12:00:00+00:00</updated>
      <summary>Build LLM-powered applications in Python. Call model APIs, craft prompts, add retrieval-augmented generation, create AI agents, and connect via MCP.</summary>
      <content type="html">
        &lt;p&gt;Build LLM-powered applications in Python. Call model APIs, craft prompts, add retrieval-augmented generation, create AI agents, and connect via MCP.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Python Coding With AI</title>
      <id>https://realpython.com/learning-paths/coding-with-ai/</id>
      <link href="https://realpython.com/learning-paths/coding-with-ai/"/>
      <updated>2025-12-07T12:00:00+00:00</updated>
      <summary>Use AI coding assistants to write, review, and debug Python code faster. Choose an editor-based assistant like Cursor or a terminal-based one like Claude Code, then make it part of your daily workflow.</summary>
      <content type="html">
        &lt;p&gt;Use AI coding assistants to write, review, and debug Python code faster. Choose an editor-based assistant like Cursor or a terminal-based one like Claude Code, then make it part of your daily workflow.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Perfect Your Python Development Setup</title>
      <id>https://realpython.com/learning-paths/perfect-your-python-development-setup/</id>
      <link href="https://realpython.com/learning-paths/perfect-your-python-development-setup/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Set up a Python development environment with VS Code, PyCharm, virtual environments, Git, pyenv, Docker, and AI coding tools like Claude Code and Cursor.</summary>
      <content type="html">
        &lt;p&gt;Set up a Python development environment with VS Code, PyCharm, virtual environments, Git, pyenv, Docker, and AI coding tools like Claude Code and Cursor.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Important Standard Library Modules</title>
      <id>https://realpython.com/learning-paths/standard-library-modules-you-should-know/</id>
      <link href="https://realpython.com/learning-paths/standard-library-modules-you-should-know/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Explore Python standard library modules including math, datetime, JSON, CSV, regex, subprocess, and argparse through hands-on tutorials and courses.</summary>
      <content type="html">
        &lt;p&gt;Explore Python standard library modules including math, datetime, JSON, CSV, regex, subprocess, and argparse through hands-on tutorials and courses.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Functions and Scopes</title>
      <id>https://realpython.com/learning-paths/functions-and-scopes/</id>
      <link href="https://realpython.com/learning-paths/functions-and-scopes/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Learn to define Python functions, use parameters and return values, create inner functions, and understand namespaces and scope.</summary>
      <content type="html">
        &lt;p&gt;Learn to define Python functions, use parameters and return values, create inner functions, and understand namespaces and scope.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Create Graphical User Interfaces (GUI)</title>
      <id>https://realpython.com/learning-paths/python-gui-programming/</id>
      <link href="https://realpython.com/learning-paths/python-gui-programming/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Build Python GUI applications with Tkinter, PyQt, wxPython, and Kivy. Learn layouts, event handling, threading, and database integration.</summary>
      <content type="html">
        &lt;p&gt;Build Python GUI applications with Tkinter, PyQt, wxPython, and Kivy. Learn layouts, event handling, threading, and database integration.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Network Programming and Security</title>
      <id>https://realpython.com/learning-paths/network-programming-and-security/</id>
      <link href="https://realpython.com/learning-paths/network-programming-and-security/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Learn network programming and security in Python. Work with CRUD operations, REST APIs, HTTPS, and socket programming to build networked apps.</summary>
      <content type="html">
        &lt;p&gt;Learn network programming and security in Python. Work with CRUD operations, REST APIs, HTTPS, and socket programming to build networked apps.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  
    <entry>
      <title>Learning Path: Python Control Flow and Loops</title>
      <id>https://realpython.com/learning-paths/python-control-flow-and-loops/</id>
      <link href="https://realpython.com/learning-paths/python-control-flow-and-loops/"/>
      <updated>2024-11-14T12:00:00+00:00</updated>
      <summary>Learn Python control flow and loops. Use conditional statements, Boolean operators, for and while loops, and keywords like break and continue.</summary>
      <content type="html">
        &lt;p&gt;Learn Python control flow and loops. Use conditional statements, Boolean operators, for and while loops, and keywords like break and continue.&lt;/p&gt;
        &lt;hr /&gt;
        &lt;p&gt;&lt;em&gt;[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short &amp;amp; sweet Python Trick delivered to your inbox every couple of days. &lt;a href=&quot;https://realpython.com/python-tricks/?utm_source=realpython&amp;amp;utm_medium=rss&amp;amp;utm_campaign=footer&quot;&gt;&amp;gt;&amp;gt; Click here to learn more and see examples&lt;/a&gt; ]&lt;/em&gt;&lt;/p&gt;
      </content>
    </entry>
  

</feed>
