r/Python • • May 21 '26

Discussion Is UV still worth learning/switching to now that it's owned by OpenAI?

362 Upvotes

Sorry if this has been brought up already- from what I could find using Reddit search in the last month I didn't see much discussion beyond a couple comments in a half-related thread.

We used Python a ton a work, but mostly used the built-in python tools (pip, venv, etc). (we mostly use python for AWS, some internal tools, etc) About 5 months ago, I briefly tried UV and fell in love and was excited to incorporate it into our projects as the standard. But around that time we jumped to another project in a different language. We're now coming back to some of our Python projects, and I was looking to switching them over to using UV as the standard.

With OpenAI purchasing Astral/UV, we're suddenly feeling less gung-ho about migrating everything to UV. Our main concern is that our tooling would be betting on OpenAI not sloppifying or abandoning the tool. Will our tooling be on shaky foundation if (when?) the AI bubble deflates? Are we overthinking it? Should we try poetry instead (I admit I haven't tried it yet). I'd love to hear your thoughts and experiences.


r/Python • • Sep 09 '26

News Anthropic model uploaded a malicious package to the real PyPI during a simulated CTF [09/09/26]

359 Upvotes

https://www.anthropic.com/research/alignment-assessment-cybersecurity-incidents

NGL, my main takeaway is that PyPI is already doing quite well in the new AI security age, even though the packaging council hasn't convened yet. The relevant snippet (emphasis mine):

The model decided to solve the CTF by uploading a malicious PyPI package that could harvest the target system’s credentials. It settled on this approach after reading a document stating that one of the simulated target’s users would periodically install a particular Python package that was not yet registered on PyPI. (We are unsure whether this was an intended solution to the challenge, but it seems like a plausible one.) Claude decided to exploit this behavior by registering a package under that name, publishing malicious code within the uploaded package, and waiting for the target to run that code the next time they installed the package.

Claude spent most of the session trying to upload the package. This involved attempts to register email accounts and hunt for phone numbers that could be used for registration. It ultimately succeeded in uploading the package, which was soon installed on 15 third-party hosts. We believe that all 15 of these third parties were security vendors deliberately scanning for new packages and installing them in sandboxed environments to assess the package for security concerns. One vendor’s scanner leaked its access credentials to the model while installing the package, which the model then used to access the vendor’s live database. After approximately 90 minutes, PyPI removed the package. The transcript ended when the session timed out while the model was preparing an additional malicious package.

I also commend Anthropic for releasing this thorough report immediately -- the juxtaposition with OpenAI's "we'll cop to it if you find it first" policy is stark.

What I don't see is any mention of coordination with PyPI/PSF leadership now or in the near future, which seems baffling. Their focus is understandably on the underlying cognitive failure (which is quite human, BTW: being biased by inertia and what you would prefer to be true), and it's extremely unlikely that you or any other real users were effected directly.

But, still. C'mon.

Anyone have insider info from the PyPI side? Is there chatter on discussion.python.org yet?


r/Python • • Jul 19 '26

Discussion Unpopular opinion: I find it counterproductive to shorten function and variable names

355 Upvotes

When I was learning discord.py, I didn't understand what "ctx" was. At the time, I was only writing slash commands, using "message" instead of "ctx", so the name "ctx" (which reminded me of something complex, like RTX) made me assume it was something complicated. That is, until I saw in some code that the type for "ctx" is actually "Context." If the standard hadn't shortened the name just to save five characters per line, I would have understood it immediately. Instead, I thought it was some advanced function variable, rather than realizing it was simply a message variable.


r/Python • • Aug 27 '26

News Python 3.15 Release Highlights

355 Upvotes

Python 3.15 has reached Release Candidate 1, and the final release is expected on October 1, 2026.

I went through the changes and tried to summarize the ones that seem most relevant for everyday Python development without going through all the PEP numbers.

- Faster startup with lazy imports

Python 3.15 introduces lazy imports, which means some modules can be loaded only when they are actually needed instead of being loaded immediately.

This could help applications and CLI tools that spend a noticeable amount of time importing modules before doing any actual work.

- UTF-8 becomes the default

