Ephes Blog

Miscellaneous things. Mostly Weeknotes and links I stumbled upon.


Weeknotes 2025-05-19

KptnCook

Nero3ooo developed a helpful Progressive Web App (PWA) frontend for my KptnCook scraper. This is particularly useful if you use the KptnCook app on your smartphone and want to save recipes for later. Now, you can simply use the share button in the KptnCook app to share recipes directly with the PWA. I feel a bit guilty about neglecting KptnCook lately, as I've been so busy. I really should maintain it more actively 😅.

Progress Update on Vibe Coding Project

I've made significant progress on my vibe coding experiment (Nyxmon). The monitoring agent is now running fairly stably, so I decided to create a dashboard to display all the checks in one place. To make use of the empty space, I added a progress ring that shows when each check will run next. Users can manually trigger checks or disable them as needed. While it looks like a modern single-page application, it's actually a traditional multi-page application that uses htmx and some web components running on a Django backend. My next steps will be implementing more sophisticated checks that go beyond simple HTTP status monitoring—like analyzing JSON responses or supporting other protocols such as ICMP.

Articles

Videos

Software


Weeknotes 2025-05-12

The thing about being wrong is that before you know you’re wrong, it feels •exactly• like being right. --Roman Mars

Beyond Tellerrand 2025

I attended the Beyond Tellerrand conference in Düsseldorf this year. Being local residents, my partner and I didn't have to travel far to the venue, and since we're both interested in the topics, we always attend together. In previous years, we'd bring our children along, taking turns watching them between talks. This year marked the first time both kids were in kindergarten or school in the mornings and at playdates in the afternoons, so they didn't join us. Several attendees actually noticed their absence and asked where we'd "left the little ones."

The conference was excellent as always. I gained plenty of inspiration and thoroughly enjoyed both the presentations and conversations with familiar faces and new acquaintances alike. I did find myself wondering if the conference might benefit from exploring even more diverse topics "beyond tellerrand." It would be fascinating to see someone like Simon Willison discuss AI and its implications, or perhaps dive into more technically in-depth backend topics that could bring fresh perspectives.

That said, I can't recommend Beyond Tellerrand highly enough! The event consistently delivers exceptional content in a welcoming atmosphere that encourages creativity and connection. If you haven't experienced it yet, you're truly missing out on one of the best web conferences in Europe. And if you can't make it yourself, definitely encourage a colleague or friend to go – they'll thank you for it!

Special shout-out to my fellow podcast colleagues who made this event even more enjoyable: Alexander Bürner (devslove.it), Christian Schaefer (Working Draft), Sarah Gross (wwsiv) – and to Daniel Pietzsch and Nik Rademacher – it was fantastic seeing all of you there!

Nyxmon

I've made significant progress with my experiment developing a minimalist monitoring tool using vibe coding. I now have a comprehensive integration test where I add a check to the database and launch a check collector in a separate thread. This collector uses a blocking portal to poll the database for checks that are due to run.

Once a check is identified, the system issues an "execute checks" command that leverages an async check runner adapter along with another blocking portal. This setup allows the pending checks to run via httpx async in the event loop before returning results back to the synchronous message bus through a callback.

After receiving the result, the system issues an "add result" command to the message bus. Then the SQLite repository adapter utilizes a portal to write the result to the database within an async context.

While the code structure appears somewhat complex, it seems to be functioning as intended. The architecture successfully bridges synchronous and asynchronous operations throughout the monitoring workflow.

django-cast

Just released a new version with official support for Wagtail 7 and Django 5.2.

Articles

Software

People


Weeknotes 2025-05-05

I'm not passive aggressive unlike *some* people --Benack OBena

Getting back to work after a conference week. Barely had time for anything else. Made it to the beyond tellerrand warm-up event and heard some heartwarming stories about the indiewebcamp, which I unfortunately missed. Hoping to attend next year.

Articles


Weeknotes 2025-04-28

You can tell the Old Testament is the product of a desert people, because when they tried to imagine the end of the world they went with “rained for forty days and forty nights”, which in Ireland is just called Spring. --Simon McGarr

Attending DjangoConEU 2025

