-
Notifications
You must be signed in to change notification settings - Fork 142
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #99 from Azure-Samples/feature/add-progressive-pol…
…icies-1-lab Feature/add zero-to-production lab
- Loading branch information
Showing
11 changed files
with
1,372 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ __pycache__/ | |
.azure/ | ||
|
||
labs-in-progress/ | ||
params.json | ||
params*.json | ||
policy-updated.xml | ||
|
||
.vscode/**/* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# APIM ❤️ OpenAI | ||
|
||
## [Zero-to-Production lab](zero-to-production.ipynb) | ||
|
||
Playground to create a combination of several policies in an iterative approach. We start with load balancing, then progressively add token emitting, rate limiting, and, eventually, semantic caching. Each of these sets of policies is derived from other labs in this repo. | ||
|
||
[View policy configuration](policy.xml) | ||
|
||
### Prerequisites | ||
|
||
- [Python 3.12 or later version](https://www.python.org/) installed | ||
- [Pandas Library](https://pandas.pydata.org) installed | ||
- [VS Code](https://code.visualstudio.com/) installed with the [Jupyter notebook extension](https://marketplace.visualstudio.com/items?itemName=ms-toolsai.jupyter) enabled | ||
- [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed | ||
- [An Azure Subscription](https://azure.microsoft.com/free/) with Contributor permissions | ||
- [Access granted to Azure OpenAI](https://aka.ms/oai/access) | ||
- [Sign in to Azure with Azure CLI](https://learn.microsoft.com/cli/azure/authenticate-azure-cli-interactively) | ||
|
||
### 🚀 Get started | ||
|
||
Proceed by opening the [Jupyter notebook](zero-to-production.ipynb), and follow the steps provided. | ||
|
||
### 🗑️ Clean up resources | ||
|
||
When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered. | ||
Use the [clean-up-resources notebook](clean-up-resources.ipynb) for that. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"### 🗑️ Clean up resources\n", | ||
"\n", | ||
"When you're finished with the lab, you should remove all your deployed resources from Azure to avoid extra charges and keep your Azure subscription uncluttered." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import os, sys\n", | ||
"sys.path.insert(1, '../../shared') # add the shared directory to the Python path\n", | ||
"import utils\n", | ||
"\n", | ||
"deployment_name = os.path.basename(os.path.dirname(globals()['__vsc_ipynb_file__']))\n", | ||
"utils.cleanup_resources(deployment_name)" | ||
] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.12.8" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
// ------------------ | ||
// PARAMETERS | ||
// ------------------ | ||
|
||
// Typically, parameters would be decorated with appropriate metadata and attributes, but as they are very repetetive in these labs we omit them for brevity. | ||
|
||
param apimSku string | ||
param openAIConfig array = [] | ||
param openAIModelName string | ||
param openAIModelVersion string | ||
param openAIDeploymentName string | ||
param openAIModelCapacity int | ||
param openAIAPIVersion string = '2024-02-01' | ||
param policyXml string | ||
|
||
// ------------------ | ||
// VARIABLES | ||
// ------------------ | ||
|
||
var resourceSuffix = uniqueString(subscription().id, resourceGroup().id) | ||
var apiManagementName = 'apim-${resourceSuffix}' | ||
var openAISubscriptionName = 'openai-subscription' | ||
var openAISubscriptionDescription = 'OpenAI Subscription' | ||
var openAIAPIName = 'openai' | ||
|
||
// ------------------ | ||
// RESOURCES | ||
// ------------------ | ||
|
||
// 1. Log Analytics Workspace | ||
module lawModule '../../modules/operational-insights/v1/workspaces.bicep' = { | ||
name: 'lawModule' | ||
} | ||
|
||
var lawId = lawModule.outputs.id | ||
|
||
// 2. Application Insights | ||
module appInsightsModule '../../modules/monitor/v1/appinsights.bicep' = { | ||
name: 'appInsightsModule' | ||
params: { | ||
workbookJson: loadTextContent('openai-usage-analysis-workbook.json') | ||
lawId: lawId | ||
customMetricsOptedInType: 'WithDimensions' | ||
} | ||
} | ||
|
||
var appInsightsId = appInsightsModule.outputs.id | ||
var appInsightsInstrumentationKey = appInsightsModule.outputs.instrumentationKey | ||
|
||
// 3. API Management | ||
module apimModule '../../modules/apim/v1/apim.bicep' = { | ||
name: 'apimModule' | ||
params: { | ||
apimSku: apimSku | ||
appInsightsInstrumentationKey: appInsightsInstrumentationKey | ||
appInsightsId: appInsightsId | ||
} | ||
} | ||
|
||
// 4. Cognitive Services | ||
module openAIModule '../../modules/cognitive-services/v1/openai.bicep' = { | ||
name: 'openAIModule' | ||
params: { | ||
openAIConfig: openAIConfig | ||
openAIDeploymentName: openAIDeploymentName | ||
openAIModelName: openAIModelName | ||
openAIModelVersion: openAIModelVersion | ||
openAIModelCapacity: openAIModelCapacity | ||
apimPrincipalId: apimModule.outputs.principalId | ||
lawId: lawId | ||
} | ||
} | ||
|
||
// 5. APIM OpenAI API | ||
module openAIAPIModule '../../modules/apim/v1/openai-api.bicep' = { | ||
name: 'openAIAPIModule' | ||
params: { | ||
policyXml: policyXml | ||
openAIConfig: openAIModule.outputs.extendedOpenAIConfig | ||
openAIAPIVersion: openAIAPIVersion | ||
appInsightsInstrumentationKey: appInsightsInstrumentationKey | ||
appInsightsId: appInsightsId | ||
} | ||
} | ||
|
||
// 6. Create New APIM Subscriptions | ||
|
||
// We presume the APIM resource has been created as part of this bicep flow. | ||
resource apim 'Microsoft.ApiManagement/service@2024-06-01-preview' existing = { | ||
name: apiManagementName | ||
dependsOn: [ | ||
apimModule | ||
] | ||
} | ||
|
||
resource api 'Microsoft.ApiManagement/service/apis@2024-06-01-preview' existing = { | ||
parent: apim | ||
name: openAIAPIName | ||
dependsOn: [ | ||
openAIAPIModule | ||
] | ||
} | ||
|
||
// Ignore the subscription that gets created in the APIM module and create three new ones for this lab. | ||
resource apimSubscriptions 'Microsoft.ApiManagement/service/subscriptions@2024-06-01-preview' = [for i in range(1, 3): { | ||
name: '${openAISubscriptionName}${i}' | ||
parent: apim | ||
properties: { | ||
allowTracing: true | ||
displayName: '${openAISubscriptionDescription} ${i}' | ||
scope: '/apis/${api.id}' | ||
state: 'active' | ||
} | ||
dependsOn: [ | ||
api | ||
] | ||
}] | ||
|
||
// ------------------ | ||
// MARK: OUTPUTS | ||
// ------------------ | ||
|
||
output applicationInsightsAppId string = appInsightsModule.outputs.appId | ||
output applicationInsightsName string = appInsightsModule.outputs.applicationInsightsName | ||
output logAnalyticsWorkspaceId string = lawModule.outputs.customerId | ||
output apimServiceId string = apimModule.outputs.id | ||
output apimResourceGatewayURL string = apimModule.outputs.gatewayUrl | ||
|
||
#disable-next-line outputs-should-not-contain-secrets | ||
output apimSubscription1Key string = apimSubscriptions[0].listSecrets().primaryKey | ||
#disable-next-line outputs-should-not-contain-secrets | ||
output apimSubscription2Key string = apimSubscriptions[1].listSecrets().primaryKey | ||
#disable-next-line outputs-should-not-contain-secrets | ||
output apimSubscription3Key string = apimSubscriptions[2].listSecrets().primaryKey |
Oops, something went wrong.