![[None]]
I figured out the killer combination for python lsp servers, ruff and jedi! ruff does all of the diagnostics and formatting, then jedi handles all the code objects like go to definition and go to reference.
local servers = {
ruff_lsp = {},
jedi_language_server = {},
}
Note
This post is a thought [1]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: /thoughts/
Posts tagged: python
All posts with the tag "python"
312 posts
latest post 2026-05-06
Publishing rhythm
Client Challenge
pypi.org [1]
Underrated python library to on board ruff, or just use it on a project where its not the norm. ruff claims that its 99.9% compatible with black and when you read through the known differences they are clearly edge case bugs in black.
See this page for more about the comparison to black https://docs.astral.sh/ruff/faq/#how-does-ruffs-formatter-compare-to-black
oh and I just noticed that it is maintianed by Charlie, and comes straight out of astral.
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://pypi.org/project/flake8-to-ruff/
[2]: /thoughts/
![[None]]
First I need to fetch my thoughts from the api, and put it in a local sqlite database using sqlite-utils.
fthoughts () {
# fetch thoughts
curl 'https://thoughts.waylonwalker.com/posts/waylonwalker/?page_size=9999999999' | sqlite-utils insert ~/.config/thoughts/database2.db post --pk=id --alter --ignore -
}
Now that I have my posts in a local sqlite database I can use sqlite-utils to enable full text search and populate the full text search on the post table using the title message and tags columns as search.
sthoughts () {
# search thoughts
# sqlite-utils enable-fts ~/.config/thoughts/database2.db post title message tags
# sqlite-utils populate-fts ~/.config/thoughts/database2.db post title message tags
sqlite-utils search ~/.config/thoughts/database2.db post "$*" | ~/git/thoughts/format_thought.py | bat --style=plain --color=always --language=markdown
}
alias st=sthoughts
Now I am ready to search my thoughts, which is a tiny blog format that I created mostly for leaving my own personal comment on web pages, so most of them have a link to some other online content, and their title is based on the authors title.
[1]
[2]
Note
This post is a thought [3]. It...
-
Great example from Anthony showing how easy it is to practice building database orm models and playing with them in a repl. This is good practice even if you are in a big code base to be able to test and learn in a simplified code base that does not have a mountain of other code around atuh, permissions, security, and other complex things that come into real production code bases that might make it hard to focus on what you are trying to do.
Note
Anthony uses backref here, thats legacy, use back_populates on both parent and child.
Note
This post is a thought [1]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: /thoughts/
External Link
stackoverflow.com [1]
Today I came across some sqlalchemy models that created some relationships, some used backref
some used back_populates. I was stumped why, I had never came accross backref before and I felt skill issues sinking in.
backref is considered legacy # [2]
https://docs.sqlalchemy.org/en/14/orm/backref.html
As stated in the sqlalchemy docs, backref is a legacy feature. Its shorthand to creating relationships between parent and child, but only adding it to the parent. While this is simpler it introduces some invisible magic.
Note
This post is a thought [3]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://stackoverflow.com/questions/51335298/concepts-of-backref-and-back-populate-in-sqlalchemy#answer-59920780
[2]: #backref-is-considered-legacy
[3]: /thoughts/
Read a Range of Data - LIMIT and OFFSET - SQLModel
SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness.
sqlmodel.tiangolo.com [1]
Today I was running some sqlmodel queries through the sqlalchemy orm. Admittedly I’ve not done enough orm queries before, and I’ve done quite a bit of raw sql. I was trying to get objects from two separate models that had relationships setup.
session.query(User, Images).where(User.id == 3).all()
It is incredibly slow, and gives me the following warning.
SELECT statement has a cartesian product between FROM element(s)
What I learned from the SQLModel docs is that you should give it a join to correct this and go much faster.
session.query(User, Images).join(Images).where(User.id == 3).all()
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://sqlmodel.tiangolo.com/tutorial/limit-and-offset/
[2]: /thoughts/
-
Theo’s response puts a lot of my feelings about unit testing into words. It’s crazy how cargo culty it becomes that the echo chamber of twitter can bring in beliefs that we think we believe, but have not experienced enough or put enough thought in to form our own opinion.
This video made me think so much that it turned into it’s own blog post
Thoughts on Unit Testing [1]
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://waylonwalker.com/thoughts-on-unit-tests
[2]: /thoughts/
thoughts on unit tests
[1]
Your browser does not support the audio element.
Theo’s response puts a lot of my feelings about unit testing into words. Many
of us have grown up in this world preaching unit testing. We often hear these
statements “Everything must be unit tested, tests make code more maintainable.”
In reality when we are not writing complex low level code unit tests are
probably the wrong approach.
[2]
Most of us are assemblers # [3]
So much of software engineering is assembling existing well tested code. Crud
applications, UI, Data Pipelines, building on top of battle tested code.
Manufacturing Analogy - Unit Testing # [4]
This kind of reminds me of Manufacturing. Individual components are QA tested
with tests that look more like unit test. Parts like bearings, pistons,
shafts, valves, they are all tested against sophisticated statistics of sample
measurements. This is quite similar to unit testing.
[5]
You see measuring the individual sizes of these components does not guarantee
...
Mastodon.py — Mastodon.py 2.2.1 documentation
mastodonpy.readthedocs.io [1]
Mastadon.py is a python api client for mastadon that makes it easy to cross post to mastadon.
from mastodon import Mastodon
Mastodon.create_app(
'pytooterapp',
api_base_url = 'https://mastodon.social',
to_file = 'pytooter_clientcred.secret'
)
from mastodon import Mastodon
mastodon = Mastodon(client_id = 'pytooter_clientcred.secret',)
mastodon.log_in(
'[email protected]',
'incrediblygoodpassword',
to_file = 'pytooter_usercred.secret'
)
mastodon.toot('Tooting from Python using #mastodonpy !')
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://mastodonpy.readthedocs.io/en/stable/
[2]: /thoughts/
External Link
stackoverflow.com [1]
After struggling to get dependencies inside of middleware I learned that you can make global dependencies at the app level. I used this to set the user on every single route of the application without needing Depend on getting the user on each route.
from fastapi import Depends, FastAPI, Request
def get_db_session():
print("Calling 'get_db_session(...)'")
return "Some Value"
def get_current_user(session=Depends(get_db_session)):
print("Calling 'get_current_user(...)'")
return session
def recalculate_resources(request: Request, current_user=Depends(get_current_user)):
print("calling 'recalculate_resources(...)'")
request.state.foo = current_user
app = FastAPI(dependencies=[Depends(recalculate_resources)])
@app.get("/")
async def root(request: Request):
return {"foo_from_dependency": request.state.foo}
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://stackoverflow.com/questions/72243379/fastapi-dependency-inside-middleware#answer-72480781
[2]: /thoughts/
Handling Errors - FastAPI
FastAPI framework, high performance, easy to learn, fast to code, ready for production
fastapi.tiangolo.com [1]
This page shows how to customize your fastapi [2] errors. I found this very useful to setup common templates so that I can return the same 404’s both programatically and by default, so it all looks the same to the end user.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
class UnicornException(Exception):
def __init__(self, name: str):
self.name = name
app = FastAPI()
@app.exception_handler(UnicornException)
async def unicorn_exception_handler(request: Request, exc: UnicornException):
return JSONResponse(
status_code=418,
content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."},
)
@app.get("/unicorns/{name}")
async def read_unicorn(name: str):
if name == "yolo":
raise UnicornException(name=name)
return {"unicorn_name": name}
Note
This post is a thought [3]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://fastapi.tiangolo.com/tutorial/handling-errors/
[2]: /fastapi/
[3]: /thoughts/
logs with FastAPI and Uvicorn · Issue #1508 · fastapi/fastapi
Hello, Thanks for FastAPI, easy to use in my Python projects ! However, I have an issue with logs. In my Python project, I use : app = FastAPI() uvicorn.run(app, host="0.0.0.0", port=8000) And when...
GitHub · github.com [1]
Setting an additional log handler to the uvicorn logger for access logs in fastapi [2] was not straightforward, but This post was very helpful.
@app.on_event("startup")
async def startup_event():
logger = logging.getLogger("uvicorn.access")
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("%(asctime)s - %(levelname)s - %(message)s"))
logger.addHandler(handler)
Note
This post is a thought [3]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://github.com/tiangolo/fastapi/issues/1508
[2]: /fastapi/
[3]: /thoughts/
External Link
stackoverflow.com [1]
Setting tags in your fastapi endpoints will group them in the docs. You can also set some metadata around the tags to get nice descriptions.
Here is a full example from the post.
from fastapi import FastAPI
tags_metadata = [
{"name": "Get Methods", "description": "One other way around"},
{"name": "Post Methods", "description": "Keep doing this"},
{"name": "Delete Methods", "description": "KILL 'EM ALL"},
{"name": "Put Methods", "description": "Boring"},
]
app = FastAPI(openapi_tags=tags_metadata)
@app.delete("/items", tags=["Delete Methods"])
@app.put("/items", tags=["Put Methods"])
@app.post("/items", tags=["Post Methods"])
@app.get("/items", tags=["Get Methods"])
async def handle_items():
return
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://stackoverflow.com/questions/63762387/how-to-group-fastapi-endpoints-in-swagger-ui#answer-63762765
[2]: /thoughts/
Show some equivalent list comprehensions in filter examples · Issue #1068 · pallets/jinja
I'm willing to write a pull-request for this, but I just want to see what people think before I write it. So the issue is this. I'm very familiar with python. I'm new to Jinja2. Often I find myself...
GitHub · github.com [1]
I often want to reach for non existing list comprehensions in jinja 2, Here are a few nice equivalents.
a: {{ data | selectattr('x', 'gt', 5) | list }}
b: {{ data | map(attribute='c') | list }}
c: {{ data | selectattr('x', 'gt', 5) | map(attribute='c') | list }}
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://github.com/pallets/jinja/issues/1068
[2]: /thoughts/
GitHub - DataDog/ddqa: Datadog's QA manager for releases of GitHub repositories
Datadog's QA manager for releases of GitHub repositories - DataDog/ddqa
GitHub · github.com [1]
DataDog ddqa is building out a textual app and deploying it with pyapp. They have CI setup to fully build and cross compile their textual tui into github releases that you can just download from their releases page. This is something I am looking at for markata. This would be pretty sweet to be able to make it just work on places like windows. It would also be interesting to try to build a full desktop app with pyapp.
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://github.com/DataDog/ddqa
[2]: /thoughts/
Path Operation Advanced Configuration - FastAPI
FastAPI framework, high performance, easy to learn, fast to code, ready for production
fastapi.tiangolo.com [1]
Excluding routes from fastapi docs, can be done from the route configuration using `include_in_schema`. This is handy for routes that are not really api based or duplicates.
From the Docs # [2]
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/", include_in_schema=False)
async def read_items():
return [{"item_id": "Foo"}]
trailing slash # [3]
I’ve had better luck just routing both naked and trailing slash routes in fastapi [4]. I’ve had api’s deployed as a subroute to a site rather than a subdomain, and the automatic redirect betweens them tended to always get messed up. This is pretty easy fix for the pain is causes just give vim a yyp, and if you don’t want deuplicates in your docs, ignore one.
from fastapi import FastAPI
app = FastAPI()
@app.get("/items")
@app.get("/items/", include_in_schema=False)
async def read_items():
return [{"item_id": "Foo"}]
favicon.ico # [5]
Now you do not need to deploy favicons to your api in any way, it is nice to have it in your browser tab, but more importantly ...
Protect API docs behind authentication? · Issue #364 · fastapi/fastapi
Basic Question Does FastAPI provide a method for implementing authentication middleware or similar on the docs themselves (e.g. to protect access to /docs and /redoc)? Additional context My company...
GitHub · github.com [1]
You can protect your fastapi [2] docs behind auth so that not only can certain roles not run certain routes, but they cannot even see the docs at all. This way no one that shouldn’t be poking around can even discover routes they shouldn’t be using.
Here is the soluteion provided by @kennylajara [3]
from fastapi import FastAPI
from fastapi.openapi.docs import get_redoc_html, get_swagger_ui_html
from fastapi.openapi.utils import get_openapi
import secrets
from fastapi import Depends, FastAPI, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials
app = FastAPI(
title="FastAPI",
version="0.1.0",
docs_url=None,
redoc_url=None,
openapi_url = None,
)
security = HTTPBasic()
def get_current_username(credentials: HTTPBasicCredentials = Depends(security)):
correct_username = secrets.compare_digest(credentials.username, "user")
correct_password = secrets...
Today I am working on fokais.com, trying to get to a point where I can launch
by workig through stripe integrations. This is my first time using stripe, so
there has been quite a bit to learn, and I am probably building in more than I
need to before launching, but I am learning, and not in a rush to launch.
I am building the fokais backent in python primarilyt with fastapi [1] and sqlmodel
on sqlite. My billing integration is going to be all Stripe.
Stripe Subscription Cancellations Docs # [2]
Here is a link to the stripe docs for your refrence, especially if you want to
see how to cancel subscriptions in other languages. They include code samples
for many popular languages.
[3]
User Model # [4]
This is the part of the user model that includes the cancel and reactivate
methods. It pretty much follows the stripe guide.
class UserBase(SQLModel, table=False): # type: ignore[call-arg]
username: str = Field(unique=True)
full_name: str
email: str
email_verified: bool = False
disabled: bool = False
signup_date: Optional[datetime] = Field(default_factory=datetime.utcnow)
stripe_customer_id: Optional[str]
def cancel_subscription(self):
for subscription in self.active_sub...
Looking for a Heroku replacement, What I found was shocking!
Your browser does not support the audio element.
I’ve long hosted my personal blog as a static site on waylonwalker.com. It’s
all markdown, converted to html [1], and shipped as is. It’s been great, I’ve
moved it from GitHub Pages, to Netlify, tried Vercel for a minute, and have
landed on Cloudflare Pages. Each migration has not really been that
hard, it’s just pointing ci to a different host after the site has built.
[2]
What about server side # [3]
Now the part that I have struggled with is how to cheaply host a server
rendered application that can just live on forever without me paying for it.
This is a harder problem as it costs more to keep servers spinning, memory, and
disk all ready for you to use at a moments notice.
Honestly # [4]
I never really deployed anything that useful on heroku, but it seems like the
klenex of the bunch that’s why they are in the title. I’ve moved between
digital ocean and fly.io, and have had some great experiences with both. I
just don’t want...
External Link
X (formerly Twitter) · twitter.com [1]
Textual is so sick, Will just made a live markdown editor in the terminal!
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://twitter.com/willmcgugan/status/1729158038551220477
[2]: /thoughts/