Delen via


Azure AI Document Intelligence-clientbibliotheek voor Python - versie 1.0.0b1

Azure AI Document Intelligence (voorheen bekend als Form Recognizer) is een cloudservice die machine learning gebruikt om tekst en gestructureerde gegevens uit uw documenten te analyseren. Het bevat de volgende hoofdfuncties:

  • Indeling: inhoud en structuur (bijvoorbeeld woorden, selectiemarkeringen, tabellen) uit documenten extraheren.
  • Document: analyseer sleutel-waardeparen naast de algemene indeling van documenten.
  • Lezen: pagina-informatie uit documenten lezen.
  • Vooraf samengesteld: algemene veldwaarden extraheren uit bepaalde documenttypen (bijvoorbeeld ontvangstbewijzen, facturen, visitekaartjes, id-documenten, Amerikaanse W-2-belastingdocumenten, onder andere) met behulp van vooraf samengestelde modellen.
  • Aangepast: maak aangepaste modellen van uw eigen gegevens om op maat gemaakte veldwaarden te extraheren naast de algemene indeling uit documenten.
  • Classificaties: bouw aangepaste classificatiemodellen die indelings- en taalfuncties combineren om documenten die u in uw toepassing verwerkt, nauwkeurig te detecteren en te identificeren.
  • Invoegtoepassingsmogelijkheden: streepjescodes/QR-codes, formules, lettertype/stijl, enzovoort extraheren of de hoge resolutiemodus inschakelen voor grote documenten met optionele parameters.

Aan de slag

Het pakket installeren

python -m pip install azure-ai-documentintelligence

Vereisten

  • Python 3.7 of hoger is vereist voor het gebruik van dit pakket.
  • U hebt een Azure-abonnement nodig om dit pakket te gebruiken.
  • Een bestaand Azure AI Document Intelligence-exemplaar.

Een Cognitive Services- of Document Intelligence-resource maken

Document Intelligence ondersteunt toegang tot meerdere services en toegang met één service. Maak een Cognitive Services-resource als u van plan bent toegang te krijgen tot meerdere Cognitive Services onder één eindpunt/sleutel. Maak een Document Intelligence-resource voor alleen documentinformatietoegang. Houd er rekening mee dat u een resource met één service nodig hebt als u Azure Active Directory-verificatie wilt gebruiken.

U kunt beide resources maken met behulp van:

Hieronder ziet u een voorbeeld van hoe u een Document Intelligence-resource kunt maken met behulp van de CLI:

# Create a new resource group to hold the Document Intelligence resource
# if using an existing resource group, skip this step
az group create --name <your-resource-name> --location <location>
# Create the Document Intelligence resource
az cognitiveservices account create \
    --name <your-resource-name> \
    --resource-group <your-resource-group-name> \
    --kind FormRecognizer \
    --sku <sku> \
    --location <location> \
    --yes

Zie hier voor meer informatie over het maken van de resource of het ophalen van de locatie- en SKU-informatie.

De client verifiëren

Als u wilt communiceren met de Document Intelligence-service, moet u een exemplaar van een client maken. Een eindpunt en referentie zijn nodig om het clientobject te instantiëren.

Het eindpunt ophalen

U kunt het eindpunt voor uw Document Intelligence-resource vinden met behulp van Azure Portal of Azure CLI:

# Get the endpoint for the Document Intelligence resource
az cognitiveservices account show --name "resource-name" --resource-group "resource-group-name" --query "properties.endpoint"

Een regionaal eindpunt of een aangepast subdomein kan worden gebruikt voor verificatie. Ze hebben de volgende indeling:

Regional endpoint: https://<region>.api.cognitive.microsoft.com/
Custom subdomain: https://<resource-name>.cognitiveservices.azure.com/

Een regionaal eindpunt is hetzelfde voor elke resource in een regio. Een volledige lijst met ondersteunde regionale eindpunten kunt u hier raadplegen. Houd er rekening mee dat regionale eindpunten geen ondersteuning bieden voor AAD-verificatie.

Een aangepast subdomein is daarentegen een naam die uniek is voor de Document Intelligence-resource. Ze kunnen alleen worden gebruikt door resources met één service.

De API-sleutel ophalen

