---
name: extract_or_make_uid
kind: function
lang: py
domain: infra
version: "1.0.0"
purity: pure
signature: "def extract_or_make_uid(component_text: str, prefix: str = 'goog-') -> str"
description: "Extrae el campo UID: de un componente iCal (VEVENT/VCALENDAR) o vCard (VCARD). Si el componente no declara UID, sintetiza uno determinista derivado del contenido: '<prefix><md5(text)[:16]>'. El mismo texto produce siempre el mismo UID. Pura, solo stdlib (re, hashlib). Imprescindible al importar a CardDAV/CalDAV: el nombre del recurso se deriva del UID y cada componente necesita uno estable para idempotencia (re-importar no duplica)."
tags: [dav, carddav, caldav, uid, vcard, vevent, ical, infra, extract]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: ""
imports: [re, hashlib]
params:
  - name: component_text
    desc: "texto de un componente VCARD o VEVENT/VCALENDAR del que extraer (o derivar) el UID."
  - name: prefix
    desc: "prefijo del UID sintetico cuando el componente no declara UID. Default 'goog-' (origen Google export)."
output: "str. El valor del campo UID stripeado si el componente lo declara. Si no, un UID determinista '<prefix><md5(component_text)[:16]>'. No lanza para input no vacio."
tested: true
tests:
  - "test_uid_presente_se_extrae"
  - "test_sin_uid_genera_determinista"
  - "test_mismo_texto_mismo_uid_sintetico"
  - "test_prefix_personalizado"
  - "test_uid_con_espacios_se_stripea"
test_file_path: "python/functions/infra/extract_or_make_uid_test.py"
file_path: "python/functions/infra/extract_or_make_uid.py"
---

## Ejemplo

```python
import sys
sys.path.insert(0, "python/functions")
from infra.extract_or_make_uid import extract_or_make_uid

with_uid = "BEGIN:VEVENT\r\nUID:abc-123@google.com\r\nSUMMARY:x\r\nEND:VEVENT"
print(extract_or_make_uid(with_uid))     # abc-123@google.com

no_uid = "BEGIN:VCARD\r\nFN:Ada\r\nEND:VCARD"
print(extract_or_make_uid(no_uid))       # goog-<md5 16 hex>  (estable)
```

## Cuando usarla

Cuando importas un VCARD o un VEVENT a un servidor DAV y necesitas el UID para
(a) construir el nombre del recurso (`safe(uid) + .vcf/.ics`) y (b) garantizar
idempotencia: re-subir el mismo componente sobrescribe en vez de duplicar.
Usada por los pipelines `import_vcf_to_carddav` e `import_ics_to_caldav` por
cada elemento antes del PUT. Si el export no trae UID (comun en algunas tarjetas
de Google), esta funcion lo fabrica de forma estable a partir del contenido.

## Gotchas

Funcion pura. El UID sintetico depende del contenido EXACTO del componente: si
el texto cambia (aunque sea un espacio), el md5 cambia y se generaria un recurso
nuevo en vez de actualizar el existente. Para componentes con UID propio esto no
ocurre. md5 se usa solo como hash de identidad determinista, no como primitiva
de seguridad.
