Published
All published posts
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 is a modern and efficient web framework for Python, built on top of the Starlette web framework, and pydantic for data validation and serialization.
From the FastAPI documentation #
FastAPI is a modern, fast (high-performance), web framework for building APIs with Python based on standard Python type hints.
The key features are:
- Fast: Very high performance, on par with NodeJS and Go (thanks to Starlette and Pydantic). One of the fastest Python frameworks available.
- Fast to code: Increase the speed to develop features by about 200% to 300%. *
- Fewer bugs: Reduce about 40% of human (developer) induced errors. *
- Intuitive: Great editor support. Completion everywhere. Less time debugging.
- Easy: Designed to be easy to use and learn. Less time reading docs.
- Short: Minimize code duplication. Multiple features from each parameter declaration. Fewer bugs.
- Robust: Get production-ready code. With automatic interactive documentation.
- Standards-based: Based on (and fully compatible with) the open standards for APIs: OpenAPI (previously known as Swagger) and JSON Schema.
Mentioned in 2025 Stack Overflow Survey #
The +5 point increase for FastAPI is one of the most significant shifts in the web framework space. This signals a strong trend towards using Python for building performant APIs and reflects the overall strength of the Python ecosystem.
Starlette
Starlette is a low level web framework for modern (as of 2025) async python development most famously used by 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.
Calendar data could not load. Try again.