skip to navigation
skip to content

Planet Python

Last update: April 27, 2026 09:43 PM UTC

April 27, 2026


Python Engineering at Microsoft

Python Environments Extension for VS Code- April Update

Python Environments — April 2026 Release

We’re excited to announce the latest update to the Python Environments extension for Visual Studio Code. This release focuses on startup performance, reliability, and quality-of-life improvements for terminals and package management.

Faster startup

Activation is now noticeably snappier, especially on remote and containerized workspaces. We made three key changes:

Lazy manager discovery. Pipenv, pyenv, and poetry environments are no longer discovered eagerly on startup. Instead, detection is deferred until you actually interact with one of those managers — for example, by opening a project that uses a Pipfile or pyproject.toml with a poetry backend. This eliminates unnecessary work for the majority of users who rely on venv, uv, or conda. (#1423, #1408)

Faster environment resolution. The path from “extension activated” to “interpreter ready” is shorter. Resolution during startup and interpreter selection now completes with less overhead. (#1419)

Narrower default workspace scanning. The default search pattern for virtual environments was ./**/.venv, which triggered a recursive scan of the entire workspace tree. On large projects — and especially over Remote-SSH — this could cause the Python Environment Tools (PET) process to hang for 30+ seconds during configuration, leading to cascading timeouts and restart loops (see #1460, #1434). The default is now .venv and */.venv, which covers the standard layout without deep traversal. If you have virtual environments nested more than one level deep, you can add custom paths via the python-envs.workspaceSearchPaths setting. (#1419)

Improved reliability

PET crash recovery. When the PET process crashed mid-refresh, the extension could end up in a broken state with no environments visible. We now retry the refresh after a crash and handle empty or malformed responses defensively, so a transient PET failure no longer leaves you with a blank environment list. (#1442, #1447, #1444)

Conda base environment fix. After a window reload, the conda base environment could be incorrectly restored as a different named environment — making it appear that your interpreter selection had silently changed. This is now fixed. (#1412)

Environment updates and terminals

Auto-refreshing package lists. You no longer need to manually refresh the package view after running pip install or pip uninstall. The extension now watches for metadata changes in site-packages and updates the package list automatically. (#1420)

Multi-project terminal creation. In workspaces with multiple Python projects, creating a new terminal now prompts you to choose which project’s environment to activate, rather than picking one silently. (#1401)

PowerShell activation on Windows. Virtual environment activation via PowerShell could fail if the system execution policy blocked scripts. The extension now sets a process-scoped execution policy before running activation, so .ps1 activate scripts work out of the box without requiring system-wide policy changes. (#1414)


Try the update today and let us know how it works for you. If you run into issues, please file them on GitHub.

The post Python Environments Extension for VS Code- April Update appeared first on Microsoft for Python Developers Blog.

April 27, 2026 08:07 PM UTC


Talk Python to Me

#546: Self hosting apps for Python people

The cloud is convenient until it isn't. You upload your photos, sync your contacts, click through the cookie banners. Then prices go up again or you read about a family that lost their entire Google account over a medical photo sent to a doctor. At some point, the question shifts from "why would I run this myself?" to "why aren't I?" <br/> <br/> My guest this week is Alex Kretzschmar, head of DevRel at Tailscale, longtime host of the Self-Hosted podcast, and co-founder of Linuxserver.io. We cover what self-hosting really means in 2026, the apps worth running yourself like Immich and Home Assistant, why Docker Compose ties it all together, and how Tailscale lets you reach any of it from anywhere, without opening a single port. If you've been thinking about pulling your digital life back behind your own walls, this is your roadmap.<br/> <br/> <strong>Episode sponsors</strong><br/> <br/> <a href='/proxy?url=https%3A%2F%2Ftalkpython.fm%2Ftemporal-replay'>Temporal</a><br> <a href='/proxy?url=https%3A%2F%2Ftalkpython.fm%2Ftraining'>Talk Python Courses</a><br/> <br/> <h2 class="links-heading mb-4">Links from the show</h2> <div><strong>Guest</strong><br/> <strong>Alex Kretzschmar</strong>: <a href="/proxy?url=https%3A%2F%2Falex.ktz.me%2F%3Ffeatured_on%3Dtalkpython" target="_blank" >alex.ktz.me</a><br/> <br/> <strong>Bitflip podcast</strong>: <a href="/proxy?url=https%3A%2F%2Fbitflip.show%3Ffeatured_on%3Dtalkpython" target="_blank" >bitflip.show</a><br/> <strong>Self-Hosted podcast (Alex's previous show)</strong>: <a href="/proxy?url=https%3A%2F%2Fselfhosted.show%3Ffeatured_on%3Dtalkpython" target="_blank" >selfhosted.show</a><br/> <strong>Perfect Media Server</strong>: <a href="/proxy?url=https%3A%2F%2Fperfectmediaserver.com%3Ffeatured_on%3Dtalkpython" target="_blank" >perfectmediaserver.com</a><br/> <strong>KTZ Systems on YouTube</strong>: <a href="/proxy?url=https%3A%2F%2Fyoutube.com%2F%40ktzsystems" target="_blank" >youtube.com/@ktzsystems</a><br/> <strong>Linuxserver.io (co-founded by Alex)</strong>: <a href="/proxy?url=https%3A%2F%2Flinuxserver.io%3Ffeatured_on%3Dtalkpython" target="_blank" >linuxserver.io</a><br/> <strong>"How Tailscale Works" blog post</strong>: <a href="/proxy?url=https%3A%2F%2Ftailscale.com%2Fblog%2Fhow-tailscale-works%3Ffeatured_on%3Dtalkpython" target="_blank" >tailscale.com/blog/how-tailscale-works</a><br/> <strong>https://tailscale.com/</strong>: <a href="/proxy?url=https%3A%2F%2Ftailscale.com%2F%3Ffeatured_on%3Dtalkpython" target="_blank" >tailscale.com</a><br/> <br/> <strong>Self-hosted apps discussed</strong><br/> <strong>Awesome Self-Hosted (GitHub list)</strong>: <a href="/proxy?url=https%3A%2F%2Fgithub.com%2Fawesome-selfhosted%2Fawesome-selfhosted%3Ffeatured_on%3Dtalkpython" target="_blank" >github.com</a><br/> <strong>Immich (Google Photos alternative)</strong>: <a href="/proxy?url=https%3A%2F%2Fimmich.app%3Ffeatured_on%3Dtalkpython" target="_blank" >immich.app</a><br/> <strong>Home Assistant</strong>: <a href="/proxy?url=https%3A%2F%2Fhome-assistant.io%3Ffeatured_on%3Dtalkpython" target="_blank" >home-assistant.io</a><br/> <strong>Open Home Foundation</strong>: <a href="/proxy?url=https%3A%2F%2Fopenhomefoundation.org%3Ffeatured_on%3Dtalkpython" target="_blank" >openhomefoundation.org</a><br/> <strong>Plausible Analytics</strong>: <a href="/proxy?url=https%3A%2F%2Fplausible.io%3Ffeatured_on%3Dtalkpython" target="_blank" >plausible.io</a><br/> <strong>Umami Analytics</strong>: <a href="/proxy?url=https%3A%2F%2Fumami.is%3Ffeatured_on%3Dtalkpython" target="_blank" >umami.is</a><br/> <strong>Python integration for umami</strong>: <a href="/proxy?url=https%3A%2F%2Fpypi.org%2Fproject%2Fumami-analytics%2F%3Ffeatured_on%3Dtalkpython" target="_blank" >pypi.org</a><br/> <strong>Pi-hole</strong>: <a href="/proxy?url=https%3A%2F%2Fpi-hole.net%3Ffeatured_on%3Dtalkpython" target="_blank" >pi-hole.net</a><br/> <strong>AdGuard Home</strong>: <a href="/proxy?url=https%3A%2F%2Fadguard.com%2Fadguard-home%3Ffeatured_on%3Dtalkpython" target="_blank" >adguard.com</a><br/> <strong>NextDNS</strong>: <a href="/proxy?url=https%3A%2F%2Fnextdns.io%3Ffeatured_on%3Dtalkpython" target="_blank" >nextdns.io</a><br/> <strong>Coolify</strong>: <a href="/proxy?url=https%3A%2F%2Fcoolify.io%3Ffeatured_on%3Dtalkpython" target="_blank" >coolify.io</a><br/> <strong>Docker + ufw</strong>: <a href="/proxy?url=https%3A%2F%2Fdocs.docker.com%2Fengine%2Fnetwork%2Fpacket-filtering-firewalls%2F%23docker-and-ufw" target="_blank" >docs.docker.com</a><br/> <br/> <strong>Storage, backup &amp; filesystem</strong><br/> <strong>OpenZFS</strong>: <a href="/proxy?url=https%3A%2F%2Fopenzfs.org%3Ffeatured_on%3Dtalkpython" target="_blank" >openzfs.org</a><br/> <strong>ZFS.rent (offsite ZFS replication)</strong>: <a href="/proxy?url=https%3A%2F%2Fzfs.rent%3Ffeatured_on%3Dtalkpython" target="_blank" >zfs.rent</a><br/> <strong>Backblaze</strong>: <a href="/proxy?url=https%3A%2F%2Fbackblaze.com%3Ffeatured_on%3Dtalkpython" target="_blank" >backblaze.com</a><br/> <strong>Hetzner Storage Box</strong>: <a href="/proxy?url=https%3A%2F%2Fhetzner.com%2Fstorage%2Fstorage-box%3Ffeatured_on%3Dtalkpython" target="_blank" >hetzner.com</a><br/> <strong>DigitalOcean</strong>: <a href="/proxy?url=https%3A%2F%2Fdigitalocean.com%3Ffeatured_on%3Dtalkpython" target="_blank" >digitalocean.com</a><br/> <br/> <strong>Secrets management mentioned</strong><br/> <strong>OpenBao (open-source Vault fork)</strong>: <a href="/proxy?url=https%3A%2F%2Fopenbao.org%3Ffeatured_on%3Dtalkpython" target="_blank" >openbao.org</a><br/> <strong>HashiCorp Vault</strong>: <a href="/proxy?url=https%3A%2F%2Fhashicorp.com%2Fproducts%2Fvault%3Ffeatured_on%3Dtalkpython" target="_blank" >hashicorp.com</a><br/> <strong>Bitwarden</strong>: <a href="/proxy?url=https%3A%2F%2Fbitwarden.com%3Ffeatured_on%3Dtalkpython" target="_blank" >bitwarden.com</a><br/> <strong>1Password</strong>: <a href="/proxy?url=https%3A%2F%2F1password.com%3Ffeatured_on%3Dtalkpython" target="_blank" >1password.com</a><br/> <br/> <strong>Hardware mentioned</strong><br/> <strong>Proxmox VE</strong>: <a href="/proxy?url=https%3A%2F%2Fproxmox.com%3Ffeatured_on%3Dtalkpython" target="_blank" >proxmox.com</a><br/> <strong>Minisforum MS01</strong>: <a href="/proxy?url=https%3A%2F%2Fminisforum.com%3Ffeatured_on%3Dtalkpython" target="_blank" >minisforum.com</a><br/> <strong>Zima Board / Zima OS</strong>: <a href="/proxy?url=https%3A%2F%2Fzimaspace.com%3Ffeatured_on%3Dtalkpython" target="_blank" >zimaspace.com</a><br/> <br/> <strong>Other references</strong><br/> <strong>Cory Doctorow on "enshittification" (Cory's blog where he coined the term)</strong>: <a href="/proxy?url=https%3A%2F%2Fpluralistic.net%3Ffeatured_on%3Dtalkpython" target="_blank" >pluralistic.net</a><br/> <strong>Linus Tech Tips' WAN Show (Linus mentioned NAS-building going mainstream)</strong>: <a href="/proxy?url=https%3A%2F%2Flinustechtips.com%3Ffeatured_on%3Dtalkpython" target="_blank" >linustechtips.com</a><br/> <br/> <strong>Watch this episode on YouTube</strong>: <a href="/proxy?url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D1iAQRY7hiVA" target="_blank" >youtube.com</a><br/> <strong>Episode #546 deep-dive</strong>: <a href="/proxy?url=https%3A%2F%2Ftalkpython.fm%2Fepisodes%2Fshow%2F546%2Fself-hosting-apps-for-python-people%23takeaways-anchor" target="_blank" >talkpython.fm/546</a><br/> <strong>Episode transcripts</strong>: <a href="/proxy?url=https%3A%2F%2Ftalkpython.fm%2Fepisodes%2Ftranscript%2F546%2Fself-hosting-apps-for-python-people" target="_blank" >talkpython.fm</a><br/> <br/> <strong>Theme Song: Developer Rap</strong><br/> <strong>🥁 Served in a Flask 🎸</strong>: <a href="/proxy?url=https%3A%2F%2Ftalkpython.fm%2Fflasksong" target="_blank" >talkpython.fm/flasksong</a><br/> <br/> <strong>---== Don't be a stranger ==---</strong><br/> <strong>YouTube</strong>: <a href="/proxy?url=https%3A%2F%2Ftalkpython.fm%2Fyoutube" target="_blank" ><i class="fa-brands fa-youtube"></i> youtube.com/@talkpython</a><br/> <br/> <strong>Bluesky</strong>: <a href="/proxy?url=https%3A%2F%2Fbsky.app%2Fprofile%2Ftalkpython.fm" target="_blank" >@talkpython.fm</a><br/> <strong>Mastodon</strong>: <a href="/proxy?url=https%3A%2F%2Ffosstodon.org%2Fweb%2F%40talkpython" target="_blank" ><i class="fa-brands fa-mastodon"></i> @talkpython@fosstodon.org</a><br/> <strong>X.com</strong>: <a href="/proxy?url=https%3A%2F%2Fx.com%2Ftalkpython" target="_blank" ><i class="fa-brands fa-twitter"></i> @talkpython</a><br/> <br/> <strong>Michael on Bluesky</strong>: <a href="/proxy?url=https%3A%2F%2Fbsky.app%2Fprofile%2Fmkennedy.codes%3Ffeatured_on%3Dtalkpython" target="_blank" >@mkennedy.codes</a><br/> <strong>Michael on Mastodon</strong>: <a href="/proxy?url=https%3A%2F%2Ffosstodon.org%2Fweb%2F%40mkennedy" target="_blank" ><i class="fa-brands fa-mastodon"></i> @mkennedy@fosstodon.org</a><br/> <strong>Michael on X.com</strong>: <a href="/proxy?url=https%3A%2F%2Fx.com%2Fmkennedy%3Ffeatured_on%3Dtalkpython" target="_blank" ><i class="fa-brands fa-twitter"></i> @mkennedy</a><br/></div>

April 27, 2026 07:53 PM UTC


EuroPython

Humans of EuroPython: Martin Borus

EuroPython wouldn’t exist if it weren’t for all the volunteers who put in countless hours to organize it. Whether it’s contracting the venue, ordering catering for a week-long conference, selecting and confirming talks & workshops, hundreds of hours of loving work have been put into making each edition the best one yet.

Today, we’d like to share an interview with Martin Borus, a member of the EuroPython 2025 Operations team and a returning conference contributor.

Thank you for making EuroPython such a welcoming conference, Martin!

altMartin Borus, member of the Operations Team at EuroPython 2025 Prague & Remote

EP: What first inspired you to volunteer for EuroPython?

When visiting EuroPython - which was my first big Python conference - I got to know some volunteers. From the next year on I got gradually into helping. It seemed like a good idea to help.

EP: How did contributing to EuroPython impact your relationships within the community?

It was an entry point into the Python community. I met a lot of people I would not have met otherwise. Which led to a lot of interesting conversions and specific help for my journey into Python.

EP: Was there a moment when you felt your contribution really made a difference?

One of these moments comes from the Beginners’ Orientation sessions. I still remember the problems I had being alone on my first EuroPython that motivated me to give others a better start. I got feedback that this helped others to enjoy their first conference more.

EP: What&aposs one thing you took away from contributing to EuroPython that you still use today?

The experiences gained in working with a team coming from all over Europe.

EP: If you could add one thing to make the volunteer experience even better, what would it be?

If there was a single thing, we’d have implemented it already, because each year the volunteers try to improve based on the experiences of the previous years.

EP: What tips do you have for people attending the conference?

For anybody coming to EuroPython, volunteer or attendee, I can highly recommend having a note on your phone about what topics you’re interested in. Collect questions in the weeks before the conference, so you can pull them out in conversations. I call this my “EuroPython wish list” and usually get large parts of it covered during the week.

EP: What would you say to someone considering volunteering at EuroPython but feeling hesitant?

Even if it’s at the cost of missing some of the talks, as a volunteer you are where the action is and you have a chance to get more experiences out of the conference.

EP: Thank you for your contribution, Martin!

April 27, 2026 07:02 PM UTC


PyCon

Asking the Key Questions: Q&A with the PyCon US 2026 keynote speaker Lin Qiao

This is a blog series where we're asking each of our PyConUS 2026 keynote speakers about their journey into tech, how excited they are for PyconUS and any tips they can provide for an awesome conference experience! Here's our interview with Lin Qiao




Without giving too many spoilers, tell us what your keynote is about?

Most AI products are built on rented land. If your competitor can make the same API call, you do not have a moat. I will break down what the teams pulling ahead are doing differently, with real examples from Cursor, Notion, and Vercel, and get into the hard tradeoffs nobody talks about enough.

How did you get started in tech/Python?

My path into tech started pretty naturally. I studied STEM all through high school and undergrad, so it was always the space I gravitated toward. Python specifically came later, during my PhD, where I started using it to run experiments and support my research papers.

What do you think the most important work you've ever done is?

Co-creating PyTorch was a defining chapter, because it became the foundation for how the world does AI research. But I think the most important work is really what I’m doing now. I founded Fireworks because I spent years watching companies outside Big Tech struggle to get AI into production. They had the ambition but not the infrastructure, and we’re changing that.

Have you been to PyCon US before? What are you looking forward to?

PyTorch was built on Python, so this community is close to my heart. I am most looking forward to the hallway conversations. The best ideas come from talking to people who are deep in the work.

Any advice for first-time conference goers?

Talk to people. The sessions are recorded, but the people are only there for a few days. Go to the hallway track, sit at lunch tables where you do not know anyone, and if a talk resonated with you, go tell the speaker. That’s how the best professional relationships start.

Can you tell us about an open source or open culture project that you think not enough people know about?

I am biased, but I think the broader open model ecosystem does not get the credit it deserves. Everyone knows the big names, but there is an incredible amount of work happening in specialized open models, evaluation frameworks, and fine-tuning tooling that is quietly making AI more accessible. The pattern I keep seeing is that the most impactful open-source projects are the ones that lower the barrier for the next person to build something better. That was true for PyTorch, and it is true today for the tools that help developers go from an off-the-shelf model to something truly customized for their use case.


April 27, 2026 04:11 PM UTC


Ari Lamstein

A Web App for Exploring Foreign‑Born Population Trends

I just created a web app for exploring trends in the foreign-born population in the United States. The app lets you pick a location and see how the size of the foreign-born population there has changed over time. More importantly, it gives people a way to track how the foreign‑born population shifts as the Trump administration’s immigration enforcement efforts unfold.

The app is built in Python with Streamlit, and the data comes from the American Community Survey (ACS) 1‑year estimates. Everything is powered by the acs‑nativity package I recently published to PyPI. The ACS currently covers 2005–2024, and the 2025 release is expected in September — I’ll update the app as soon as the new data becomes available. Data is available for the nation, all states, and any county or city with at least 65,000 residents.

Here’s a screenshot from the app providing data on Chicago, Illinois:

Chicago’s foreign‑born population has risen and fallen sharply at different points between 2005 and 2024. Last September President Trump launched an immigration enforcement action in the city called Operation Midway Blitz. When the 2025 ACS estimates come out in September, we’ll get the first chance to see whether that enforcement action shows up in the data – and how any change compares with the kinds of fluctuations Chicago has experienced in the past.

Exploratory Data Analysis

In addition to the graphs generated by the acs-nativity package, the app provides two additional tabs to help you explore nativity trends: the Table tab and the Compare Years tab.

Table Tab

The Table tab shows the full dataset for the selected geography level, and you can sort by any column. Sorting makes it easy to spot outliers. For example, in 2024 the location with the highest share of foreign‑born residents was Hialeah, Florida (77.1%), while the lowest was Muskingum County, Ohio (0.7%):

Compare Years Tab

The Compare Years tab lets you create a table showing how a demographic has changed between two years. This often surfaces surprising results. For example, between 2023 and 2024, New York City saw an estimated increase of 205,767 in the Native-born population – slightly larger than California’s increase of 204,056, despite California’s population being several times larger:

Try the App

If you’re interested in how these patterns play out in your own community, you can explore the app here.

April 27, 2026 04:00 PM UTC


Rodrigo Girão Serrão

TIL #143 – Resolve a lazy import manually

Learn how to work around the Python machinery to resolve an explicit lazy import manually.

A couple of articles ago I wrote about how you could inspect a lazy import.

Apparently, you can use a similar trick to check the attributes and methods that a lazy import has:

>>> lazy import json
>>> dir(globals()["json"])
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'resolve']

Apart from a large number of dunder methods and dunder attributes, you'll find the method resolve. You can run help(globals()["json"].resolve) to get the help text on that method:

Help on built-in function resolve:

resolve() method of builtins.lazy_import instance
    resolves the lazy import and returns the actual object

This shows that it's the method resolve that resolves a lazy import.

If you call the method, you can get access to the resolved module:

>>> lazy import json
>>> resolved_json = globals()["json"].resolve()
>>> resolved_json
<module 'json' from '/Users/rodrigogs/.local/share/uv/python/cpython-3.15.0a8-macos-aarch64-none/lib/python3.15/json/__init__.py'>

After calling resolve, the lazy module doesn't disappear automatically:

>>> globals()["json"]
<lazy_import 'json'>

Which shows that the mechanism that's responsible for reification most likely calls the method resolve and then reassigns the name of the module to the module returned by resolve. In a way, it's as if the reification process ran something like

globals()["json"] = globals()["json"].resolve()

In hindsight, this isn't too surprising. After all, Python tends to be very consistent. The only mistery that remains is what triggers the reification process. How is it that Python can detect when something touches the lazy import..?

April 27, 2026 03:18 PM UTC


Real Python

How to Conceptualize Python Fundamentals for Greater Mastery

Struggling to conceptualize Python fundamentals is a common problem learners face. If you’re unable to put a fundamental concept into perspective and form a clear mental picture of what it’s about, it’ll be difficult to understand and apply it.

In this guide, you’ll walk through a framework of steps to help you better conceptualize Python fundamentals. This process is helpful for Python developers and learners at any experience level, but especially for beginners. If you are just starting out, this guide will help you build a solid understanding of the basics.

You might want to set aside twenty minutes or so to read through the tutorial, and another thirty minutes to practice on a few key concepts. You should also gather a list of difficult topics, your preferred learning resources, and a note-taking app or pen and paper.

Click the link below to download a free cheat sheet that covers the framework steps you’ll walk through in this guide:

Get Your Cheat Sheet: Click here to download a free PDF that outlines the framework of steps for conceptualizing Python fundamentals.

Take the Quiz: Test your knowledge with our interactive “How to Conceptualize Python Fundamentals for Greater Mastery” quiz. You’ll receive a score upon completion to help you track your learning progress:


Interactive Quiz

How to Conceptualize Python Fundamentals for Greater Mastery

Check your understanding of a framework for conceptualizing Python fundamentals, from defining concepts to comparing similar ideas.

Step 1: Define the Concept in Your Own Words

Begin by briefly describing the concept in your own words. You can write your definition in the downloadable worksheet provided with this tutorial. Note that writing is a powerful tool for reinforcing learning, as educator and former Rutgers University professor Janet Emig asserted in her paper, Writing as a Mode of Learning.

Answer Key Questions for Defining a Concept

As a framework for your definition, consider these key questions:

  • What: What is a short description of the concept?
  • Why: Why is the concept important in the broader Python context?
  • How: How is the concept used in a Python program?

These questions will help you establish a core understanding of the concept you’re learning.

You might feel intimidated when you’re trying to define a Python concept. If you need help, there are many resources that can assist you. Real Python’s Reference section has concise definitions of Python keywords, built-in types, standard library modules, and more to help you build your own descriptions.

If you’re a visual learner, using an illustration can be a powerful way to enhance your understanding. In addition to a written definition, you can draw a picture or diagram to illustrate the concept. For example, the Variables in Python: Usage and Best Practices tutorial shows some example images of how you might picture variables. If you look at the Lists vs Tuples in Python tutorial, you can see a diagram of a Python list.

While pictures can be helpful, being able to conceptualize doesn’t necessarily mean you have to think visually. There are different thinking styles. Some researchers suggest that people can be visual or verbal thinkers. Pattern-based thinking is another style. Several of the tips in this tutorial encourage you to explore different aspects of these styles, depending on which works best for you.

View Examples of Concept Definitions

You might find a couple of examples helpful in understanding how to define difficult concepts. Suppose you’re studying variables. Here are possible responses to the key questions:

  • What: A variable is a name that points to an object stored in the program’s memory.
  • Why: Variables are key for data processing.
  • How: Assigning a value to a variable using the assignment operator (=) allows you to access your program’s data in a user-friendly way. You can then access and change the value by name throughout the program as needed.

This description provides a concise summary of what a variable is, why it matters, and how to use one. You can also include an example of variable usage as an addendum to your definition:

Language: Python
>>> age = 25

Here, you created a variable called age and assigned it a value of 25. From now on, you can use the variable name age to access, modify, or use the variable’s value.

Or, you might be learning about lists. Your definitions could look like this:

  • What: A list is a sequence of values or objects.
  • Why: Working with sequences of items is a common, foundational task in programming. Python lists make this important work easier.
  • How: You can create a list by writing a pair of square brackets, with a comma-separated sequence of items inside them. Assign the list to a variable to use it throughout your program.

Here’s a short Python list that demonstrates the points in the definitions above:

Read the full article at https://realpython.com/conceptualize-python-fundamentals/ »


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

April 27, 2026 02:00 PM UTC


Django Weblog

It&#x27;s time to redesign djangoproject.com

If you've felt like djangoproject.com could use a refresh, you're not alone. The site has served the community well for a long time, it’s beloved by a lot of people but doesn’t reflect where Django is today or who we want to reach. We've been working on a redesign behind the scenes, and we want to share where we're headed and how you can get involved.

Why a redesign

The case has been building for a while. The excellent user research report from 20tab documented in detail what current site users struggle with, and the more recent community discussion on homepage redesigns on the forum focuses on the image issue.

In her recent talk Debunking Django Myths, Sarah Boyce, one of our Django Fellows who helps maintain the project, walked through the gap between how Django is perceived and what it actually offers in 2026. Our website is one of the places where the gap is widest, and we need to close it.

Debunking Django Myths - Sarah Boyce @ Python Unplugged on PyTV

It’s harder than it looks on the surface, as it’s essential the site serves both as a showcase of the value of Django for newcomers; and as a central information space for our users; and as an online and in-person community hub; and a fundraising and sustainability tool for our Django Software Foundation.

How we're approaching this

We're planning the work in three phases.

Discovery and groundwork. This is where we’re at right now. Before anything gets designed, we need clarity on what the site should communicate: Django's value, who we're speaking to, and what success looks like. That means a marketing strategy (at least bigger-picture). Possibly additional user research focused on new users. Definitely site analytics so we know how different aspects of the site are working. And a redesign brief we can share with UX and visual design experts. We also need to be building up capacity in UX, Information Architecture (IA), and marketing, since those areas of expertise are essential for the success of the website but not well represented in our working groups.

Design. From there we'll move into IA, mockups, and low-fidelity prototypes. We expect this visual work will be component-driven, producing a small design system and pattern library that can support a section-by-section rollout rather than a big-bang launch. The homepage is the most visible surface and a natural focus, but it might be easier for our volunteers to first look at more specific sections (docs, donation flows, community) before tackling the more complex multi-purpose areas.

Build. For that, we want to work with our existing volunteer contributors as much as possible, so implementation will be incremental against mockups that reflect the long-term goal. This keeps the site working and evolving while we make progress on the design.

Who's doing the work

We hope to do most of this with existing volunteers. The Website working group, the Accessibility team, and the Social Media working group. Working with paid contractors for specific tasks if Django Software Foundation finances allow. A project this size really needs both: the continuity of volunteers who know Django and our community and Foundation, and focused professional time for the pieces that need it.

Where you come in

If you have relevant experience in any of the following, we'd genuinely love to hear from you:

Check out the Django forum thread we’re using for ongoing updates, come say hi in DMs, or chime in on the tracking issue for this work. Our Discord server is a good place to reach out too.
And separately - a good redesign will cost real money. We'd like some of this work to be handled by paid contractors where it makes sense, and that depends on what the Foundation can afford. If you're in a position to support the DSF financially, it directly helps us make that possible. Thanks for caring about this! Let's make djangoproject.com as good as the framework and community it represents.

April 27, 2026 01:00 PM UTC


Caktus Consulting Group

Easily Stream LLM Responses with Django-Bolt and PydanticAI

I like how easy it is to create an async streaming endpoint with django-bolt and PydanticAI from scratch. With only a few commands you can set it up.

April 27, 2026 01:00 PM UTC


Real Python

Quiz: Python's __all__: Packages, Modules, and Wildcard Imports

In this quiz, you’ll test your understanding of Python’s __all__: Packages, Modules, and Wildcard Imports.

By working through this quiz, you’ll revisit how wildcard imports work, what role the __all__ variable plays in modules and packages, and how to define a clean public API for your Python code.

You’ll need to know the basics of Python modules and packages and the import system to get the most out of this quiz. Good luck!


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

April 27, 2026 12:00 PM UTC


"Michiel's Blog"

httpxyz one month in

It has been roughly a month since we forked httpx and named our package httpxyz. For the reasons why I refer you to Why I forked httpx. In this post I will explain where we are now, one month ‘into’ having created the fork.

TL;DR: httpxyz has now many bug fixes and significantly better performance than httpx, and we would encourage anyone to move to our version!

httpxyz logo

Where we are now

Initial version of fork

Our first version of httpxyz contained just the fixes to get zstd working, and the fixes to get the test suite running on python 3.14, some ‘housekeeping’ changes related to the renaming, as well as some minor and trivial fixes that had already been merged in httpx and had not been released yet.

End of March: bugfixes, and performance improvements

Then at the end of March we did another release of httpxyz, containing a compatibility shim that allows you to use httpxyz even with third-party packages that import httpx themselves, as long as you import httpxyz first. We’ve added a nice documentation page for this.

This release also included a change that lazily imports the CLI for httpxyz, which is typically not used in your app; in my measurements this makes httpxyz import in half the time needed by httpx. This PR has been sitting idle at the httpx repository for over a year ref and we’ve kindly adopted it, thanks to Nate Hardison for providing it!

And apart from that we adopted a bunch of other smaller and bigger bug fixes and improvements in this release.

httpcorexyz!

But we realized pretty soon that there were some problems that httpx was having, that were actually caused by the underlying ‘transport’ which is defined in a different module, httpcore. This module also had no release in over a year, and there were a bunch of issues reported by users, with fixes even, that were not landing. So we ended up also forking httpcore and created httpcorexyz.

Here we fixed a WHOLE bunch of performance related issues:

These are serious issues, and it’s not even all. Almost all of these were already fixed by ‘the community’ and were living in unmerged pull requests. We code reviewed them, fixed them up where needed and adapted them to our code base. We also now added a benchmarks section to the documentation; httpxyz is now MUCH faster than httpx in many serious use cases.

Then we released a new version of HTTPXYZ earlier this week: 0.31.0 with this updated version of httpcorexyz and also more bug fixes of its own.

Where I previously stated having the fork is about future-proofing and I would not necessarily recommend people to switch to httpx, with this new version 0.31.0 I now feel that you should definitely move to httpxyz. With All new fixes and performance improvements it now makes ‘business sense’ to switch from httpx to httpxyz, the ‘churn’ is worth it now!

Adoption

We’re happy to see projects moving to using our package, even though it’s not much yet. We encourage everyone to do so, and please tell others and convince them! If you would find issues with your switchover, which I do not expect, please just open an issue and I’m sure we can figure it out!

Quotes

I'm a big user of httpx... Thanks for the fork. Here's to hoping it gained some traction. (Michael Kennedy, Founder, Talk Python)

Thank you for forking httpx. httpx is a joy to work with, but clearly a bit dead in the water. Really nice to see it moving forward again. (hhartzer)

If you want to have traction, you should probably move to GitHub instead of using Codeberg (Marcelo Trylesinski aka Kludex / FastAPI)

On Codeberg

We explained the last time why we chose Codeberg; we’re not unhappy about our choice. We got 39 ‘stars’ so far on our Codeberg repository and many of those are from ‘fresh’ accounts. If us being on codeberg helps a tiny little bit making github a bit less dominant, I think this is a good thing, and I hope it can inspire other projects to do the same. And after all, for most users, who would just pip install httpxyz or uv add httpxyz it does not matter where the source is hosted.

Thanks, and have fun!

April 27, 2026 07:00 AM UTC


Seth Michael Larson

pip v26.1 adds support for relative dependency cooldowns

My work as the Security Developer-in-Residence at the Python Software Foundation is sponsored by Alpha-Omega. Thanks to Alpha-Omega for supporting security in the Python ecosystem.

I published a blog post two months ago about how to hack relative dependency cooldowns into pip v26.0 with crontab. Now with pip v26.1 available, this hack is no longer required! Time to upgrade my pip and delete that cron job...

Now in pip v26.1 you can use uploaded-prior-to in your ~/.config/pip/pip.conf file or --uploaded-prior-to= as a CLI option with relative RFC 3339 duration values. pip supports setting days using “PND” where N is the number of days.

For example, using the following as your ~/.config/pip/pip.conf file will only install packages that are at least 7 days old on the Python Package Index:

[install]
uploaded-prior-to = P7D

Because this setting is in your global pip config, it means that you won't have to remember to set the option when invoking pip install. Using a relative value also means you won't have to repeatedly set new dates to receive new releases of the packages you use.

Using relative dependency cooldowns means that installing directly from a public index such as the Python Package Index (PyPI) will benefit from manual malware reporting, triaging, and removal efforts. The vast majority of malware and supply chain attacks published are detected and removed within hours of being uploaded to the index. Using relative dependency cooldowns means indexes have time to respond to malicious software and keep you safe.

Reminder that dependency cooldowns should be paired with a dependency management strategy that prioritizes dependency releases that fix vulnerabilities. You don't want to be waiting for days for a dependency cooldown to clear while your service is vulnerable. Managing, reviewing, upgrading, and deploying vulnerability patches should be a deliberate task, not one that happens "on-accident" due to an upgrade-by-default installation strategy.

Andrew Nesbitt has published a comprehensive review of dependency cooldowns across many different package managers. Thanks to William Woodruff who originally published this approach.



Thanks for keeping RSS alive! ♥

April 27, 2026 12:00 AM UTC

April 26, 2026


death and gravity

reader 3.23 released – OPML, hosted reader intro

Hi there!

I'm happy to announce version 3.23 of reader, a Python feed reader library.

What's new? #

Here are the highlights since reader 3.22.

OPML support #

reader can finally import and export feeds as OPML subscription lists!

I initially wanted to use listparser, but I ended writing my own reader.opml module, mainly to keep dependencies down; it's just ~100 lines of code, including the work-around for an xml.etree bug I found.

Protip

utf-8 is a valid XML encoding name, utf8 is not.

Here are some web app screenshots:

export feeds export feeds
import feeds (select) import feeds (select)
import feeds (result) import feeds (result)

Hosted reader status update #

As I said last time, I'm working on a hosted version of reader. It's still some ways off from a proper launch, but I have to start writing about it eventually, so it might as well be here.

Why another feed reader web app? #

While reader the library allows you to write your own feed reader, I don't expect most people to do that, and nor should they; for reader to be truly useful, it needs to reach all the way to the end user.

But I am making the web app for myself anyway, why not share it with others?

Why not just self-host it? #

Because for most people, "self-host it" is not the answer – it takes knowledge, time, and if you don't already have a server you can use, it can cost a bit too.

If someone were to host reader for me, I'd gladly pay for it; what matters more is that it is possible to self-host, should the need arise; none of that sunsetting bullshit.

But I am self-hosting for myself anyway, so sharing it with others wouldn't be that big of a stretch. And while it is a stretch, it's going to make reader better overall.

OK, so what now? #

This is what is finished so far:

(More on architecture and so on in a dedicated future article.)

Remaining work to an MVP:

And then there's the promotional stuff:

Meanwhile, if this sounds like something you'd like to use, get in touch.


That's it for now. For more details, see the full changelog.

Want to contribute? Check out the docs and the roadmap.

Learned something new today? Share it with others, it really helps!

What is reader? #

reader takes care of the core functionality required by a feed reader, so you can focus on what makes yours different.

reader in action reader allows you to:

...all these with:

To find out more, check out the GitHub repo and the docs, or give the tutorial a try.

Why use a feed reader library? #

Have you been unhappy with existing feed readers and wanted to make your own, but:

Are you already working with feedparser, but:

... while still supporting all the feed types feedparser does?

If you answered yes to any of the above, reader can help.

The reader philosophy #

April 26, 2026 06:00 PM UTC

April 24, 2026


Real Python

The Real Python Podcast – Episode #292: Becoming a Better Python Developer Through Learning Rust

How can learning Rust help make you a better Python Developer? How do techniques required by a compiled language translate to improving your Python code? Christopher Trudeau is back on the show this week with another batch of PyCoder's Weekly articles and projects.


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

April 24, 2026 12:00 PM UTC

Quiz: AI Coding Agents Guide: A Map of the Four Workflow Types

In this quiz, you’ll test your understanding of AI Coding Agents Guide: A Map of the Four Workflow Types.

By working through this quiz, you’ll revisit the four common workflow types for AI coding agents: IDE, terminal, pull request, and cloud. You’ll also get a chance to review how to match the right workflow to the task in front of you.


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

April 24, 2026 12:00 PM UTC


The Python Coding Stack

Doubling Down on Python in The Age of AI

If you’ve been wondering where I’ve been, yes, it’s been quieter than usual around here. No dramatic reason. Just life, work, the usual stuff.

But one thing kept catching my attention: all the noise outside. Everyone’s talking about AI writing code, agents shipping products, the death of programming. And every so often, someone asks me — usually with that slightly guilty look of someone who thinks they’re about to insult my livelihood — “but do you really still need to learn Python? In this age?”

So I’ve been thinking about it. Properly. And I wanted to share where I’ve landed, because I think the answer matters and it’s different from what some hot takes suggest.

Do I still need to learn to code?

The way we write computer programs is changing. I don’t have a crystal ball for what programming looks like in five or ten years.

But here’s the thing: neither does anyone else.

Here’s what I know from watching others and experimenting with AI tools in my own work: right now, the people getting the most out of AI are the ones who already know how to code.

Here’s the hierarchy as I see it today:

Where we stand today:

We’re in an era where some coding knowledge takes you much further than it could have a few years ago. That’s not an argument against learning to code. It’s an argument for it.

“But what about those vibe coding people? They seem to be shipping things.” Some are. I’ll be honest about that.

The projects I’ve seen from pure vibe coders tend to be smaller, tend to follow well-trodden patterns, and often hit a ceiling when something goes slightly wrong or slightly off-piste. Which is fine for a side project. I just created a useful dashboard to help me organise my day the way I want to using this approach.

But it tells you something: the AI does the heavy lifting on the known stuff. The moment something needs genuine thinking, you need the human who knows what’s going on beneath the surface.

AI-Assisted Human Coding and Human-Assisted AI Coding

Most serious work right now is a partnership.

Sometimes it’s AI-assisted human coding. The human drives, AI assists.

Sometimes it’s human-assisted AI programming. The AI writes most of the code, but the human knows what to ask for, how to steer it toward good design, how to evaluate whether the output actually makes sense.

Even when the coding looks like it’s done by AI, the person prompting and reviewing it is generally an experienced programmer. They’ve learned enough Python to know what’s reasonable, what’s a red flag, and when the AI is confidently wrong.

I’ve been experimenting with agentic AI over the past few weeks. I’ve tackled side projects I’d never have had the time for before. I didn’t have the time to start then, let alone finish them. Some of that output will show up in other places — stay tuned! But not here. The Python Coding Stack is the place for my writing.

The Programming Mindset When Talking to AI Agents

Here’s one thing I noticed. Talking to AI agents isn’t like talking to humans. But it isn’t like talking to computers (a.k.a. programming) either.

You need both qualities at the same time.

You need the clarity and communication skills you’d use with a person — explaining context, setting direction, knowing what matters, using clear language.

And you need the precision you’d use when programming — no ambiguity, clear intent, structure.

A good programmer who’s also a good communicator is the best human to work with AI agents.

That’s not coincidental. The same thought habits that make you an effective programmer also make you an effective prompter and reviewer when AI is involved.

I’ll share some of the prompts I’m using in a future post and analyse them to discuss why I wrote what I wrote. Learning to code well gives you an unfair advantage in this new world.

There’s Never Been a Better Time to Learn Python

Here’s what I’ve convinced myself of after all this. There’s never been a better time to learn Python.

A few years ago, you needed to reach an intermediate-to-advanced level before you could do something genuinely useful with Python. The bar was high. Now, with AI assistance, the bar is lower. Less Python knowledge takes you further than ever.

What used to need expertise can now be explored with curiosity and a bit of intermediate-ish-level Python.

That’s not replacing deeper learning. It’s making the entry point more accessible. And once you’re in, you can go as deep as you want.

So yes, I’ll keep coding in Python. Sometimes with a bit of help from AI. Sometimes with a lot of help from AI.

And yes, I’ll keep writing about Python here, as I’ve always done.

The Fun Factor

Here’s the thing we don’t talk about enough when discussing programming. It’s fun. It’s challenging. It’s rewarding. It’s fulfilling. It’s stimulating. It keeps my brain active.

I code because I enjoy it. I’ll keep writing about Python because I enojoy that, too,, and because I find value in sharing here — for myself and, hopefully, for you too.

Normal service resumes here. More Python posts coming. And maybe, just maybe, some of the AI things I’m learning will make their way in, too.

Psst–did you know you can become a premium member to be a part of The Club? It would mean so much to me!

Subscribe now


Quick question:

Photo by Maksim Goncharenok


Join The Club, the exclusive area for paid subscribers for more Python posts, videos, a members’ forum, and more.

Subscribe now

You can also support this publication by making a one-off contribution of any amount you wish.

Support The Python Coding Stack


For more Python resources, you can also visit Real Python—you may even stumble on one of my own articles or courses there!

Also, are you interested in technical writing? You’d like to make your own writing more narrative, more engaging, more memorable? Have a look at Breaking the Rules.

And you can find out more about me at stephengruppetta.com

April 24, 2026 08:53 AM UTC


Python GUIs

Streamlit Widgets — An Overview of Commonly Used Widgets in Streamlit

Streamlit is a powerful Python library designed to build interactive web apps with minimal code. One of its core features is an extensive collection of widgets that allow users to interact with the app in various ways, such as providing inputs, triggering actions, or visualizing data. Streamlit makes it easy to create these elements with simple, intuitive syntax.

In the previous tutorial, we saw how to get started with Streamlit and run it on your local host. Here, we'll cover the main widgets available in Streamlit, explaining how they work, and how to customize them using various examples.

Getting started with Widgets Streamlit

Widgets in Streamlit are simple yet customizable. By combining multiple widgets together in different layouts, you can create interactive dashboards, data visualizations, and forms. Whether you want to include buttons, sliders, checkboxes, or display tables and plots, Streamlit offers a wide range of widgets that cater to different needs. Adding a widget to your Streamlit app is as easy as calling a single function, and customizing its behavior requires only minimal code.

In this guide, we will explore the various widgets that Streamlit offers, from basic input elements like text boxes and radio buttons to more complex visual components like plots and tables. We'll also dive into how to customize the behavior of these widgets to suit your app's specific requirements, such as adjusting slider ranges, modifying button text, and adding captions to images. By the end of this article, you'll have a solid understanding of how to leverage Streamlit widgets to enhance the interactivity and functionality of your applications.

Let's start by exploring the basic widgets Streamlit provides and how you can easily integrate them into your app. Make sure you have installed the streamlit module on your system and imported it on your Python file.

Buttons in Streamlit

Buttons are one of the most essential and commonly used components in any interactive application. In Streamlit, the st.button() widget provides an easy and effective way to allow users to trigger actions, interact with your app, or make decisions. With just a few lines of Python code, you can integrate buttons into your Streamlit app to perform tasks like data processing, changing app state, or displaying content.

The st.button() widget creates a clickable button on the interface. When clicked, it returns True, which can be used to trigger specific actions. If the button is not clicked, it returns False.

The basic syntax for creating a button in Streamlit is given below:

python
import streamlit as st
if st.button('Click Me'):
    st.write("Button clicked!")

A Streamlit button widget A Streamlit button widget

In this simple example, the button's label is "Click Me". When clicked, the app prints "Button clicked!" to the interface.

The most common customization for a button is its label — the text that appears on the button. The label is the first argument you pass to the st.button() function. For example, we can change the "Click Me" to a "Submit" button.

python
import streamlit as st
if st.button('Submit'):
    st.write("Form submitted successfully!")

A Streamlit button widget with a different label A Streamlit button widget with a different label

You can customize this label to suit the action you want to convey to the user. Whether it's Submit, Cancel, Run, or any custom text, Streamlit will display it as the button text

Moreover, Streamlit makes it simple to handle multiple buttons on the same page. You can define multiple st.button() widgets, each with its own label and action. Here is an example of how we can add multiple buttons.

python
import streamlit as st
if st.button('Button A'):
    st.write("Button A clicked!")

if st.button('Button B'):
    st.write("Button B clicked!")

Multiple Streamlit buttons Multiple Streamlit buttons

Similarly, you can add as many buttons as you wish.

Checkboxes in Streamlit

Checkboxes are a fundamental widget in Streamlit that allows users to toggle between two states: checked True or unchecked False. They are ideal for scenarios where you want users to make binary choices, such as showing or hiding content, enabling or disabling features, or making Yes/No decisions. It can also be used to select multiple options as the same time as well. The st.checkbox() widget is incredibly versatile and easy to implement, making it a key component in creating interactive applications.

As mentioned, the st.checkbox() widget creates a simple checkbox in your Streamlit app. When a user checks the box, it returns True, and when the box is unchecked, it returns False. Here is a basic example of checkboxes in Streamlit.

python
show_text = st.checkbox('Show text')
if show_text:
    st.write("You checked the box!")

Streamlit checkbox Streamlit checkbox

In this example, the checkbox is labeled "Show text". When the user checks the box, the app displays "You checked the box!" on the interface.

The most common customization for a checkbox is its label, which appears next to the checkbox itself. This label should clearly indicate what action will occur when the checkbox is checked.

python
subscribe = st.checkbox('Subscribe to our newsletter')
if subscribe:
    st.write("Thanks for subscribing!")

Streamlit checkbox with custom label Streamlit checkbox with custom label

Here, the checkbox label is customized to "Subscribe to our newsletter", and when the user checks it, a thank-you message is displayed.

By default, checkboxes in Streamlit are unchecked (False). However, you can change this by setting the value parameter to True, so that the checkbox is pre-checked when the app loads.

python
subscribe = st.checkbox('Subscribe to our newsletter', value=True)
if subscribe:
    st.write("Thanks for subscribing!")

In this case, the checkbox is checked by default, and the welcome message is shown immediately when the app starts.

Furthermore, Streamlit makes it easy to handle multiple checkboxes, each controlling different parts of your app. You can create several checkboxes, and based on their states, you can conditionally display content or execute logic.

python
option1 = st.checkbox('Enable Feature 1')
option2 = st.checkbox('Enable Feature 2')

if option1:
    st.write("Feature 1 is enabled!")
if option2:
    st.write("Feature 2 is enabled!")

Multiple Streamlit checkboxes Multiple Streamlit checkboxes

Sometimes, you may need to generate checkboxes dynamically, especially if the number of checkboxes depends on user input or the result of some computation.

python
options = ['Apple', 'Banana', 'Cherry']
selected = []

for fruit in options:
    if st.checkbox(fruit):
        selected.append(fruit)

st.write(f'Selected fruits: {", ".join(selected)}')

Getting Streamlit checkboxes selection state Getting Streamlit checkboxes selection state

In this example a list of fruit names is used to dynamically create a set of checkboxes. When a user checks a box, the corresponding fruit is added to a list, and the selected fruits are displayed.

Radio buttons in Streamlit

Radio buttons are an essential widget in Streamlit that allow users to select a single option from a predefined list of choices. They are perfect for scenarios where only one selection can be made at a time, such as selecting a category, choosing between modes, or answering questions. The st.radio() widget provides an intuitive and simple way for users to interact with your Streamlit application.

The st.radio() widget creates a list of radio buttons where the user can select only one option at a time. It returns the selected option, which can be used to drive various actions in the app. Let us have a look at a very simple example of a radio button.

python
choice = st.radio('Choose an option:', ['Option 1', 'Option 2', 'Option 3'])
st.write(f'You selected: {choice}')

Streamlit radio buttons Streamlit radio buttons

In this example:

By default, the first option in the list of radio buttons is selected. However, you can customize this by setting the index parameter, which specifies which option should be selected when the app loads.

python
travel_mode = st.radio('Preferred mode of travel:', ['Car', 'Bike', 'Plane'], index=2)
st.write(f'You selected: {travel_mode}')

Streamlit radio buttons with default selection Streamlit radio buttons with default selection

The index=2 means the third option ("Plane") is selected by default when the app is loaded.

Select box in Streamlit

A select box in Streamlit is a widget that lets users choose a single option from a dropdown list. This widget is perfect for situations where you have a predefined list of options but want to save space on your interface by not displaying all the options upfront. The st.selectbox() widget is highly customizable and can be used for anything from simple selections to dynamically populated lists. It's ideal for situations where you want to offer multiple choices, but only display the currently selected item. Let us create a simple dropdown menu with three options.

python
option = st.selectbox('Choose an option:', ['Option 1', 'Option 2', 'Option 3'])
st.write(f'You selected: {option}')

Streamlit select box Streamlit select box

In this example:

By default, the first item in the list of options is selected in a select box. However, you can specify a different default selection by setting the index parameter. The index corresponds to the zero-based position of the option in the list.

python
city = st.selectbox('Select your city:', ['New York', 'London', 'Paris', 'Tokyo'], index=2)
st.write(f'You selected: {city}')

When you run this code, you will notice that, Paris will be selected as city because it is at index 2.

Slider in Streamlit

Sliders are a popular widget in Streamlit that allows users to select values by dragging a handle across a range. They are perfect for collecting numerical inputs or setting parameters like dates, time, and ranges. Streamlit's st.slider() widget provides a flexible and easy-to-use interface for adding sliders to your app, enabling users to interactively choose values with precision. It can handle integers, floats, dates, and times, making it highly versatile for various use cases.

Let us create a simple slider where a user can select any number from 0 to 100.

python
value = st.slider('Select a value:', 0, 100)
st.write(f'You selected: {value}')

Streamlit slider widget Streamlit slider widget

By default, the slider handle is set to the minimum value of the range, but you can specify a default value by providing a value argument. This is useful when you want the slider to start at a specific position.

python
temperature = st.slider('Set the temperature:', -50, 50, value=20)
st.write(f'Temperature set to: {temperature}°C')

Streamlit slider widget with default value Streamlit slider widget with default value

By default, the 20 will be selected as set temperature.

Sliders in Streamlit can handle both integers and floating-point numbers. To use floating-point values, you simply specify a range with float values. You can also control the step size between values using the step parameter.

python
price = st.slider('Select a price:', 0.0, 1000.0, step=0.5)
st.write(f'Price selected: ${price}')

Streamlit float slider widget Streamlit float slider widget

In this example:

Streamlit's slider widget also allows users to select a range of values, which is particularly useful when you need two values (e.g., a start and end date, or a minimum and maximum range). To do this, provide a tuple as the value argument.

python
salary_range = st.slider('Select a salary range:', 20000, 100000, (30000, 80000))
st.write(f'Selected salary range: ${salary_range[0]} - ${salary_range[1]}')

Streamlit range slider widget Streamlit range slider widget

Here, the slider has a range from 20000 to 100000. The user can select a minimum and maximum value for the salary range (initially set between 30000 and 80000).

Apart from that, Streamlit sliders can also handle date and time values, which is especially useful when users need to select a specific day or time range. You can create sliders with datetime.date and datetime.time objects to allow users to make date-based selections.

python
import streamlit as st
import datetime

date = st.slider('Select a date:', datetime.date(2020, 1, 1), datetime.date(2024, 12, 31), value=datetime.date(2023, 1, 1))

Streamlit date slider Streamlit date slider

In this example, the user can select a date between January 1, 2020, and December 31, 2024. The default value is set to January 1, 2023.

You can use sliders with any other widgets or functions to make it more dynamic and interactive. For example, we can combine them with conditional logic to adjust the behavior or content of an app based on the selected value. This is particularly useful for creating dynamic and interactive experiences.

python
rating = st.slider('Rate our service:', 1, 5)

if rating <= 2:
    st.write('We are sorry to hear that. Please let us know how we can improve.')
else:
    st.write('Thank you for your feedback!')

Streamlit slider interactivity Streamlit slider interactivity

The slider allows users to rate a service between 1 and 5. Based on the rating, different messages are displayed.

Different input options in Streamlit

In Streamlit, input options are essential for creating interactive applications, allowing users to interact with data and visualizations dynamically. Streamlit offers a variety of input widgets that cater to different types of data and user interactions. Below are the main input options that we will be discussing in this section:

Now, let us discuss each of these options in details by taking examples.

Date and Time Input

Among its many features, Streamlit provides robust support for handling date and time inputs, allowing developers to easily integrate date and time pickers into their applications. This is useful in a wide variety of contexts, such as scheduling applications, time series analysis, filtering data based on time ranges, or tracking events.

The st.date_input() widget in Streamlit provides a simple and intuitive interface for users to select dates. This widget can be used to input a single date or a range of dates. The basic syntax of date_input() function is given below will possible parameter values.

python
st.date_input("Date", value=None, min_value=None, max_value=None, key=None, help=None, on_change=None)

Streamlit date input Streamlit date input

Let us explore the parameters in turn:

In addition to that, you can also use st.date_input() to allow users to pick a range of dates by passing a tuple of two datetime.date objects as the default value.

python
import streamlit as st
import datetime

# Date range input
start_date = datetime.date(2023, 9, 1)
end_date = datetime.date(2023, 9, 30)
date_range = st.date_input("Select a date range", (start_date, end_date))
st.write(f"Start date: {date_range[0]}")
st.write(f"End date: {date_range[1]}")

Streamlit date range input Streamlit date range input

In this case, the user can select a range of dates. The widget will return a tuple containing the start and end dates.

On the other hand, the st.time_input() widget allows users to select a specific time. This widget is useful in scenarios like scheduling events or setting alarms. Here is the simple syntax off time_input() function with its possible parameter values.

python
st.time_input(label="Time", value=None, key=None, help=None, on_change=None)

Streamlit time input Streamlit time input

The parameters in the time_input functions:

In many applications, you'll need both date and time inputs together. Although Streamlit doesn't provide a single widget for selecting both date and time, you can combine the st.date_input() and st.time_input() widgets to achieve this functionality.

python
import streamlit as st
import datetime

# Date input
date = st.date_input("Pick a date", datetime.date.today())
# Time input
time = st.time_input("Pick a time", datetime.time(9, 00))

# Combine date and time
selected_datetime = datetime.datetime.combine(date, time)
st.write(f"Selected date and time: {selected_datetime}")

Combining Streamlit widgets for selecting date and time Combining Streamlit widgets for selecting date and time

This code lets the user select both a date and a time, then combines them into a single datetime.datetime object.

Text and area input

One of the essential features of any web app is gathering user input, and Streamlit provides several widgets to capture user input easily. Among them, text input widgets play a crucial role in allowing users to input free-form text data. In this article, we will dive into Streamlit's text input widgets and explore their capabilities, practical applications, and customization options.

Streamlit offers two primary widgets for capturing text input:

Both widgets are used to gather text-based input from users but differ in the amount of text they are designed to handle. Let's take a closer look at each of these widgets.

The st.text_input() widget allows users to input a single line of text. This is ideal for cases where you want to gather short responses such as names, email addresses, usernames, search queries, or small pieces of data.

python
# Single-line text input
name = st.text_input("Enter your name")
st.write(f"Hello, {name}!")

Streamlit text input widget Streamlit text input widget

This example creates a simple input box where users can enter their names. The app then displays a message using the entered text.

In some cases, we may need to limit the total number of characters entered by the user. So, we can use the max_charsparameter as shown below:

python
# Text input with character limit
username = st.text_input("Enter your username", max_chars=15)
st.write(f"Your username is: {username}")

This is similar to the previous example, but this time the user is not allowed to enter characters more than 15. In the text_input() function, we can also specify the type of text we want the user to enter. For example, if we want a user to enter an email and password, we can specify those as shown below:

python
email = st.text_input("Enter your email")
st.write(f"Email entered: {email}")
password = st.text_input("Enter your password", type='password')
st.write(f"Password length: {len(password)} characters")

Streamlit password input widget Streamlit password input widget

As shown above, when we enter the password, it will not be visible.

The st.text_area() widget is ideal when you need to capture longer inputs or multi-line text, such as feedback, code snippets, or detailed descriptions. It provides users with a resizable text area where they can enter more extensive information

python
# Multi-line text area
feedback = st.text_area("Your feedback", "Enter your comments here...")
st.write(f"Your feedback: {feedback}")

Streamlit text area for text input Streamlit text area for text input

In this example, the text area allows the user to enter multiple lines of text. The entered feedback is then displayed. In a similar way as we did before, you can limit the max number of characters by assigning a value to the max_chars parameter.

Number Input in Streamlit

The st.number_input() widget allows users to input numbers, offering several customization options like setting minimum and maximum values, adjusting step increments, and choosing between integers and floating-point numbers. This widget is particularly useful for inputs like prices, quantities, percentages, or any scenario where numerical precision is required.

The simplest form of the st.number_input() widget involves asking the user to input a number without setting any constraints like minimum or maximum values.

python
age = st.number_input("Enter your age")
st.write(f"Your age is: {age}")

Streamlit numeric input Streamlit numeric input

In this example, the widget accepts any number, and the user's input is displayed back on the screen.

You can restrict the input to a certain range by specifying the min_value and max_value parameters. This is particularly useful when you need to validate the input against specific boundaries.

python
# Number input with a range
rating = st.number_input("Rate your experience", min_value=1, max_value=5)
st.write(f"Your rating is: {rating}")

Numeric input with validation Numeric input with validation

In this example, the user can only select a rating between 1 and 5, ensuring valid input. You can set a default value that appears in the input box when the app first loads, and you can also define how much the value should increase or decrease when the user interacts with the widget.

python
# Number input with default value and step size
quantity = st.number_input("Select quantity", min_value=0, max_value=100, value=10, step=5)
st.write(f"You have selected: {quantity} units")

Numeric input with validation and step size Numeric input with validation and step size

In this example, the widget starts with a default value of 10, and the user can adjust the value in increments of 5, from 0 to 100.

File uploader in Streamlit

st.file_uploader() widget, which allows users to upload files directly into your Streamlit app. This functionality is vital in many applications, such as data analysis tools, machine learning models, and document processing systems. This widget is a convenient tool for enabling users to upload files of various types, such as text files, CSVs, images, PDFs, and more. Once uploaded, the files can be processed or analyzed directly within the Streamlit app.

The simplest use case of st.file_uploader() is to upload a single file of a specific type.

python
import pandas as pd

# Single file uploader for CSV files
uploaded_file = st.file_uploader("Upload a CSV file", type="csv")

if uploaded_file is not None:
    df = pd.read_csv(uploaded_file)
    st.write(df)

Upload CSV files Upload CSV files

In this example, the user can upload a CSV file, and the app reads and displays the contents using the pandas library.

We can also upload images and show them in our web app. For images, we need to specify the type of images as shown in the example below:

python
import streamlit as st
from PIL import Image

# Upload an image file
uploaded_image = st.file_uploader("Upload an image", type=["png", "jpg", "jpeg"])

if uploaded_image is not None:
    image = Image.open(uploaded_image)
    st.image(image, caption="Uploaded Image", use_column_width=True)

Upload image files Upload image files

Here, users can upload image files in formats like PNG, JPG, or JPEG. Once uploaded, the app uses the Pillow library to open and display the image.

Furthermore, you can use the accept_multiple_files parameter to allow users to upload several files at once. This is useful when handling bulk uploads or cases where multiple files need to be processed together.

python
# Multiple file uploader for text files
uploaded_files = st.file_uploader("Upload multiple text files", type="txt", accept_multiple_files=True)

if uploaded_files:
    for uploaded_file in uploaded_files:
        st.write(f"File name: {uploaded_file.name}")
        content = uploaded_file.read().decode("utf-8")
        st.write(content)

Uploading multiple files Uploading multiple files

In this example, the user can upload multiple text files. The app reads and displays the contents of each file.

Streamlit also allows you to validate uploaded files based on specific conditions, such as file size, format, or content.

python
uploaded_file = st.file_uploader("Upload a file")

if uploaded_file is not None:
    # Check file size (less than 2 MB)
    file_size = uploaded_file.size
    if file_size > 2 * 1024 * 1024:
        st.error("File size exceeds 2 MB limit!")
    else:
        st.success("File uploaded successfully.")
        st.write(f"File size: {file_size} bytes")

Uploading file too large Uploading file too large

As you can see, the file was not uploaded because it exceeds the max size.

Conclusion

Streamlit's widget system is a powerful and intuitive way to add interactivity to web applications. From simple text and number inputs to more complex file uploaders and sliders, Streamlit provides a wide range of widgets that allow users to seamlessly interact with your app. These widgets can be easily integrated into data-driven applications, enabling users to input data, upload files, and adjust parameters in real-time.

Streamlit widgets are designed to be highly customizable, offering various configuration options like minimum and maximum values, step sizes, file type restrictions, and dynamic callbacks. With minimal code, developers can create sophisticated, interactive applications that enhance user experience and make complex workflows more accessible.

April 24, 2026 06:00 AM UTC

April 23, 2026


PyCon

Asking the Key Questions: Q&A with the PyCon US 2026 keynote speakers: Rachell Calhoun and Tim Schilling

Welcome to our annual blog series where we're asking each of our PyConUS 2026 keynote speakers about their journey into tech, how excited they are for Pycon US and any tips they can provide for an awesome conference experience!

Thank you to Rachell and Tim for this interview! You can learn more about their keynote on the PyConUS Keynote Speakers page and you can also attend their meet and greet at the PSF Booth in the Expo Hall on Friday May 15 from 1 to 2pm PT.



Without giving any too many spoilers, tell us what your keynote is about? 

Tim: Did Rachell answer this question already? Can I cheat off her response? No?


Hmm... Well, it's about Djangonaut Space, a contributor mentorship program for members of the Django community. It'll talk about why the founders created it, what it does, how it works, and why it works.


If you're a part of an open-source community or want to be a part of an open-source community, you may find the talk interesting. We've tackled some really hard freaking problems. Improving diversity, finding regular contributors, and helping them grow into community leaders.


When we sat down to discuss what we wanted to speak about (thanks again, Jon, for advocating for us!), we decided we wanted to focus on the human element. We lean pretty hard on that in our community, and our keynote reflects that.


So, what did Rachell say? 


Rachell: Tim and I want to talk about what happens when you invest in the people behind the commits. We're going to take you inside our open source mentorship program, Djangonaut Space. The success stories, the ripple effects, and how one person's growth becomes someone else's opportunity. Oh yeah, and there's some open source in there too!



How did you get started in tech/Python? Did you have a friend or a mentor that helped you?


Rachell: I had been teaching English for a while in South Korea and I wanted to do something else because I had kind of hit a plateau with where I was. So I tried to get a job at an e-publishing company that wanted someone with English teaching experience, some tech, and some business. I had one out of three.


I remember one of the questions they asked was if I knew what HTML was. I said it had something to do with the web. I had no idea beyond that. Kind of thankfully, I did not get that job, but it was the moment I realized tech touches everything, so I started learning. 


Did I have mentors and friends? Yes, lots, and I would not be here without them. The most impactful learning experience from one was when I asked a friend a question and he said “I don’t know, let’s google it”. And I was shocked that he didn’t know everything. This normalized not knowing everything and made me feel a lot more comfortable while I was learning and even today!  Tim: As a child, like a 5-year-old child, my mom was supportive of me messing around on the home computer. I still have this fuzzy memory of me at school "fixing" the computer in kindergarten. In reality, I was just unplugging and plugging things back in, but hey, it worked!


I got into programming in college when I was accidentally put into the computer engineering program. I noticed it about two weeks before courses started but figured it couldn't be too much different than the business school's management information systems degree. After my freshman year, I got an internship at a local company where I learned so much about web development, the software development lifecycle, and working in a corporate environment. That was incredibly helpful to my development.


A year after college, I decided to build my own SaaS (and move across the country). That's when I finally picked up Python and Django. I got started with "Learn Python the Hard Way" and was lucky enough to work with Greg Newman on a project early on.


Though to specifically answer your question, outside the few years I worked in a corporate environment with a manager, I haven't had a stereotypical mentor. I've absorbed knowledge and wisdom from friends, colleagues, and the old standby, the trial and error approach.



What do you think the most important work you’ve ever done is? Or if you think it might still be in the future, can you tell us something about your plans?


Rachell: Hands down it's helping people find their opportunity for upward mobility. It's so easy to get in the weeds with a language, a framework, or even industry specific stuff, especially at conferences. But the point I always come back to with any community work that I do or have done is that this work is giving people their opportunity for upward mobility in a world where that is extremely difficult.


More important than Python, or this package, or a conference talk is helping people be financially stable. Housing, food on the table, health insurance, not constantly stressed about making ends meet. People can't thrive and volunteer their time if they are just surviving.


For me personally, I was a late career transitioner, and the upward mobility I experienced didn’t just help me but also my extended family. It's so impactful. I even need reminders sometimes of how impactful community work can be because I get so deep into the details about, ya know, “what is the exact hex of the logo on this t-shirt for an event”. 


I know folks who have directly benefited from the community organizing I've been a part of in Django Girls, Djangonaut Space, and even just personally. Some have transitioned careers, others found a job after a long time struggling. A good friend attributes the ability to have a kid (a very cute one!) to me because without the career transition into tech, she wouldn't have been able to afford to raise one.


And this motivates me and keeps me organizing. It's not everyone that shows up to a Djangonaut Space session that is going to have some life-changing experience, but maybe one will. And that's enough. Tim: I'm a middle child, so I have literally grown up with a complex to please people, mediate situations, and help things move forward. It's also probably why I crave praise but absolutely hate getting it. I'm pretty sure that's why my answer to this is helping people contribute to open-source software.  


It's something I've been doing in one way or another for a while. In 2020, my efforts picked up quite a bit with Underdog Devs and then getting way more involved in the Django community.


I think the reason why I find it important was solidified when I read my friend Eric Matthes' post "Coding is Political". Programming, software development, and software engineering are something anyone can learn; you don't need a degree for them, and you can get paid a lot to do them. Contributing to open source isn't the only way to learn these skills, but it's freely accessible and provides a benefit to others.


If I can help cultivate organizational cultures and systems that support more people contributing to open source so they learn skills that help them get paid, well, that'd be pretty cool.


Have you been to PyCon US before? What are you looking forward to?


Rachell: I’ve been to PyCon US a few times, but it’s been a while! It’ll be nice to be back. I sometimes feel a bit out of my depth because there are just so many people, but I counter that with finding pockets of smaller spaces to really connect with people. Which is why I like the open spaces, they’re so fun and I always meet new people. 


Tim: No, this will be my first PyCon US. Back in December, I was so excited to come to my first PyCon, blend into the background, and enjoy a new conference purely as an attendee. In fact, I had bought my plane tickets, lodging, and my conference tickets. Then Elaine and Jon invited us to keynote, which threw all those plans right out the window.


What I'm looking forward to is meeting a bunch of new people and experiencing the PyCon US culture. I'm excited to see the similarities and differences between DjangoCon US and PyCon US.


Do you have any advice for first-time conference goers or any general conference tips?


Rachell: Think carefully about what kind of experience you want, and what you want to get out of the conference. If you want to meet people, for example, a great way to do that is to volunteer, or find some interesting open spaces to attend. I love volunteering at registration because you get to see and meet so many people and they have to come to you! It makes saying hi super easy.


If you are interested in certain topics, find those talks and go there! Other people attending the talk are likely just as interested. 


Lastly, drink a lot of water, take breaks when you need them. For example, go outside for a short walk to get some fresh air, it can really recharge you in a mid-day energy slump. 

Tim: In general, eat some protein in the morning. I've been contemplating bringing protein powder to supplement my breakfast. Though this may be a me thing since I tend to not eat when I get nervous.


The better advice is to reflect on your goals for the conference before the conference. Kojo Idrissa shared this wisdom at a DjangoCon US and it made so much sense. By knowing what you want to come away from the conference with, you can put yourself in a position to make that happen. For example, at that event, I wanted to get to know people. So I hung out in the common areas just before dinner. I ate dinner with different groups each night with zero planning. One of those nights, I was in the back of a van with the hosts of my favorite podcast.



Can you tell us about an open source or open culture project that you think not enough people know about?


Rachell: Have you heard of Outreachy? It's an open source mentorship program that pays!


 "Outreachy provides internships in open source. Outreachy provides internships to anyone from any background who faces underrepresentation, systemic bias, or discrimination in the technical industry where they are living."     



Djangonaut Space was not built in a vacuum, and this was definitely one of the organizations we pulled inspiration from in creating it. Although we aren’t there yet, I think paying people for their time is amazing and really important in lowering the barriers to participating in open source. Working for free is a huge barrier. Tim: Yes, I can! I'd love to shout out the Django Commons organization. It's a home for community-maintained Django packages. It seeks to improve the maintenance experience for package maintainers.


What excites me about this organization is that it's working to provide a framework for making the Django ecosystem (and by extension the Python ecosystem) more robust. Maintaining an open-source package can feel like a lonely endeavor at times, but this is a community that wants to support you.


It does so by:

  • Providing a home for community-maintained packages and supporting easy transitions of maintainers
  • Managing teams and permissions for contributors, maintainers, and administrators of each package
  • Having multiple organization administrators (we just brought new people on in April!)
  • Automate actions as much as possible
  • Provide best practices for packages
  • Providing a mechanism for being paid for open-source work


If you have to maintain a Python or Django package and are looking for a more community-based maintenance approach, consider transitioning your project to Django Commons. Or if you're looking to get started contributing to open source and find the larger projects a bit intimidating, consider contributing to one of our packages!





April 23, 2026 05:01 PM UTC


Python Software Foundation

Announcing Python Software Foundation Fellow Members for Q1 2026! 🎉

The PSF is pleased to announce its first batch of PSF Fellows for 2026. Let us welcome the new PSF Fellows for Q1! The following people continue to do amazing things for the Python community:

Bill Deegan

Website, LinkedIn, GitHub, X

El-karece Asiedu

LinkedIn

(James) Kanin Kearpimy

Linktree

Jonas Obrist

Kristen McIntyre

Lucie Anglade

Website

Phebe Polk

Philippe Gagnon

Sarah Kuchinsky

Mastodon, Bluesky

Simon Charette

LinkedIn, GitHub

Sony Valdez

Website, GitHub

Stan Ulbrych

GitHub, Mastodon

Steve Yonkeu

Website, GitHub

 

Thank you for your continued contributions. We have added you to our Fellows Roster.

The above members help support the Python ecosystem by being phenomenal leaders, sustaining the growth of the Python scientific community, maintaining virtual Python communities, maintaining Python libraries, creating educational material, organizing Python events and conferences, starting Python communities in local regions, and overall being great mentors in our community. Each of them continues to help make Python more accessible around the world. To learn more about the new Fellow members, check out their links above.

Let's continue recognizing Pythonistas all over the world for their impact on our community. The criteria for Fellow members is available on our PSF Fellow Membership page. If you would like to nominate someone to be a PSF Fellow, please send a description of their Python accomplishments and their email address to psf-fellow at python.org. We are accepting nominations for Quarter 2 of 2026 through May 20th, 2026.

Are you a PSF Fellow and want to help the Work Group review nominations? Contact us at psf-fellow at python.org.

April 23, 2026 03:05 PM UTC


EuroPython

April Newsletter: First Keynote Speakers Announcements

Hi all Pythonistas! 👋 

As the spring sun charges us all with new energy, the EuroPython team has been busy translating that spring buzz into exciting progress with the conference. But don’t take our word for it—see for yourself:

🗣️ Keynote Speakers

We are thrilled to announce that these three speakers will be returning to EuroPython:

altGuido van Rossum, Creator of Python

Guido van Rossum created Python in 1990 while working at CWI in Amsterdam. He was the language&aposs BDFL until he stepped down in 2018. He has held various tech jobs, including Senior Staff Engineer at Google and Principal Engineer at Dropbox. He is currently a Distinguished Engineer at Microsoft, where he is still actively involved in Python&aposs development. Born and raised in the Netherlands, he moved to the US in 1995 and currently lives with his family in the Bay Area.


altPablo Galindo Salgado, CPython Core Developer

Pablo Galindo Salgado works in the Python team at Hudson River Trading. He is a CPython core developer and a theoretical physicist specialising in general relativity and black hole physics. He serves on the Python Steering Council, having been re-elected for his 6th term in 2026, and was the release manager for Python 3.10 and 3.11. He also has a cat, though it does not code.


altŁukasz Langa, Creator of Black

Łukasz Langa is a failed comedian. Wannabe musician. Python guy at Meta. Co-host of the core.py podcast. Former CPython Developer in Residence at the Python Software Foundation. Former Python release manager. Creator of Black.

Stay tuned for more information about EuroPython 2026 keynotes!

💸 Financial Aid

There is still time to apply for Financial Aid to attend EuroPython 2026, whether you want to attend in-person, or remotely. The first round of applications is now closed, however you have until 11 May to submit to the second round.

We strongly encourage anyone who needs support to attend the event to apply. Results from the first round of applications should be hitting inboxes very soon - but don’t worry, if you were not accepted, we will automatically consider you for the second round. 🤗

👉 For full details, including how to apply, visit https://ep2026.europython.eu/finaid/

✉️ Visa Support Letters

If you are attending EuroPython in person this year and you need a visa to enter Poland, then we are able to provide a letter in support of your visa application. Poland is part of the EU and Schengen Area, and we recommend referring to the official Polish government guidance to verify entry requirements before confirming your travel arrangements.

If you do need a visa, please book an appointment to obtain one as soon as possible, and let us know at least one week before your appointment so that we can prepare the letter for you.

👉 To request a visa support letter, and for links to official guidance on entry to Poland, please visit https://ep2026.europython.eu/visa/

🚀 Startup Row: A New Opportunity for Startups

New this year, Startup Row gives early-stage companies a focused way to get in front of a highly engaged developer audience. Enjoy a 3-day exhibition space to share what you’re building and connect with the Python community. Spots are limited—secure yours early.

👉 Learn more & get in touch: https://ep2026.europython.eu/sponsorship/sponsor/

👩‍🏫 Speaker Mentorship Program: Orientation

Do you want to improve your stage presence, learn how to confidently handle audience questions, and make sure that your talk is as engaging as possible? Our experienced community members are keen to support you! 💚

altEuroPython 2026 Speaker Mentorship Programme orientation meeting

The Speaker Mentorship Team is running an online workshop on the 3 June 2026, at 18:00 CEST. Whilst newer speakers are particularly encouraged to attend, we’ve designed the session for people of all experience levels—and we welcome speakers from other conferences, too! 🐍

👉 Register now to confirm your place: https://forms.gle/uZKwuAiBkUSmx7gn7

💰 Sponsorship: Packages Selling Out

While the Gold and Platinum sponsorship packages are almost sold out (wow!), we&aposve still a range of add-ons to help your company really connect with the EuroPython audience:

  1. Social Event Sponsor
  2. Hackathon Sponsor
  3. Speaker Dinner Sponsor
  4. Financial Aid Sponsor

🌐 More information at: https://ep2026.europython.eu/sponsorship/sponsor/#optional-add-ons

👉 Contact us at sponsoring@europython.eu

🤝 Community Partners

Here&aposs the latest from our partners:

Warsaw Python Pizza

Warsaw Python Pizza is a community-driven micro conference for Python enthusiasts featuring short, practical talks and great pizza. It will take place on 9 May, 2026, at PJAIT, Koszykowa 86 in Warsaw. Ticket sales are planned to start on April 24, and they expect to announce the speaker lineup on April 27. 

👉 Reach Warsaw Python Pizza: warsawpythonpizza@gmail.com

🌐 For more info visit https://warsaw.python.pizza/ 

PyData Trójmiasto

PyData Trójmiasto is an event that brings together AI/ML enthusiasts. Originally based in the Gdańsk area, currently it is held monthly in Gdynia. From the very beginning, it has focused on building a local community through the exchange of knowledge and experience. Organizers are actively looking for speakers and sponsors for future editions. 

👉 Get in touch with PyData Trójmiasto via kontakt@pydata-trojmiasto.pl or their social media.

🌐 Join them on Meetup: https://www.meetup.com/PyData-Trojmiasto 

DevOpsDays Kraków 2026

DevOpsDays Kraków 2026 is back on 4 July at ECHO Miasta, Kraków — the Call for Proposals is open until 10 May

👉 Submit a 30-minute talk or a 5-minute lightning talk at https://devopsdays.org/krakow. Real stories from production beat polished decks every time.

🔗 You can find more information about EuroPython 2026 Community Partners at https://ep2026.europython.eu/community-partners/

📣 Community Outreach: From Lithuania To Texas

April’s been a proper whirlwind for the community, and we’ve been right there cheering on our fellow organisers:

DjangoCon Europe

Several members of the EuroPython Society attended DjangoCon Europe in Athens between the 15 and 19 April. This was the first DjangoCon Europe to be held in Greece, and the location of the conference - immediately adjacent to the Lyceum of Aristotle and the National Gardens - felt like the perfect backdrop for three incredible days of talks. ✨

altAndrew Northall, member of the EuroPython 2026 Communications Team, promoting EuroPython at DjangoCon Europe 2026

PyCon DE & PyData 

We headed over to Darmstadt to support the community at the joint PyCon DE & PyData conference. This four-day event was packed with talks, masterclasses, sprints, and PyLadies sessions. EuroPython Society was one of the Diversity Sponsors of the conference.

PyCon Lithuania

We also supported the 15th edition of PyCon Lithuania, held in Vilnius from 8 to 10 May. It’s a three-day event and the largest Python and PyData gathering in the Baltic and Nordic regions, with over 600 participants.

PyTexas

Last but not least, we have also visited PyTexas, a three-day conference located in Austin, which celebrated its 20th anniversary. In a lightning talk, we have invited attendees to join us in the City of Castle and Dragons in July to enjoy pierogi, meeting European friends, and getting to know the lovely city.

A photo of a EuroPython Society banner in an event venue, with wooden glass doors through which attendees can be seenThat EuroPython Society banner made the trip all the way to Austin for PyTexas with Ege Akman

🎁 Sponsors Spotlight

We&aposd like to thank Manychat for sponsoring EuroPython.

Manychat builds AI-powered chat automation for 1M+ creators and brands at real production scale.

The Manychat wordmark, a plain white background with black textView job openings at Manychat

👋 Stay Connected

Follow us on social media and subscribe to our newsletter for all the updates:

👉 Sign up for the newsletter: https://blog.europython.eu/portal/signup

Tickets are going on sale next week, and we’ll send you an email with the link. Our Programme team’s busy finalising all the talks, workshops, and bits and bobs, so we can share the full lineup with you soon. We have a few exciting months ahead of us. See you all in Kraków! 🐍❤️

Cheers,

The EuroPython Team

April 23, 2026 09:45 AM UTC


Armin Ronacher

Equity for Europeans

If you spend enough time in US business or finance conversations, one word keeps showing up: equity.

Coming from a German-speaking, central European background, I found it surprisingly hard to fully internalize what that word means. More than that, I find it very hard to talk with other Europeans about it. Worst of all it’s almost impossible to explain it in German without either sounding overly technical or losing an important part of the meaning.

This post is in English, but it is written mostly for readers in Germany, Austria, and Switzerland, and more broadly for people from continental Europe. I move between “German-speaking” and “continental European” a bit. They are not the same thing, of course, but many continental European countries share a civil-law background that differs sharply from the English common-law and equity tradition. The words differ by language and jurisdiction, but the conceptual gap I am interested in shows up in similar ways.

In US usage, the word “equity” appears everywhere:

If you try to translate this into German, you have to choose words. Of course we can say Eigenkapital, Beteiligung, Anteil, Vermögen, Nettovermögen, or sometimes Substanzwert. In narrow contexts, each can be correct, but none of them carries the full concept. I find that gap interesting, because language affects default behavior and how we think about things.

One Word, Shared Meanings

In the English language, “equity” often carries multiple things at once. I believe the following ones to be the most important ones:

  1. A legal-fairness dimension: historically tied to equity in law
  2. A financial-accounting dimension: residual value after debt
  3. A cultural dimension: ownership as a path to wealth and agency

If you open Wikipedia, you will find many more distinct meanings of equity, but they all relate to much the same concept, just from different angles.

German, on the other hand, can express each of these layers precisely, including the subtleties within each, but it uses different words and there is no common, everyday umbrella word that naturally bundles all three.

When a concept has one short, reusable, positive word, people can move it across contexts very easily. When the concept is split into technical fragments, it tends to stay technical, and people do not necessarily think of these things as related at all in a continental European context.

How Equity Got Here

What is hard for Europeans to understand is how the financial meaning of equity appeared, because it did not appear out of nowhere. The word’s original meaning comes from fairness or impartiality, and it made it to modern English via Old French and Latin (equité / aequitas).

Historically, English law had separate traditions: common law courts and courts of equity (especially the Court of Chancery). Equity in law was about fairness, conscience, and remedies where strict common law rules were too rigid. Take mortgages for instance: in older English practice, a mortgage could transfer title as security. Under strict common law, missing a deadline could mean losing the property entirely. Courts of equity developed the “equity of redemption”: a borrower could still redeem by paying what was owed.

That equitable interest became foundational for how ownership and claims were understood. In finance, equity came to mean not just a number, but a claim: the residual owner’s stake after prior claims are satisfied.

The European Split

German and continental European legal development took a different path. Civil law systems did not build the same separate institutional track of “equity courts” versus common law courts. Fairness principles absolutely exist, but inside the codified system, not as a parallel jurisdiction with its own language and mythology.

As a result, German vocabulary has many different words, and they are highly domain-specific. There are equivalents in other languages, and to some degree they exist in English too:

This precision is useful for legal drafting and accounting. But it also means we have less of the shared mental package that many Americans get from “equity”: own a piece, carry risk, participate in upside, build wealth.

Schuld Is Not Just Debt

There is another linguistic oddity worth noting: in German, “Schuld” can mean both debt/liability and guilt, and I think that too has changed how we think about equity.

“Schuld” in everyday language makes debt feel more morally charged than it does in the US. Indebtedness is often framed as a burden, and it is not thought of as a tool at all.

US financial language, by contrast, often frames debt more instrumentally and pairs it with an explicit positive counterpart: equity. Equity is what is yours after debt, what can appreciate, what can be transferred, and what can give you control.

In American financial language, debt is not as morally burdened, and equity is more than the absence of debt: it is the positive claim on the balance sheet — ownership, optionality, control, and upside.

Practical Matters

If you grew up with German-speaking framing, many US statements around equity can sound ideological or naive. From a continental European lens, they can sound like imported jargon or hollow. But if we ignore the concept, we lose something practical:

I am not saying German-speaking Europeans are incapable of this mindset. Obviously we are not. But we clearly tend to think about these things differently.

Normalize Equity

When you hear “equity,” it helps to think of it as a rightful stake. Historically, it is connected to fairness and the recognition of a claim where strict rules would be too rigid. Financially, it is the part that remains after prior obligations. Culturally, it is something that can grow into control, agency, and upside.

That is not a perfect definition, but it captures why the term is so sticky in American discourse. It combines a present claim with a future possibility. It is not just what remains after debt; it is the part that can grow, compound, and give you agency.

If Europeans want to talk more seriously about entrepreneurship, retirement, housing, and wealth building, we would benefit from a stronger everyday vocabulary for exactly this idea. We need a longing for equity so that ownership does not remain something for founders, lawyers, accountants, and wealthy families, but becomes a normal part of how people think about work, risk, and their future.

Not because we should imitate America, but because this mental model helps people make clearer decisions about ownership, incentives, and long-term agency. For Europe, that shift feels long overdue.

April 23, 2026 12:00 AM UTC

April 22, 2026


Kay Hayen

Nuitka Release 4.0

This is to inform you about the new stable release of Nuitka. It is the extremely compatible Python compiler, “download now”.

This release is a major release with many new features and the long wanted improvements for scalability of the Python compilation.

Bug Fixes

Package Support

New Features

Optimization

Anti-Bloat

Organizational

Tests

Cleanups

Summary

This release is finally a break-through for scalability. We will continue the push for scalability in the next release as well, but with more of a focus on the C compilation step, to generate C code that is easier for the backend compiler.

Also, this release finally addresses many usability problems. The non-deployment hooks for imports not found, that were actively excluded, are one such thing. The start of --project enables far easier adoption of Nuitka for existing projects.

Other huge improvements are related to generics, they are now much better support, closing gaps in the Python3.12 support.

The onefile DLL mode as used on Windows is finally perfect and should have no issues anymore, while enabling big future improvements.

Unfortunately 3.14 support is not yet ready and will have to be delayed until the next release.

April 22, 2026 06:03 PM UTC


Real Python

Altair: Declarative Charts With Python

There’s a moment many data analysts know well: you have a new dataset and a clear question, and you open a notebook only to find yourself writing boilerplate axis and figure setup before you’ve even looked at the data. Matplotlib gives you fine-grained control, but that control comes with a cost. Altair takes a completely different approach to data visualization in Python.

Instead of scripting every visual detail, you describe what your data means. This includes specifying which column goes on which axis, what should be colored, and what should be interactive. Altair then generates the visualization.

If you’re wondering whether it’s worth adding another visualization library to your toolkit, here’s how Altair and Matplotlib compare:

Use Case Pick Altair Pick Matplotlib
Interactive exploratory charts in notebooks
Pixel-precise publication figures or 3D plots

Altair generates web-native charts. The output is HTML and JavaScript, which means charts render right in your notebook and can be saved as standalone HTML files or embedded in web pages. It’s not a replacement for Matplotlib, and it doesn’t try to be. Think of them as tools you reach for in different situations.

Get Your Code: Click here to download the free sample code you’ll use to build interactive Python charts the declarative way with Altair.

Take the Quiz: Test your knowledge with our interactive “Altair: Declarative Charts With Python” quiz. You’ll receive a score upon completion to help you track your learning progress:


Interactive Quiz

Altair: Declarative Charts With Python

Test your knowledge of Altair, the declarative data visualization library for Python that turns DataFrames into interactive charts.

Start Using Altair in Python

It’s a good idea to install Altair in a dedicated virtual environment. It pulls in several dependencies like pandas and the Vega-Lite renderer, and a virtual environment keeps them from interfering with your other projects. Create one and install Altair with pip:

Language: Shell
$ python -m venv altair-venv
$ source altair-venv/bin/activate
(altair-venv) $ python -m pip install altair

This tutorial uses Python 3.14 and Altair 6.0. All the code runs inside a Jupyter notebook, which is the most common environment for interactive data exploration with Altair. If you prefer a different JavaScript-capable environment like VS Code, Google Colab, or JupyterLab, feel free to use that instead. To launch a Jupyter notebook, run the following:

Language: Shell
(altair-venv) $ python -m pip install notebook
(altair-venv) $ jupyter notebook

The second command launches the Jupyter Notebook server in your browser. Create a new notebook and enter the following code, which builds a bar chart from a small DataFrame containing daily step counts for one week:

Language: Python
import altair as alt
import pandas as pd

steps = pd.DataFrame({
    "Day": ["1-Mon", "2-Tue", "3-Wed", "4-Thu", "5-Fri", "6-Sat", "7-Sun"],
    "Steps": [6200, 8400, 7100, 9800, 5500, 9870, 3769],
})

weekly_steps = alt.Chart(steps).mark_bar().encode(
    x="Day",
    y="Steps",
)
weekly_steps

You should see a bar chart displaying daily step counts:

Altair Bar Chart Showing Daily Step CountsStep Counts as a Bar Chart

The dataset is intentionally minimal because data isn’t the main focus: it has seven rows for seven days, and two columns for the day name and step count. Notice how the weekly_steps chart is constructed. Every Altair chart follows this same pattern. It’s built from these three building blocks:

  • Data: A pandas DataFrame handed to alt.Chart().
  • Mark: The visual shape you want, chosen via .mark_*(). Here, .mark_bar() draws bars. Other options include .mark_point(), .mark_line(), and .mark_arc().
  • Encode: The mapping from data columns to visual properties, declared inside .encode(). Here, Day goes to the x-axis and Steps to the y-axis.

This is Altair’s core grammar in action: Data → Mark → Encode. You’ll use it every time.

Read the full article at https://realpython.com/altair-python/ »


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

April 22, 2026 02:00 PM UTC


PyCharm

PyCharm for Django Fundraiser: Why Django Matters in the AI Era – And Why We’re Supporting It

Spend a few minutes around developer content, and it’s easy to come away with the impression that web apps now appear to almost write themselves.

Everything that follows – review, verification, refactoring, debugging, and the open-source frameworks that make those apps dependable – gets less attention. AI can speed up code generation, but it does not remove the need for stable foundations. A lot of AI-generated code works because it’s built on top of mature open-source frameworks, libraries, and documentation. 

AI can scaffold a web app in thirty seconds. Django is what keeps it running for ten years. That gap is only getting more valuable.

Will Vincent, former Django Board Member, co-host of the Django Chat podcast and co-writer of the weekly Django News newsletter

As AI makes OSS easier to consume, it can also make the work behind it easier to overlook. But OSS still needs support – perhaps more than ever.

PyCharm for Django Fundraiser

PyCharm has supported Django through fundraising campaigns and ongoing collaboration with the Django Software Foundation (DSF). This year, we’re doing it again.

Together with the Django community, this campaign raised $350,000 for Django from 2016 to 2025. That support helps keep Django secure, stable, relevant, and sustainable, while also supporting community programs such as Django Girls and official events. Previous PyCharm fundraisers accounted for approximately 25% of the DSF budget, according to Django’s official blog.

Django is the rare framework that rewards you the longer you use it: mature, dependable, and still innovating. Best-in-class software, matched by one of the most welcoming communities in open source.

Will Vincent, former Django Board Member, co-host of the Django Chat podcast and co-writer of the weekly Django News newsletter

If Django has helped you learn, ship, or maintain real web products, this is a direct way to give back.

You can donate to the Django Software Foundation directly, or you can support Django through this fundraiser and get a tool you’ll rely on every day.

Django’s ‘batteries included’ philosophy was built for humans who wanted to ship fast. Turns out it’s perfect for AI agents too — fewer decisions, fewer dependencies, and fewer ways to go wrong.

Will Vincent, former Django Board Member, co-host of the Django Chat podcast and co-writer of the weekly Django News newsletter

The offer

During this campaign, get 30% off PyCharm Pro, with 100% of the proceeds going to the DSF. Or you can bundle PyCharm Pro with the JetBrains AI Pro plan and get 40% off PyCharm Pro.

This campaign ends in less than two weeks, so act now!

Why PyCharm Pro

Perfect for your workflow

The hard part of modern development is often not writing code from scratch – it’s understanding the whole project well enough to change it safely.

That’s where PyCharm Pro proves its value:

No editor understands Django like PyCharm does — from template tags to ORM queries to migrations, it sees the whole stack the way you do.

Will Vincent, former Django Board Member, co-host of the Django Chat podcast and co-writer of the weekly Django News newsletter

For Django work, I think PyCharm is one of the best tools available. I use it every day. If you haven’t given it a try, this campaign is a great opportunity – AND it supports the Django Software Foundation!

Sarah Boyce, Django Fellow and Djangonaut Space co-organizer

AI on your terms

If you want AI in PyCharm, you can start with JetBrains AI directly in the IDE. You can also shape it to fit your workflow. Bring your own key, sign in with a supported provider, use third-party or local models, or connect compatible agents such as Claude Code and Codex via ACP.

That gives you more control over how you work with AI, instead of locking you into a single workflow, model, or provider. And if AI isn’t what you need, you can simply turn it off.

Support the framework you use every day

If Django is part of how you build, this purchase can improve your workflow while also investing in the framework behind it.

Happy coding!

April 22, 2026 12:15 PM UTC


Real Python

Quiz: SQLite and SQLAlchemy in Python: Move Your Data Beyond Flat Files

In this quiz, you’ll test your understanding of the concepts in the video course SQLite and SQLAlchemy in Python: Move Your Data Beyond Flat Files.

By working through this quiz, you’ll revisit how Python, SQLite, and SQLAlchemy work together to give your programs reliable data storage. You’ll also check your grasp of primary and foreign keys, SQLAlchemy’s Core and ORM layers, and the many-to-many relationships that tie your data together.


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

April 22, 2026 12:00 PM UTC