Pustaka klien Azure AI Document Intelligence untuk Python - versi 1.0.0b1

Kecerdasan Dokumen Azure AI (sebelumnya dikenal sebagai Form Recognizer) adalah layanan cloud yang menggunakan pembelajaran mesin untuk menganalisis teks dan data terstruktur dari dokumen Anda. Ini termasuk fitur utama berikut:

  • Tata Letak - Ekstrak konten dan struktur (misalnya kata, tanda pilihan, tabel) dari dokumen.
  • Dokumen - Menganalisis pasangan kunci-nilai selain tata letak umum dari dokumen.
  • Baca - Membaca informasi halaman dari dokumen.
  • Bawaan - Ekstrak nilai bidang umum dari jenis dokumen tertentu (mis. tanda terima, faktur, kartu nama, dokumen ID, dokumen pajak W-2 AS, antara lain) menggunakan model bawaan.
  • Kustom - Buat model kustom dari data Anda sendiri untuk mengekstrak nilai bidang yang disesuaikan selain tata letak umum dari dokumen.
  • Pengklasifikasi - Membangun model klasifikasi kustom yang menggabungkan fitur tata letak dan bahasa untuk mendeteksi dan mengidentifikasi dokumen yang Anda proses secara akurat dalam aplikasi Anda.
  • Kemampuan add-on - Ekstrak kode batang/kode QR, rumus, font/gaya, dll. atau aktifkan mode resolusi tinggi untuk dokumen besar dengan parameter opsional.

Memulai

Menginstal paket

python -m pip install azure-ai-documentintelligence

Prasyarat

  • Python 3.7 atau yang lebih baru diharuskan untuk menggunakan paket ini.
  • Anda memerlukan langganan Azure untuk menggunakan paket ini.
  • Instans Kecerdasan Dokumen Azure AI yang sudah ada.

Membuat sumber daya Cognitive Services atau Kecerdasan Dokumen

Kecerdasan Dokumen mendukung akses multi-layanan dan layanan tunggal. Buat sumber daya Cognitive Services jika Anda berencana untuk mengakses beberapa layanan kognitif di bawah satu titik akhir/kunci. Hanya untuk akses Kecerdasan Dokumen, buat sumber daya Kecerdasan Dokumen. Harap dicatat bahwa Anda akan memerlukan sumber daya layanan tunggal jika Anda berniat menggunakan autentikasi Azure Active Directory.

Anda dapat membuat salah satu sumber daya menggunakan:

Di bawah ini adalah contoh bagaimana Anda dapat membuat sumber daya Inteligensi Dokumen menggunakan 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

Untuk informasi selengkapnya tentang membuat sumber daya atau cara mendapatkan informasi lokasi dan sku, lihat di sini.

Mengautentikasi klien

Untuk berinteraksi dengan layanan Kecerdasan Dokumen, Anda harus membuat instans klien. Titik akhir dan kredensial diperlukan untuk membuat instans objek klien.

Mendapatkan titik akhir

Anda dapat menemukan titik akhir untuk sumber daya Inteligensi Dokumen Anda menggunakan Portal Microsoft Azure atau 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"

Baik titik akhir regional atau subdomain kustom dapat digunakan untuk autentikasi. Mereka diformat sebagai berikut:

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

Titik akhir regional sama untuk setiap sumber daya di suatu wilayah. Daftar lengkap titik akhir regional yang didukung dapat dikonsultasikan di sini. Harap dicatat bahwa titik akhir regional tidak mendukung autentikasi AAD.

Subdomain kustom, di sisi lain, adalah nama yang unik untuk sumber daya Kecerdasan Dokumen. Mereka hanya dapat digunakan oleh sumber daya layanan tunggal.

Mendapatkan kunci API

Kunci API dapat ditemukan di Portal Microsoft Azure atau dengan menjalankan perintah Azure CLI berikut:

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

Membuat klien dengan AzureKeyCredential

Untuk menggunakan kunci API sebagai credential parameter, teruskan kunci sebagai string ke dalam instans 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)

Membuat klien dengan kredensial Azure Active Directory

AzureKeyCredential autentikasi digunakan dalam contoh dalam panduan memulai ini, tetapi Anda juga dapat mengautentikasi dengan Azure Active Directory menggunakan pustaka azure-identity . Perhatikan bahwa titik akhir regional tidak mendukung autentikasi AAD. Buat nama subdomain kustom untuk sumber daya Anda untuk menggunakan jenis autentikasi ini.

