Posts tagged: python
All posts with the tag "python"
I wanted to host some static files through fastapi. Typical use cases for this might be some static web content like html/css/js. It could also be images or some data that doesn’t need dynamically rendered.
From the Docs #
The docs cover how to host static files, and give this solution that is built into fastapi.
https://fastapi.tiangolo.com/tutorial/static-files/
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
Authenticated Static Files #
Thanks to #858.
OscartGiles posted this solution to add authentication to static files. I tried this out on my thoughts and it worked flawlessly.
import typing
from pathlib import Path
import secrets
from fastapi import FastAPI, Request, HTTPException, status
from fastapi.staticfiles import StaticFiles
from fastapi.security import HTTPBasic, HTTPBasicCredentials
PathLike = typing.Union[str, "os.PathLike[str]"]
app = FastAPI()
security = HTTPBasic()
async def verify_username(request: Request) -> HTTPBasicCredentials:
credentials = await security(request)
correct_username = secrets.compare_digest(credentials.username, "user")
correct_password = secrets.compare_digest(credentials.password, "password")
if not (correct_username and correct_password):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect email or password",
headers={"WWW-Authenticate": "Basic"},
)
return credentials.username
class AuthStaticFiles(StaticFiles):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
async def __call__(self, scope, receive, send) -> None:
assert scope["type"] == "http"
request = Request(scope, receive)
await verify_username(request)
await super().__call__(scope, receive, send)
app.mount(
"/static",
AuthStaticFiles(directory=Path(__file__).parent / "static"),
name="static",
)
If you want both then, all you have to do is mount AuthStaticFiles to a
different route. Now you can have private, or paid content behind
/restricted.
app.mount("/static", StaticFiles(directory="static"), name="static")
app.mount(
"/restricted",
AuthStaticFiles(directory=Path(__file__).parent / "restricted"),
name="restricted"
)
I recently se tup minio object storage in my homelab for litestream sqlite backups. The litestream quickstart made it easy to get everything up and running on localhost, but I hit a wall when dns was involved to pull it from a different machine.
Here is what I got to work #
First I had to configure the Key ID and Secret Access Key generated in the minio ui.
❯ aws configure
AWS Access Key ID [****************VZnD]:
AWS Secret Access Key [****************xAm8]:
Default region name [us-east-1]:
Default output format [None]:
Then set the the s3 signature_version to s3v4.
aws configure set default.s3.signature_version s3v4
Now when I have minio running on https://my-minio-endpoint.com I can use the aws cli to access the bucket.
Note that
https://my-minio-endpoint.comresolves to the bucket endpoint (default 9000) not the ui (default 9001).
aws --endpoint-url https://my-minio-endpoint.com s3 ls my_bucket
Now Configuring Litestream #
Litestream also accepts the endpoint argument via config. I could not get it
to work just with the ui.
Note the
aws configurestep above is not required for litestream, only the aws cli.
dbs:
- path: /path/to/database.db
replicas:
- url: s3://my_bucket/
endpoint: https://my-minio-endpoint.com
region: us-east-1
access-key-id: ****************VZnD
secret-access-key: ************************************xAm8
Now run a litestream replication.
litestream replicate -config litestream.yml
# or put the config in /etc/litestream.yml and just run replicate
litestream replicate
why-is-postgres-default
I’ve recently given tailwindcss a second chance and am really liking it. Here is how I set it up for my python based projects.
https://waylonwalker.com/a-case-for-tailwindcss
Installation #
npm is used to install the cli that you will need to configure and compile tailwindcss.
npm install -g tailwindcss-cli
Setup #
You will need to create a tailwind.config.js file, to get this you can use the cli.
npx tailwindcss init
Using tailwind with jinja templates #
To set up tailwind to work with jinja templates you will need to point the tailwind config content to your jinja templates directory.
module.exports = {
content: ["templates/**/*.html"],
};
Setting up the base styles #
I like to use the @tailwind base;, to do this I set up an input.css file.
@tailwind base;
@tailwind components;
@tailwind utilities;
Compiling #
Now that it’s all setup you can run the tailwindcss command. You will get an output.css with base tailwind plus any of the classes that you used.
tailwindcss -i ./input.css -o ./output.css --watch