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 →
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 →
A friend writing about desktop environments
reminded me of a few things as I consider a future switch to a Linux desktop.
Read More →
I do not (usually) think of myself a hoarder, but any kind of reading online seems to result in a browser full of tabs (as xkcd
humorously illustrates).
Even though desktop has more room to handle tabs, I find that even light research or troubleshooting can result in dozens of tabs, and after a point, only the favicon remains.
When switching to a new task, I usually find it easier to close everything and start from scratch though I tend to bookmark to raindrop
anything I might want later.
Read More →
It has been 10 years since I moved to Japan.
While I still mostly enjoy a lot about living in Japan, this year was more challenging than previous years.
There is still uncertainty about what 2025 will hold but I remain optimistic.
Read More →
While experimenting with yamdl
to prototype an idea for a wiki-like django site, I was curious about the various lower level Django signals.
To better understand them, I wrote a simple app config to log the various checks.
To help them be more visible in the terminal, I have also somewhat randomly added some assorted colors.
import os
from pathlib import Path
from django.apps import AppConfig
from django.core.checks import register
from django.db.backends.signals import connection_created
from django.db.models.signals import class_prepared
from django.dispatch import receiver
from django.utils.autoreload import BaseReloader, autoreload_started, file_changed
from django.utils.termcolors import make_style
red = make_style(fg="red")
blue = make_style(fg="blue")
cyan = make_style(fg="cyan")
yellow = make_style(fg="yellow")
magenta = make_style(fg="magenta")
bold_yellow = make_style(opts=("bold",), fg="yellow")
class TestappConfig(AppConfig):
name = __package__
def ready(self):
print(bold_yellow("ready"), __class__, os.getpid())
if os.environ.get("RUN_MAIN"):
print(bold_yellow("On app thread"))
@register
def test_checks(*args, **kwargs):
print(red("test_checks"), args, kwargs)
return []
@receiver(connection_created, dispatch_uid="print_connection_created")
def print_connection_created(*args, **kwargs):
print(red("connection_created"), args, kwargs)
@receiver(autoreload_started, dispatch_uid="print_autoreload_started")
def print_autoreload_started(sender: BaseReloader, **kwargs):
print(magenta("autoreload_started"), sender, kwargs)
@receiver(file_changed, dispatch_uid="print_file_changed")
def print_file_changed(sender: BaseReloader, file_path: Path, **kwargs):
print(magenta("file_changed"), sender, file_path, kwargs)
@receiver(class_prepared, dispatch_uid="print_class_prepared")
def print_class_prepared(sender, **kwargs):
print(cyan("print_class_prepared"), sender, kwargs)
After adding my new app to my INSTALLED_APPS
setting, I get a similar output when I run it.
Read More →
I have several Django projects, like my timebox
or chore tracker
project.
Two fields I will often add to most models is some kind of description/memo field and a url/more field.
from django.db import models
class Project(models.Model):
# most of the model specific bits
...
# common fields I add.
description = models.TextField(blank=True)
url = models.URLField(blank=True)
I will typically allow either to be blank, since both are intended to be optional.
A name/title might be enough as a quick hint or label, but often having a longer description/memo field is essential to provide extra detail once you have enough objects.
I have mostly kept it as a plain text description (I will often use {{ obj.description|linebreaks }}
to allow a bit of formatting), though other times I will consider allowing a full markdown description.
Read More →
I tend to use my calendar and reminders to track a lot of what I want to do, but sometimes I want to manage the data externally and sync.
For certain kinds of repeating tasks, I wanted to edit a list of tasks in a group, and it seemed like csv might work.
While csv does not have a strong specification, many programming tools make it easy to work with.
The initial format I thought about was something simple.
Read More →
A friend recently wrote “our personal database
, about how they maintain a postgres database for various projects.
I wrote something similar when I wrote about my personal api
, though Rubenerd’s post made me want to write a little bit more about it.
Since I am already using django
for various projects, my personal API is also built on Django.
While I could modify thing directly using something like pgAdmin, building on Django means I can take advantage of the models
and admin
built in to Django.
Read More →
There have been a few times while working with Django
, where I have wanted to triger something only if the instance changed.
Since Django provides a robust signals system, I decided to use that for my prototype.
First we need to import the packages we will use.
from django.db import models
from django.db.models.signals import post_save, pre_save, ModelSignal
from django.dispatch import receiver
from django.forms.models import model_to_dict
Next, we want to handle our pre_save
signal.
We want to store a snapshot of the original object so that we can compare it later.
Read More →