Skip to content

Commit d725736

Browse files
authored
Adding da-rapairs-oauth-python sample (#144)
* Adding da-rapairs-oauth-python sample * Create .gitignore * Fixing PR comments
1 parent 6ea9655 commit d725736

24 files changed

Lines changed: 995 additions & 0 deletions
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
.funcignore
2+
*.pyc
3+
__pycache__/
4+
.git*
5+
.localConfigs
6+
.vscode
7+
local.settings.json
8+
test
9+
.DS_Store
10+
.deployment
11+
.venv/
12+
.env/
13+
README.md
14+
m365agents.yml
15+
m365agents.*.yml
16+
/env/
17+
/appPackage/
18+
/infra/
19+
/devTools/
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# TeamsFx files
2+
env/.env.*.user
3+
env/.env.local
4+
.localConfigs
5+
appPackage/build
6+
7+
# dependencies
8+
node_modules/
9+
.venv/
10+
__pycache__/
11+
*.pyc
12+
13+
# misc
14+
.env
15+
.deployment
16+
.DS_Store
17+
18+
# Dev tool directories
19+
/devTools/
20+
21+
# Azure Functions artifacts
22+
bin
23+
obj
24+
local.settings.json
25+
build
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Declarative agent for Microsoft 365 Copilot with an API plugin connected to a Python API secured with OAuth
2+
3+
## Summary
4+
5+
This sample demonstrates how to build a declarative agent for Microsoft 365 Copilot that answers questions about repairs. The agent uses an API plugin to connect to a Python Azure Function API secured with OAuth. The project contains an Azure Function that serves as the API and uses the built-in Azure App Service authentication and authorization capabilities (also referred to as Easy Auth) to secure access to APIs.
6+
7+
![Declarative agent answering questions about repairs using the information from an API secured with OAuth](./assets/screenshot.png)
8+
9+
## Contributors
10+
11+
* [AjayJ12-MSFT](https://github.com/AjayJ12-MSFT)
12+
13+
## Version history
14+
15+
Version|Date|Comments
16+
-------|----|--------
17+
1.0|May 11, 2025|Initial release
18+
19+
## Prerequisites
20+
21+
* Microsoft 365 tenant with Microsoft 365 Copilot
22+
* [Visual Studio Code](https://code.visualstudio.com/) with the [Teams Toolkit](https://marketplace.visualstudio.com/items?itemName=TeamsDevApp.ms-teams-vscode-extension) extension
23+
* [Python](https://www.python.org/) 3.9 or later
24+
* [Azure Functions Core Tools](https://learn.microsoft.com/azure/azure-functions/functions-run-local#install-the-azure-functions-core-tools)
25+
26+
## Minimal path to awesome
27+
28+
* Clone this repository (or [download this solution as a .ZIP file](https://pnp.github.io/download-partial/?url=https://github.com/pnp/copilot-pro-dev-samples/tree/main/samples/da-repairs-oauth-python) then unzip it)
29+
* Open the Teams Toolkit extension and sign in to your Microsoft 365 tenant with Microsoft 365 Copilot
30+
* Select **Debug in Copilot (Edge)** from the launch configuration dropdown
31+
32+
## Features
33+
34+
This sample illustrates the following concepts:
35+
36+
* Building a declarative agent for Microsoft 365 Copilot with an API plugin
37+
* Connecting an API plugin to an API secured with OAuth
38+
* Using Azure Functions in Python to build an API secured with Azure App Service authentication and authorization (Easy Auth)
39+
* Using [dev tunnels](https://learn.microsoft.com/azure/developer/dev-tunnels/overview) to test the API plugin locally
40+
41+
## Help
42+
43+
We do not support samples, but this community is always willing to help, and we want to improve these samples. We use GitHub to track issues, which makes it easy for community members to volunteer their time and help resolve issues.
44+
45+
You can try looking at [issues related to this sample](https://github.com/pnp/copilot-pro-dev-samples/issues?q=label%3A%22sample%3A%20da-repairs-oauth-python%22) to see if anybody else is having the same issues.
46+
47+
If you encounter any issues using this sample, [create a new issue](https://github.com/pnp/copilot-pro-dev-samples/issues/new).
48+
49+
Finally, if you have an idea for improvement, [make a suggestion](https://github.com/pnp/copilot-pro-dev-samples/issues/new).
50+
51+
## Disclaimer
52+
53+
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
54+
55+
<img src="https://m365-visitor-stats.azurewebsites.net/copilot-pro-dev-samples/samples/da-repairs-oauth-python" />
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"id": "${{AAD_APP_OBJECT_ID}}",
3+
"appId": "${{AAD_APP_CLIENT_ID}}",
4+
"name": "da-repairs-oauth-python-aad",
5+
"accessTokenAcceptedVersion": 2,
6+
"signInAudience": "AzureADMyOrg",
7+
"optionalClaims": {
8+
"idToken": [],
9+
"accessToken": [
10+
{
11+
"name": "idtyp",
12+
"source": null,
13+
"essential": false,
14+
"additionalProperties": []
15+
}
16+
],
17+
"saml2Token": []
18+
},
19+
"oauth2Permissions": [
20+
{
21+
"adminConsentDescription": "Allows Copilot to read repair records on your behalf.",
22+
"adminConsentDisplayName": "Read repairs",
23+
"id": "${{AAD_APP_ACCESS_AS_USER_PERMISSION_ID}}",
24+
"isEnabled": true,
25+
"type": "User",
26+
"userConsentDescription": "Allows Copilot to read repair records.",
27+
"userConsentDisplayName": "Read repairs",
28+
"value": "repairs_read"
29+
}
30+
],
31+
"replyUrlsWithType": [
32+
{
33+
"url": "https://teams.microsoft.com/api/platform/v1.0/oAuthRedirect",
34+
"type": "Web"
35+
}
36+
],
37+
"identifierUris": [
38+
"api://${{AAD_APP_CLIENT_ID}}"
39+
]
40+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
{
2+
"$schema": "https://aka.ms/json-schemas/copilot/plugin/v2.1/schema.json",
3+
"schema_version": "v2.1",
4+
"namespace": "repairs",
5+
"name_for_human": "da-repairs-oauth${{APP_NAME_SUFFIX}}",
6+
"description_for_human": "Track your repair records",
7+
"description_for_model": "Plugin for searching a repair list, you can search by who's assigned to the repair.",
8+
"functions": [
9+
{
10+
"name": "listRepairs",
11+
"description": "Returns a list of repairs with their details and images",
12+
"capabilities": {
13+
"response_semantics": {
14+
"data_path": "$.results",
15+
"properties": {
16+
"title": "$.title",
17+
"subtitle": "$.description",
18+
"url": "$.image"
19+
},
20+
"static_template": {
21+
"type": "AdaptiveCard",
22+
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
23+
"version": "1.5",
24+
"body": [
25+
{
26+
"type": "Container",
27+
"$data": "${$root}",
28+
"items": [
29+
{
30+
"type": "TextBlock",
31+
"text": "id: ${if(id, id, 'N/A')}",
32+
"wrap": true
33+
},
34+
{
35+
"type": "TextBlock",
36+
"text": "title: ${if(title, title, 'N/A')}",
37+
"wrap": true
38+
},
39+
{
40+
"type": "TextBlock",
41+
"text": "description: ${if(description, description, 'N/A')}",
42+
"wrap": true
43+
},
44+
{
45+
"type": "TextBlock",
46+
"text": "assignedTo: ${if(assignedTo, assignedTo, 'N/A')}",
47+
"wrap": true
48+
},
49+
{
50+
"type": "TextBlock",
51+
"text": "date: ${if(date, date, 'N/A')}",
52+
"wrap": true
53+
},
54+
{
55+
"type": "Image",
56+
"url": "${image}",
57+
"$when": "${image != null}"
58+
}
59+
]
60+
}
61+
]
62+
}
63+
}
64+
}
65+
}
66+
],
67+
"runtimes": [
68+
{
69+
"type": "OpenApi",
70+
"auth": {
71+
"type": "OAuthPluginVault",
72+
"reference_id": "${{OAUTH2AUTHCODE_CONFIGURATION_ID}}"
73+
},
74+
"spec": {
75+
"url": "apiSpecificationFile/repair.yml",
76+
"progress_style": "ShowUsageWithInputAndOutput"
77+
},
78+
"run_for_functions": ["listRepairs"]
79+
}
80+
],
81+
"capabilities": {
82+
"localization": {},
83+
"conversation_starters": [
84+
{
85+
"text": "List all repairs"
86+
}
87+
]
88+
}
89+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
openapi: 3.0.0
2+
info:
3+
title: Repair Service
4+
description: A simple service to manage repairs
5+
version: 1.0.0
6+
servers:
7+
- url: ${{OPENAPI_SERVER_URL}}/api
8+
description: The repair api server
9+
components:
10+
securitySchemes:
11+
oAuth2AuthCode:
12+
type: oauth2
13+
description: OAuth configuration for the repair service
14+
flows:
15+
authorizationCode:
16+
authorizationUrl: https://login.microsoftonline.com/${{AAD_APP_TENANT_ID}}/oauth2/v2.0/authorize
17+
tokenUrl: https://login.microsoftonline.com/${{AAD_APP_TENANT_ID}}/oauth2/v2.0/token
18+
scopes:
19+
api://${{AAD_APP_CLIENT_ID}}/repairs_read: Read repair records
20+
paths:
21+
/repairs:
22+
get:
23+
operationId: listRepairs
24+
summary: List all repairs
25+
description: Returns a list of repairs with their details and images
26+
security:
27+
- oAuth2AuthCode:
28+
- api://${{AAD_APP_CLIENT_ID}}/repairs_read
29+
parameters:
30+
- name: assignedTo
31+
in: query
32+
description: Filter repairs by who they're assigned to
33+
schema:
34+
type: string
35+
required: false
36+
responses:
37+
'200':
38+
description: A list of repairs
39+
content:
40+
application/json:
41+
schema:
42+
type: object
43+
properties:
44+
results:
45+
type: array
46+
items:
47+
type: object
48+
properties:
49+
id:
50+
type: string
51+
description: The unique identifier of the repair
52+
title:
53+
type: string
54+
description: The short summary of the repair
55+
description:
56+
type: string
57+
description: The detailed description of the repair
58+
assignedTo:
59+
type: string
60+
description: The user who is responsible for the repair
61+
date:
62+
type: string
63+
format: date
64+
description: The date when the repair is scheduled or completed
65+
image:
66+
type: string
67+
format: uri
68+
description: The URL of the image of the item to be repaired or the repair process
5.78 KB
Loading
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"$schema": "https://developer.microsoft.com/json-schemas/copilot/declarative-agent/v1.6/schema.json",
3+
"version": "v1.6",
4+
"name": "da-repairs-oauth-python${{APP_NAME_SUFFIX}}",
5+
"description": "Declarative agent created with Microsoft 365 Agents Toolkit",
6+
"instructions": "$[file('instruction.txt')]"
7+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
You will help the user find car repair records assigned to a specific person, the name of the person should be provided by the user. The user will provide the name of the person and you will need to understand the user's intent and provide the car repair records assigned to that person. You can only access and leverage the data from the 'repairPlugin' action.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"$schema": "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.schema.json",
3+
"manifestVersion": "devPreview",
4+
"id": "${{TEAMS_APP_ID}}",
5+
"version": "1.0.0",
6+
"developer": {
7+
"name": "Teams App, Inc.",
8+
"websiteUrl": "https://www.example.com",
9+
"privacyUrl": "https://www.example.com/privacy",
10+
"termsOfUseUrl": "https://www.example.com/termsofuse"
11+
},
12+
"icons": {
13+
"color": "color.png",
14+
"outline": "outline.png"
15+
},
16+
"name": {
17+
"short": "da-repairs-oauth${{APP_NAME_SUFFIX}}",
18+
"full": "Full name for da-repairs-oauth"
19+
},
20+
"description": {
21+
"short": "Track and monitor car repair records for stress-free maintenance management.",
22+
"full": "The ultimate solution for hassle-free car maintenance management makes tracking and monitoring your car repair records a breeze."
23+
},
24+
"accentColor": "#FFFFFF",
25+
"copilotAgents": {
26+
"declarativeAgents": [
27+
{
28+
"id": "repairDeclarativeAgent",
29+
"file": "repairDeclarativeAgent.json"
30+
}
31+
]
32+
},
33+
"permissions": [
34+
"identity",
35+
"messageTeamMembers"
36+
]
37+
}

0 commit comments

Comments
 (0)