{"id":22463248,"url":"https://github.com/f2calv/cascap.api.googlephotos","last_synced_at":"2025-04-05T14:03:59.092Z","repository":{"id":37884641,"uuid":"270907384","full_name":"f2calv/CasCap.Api.GooglePhotos","owner":"f2calv","description":"*unofficial* Google Photos REST API library for .NET projects.","archived":false,"fork":false,"pushed_at":"2025-01-27T04:04:14.000Z","size":5402,"stargazers_count":61,"open_issues_count":13,"forks_count":11,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-02-02T09:29:04.189Z","etag":null,"topics":["google-photos","google-photos-albums","google-photos-api","google-photos-backup","google-photos-cli","google-photos-download","google-photos-library-api"],"latest_commit_sha":null,"homepage":null,"language":"C#","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/f2calv.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}},"created_at":"2020-06-09T05:04:22.000Z","updated_at":"2024-12-16T14:28:56.000Z","dependencies_parsed_at":"2024-04-29T05:23:27.183Z","dependency_job_id":"d4aebe16-0f19-434a-a310-4ac8e9d5e340","html_url":"https://github.com/f2calv/CasCap.Api.GooglePhotos","commit_stats":{"total_commits":88,"total_committers":4,"mean_commits":22.0,"dds":"0.38636363636363635","last_synced_commit":"cfbdacd071be2502cfc3405bf0410ee5e1bf8baf"},"previous_names":["f2calv/cascap.api.googlephotos","f2calv/cascap.apis.googlephotos"],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f2calv%2FCasCap.Api.GooglePhotos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f2calv%2FCasCap.Api.GooglePhotos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f2calv%2FCasCap.Api.GooglePhotos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f2calv%2FCasCap.Api.GooglePhotos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/f2calv","download_url":"https://codeload.github.com/f2calv/CasCap.Api.GooglePhotos/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247345850,"owners_count":20924102,"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","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":["google-photos","google-photos-albums","google-photos-api","google-photos-backup","google-photos-cli","google-photos-download","google-photos-library-api"],"created_at":"2024-12-06T09:12:36.379Z","updated_at":"2025-04-05T14:03:59.074Z","avatar_url":"https://github.com/f2calv.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CasCap.Api.GooglePhotos\n\n## _Unofficial_ Google Photos Library API wrapper library for .NET applications\n\n[CasCap.Api.GooglePhotos-badge]: https://img.shields.io/nuget/v/CasCap.Api.GooglePhotos?color=blue\n[CasCap.Api.GooglePhotos-url]: https://nuget.org/packages/CasCap.Api.GooglePhotos\n\n![CI](https://github.com/f2calv/CasCap.Api.GooglePhotos/actions/workflows/ci.yml/badge.svg) [![Coverage Status](https://coveralls.io/repos/github/f2calv/CasCap.Api.GooglePhotos/badge.svg?branch=main)](https://coveralls.io/github/f2calv/CasCap.Api.GooglePhotos?branch=main) [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=f2calv_CasCap.Api.GooglePhotos\u0026metric=code_smells)](https://sonarcloud.io/summary/new_code?id=f2calv_CasCap.Api.GooglePhotos) [![Nuget][CasCap.Api.GooglePhotos-badge]][CasCap.Api.GooglePhotos-url]\n\n\u003e Want to save yourself some coding? See the _preview_ release of [GooglePhotosCli](https://github.com/f2calv/CasCap.GooglePhotosCli) using this library...\n\nThis is an _unofficial_ Google Photos REST API library targeting .NET 8.0.\n\nNote: Older projects that require .NET Standard 2.0 please use version 1.x of this library.\n\nIf you find this library of use then please give it a thumbs-up by giving this repository a :star: ... :wink:\n\nIf you wish to interact with your Google Photos media items/albums then there are official [PHP and Java Client Libraries](https://developers.google.com/photos/library/guides/client-libraries). However if you're looking for a comprehensive .NET library then you were out of luck... until now :)\n\nThe _CasCap.Api.GooglePhotos_ library wraps up all the available functionality of the Google Photos REST API in easy to use methods.\n\nNote: Before you jump in and use this library you should be aware that the [Google Photos Library API](https://developers.google.com/photos/library/reference/rest) has some key limitations. The biggest of these is that the API only allows the upload/addition of images/videos to the library, no edits or deletion are possible and have to be done manually via [https://photos.google.com](https://photos.google.com).\n\n## Google Photos API Set-up\n\nWhen you create your photos application, you must first create an OAuth login details using the [Google API Console](https://console.developers.google.com/) and retrieve a Client ID and a Client Secret.\n\nUsing your Google Account the steps are\\*;\n\n1. Visit [Google API Console](https://console.developers.google.com/)\n2. Select 'Library' on the main menu;\n   - Search for 'Photos Library API', select it from the results and hit the Enable button.\n3. Select 'Credentials' on the main menu;\n   - Select 'Create Credentials' on the sub menu and pick 'OAuth client ID'\n   - Select 'Desktop' as the application type.\n   - Enter a suitable application name and hit the Create button.\n   - Copy/save the Client ID and Client Secret which are then displayed you will use these to authenticate with the GooglePhotosService.\n\n\\*Note: the above instructions are correct as of 2022-04-06.\n\n## Library Configuration/Usage\n\nInstall the package into your project using NuGet ([see details here](https://www.nuget.org/packages/CasCap.Api.GooglePhotos/)).\n\nFor .NET Core applications using dependency injection the primary API usage is to call IServiceCollection.AddGooglePhotos in the Startup.cs ConfigureServices method.\n\n```csharp\n//Startup.cs\nusing Microsoft.Extensions.DependencyInjection;\n\npublic class Startup\n{\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddGooglePhotos();\n    }\n}\n```\n\nThere are 4 mandatory configuration options that must be passed;\n\n- User (your email address)\n- Google Client ID\n- Google Client Secret\n- Authorisation Scopes\n\nThere are 5 possible [authorisation scopes](https://developers.google.com/photos/library/guides/authorization) which designate the level of access you wish to give, these scopes can be combined if required;\n\n- ReadOnly\n- AppendOnly\n- AppCreatedData\n- Access\n- Sharing\n\nBest practise is to assign the lowest access level possible to meet your requirements. If you wish to go against best practise and give your application unfettered access to your media collection then use Access and Sharing scopes combined.\n\nThe recommended method of setting these mandatory options is via the appsettings.json file;\n\n```json5\n// appsettings.json\n{\n    ...\n    \"CasCap\": {\n        \"GooglePhotosOptions\": {\n            // This is the email address of the Google Account.\n            \"User\": \"your.email@mydomain.com\",\n\n            // There are 5 security scopes, which can be combined.\n            \"Scopes\": [\n                \"ReadOnly\"\n                //\"AppendOnly\",\n                //\"AppCreatedData\",\n                //\"Access\",\n                //\"Sharing\"\n                ],\n\n            // The ClientId and ClientSecret are provided by the Google Console after you register your own application.\n            \"ClientId\": \"012345678901-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com\",\n\n            \"ClientSecret\": \"abcabcabcabcabcabcabcabc\",\n        }\n    }\n    ...\n}\n```\n\nAlternatively you can pass the options into the AddGooglePhotos method;\n\n```csharp\n//Startup.cs\nusing Microsoft.Extensions.DependencyInjection;\n\npublic class Startup\n{\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddGooglePhotos(options =\u003e\n        {\n            options.User = \"your.email@mydomain.com\";//replace with **your** info\n            options.ClientId = \"012345678901-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com\";//replace with **your** info\n            options.ClientSecret = \"abcabcabcabcabcabcabcabc\";//replace with **your** info\n            options.Scopes = new[] { GooglePhotosScope.ReadOnly };\n        });\n    }\n}\n```\n\nUsing appsettings.json is generally the best option however remember the Client ID \u0026 Client Secret should be stored securely outside of source control via [Azure KeyVault](https://azure.microsoft.com/en-us/services/key-vault/) (or [.NET Secret Manager](https://docs.microsoft.com/en-us/aspnet/core/security/app-secrets?view=aspnetcore-3.1\u0026tabs=windows#secret-manager) as shown below).\n\n```pwsh\ndotnet user-secrets init\ndotnet user-secrets set \"CasCap:GooglePhotosOptions:User\" \"your.email@mydomain.com\" #replace with **your** info\ndotnet user-secrets set \"CasCap:GooglePhotosOptions:ClientId\" \"012345678901-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com\" #replace with **your** info\ndotnet user-secrets set \"CasCap:GooglePhotosOptions:ClientSecret\" \"abcabcabcabcabcabcabcabc\" #replace with **your** info\n```\n\nAfter calling AddGooglePhotos in the ConfigureServices method of Startup.cs you can then call upon the GooglePhotosService within your own services shown below.\n\n```csharp\nusing Microsoft.Extensions.Logging;\nusing System;\nusing System.Threading.Tasks;\nnamespace CasCap.Services\n{\n    public class MyPhotoService\n    {\n        readonly ILogger _logger;\n        readonly GooglePhotosService _googlePhotosSvc;\n\n        public MyPhotoService(ILogger\u003cMyPhotoService\u003e logger, GooglePhotosService googlePhotosSvc)\n        {\n            _logger = logger;\n            _googlePhotosSvc = googlePhotosSvc;\n        }\n\n        public async Task Login_And_List_Albums()\n        {\n            if (!await _googlePhotosSvc.LoginAsync())\n                throw new Exception($\"login failed\");\n\n            var albums = await _googlePhotosSvc.GetAlbums();\n            foreach (var album in albums)\n            {\n                _logger.LogInfo($\"{album.id}\\t{album.title}\");\n            }\n        }\n    }\n}\n```\n\nIf you don't use dependency injection you can new-up the GooglePhotosService manually and pass the mandatory configuration options, logger and HttpClient via the service constructor;\n\n```csharp\n//MyPhotosClass.cs\nusing CasCap.Models;\nusing CasCap.Services;\nusing Microsoft.Extensions.Logging;\nusing Microsoft.Extensions.Options;\nusing System;\nusing System.Net;\nusing System.Net.Http;\nusing System.Threading.Tasks;\n\npublic class MyPhotosClass\n{\n    public async Task Login_And_List_Albums()\n    {\n        //new-up logging\n        var logger = new LoggerFactory().CreateLogger\u003cGooglePhotosService\u003e();\n\n        //new-up configuration options\n        var options = new GooglePhotosOptions\n        {\n            User = \"your.email@mydomain.com\",//replace with **your** info\n            ClientId = \"012345678901-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com\",//replace with **your** info\n            ClientSecret = \"abcabcabcabcabcabcabcabc\",//replace with **your** info\n            Scopes = new[] { GooglePhotosScope.ReadOnly },\n        };\n\n        //new-up a single HttpClient\n        var handler = new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate };\n        var client = new HttpClient(handler) { BaseAddress = new Uri(options.BaseAddress) };\n\n        //new-up the GooglePhotosService and pass in the logger, options and HttpClient\n        var googlePhotosSvc = new GooglePhotosService(logger, Options.Create(options), client);\n\n        //attempt to log-in\n        if (!await googlePhotosSvc.LoginAsync())\n            throw new Exception($\"login failed!\");\n\n        //get and list all albums\n        var albums = await googlePhotosSvc.GetAlbums();\n        foreach (var album in albums)\n        {\n            Console.WriteLine(album.title);\n        }\n    }\n}\n```\n\n## Misc\n\n### Changing Users/Scopes\n\nThe [Google.Apis.Auth](https://www.nuget.org/packages/Google.Apis.Auth/) library will cache the OAuth 2.0 login information in a local JSON file which it will then read tokens from (and renew if necessary) on subsequent logins. The JSON file(s) are stored on a per-User basis in the Environment.SpecialFolder.ApplicationData folder. On Windows 10 this folder is located at;\n\n- %UserProfile%\\AppData\\Roaming\\Google.Apis.Auth\n\nIf you change the authentication scopes for a User you must delete the JSON file and allow the [Google.Apis.Auth](https://www.nuget.org/packages/Google.Apis.Auth/) library to re-auth and re-create a new JSON file with the new scopes.\n\nYou can change the location where these JSON token files are stored at using the FileDataStoreFullPathOverride property in the configuration options;\n\n```csharp\n//Startup.cs\nusing Microsoft.Extensions.DependencyInjection;\n\npublic class Startup\n{\n    public void ConfigureServices(IServiceCollection services)\n    {\n        services.AddGooglePhotos(options =\u003e\n        {\n            options.User = \"your.email@mydomain.com\";\n            options.Scopes = new[] { GooglePhotosScope.ReadOnly };\n            options.ClientId = \"012345678901-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.apps.googleusercontent.com\";\n            options.ClientSecret = \"abcabcabcabcabcabcabcabc\";\n            //change FileDataStoreFullPathOverride\n            options.FileDataStoreFullPathOverride = \"c:/temp/GooglePhotos/\"\n        });\n    }\n}\n```\n\n### Sample Projects\n\nAll API functions are exposed by the GooglePhotosService class. There are several sample .NET Core applications which show the basics on how to set-up/config/use the library;\n\n- [Console App](https://github.com/f2calv/CasCap.Api.GooglePhotos/tree/master/samples/ConsoleApp) with no dependency injection.\n- [Console App](https://github.com/f2calv/CasCap.Api.GooglePhotos/tree/master/samples/GenericHost) using configuration, logging and dependency injection via the [.NET Generic Host](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/host/generic-host?view=aspnetcore-3.1).\n- [Integration Test App](https://github.com/f2calv/CasCap.Api.GooglePhotos/blob/master/src/CasCap.Api.GooglePhotos.Tests/Tests/Tests.cs) has the majority of the commented examples of various interactions.\n\n### Core Dependencies\n\n- [Google.Apis.Auth](https://www.nuget.org/packages/Google.Apis.Auth/) handles the [OAuth 2.0 authentication](https://developers.google.com/identity/protocols/oauth2), see the [project site](https://github.com/googleapis/google-api-dotnet-client).\n- [Polly](https://www.nuget.org/packages/Polly/) is a .NET resilience and transient-fault-handling library that handles retry, see [project site](https://github.com/App-vNext/Polly).\n- [CasCap.Common.Extensions](https://www.nuget.org/packages/CasCap.Common.Extensions/) and [CasCap.Common.Net](https://www.nuget.org/packages/CasCap.Common.Net/) contains a variety of extension methods and abstract classes to make my life easier :)\n\n### Misc Tips\n\n- The [NuGet package](https://www.nuget.org/packages/CasCap.Api.GooglePhotos/) includes [SourceLink](https://github.com/dotnet/sourcelink) which enables you to jump inside the library and debug the API yourself. By default Visual Studio 2017/2019 does not allow this and will pop up an message \"You are debugging a Release build of...\", to disable this message go into the Visual Studio debugging options and un-check the 'Just My Code' option (menu path, Tools \u003e Options \u003e Debugging).\n\n### Resources\n\n- \u003chttps://developers.google.com/photos\u003e\n- \u003chttps://console.developers.google.com\u003e\n- [Google Photos Library API](https://developers.google.com/photos)\n- [Google Photos Library API REST Reference](https://developers.google.com/photos/library/reference/rest)\n- [Google Photos Library API Authorisation Scopes](https://developers.google.com/photos/library/guides/authorization)\n\n### Feedback/Issues\n\nPlease post any issues or feedback [here](https://github.com/f2calv/CasCap.Api.GooglePhotos/issues).\n\n### License\n\nCasCap.Api.GooglePhotos is Copyright \u0026copy; 2020 [Alex Vincent](https://github.com/f2calv) under the [MIT license](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff2calv%2Fcascap.api.googlephotos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ff2calv%2Fcascap.api.googlephotos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff2calv%2Fcascap.api.googlephotos/lists"}