> This page is for Piattaforma, version Versione precedente.
> For other versions, use one of these documentation indexes:
> - V4 (default): https://next.developer.frame.io/platform/v4/llms.txt
> - V4 sperimentale: https://next.developer.frame.io/platform/v4-experimental/llms.txt
> - Versione precedente: 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.

# Raccogliere tutti i commenti da un progetto

## Panoramica




L'estrattore di commenti recupera tutte le risorse in un progetto, estrae i commenti ed esporta tutto in un file .csv.Questa procedura dettagliata utilizza le seguenti risorse:



* [SDK Python](https://github.com/Frameio/python-frameio-client): l'SDK gestisce la paginazione e configura un client che puoi utilizzare con i token sviluppatore (autenticazione bearer).
* [Estrattore di commenti in Python](https://github.com/Frameio/comment-scraper-python): l'esempio di codice che stiamo usando è qui.




### Provalo su Glitch

Glitch è uno strumento semplice che ti permette di configurare, testare ed eseguire le applicazioni utilizzando i loro server. Se non conosci Glitch, consulta la nostra guida sull'[utilizzo di Glitch](/other-tools/using-glitch). Se vuoi vedere come funziona l'estrattore di commenti su un server, abbiamo configurato un'app Flask su [Glitch](https://glitch.com): [Frame.io Comment Scraper in Python](https://glitch.com/~frameio-comment-scraper).

### Ambiti richiesti




Prima di iniziare questa guida, assicurati di avere un token che includa almeno i seguenti ambiti:




| Ambito | Motivo |
| ---------- | ---------- |
| **Progetti:** lettura | Non strettamente necessario, ma serve per recuperare il `root_asset_id` di un progetto. |
| **Risorse:** lettura | Necessario per navigare tra gli `asset_id` tramite API |
| **Commenti:** lettura | Necessario per recuperare i commenti stessi. |




### 1. Prepara l'app

Questa guida seguirà un modello simile a quello della guida [Leggere l'albero dei file](/workflows-assets/reading-the-file-tree). Di conseguenza, per iniziare ti serve:
* Il `root_asset_id` del progetto che stai scansionando
* Il tuo [token sviluppatore](/authentication/developer-tokens)

Devi anche importare `FrameioClient` nell'app Python, oltre ad alcune librerie di supporto aggiuntive:

**`Python`**

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

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





### 2. Scansiona il progetto




Ora devi recuperare ricorsivamente tutte le risorse, controllarle per verificare la presenza di commenti e archiviare le risorse commentate in un elenco da cui costruire il file .csv.





Durante la scansione del progetto, devi eseguire i seguenti controlli su ogni risorsa:



* La risorsa è un file? (`&quot;_type&quot;: &quot;file&quot;`).

* Se è un file, contiene commenti? * **Se li contiene, recuperali e aggiungili all'elenco.**
* La risorsa è una cartella? (`&quot;_type&quot;: &quot;folder&quot;`)

* **Se è una cartella, esegui una scansione ricorsiva sulle relative cartelle figlio.**
* La risorsa è uno stack di versioni? (`&quot;_type&quot;: &quot;version_stack&quot;`)

* **Se è uno stack di versioni, recupera tutti gli elementi figlio e controlla se hanno dei commenti.**

**`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="Non dimenticare la paginazione">
  L'esempio precedente ignora la paginazione, ma durante la navigazione in raccolte di grandi dimensioni, non conviene ignorarla.Consulta la guida sui [concetti chiave](/getting-started/key-concepts#pagination) come riferimento.
</Info>


### 3. Appiattisci l'elenco dei commenti




A meno che non l'abbia già fatto durante la scansione, devi appiattire l'elenco per semplificare l'elaborazione.





**`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. Seleziona l'elenco e crea il file .csv




Quando l'elenco è appiattito, puoi usare la comprensione dell'elenco per acquisire gli elementi che ritieni utili di ogni commento, per poi inviarli in un file .csv.Consigliamo di includere almeno:



* Commento - `text`
* ID padre - `parent_id`
* ID risorsa - `asset_id`
* Nome risorsa - `name`
* ID proprietario - `owner_id`
* E-mail del proprietario - `owner.email`
* Marca temporale - `timestamp`
* Ora di aggiornamento - `updated_at`




Dopo aver creato un nuovo elenco contenente l'output desiderato per ogni risorsa per l'ouput finale, è il momento di scrivere nel file .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)
```





Ecco fatto! Ora hai un file .csv con i commenti appiattiti di un intero progetto Frame.io.