# Télécharger les fichiers uploadés par un usager sur son dossier

{% hint style="info" %}
**Nous recommandons de paralléliser / asynchroniser le téléchargement des fichiers**. En effet, un dossier peut avoir de nombreuses PJ, qui elle même peuvent peser jusqu'a 200Mo.&#x20;
{% endhint %}

{% hint style="danger" %}
Attention, les liens vers **les fichiers expirent au bout de 1h**.
{% endhint %}

Pour ajouter les URLs des fichiers à votre code existant, Il vous faut ajouter le `FileFragment` au `ChampFragment` :

```graphql
  fragment ChampFragment on Champ {
    ... on PieceJustificativeChamp {
      files {
        ...FileFragment
      }
    }
  }
  
  fragment FileFragment on File {
    filename
    contentType
    checksum
    byteSize: byteSizeBigInt
    url
  }
```

Vous pouvez tester en executant le script suivant avec les variables d'environnement adaptées :

<pre class="language-bash"><code class="lang-bash"><strong>API_TOKEN="votre_token" DEMARCHE_NUMBER=votre_numero_de_demarche ruby downloader.rb
</strong></code></pre>

Pour faciliter la lecture du code, la query complète GraphQL est fournie en PJ

{% file src="/files/EyJSItON49QJ7NhVP4IF" %}
query GraphQL minimaliste pour lister les type de champs Piece Justificative ainsi que les fichiers associéés
{% endfile %}

Ensuite, vous pouvez executer ce code ruby

{% code title="downloader.rb" %}

```ruby
require 'net/http'
require 'uri'
require 'json'
ENDPOINT = URI('https://demarche.numerique.gouv.fr/api/v2/graphql')

### that's the GraphQL part.
# We store the query in a flat file because it's easier to read
def query
  File.read("getDemarche.listOnlyFilesUrl.graphql")
end

### that's the HTTP part
# open an http connexion to our GraphQL endpoint
def open_http_connection
  http = Net::HTTP.new(ENDPOINT.host, ENDPOINT.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  http
end

# the headers of our http query, include auth
def request_headers
  {
    "Content-Type" => "application/json",
    "Authorization" => "Bearer #{ENV['API_TOKEN']}"
  }
end

# given an http connexion, request the API for page
def request_page(http)
  # the data of our query
  data = {
    "query" => query,
    "operationName" => "getDemarche",
    "variables" => {
      "demarcheNumber": ENV['DEMARCHE_NUMBER'].to_i,
      "first": 100
    }
  }

  req = Net::HTTP::Post.new(ENDPOINT, request_headers)
  req.body = data.to_json

  response = http.request(req)

  data = JSON.parse(response.body)
  data
end

http = open_http_connection
# check if we persisted a cursor so we continue polling
data = request_page(http)

dossiers = data.dig('data', 'demarche', 'dossiers', 'nodes')
puts "Info: fetched dossiers ids: #{dossiers.map{ _1['number'] }.join(', ')}"

all_champs = dossiers.flat_map { |dossier| dossier['champs'] }
all_champs_pj = all_champs.filter { |champ| champ['files'] }
all_url_to_download = all_champs_pj.flat_map { |pj| pj['files'].map{ |file| file['url'] } }

puts "Info: now you can download each of those url: #{all_url_to_download.join(', ')}"

```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://doc.demarches-simplifiees.fr/api-graphql/cas-dusages-exemple-dimplementation/telecharger-les-fichiers-uploades-par-un-usager-sur-son-dossier.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
