> This page is for Plataforma, version Heredado.
> For other versions, use one of these documentation indexes:
> - V4 (default): https://next.developer.frame.io/platform/v4/llms.txt
> - V4 experimental: https://next.developer.frame.io/platform/v4-experimental/llms.txt
> - Heredado: https://next.developer.frame.io/platform/v2/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://next.developer.frame.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://next.developer.frame.io/_mcp/server.

# Recopilar todos los comentarios de un proyecto

## Información general




El extractor de comentarios recuperará todos los activos de un proyecto, extraerá los comentarios y los exportará en un archivo .csv. Esta descripción detallada utiliza los siguientes recursos:



* [SDK de Python](https://github.com/Frameio/python-frameio-client): El SDK gestiona automáticamente la paginación y configura un cliente que puede usar con tokens de desarrollador (autenticación de portador).
* El [extractor de comentarios en Python](https://github.com/Frameio/comment-scraper-python): La muestra de código que estamos usando está aquí.




### Probarlo en Glitch

Glitch es una herramienta sencilla que le permite configurar sus propias aplicaciones, así como probarlas y ejecutarlas usando sus servidores. Si no está familiarizado con Glitch, consulte nuestra guía sobre el [uso de Glitch](/other-tools/using-glitch). Si quiere ver cómo funciona el extractor de comentarios en un servidor, tenemos una aplicación Flask configurada en [Glitch](https://glitch.com): [Extractor de comentarios de Frame.io en Python](https://glitch.com/~frameio-comment-scraper).

### Ámbitos necesarios




Antes de comenzar a leer esta guía, asegúrese de tener un token que incluya al menos los siguientes ámbitos:




| Ámbito | Motivo |
| ---------- | ---------- |
| **Proyectos:** Lectura | No es estrictamente necesario, pero sí para recuperar el `root_asset_id` de un proyecto. |
| **Activos:** Lectura | Necesario para navegar por `asset_ids` a través de la API. |
| **Comentarios:** Lectura | Necesario para recuperar los comentarios. |




### 1. Preparar su aplicación

Esta guía seguirá un patrón similar al de [Leer el árbol de archivos](/workflows-assets/reading-the-file-tree). Por consiguiente, para empezar, necesitará:
* El `root_asset_id` del proyecto que está rastreando
* Su [token de desarrollador](/authentication/developer-tokens)

También debe importar el `FrameioClient` en su aplicación Python, así como algunas bibliotecas auxiliares adicionales:

**`Python`**

```python title="Python"
from frameioclient import FrameioClient
import requests, json, csv, itertools

ROOT_ASSET_ID = "<ROOT_ASSET_ID>"
TOKEN = "<DEV_TOKEN>"
```





### 2. Rastrear el proyecto




Ahora, necesitará recuperar de forma recursiva todos los activos, comprobarlos para ver si tienen comentarios y almacenar cualquier activo comentado en una lista desde la cual puede construir su archivo .csv.





Durante el rastreo su proyecto, necesitará hacer las siguientes comprobaciones en cada activo:



* ¿Es el activo un archivo? (`&quot;_type&quot;: &quot;file&quot;`).

* Si es un archivo, ¿tiene comentarios? * **Si los tiene, recupérelos y añádalos a su lista.**
* ¿Es el activo una carpeta? (`&quot;_type&quot;: &quot;folder&quot;`)

* **Si es una carpeta, entonces rastree sus elementos secundarios.**
* ¿Es el activo una pila de versiones? (`&quot;_type&quot;: &quot;version_stack&quot;`)

* **Si lo es, obtenga todos los elementos secundarios y compruebe si hay comentarios.**

**`Python`**

```python title="Python"
def all_comments(client, asset_id, comment_list):
    files = client.get_asset_children(asset_id)

    for asset in files:
        if asset['type'] == "file":
            if asset['comment_count'] > 0:
                asset_parent_id = asset['parent_id']
                asset_name = asset['name']
                comments = client.get_comments(asset['id'])
                my_comment_list = [comment for comment in comments.results]
                for object in my_comment_list:
                    object.update({'parent_id':asset_parent_id})
                    object.update({'name':asset_name})
                comment_list.append(my_comment_list)

        if asset['type'] == "folder":
            if asset['item_count'] > 0:
                all_comments(client, asset['id'], comment_list)

        if asset['type'] == "version_stack":
            asset_name = asset['name']
            parent_id = asset['parent_id']
            vfiles = client.get_asset_children(asset['id'])

            for asset in vfiles.results:
                asset_name = asset['name']
                parent_id = asset['parent_id']
                if asset['type'] == "file":
                    if asset['comment_count'] > 0:
                        comments = client.get_comments(asset['id'])
                        my_comment_list = [comment for comment in comments.results]
                        for object in my_comment_list:
                            object.update({'parent_id':parent_id})
                            object.update({'name':asset_name})
                        comment_list.append(my_comment_list)

def get_all_project_comments(root_asset_id, token):
    comment_list = []
    client = FrameioClient(token)

    all_comments(client, root_asset_id, comment_list)

    return comment_list
```




<Info title="No olvide paginar">
  En el ejemplo anterior se ignora la paginación, pero cuando gestione colecciones grandes, no debería hacerlo. Consulte nuestra guía [Conceptos clave](/getting-started/key-concepts#pagination) para obtener referencias.
</Info>


### 3. Aplanar su lista de comentarios




A menos que haya gestionado esto durante su rastreo, lo ideal es que su lista sea plana para facilitar el procesamiento.





**`Python`**

```python title="Python"
# The response list comes back as a list of lists.
# Flatten out responses to a single list so you can build your .csv file.

flat_response_list = list(itertools.chain.from_iterable(responses))
```





### 4. Depurar la lista y crear su .csv




Cuando su lista sea plana, puede usar la comprensión de listas para obtener los elementos de cada comentario que crea que es útil, y luego exportarlos a un archivo .csv. Recomendamos tener al menos:



* Comentario: `text`
* ID principal: `parent_id`
* ID de activo: `asset_id`
* Nombre del activo: `name`
* ID del propietario: `owner_id`
* Correo electrónico del propietario: `owner.email`
* Marca de tiempo: `timestamp`
* Actualizado el: `updated_at`




Cuando haya creado una lista nueva que contenga el resultado que desea por activo para su resultado final, llega el momento de escribir en su archivo .csv.





**`Python`**

```python title="Python"
list_for_csv = [[o['text'], o['parent_id'], o['asset_id'], o['name'], o['owner_id'], o['owner']['email'], o['timestamp'], o['updated_at']] for o in flat_response_list]

# Let's write our new list out to a .csv file. We'll add a heading.
with open("output.csv", 'w') as myfile:
     wr = csv.writer(myfile, dialect='excel')
     wr.writerow(['Comment', 'Parent ID', 'Asset ID', 'Asset Name', 'Owner ID', 'Email', 'Timestamp', 'Updated At'])
     wr.writerows(list_for_csv)
```





Eso es todo. Ahora tiene un archivo .csv con los comentarios planos de todo un proyecto de Frame.io.