Arran de la substitució forçada de nginx unit he començat a fer servir uv per a la gestió dels paquets dels contenidors python.
És una eina molt potent i ràpida. Astral ha fet l’eina que python necessitava.
Molt recomanable.
Notes sobre programació, sistemes operatius, comunicacions
Arran de la substitució forçada de nginx unit he començat a fer servir uv per a la gestió dels paquets dels contenidors python.
És una eina molt potent i ràpida. Astral ha fet l’eina que python necessitava.
Molt recomanable.
DNS4EU és un servei de resolució de noms (DNS) cofinançat per la Unió Europea, amb diversos nivells de protecció (sense filtres, evitar webs malicioses, evitar contingut inadequat per a criatures, evitar anuncis).
La configuració estàndard està pensada i és gratuïta per a ús particular, si bé ofereixen opcions per a empreses i organitzacions governamentals.
Durant molts anys he fet servir OpenDNS, i aquesta setmana he canviat a DNS4EU.
Un inconvenient: només admeten DOH amb http/2; el router que tinc fa servir http/1.1 per DOH. Tinc esperances que aviat això canviï.
Amb OpenDNS feia servir DOH, tot i que al log del router cada dia s’hi registraven alguns errors.
HTTP/3 activat per aquest blog.
Costa moltíssim avançar estàndards en la tecnologia de fons d’internet. IPv6 no s’implanta, encara hi ha moltíssim HTTP/1.1, i només el frau i la privacitat ha forçat l’extensió de la navegació encriptada (https).
12/01/26: He hagut de tocar el fitxer de configuració nginx per fer servir $host on hi havia $http_host.
Em queda algun error a les eines d’administració de wordpress, també relacionat amb HTTP_HOST; confio que el resoldré retocant una mica més la configuració de nginx.
14/01/2026: Resumeixo els passos:
Cal permetre el tràfic amb protocol UDP pel port en què hi ha el web (normalment 443).
Nginx ha d’estar compilat amb l’opció –with-http_v3_module.
Al bloc server de nginx.conf cal afegir:
listen 443 quic reuseport;
listen [::]:443 quic reuseport;
http3 on;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers on;
add_header alt-svc 'h3=":443"; ma=86400';
reuseport només es pot fer servir a un dels servidors.
No tinc clar que ssl_prefer_server_ciphers sigui estrictament necessari.
add_header alt-svc publicita la disponibilitat de HTTP/3 per aquest servidor.
I wordpress necessita $HTTP_HOST informat, l’he passat a l’entorn fastcgi de php-fpm a partir de $HOST:
fastcgi_param HTTP_HOST $host;
Acabo de substituir nginx unit per (tal com preveia):
Queden detalls per polir però el gros està fet.
De fet aquesta entrada és una de les proves bàsiques (assegurar que puc publicar).
Nginx unit ha estat canceŀlat:

Haig de trobar alternativa per aquest web mateix (ara amb WordPress sota nginx-unit/PHP) i una eina particular que va amb nginx-unit/Python.
Per PHP puc tornar a PHP-FPM i per python possiblement amb el python estàndard i el mateix miniservidor d’aplicacions que té cherrypy.
Unit m’agradava, el mateix concepte pels 2 sistemes (python i php).
Python no té una funció específica per eliminar espais superflus (és a dir, eliminar tots els espais del principi i del final d’un text, i entre paraules deixar-hi només un espai).
Hi ha una manera molt pythònica de fer-ho:
" ".join(text_amb_espais.split())
I això és ràpid? Doncs comparem 3 alternatives amb timeit:
El codi per mesurar-ho és:
from timeit import timeit
def eliminar_espais_split_join (text: str) -> str:
return " ".join(text.split())
def eliminar_espais_posicio_a_posicio (text: str) -> str:
anterior_es_espai = True
sense_espais_redundants = ""
for x in text:
if x == " ":
if not anterior_es_espai:
sense_espais_redundants += x
anterior_es_espai = True
else:
sense_espais_redundants += x
anterior_es_espai = False
if len(sense_espais_redundants) > 0:
if sense_espais_redundants [-1] == " ":
sense_espais_redundants = sense_espais_redundants[:-1]
return sense_espais_redundants
def eliminar_espais_replace (text: str) -> str:
r2 = text
while (r1:= r2.replace(" ", " ")) != r2:
r2 = r1
if len(r2) > 0:
if r2[0] == " ":
r2 = r2[1:]
if len(r2) > 0:
if r2[-1] == " ":
r2 = r2[:-1]
return r2
TEXT_PROVA = " Vivamus quis lacus quis sapien elementum finibus et sollicitudin nisi. "
assert (eliminar_espais_posicio_a_posicio (TEXT_PROVA) == eliminar_espais_split_join(TEXT_PROVA))
assert (eliminar_espais_replace (TEXT_PROVA) == eliminar_espais_split_join(TEXT_PROVA))
EXECUCIONS = 100_000
temps = (timeit (lambda: eliminar_espais_split_join (TEXT_PROVA), number=EXECUCIONS),
timeit (lambda: eliminar_espais_posicio_a_posicio (TEXT_PROVA), number=EXECUCIONS),
timeit (lambda: eliminar_espais_replace(TEXT_PROVA), number=EXECUCIONS))
temps_minim = min(temps)
print (f"eliminar_espais_split_join: {temps [0] / temps_minim:.2f} vegades el mínim")
print (f"eliminar_espais_posicio_a_posicio: {temps [1] / temps_minim:.2f} vegades el mínim")
print (f"eliminar_espais_replace: {temps [2] / temps_minim:.2f} vegades el mínim")
I el resultat:
eliminar_espais_split_join: 1.00 vegades el mínim
eliminar_espais_replace: 2.25 vegades el mínim
eliminar_espais_posicio_a_posicio: 8.83 vegades el mínim
He provat algunes variants, sense que influeixin significativament en els resultats:
O sigui, he deixat l’split_join al codi, la manera més genuïna del Python és alhora la més ràpida.
Una fotografia que m’ha arribat per WhatsApp i que m’he passat a l’ordinador no té cap dada EXIF, ni la data / hora.
D’entrada m’ha xocat, després he vist que no està mal pensat, per privacitat. Desconec qui ho esborra: el sistema operatiu en posar-la al xat, l’aplicació WhatsApp o el meu telèfon en rebre-la o desar-la. Tampoc no sé amb quin telèfon va ser feta.
He passat la base de dades de fotografies a Sqlite. Fins ara havia fet servir Sqlite molt poc.
El canvi ha estst fàcil perquè tinc l’aplicació amb Sqlalchemy. He pogut canviar noms de columnes tocant només el fitxer de configuració (definició d’entitats Sqlalchemy). Traspàs de dades amb select de MySQL i insert a Sqlite.
L’aplicació funciona de meravella, i podria deixar-la així, però segueixo amb MySQL. Sqlite no em fa el pes per dos detalls, irrellevants en una aplicació com aquesta:
I potser ho passo a Firebird.
Actualització 1/10/25: Descarto Firebird, la creació de la base de dades amb Sqlalchemy no funciona.