Untuk menggunakan jenis DefaultAzureCredential yang ditunjukkan di bawah ini, atau jenis kredensial lain yang disediakan dengan Azure SDK, harap instal azure-identity paket:

pip install azure-identity

Anda juga perlu mendaftarkan aplikasi AAD baru dan memberikan akses ke Kecerdasan Dokumen dengan menetapkan peran ke "Cognitive Services User" perwakilan layanan Anda.

Setelah selesai, atur nilai ID klien, ID penyewa, dan rahasia klien aplikasi AAD sebagai variabel lingkungan: AZURE_CLIENT_ID, , AZURE_TENANT_IDAZURE_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)

Konsep utama

DocumentIntelligenceClient

DocumentIntelligenceClient menyediakan operasi untuk menganalisis dokumen input menggunakan model bawaan dan kustom melalui begin_analyze_document API. model_id Gunakan parameter untuk memilih jenis model untuk analisis. Lihat daftar lengkap model yang didukung di sini. juga DocumentIntelligenceClient menyediakan operasi untuk mengklasifikasikan begin_classify_document dokumen melalui API. Model klasifikasi kustom dapat mengklasifikasikan setiap halaman dalam file input untuk mengidentifikasi dokumen di dalamnya dan juga dapat mengidentifikasi beberapa dokumen atau beberapa instans dari satu dokumen dalam file input.

Cuplikan kode sampel disediakan untuk mengilustrasikan menggunakan Contoh DocumentIntelligenceClient di sini. Informasi selengkapnya tentang menganalisis dokumen, termasuk fitur, lokal, dan jenis dokumen yang didukung dapat ditemukan dalam dokumentasi layanan.

DocumentIntelligenceAdministrationClient

DocumentIntelligenceAdministrationClient menyediakan operasi untuk:

  • Membangun model kustom untuk menganalisis bidang tertentu yang Anda tentukan dengan memberi label dokumen kustom Anda. DocumentModelDetails dikembalikan yang menunjukkan jenis dokumen yang dapat dianalisis model, serta perkiraan keyakinan untuk setiap bidang. Lihat dokumentasi layanan untuk penjelasan yang lebih rinci.
  • Membuat model yang terdiri dari kumpulan model yang ada.
  • Mengelola model yang dibuat di akun Anda.
  • Mencantumkan operasi atau mendapatkan operasi model tertentu yang dibuat dalam 24 jam terakhir.
  • Menyalin model kustom dari satu sumber daya Kecerdasan Dokumen ke sumber daya lainnya.
  • Buat dan kelola model klasifikasi kustom untuk mengklasifikasikan dokumen yang Anda proses dalam aplikasi Anda.

Harap dicatat bahwa model juga dapat dibangun menggunakan antarmuka pengguna grafis seperti Document Intelligence Studio.

Cuplikan kode sampel disediakan untuk mengilustrasikan menggunakan Contoh DocumentIntelligenceAdministrationClient di sini.

Operasi jangka panjang

Operasi jangka panjang adalah operasi yang terdiri dari permintaan awal yang dikirim ke layanan untuk memulai operasi, diikuti dengan polling layanan pada interval untuk menentukan apakah operasi telah selesai atau gagal, dan jika telah berhasil, untuk mendapatkan hasilnya.

Metode yang menganalisis dokumen, model build, atau model salin/buat dimodelkan sebagai operasi yang berjalan lama. Klien mengekspos begin_<method-name> metode yang mengembalikan LROPoller atau AsyncLROPoller. Penelepon harus menunggu operasi selesai dengan memanggil result() objek poller yang dikembalikan dari begin_<method-name> metode . Cuplikan kode sampel disediakan untuk mengilustrasikan menggunakan Contoh operasi yang berjalan lama di bawah ini.

Contoh

Bagian berikut ini menyediakan beberapa cuplikan kode yang mencakup beberapa tugas Inteligensi Dokumen yang paling umum, termasuk:

Ekstrak Tata Letak

Ekstrak teks, tanda pilihan, gaya teks, dan struktur tabel, bersama dengan koordinat wilayah pembatasnya, dari dokumen.

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("----------------------------------------")

Menggunakan Model Bawaan

Ekstrak bidang dari jenis dokumen tertentu seperti tanda terima, faktur, kartu nama, dokumen identitas, dan dokumen pajak W-2 AS menggunakan model bawaan yang disediakan oleh layanan Inteligensi Dokumen.

Misalnya, untuk menganalisis bidang dari tanda terima penjualan, gunakan model tanda terima bawaan yang disediakan dengan meneruskan model_id="prebuilt-receipt" ke begin_analyze_document metode :

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("--------------------------------------")

