> ## Documentation Index
> Fetch the complete documentation index at: https://docs.x.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Autenticación

> Autentica el Python XDK con Bearer Token, OAuth 2.0 PKCE o contexto de usuario OAuth 1.0a para llamar a los endpoints de la X API y publicar en nombre de los usuarios.

La X API requiere autenticación para todos los endpoints. El XDK admite tres métodos de autenticación:

1. Bearer Token (app-only)
2. OAuth 2.0 con PKCE
3. OAuth 1.0a (contexto de usuario)

* **Bearer Token**: Úsalo para acceso de solo lectura en endpoints que admiten autenticación de app (por ejemplo, buscar Posts, endpoints de streaming).
* **OAuth 2.0 PKCE**: Autenticación segura para acceso autorizado por el usuario y basado en scopes (por ejemplo, obtener las métricas no públicas del Post del usuario autenticado).
* **OAuth 1.0a**: Autenticación heredada para operaciones específicas del usuario (por ejemplo, publicar en nombre de un usuario, gestionar listas).
  Obtén las credenciales desde la [X Developer Console](https://developer.x.com/en/portal/dashboard). Necesitarás una cuenta de desarrollador aprobada y una app con los permisos adecuados (por ejemplo, Read + Write).

## Crear un Client

Todos los flujos de autenticación crean una instancia de `Client`:

```python theme={null}
from xdk import Client
```

### 1. Bearer Token (App-Only)

Para operaciones de solo lectura sin contexto de usuario.
**Pasos**:

1. En la Developer Console, genera un Bearer Token para tu app.
2. Pásalo al `Client`.
   **Ejemplo**:

```python theme={null}
client = Client(bearer_token="XXXXX")
```

**Uso**:

```python theme={null}
# search_recent returns an Iterator, so iterate over it
for page in client.posts.search_recent(query="python", max_results=10):
    if page.data and len(page.data) > 0:
        first_post = page.data[0]
        post_text = first_post.text if hasattr(first_post, 'text') else first_post.get('text', '')
        print(post_text)  # Access first Post
        break
```

### 2. OAuth 2.0 con PKCE (contexto de usuario)

Este ejemplo muestra cómo usar OAuth 2.0 con Proof Key for Code Exchange (PKCE). Úsalo para acceso específico de un usuario (por ejemplo, publicar en nombre de un usuario, subir contenido multimedia para un usuario, etc.).
**Pasos**:

1. En la Developer Console, registra tu app con una URI de redirección (por ejemplo, `http://localhost:8080/callback`).
2. Obtén el Client ID (no se necesita secret para PKCE).
3. Inicia el flujo, dirige al usuario a la URL de autorización y gestiona el callback.
   **Ejemplo** (usando un servidor web para el callback):

```python title="Example" expandable lines wrap icon="python" theme={null}
from xdk.oauth2_auth import OAuth2PKCEAuth
from urllib.parse import urlparse
import webbrowser
# Step 1: Create PKCE instance
auth = OAuth2PKCEAuth(
    client_id="YOUR_CLIENT_ID",
    redirect_uri="YOUR_CALLBACK_URL",
    scope="tweet.read users.read offline.access"
)
# Step 2: Get authorization URL
auth_url = auth.get_authorization_url()
print(f"Visit this URL to authorize: {auth_url}")
webbrowser.open(auth_url)
# Step 3: Handle callback (in a real app, use a web framework like Flask)
# Assume callback_url = "http://localhost:8080/callback?code=AUTH_CODE_HERE"
callback_url = input("Paste the full callback URL here: ")
# Step 4: Exchange code for tokens
tokens = auth.fetch_token(authorization_response=callback_url)
access_token = tokens["access_token"]
refresh_token = tokens["refresh_token"]  # Store for renewal
# Step 5: Create client
# Option 1: Use bearer_token (OAuth2 access tokens work as bearer tokens)
client = Client(bearer_token=access_token)
# Option 2: Pass the full token dict for automatic refresh support
# client = Client(token=tokens)
```

**Renovación de token** (automática en el SDK para sesiones de larga duración):

```python theme={null}
# If access token expires, refresh using stored refresh_token
# The refresh_token method uses the stored token from the OAuth2PKCEAuth instance
tokens = auth.refresh_token()
# Use the refreshed token
client = Client(bearer_token=tokens["access_token"])
# Or pass the full token dict: client = Client(token=tokens)
```

### 3. OAuth 1.0a (contexto de usuario)

Para aplicaciones heredadas o casos de uso específicos que requieren autenticación con OAuth 1.0a:
**Pasos**:

1. En la Developer Console, obtén tu API Key y API Secret.
2. Si ya tienes access tokens, úsalos directamente. De lo contrario, completa el flujo de OAuth 1.0a para obtenerlos.
3. Crea una instancia de OAuth1 y pásala al Client.
   **Ejemplo** (con access tokens existentes):

```python title="Example" lines wrap icon="python" theme={null}
from xdk import Client
from xdk.oauth1_auth import OAuth1
# Step 1: Create OAuth1 instance with credentials
oauth1 = OAuth1(
    api_key="YOUR_API_KEY",
    api_secret="YOUR_API_SECRET",
    callback="http://localhost:8080/callback",
    access_token="YOUR_ACCESS_TOKEN",
    access_token_secret="YOUR_ACCESS_TOKEN_SECRET"
)
# Step 2: Create client with OAuth1
client = Client(auth=oauth1)
# Step 3: Use the client
response = client.users.get_me()
me = response.data
print(me)
```

**Ejemplo** (flujo completo de OAuth 1.0a):

```python title="Example" lines wrap icon="python" theme={null}
from xdk import Client
from xdk.oauth1_auth import OAuth1
import webbrowser
# Step 1: Create OAuth1 instance
oauth1 = OAuth1(
    api_key="YOUR_API_KEY",
    api_secret="YOUR_API_SECRET",
    callback="http://localhost:8080/callback"
)
# Step 2: Get request token
request_token = oauth1.get_request_token()
# Step 3: Get authorization URL
auth_url = oauth1.get_authorization_url(login_with_x=False)
print(f"Visit this URL to authorize: {auth_url}")
webbrowser.open(auth_url)
# Step 4: User authorizes and you receive oauth_verifier
# In a real app, handle this via callback URL
oauth_verifier = input("Enter the OAuth verifier from the callback: ")
# Step 5: Exchange for access token
access_token = oauth1.get_access_token(oauth_verifier)
# Step 6: Create client
client = Client(auth=oauth1)
# Now you can use the client
response = client.users.get_me()
```

**Nota**:

* Nunca guardes secrets en el código en producción; usa variables de entorno o gestores de secretos (por ejemplo, `os.getenv("X_BEARER_TOKEN")`).
* Para PKCE, asegúrate de usar HTTPS en las URIs de redirección en producción.
* El SDK valida los tokens y lanza `xdk.AuthenticationError` si fallan.
  Para ejemplos de código detallados usando el Python XDK, consulta nuestro [repositorio de ejemplos de código en GitHub](https://github.com/xdevplatform/samples/tree/main/python).
