django-msgraphbackend


Namedjango-msgraphbackend JSON
Version 1.0.0 PyPI version JSON
download
home_pageNone
SummaryA Microsoft Graph Email Backend for Django.
upload_time2024-05-07 19:51:16
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseMIT License Copyright (c) 2024 Daniel Niccoli Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords django backend emailbackend microsoft graph
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [![Python Build](https://github.com/danielniccoli/django-msgraphbackend/actions/workflows/python-publish.yml/badge.svg)](https://github.com/danielniccoli/django-msgraphbackend/actions/workflows/python-publish.yml)

# Microsoft Graph Backend for Django

An dependency-free email backend for Django that sends emails via Microsoft Graph.

The package is a drop-in replacement for any `BaseEmailBackend` such as the default SMTP email backend `django.core.mail.backends.smtp.EmailBackend`.


## Installation

### Django

To include the *Microsoft Graph Backend for Django* in your project, add `"msgraphbackend" ` to `INSTALLED_APPS` in your `settings.py`. Then set `EMAIL_BACKEND` to `"msgraphbackend.MSGraphBackend"`. The example below shows all required changes to your `settings.py`.

```python
INSTALLED_APPS = [
    "...",
    "msgraphbackend",
]

EMAIL_BACKEND = "msgraphbackend.MSGraphBackend"

MSGRAPH_TENANT_ID = "..."
MSGRAPH_CLIENT_ID = "..."
MSGRAPH_CLIENT_SECRET = "..."
MSGRAPH_USER_ID = "..."  # Optional
```

The `MSGRAPH_USER_ID` is optional and not needed if you follow the instructions in section [Microsoft Entra](#microsoft-entra)


### Microsoft Entra

> [!IMPORTANT]
> This step describes the most permissive setup. For a more restrictive setup, see section [Modes of Operation](#modes-of-operation).

To enable the backend to connect to the Microsoft Graph API, you first need to register a Microsoft Entra App, or use an existing one. The registered app should be granted the *application permissions* `User.Read.All` and `Mail.Send` and then admin consent must be given. Finally, an app secret needs to be created. This can all be done via the Microsoft Entra Portal. For your convenience, the PowerShell script below streamlines this task.


```PowerShell
Connect-MgGraph -Scopes Application.ReadWrite.All,AppRoleAssignment.ReadWrite.All -UseDeviceAuthentication

# Get Microsoft Graph properties
$mgEnterpriseApp = Get-MgServicePrincipal -Filter "AppId eq '00000003-0000-0000-c000-000000000000'"
$mgUserReadAll = $mgEnterpriseApp.AppRoles | ? Value -eq "User.Read.All"
$mgMailSend = $mgEnterpriseApp.AppRoles | ? Value -eq "Mail.Send"

# Register a Microsoft Entra Application
$params = @{
    DisplayName            = "Microsoft Graph Backend for Django"
    Description            = "Client Application for Microsoft Graph Backend for Django."
    RequiredResourceAccess = @{
        ResourceAppId  = $mgEnterpriseApp.AppId # Microsoft Graph
        ResourceAccess = @(
            @{ Id = $mgUserReadAll.Id; Type = "Role" }
            @{ Id = $mgMailSend.Id; Type = "Role" }
        ) 
    }
    Tags = "HideApp"
}
$registeredApp = New-MgApplication @params

# Create a Microsoft Entra Enterprise App in your tenant
$enterpriseApp = New-MgServicePrincipal -AppId $registeredApp.AppId -AppRoleAssignmentRequired

# Grant Admin Consent for User.Read.All and Mail.Send
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $enterpriseApp.Id -PrincipalId $enterpriseApp.Id -AppRoleId $mgUserReadAll.Id -ResourceId $mgEnterpriseApp.Id | Out-Null
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $enterpriseApp.Id -PrincipalId $enterpriseApp.Id -AppRoleId $mgMailSend.Id -ResourceId $mgEnterpriseApp.Id | Out-Null

# Create a Client Secret
$params = @{
    ApplicationId      = $registeredApp.Id
    PasswordCredential = @{
        displayName = "Django"
        endDateTime = (Get-Date).AddMonths(6)
    }
}
$secret = Add-MgApplicationPassword @params

# Output a summary
Write-Host "
Your Tenant ID:     $($enterpriseApp.AppOwnerOrganizationId)
Your Client ID:     $($enterpriseApp.AppId)
Your Client Secret: $($secret.SecretText)"

```

For detailed information, refer to the article [Register an application with the Microsoft identity platform](https://learn.microsoft.com/en-us/graph/auth-register-app-v2).


## Settings
The *Microsoft Graph Backend for Django* requires the following settings:

| Setting               | Required | Description |
|-----------------------|----------|-------------|
| MSGRAPH_TENANT_ID     | Yes      | Your [Microsoft Entra tenant ID](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-find-tenant). |
| MSGRAPH_CLIENT_ID     | Yes      | The [application (client) ID](https://learn.microsoft.com/en-us/graph/auth-register-app-v2) of your Microsoft Entra app. |
| MSGRAPH_CLIENT_SECRET | Yes      | The secret to your Microsoft Entra application. |
| MSGRAPH_USER_ID       | No       | If you grant your application the `User.Read.All` application permission, this setting is not required. |



## Modes of Operation

> [!IMPORTANT]
> The Microsoft Graph API requires that all emails are sent from a particular mailbox. The sender's *from address* must match one of the email addresses assigned to that mailbox.

There are several modes of operation that you can choose from for how the *Microsoft Graph Backend for Django* sends emails. Some modes prioritize security, while others prioritize simplicity. 


### Most Permissive

This is the mode your configured if you followed section [Microsoft Entra](#microsoft-entra). 

In this mode, the *Microsoft Graph Backend for Django* is permitted to use any mailbox and *from address* available in your Microsoft 365 tenant, limited by the configuration of your Django project. For example by setting `DEFAULT_FROM_EMAIL` or `SERVER_EMAIL`.

When an email needs to be sent, the backend requests from the Graph API the user (read: mailbox) that has the email address assigned to it, that Django wants to use as the *from address*. This request requires the *application permission* `User.Read.All`. When a user is found, the mail is sent through his mailbox to the recipient. This request requires the *application permission* `Mail.Send`.

In this mode, setting `MSGRAPH_USER_ID` is not needed.

> [!WARNING]
> *Application permissions* are very permissive. A Microsoft Entra application with the `User.Read.All` permission is allowed to retrieve the complete user profile of any non-privileged user account in your Microsoft Entra ID tenant. A Microsoft Entra application with the `Mail.Send` permission is allowed to send emails from any mailbox and existing email address in your Microsoft 365 environment.


### More Restrictive

In this mode, the *Microsoft Graph Backend for Django* is restricted to sending only from selected mailboxes in your Microsoft 365 environment. This is achieved by implementing [RBAC for Apps in Exchange Online](https://learn.microsoft.com/en-us/exchange/permissions-exo/application-rbac) and limiting the users (read: mailboxes) from which the Microsoft Entra Enterprise Application is allowed to send emails. This mode requires the *application permission* `User.Read.All` and setting `MSGRAPH_USER_ID` is not needed.

> [!WARNING]
> In this mode, do not grant your Microsoft Entra registered app the `Mail.Send` permission! If you already granted the permission, you should revoke it.

After ensuring that the `Mail.Send` is revoked, you need to create the Administrative Unit.

```PowerShell
$params = @{
    displayName = "Microsoft Graph Backend for Django allowed senders"
    description = "Manages senders that Microsoft Graph Backend for Django is allowed to impersonate (read: send from)."
}
$adminUnit = New-MgDirectoryAdministrativeUnit -BodyParameter $params
```

Assign any users (read: mailboxes) to this *administrative unit* that you want to send emails from using the *Microsoft Graph Backend for Django*.

Then connect to Exchange Online and create a new service principal and link it to your *Microsoft Entra Enterprise App* via client ID and object ID. The variables refer to the script in section [Microsoft Entra](#microsoft-entra).

```PowerShell
Connect-ExchangeOnline -Device
$sp = New-ServicePrincipal -DisplayName "Microsoft Graph Backend for Django" -AppId $enterpriseApp.AppId -ObjectId $enterpriseApp.Id
New-ManagementRoleAssignment -App $sp.ObjectId -Role "Application Mail.Send" -RecipientAdministrativeUnitScope $adminUnit.Id
```

At this point your Microsoft Entra Enterprise Application should have the permission to send as any user (read: mailbox) in your *administrative unit*.

```PowerShell
Test-ServicePrincipalAuthorization -Identity $enterpriseApp.Id -Resource "<user-id>"
```


### Most Restrictive

This mode is similar to the [more restrictive](#more-restrictive) mode, but it is limited to a single mailbox. Any *from address* that you wish to use needs to be assigned to the selected mailbox.

> [!IMPORTANT]
> This mode does not require any *application permission*. If you already granted `User.Read.All` or `Mail.Send`, you should revoke them.
> Ensure that your *administrative unit* is limited to a single mailbox. That mailbox can have multiple email addresses.

This mode requires setting `MSGRAPH_USER_ID` to the user id of your selected mailbox.


## Notes

The *Microsoft Graph Backend for Django* sends email not in the Microsoft Graph-typical JSON, but in the MIME format. This is due to how `django.core.mail.message.EmailMessage` internally works. Its `message()` method returns the email in MIME format. Rather than writing a custom converter from MIME to JSON, that could introduce additional bugs, the format is left unchanged. The Microsoft's own [Graph SDK for Python](https://github.com/microsoftgraph/msgraph-sdk-python) does not support sending emails in MIME format.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "django-msgraphbackend",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "Django, Backend, EmailBackend, Microsoft Graph",
    "author": null,
    "author_email": "Daniel Niccoli <daniel.niccoli@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/88/ab/a84be65c2cec773c31435f9e67ce7302c912bba2cf0d13ad287ca501a538/django_msgraphbackend-1.0.0.tar.gz",
    "platform": null,
    "description": "[![Python Build](https://github.com/danielniccoli/django-msgraphbackend/actions/workflows/python-publish.yml/badge.svg)](https://github.com/danielniccoli/django-msgraphbackend/actions/workflows/python-publish.yml)\n\n# Microsoft Graph Backend for Django\n\nAn dependency-free email backend for Django that sends emails via Microsoft Graph.\n\nThe package is a drop-in replacement for any `BaseEmailBackend` such as the default SMTP email backend `django.core.mail.backends.smtp.EmailBackend`.\n\n\n## Installation\n\n### Django\n\nTo include the *Microsoft Graph Backend for Django* in your project, add `\"msgraphbackend\" ` to `INSTALLED_APPS` in your `settings.py`. Then set `EMAIL_BACKEND` to `\"msgraphbackend.MSGraphBackend\"`. The example below shows all required changes to your `settings.py`.\n\n```python\nINSTALLED_APPS = [\n    \"...\",\n    \"msgraphbackend\",\n]\n\nEMAIL_BACKEND = \"msgraphbackend.MSGraphBackend\"\n\nMSGRAPH_TENANT_ID = \"...\"\nMSGRAPH_CLIENT_ID = \"...\"\nMSGRAPH_CLIENT_SECRET = \"...\"\nMSGRAPH_USER_ID = \"...\"  # Optional\n```\n\nThe `MSGRAPH_USER_ID` is optional and not needed if you follow the instructions in section [Microsoft Entra](#microsoft-entra)\n\n\n### Microsoft Entra\n\n> [!IMPORTANT]\n> This step describes the most permissive setup. For a more restrictive setup, see section [Modes of Operation](#modes-of-operation).\n\nTo enable the backend to connect to the Microsoft Graph API, you first need to register a Microsoft Entra App, or use an existing one. The registered app should be granted the *application permissions* `User.Read.All` and `Mail.Send` and then admin consent must be given. Finally, an app secret needs to be created. This can all be done via the Microsoft Entra Portal. For your convenience, the PowerShell script below streamlines this task.\n\n\n```PowerShell\nConnect-MgGraph -Scopes Application.ReadWrite.All,AppRoleAssignment.ReadWrite.All -UseDeviceAuthentication\n\n# Get Microsoft Graph properties\n$mgEnterpriseApp = Get-MgServicePrincipal -Filter \"AppId eq '00000003-0000-0000-c000-000000000000'\"\n$mgUserReadAll = $mgEnterpriseApp.AppRoles | ? Value -eq \"User.Read.All\"\n$mgMailSend = $mgEnterpriseApp.AppRoles | ? Value -eq \"Mail.Send\"\n\n# Register a Microsoft Entra Application\n$params = @{\n    DisplayName            = \"Microsoft Graph Backend for Django\"\n    Description            = \"Client Application for Microsoft Graph Backend for Django.\"\n    RequiredResourceAccess = @{\n        ResourceAppId  = $mgEnterpriseApp.AppId # Microsoft Graph\n        ResourceAccess = @(\n            @{ Id = $mgUserReadAll.Id; Type = \"Role\" }\n            @{ Id = $mgMailSend.Id; Type = \"Role\" }\n        ) \n    }\n    Tags = \"HideApp\"\n}\n$registeredApp = New-MgApplication @params\n\n# Create a Microsoft Entra Enterprise App in your tenant\n$enterpriseApp = New-MgServicePrincipal -AppId $registeredApp.AppId -AppRoleAssignmentRequired\n\n# Grant Admin Consent for User.Read.All and Mail.Send\nNew-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $enterpriseApp.Id -PrincipalId $enterpriseApp.Id -AppRoleId $mgUserReadAll.Id -ResourceId $mgEnterpriseApp.Id | Out-Null\nNew-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $enterpriseApp.Id -PrincipalId $enterpriseApp.Id -AppRoleId $mgMailSend.Id -ResourceId $mgEnterpriseApp.Id | Out-Null\n\n# Create a Client Secret\n$params = @{\n    ApplicationId      = $registeredApp.Id\n    PasswordCredential = @{\n        displayName = \"Django\"\n        endDateTime = (Get-Date).AddMonths(6)\n    }\n}\n$secret = Add-MgApplicationPassword @params\n\n# Output a summary\nWrite-Host \"\nYour Tenant ID:     $($enterpriseApp.AppOwnerOrganizationId)\nYour Client ID:     $($enterpriseApp.AppId)\nYour Client Secret: $($secret.SecretText)\"\n\n```\n\nFor detailed information, refer to the article [Register an application with the Microsoft identity platform](https://learn.microsoft.com/en-us/graph/auth-register-app-v2).\n\n\n## Settings\nThe *Microsoft Graph Backend for Django* requires the following settings:\n\n| Setting               | Required | Description |\n|-----------------------|----------|-------------|\n| MSGRAPH_TENANT_ID     | Yes      | Your [Microsoft Entra tenant ID](https://learn.microsoft.com/en-us/entra/fundamentals/how-to-find-tenant). |\n| MSGRAPH_CLIENT_ID     | Yes      | The [application (client) ID](https://learn.microsoft.com/en-us/graph/auth-register-app-v2) of your Microsoft Entra app. |\n| MSGRAPH_CLIENT_SECRET | Yes      | The secret to your Microsoft Entra application. |\n| MSGRAPH_USER_ID       | No       | If you grant your application the `User.Read.All` application permission, this setting is not required. |\n\n\n\n## Modes of Operation\n\n> [!IMPORTANT]\n> The Microsoft Graph API requires that all emails are sent from a particular mailbox. The sender's *from address* must match one of the email addresses assigned to that mailbox.\n\nThere are several modes of operation that you can choose from for how the *Microsoft Graph Backend for Django* sends emails. Some modes prioritize security, while others prioritize simplicity. \n\n\n### Most Permissive\n\nThis is the mode your configured if you followed section [Microsoft Entra](#microsoft-entra). \n\nIn this mode, the *Microsoft Graph Backend for Django* is permitted to use any mailbox and *from address* available in your Microsoft 365 tenant, limited by the configuration of your Django project. For example by setting `DEFAULT_FROM_EMAIL` or `SERVER_EMAIL`.\n\nWhen an email needs to be sent, the backend requests from the Graph API the user (read: mailbox) that has the email address assigned to it, that Django wants to use as the *from address*. This request requires the *application permission* `User.Read.All`. When a user is found, the mail is sent through his mailbox to the recipient. This request requires the *application permission* `Mail.Send`.\n\nIn this mode, setting `MSGRAPH_USER_ID` is not needed.\n\n> [!WARNING]\n> *Application permissions* are very permissive. A Microsoft Entra application with the `User.Read.All` permission is allowed to retrieve the complete user profile of any non-privileged user account in your Microsoft Entra ID tenant. A Microsoft Entra application with the `Mail.Send` permission is allowed to send emails from any mailbox and existing email address in your Microsoft 365 environment.\n\n\n### More Restrictive\n\nIn this mode, the *Microsoft Graph Backend for Django* is restricted to sending only from selected mailboxes in your Microsoft 365 environment. This is achieved by implementing [RBAC for Apps in Exchange Online](https://learn.microsoft.com/en-us/exchange/permissions-exo/application-rbac) and limiting the users (read: mailboxes) from which the Microsoft Entra Enterprise Application is allowed to send emails. This mode requires the *application permission* `User.Read.All` and setting `MSGRAPH_USER_ID` is not needed.\n\n> [!WARNING]\n> In this mode, do not grant your Microsoft Entra registered app the `Mail.Send` permission! If you already granted the permission, you should revoke it.\n\nAfter ensuring that the `Mail.Send` is revoked, you need to create the Administrative Unit.\n\n```PowerShell\n$params = @{\n    displayName = \"Microsoft Graph Backend for Django allowed senders\"\n    description = \"Manages senders that Microsoft Graph Backend for Django is allowed to impersonate (read: send from).\"\n}\n$adminUnit = New-MgDirectoryAdministrativeUnit -BodyParameter $params\n```\n\nAssign any users (read: mailboxes) to this *administrative unit* that you want to send emails from using the *Microsoft Graph Backend for Django*.\n\nThen connect to Exchange Online and create a new service principal and link it to your *Microsoft Entra Enterprise App* via client ID and object ID. The variables refer to the script in section [Microsoft Entra](#microsoft-entra).\n\n```PowerShell\nConnect-ExchangeOnline -Device\n$sp = New-ServicePrincipal -DisplayName \"Microsoft Graph Backend for Django\" -AppId $enterpriseApp.AppId -ObjectId $enterpriseApp.Id\nNew-ManagementRoleAssignment -App $sp.ObjectId -Role \"Application Mail.Send\" -RecipientAdministrativeUnitScope $adminUnit.Id\n```\n\nAt this point your Microsoft Entra Enterprise Application should have the permission to send as any user (read: mailbox) in your *administrative unit*.\n\n```PowerShell\nTest-ServicePrincipalAuthorization -Identity $enterpriseApp.Id -Resource \"<user-id>\"\n```\n\n\n### Most Restrictive\n\nThis mode is similar to the [more restrictive](#more-restrictive) mode, but it is limited to a single mailbox. Any *from address* that you wish to use needs to be assigned to the selected mailbox.\n\n> [!IMPORTANT]\n> This mode does not require any *application permission*. If you already granted `User.Read.All` or `Mail.Send`, you should revoke them.\n> Ensure that your *administrative unit* is limited to a single mailbox. That mailbox can have multiple email addresses.\n\nThis mode requires setting `MSGRAPH_USER_ID` to the user id of your selected mailbox.\n\n\n## Notes\n\nThe *Microsoft Graph Backend for Django* sends email not in the Microsoft Graph-typical JSON, but in the MIME format. This is due to how `django.core.mail.message.EmailMessage` internally works. Its `message()` method returns the email in MIME format. Rather than writing a custom converter from MIME to JSON, that could introduce additional bugs, the format is left unchanged. The Microsoft's own [Graph SDK for Python](https://github.com/microsoftgraph/msgraph-sdk-python) does not support sending emails in MIME format.\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2024 Daniel Niccoli  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
    "summary": "A Microsoft Graph Email Backend for Django.",
    "version": "1.0.0",
    "project_urls": {
        "Homepage": "https://github.com/danielniccoli/django-msgraphbackend",
        "Issues": "https://github.com/danielniccoli/django-msgraphbackend/issues",
        "Repository": "https://github.com/danielniccoli/django-msgraphbackend.git"
    },
    "split_keywords": [
        "django",
        " backend",
        " emailbackend",
        " microsoft graph"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fc18167065dc9cba523887ce0a21cb2a74d3dcd4fef6e7d8e0e8d0a4dda77536",
                "md5": "04be3da1e500c604d6076854da8366b9",
                "sha256": "5c43ddad9d60fd6804bf7bbd2330154be2965ea9c2444763764283d1a9713bc2"
            },
            "downloads": -1,
            "filename": "django_msgraphbackend-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "04be3da1e500c604d6076854da8366b9",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 7741,
            "upload_time": "2024-05-07T19:51:15",
            "upload_time_iso_8601": "2024-05-07T19:51:15.849929Z",
            "url": "https://files.pythonhosted.org/packages/fc/18/167065dc9cba523887ce0a21cb2a74d3dcd4fef6e7d8e0e8d0a4dda77536/django_msgraphbackend-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "88aba84be65c2cec773c31435f9e67ce7302c912bba2cf0d13ad287ca501a538",
                "md5": "4e4ae445808dddc9cd32c338de18d6d4",
                "sha256": "3d50a786745941f3db01baf68abbb48e2ace0f0878f02b9569d7edce7550428d"
            },
            "downloads": -1,
            "filename": "django_msgraphbackend-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "4e4ae445808dddc9cd32c338de18d6d4",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 7022,
            "upload_time": "2024-05-07T19:51:16",
            "upload_time_iso_8601": "2024-05-07T19:51:16.949831Z",
            "url": "https://files.pythonhosted.org/packages/88/ab/a84be65c2cec773c31435f9e67ce7302c912bba2cf0d13ad287ca501a538/django_msgraphbackend-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-05-07 19:51:16",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "danielniccoli",
    "github_project": "django-msgraphbackend",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "django-msgraphbackend"
}
        
Elapsed time: 0.24218s