@reynlds
Our process works in multiple stages. Every morning after our SIS import runs, I download a complete list of all our canvas users and import them into a SQL Table. I then match those users and identify which ones are students, parents, teachers, etc. After I do that, I grab all the student id’s and scan a file share that has all our student id photos. If they have a photo, I update the table with the full path, and an md5 hash (to compare when a new photo is taken).
At the end of each week, our process runs gets of a list of students who have new id photos or do not have an avatar already in canvas and sends it. I took this approach rather than just reuploading them each week because Instructure seems to have a rather aggressive rate limit and would cause the process to die out. It took about 19 hours to get the main batch up. I also took this approach so that we do not keep uploading the same photo each week causing duplicates. Another thing to note is if the user is over their quota, you will not be able to upload a user avatar for them. From there it runs the API queries to create the upload form and then upload the avatar and then to assign it to the user. I log the unique ids and tokens to a database that I use to compare when a user changes their avatar or when a new one needs to be uploaded.
I know very little about python, but this is the script that I based my powershell code on:
https://github.com/unsupported/canvas/blob/b3acbb55267feb69e14078d83655f594e992c94f/api/bulk_assign_...
As far as the powershell side of things, I store all the canvas ids in a variable and then put it in a parallel foreach loop to go through each id and make the changes. If you are curious about more of the specifics on that let me know. I hope this helps.