blog Norikae Dev Server

Over a year ago, I wrote my first draft dev proxy launcher in Async Python, based on an idea I had to have something like xinetd for my various in development projects.

[service.django]
host = "django.localhost"
port = 8001
cwd = "~/Projects/my-django-project"
command = "uv run manage.py runserver {port}"
delay = 3

[service.hugo]
host = "hugo.localhost"
port = 8002
cwd = "~/Projects/my-hugo-site"
command = "hugo server --buildDrafts --buildFuture --port {port}  --liveReloadPort 80"

While the Python version validated the idea, and usually worked well, there were a few cases that did not work as well.

Recently, I decided to work on a new version using rust and hyper to handle the proxied requests, which I have named Norikae (乗り換え).

Read More →

blog Attempting a Windows Service

On my Mac, I wrote a small nagger app to help remind me when I may have extended a break too long. It is connected via mqtt to a hardware bell I have on my desk.

Recently I have been spending a bit too much time in Factorio so wanted to see if I could make a similar version on Windows.

I have not previously used my Windows PC for development (I do all of my work on MacOS or Linux), so the first step was to install VSCode, uv , and git. This was not particularly difficult and recently it seems like installers automatically handled updating PATH for powershell.

Read More →

blog Entry Points With Enums

While updating my PowerPlug ( pypi ) project, I implemented a pattern I have started using in a few other places that I use entry-points .

By creating a custom enum using one of Django’s enumeration-types , you can make it much easier to load these modules.

from importlib import metadata

from django.db import models
from django.utils.translation import gettext_lazy as _

class EntryPoints(models.TextChoices):
    APPS = "powerplug.apps", _("Installed Apps")
    REST = "powerplug.rest", _("Installed APIs")
    SIGNAL = "powerplug.signal", _("Installed Signals")
    TASK = "powerplug.task", _("Installed Tasks")
    URLS = "powerplug.urls", _("Installed URLs")
    CONTEXT = "powerplug.context", _("Installed context processor")

    def group(self) -> metadata.EntryPoints:
        return metadata.entry_points(group=self.value)

Using an enum like this, makes it very easy to load one of our entry points, while keeping all the definitions for our app in a single place.

Read More →

blog Exploring Python Requirements

Recently like a lot of my Python follows, I have been using uv to manage a lot of my python projects.

Given a project, uv tree will show you a nice tree view of your requirements.

wheat v0.1.0
├── click v8.1.8
├── inquirer v3.4.0
│   ├── blessed v1.20.0
│   │   ├── six v1.17.0
│   │   └── wcwidth v0.2.13
│   ├── editor v1.6.6
│   │   ├── runs v1.2.2
│   │   │   └── xmod v1.8.1
│   │   └── xmod v1.8.1
│   └── readchar v4.2.1
└── tomlkit v0.13.2

You can also do something like uv pip list to show it in list form. Both support a --outdated flag to show you packages needing updates.

Read More →

blog git-pending

Mostly for scripting reasons and alerting reasons, there are multiple times when I have wanted a simple status of a repository. When working from the console, there is git-status which shows things in a human parsable format, but for scripts we need something more robust.

We can ue git-status with the –porcelain=2 flag to provide a lot more information, in a more easily machine parsable format. Seeing how starship parsed git-status helped me on this path.

Using this information, I wrote my own git-pending command to parse this data, into a form I could script against more easily.

Read More →