Anda tidak terbatas pada tanda terima! Ada beberapa model bawaan untuk dipilih, yang masing-masing memiliki serangkaian bidang yang didukung sendiri. Lihat model bawaan lain yang didukung di sini.

Membangun Model Kustom

Buat model kustom pada jenis dokumen Anda sendiri. Model yang dihasilkan dapat digunakan untuk menganalisis nilai dari jenis dokumen yang dilatihnya. Berikan URL SAS kontainer ke kontainer Azure Storage Blob tempat Anda menyimpan dokumen pelatihan.

Detail selengkapnya tentang menyiapkan kontainer dan struktur file yang diperlukan dapat ditemukan dalam dokumentasi layanan.

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]}"
        )

Menganalisis Dokumen Menggunakan Model Kustom

Analisis bidang dokumen, tabel, tanda pilihan, dan lainnya. Model-model ini dilatih dengan data Anda sendiri, sehingga disesuaikan dengan dokumen Anda. Untuk hasil terbaik, Anda hanya boleh menganalisis dokumen dengan jenis dokumen yang sama dengan yang dibangun dengan model kustom.

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("-----------------------------------")

Selain itu, URL dokumen juga dapat digunakan untuk menganalisis dokumen menggunakan begin_analyze_document metode .

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()

Kelola Model Anda

Kelola model kustom yang dilampirkan ke akun Anda.

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))

Kapabilitas Add-on

Kecerdasan Dokumen mendukung kemampuan analisis yang lebih canggih. Fitur opsional ini dapat diaktifkan dan dinonaktifkan tergantung pada skenario ekstraksi dokumen.

Kemampuan add-on berikut tersedia untuk rilis 2023-07-31 (GA) dan yang lebih baru:

Perhatikan bahwa beberapa kemampuan add-on akan dikenakan biaya tambahan. Lihat harga: https://azure.microsoft.com/pricing/details/ai-document-intelligence/.

Pemecahan Masalah

Umum

Pustaka klien Inteligensi Dokumen akan memunculkan pengecualian yang ditentukan di Azure Core. Kode kesalahan dan pesan yang diajukan oleh layanan Inteligensi Dokumen dapat ditemukan dalam dokumentasi layanan.

Pembuatan Log

Pustaka ini menggunakan pustaka pengelogan standar untuk pengelogan.

Informasi dasar tentang sesi HTTP (URL, header, dll.) dicatat pada INFO tingkat.

Pengelogan tingkat terperinci DEBUG , termasuk isi permintaan/respons dan header yang tidak diredaksikan , dapat diaktifkan pada klien atau per operasi dengan logging_enable argumen kata kunci.

Lihat dokumentasi pengelogan SDK lengkap dengan contoh di sini.

Konfigurasi Opsional

Argumen kata kunci opsional dapat diteruskan di tingkat klien dan per operasi. Dokumentasi referensi azure-core menjelaskan konfigurasi yang tersedia untuk percobaan ulang, pengelogan, protokol transportasi, dan banyak lagi.

Langkah berikutnya

Lebih banyak kode sampel

Lihat Sampel README untuk beberapa cuplikan kode yang mengilustrasikan pola umum yang digunakan dalam API Python Kecerdasan Dokumen.

Dokumentasi tambahan

Untuk dokumentasi yang lebih luas tentang Kecerdasan Dokumen Azure AI, lihat dokumentasi Kecerdasan Dokumen tentang docs.microsoft.com.

Berkontribusi

Proyek ini menyambut baik kontribusi dan saran. Sebagian besar kontribusi mengharuskan Anda menyetujui Perjanjian Lisensi Kontributor (CLA) yang menyatakan bahwa Anda memiliki hak untuk, dan benar-benar melakukannya, memberi kami hak untuk menggunakan kontribusi Anda. Untuk detailnya, kunjungi https://cla.microsoft.com.

Ketika Anda mengirimkan permintaan tarik, CLA-bot akan secara otomatis menentukan apakah Anda perlu memberikan CLA dan menghias PR dengan tepat (misalnya, label, komentar). Cukup ikuti instruksi yang diberikan oleh bot. Anda hanya perlu melakukan ini sekali di semua repos menggunakan CLA kami.

Proyek ini telah mengadopsi Kode Etik Sumber Terbuka Microsoft. Untuk informasi selengkapnya, lihat Tanya Jawab Umum Kode Etik atau kontak dengan pertanyaan atau komentar opencode@microsoft.com tambahan.