Skip to content

Commit f67e715

Browse files
committed
clean up samples, code
1 parent d5939b6 commit f67e715

24 files changed

Lines changed: 2301 additions & 2224 deletions

‎samples/sample_connector_usage/sample_connector_usage_kusto.py‎

Lines changed: 361 additions & 356 deletions
Large diffs are not rendered by default.

‎samples/sample_connector_usage/sample_connector_usage_office365.py‎

Lines changed: 176 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -1,191 +1,190 @@
11
# Copyright (c) Microsoft Corporation. All rights reserved.
22

33
"""
4-
Sample program demonstrating how to use the Connector SDK with generated connector clients.
4+
Office365 Connector SDK Sample
55
6-
This sample shows the usage pattern. For actual usage, you need to:
7-
1. Generate connector code using LogicAppsCompiler CLI (see GENERATION.md)
8-
2. Install the SDK: pip install <TBD>
9-
3. Use the generated typed client classes
6+
This sample demonstrates how to use the Office365 connector SDK.
7+
8+
Prerequisites:
9+
1. Azure subscription with Office365 connection
10+
2. Office365 connection in Azure Logic Apps
11+
3. Connection runtime URL from Azure Portal
12+
13+
Installation:
14+
pip install <TBD>
15+
16+
Usage:
17+
Set environment variable:
18+
$env:OFFICE365_CONNECTION_URL = "https://[region].azure-apihub.net/apim/office365/[connection-id]"
19+
20+
python sample_connector_usage_office365.py
1021
"""
1122