Last week I headed to DjangoCon Europe 2025 in Dublin, and it was fantastic. I met some wonderful people and had countless fascinating conversations. Since all the Python Podcast hosts were there with their audio gear, we pulled off the impressive feat of recording an episode every single day (day1, day2, day3) – and actually got them published within 24 hours of recording. We set up shop in the hotel lobby, initially worried about background noise, but Auphonic worked so well at filtering that I actually had to dial back the settings to keep some of the atmosphere in the recordings! I also got to watch another podcast being recorded at the conference, which was eye-opening. It was honestly surprising to see how differently various people approach the same task.

Dublin itself is a captivating city, and we managed to explore quite a bit. Here's something interesting: after chatting with other attendees, I discovered I'm not alone in finding software development work challenging right now (except for one person who never missed a chance to remind me they're probably the notable exception to the rule – you know who you are!). The tech market seems to be in a rough patch at the moment. At least I got some validation that it's not just me struggling.

Monitoring Pet Project

I haven't had time for much "vibe coding" on my monitoring pet project, but I've been thinking about the architecture, which is almost as good. Monitoring is essentially about waiting for I/O. You periodically poll the database to see which checks to run next, make HTTP requests (or other network calls) to actually perform those checks, and write the results back to the database.

The most straightforward way to handle I/O waiting in Python is using async functions and coroutines with an event loop. But here's the catch: you can only await async functions from within another async function. The problem is that most of my business logic – like deciding whether to run a check or determining if a failed check means a service should be marked as down – doesn't benefit from being async at all. In fact, it would be cleaner to keep the core domain logic synchronous and only use async for actual I/O operations.

So here's what I really want: a sync core for business logic that deals with the monitoring domain, with all the async I/O hidden behind adapters. But this raises a tricky question: how do you call async adapters from sync domain code?

There's another practical consideration: I'll likely want to build a Django dashboard at some point, and integrating synchronous business logic with Django is much more straightforward.

My plan involves using anyio for I/O since I want the flexibility to switch async backends later. Anyio has this neat concept called "portals" that let you run async code in another thread's event loop. Here's my current plan:

  1. Use dependency injection to provide a blocking portal to any event or command handlers that need it
  2. Keep all handlers synchronous, but allow them to pass the portal to adapters
  3. Let adapters run async code using the portal – either waiting for completion with portal.call() or fire-and-forget with portal.start_task_soon()
  4. When async adapters need to call business logic, they can do so directly (since calling sync business logic from async code should be fine)

This approach seems like a clean way to keep my domain logic simple while still leveraging async for I/O efficiency.

Articles

Software

Fediverse


Weeknotes 2025-04-21

Generic expert Python programming advice: "Or, you could just not do any of that." --David Beazley

Software Architecture and Django

I recently attended a Django-Cologne Meetup focusing on Django and software architecture—two topics I'm quite passionate about. The discussions were fascinating. I appreciate Django for its "batteries included" approach, allowing you to get projects up and running quickly, but it can become somewhat restrictive as projects grow in size and complexity.

From a software architecture perspective, inheriting from models.Model presents a dilemma. You either make your business logic dependent on Django and tie it to your database structure (which isn't ideal), or you try to abstract Django away behind a Repository pattern, expending considerable effort going against Django's grain.

But perhaps there's a middle ground? What if we keep Django as an UI entry point handling mostly CRUD operations, while maintaining most business logic separately and only invoking it from Django when necessary? I'm still exploring this question, though I'll admit that implementing business logic directly in Django via fat models works well enough for many projects and might be the most practical approach in most cases.

New Podcast Episode: Bytes and Strings

It's been a while since our last release! I just published an episode we recorded almost two months ago—I simply couldn't find the time to get it out sooner. As a result, we ended up announcing a conference that has already taken place and discussing "news" that's no longer particularly new. Despite this timing issue, I really enjoyed the episode.

One challenge I often face is evaluating episodes shortly after recording them; it's difficult to judge whether content is actually interesting or boring when it's all still fresh in my mind. With this episode, enough time had passed that I'd forgotten many details, and revisiting it now, I found it quite engaging! This is definitely motivation for us to record more episodes soon.

Articles

Fediverse

Software