De API-sleutel vindt u in Azure Portal of door de volgende Azure CLI-opdracht uit te voeren:

az cognitiveservices account keys list --name "<resource-name>" --resource-group "<resource-group-name>"

De client maken met AzureKeyCredential

Als u een API-sleutel als parameter credential wilt gebruiken, geeft u de sleutel door als een tekenreeks in een exemplaar van AzureKeyCredential.

from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient

endpoint = "https://<my-custom-subdomain>.cognitiveservices.azure.com/"
credential = AzureKeyCredential("<api_key>")
document_analysis_client = DocumentIntelligenceClient(endpoint, credential)

De client maken met een Azure Active Directory-referentie

AzureKeyCredential verificatie wordt gebruikt in de voorbeelden in deze introductiehandleiding, maar u kunt zich ook verifiëren met Azure Active Directory met behulp van de azure-identity-bibliotheek . Regionale eindpunten bieden geen ondersteuning voor AAD-verificatie. Maak een aangepaste subdomeinnaam voor uw resource om dit type verificatie te kunnen gebruiken.

Als u het hieronder weergegeven type DefaultAzureCredential of andere referentietypen wilt gebruiken die bij de Azure SDK worden geleverd, installeert u het azure-identity pakket:

pip install azure-identity

U moet ook een nieuwe AAD-toepassing registreren en toegang verlenen tot Document Intelligence door de "Cognitive Services User" rol toe te wijzen aan uw service-principal.

Nadat dit is voltooid, stelt u de waarden van de client-id, tenant-id en clientgeheim van de AAD-toepassing in als omgevingsvariabelen: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET.

"""DefaultAzureCredential will use the values from these environment
variables: AZURE_CLIENT_ID, AZURE_TENANT_ID, AZURE_CLIENT_SECRET
"""
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.identity import DefaultAzureCredential

endpoint = os.environ["DOCUMENTINTELLIGENCE_ENDPOINT"]
credential = DefaultAzureCredential()

document_analysis_client = DocumentIntelligenceClient(endpoint, credential)

Belangrijkste concepten

DocumentIntelligenceClient

DocumentIntelligenceClient biedt bewerkingen voor het analyseren van invoerdocumenten met behulp van vooraf samengestelde en aangepaste modellen via de begin_analyze_document API. Gebruik de model_id parameter om het type model voor analyse te selecteren. Bekijk hier een volledige lijst met ondersteunde modellen. De DocumentIntelligenceClient biedt ook bewerkingen voor het classificeren van documenten via de begin_classify_document API. Aangepaste classificatiemodellen kunnen elke pagina in een invoerbestand classificeren om de documenten in een invoerbestand te identificeren en kunnen ook meerdere documenten of meerdere exemplaren van één document in een invoerbestand identificeren.

Hier worden voorbeeldcodefragmenten verstrekt ter illustratie met behulp van een DocumentIntelligenceClient-voorbeelden. Meer informatie over het analyseren van documenten, met inbegrip van ondersteunde functies, landinstellingen en documenttypen, vindt u in de servicedocumentatie.

DocumentIntelligenceAdministrationClient

DocumentIntelligenceAdministrationClient biedt bewerkingen voor:

  • Aangepaste modellen bouwen om specifieke velden te analyseren die u opgeeft door uw aangepaste documenten te labelen. Er wordt een DocumentModelDetails geretourneerd die aangeeft welke documenttypen het model kan analyseren, evenals de geschatte betrouwbaarheid voor elk veld. Zie de servicedocumentatie voor een meer gedetailleerde uitleg.
  • Een samengesteld model maken op basis van een verzameling bestaande modellen.
  • Modellen beheren die zijn gemaakt in uw account.
  • Bewerkingen weergeven of een specifieke modelbewerking ophalen die in de afgelopen 24 uur is gemaakt.
  • Een aangepast model kopiëren van de ene Document Intelligence-resource naar de andere.
  • Bouw en beheer een aangepast classificatiemodel om de documenten te classificeren die u in uw toepassing verwerkt.

Houd er rekening mee dat modellen ook kunnen worden gebouwd met behulp van een grafische gebruikersinterface, zoals Document Intelligence Studio.