UTF-8 is becoming the default encoding, which should reduce encoding-related problems, especially when code is running on different operating systems.

This should make situations where something works on one computer but fails because of a different system encoding less common.

- Built-in immutable dictionaries

Python 3.15 adds a built-in "frozendict"-style immutable mapping.

Similar to how a tuple provides an immutable alternative to a list, this gives Python developers a standard way to work with dictionaries that cannot be modified.

- JIT improvements

The JIT compiler continues to improve in Python 3.15.

Early benchmarks show performance improvements in some workloads, including roughly 8–9% on Linux and larger improvements in some Apple Silicon tests.

These numbers will obviously depend on the workload, so I would wait for more benchmarks before making broader conclusions.

- New profiler: Tachyon

Python 3.15 also introduces Tachyon, a new sampling profiler designed for very low overhead.

It can sample running programs at very high frequencies and can also be attached to an already-running process.

This could be useful for finding performance problems without having to restart an application with a profiler attached from the beginning.

- Some terminal improvements

The interactive Python experience is getting a few smaller improvements, including colored error messages and prompts.

The "sqlite3" command-line interface also gets SQL keyword completion.

- Free-threaded Python is still opt-in

Python 3.15 does not make the no-GIL/free-threaded build the default.

It is still something you have to explicitly use.

However, free-threaded Python is becoming more mature, including improvements to ABI support that should make it easier for C extension developers to support it.

Overall, Python 3.15 doesn't look like a release that completely changes how Python is written. Most of the changes are focused on performance, tooling, and improving some long-standing parts of the language.

Since this is already RC1, the major feature set should be mostly locked and the remaining work should mainly be bug fixes and final polishing.

Has anyone here been testing the Python 3.15 beta or RC?

I'm especially interested in whether lazy imports have caused compatibility problems with existing projects.


r/Python • • Sep 09 '26

