Page through S3 objects matching specific filename using boto3
<p>I have an AWS S3 bucket with a Prefix (or "folder") called <code>/photos</code>. That "contains" a bunch of image files and even fewer <code>EVENT.json</code> files. A naive representation might look like this:</p>

<ul>
<li>my-awesome-events-bucket

<ul>
<li>photos

<ul>
<li>image1.jpg</li>
<li>image2.jpg</li>
<li>1_EVENT.json</li>
<li>image3.jpg</li>
<li>2_EVENT.json</li>
<li>...</li>
</ul></li>
</ul></li>
</ul>

<p>The <code>EVENT.json</code> files have an object that contains a path reference to an arbitrary amount of image files, which group images into a specific event. Using the example above, image1.jpg and image2.jpg could appear in 1_EVENT.json, and image3.jpg may belong to 2_EVENT.json.</p>

<p>As the bucket gets larger, I have an interest in paging through the results. I only want to request a page at a time from S3 as I need them. The problem I'm running into is that I want to page specifically by keys that contain the word "EVENT". I'm finding this difficult to accomplish without bringing back ALL the objects and then filtering or iterating the results.</p>

<p>Using an <a href="http://boto3.readthedocs.io/en/latest/reference/services/s3.html?highlight=get_object#S3.Paginator.ListObjectsV2" rel="nofollow noreferrer">S3 Paginator</a>, I'm able to get paging working. Assuming my <code>PageSize</code> and <code>MaxItems</code> are set to 6, this is what I might get back for my first page:</p>

<pre><code>/photos/
/photos/image1.jpg
/photos/image2.jpg
/photos/1_EVENT.json
/photos/image3.jpg
/photos/2_EVENT.json
</code></pre>

<p>S3's flat structure means that it's paging through all objects in the bucket according to the Prefix, and limiting and paging according to the pagination parameters. This means that I could easily get multiple EVENT.json files, or none at all, depending on the page.</p>

<p>So I'm looking for something more along the lines of this:</p>

<pre><code>/photos/1_EVENT.json
/photos/2_EVENT.json
/photos/3_EVENT.json
/photos/4_EVENT.json
/photos/5_EVENT.json
/photos/6_EVENT.json
</code></pre>

<p><em>without</em> first having to request all objects and then slice the results set in some way; which is exactly what I'm doing currently:</p>

<pre class="lang-py prettyprint-override"><code>client = boto3.client('s3')
paginator = client.get_paginator('list_objects_v2')
page_iterator = paginator.paginate(
    Bucket=app.config.get('S3_BUCKET'),
    Prefix="photos/")  # Left PaginationConfig MaxItems &amp; PageSize off intentionally
filtered_iterator = page_iterator.search(
    "Contents[?contains(Key, `EVENT`)][]")
for page in filtered_iterator:
    # Do stuff.
    pass
</code></pre>

<p>The above is really expensive, with no paging, but it does give me a list of all files containing my "EVENT" search string.</p>

<p>I specifically want to page results of <em>only</em> EVENT.json objects through S3 using boto3 without the overhead of returning and filtering all objects every request. Is that possible?</p>

<p>EDIT: I'm already narrowing requests down to just objects with the <code>photos/</code> Prefix. This is because there are other "folders" in my bucket that also may contain EVENT files. That prevents me from using EVENT or EVENT.json as my Prefix, because the response may be polluted by files from other folders.</p>