Voorbeeldcodefragmenten worden hier verstrekt ter illustratie met behulp van een DocumentIntelligenceAdministrationClient-voorbeelden.

Langlopende bewerkingen

Langlopende bewerkingen zijn bewerkingen die bestaan uit een eerste aanvraag die naar de service wordt verzonden om een bewerking te starten, gevolgd door het pollen van de service met intervallen om te bepalen of de bewerking is voltooid of mislukt, en of deze is geslaagd, om het resultaat op te halen.

Methoden voor het analyseren van documenten, het bouwen van modellen of het kopiëren/opstellen van modellen worden gemodelleerd als langlopende bewerkingen. De client maakt een begin_<method-name> methode beschikbaar die een LROPoller of AsyncLROPollerretourneert. Aanroepende gebruikers moeten wachten tot de bewerking is voltooid door het poller-object aan te roepen result() dat door de begin_<method-name> methode is geretourneerd. Voorbeeldcodefragmenten worden verstrekt ter illustratie van langlopende bewerkingen hieronder.

Voorbeelden

De volgende sectie bevat verschillende codefragmenten die betrekking hebben op enkele van de meest voorkomende documentinformatietaken, waaronder:

Indeling extraheren

Extraheren van tekst, selectiemarkeringen, tekststijlen en tabelstructuren, samen met hun begrenzingsgebiedcoördinaten, uit documenten.

from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient

endpoint = os.environ["DOCUMENTINTELLIGENCE_ENDPOINT"]
key = os.environ["DOCUMENTINTELLIGENCE_API_KEY"]

document_intelligence_client = DocumentIntelligenceClient(
    endpoint=endpoint, credential=AzureKeyCredential(key)
)
with open(path_to_sample_documents, "rb") as f:
    poller = document_intelligence_client.begin_analyze_document(
        "prebuilt-layout", analyze_request=f, content_type="application/octet-stream"
    )
result = poller.result()

for idx, style in enumerate(result.styles):
    print(
        "Document contains {} content".format(
            "handwritten" if style.is_handwritten else "no handwritten"
        )
    )

for page in result.pages:
    print("----Analyzing layout from page #{}----".format(page.page_number))
    print(
        "Page has width: {} and height: {}, measured with unit: {}".format(
            page.width, page.height, page.unit
        )
    )

    for line_idx, line in enumerate(page.lines):
        words = line.get_words()
        print(
            "...Line # {} has word count {} and text '{}' within bounding polygon '{}'".format(
                line_idx,
                len(words),
                line.content,
                line.polygon,
            )
        )

        for word in words:
            print(
                "......Word '{}' has a confidence of {}".format(
                    word.content, word.confidence
                )
            )

    for selection_mark in page.selection_marks:
        print(
            "...Selection mark is '{}' within bounding polygon '{}' and has a confidence of {}".format(
                selection_mark.state,
                selection_mark.polygon,
                selection_mark.confidence,
            )
        )

for table_idx, table in enumerate(result.tables):
    print(
        "Table # {} has {} rows and {} columns".format(
            table_idx, table.row_count, table.column_count
        )
    )
    for region in table.bounding_regions:
        print(
            "Table # {} location on page: {} is {}".format(
                table_idx,
                region.page_number,
                region.polygon,
            )
        )
    for cell in table.cells:
        print(
            "...Cell[{}][{}] has content '{}'".format(
                cell.row_index,
                cell.column_index,
                cell.content,
            )
        )
        for region in cell.bounding_regions:
            print(
                "...content on page {} is within bounding polygon '{}'".format(
                    region.page_number,
                    region.polygon,
                )
            )

print("----------------------------------------")

Vooraf samengestelde modellen gebruiken

Extraheer velden uit bepaalde documenttypen, zoals ontvangstbewijzen, facturen, visitekaartjes, identiteitsdocumenten en Amerikaanse W-2-belastingdocumenten met behulp van vooraf samengestelde modellen van de Document Intelligence-service.

Als u bijvoorbeeld velden van een verkoopbewijs wilt analyseren, gebruikt u het vooraf samengestelde ontvangstbewijsmodel dat wordt geleverd door door te geven aan model_id="prebuilt-receipt" de begin_analyze_document methode:

from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient

endpoint = os.environ["DOCUMENTINTELLIGENCE_ENDPOINT"]
key = os.environ["DOCUMENTINTELLIGENCE_API_KEY"]

document_analysis_client = DocumentIntelligenceClient(endpoint=endpoint, credential=AzureKeyCredential(key))
with open(path_to_sample_documents, "rb") as f:
    poller = document_analysis_client.begin_analyze_document(
        "prebuilt-receipt", analyze_request=f, locale="en-US", content_type="application/octet-stream"
    )
receipts = poller.result()

for idx, receipt in enumerate(receipts.documents):
    print(f"--------Analysis of receipt #{idx + 1}--------")
    print(f"Receipt type: {receipt.doc_type if receipt.doc_type else 'N/A'}")
    merchant_name = receipt.fields.get("MerchantName")
    if merchant_name:
        print(f"Merchant Name: {merchant_name.get('valueString')} has confidence: " f"{merchant_name.confidence}")
    transaction_date = receipt.fields.get("TransactionDate")
    if transaction_date:
        print(
            f"Transaction Date: {transaction_date.get('valueDate')} has confidence: "
            f"{transaction_date.confidence}"
        )
    if receipt.fields.get("Items"):
        print("Receipt items:")
        for idx, item in enumerate(receipt.fields.get("Items").get("valueArray")):
            print(f"...Item #{idx + 1}")
            item_description = item.get("valueObject").get("Description")
            if item_description:
                print(
                    f"......Item Description: {item_description.get('valueString')} has confidence: "
                    f"{item_description.confidence}"
                )
            item_quantity = item.get("valueObject").get("Quantity")
            if item_quantity:
                print(
                    f"......Item Quantity: {item_quantity.get('valueString')} has confidence: "
                    f"{item_quantity.confidence}"
                )
            item_total_price = item.get("valueObject").get("TotalPrice")
            if item_total_price:
                print(
                    f"......Total Item Price: {format_price(item_total_price.get('valueCurrency'))} has confidence: "
                    f"{item_total_price.confidence}"
                )
    subtotal = receipt.fields.get("Subtotal")
    if subtotal:
        print(f"Subtotal: {format_price(subtotal.get('valueCurrency'))} has confidence: {subtotal.confidence}")
    tax = receipt.fields.get("TotalTax")
    if tax:
        print(f"Total tax: {format_price(tax.get('valueCurrency'))} has confidence: {tax.confidence}")
    tip = receipt.fields.get("Tip")
    if tip:
        print(f"Tip: {format_price(tip.get('valueCurrency'))} has confidence: {tip.confidence}")
    total = receipt.fields.get("Total")
    if total:
        print(f"Total: {format_price(total.get('valueCurrency'))} has confidence: {total.confidence}")
    print("--------------------------------------")

U bent niet beperkt tot ontvangstbewijzen! Er zijn een aantal vooraf gedefinieerde modellen waaruit u kunt kiezen, die elk een eigen set ondersteunde velden hebben. Bekijk hier andere ondersteunde vooraf samengestelde modellen.

Een aangepast model bouwen

Bouw een aangepast model op basis van uw eigen documenttype. Het resulterende model kan worden gebruikt om waarden te analyseren van de typen documenten waarop het is getraind. Geef een SAS-URL voor de container op voor uw Azure Storage Blob-container waar u de trainingsdocumenten opslaat.

Meer informatie over het instellen van een container en de vereiste bestandsstructuur vindt u in de servicedocumentatie.

from azure.ai.formrecognizer import (
    DocumentIntelligenceAdministrationClient,
    ModelBuildMode,
)
from azure.core.credentials import AzureKeyCredential

endpoint = os.environ["DOCUMENTINTELLIGENCE_ENDPOINT"]
key = os.environ["DOCUMENTINTELLIGENCE_API_KEY"]
container_sas_url = os.environ["CONTAINER_SAS_URL"]

document_model_admin_client = DocumentIntelligenceAdministrationClient(
    endpoint, AzureKeyCredential(key)
)
poller = document_model_admin_client.begin_build_document_model(
    ModelBuildMode.TEMPLATE,
    blob_container_url=container_sas_url,
    description="my model description",
)
model = poller.result()