1223
import asyncio
1324
import os
14-
from typing import Optional
25+
from azure.identity.aio import DefaultAzureCredential
26+
from azure.connectors import ConnectorException
27+
from azure.connectors.office365 import (
28+
Office365Client,
29+
ClientSendHtmlMessage,
30+
)
31+
32+
# Connection runtime URL format:
33+
# https://[region].azure-apihub.net/apim/office365/[connection-id]
34+
CONNECTION_RUNTIME_URL = os.environ.get(
35+
"OFFICE365_CONNECTION_URL",
36+
""
37+
)
38+
39+
40+
async def example_1_get_outlook_categories():
41+
"""Example 1: Get Outlook category names."""
42+
print("\n=== Example 1: Get Outlook Category Names ===")
43+
44+
credential = DefaultAzureCredential()
45+
46+
async with Office365Client(CONNECTION_RUNTIME_URL, credential) as client:
47+
try:
48+
categories = await client.get_outlook_category_names_async()
49+
50+
if categories and 'value' in categories:
51+
print(f"Found {len(categories['value'])} Outlook categories:")
52+
for category in categories['value'][:5]:
53+
display_name = category.get('DisplayName', 'Unknown')
54+
color = category.get('Color', 'N/A')
55+
print(f" - {display_name} (Color: {color})")
56+
else:
57+
print("No categories found or unexpected response format.")
58+
59+
except ConnectorException as ex:
60+
print(f"Connector error: {ex}")
61+
except Exception as ex:
62+
print(f"Error: {ex}")
63+
64+
65+
async def example_2_send_email():
66+
"""Example 2: Send an HTML email."""
67+
print("\n=== Example 2: Send Email ===")
68+
69+
to_address = os.environ.get("TEST_EMAIL_TO", "victoriahall@microsoft.com")
70+
71+
credential = DefaultAzureCredential()
72+
73+
async with Office365Client(CONNECTION_RUNTIME_URL, credential) as client:
74+
try:
75+
email = ClientSendHtmlMessage(
76+
to=to_address,
77+
subject="Test Email from Office365 Connector SDK",
78+
body="<p>This is a test email sent from the <strong>Python Office365 Connector SDK</strong>.</p>",
79+
)
80+
81+
await client.send_email_async(email)
82+
print(f"Email sent successfully to {to_address}")
83+
print("Note: Set TEST_EMAIL_TO environment variable to send to a real address")
84+
85+
except ConnectorException as ex:
86+
print(f"Connector error: {ex}")
87+
except Exception as ex:
88+
print(f"Error: {ex}")
89+
90+
91+
async def example_3_get_emails():
92+
"""Example 3: Get emails from inbox."""
93+
print("\n=== Example 3: Get Emails from Inbox ===")
94+
95+
credential = DefaultAzureCredential()
96+
97+
async with Office365Client(CONNECTION_RUNTIME_URL, credential) as client:
98+
try:
99+
emails = await client.get_emails_async()
100+
101+
if emails and 'value' in emails:
102+
print(f"Found {len(emails['value'])} emails:")
103+
for email in emails['value']:
104+
subject = email.get('Subject', 'No Subject')
105+
from_addr = email.get('From', 'Unknown')
106+
received = email.get('DateTimeReceived', 'Unknown')
107+
print(f" - {subject}")
108+
print(f" From: {from_addr}")
109+
print(f" Received: {received}")
110+
else:
111+
print("No emails found or unexpected response format.")
112+
113+
except ConnectorException as ex:
114+
print(f"Connector error: {ex}")
115+
except Exception as ex:
116+
print(f"Error: {ex}")
117+
118+
119+
async def example_4_draft_and_send_email():
120+
"""Example 4: Draft an email and then send it."""
121+
print("\n=== Example 4: Draft and Send Email ===")
122+
123+
to_address = os.environ.get("TEST_EMAIL_TO", "victoriahall@microsoft.com")
124+
125+
credential = DefaultAzureCredential()
126+
127+
async with Office365Client(CONNECTION_RUNTIME_URL, credential) as client:
128+
try:
129+
draft = ClientSendHtmlMessage(
130+
to=to_address,
131+
subject="Draft Email from SDK",
132+
body="<p>This email was created as a draft first.</p>",
133+
)
134+
135+
draft_response = await client.draft_email_async(draft)
136+
print(f"Draft created successfully")
137+
138+
if draft_response and 'Id' in draft_response:
139+
message_id = draft_response['Id']
140+
print(f"Draft message ID: {message_id}")
141+
142+
await client.send_draft_email_async(message_id=message_id)
143+
print(f"Draft email sent successfully to {to_address}")
144+
else:
145+
print("Draft created but no ID returned.")
146+
147+
except ConnectorException as ex:
148+
print(f"Connector error: {ex}")
149+
except Exception as ex:
150+
print(f"Error: {ex}")
151+
152+
153+
async def example_5_error_handling():
154+
"""Example 5: Demonstrate error handling."""
155+
print("\n=== Example 5: Error Handling ===")
156+
157+
credential = DefaultAzureCredential()
158+
159+
async with Office365Client(CONNECTION_RUNTIME_URL, credential) as client:
160+
try:
161+
# Attempt to get an email with an invalid ID
162+
invalid_message_id = "invalid-message-id-12345"
163+
email = await client.get_email_async(message_id=invalid_message_id)
164+
print(f"Unexpected success: {email}")
165+
166+
except ConnectorException as ex:
167+
print(f"Expected error caught:")
168+
print(f" Message: {ex}")
169+
except Exception as ex:
170+
print(f"Unexpected error type: {type(ex).__name__}")
171+
print(f" Message: {ex}")
15172

16173

