{"id":20425948,"url":"https://github.com/trevorhobenshield/amazon_photos","last_synced_at":"2025-08-01T03:06:48.763Z","repository":{"id":188303919,"uuid":"678531287","full_name":"trevorhobenshield/amazon_photos","owner":"trevorhobenshield","description":"Amazon Photos API","archived":false,"fork":false,"pushed_at":"2024-07-28T20:09:17.000Z","size":133,"stargazers_count":71,"open_issues_count":16,"forks_count":16,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-07-08T14:56:11.205Z","etag":null,"topics":["amazon","amazon-photos","api","archive","automation","data"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/amazon_photos","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/trevorhobenshield.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-08-14T19:13:12.000Z","updated_at":"2025-07-08T09:54:15.000Z","dependencies_parsed_at":"2023-12-13T07:25:47.049Z","dependency_job_id":"f5f536c1-37ae-4846-b049-e41f9b340f8c","html_url":"https://github.com/trevorhobenshield/amazon_photos","commit_stats":null,"previous_names":["trevorhobenshield/amazon_photos"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/trevorhobenshield/amazon_photos","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trevorhobenshield%2Famazon_photos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trevorhobenshield%2Famazon_photos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trevorhobenshield%2Famazon_photos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trevorhobenshield%2Famazon_photos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trevorhobenshield","download_url":"https://codeload.github.com/trevorhobenshield/amazon_photos/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trevorhobenshield%2Famazon_photos/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268162391,"owners_count":24205702,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amazon","amazon-photos","api","archive","automation","data"],"created_at":"2024-11-15T07:14:47.103Z","updated_at":"2025-08-01T03:06:48.191Z","avatar_url":"https://github.com/trevorhobenshield.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Amazon Photos API\n\n## Table of Contents\n\n\u003c!-- TOC --\u003e\n\n* [Installation](#installation)\n* [Setup](#setup)\n* [Examples](#examples)\n* [Search](#search)\n* [Nodes](#nodes)\n    * [Restrictions](#restrictions)\n    * [Range Queries](#range-queries)\n* [Notes](#notes)\n    * [Known File Types](#known-file-types)\n* [Custom Image Labeling (Optional)](#custom-image-labeling-optional)\n\n\u003c!-- TOC --\u003e\n\n\u003e It is recommended to use this API in a [Jupyter Notebook](https://jupyter.org/install), as the results from most\n\u003e endpoints\n\u003e are a [DataFrame](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame)\n\u003e which can be neatly displayed and efficiently manipulated with vectorized ops. This becomes\n\u003e increasingly important if you have \"large\" amounts of data (e.g. \u003e1 million photos/videos).\n\n## Installation\n\n```bash\npip install amazon-photos -U\n```\n\n### Output Examples\n\n`ap.db`\n\n|   | dateTimeDigitized        | id                     | name              | ... | model             | apertureValue | focalLength | width | height |   size |\n|--:|:-------------------------|:-----------------------|:------------------|:----|:------------------|:--------------|:------------|------:|-------:|-------:|\n| 0 | 2019-07-06T18:22:00.000Z | HeMReF-vvJiTTkdPIeWuoP | 1694252973839.png | ... | iPhone XS         | 54823/32325   | 17/4        |  3024 |   4032 | 432777 |\n| 1 | 2023-01-18T09:36:22.000Z | z_HiIvASAKqWmdrkjWiqMZ | 1692626817154.jpg | ... | iPhone XS         | 54823/32325   | 17/4        |  3024 |   4032 | 234257 |\n| 2 | 2022-08-14T14:13:21.000Z | LKXEZbqoVrhrOYBezisGEQ | 1798219686789.jpg | ... | iPhone 11 Pro Max | 54823/32325   | 17/4        |  3024 |   4032 | 423987 |\n| 3 | 2020-06-28T19:32:30.000Z | EPUeciHtfKkGiYkfUyEuMa | 1593482220567.jpg | ... | iPhone XS         | 54823/32325   | 17/4        |  3024 |   4032 | 898957 |\n| 4 | 2021-07-07T17:12:55.000Z | fdfKzRJbEyoVeGcfCoJgE- | 1592299282720.png | ... | iPhone XR         | 54823/32325   | 17/4        |  3024 |   4032 | 432556 |\n| 5 | 2021-08-18T18:32:41.000Z | crskJSmKPFRhxbpfkivyLm | 1592902159105.png | ... | iPhone XR         | 54823/32325   | 17/4        |  3024 |   4032 | 123123 |\n| 6 | 2023-08-23T19:12:21.000Z | qkBFUlyIdkUwVVSaVWWKEF | 1598138358650.png | ... | iPhone 11         | 54823/32325   | 17/4        |  3024 |   4032 | 437887 |\n| 7 | 2021-06-19T17:14:13.000Z | TXKMKC-mHvSUrtRfwmtyDe | 1622199863606.jpg | ... | iPhone 12 Pro     | 14447/10653   | 21/5        |  1536 |   2048 | 758432 |\n| 8 | 2023-02-15T22:45:40.000Z | FRDvvjcZdpFWiwrIZfTNHO | 1581874518054.jpg | ... | iPhone 8 Plus     | 54823/32325   | 399/100     |  1348 |   2049 | 862883 |\n\n`ap.print_tree()`\n\n```text\n~ \n├── Documents \n├── Pictures \n│   ├── iPhone \n│   └── Web \n│       ├── foo \n│       └── bar\n├── Videos \n└── Backup \n    ├── LAPTOP-XYZ \n    │   └── Desktop \n    └── DESKTOP-IJK \n        └── Desktop\n```\n\n## Setup\n\n\u003e [Update] Jan 04 2024: To avoid confusion, setting env vars is no longer supported. One must pass cookies directly as\n\u003e shown below.\n\nLog in to Amazon Photos and copy the following cookies:\n\n- `session-id`\n- `ubid`*\n- `at`*\n\n### Canada/Europe\n\nwhere `xx` is the TLD (top-level domain)\n\n- `ubid-acbxx`\n- `at-acbxx`\n\n### United States\n\n- `ubid_main`\n- `at_main`\n\nE.g.\n\n```python\nfrom amazon_photos import AmazonPhotos\n\nap = AmazonPhotos(\n    ## US\n    # cookies={\n    #     'ubid_main': ...,\n    #     'at_main': ...,\n    #     'session-id': ...,\n    # },\n\n    ## Canada\n    # cookies={\n    #     'ubid-acbca': ...,\n    #     'at-acbca': ...,\n    #     'session-id': ...,\n    # }\n\n    ## Italy\n    # cookies={\n    #     'ubid-acbit': ...,\n    #     'at-acbit': ...,\n    #     'session-id': ...,\n    # }\n)\n```\n\n## Examples\n\n\u003e A database named `ap.parquet` will be created during the initial setup. This is mainly used to reduce upload conflicts\n\u003e by checking your local file(s) md5 against the database before sending the request.\n\n```python\nfrom amazon_photos import AmazonPhotos\n\nap = AmazonPhotos(\n    # see cookie examples above\n    cookies={...},\n    # optionally cache all intermediate JSON responses\n    tmp='tmp',\n    # pandas options\n    dtype_backend='pyarrow',\n    engine='pyarrow',\n)\n\n# get current usage stats\nap.usage()\n\n# get entire Amazon Photos library\nnodes = ap.query(\"type:(PHOTOS OR VIDEOS)\")\n\n# query Amazon Photos library with more filters applied\nnodes = ap.query(\"type:(PHOTOS OR VIDEOS) AND things:(plant AND beach OR moon) AND timeYear:(2023) AND timeMonth:(8) AND timeDay:(14) AND location:(CAN#BC#Vancouver)\")\n\n# sample first 10 nodes\nnode_ids = nodes.id[:10]\n\n# move a batch of images/videos to the trash bin\nap.trash(node_ids)\n\n# get trash bin contents\nap.trashed()\n\n# permanently delete a batch of images/videos\nap.delete(node_ids)\n\n# restore a batch of images/videos from the trash bin\nap.restore(node_ids)\n\n# upload media (preserves local directory structure and copies to Amazon Photos root directory)\nap.upload('path/to/files')\n\n# download a batch of images/videos\nap.download(node_ids)\n\n# convenience method to get photos only\nap.photos()\n\n# convenience method to get videos only\nap.videos()\n\n# get all identifiers calculated by Amazon.\nap.aggregations(category=\"all\")\n\n# get specific identifiers calculated by Amazon.\nap.aggregations(category=\"location\")\n```\n\n## Search\n\n*Undocumented API, current endpoints valid Dec 2023.*\n\nFor valid **location** and **people** IDs, see the results from the `aggregations()` method.\n\n| name            | type | description                                                                                                                                                                                                                                               |\n|:----------------|:-----|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| ContentType     | str  | `\"JSON\"`                                                                                                                                                                                                                                                  |\n| _               | int  | `1690059771064`                                                                                                                                                                                                                                           |\n| asset           | str  | `\"ALL\"`\u003cbr/\u003e`\"MOBILE\"`\u003cbr/\u003e`\"NONE`\u003cbr/\u003e`\"DESKTOP\"`\u003cbr/\u003e\u003cbr/\u003edefault: `\"ALL\"`                                                                                                                                                                              |\n| filters         | str  | `\"type:(PHOTOS OR VIDEOS) AND things:(plant AND beach OR moon) AND timeYear:(2019) AND timeMonth:(7) AND location:(CAN#BC#Vancouver) AND people:(CyChdySYdfj7DHsjdSHdy)\"`\u003cbr/\u003e\u003cbr/\u003edefault: `\"type:(PHOTOS OR VIDEOS)\"`                                   |\n| groupByForTime  | str  | `\"day\"`\u003cbr/\u003e`\"month\"`\u003cbr/\u003e`\"year\"`                                                                                                                                                                                                                        |\n| limit           | int  | `200`                                                                                                                                                                                                                                                     |\n| lowResThumbnail | str  | `\"true\"`\u003cbr/\u003e`\"false\"`\u003cbr/\u003e\u003cbr/\u003edefault: `\"true\"`                                                                                                                                                                                                         |\n| resourceVersion | str  | `\"V2\"`                                                                                                                                                                                                                                                    |\n| searchContext   | str  | `\"customer\"`\u003cbr/\u003e`\"all\"`\u003cbr/\u003e`\"unknown\"`\u003cbr/\u003e`\"family\"`\u003cbr/\u003e`\"groups\"`\u003cbr/\u003e\u003cbr/\u003edefault: `\"customer\"`                                                                                                                                                     |\n| sort            | str  | `\"['contentProperties.contentDate DESC']\"`\u003cbr/\u003e`\"['contentProperties.contentDate ASC']\"`\u003cbr/\u003e`\"['createdDate DESC']\"`\u003cbr/\u003e`\"['createdDate ASC']\"`\u003cbr/\u003e`\"['name DESC']\"`\u003cbr/\u003e`\"['name ASC']\"`\u003cbr/\u003e\u003cbr/\u003edefault: `\"['contentProperties.contentDate DESC']\"` |\n| tempLink        | str  | `\"false\"`\u003cbr/\u003e`\"true\"`\u003cbr/\u003e\u003cbr/\u003edefault: `\"false\"`                                                                                                                                                                                                        |             |\n\n## Nodes\n\n*Docs last updated in 2015*\n\n| FieldName                     | FieldType                | Sort Allowed | Notes                                                                                                                                                                                                                                       |\n|-------------------------------|--------------------------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| isRoot                        | Boolean                  |              | Only lower case `\"true\"` is supported.                                                                                                                                                                                                      |\n| name                          | String                   | Yes          | This field does an exact match on the name and prefix query. Consider `node1{ \"name\" : \"sample\" }` `node2 { \"name\" : \"sample1\" }` Query filter\u003cbr\u003e`name:sample` will return node1\u003cbr\u003e`name:sample*` will return node1 and node2             |\n| kind                          | String                   | Yes          | To search for all the nodes which contains kind as FILE `kind:FILE`                                                                                                                                                                         |\n| modifiedDate                  | Date (in ISO8601 Format) | Yes          | To Search for all the nodes which has modified from time `modifiedDate:{\"2014-12-31T23:59:59.000Z\" TO *]`                                                                                                                                   |\n| createdDate                   | Date (in ISO8601 Format) | Yes          | To Search for all the nodes created on  `createdDate:2014-12-31T23:59:59.000Z`                                                                                                                                                              |\n| labels                        | String Array             |              | Only Equality can be tested with arrays.\u003cbr\u003eif labels contains `[\"name\", \"test\", \"sample\"]`.\u003cbr\u003eLabel can be searched for name or combination of values.\u003cbr\u003eTo get all the labels which contain name and test\u003cbr\u003e`labels: (name AND test)`  |\n| description                   | String                   |              | To Search all the nodes for description with value 'test'\u003cbr\u003e`description:test`                                                                                                                                                             |\n| parents                       | String Array             |              | Only Equality can be tested with arrays.\u003cbr\u003eif parents contains `[\"id1\", \"id2\", \"id3\"]`.\u003cbr\u003eParent can be searched for name or combination of values.\u003cbr\u003eTo get all the parents which contains id1 and id2\u003cbr\u003e`parents:id1 AND parents:id2` |\n| status                        | String                   | Yes          | For searching nodes with AVAILABLE status.\u003cbr\u003e`status:AVAILABLE`                                                                                                                                                                            |\n| contentProperties.size        | Long                     | Yes          |                                                                                                                                                                                                                                             |\n| contentProperties.contentType | String                   | Yes          | If prefix query, only the major content-type (e.g. `image*`, `video*`, etc.) is supported as a prefix.                                                                                                                                      |\n| contentProperties.md5         | String                   |              |                                                                                                                                                                                                                                             |\n| contentProperties.contentDate | Date (in ISO8601 Format) | Yes          | RangeQueries and equals queries can be used with this field                                                                                                                                                                                 |\n| contentProperties.extension   | String                   | Yes          |                                                                                                                                                                                                                                             |\n\n### Restrictions\n\n\u003e Max # of Filter Parameters Allowed is 8\n\n| Filter Type | Filters                                                                               |\n|:------------|:--------------------------------------------------------------------------------------|\n| Equality    | createdDate, description, isRoot, kind, labels, modifiedDate, name, parentIds, status |\n| Range       | contentProperties.contentDate, createdDate, modifiedDate                              |\n| Prefix      | contentProperties.contentType, name                                                   |\n\n### Range Queries\n\n| Operation            | Syntax                                                           |\n|----------------------|------------------------------------------------------------------|\n| GreaterThan          | `{\"valueToBeTested\" TO *}`                                       |\n| GreaterThan or Equal | `[\"ValueToBeTested\" TO *]`                                       |\n| LessThan             | `{* TO \"ValueToBeTested\"}`                                       |\n| LessThan or Equal    | `{* TO \"ValueToBeTested\"]`                                       |\n| Between              | `[\"ValueToBeTested_LowerBound\" TO \"ValueToBeTested_UpperBound\"]` |\n\n## Notes\n\n#### `https://www.amazon.ca/drive/v1/batchLink`\n\n- This endpoint is called when downloading a batch of photos/videos in the web interface. It then returns a URL to\n  download a zip file, then makes a request to that url to download the content.\n  When making a request to download data for 1200 nodes (max batch size), it turns out to be much slower (~2.5 minutes)\n  than asynchronously downloading 1200 photos/videos individually (~1 minute).\n\n### Known File Types\n\n| Extension | Category |\n|-----------|----------|\n| \\.pdf     | pdf      |\n| \\.doc     | doc      |\n| \\.docx    | doc      |\n| \\.docm    | doc      |\n| \\.dot     | doc      |\n| \\.dotx    | doc      |\n| \\.dotm    | doc      |\n| \\.asd     | doc      |\n| \\.cnv     | doc      |\n| \\.mp3     | mp3      |\n| \\.m4a     | mp3      |\n| \\.m4b     | mp3      |\n| \\.m4p     | mp3      |\n| \\.wav     | mp3      |\n| \\.aac     | mp3      |\n| \\.aif     | mp3      |\n| \\.mpa     | mp3      |\n| \\.wma     | mp3      |\n| \\.flac    | mp3      |\n| \\.mid     | mp3      |\n| \\.ogg     | mp3      |\n| \\.xls     | xls      |\n| \\.xlm     | xls      |\n| \\.xll     | xls      |\n| \\.xlc     | xls      |\n| \\.xar     | xls      |\n| \\.xla     | xls      |\n| \\.xlb     | xls      |\n| \\.xlsb    | xls      |\n| \\.xlsm    | xls      |\n| \\.xlsx    | xls      |\n| \\.xlt     | xls      |\n| \\.xltm    | xls      |\n| \\.xltx    | xls      |\n| \\.xlw     | xls      |\n| \\.ppt     | ppt      |\n| \\.pptx    | ppt      |\n| \\.ppa     | ppt      |\n| \\.ppam    | ppt      |\n| \\.pptm    | ppt      |\n| \\.pps     | ppt      |\n| \\.ppsm    | ppt      |\n| \\.ppsx    | ppt      |\n| \\.pot     | ppt      |\n| \\.potm    | ppt      |\n| \\.potx    | ppt      |\n| \\.sldm    | ppt      |\n| \\.sldx    | ppt      |\n| \\.txt     | txt      |\n| \\.text    | txt      |\n| \\.rtf     | txt      |\n| \\.xml     | markup   |\n| \\.htm     | markup   |\n| \\.html    | markup   |\n| \\.zip     | zip      |\n| \\.rar     | zip      |\n| \\.7z      | zip      |\n| \\.jpg     | img      |\n| \\.jpeg    | img      |\n| \\.png     | img      |\n| \\.bmp     | img      |\n| \\.gif     | img      |\n| \\.tif     | img      |\n| \\.svg     | img      |\n| \\.mp4     | vid      |\n| \\.m4v     | vid      |\n| \\.qt      | vid      |\n| \\.mov     | vid      |\n| \\.mpg     | vid      |\n| \\.mpeg    | vid      |\n| \\.3g2     | vid      |\n| \\.3gp     | vid      |\n| \\.flv     | vid      |\n| \\.f4v     | vid      |\n| \\.asf     | vid      |\n| \\.avi     | vid      |\n| \\.wmv     | vid      |\n| \\.swf     | exe      |\n| \\.exe     | exe      |\n| \\.dll     | exe      |\n| \\.ax      | exe      |\n| \\.ocx     | exe      |\n| \\.rpm     | exe      |\n\n## Custom Image Labeling (Optional)\n\nCategorize your images into folders using computer vision models.\n\n```bash\npip install amazon-photos[extras] -U\n```\n\nSee the [Model List](https://www.hobenshield.com/stats/bench/index.html) for a list of all available models.\n\n### Sample Models\n\n**Very Large**\n\n```\neva02_base_patch14_448.mim_in22k_ft_in22k_in1k\n```\n\n**Large**\n\n```\neva02_large_patch14_448.mim_m38m_ft_in22k_in1k\n```\n\n**Medium**\n\n```\neva02_small_patch14_336.mim_in22k_ft_in1k\nvit_base_patch16_clip_384.laion2b_ft_in12k_in1k\nvit_base_patch16_clip_384.openai_ft_in12k_in1k\ncaformer_m36.sail_in22k_ft_in1k_384\n```\n\n**Small**\n\n```\neva02_tiny_patch14_336.mim_in22k_ft_in1k\ntiny_vit_5m_224.dist_in22k_ft_in1k\nedgenext_small.usi_in1k\nxcit_tiny_12_p8_384.fb_dist_in1k\n```\n\n```python\nrun(\n    'eva02_base_patch14_448.mim_in22k_ft_in22k_in1k',\n    path_in='images',\n    path_out='labeled',\n    thresh=0.0,  # threshold for predictions, 0.9 means you want very confident predictions only\n    topk=5,\n    # window of predictions to check if using exclude or restrict, if set to 1, only the top prediction will be checked\n    exclude=lambda x: re.search('boat|ocean', x, flags=re.I),\n    # function to exclude classification of these predicted labels\n    restrict=lambda x: re.search('sand|beach|sunset', x, flags=re.I),\n    # function to restrict classification to only these predicted labels\n    dataloader_options={\n        'batch_size': 4,  # *** adjust ***\n        'shuffle': False,\n        'num_workers': psutil.cpu_count(logical=False),  # *** adjust ***\n        'pin_memory': True,\n    },\n    accumulate=False,\n    # accumulate results in path_out, if False, everything in path_out will be deleted before running again\n    device='cuda',\n    naming_style='name',  # use human-readable label names, optionally use the label index or synset\n    debug=0,\n)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrevorhobenshield%2Famazon_photos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrevorhobenshield%2Famazon_photos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrevorhobenshield%2Famazon_photos/lists"}