print(f"Model ID: {model.model_id}")
print(f"Description: {model.description}")
print(f"Model created on: {model.created_on}")
print(f"Model expires on: {model.expires_on}")
print("Doc types the model can recognize:")
for name, doc_type in model.doc_types.items():
    print(
        f"Doc Type: '{name}' built with '{doc_type.build_mode}' mode which has the following fields:"
    )
    for field_name, field in doc_type.field_schema.items():
        print(
            f"Field: '{field_name}' has type '{field['type']}' and confidence score "
            f"{doc_type.field_confidence[field_name]}"
        )

Documenten analyseren met een aangepast model

Documentvelden, tabellen, selectiemarkeringen en meer analyseren. Deze modellen worden getraind met uw eigen gegevens, zodat ze zijn afgestemd op uw documenten. Voor de beste resultaten moet u alleen documenten analyseren van hetzelfde documenttype waarmee het aangepaste model is gemaakt.

from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient

endpoint = os.environ["DOCUMENTINTELLIGENCE_ENDPOINT"]
key = os.environ["DOCUMENTINTELLIGENCE_API_KEY"]
model_id = os.getenv("CUSTOM_BUILT_MODEL_ID", custom_model_id)

document_analysis_client = DocumentIntelligenceClient(endpoint=endpoint, credential=AzureKeyCredential(key))

# Make sure your document's type is included in the list of document types the custom model can analyze
with open(path_to_sample_documents, "rb") as f:
    poller = document_analysis_client.begin_analyze_document(
        model_id=model_id, analyze_request=f, content_type="application/octet-stream"
    )
result = poller.result()

for idx, document in enumerate(result.documents):
    print(f"--------Analyzing document #{idx + 1}--------")
    print(f"Document has type {document.doc_type}")
    print(f"Document has document type confidence {document.confidence}")
    print(f"Document was analyzed with model with ID {result.model_id}")
    for name, field in document.fields.items():
        field_value = field.get("valueString") if field.get("valueString") else field.content
        print(
            f"......found field of type '{field.type}' with value '{field_value}' and with confidence {field.confidence}"
        )

# iterate over tables, lines, and selection marks on each page
for page in result.pages:
    print(f"\nLines found on page {page.page_number}")
    for line in page.lines:
        print(f"...Line '{line.content}'")
    for word in page.words:
        print(f"...Word '{word.content}' has a confidence of {word.confidence}")
    if page.selection_marks:
        print(f"\nSelection marks found on page {page.page_number}")
        for selection_mark in page.selection_marks:
            print(
                f"...Selection mark is '{selection_mark.state}' and has a confidence of {selection_mark.confidence}"
            )

for i, table in enumerate(result.tables):
    print(f"\nTable {i + 1} can be found on page:")
    for region in table.bounding_regions:
        print(f"...{region.page_number}")
    for cell in table.cells:
        print(f"...Cell[{cell.row_index}][{cell.column_index}] has text '{cell.content}'")
print("-----------------------------------")

Daarnaast kan een document-URL ook worden gebruikt om documenten te analyseren met behulp van de begin_analyze_document methode .

from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import AnalyzeDocumentRequest

endpoint = os.environ["DOCUMENTINTELLIGENCE_ENDPOINT"]
key = os.environ["DOCUMENTINTELLIGENCE_API_KEY"]

document_analysis_client = DocumentIntelligenceClient(endpoint=endpoint, credential=AzureKeyCredential(key))
url = "https://raw.githubusercontent.com/Azure/azure-sdk-for-python/main/sdk/documentintelligence/azure-ai-documentintelligence/tests/sample_forms/receipt/contoso-receipt.png"
poller = document_analysis_client.begin_analyze_document("prebuilt-receipt", AnalyzeDocumentRequest(url_source=url))
receipts = poller.result()

Uw modellen beheren

Beheer de aangepaste modellen die aan uw account zijn gekoppeld.

from azure.ai.documentintelligence import DocumentIntelligenceAdministrationClient
from azure.core.credentials import AzureKeyCredential
from azure.core.exceptions import ResourceNotFoundError

endpoint = "https://<my-custom-subdomain>.cognitiveservices.azure.com/"
credential = AzureKeyCredential("<api_key>")

document_model_admin_client = DocumentIntelligenceAdministrationClient(endpoint, credential)

