pythonpermissionsphoto

PermissionError: Operation not permitted, I can't access to my photos library (python)


I know there are a lot of questions like this but I just couldn't get right answers .

I have updated my mac to macOS Catalina, I use Python 3.7.9 with IDLE but I can't access to my photos library.

import os
os.listdir("/Users/me/Pictures/Photos Library.photoslibrary")

and this raise an error:

Traceback (most recent call last):
  File "/Users/me/mycode.py", line 2, in <module>
    os.listdir("/Users/me/Pictures/Photos Library.photoslibrary")
PermissionError: [Errno 1] Operation not permitted: '/Users/me/Pictures/Photos Library.photoslibrary'

I can execute the code with Terminal:

$ python "/Users/me/mycode.py"

That works but I prefer execute my code in IDLE and it doesn't work.

I execute this:

$ ls -l "/Users/me/Pictures"

It's returned:

drwxrwxrwx@ 13 me group  416 Jan  2 10:10 Photos Library.photoslibrary

In System Preferences > Security & Privacy > Privacy, The IDLE is already in the Full Disk Access and in Photos with check mark in both. I have also add Finder in Developer Tools.

In Terminal I have executed this code:

$ sudo chown me:group "/Users/me/Pictures/Photos Library.photoslibrary"

It still does not work.

I don't know what to do to solve this problem.

Help me please, Thanks.


Solution

  • Answer: "Full Disk Access"

    Stumbled on the answer that worked for me at least here, https://cleanmymac.com/blog/operation-not-permitted-terminal ,

    was to give the Terminal app "Full Disk Access" from "System Preferences > Security & Privacy > Privacy > Full Disk Access ". (I'm on macos Monterey "12.4")

    Before doing the above, I was similarly stumped!

    I was only able to access the first of the 16 special hex directories, "/Users/me/Pictures/Photos Library.photoslibrary/originals/0" , but mysteriously none of the others 1, 2,..., E, F

    # (replaced my name with "me" below)
    workdir = "/Users/me/Pictures/Photos Library.photoslibrary/originals"
    [str(x) for x in (Path(workdir) / "0").glob("*")][:5]
    
    ['/Users/me/Pictures/Photos Library.photoslibrary/originals/0/0D1F85D7-627E-49A6-B108-65EF9BB46681.heic',
     '/Users/me/Pictures/Photos Library.photoslibrary/originals/0/0FB4B6E0-22D3-4601-B524-8708A18B1B10.jpeg',
     '/Users/me/Pictures/Photos Library.photoslibrary/originals/0/04122C50-1648-43CC-A325-DDF72C2F1FE3.jpeg',
     '/Users/me/Pictures/Photos Library.photoslibrary/originals/0/048D0DF3-F9D5-4DB6-B1F1-DE1C54A2786F.jpeg',
     '/Users/me/Pictures/Photos Library.photoslibrary/originals/0/082F4E1D-C222-47F3-99EA-9D7501848B6B.jpeg']
    

    Mini side note

    Also, I found this, https://github.com/muxcmux/apple-photos-forensics , to be an interesting resource about interpreting /Users/me/Pictures/Photos Library.photoslibrary/database/Photos.sqlite , for instance when I ran,

    select * from ZASSET
    

    I got, 11773 rows, containing those above filenames as the "ZFILENAME" column. (So below, I'm just using a function run_query that uses python's built-in sqlite3 to run queries)

    In [153]: sql = "select ZUUID, ZFILENAME from ZASSET  "
         ...: df = run_query("Photos.sqlite", sql)
         ...: print(df.shape)
         ...: df.head()
    (11773, 2)
    Out[153]: 
                                      ZUUID                                 ZFILENAME
    0  54ACC8C9-A682-4A4C-A4F1-E1808DBF8B0A  54ACC8C9-A682-4A4C-A4F1-E1808DBF8B0A.JPG
    1  162CBC99-72D3-44AD-AB4E-9FC1909BCFA6  162CBC99-72D3-44AD-AB4E-9FC1909BCFA6.JPG
    2  182AD204-814A-4E0E-94D1-6E9D7A9ED26B  182AD204-814A-4E0E-94D1-6E9D7A9ED26B.JPG
    3  5C0D5113-9017-4E5A-BB67-EF875F99B906  5C0D5113-9017-4E5A-BB67-EF875F99B906.JPG
    4  576C9DCB-71A1-4AEF-A4C8-6EC4B561AFDB  576C9DCB-71A1-4AEF-A4C8-6EC4B561AFDB.JPG