Files
fn_registry/python/functions/infra/dav_make_addressbook.md
T
egutierrez 236a4740b0 fix(dav): error_type en dav_make_addressbook/dav_make_calendar (impure requiere error_type)
El indexer rechaza funciones impure con error_type vacío. Ambas funciones del grupo dav
declaran error_go_core como el resto de las funciones DAV Python del registry.
2026-06-13 00:45:00 +02:00

6.0 KiB

name, kind, lang, domain, version, purity, signature, description, tags, uses_functions, uses_types, returns, returns_optional, error_type, imports, params, output, tested, tests, test_file_path, file_path
name kind lang domain version purity signature description tags uses_functions uses_types returns returns_optional error_type imports params output tested tests test_file_path file_path
dav_make_addressbook function py infra 1.0.0 impure def dav_make_addressbook(base_url: str, username: str, password: str, contacts_home: str, slug: str, display_name: str = "", description: str = "", *, timeout_s: float = 20.0, verify_tls: bool = True) -> dict Crea una nueva coleccion de contactos CardDAV (una libreta/agenda de contactos nueva) bajo el contacts-home de un principal via MKCOL extendido (RFC 5689), declarando el resourcetype como addressbook y fijando el displayname y la descripcion (addressbook-description) en el propio cuerpo XML. La coleccion se crea en <contacts_home><slug>/. El slug se sanea a [a-z0-9_-] (minusculas, espacios->guion); si queda vacio devuelve error de validacion. Idempotente: 201 Created es exito; 405/301 (ya existe) devuelve {status:'ok', existed:True}. Escapa display_name/description para XML. Construye Authorization: Basic base64(user:pass) a mano. Maneja errores sin lanzar (salvo validacion de args). Solo stdlib (urllib, base64, re, ssl, xml.sax.saxutils). Probado contra Xandikos. Analoga de dav_make_calendar para CardDAV.
dav
carddav
addressbook
contacts
mkcol
create
collection
http
infra
false error_go_core
base64
re
ssl
urllib.error
urllib.request
xml.sax.saxutils
name desc
base_url URL base del servidor DAV sin barra final (p.ej. 'https://dav-eedeb681c4ab89ab8e444ac9.organic-machine.com').
name desc
username usuario para HTTP Basic auth (p.ej. 'enmanuel').
name desc
password contrasena para HTTP Basic auth. Resolver desde pass con pass_get_secret, nunca hardcodear.
name desc
contacts_home ruta del contacts-home del principal con barra final (p.ej. '/enmanuel/contacts/'). La nueva coleccion cuelga de el.
name desc
slug segmento de path de la coleccion en la URL (p.ej. 'trabajo'); se sanea a [a-z0-9_-]. La coleccion se crea en <contacts_home><slug>/. Si queda vacio tras sanear, devuelve error de validacion.
name desc
display_name nombre visible de la coleccion (DAV:displayname). Si vacio, usa el slug saneado.
name desc
description descripcion de la coleccion (addressbook-description de CardDAV). Opcional; '' lo omite.
name desc
timeout_s timeout de cada peticion HTTP en segundos. Default 20.0.
name desc
verify_tls si True (default) verifica el certificado TLS. No desactivar salvo entorno de prueba.
dict. En exito: {status:'ok', http_status:int, href:str} y, si la coleccion ya existia, ademas existed:True. En error (sin lanzar): {status:'error', http_status:int|None, href:str, error:str}. href es la ruta de la coleccion (contacts_home + slug saneado + '/'). true
test_sanitize_slug_minusculas
test_sanitize_slug_espacios_a_guion
test_sanitize_slug_elimina_caracteres_raros
test_sanitize_slug_colapsa_guiones_y_recorta
test_sanitize_slug_vacio
test_join_url_compone_la_coleccion
test_mkcol_xml_es_mkcol_extendido
test_mkcol_xml_declara_resourcetype_addressbook
test_mkcol_xml_incluye_displayname
test_mkcol_xml_escapa_displayname
test_mkcol_xml_incluye_y_escapa_descripcion
test_mkcol_xml_omite_descripcion_vacia
python/functions/infra/dav_make_addressbook_test.py python/functions/infra/dav_make_addressbook.py

Ejemplo

import sys
sys.path.insert(0, "python/functions")
from infra.pass_get_secret import pass_get_secret
from infra.dav_make_addressbook import dav_make_addressbook

pw = pass_get_secret("dav/xandikos-enmanuel")["value"]  # NO logear

res = dav_make_addressbook(
    base_url="https://dav-eedeb681c4ab89ab8e444ac9.organic-machine.com",
    username="enmanuel",
    password=pw,
    contacts_home="/enmanuel/contacts/",
    slug="trabajo",
    display_name="Trabajo",
)
print(res)
# {'status': 'ok', 'http_status': 201, 'href': '/enmanuel/contacts/trabajo/'}
# Volver a llamar con el mismo slug:
# {'status': 'ok', 'http_status': 405, 'href': '/enmanuel/contacts/trabajo/', 'existed': True}

Cuando usarla

Cuando el usuario quiere una libreta/agenda de contactos nueva ademas de la principal: una coleccion CardDAV separada ("Trabajo", "Personal", "Familia") con su propio nombre visible, bajo el contacts-home del principal. Es la analoga de dav_make_calendar para CardDAV. El href devuelto es la ruta de la coleccion que luego usas para escribir vCards (PUT de cada contacto) o para listarla en el selector de libretas.

Gotchas

  • Impura: requiere red + Basic auth contra el servidor DAV. El password viene de pass, no se logea ni se hardcodea.
  • Idempotente: si la coleccion ya existe en ese path el servidor responde 405 (Method Not Allowed) o 301; ambos se traducen a {status:'ok', existed:True} en vez de error, asi que es seguro reintentar.
  • A diferencia de los calendarios (que tienen el metodo HTTP dedicado MKCALENDAR), CardDAV NO define un "MKADDRESSBOOK". La creacion se hace con MKCOL extendido (RFC 5689): metodo HTTP MKCOL con un cuerpo XML que declara el resourcetype como D:collection + C:addressbook. Probado contra Xandikos, que lo soporta.
  • Fallback para servidores sin MKCOL extendido: algunos servidores CardDAV viejos no aceptan cuerpo en MKCOL y devuelven 415/400. En ese caso el patron es MKCOL simple (sin cuerpo) para crear la coleccion + un PROPPATCH posterior que fije el resourcetype addressbook, el displayname y la addressbook-description. Esta funcion implementa solo el camino extendido (un request); si te topas con un servidor que no lo soporta, anade el fallback MKCOL+PROPPATCH antes de promoverlo.
  • El slug se sanea a [a-z0-9_-] (minusculas, espacios->guion, resto fuera). Un slug que queda vacio tras sanear (p.ej. solo simbolos) devuelve error de validacion sin tocar la red. El display_name y la description se escapan para XML, pero el slug que va en la URL ya esta restringido al charset seguro.