17174
async def main():
18-
"""Entry point for the sample application."""
19-
print("Azure Logic Apps Connector SDK - Sample Usage (Python)")
20-
print("======================================================")
21-
print()
22-
23-
# Example 1: SDK Runtime Components
24-
print("Example 1: SDK Runtime Components")
25-
print("----------------------------------")
26-
print("The SDK provides runtime infrastructure for generated connector clients:")
27-
print()
28-
print(" Authentication:")
29-
print(" - ManagedIdentityTokenProvider: For Azure-hosted apps")
30-
print(" - ConnectionStringTokenProvider: For local development")
31-
print()
32-
print(" HTTP:")
33-
print(" - ConnectorHttpClient: Async HTTP client with aiohttp")
34-
print(" - Automatic retry and error handling")
35-
print()
36-
print(" Base Classes:")
37-
print(" - ConnectorClientBase: Base class for all generated clients")
38-
print(" - ConnectorClientOptions: Configuration options")
39-
print()
40-
41-
# Example 2: Token Provider Usage
42-
print("Example 2: Token Provider Usage")
43-
print("-------------------------------")
44-
45-
try:
46-
# Import the SDK (demonstrates that it's installed)
47-
from azure_workflows_connectors_sdk import (
48-
ManagedIdentityTokenProvider,
49-
ConnectionStringTokenProvider,
50-
)
51-
52-
# Managed Identity for Azure-hosted scenarios
53-
print(" Managed Identity (for Azure-hosted apps):")
54-
print(" from azure_workflows_connectors_sdk import ManagedIdentityTokenProvider")
55-
print(" token_provider = ManagedIdentityTokenProvider()")
56-
print(" token = await token_provider.get_access_token_async(scopes)")
57-
print()
58-
59-
# Connection String for local development
60-
api_key = os.environ.get("CONNECTOR_API_KEY", "demo-key")
61-
connection_token_provider = ConnectionStringTokenProvider(api_key)
62-
print(" Connection String (for local development):")
63-
print(" token_provider = ConnectionStringTokenProvider(api_key)")
64-
print(f" Created with key: {api_key[:min(4, len(api_key))]}...")
65-
except ImportError:
66-
print(" Note: <TBD> not installed")
67-
print(" Run: pip install <TBD>")
68-
except Exception as ex:
69-
print(f" Error: {ex}")
70-
71-
print()
72-
73-
# Example 3: Generated Client Usage Pattern
74-
print("Example 3: Generated Client Usage Pattern")
75-
print("------------------------------------------")
76-
print("After generating connector code with LogicAppsCompiler CLI:")
77-
print()
78-
print(" # Using generated Office365Client (from office365_client.py)")
79-
print(" from azure_workflows_connectors_sdk.generated.office365_client import (")
80-
print(" Office365Client, ClientSendHtmlMessage")
81-
print(" )")
82-
print(" from azure_workflows_connectors_sdk import ManagedIdentityTokenProvider")
83-
print()
84-
print(" # Create the client with connection runtime URL")
85-
print(" connection_runtime_url = 'https://...' # From Azure Portal")
86-
print(" token_provider = ManagedIdentityTokenProvider()")
87-
print()
88-
print(" async with Office365Client(connection_runtime_url, token_provider) as client:")
89-
print(" # Call typed operations with request dataclasses")
90-
print(" email = ClientSendHtmlMessage(")
91-
print(" to='recipient@example.com',")
92-
print(" subject='Hello from SDK',")
93-
print(" body='<p>Email body</p>',")
94-
print(" )")
95-
print(" await client.send_email_v2_async(email)")
96-
print()
97-
print(" categories = await client.get_outlook_category_names_async()")
98-
print()
99-
100-
# Example 4: Generation Instructions
101-
print("Example 4: How to Generate Connector Code")
102-
print("------------------------------------------")
103-
print("Use the LogicAppsCompiler CLI from the BPM repository:")
104-
print()
105-
print(" # Build the generator")
106-
print(" dotnet build .\\src\\tools\\CodefulSdkGenerator\\LogicAppsCompiler.Cli -c Release")
107-
print()
108-
print(" # Generate Office365 connector (Python)")
109-
print(" cd src\\tools\\CodefulSdkGenerator\\LogicAppsCompiler.Cli\\bin\\Release")
110-
print(' .\\LogicAppsCompiler.exe "..\\..\\..\\..\\..\\..\\PythonSDK\\src\\azure_workflows_connectors_sdk\\generated" --pythonDirectClient --connectors=office365')
111-
print()
112-
print("See PythonSDK/GENERATION.md for complete documentation.")
113-
print()
114-
115-
# Example 5: Integration with Azure Functions
116-
print("Example 5: Azure Functions Integration (Python)")
117-
print("------------------------------------------------")
118-
print("The generated clients work well with Azure Functions:")
119-
print()
120-
print(" import azure.functions as func")
121-
print(" from azure_workflows_connectors_sdk.generated.office365_client import Office365Client")
122-
print(" from azure_workflows_connectors_sdk import ManagedIdentityTokenProvider")
123-
print()
124-
print(" app = func.FunctionApp()")
125-
print()
126-
print(" @app.route(route='send-email', auth_level=func.AuthLevel.FUNCTION)")
127-
print(" async def send_email(req: func.HttpRequest) -> func.HttpResponse:")
128-
print(" connection_url = os.environ['CONNECTION_RUNTIME_URL']")
129-
print(" token_provider = ManagedIdentityTokenProvider()")
130-
print()
131-
print(" async with Office365Client(connection_url, token_provider) as client:")
132-
print(" email = ClientSendHtmlMessage(")
133-
print(" to=req.params.get('to'),")
134-
print(" subject='Hello from Azure Function',")
135-
print(" body='<p>Sent from Python!</p>',")
136-
print(" )")
137-
print(" await client.send_email_v2_async(email)")
138-
print()
139-
print(" return func.HttpResponse('Email sent!', status_code=200)")
140-
print()
141-
142-
# Example 6: Async Context Manager Pattern
143-
print("Example 6: Async Context Manager Pattern")
144-
print("-----------------------------------------")
145-
print("All generated clients support async context managers:")
146-
print()
147-
print(" # Automatic cleanup with context manager")
148-
print(" async with Office365Client(url, token_provider) as client:")
149-
print(" email = ClientSendHtmlMessage(to='...', subject='...', body='...')")
150-
print(" await client.send_email_v2_async(email)")
151-
print(" # Client automatically closed after exiting context")
152-
print()
153-
print(" # Manual lifecycle management")
154-
print(" client = Office365Client(url, token_provider)")
155-
print(" try:")
156-
print(" email = ClientSendHtmlMessage(to='...', subject='...', body='...')")
157-
print(" await client.send_email_v2_async(email)")
158-
print(" finally:")
159-
print(" await client.close()")
160-
print()
161-
162-
# Example 7: Error Handling
163-
print("Example 7: Error Handling")
164-
print("-------------------------")
165-
print("The SDK provides structured error handling:")
166-
print()
167-
print(" from azure_workflows_connectors_sdk import ConnectorException")
168-
print(" from azure_workflows_connectors_sdk.generated.office365_client import (")
169-
print(" Office365Client, ClientSendHtmlMessage")
170-
print(" )")
171-
print()
172-
print(" try:")
173-
print(" async with Office365Client(url, token_provider) as client:")
174-
print(" email = ClientSendHtmlMessage(to='...', subject='...', body='...')")
175-
print(" await client.send_email_v2_async(email)")
176-
print(" except ConnectorException as ex:")
177-
print(" print(f'Connector error: {ex.message}')")
178-
print(" print(f'Status code: {ex.status_code}')")
179-
print(" print(f'Error body: {ex.error_body}')")
180-
print()
181-
182-
print("Sample completed successfully!")
183-
print()
184-
print("Next steps:")
185-
print(" 1. Run LogicAppsCompiler CLI to generate connector code")
186-
print(" 2. Install the SDK: pip install <TBD>")
187-
print(" 3. Use typed clients with the connection runtime URL from Azure Portal")
188-
print(" 4. Deploy to Azure Functions or run locally")
175+
"""Run all examples."""
176+
print("Office365 Connector SDK - Sample Usage")
177+
print("=" * 50)
178+
print()
179+
180+
await example_1_get_outlook_categories()
181+
await example_2_send_email()
182+
await example_3_get_emails()
183+
await example_4_draft_and_send_email()
184+
await example_5_error_handling()
185+
186+
print("\n" + "=" * 50)
187+
print("Sample completed!")
189188

190189

191190
if __name__ == "__main__":

0 commit comments

Comments
 (0)