Files
fn_registry/python/functions/infra/carddav_put_vcard.md
T
egutierrez a76760edba feat(dav,obsidian): grupo dav completo (CardDAV/CalDAV client + split vcf/ics + import pipelines) + build_obsidian_graph + dav_list_calendars
Funciones reutilizables creadas esta sesion para el sistema self-hosted de contactos/calendario (Xandikos) y la app osint_web:
- grupo dav (infra): split_vcards, split_vevents_to_vcalendars, extract_or_make_uid, carddav_put_vcard, caldav_put_event, dav_list_resources, dav_get_resource, dav_list_calendars
- pipelines: import_vcf_to_carddav, import_ics_to_caldav
- obsidian: build_obsidian_graph (grafo agregado del vault)
2026-06-12 00:43:59 +02:00

4.1 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
carddav_put_vcard function py infra 1.0.0 impure def carddav_put_vcard(base_url: str, username: str, password: str, collection_path: str, uid: str, vcard_text: str, *, timeout_s: float = 20.0, verify_tls: bool = True) -> dict Sube (HTTP PUT) un VCARD a una coleccion CardDAV con HTTP Basic auth. Construye el header Authorization: Basic base64(user:pass) a mano con stdlib. El nombre del recurso se deriva del UID saneado (safe(uid)+'.vcf'). verify_tls=True por defecto. Idempotente por UID: re-subir el mismo UID sobrescribe el recurso. Maneja errores sin lanzar (HTTPError/URLError -> {status:'error'}). Solo stdlib (urllib, base64, re, ssl). Probado contra Xandikos.
dav
carddav
vcard
http
put
contacts
infra
upload
false error_go_core
base64
re
ssl
urllib.error
urllib.request
name desc
base_url URL base del servidor DAV (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
collection_path ruta de la coleccion CardDAV (p.ej. '/enmanuel/contacts/addressbook/').
name desc
uid UID del contacto; se sanea ([^A-Za-z0-9_.-]->_ , max 120 chars) para formar el nombre del recurso .vcf.
name desc
vcard_text texto completo del VCARD (BEGIN:VCARD..END:VCARD). Se asegura terminacion en CRLF.
name desc
timeout_s timeout de la 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, url:str}. En error (sin lanzar): {status:'error', error:str, http_status:int|None}. http_status es el codigo HTTP devuelto por el servidor (201 created / 204 no content tipico en CardDAV). true
test_construye_request_put_con_headers_correctos
test_url_se_forma_con_uid_saneado
test_content_type_es_text_vcard
test_basic_auth_header_correcto
test_httperror_devuelve_status_error
python/functions/infra/carddav_put_vcard_test.py python/functions/infra/carddav_put_vcard.py

Ejemplo

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

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

res = carddav_put_vcard(
    base_url="https://dav-eedeb681c4ab89ab8e444ac9.organic-machine.com",
    username="enmanuel",
    password=pw,
    collection_path="/enmanuel/contacts/addressbook/",
    uid="abc-123@google.com",
    vcard_text="BEGIN:VCARD\r\nVERSION:3.0\r\nFN:Ada Lovelace\r\nUID:abc-123@google.com\r\nEND:VCARD\r\n",
)
print(res)  # {"status": "ok", "http_status": 201, "url": ".../abc-123_google.com.vcf"}

Cuando usarla

Cuando quieres subir un contacto individual a Xandikos (u otro servidor CardDAV) por HTTP. Es la primitiva de escritura del grupo dav; el pipeline import_vcf_to_carddav la invoca por cada tarjeta de un .vcf. Antes de llamarla, resuelve el UID con extract_or_make_uid y la password con pass_get_secret.

Gotchas

  • Hace una escritura remota real: re-subir el mismo UID SOBRESCRIBE el recurso en el servidor (idempotente, no acumula duplicados — esa es la intencion).
  • La contrasena va en el header Basic en claro sobre TLS; nunca hardcodear, leer de pass. La funcion no logea la password.
  • verify_tls=False solo para entornos de prueba; deja un agujero MITM.
  • El servidor puede rechazar (4xx) si el path de la coleccion no existe o el UID del nombre del recurso no coincide con el UID dentro del VCARD: asegurate de que el mismo UID se usa para el nombre del archivo y para el campo UID:.
  • Devuelve dict (status/http_status/error), NO un int crudo: asi captura errores HTTP/red sin lanzar. Consulta res["http_status"] para el codigo.