Python sample: submissions for apps, add-ons, and flights
This article provides Python code examples that demonstrate how to use the Microsoft Store submission API for these tasks:
- Obtain an Azure AD access token
- Create an add-on
- Create a package flight
- Create an app submission
- Create an add-on submission
- Create a package flight submission
Obtain an Azure AD access token
The following example demonstrates how to obtain an Azure AD access token that you can use to call methods in the Microsoft Store submission API. After you obtain a token, you have 60 minutes to use this token in calls to the Microsoft Store submission API before the token expires. After the token expires, you can generate a new token..
import http.client, json
tenantId = "" # Your tenant ID
clientId = "" # Your client ID
clientSecret = "" # Your client secret
tokenEndpoint = "https://login.microsoftonline.com/{0}/oauth2/token"
tokenResource = "https://manage.devcenter.microsoft.com"
tokenRequestBody = "grant_type=client_credentials&client_id={0}&client_secret={1}&resource={2}".format(clientId, clientSecret, tokenResource)
headers = {"Content-Type": "application/x-www-form-urlencoded; charset=utf-8"}
tokenConnection = http.client.HTTPSConnection("login.microsoftonline.com")
tokenConnection.request("POST", "/{0}/oauth2/token".format(tenantId), tokenRequestBody, headers=headers)
tokenResponse = tokenConnection.getresponse()
print(tokenResponse.status)
tokenJson = json.loads(tokenResponse.read().decode())
print(tokenJson["access_token"])
tokenConnection.close()
Create an add-on
The following example demonstrates how to create and then delete an add-on.
import http.client, json
accessToken = "" # Your access token
iapRequestJson = "" # Your in-app-product request JSON
headers = {"Authorization": "Bearer " + accessToken,
"Content-type": "application/json",
"User-Agent": "Python"}
ingestionConnection = http.client.HTTPSConnection("manage.devcenter.microsoft.com")
# Create a new in-app-product
ingestionConnection.request("POST", "/v1.0/my/inappproducts", iapRequestJson, headers)
createIapResponse = ingestionConnection.getresponse()
print(createIapResponse.status)
print(createIapResponse.reason)
print(createIapResponse.headers["MS-CorrelationId"]) # Log correlation ID
iapJsonObject = json.loads(createIapResponse.read().decode())
inAppProductId = iapJsonObject["id"]
# Delete created in-app-product
ingestionConnection.request("DELETE", "/v1.0/my/inappproducts/" + inAppProductId, "", headers)
deleteIapResponse = ingestionConnection.getresponse()
print(deleteIapResponse.status)
print(deleteIapResponse.headers["MS-CorrelationId"]) # Log correlation ID
ingestionConnection.close()
Create a package flight
The following example demonstrates how to create and then delete a package flight.
import http.client, json, requests, time
from azure.storage.blob import BlobClient
accessToken = "" # Your access token
applicationId = "" # Your application ID
flightRequestJson = "" # Your flight request JSON
headers = {"Authorization": "Bearer " + accessToken,
"Content-type": "application/json",
"User-Agent": "Python"}
ingestionConnection = http.client.HTTPSConnection("manage.devcenter.microsoft.com")
# Create a new flight, a flight submission will be created together with the flight
ingestionConnection.request("POST", "/v1.0/my/applications/{0}/flights".format(applicationId), flightRequestJson, headers)
createFlightResponse = ingestionConnection.getresponse()
print(createFlightResponse.status)
print(createFlightResponse.reason)
print(createFlightResponse.headers["MS-CorrelationId"]) # Log correlation ID
flightJsonObject = json.loads(createFlightResponse.read().decode())
flightId = flightJsonObject["flightId"]
submissionId = flightJsonObject["pendingFlightSubmission"]["id"]
# Delete created flight
ingestionConnection.request("DELETE", "/v1.0/my/applications/{0}/flights/{1}".format(applicationId, flightId), "", headers)
deleteFlightResponse = ingestionConnection.getresponse()
print(deleteFlightResponse.status)
print(deleteFlightResponse.headers["MS-CorrelationId"]) # Log correlation ID
ingestionConnection.close()
Create an app submission
The following example shows how to use several methods in the Microsoft Store submission API to create an app submission. To do this, the code creates a new submission as a clone of the last published submission, and then updates and commits the cloned submission to Partner Center. Specifically, the example performs these tasks:
- To begin, the example gets data for the specified app.
- Next, it deletes the pending submission for the app, if one exists.
- It then creates a new submission for the app (the new submission is a copy of the last published submission).
- It changes some details for the new submission and upload a new package for the submission to Azure Blob Storage.
- Next, it updates and then commits the new submission to Partner Center.
- Finally, it periodically checks the status of the new submission until the submission is successfully committed.
import http.client, json, requests, time
from azure.storage.blob import BlobClient
accessToken = "" # Your access token
applicationId = "" # Your application ID
appSubmissionRequestJson = ""; # Your submission request JSON
zipFilePath = r'*.zip' # Your zip file path
headers = {"Authorization": "Bearer " + accessToken,
"Content-type": "application/json",
"User-Agent": "Python"}
ingestionConnection = http.client.HTTPSConnection("manage.devcenter.microsoft.com")
# Get application
ingestionConnection.request("GET", "/v1.0/my/applications/{0}".format(applicationId), "", headers)
appResponse = ingestionConnection.getresponse()
print(appResponse.status)
print(appResponse.headers["MS-CorrelationId"]) # Log correlation ID
# Delete existing in-progress submission
appJsonObject = json.loads(appResponse.read().decode())
if "pendingApplicationSubmission" in appJsonObject :
submissionToRemove = appJsonObject["pendingApplicationSubmission"]["id"]
ingestionConnection.request("DELETE", "/v1.0/my/applications/{0}/submissions/{1}".format(applicationId, submissionToRemove), "", headers)
deleteSubmissionResponse = ingestionConnection.getresponse()
print(deleteSubmissionResponse.status)
print(deleteSubmissionResponse.headers["MS-CorrelationId"]) # Log correlation ID
deleteSubmissionResponse.read()
# Create submission
ingestionConnection.request("POST", "/v1.0/my/applications/{0}/submissions".format(applicationId), "", headers)
createSubmissionResponse = ingestionConnection.getresponse()
print(createSubmissionResponse.status)
print(createSubmissionResponse.headers["MS-CorrelationId"]) # Log correlation ID
submissionJsonObject = json.loads(createSubmissionResponse.read().decode())
submissionId = submissionJsonObject["id"]
fileUploadUrl = submissionJsonObject["fileUploadUrl"]
print(submissionId)
print(fileUploadUrl)
# Update submission
ingestionConnection.request("PUT", "/v1.0/my/applications/{0}/submissions/{1}".format(applicationId, submissionId), appSubmissionRequestJson, headers)
updateSubmissionResponse = ingestionConnection.getresponse()
print(updateSubmissionResponse.status)
print(updateSubmissionResponse.headers["MS-CorrelationId"]) # Log correlation ID
updateSubmissionResponse.read()
# Upload images and packages in a zip file.
blob_client = BlobClient.from_blob_url(fileUploadUrl)
with open(zipFilePath, "rb") as data:
blob_client.upload_blob(data, blob_type="BlockBlob")
# Commit submission
ingestionConnection.request("POST", "/v1.0/my/applications/{0}/submissions/{1}/commit".format(applicationId, submissionId), "", headers)
commitResponse = ingestionConnection.getresponse()
print(commitResponse.status)
print(commitResponse.headers["MS-CorrelationId"]) # Log correlation ID
print(commitResponse.read())
# Pull submission status until commit process is completed
ingestionConnection.request("GET", "/v1.0/my/applications/{0}/submissions/{1}/status".format(applicationId, submissionId), "", headers)
getSubmissionStatusResponse = ingestionConnection.getresponse()
submissionJsonObject = json.loads(getSubmissionStatusResponse.read().decode())
while submissionJsonObject["status"] == "CommitStarted":
time.sleep(60)
ingestionConnection.request("GET", "/v1.0/my/applications/{0}/submissions/{1}/status".format(applicationId, submissionId), "", headers)
getSubmissionStatusResponse = ingestionConnection.getresponse()
submissionJsonObject = json.loads(getSubmissionStatusResponse.read().decode())
print(submissionJsonObject["status"])
print(submissionJsonObject["status"])
print(submissionJsonObject)
ingestionConnection.close()
Create an add-on submission
The following example shows how to use several methods in the Microsoft Store submission API to create an add-on submission. To do this, the code creates a new submission as a clone of the last published submission, and then updates and commits the cloned submission to Partner Center. Specifically, the example performs these tasks:
- To begin, the example gets data for the specified add-on.
- Next, it deletes the pending submission for the add-on, if one exists.
- It then creates a new submission for the add-on (the new submission is a copy of the last published submission).
- It uploads a ZIP archive that contains icons for the submission to Azure Blob Storage. For more information, see the relevant instructions about uploading a ZIP archive to Azure Blob Storage in Create an add-on submission.
- Next, it updates and then commits the new submission to Partner Center.
- Finally, it periodically checks the status of the new submission until the submission is successfully committed.
import http.client, json, requests, time
from azure.storage.blob import BlobClient
accessToken = "" # Your access token
inAppProductId = "" # Your in-app-product ID
updateSubmissionRequestBody = ""; # Your in-app-product submission request JSON
zipFilePath = r'*.zip' # Your zip file path
headers = {"Authorization": "Bearer " + accessToken,
"Content-type": "application/json",
"User-Agent": "Python"}
ingestionConnection = http.client.HTTPSConnection("manage.devcenter.microsoft.com")
# Get in-app-product
ingestionConnection.request("GET", "/v1.0/my/inappproducts/{0}".format(inAppProductId), "", headers)
iapResponse = ingestionConnection.getresponse()
print(iapResponse.status)
print(iapResponse.headers["MS-CorrelationId"]) # Log correlation ID
# Delete existing in-progress submission
iapJsonObject = json.loads(iapResponse.read().decode())
if "pendingInAppProductSubmission" in iapJsonObject :
submissionToRemove = iapJsonObject["pendingInAppProductSubmission"]["id"]
ingestionConnection.request("DELETE", "/v1.0/my/inappproducts/{0}/submissions/{1}".format(inAppProductId, submissionToRemove), "", headers)
deleteSubmissionResponse = ingestionConnection.getresponse()
print(deleteSubmissionResponse.status)
print(deleteSubmissionResponse.headers["MS-CorrelationId"]) # Log correlation ID
deleteSubmissionResponse.read()
# Create submission
ingestionConnection.request("POST", "/v1.0/my/inappproducts/{0}/submissions".format(inAppProductId), "", headers)
createSubmissionResponse = ingestionConnection.getresponse()
print(createSubmissionResponse.status)
print(createSubmissionResponse.headers["MS-CorrelationId"]) # Log correlation ID
submissionJsonObject = json.loads(createSubmissionResponse.read().decode())
submissionId = submissionJsonObject["id"]
fileUploadUrl = submissionJsonObject["fileUploadUrl"]
print(submissionId)
print(fileUploadUrl)
# Update submission
ingestionConnection.request("PUT", "/v1.0/my/inappproducts/{0}/submissions/{1}".format(inAppProductId, submissionId), updateSubmissionRequestBody, headers)
updateSubmissionResponse = ingestionConnection.getresponse()
print(updateSubmissionResponse.status)
print(updateSubmissionResponse.headers["MS-CorrelationId"]) # Log correlation ID
updateSubmissionResponse.read()
# Upload images and packages in a zip file.
blob_client = BlobClient.from_blob_url(fileUploadUrl)
with open(zipFilePath, "rb") as data:
blob_client.upload_blob(data, blob_type="BlockBlob")
# Commit submission
ingestionConnection.request("POST", "/v1.0/my/inappproducts/{0}/submissions/{1}/commit".format(inAppProductId, submissionId), "", headers)
commitResponse = ingestionConnection.getresponse()
print(commitResponse.status)
print(commitResponse.headers["MS-CorrelationId"]) # Log correlation ID
print(commitResponse.read())
# Pull submission status until commit process is completed
ingestionConnection.request("GET", "/v1.0/my/inappproducts/{0}/submissions/{1}/status".format(inAppProductId, submissionId), "", headers)
getSubmissionStatusResponse = ingestionConnection.getresponse()
submissionJsonObject = json.loads(getSubmissionStatusResponse.read().decode())
while submissionJsonObject["status"] == "CommitStarted":
time.sleep(60)
ingestionConnection.request("GET", "/v1.0/my/inappproducts/{0}/submissions/{1}/status".format(inAppProductId, submissionId), "", headers)
getSubmissionStatusResponse = ingestionConnection.getresponse()
submissionJsonObject = json.loads(getSubmissionStatusResponse.read().decode())
print(submissionJsonObject["status"])
print(submissionJsonObject["status"])
print(submissionJsonObject)
ingestionConnection.close()
Create a package flight submission
The following example shows how to use several methods in the Microsoft Store submission API to create a package flight submission. To do this, the code creates a new submission as a clone of the last published submission, and then updates and commits the cloned submission to Partner Center. Specifically, the example performs these tasks:
- To begin, the example gets data for the specified package flight.
- Next, it deletes the pending submission for the package flight, if one exists.
- It then creates a new submission for the package flight (the new submission is a copy of the last published submission).
- It uploads a new package for the submission to Azure Blob Storage. For more information, see the relevant instructions about uploading a ZIP archive to Azure Blob Storage in Create a package flight submission.
- Next, it updates and then commits the new submission to Partner Center.
- Finally, it periodically checks the status of the new submission until the submission is successfully committed.
import http.client, json, requests, time, zipfile
from azure.storage.blob import BlobClient
accessToken = "" # Your access token
applicationId = "" # Your application ID
flightId = "" # Your flight ID
flightSubmissionRequestJson = "" # Your submission request JSON
zipFilePath = r'*.zip' # Your zip file path
headers = {"Authorization": "Bearer " + accessToken,
"Content-type": "application/json",
"User-Agent": "Python"}
ingestionConnection = http.client.HTTPSConnection("manage.devcenter.microsoft.com")
# Get flight
ingestionConnection.request("GET", "/v1.0/my/applications/{0}/flights/{1}".format(applicationId, flightId), "", headers)
flightResponse = ingestionConnection.getresponse()
print(flightResponse.status)
print(flightResponse.headers["MS-CorrelationId"]) # Log correlation ID
# Delete existing in-progress submission
flightJsonObject = json.loads(flightResponse.read().decode())
if "pendingFlightSubmission" in flightJsonObject :
submissionToRemove = flightJsonObject["pendingFlightSubmission"]["id"]
ingestionConnection.request("DELETE", "/v1.0/my/applications/{0}/flights/{1}/submissions/{2}".format(applicationId, flightId, submissionToRemove), "", headers)
deleteSubmissionResponse = ingestionConnection.getresponse()
print(deleteSubmissionResponse.status)
print(deleteSubmissionResponse.headers["MS-CorrelationId"]) # Log correlation ID
deleteSubmissionResponse.read()
# Create submission
ingestionConnection.request("POST", "/v1.0/my/applications/{0}/flights/{1}/submissions".format(applicationId, flightId), "", headers)
createSubmissionResponse = ingestionConnection.getresponse()
print(createSubmissionResponse.status)
print(createSubmissionResponse.headers["MS-CorrelationId"]) # Log correlation ID
submissionJsonObject = json.loads(createSubmissionResponse.read().decode())
submissionId = submissionJsonObject["id"]
fileUploadUrl = submissionJsonObject["fileUploadUrl"]
print(submissionId)
print(fileUploadUrl)
# Update submission
ingestionConnection.request("PUT", "/v1.0/my/applications/{0}/flights/{1}/submissions/{2}".format(applicationId, flightId, submissionId), flightSubmissionRequestJson, headers)
updateSubmissionResponse = ingestionConnection.getresponse()
print(updateSubmissionResponse.status)
print(updateSubmissionResponse.headers["MS-CorrelationId"]) # Log correlation ID
updateSubmissionResponse.read()
# Upload images and packages in a zip file.
blob_client = BlobClient.from_blob_url(fileUploadUrl)
with open(zipFilePath, "rb") as data:
blob_client.upload_blob(data, blob_type="BlockBlob")
# Commit submission
ingestionConnection.request("POST", "/v1.0/my/applications/{0}/flights/{1}/submissions/{2}/commit".format(applicationId, flightId, submissionId), "", headers)
commitResponse = ingestionConnection.getresponse()
print(commitResponse.status)
print(commitResponse.headers["MS-CorrelationId"]) # Log correlation ID
print(commitResponse.read())
# Pull submission status until commit process is completed
ingestionConnection.request("GET", "/v1.0/my/applications/{0}/flights/{1}/submissions/{2}/status".format(applicationId, flightId, submissionId), "", headers)
getSubmissionStatusResponse = ingestionConnection.getresponse()
submissionJsonObject = json.loads(getSubmissionStatusResponse.read().decode())
while submissionJsonObject["status"] == "CommitStarted":
time.sleep(60)
ingestionConnection.request("GET", "/v1.0/my/applications/{0}/flights/{1}/submissions/{2}/status".format(applicationId, flightId, submissionId), "", headers)
getSubmissionStatusResponse = ingestionConnection.getresponse()
submissionJsonObject = json.loads(getSubmissionStatusResponse.read().decode())
print(submissionJsonObject["status"])
print(submissionJsonObject["status"])
print(submissionJsonObject)
ingestionConnection.close()