account_details = document_model_admin_client.get_resource_info()
print("Our account has {} custom models, and we can have at most {} custom models".format(
    account_details.custom_document_models.count, account_details.custom_document_models.limit
))

# Here we get a paged list of all of our models
models = document_model_admin_client.list_models()
print("We have models with the following ids: {}".format(
    ", ".join([m.model_id for m in models])
))

# Replace with the custom model ID from the "Build a model" sample
model_id = "<model_id from the Build a Model sample>"

custom_model = document_model_admin_client.get_model(model_id=model_id)
print("Model ID: {}".format(custom_model.model_id))
print("Description: {}".format(custom_model.description))
print("Model created on: {}\n".format(custom_model.created_on))

# Finally, we will delete this model by ID
document_model_admin_client.delete_model(model_id=custom_model.model_id)

try:
    document_model_admin_client.get_model(model_id=custom_model.model_id)
except ResourceNotFoundError:
    print("Successfully deleted model with id {}".format(custom_model.model_id))

Mogelijkheden van invoegtoepassingen

Document Intelligence ondersteunt geavanceerdere analysemogelijkheden. Deze optionele functies kunnen worden in- en uitgeschakeld, afhankelijk van het scenario van de documentextractie.

De volgende invoegtoepassingsmogelijkheden zijn beschikbaar voor 31-07-2023 (GA) en latere versies:

Houd er rekening mee dat voor sommige mogelijkheden van invoegtoepassingen extra kosten in rekening worden gebracht. Zie prijzen: https://azure.microsoft.com/pricing/details/ai-document-intelligence/.

Problemen oplossen

Algemeen

Document Intelligence-clientbibliotheek genereert uitzonderingen die zijn gedefinieerd in Azure Core. Foutcodes en berichten die door de Document Intelligence-service worden gegenereerd, vindt u in de servicedocumentatie.

Logboekregistratie

Deze bibliotheek gebruikt de standaardbibliotheek voor logboekregistratie voor logboekregistratie.

Basisinformatie over HTTP-sessies (URL's, headers, enzovoort) wordt op INFO niveau geregistreerd.

Gedetailleerde DEBUG logboekregistratie op niveau, inclusief aanvraag-/antwoordteksten en niet-geredigeerde headers, kan worden ingeschakeld op de client of per bewerking met het logging_enable sleutelwoordargument.

Zie hier de volledige documentatie voor SDK-logboekregistratie met voorbeelden.

Optionele configuratie

Optionele trefwoordargumenten kunnen worden doorgegeven op het niveau van de client en per bewerking. In de referentiedocumentatie voor Azure Core worden de beschikbare configuraties beschreven voor nieuwe pogingen, logboekregistratie, transportprotocollen en meer.

Volgende stappen

Meer voorbeeldcode

Zie de Voorbeeld-LEESMIJ voor verschillende codefragmenten die veelvoorkomende patronen illustreren die worden gebruikt in de Document Intelligence Python-API.

Aanvullende documentatie

Zie de Document Intelligence-documentatie over docs.microsoft.com voor uitgebreidere documentatie over Azure AI Document Intelligence.

Bijdragen

Wij verwelkomen bijdragen en suggesties voor dit project. Voor de meeste bijdragen moet u instemmen met een licentieovereenkomst voor bijdragers (CLA: Contributor License Agreement) waarin u verklaart dat u gerechtigd bent ons het recht te geven uw bijdrage te gebruiken, en dat u dit ook doet. Ga naar https://cla.microsoft.com voor meer informatie.

Wanneer u een pull-aanvraag indient, wordt met een CLA-bot automatisch bepaald of u een CLA moet verschaffen en wordt de pull-aanvraag dienovereenkomstig opgemaakt (bijvoorbeeld met een label of commentaar). Volg gewoon de instructies van de bot. U hoeft dit maar eenmaal te doen voor alle repo's waar gebruik wordt gemaakt van onze CLA.

Op dit project is de Microsoft Open Source Code of Conduct (Microsoft Open Source-gedragscode) van toepassing. Raadpleeg de Veelgestelde vragen over de gedragscode voor meer informatie of neem contact op met opencode@microsoft.com als u meer vragen of opmerkingen hebt.