The tea command for gitea (used by forgejo) has a flag for login. With gitea
you can have multiple accounts logged in. When you try to run a command such
as repo create it will prompt you which login to use, but I learned that you
can bake it in to all of them with --login <login-name>
❯ tea repo create --name deleteme --description 'for example'
┃ NOTE: no gitea login detected, whether falling back to login 'git.waylonwalker.com'?
tea repo create --name deleteme --description 'for example' --login git.wayl.one
2025-11-21 Notes
Learned about nginx_auth today. Feels good to unlock a new skill that I did not quite understand before. I don't think I grasped that there is a backend...
2025-11-19 Notes
Making progress on dropper this week.
Another Big Cloud Outage Nov 2025
Today I learned how to use AliasChoices with pydantic settings to setup common aliases for the same field. I’m bad about remembering these things, and hate looking up the docs. I like things to be intuitive and just do the thing I want it to do. Especially when they get configured through something like yaml and do not have a direct lsp look up right from my editor. I figured out how to support what might be common aliases for a storage directory. These can be set up as environment variables and used by config.
from pathlib import Path
from pydantic import Field
from pydantic import AliasChoices
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
storage_dir: Path | None = Field(
default=None,
validation_alias=AliasChoices(
"STORAGE_DIR", "STORAGE_DIRECTORY", "STORAGE_PATH", "STORAGE_PATHNAME",
"DROPPER_STORAGE_DIR", "DROPPER_STORAGE_DIRECTORY", "DROPPER_STORAGE_PATH", "DROPPER_STORAGE_PATHNAME",
),
description="Directory for stored files",
)
3d-Printed Corner Clamp
Techbrophobic
Mcat Anything
Missing Thoughts
2025-11-04 Notes
Today I gave mcat a try and it's so sick. It can anything right in the terminal, pdf, image, even video. It even works inside tmux unlike almost anything...
Rules
I often want to run an s3 sync in an isolated environment, I don’t want to set
any environment variables, I don’t want anything secret in my history, and I
don’t want to change my dotenv into something that exports variables, I just
want s3 sync to work. dotenv run is the tool that I’ve been using for this,
and this uv one liner lets it run fully isolated from the project.
one liner #
uv tool run --from 'python-dotenv[cli]' dotenv run -- uv tool run --from awscli aws s3 sync s3://bucket data
multi-line #
same thing formatted for readability
uv tool run \
--from 'python-dotenv[cli]' \
dotenv run -- \
uv tool run \
--from awscli \
aws s3 sync s3://dropper data
There are probably 10 ways to skin this cat, but this is what I did, if you have a better way let me know, I’ll link you below.
First 3d Printed Threads
FastAPI.">Starlette has a head request that works right along side your get requests.
This morning I fiddled around with custom routes for GET and HEAD, but had
to manually set some things about the file, and was still missing e-tag in
the end. Turns out as a developer you can just add a head route to
your get routes and starlette will strip the content for you, while
preserving all of those good headers that fastapi FileResponse created
automatically for you.
from fastapi import APIRouter
from fastapi.response import FileResponse
from fastapi import Request
from pathlib import Path
router = APIRouter()
@router.get("/file/{filename}")
@router.head("/file/{filename}")
async def get_file(filename: str, request: Request,):
headers = {
"Cache-Control": "no-cache, no-store, must-revalidate",
}
from pathlib import Path
filename = Path(f"data/{filename}")
if not filename.exists():
raise HTTPException(status_code=404, detail="File not found")
return FileResponse(filename, headers=headers)
Here is an example of the response with curl.
❯ curl -I -L "http://localhost:8100/api/file/e5523925-1565-454c-bab3-c70c4deabc83.webp?width=250"
HTTP/1.1 200 OK
date: Wed, 22 Oct 2025 14:16:03 GMT
server: uvicorn
cache-control: no-cache, no-store, must-revalidate
content-type: image/webp
content-length: 17206
last-modified: Tue, 23 Sep 2025 14:03:20 GMT
etag: f891660c1543feb1af7564f08abdd511
❯ curl -I -L "http://localhost:8100/api/file/unknown-file.webp?width=250"
HTTP/1.1 404 Not Found
date: Wed, 22 Oct 2025 14:16:11 GMT
server: uvicorn
content-length: 27
content-type: application/json
Today I learned that while .stignore and .gitignore look very similar they
are not. My obsidian directory had been locked up for a few weeks and I had no
idea why until I logged into the web ui and saw errors. The errors were some
confusing regex validator not matching. I don’t know what the exact error was,
but I went in and only ignored the files I cared about instead of the entire
gitignore. Primarily I was getting conflicts in my .git directory.