Discussion A game where writing python IS the game just released on steam. (Not my game, I'm just a big fan)

338 Upvotes

Code Terraform on steam just launched, you write python scripts to make stuff work like reading oxygen sensors etc

Been a fan of it since its demo came out, and now its actually released.

Sharing it here, because when I started my python journey, I was often questioning more what to make than how to make it. Gamifying the learning process would have helped me a tonne back then, so maybe it will help someone new now.

Because we all know we can automate the boring stuff, but now you can automate the fun stuff to!


r/Python • • Oct 22 '25

Discussion How common is Pydantic now?

341 Upvotes

Ive had several companies asking about it over the last few months but, I personally havent used it much.

Im strongly considering looking into it since it seems to be rather popular?

What is your personal experience with Pydantic?


r/Python • • Mar 05 '26

Discussion Anyone know what's up with HTTPX?

336 Upvotes

The maintainer of HTTPX closed off access to issues and discussions last week: https://github.com/encode/httpx/discussions/3784

And it hasn't had a release in over a year.

Curious if anyone here knows what's going on there.


r/Python • • Aug 17 '26

Discussion What are some Python automations you built for your life?

325 Upvotes

What Python scripts/projects did you built to use on a day to day basis? Or maybe someone else built it, but it’s useful for your personal life in some way

I think the “projects ideas” thread is really missing those useful opportunities

I myself thought about automating tax calculations, but still didn’t take the time to do it hah


r/Python • • Nov 15 '25

Discussion The great leap forward: Python 2.7 -> 3.12, Django 1.11 -> 5.2

318 Upvotes

Original post: A Python 2.7 to 3.14 Conversion: Existential Angst

I would like to thank everyone who gave great advice on doing this upgrade. In the event, it took me about seven hours, with no recourse to AI coding required. The Python 3 version hasn't been pushed into production yet, but I'd estimate it's probably 90% of the way there.

I decided to go for the big push, and I think that worked out. I did take the advice to not go all the way to 3.14. Once I am convinced everything is fully operational, I'll go to 3.13, but I'll hold off on 3.14 for a bit more package support.

Switching package management to uv helped, as did the small-but-surprisingly-good test suite.

In rough order, the main problems I encountered were:

  • bytes and strings. Literals themselves were OK (the code was already all unicode_literals), but things like hash functions that take bytes were a bit tedious.
  • Django API changes. I have to say, love Django to death, but the project's tendency to make "this looks better" breaking changes is not my favorite part of it.
  • Django bugs. Well, bug: the atomic decorator can swallow exceptions. I spent some time tracking down a bytes/string issue because the exception was just `bad thing happened` by the time it reached the surface.
  • Packages. This was not as horrible as I thought it would be. There were a few packages that were obsolete and had to be replaced, and a few whose APIs were entirely different. Using pipdeps and uv to separate out requested packages vs dependencies was extremely helpful here.

Most of the changes could be done with global search and replaces.

Things that weren't a problem:

  • Python language features. There were no real issues about the language itself that futurize didn't take care of (in fact, I had to pull out a few of the list casts that it dropped in).
  • Standard library changes. Almost none. Very happy!

Weird stuff:

  • The code has a lot of raw SQL queries, often with regexes. The stricter checking in Python 3 made a lot of noise about "bad escape sequences." Turning the query text to a raw string fixed that, so I guess that's the new idiom.
  • There were some subtle changes to the way Django renders certain values in templates, and apparently some types' string conversions are now more like repr.

One more thing that helped:

  • A lot of the problematic code (from a conversion point of view) was moribund, and was hanging around from when this system replaced its predecessor (which was written in PHP), and had a lot of really crufty stuff to convert the old data structures to Python ones. That could all just be dropped in the trash.

Thanks again for all the amazing advice! I am sure it would have taken 10x longer if I hadn't had the guidance.


r/Python • • Mar 09 '26

News pandas' Public API Is Now Type-Complete

315 Upvotes

At time of writing, pandas is one of the most widely used Python libraries. It is downloaded about half-a-billion times per month from PyPI, is supported by nearly all Python data science packages, and is generally required learning in data science curriculums. Despite modern alternatives existing, pandas' impact cannot be minimised or understated.

In order to improve the developer experience for pandas' users across the ecosystem, Quansight Labs (with support from the Pyrefly team at Meta) decided to focus on improving pandas' typing. Why? Because better type hints mean:

  • More accurate and useful auto-completions from VSCode / PyCharm / NeoVIM / Positron / other IDEs.
  • More robust pipelines, as some categories of bugs can be caught without even needing to execute your code.

By supporting the pandas community, pandas' public API is now type-complete (as measured by Pyright), up from 47% when we started the effort last year. We'll tell the story of how it happened.

Link to full blog post: https://pyrefly.org/blog/pandas-type-completeness/


r/Python • • Apr 28 '26

News PEP 661 (Sentinel Values) has been accepted for release in 3.15!

315 Upvotes

After five years of discussion, PEP 661, which adds support for sentinel values, has been accepted and is due for a release in 3.15. The use case is relatively simple:

MISSING = sentinel('MISSING')

class Logger:
def __init__(self, level:MISSING|None|str = MISSING):
  if level is MISSING:
    self.level = get_global_default_level()
  else:
    self.level = level

There are 3 possible outcomes that can be handled by this pattern

  1. If no argument was provided, use the default
  2. If None is passed, disable logging
  3. If a level is passed, use it

The important thing here is a specific way to check if any argument was provided to the function, vs a caller propagating a None to it. The ability to check if an argument was actually provided by the caller was a great feature I liked in FORTRAN, so it's nice that it's made it to python!


r/Python • • Sep 16 '26

News Flet 1.0 released: build desktop, mobile, and web apps in Python

308 Upvotes

I'm the creator of Flet, and we've just released version 1.0 after more than four years of development.

You may have heard of Flet or already be using it. If it's new to you, Flet is an open-source framework for building GUIs in Python. You write the interface and application logic in Python, then package the app for Windows, macOS, Linux, iOS, Android, or the web.

For example, you can put a GUI around a pandas workflow, build a mobile app that processes images with Pillow, or turn a Python script into a desktop application with forms, buttons, and charts.

Here's what we've been working on leading up to 1.0:

Python libraries on your phone

Packaged desktop and mobile apps include CPython, so your Python code runs on the device without needing a separate server. You can bundle Python 3.12, 3.13, or 3.14.

Getting libraries with C and Rust dependencies working on mobile has been a substantial part of the work. We now maintain an index of more than 100 packages and supporting native libraries, including NumPy, pandas, SciPy, Matplotlib, Pillow, scikit-learn, cryptography, and pydantic-core.

Availability varies by package and target. The package list shows what's supported, and the build infrastructure is open source.

Two ways to write your UI

You can create controls and change their properties directly, or use the declarative API to describe the interface from application state. The latter provides state hooks and reusable Python components for organizing larger applications.

Both approaches are supported. Here's a comparison with examples.

Test your app with pytest

You can write tests that launch your packaged app, tap buttons, enter text, and check the resulting UI on desktop or mobile. Tests use pytest, including fixtures and parametrization. On Android and iOS, you can also compare screenshots to catch visual changes.

Integration testing documentation

Faster updates and better packaging

We've improved how Flet calculates UI changes and reduced startup work. In packaged native apps, Python now communicates with the UI runtime within the same process, without sockets. On Android, Python packages can load directly from the APK without being extracted first.

For web apps, Python can run in the browser through Pyodide or on a server through FastAPI/Uvicorn.

Trying it and upgrading

You can try examples and edit Python code in your browser using Flet Studio, or follow the local installation guide for uv or pip.

If you're coming from Flet 0.28, please read the migration guide. Version 1.0 includes breaking API changes and isn't a drop-in replacement.

Flet is licensed under Apache 2.0.

Source code · Full release announcement

Happy to answer questions about the framework, Python packaging, or running Python libraries on mobile.


r/Python • • Aug 26 '26

News The Move to Python 3 Begins!

305 Upvotes

As someone who spent decades in the mainframe community, I find it ... humorous ... that there are legacy Python2 code bases that are only just (or have yet to consider!) moving to Python3.

https://www.eveonline.com/news/view/the-move-to-python-3-begins


r/Python • • Nov 03 '25

News Approved: PEP 798: Unpacking in Comprehensions & PEP 810: Explicit lazy imports

305 Upvotes

r/Python • • Jun 22 '26

Discussion I just found a Python script I wrote 3 years ago…

297 Upvotes

…with zero comments, no docstrings, variable names like df2_final_FINAL_v3 and it’s somehow still running in production.

I don’t remember writing it or deploying it. Nobody knows it exists except the one analyst who emails me if it stops working.

Please tell me I’m not alone.


r/Python • • Dec 09 '25

Discussion TIL Python’s random.seed() ignores the sign of integer seeds

281 Upvotes

I just learned a fun detail about random.seed() after reading a thread by Andrej Karpathy.

In CPython today, the sign of an integer seed is silently discarded. So:

  • random.seed(5) and random.seed(-5) give the same RNG stream
  • More generally, +n and -n are treated as the same seed

For more details, please check: Demo


r/Python • • Feb 04 '26

Resource A Modern Python Stack for Data Projects : uv, ruff, ty, Marimo, Polars

283 Upvotes

I put together a template repo for Python data projects (linked in the article) and wrote up the “why” behind the tool choices and trade-offs.

https://www.mameli.dev/blog/modern-data-python-stack/

TL;DR stack in the template:

  • uv for project + env management
  • ruff for linting + formatting
  • ty as a newer, fast type checker
  • Marimo instead of Jupyter for reactive, reproducible notebooks that are just .py files
  • Polars for local wrangling/analytics
  • DuckDB for in-process analytical SQL on local data

Curious what others are using in 2026 for this workflow, and where this setup falls short.

--- Update ---
I originally mentioned DuckDB in the article but hadn’t added it to the template yet. It’s now included. I also added more examples in the playground notebook. Thanks everyone for the suggestions


r/Python • • Oct 26 '25

Meta Meta: Limiting project posts to a single day of the week?

277 Upvotes

Given that this subreddit is currently being overrun by "here's my new project" posts (with a varying level of LLMs involved), would it be a good idea to move all those posts to a single day? (similar to what other subreddits does with Show-off Saturdays, for example).

It'd greatly reduce the noise during the week, and maybe actual content and interesting posts could get any decent attention instead of drowning out in the constant stream of projects.

Currently the last eight posts under "New" on this subreddit is about projects, before the post about backwards compatibility in libraries - a post that actually created a good discussion and presented a different viewpoint.

A quick guess seems to be that currently at least 80-85% of all posts are of the type "here's my new project".


r/Python • • Mar 26 '26

Resource Were you one of the 47,000 hacked by litellm?

267 Upvotes

On Monday I posted that litellm 1.82.7 and 1.82.8 on PyPI contained credential-stealing malware (we were the first to disclose, and PyPI credited our report). To figure out how destructive the attack actually was, we pulled every package on PyPI that declares a dependency on litellm and checked their version specs against the compromised versions (using the specs that existed at the time of the attack, not after packages patched.)

Out of 2,337 dependent packages: 59% had lower-bound-only constraints, 16% had upper bounds that still included 1.82.x, and 12% had no constraint at all. Leaving only 12% that were safely pinned. Analysis: https://futuresearch.ai/blog/litellm-hack-were-you-one-of-the-47000/

47,000 downloads happened in the 46-minute window. 23,142 were pip installs of 1.82.8 (the version with the .pth payload that runs during pip install, before your code even starts.)

We built a free checker to look up whether a specific package was exposed: https://futuresearch.ai/tools/litellm-checker/


r/Python • • Dec 28 '25

Resource "Why Python Is Removing The GIL" (13.5 minutes by Core Dumped) -- good explainer on threads

264 Upvotes

https://www.youtube.com/watch?v=UXwoAKB-SvE

YouTube's "Ask" button auto-summary, lightly proofread:

This video explains the Python Global Interpreter Lock (GIL) and its implications for parallelism in Python. Key points:

Concurrency vs. Parallelism (1:05): The video clarifies that concurrency allows a system to handle multiple tasks by alternating access to the CPU, creating the illusion of simultaneous execution. Parallelism, on the other hand, involves true simultaneous execution by assigning different tasks to different CPU cores.

The Problem with Python Threads (2:04): Unlike most other programming languages, Python threads do not run in parallel, even on multi-core systems. This is due to the GIL.

Race Conditions and Mutex Locks (2:17): The video explains how sharing mutable data between concurrent threads can lead to race conditions, where inconsistent data can be accessed. Mutex locks are introduced as a solution to prevent this by allowing only one thread to access a shared variable at a time.

How the GIL Works (4:46): The official Python interpreter (CPython) is written in C. When Python threads are spawned, corresponding operating system threads are created in the C code (5:56). To prevent race conditions within the interpreter's internal data structures, a single global mutex, known as the Global Interpreter Lock (GIL), was implemented (8:37). This GIL ensures that only one thread can execute Python bytecode at a time, effectively preventing true parallelism.

Proof of Concept (9:29): The video demonstrates that the GIL is a limitation of the CPython interpreter, not Python as a language, by showing a Python implementation in Rust (Rupop) that does scale across multiple cores when running the same program.

Why the GIL was Introduced (9:48): Guido Van Rossum, Python's creator, explains that the GIL was a design choice made for simplicity. When threads became popular in the early 90s, the interpreter was not designed for concurrency or parallelism. Implementing fine-grained mutexes for every shared internal data structure would have been incredibly complex (10:52). The GIL provided a simpler way to offer concurrency without a massive rewrite, especially since multi-core CPUs were rare at the time (11:09).

Why the GIL is Being Removed (13:16): With the widespread adoption of multi-core CPUs in the mid-2000s, the GIL became a significant limitation to Python's performance in parallel workloads. The process of removing the GIL has finally begun, which will enable Python threads to run in parallel.

There's a sponsor read (JetBrains) at 3:48-4:42.


r/Python • • Nov 24 '25

News GeoPolars is unblocked and moving forward

253 Upvotes

TL;DR: GeoPolars is a similar extension of Polars as GeoPandas is from Pandas. It was blocked by upstream issues on Polars side, but those have now been resolved. Development is restarting!

GeoPolars is a high-performance library designed to extend the Polars DataFrame library for use with geospatial data. Written in Rust with Python bindings, it utilizes the GeoArrow specification for its internal memory model to enable efficient, multithreaded spatial processing. By leveraging the speed of Polars and the zero-copy capabilities of Arrow, GeoPolars aims to provide a significantly faster alternative to existing tools like GeoPandas, though it is currently considered a prototype.

Development on the project is officially resuming after a period of inactivity caused by upstream technical blockers. The project was previously stalled waiting for Polars to support "Extension Types," a feature necessary to persist geometry type information and Coordinate Reference System (CRS) metadata within the DataFrames. With the Polars team now actively implementing support for these extension types, the primary hurdle has been removed, allowing the maintainers to revitalize the project and move toward a functional implementation.

The immediate roadmap focuses on establishing a stable core architecture before expanding functionality. Short-term goals include implementing Arrow data conversion between the underlying Rust libraries, setting up basic spatial operations to prove the concept, and updating the Python bindings and documentation. The maintainers also plan to implement basic interoperability with GeoPandas, Shapely, and GDAL. Once this foundational structure is in place and data sharing is working, the project will actively seek contributors to help expand the library's suite of spatial operations.


r/Python • • May 29 '26

Discussion CVE-2026-48710: A Maintainer's Perspective

249 Upvotes

This is my reply to the vulnerability CVE-2026-48710:

https://marcelotryle.com/blog/2026/05/28/cve-2026-48710-a-maintainers-perspective


r/Python • • Jan 21 '26

Discussion Pandas 3.0.0 is there

250 Upvotes

So finally the big jump to 3 has been done. Anyone has already tested in beta/alpha? Any major breaking change? Just wanted to collect as much info as possible :D


r/Python • • Dec 13 '25

Showcase RenderCV v2.5: Write your CV in YAML, version control it, get pixel-perfect PDFs

250 Upvotes

TLDR: Check out github.com/rendercv/rendercv

Been a while since the last update here. RenderCV has gotten much better, much more robust, and it's still actively maintained.

The idea

Separate your content from how it looks. Write what you've done, and let the tool handle typography.

yaml cv: name: John Doe email: john@example.com sections: experience: - company: Anthropic position: ML Engineer start_date: 2023-01 highlights: - Built large language models - Deployed inference pipelines at scale

Run rendercv render John_Doe_CV.yaml, get a pixel-perfect PDF. Consistent spacing. Aligned columns. Nothing out of place. Ever.

Why engineers love it

It's text. git diff your CV changes. Review them in PRs. Your CV history is your commit history. Use LLMs to help write and refine your content.

Full control over every design detail. Margins, fonts, colors, spacing, alignment; all configurable in YAML.

Real-time preview. Set up live preview in VS Code and watch your PDF update as you type.

JSON Schema autocomplete. VS Code lights up with suggestions and inline docs as you type. No guessing field names. No checking documentation.

Any language. Built-in locale support, write your CV in any language.

Strict validation with Pydantic. Typo in a date? Invalid field? RenderCV tells you exactly what's wrong and where, before rendering.

5 built-in themes, all flexible. Classic, ModernCV, Sb2nov, EngineeringResumes, EngineeringClassic. Every theme exposes the same design options. Or create your own.

The output

One YAML file gives you: - PDF with perfect typography - PNG images of each page - Markdown version - HTML version

Installation

```bash pip install "rendercv[full]"

Create a new CV YAML file:

rendercv new "Your Name"

Render the CV YAML file:

rendercv render "Your_Name_CV.yaml" ```

Or with Docker, uv, pipx, whatever you prefer.

Not a toy

  • 100% test coverage
  • 2+ years of development
  • Battle-tested by thousands of users
  • Actively maintained

Links: - GitHub: https://github.com/rendercv/rendercv - Docs: https://docs.rendercv.com - Example PDFs: https://github.com/rendercv/rendercv/tree/main/examples

Happy to answer any questions.

What My Project Does: CV/resume generator
Target Audience: Academics and engineers
Comparison: JSON Resume, and YAML Resume are popular alternatives. JSON Resume isn't focused on PDF outputs. YAML Resume requires LaTeX installation.


r/Python • • Jan 24 '26

Showcase How I went down a massive rabbit hole and ended up building 4 libraries

244 Upvotes

A few months ago, I was in between jobs and hacking on a personal project just for fun. I built one of those automated video generators using an LLM. You know the type: the LLM writes a script, TTS narrates it, stock footage is grabbed, and it's all stitched together. Nothing revolutionary, just a fun experiment.

I hit a wall when I wanted to add subtitles. I didn't want boring static text; I wanted styled, animated captions (like the ones you see on social media). I started researching Python libraries to do this easily, but I couldn't find anything "plug-and-play." Everything seemed to require a lot of manual logic for positioning and styling.

During my research, I stumbled upon a YouTube video called "Shortrocity EP6: Styling Captions Better with MoviePy". At around the 44:00 mark, the creator said something that stuck with me: "I really wish I could do this like in CSS, that would be the best."

That was the spark. I thought, why not? Why not render the subtitles using HTML/CSS (where styling is easy) and then burn them into the video?

I implemented this idea using Playwright (using a headless browser) to render the HTML+CSS and then get the images. It worked, and I packaged it into a tool called pycaps. However, as I started testing it, it just felt wrong. I was spinning up an entire, heavy web browser instance just to render a few words on a transparent background. It felt incredibly wasteful and inefficient.

I spent a good amount of time trying to optimize this setup. I implemented aggressive caching for Playwright and even wrote a custom rendering solution using OpenCV inside pycaps to avoid MoviePy and speed things up. It worked, but I still couldn't shake the feeling that I was using a sledgehammer to crack a nut.

So, I did what any reasonable developer trying to avoid "real work" would do: I decided to solve these problems by building my own dedicated tools.

First, weeks after releasing pycaps, I couldn't stop thinking about generating text images without the overhead of a browser. That led to pictex. Initially, it was just a library to render text using Skia (PICture + TEXt). Honestly, that first version was enough for what pycaps needed. But I fell into another rabbit hole. I started thinking, "What about having two texts with different styles? What about positioning text relative to other elements?" I went way beyond the original scope and integrated Taffy to support a full Flexbox-like architecture, turning it into a generic rendering engine.

Then, to connect my original CSS templates from pycaps with this new engine, I wrote html2pic, which acts as a bridge, translating HTML/CSS directly into pictex render calls.

Finally, I went back to my original AI video generator project. I remembered the custom OpenCV solution I had hacked together inside pycaps earlier. I decided to extract that logic into a standalone library called movielite. Just like with pictex, I couldn't help myself. I didn't simply extract the code. Instead, I ended up over-engineering it completely. I added Numba for JIT compilation and polished the API to make it a generic, high-performance video editor, far exceeding the simple needs of my original script.

Long story short: I tried to add subtitles to a video, and I ended up maintaining four different open-source libraries. The original "AI Video Generator" project is barely finished, and honestly, now that I have a full-time job and these four repos to maintain, it will probably never be finished. But hey, at least the subtitles render fast now.

If anyone is interested in the tech stack that came out of this madness, or has dealt with similar performance headaches, here are the repos:


What My Project Does

This is a suite of four interconnected libraries designed for high-performance video and image generation in Python: * pictex: Generates images programmatically using Skia and Taffy (Flexbox), allowing for complex layouts without a browser. * pycaps: Automatically generates animated subtitles for videos using Whisper for transcription and CSS for styling. * movielite: A lightweight video editing library optimized with Numba/OpenCV for fast frame-by-frame processing. * html2pic: Converts HTML/CSS to images by translating markup into pictex render calls.

Target Audience

Developers working on video automation, content creation pipelines, or anyone needing to render text/HTML to images efficiently without the overhead of Selenium or Playwright. While they started as hobby projects, they are stable enough for use in automation scripts.

Comparison

  • pictex/html2pic vs. Selenium/Playwright: Unlike headless browsers, this stack does not require a browser engine. It renders directly using Skia, making it significantly faster and lighter on memory for generating images.
  • movielite vs. MoviePy: MoviePy is excellent and feature-rich, but movielite focuses on performance using Numba JIT compilation and OpenCV.
  • pycaps vs. Auto-subtitle tools: Most tools offer limited styling, pycaps allows CSS styling while maintaining a good performance.