# Useful SDK Snippets

On this page are some ready-made snippets that you may use in their entirety or as a starting point in using the Ango SDK.

### End-to-end project preparation via SDK

This code snippet provides a step-by-step guide to programmatically preparing a new project using our SDK. It covers everything from project initialization to configuring settings, managing assets, and integrating workflows. Following the outlined procedures, users can create a fully functional project from scratch, enabling efficient setup and streamlined development processes.&#x20;

{% code lineNumbers="true" fullWidth="false" %}

```python
import os
import json
import random
from dotenv import load_dotenv
from imerit_ango.sdk import SDK
from imerit_ango.models.export_options import ExportOptions
from imerit_ango.models.invite import Invitation, ProjectAssignment
from imerit_ango.models.enums import OrganizationRoles, ProjectRoles
from imerit_ango.models.label_category import LabelOption, ClassificationCategory, Classification

# Organization Configurations
load_dotenv('variables.env')
api_key = os.getenv('API_KEY')

# Project Configurations
project_name = "Sample Text Classification Project"
project_description = "Created by end-to-end project preparation script"

labeler_email_list = ["user_1@sample.mail", "user_2@sample.mail"]
reviewer_email_list = ["user_3@sample.mail"]

# Initialize SDK
ango_sdk = SDK(api_key)
print("SDK initialized with API key.")

# Create Project
response = ango_sdk.create_project(name=project_name, description=project_description)
organization_id = response.get("data", {}).get("project", {}).get("organization")
project_id = response.get("data", {}).get("project", {}).get("_id")

print(f"Project '{project_name}' created successfully.")
print(f"Project ID: {project_id}, Organization ID: {organization_id}")

# Add Members to the Project
# Add Labelers
labeler_project_assignments = [ProjectAssignment(project_id=project_id, project_role=ProjectRoles.Labeler)]
labeler_invitation = Invitation(to=labeler_email_list, organization_role=OrganizationRoles.Member, project_assignments=labeler_project_assignments)
labeler_invite_response = ango_sdk.invite_members_to_org(organization_id=organization_id, invite_data=labeler_invitation)

# Add Reviewers
reviewer_project_assignments = [ProjectAssignment(project_id=project_id, project_role=ProjectRoles.Reviewer)]
reviewer_invitation = Invitation(to=reviewer_email_list, organization_role=OrganizationRoles.Member, project_assignments=reviewer_project_assignments)
reviewer_invite_response = ango_sdk.invite_members_to_org(organization_id=organization_id, invite_data=reviewer_invitation)

# The add_members_to_project function can also be used if the members are already part of the organization:
# ango_sdk.add_members_to_project(project_id=project_id, members=labeler_email_list, role=ProjectRoles.Labeler)
# ango_sdk.add_members_to_project(project_id=project_id, members=reviewer_email_list, role=ProjectRoles.Reviewer)

print(f"Added {len(labeler_email_list)} labelers to the project.")
print(f"Added {len(reviewer_email_list)} reviewers to the project.")

# Update Workflow Stages
start_stage = {"id": "Start",
               "type": "Start",
               "name": "Start",
               "next": ["Label"],
               "autoForward": False,
               "position": {"x": 0, "y": 0}}

label_stage = {"id": "Label",
               "type": "Label",
               "name": "Label",
               "next": ["Review"],
               "assignedTo": [],
               "position": {"x": 400, "y": 0}}

review_stage = {"id": "Review",
                "type": "Review",
                "name": "Review",
                "next": ["Complete", "Label"],
                "assignedTo": [],
                "position": {"x": 800, "y": 0}}

complete_stage = {"id": "Complete",
                  "type": "Complete",
                  "name": "Complete",
                  "next": [],
                  "position": {"x": 1200, "y": 0},
                  "preventRequeue": False}

stages = [start_stage, label_stage, review_stage, complete_stage]
sdk_response = ango_sdk.update_workflow_stages(project_id, stages)
print("Workflow stages updated successfully.")

# Create Category Schema
schema_id = "123456"
category = ClassificationCategory(classification=Classification.Single_dropdown,
                                  title="Choice",
                                  options=[LabelOption("First"), LabelOption("Second"), LabelOption("Third")],
                                  schemaId=schema_id,
                                  shortcutKey="1")

response = ango_sdk.create_label_set(project_id=project_id, classifications=[category])
print("Label set with classification category created successfully.")

# Create Batches
for index in range(3):
    batch_name = "Batch-" + str(index+1)
    ango_sdk.create_batch(project_id=project_id, batch_name=batch_name)
print("Batches created successfully.")

# Prepare Files for Upload
file_paths = []
external_id_list = []
for asset_index in range(30):
    external_id = str(asset_index + 1).zfill(5) + ".txt"
    content = "The quick brown fox jumps over the lazy dog."
    batch_name = "Batch-" + str(1 + asset_index // 10)

    external_id_list.append(external_id)
    file_paths.append({"data": content, "externalId": external_id, "batches": [batch_name]})

# Upload Files
ango_sdk.upload_files_cloud(project_id, file_paths)
print("Files uploaded successfully to the cloud.")

# Prepare Pre-labels
annotations = []
options = ["First", "Second", "Third"]
for external_id in external_id_list:
    answer = random.choice(options)
    annotation = {"externalId": external_id, "classifications": [{"schemaId": schema_id, "answer": answer}]}
    annotations.append(annotation)

# Import Pre-labels
ango_sdk.import_labels(project_id, annotations)
print("Pre-labels imported successfully.")

# Export Project
export_options = ExportOptions(stage=["Complete"])
export_response = ango_sdk.export(project_id=project_id, options=export_options)

# Save the export as a JSON file
with open('project_export.json', 'w') as file:
    json.dump(export_response, file, indent=4)
print("Export saved successfully.")
```

{% endcode %}

### Clone an Existing Project’s Category Schema and Workflow

This code snippet allows you to copy an existing project's category schema and workflow using the SDK. This functionality provides users to create a new project that retains the configuration and structure of a previously established project, facilitating consistency and saving time.&#x20;

{% code lineNumbers="true" fullWidth="false" %}

```python
import os
from dotenv import load_dotenv
from imerit_ango.sdk import SDK

load_dotenv('variables.env')

api_key = os.getenv('API_KEY')
project_id = os.getenv('PROJECT_ID')

ango_sdk = SDK(api_key)

# Get existing project's workflow and category schema
project_response = ango_sdk.get_project(project_id=project_id)

existing_project = project_response.get("data", {}).get("project", {})
copied_workflow = existing_project.get("stages", [])
copied_category_schema = existing_project.get("categorySchema", [])

# Create a new project and get its project ID
new_project_response = ango_sdk.create_project(name="New Project Name", description="New Project Description")
new_project_id = new_project_response.get("data", {}).get("project", {}).get("_id")

print("New Project ID:", new_project_id)

# Import copied category schema and workflow to the new project id
copied_category_response = ango_sdk.create_label_set(project_id=new_project_id, raw_category_schema=copied_category_schema)
copied_workflow_response = ango_sdk.update_workflow_stages(project_id=new_project_id, stages=copied_workflow)

print("Copied Category Schema Response:", copied_category_response.get("status"))
print("Copied Workflow Response:", copied_workflow_response.get("status"))

```

{% endcode %}

### Detect Duplicate External IDs in Your Project

This code snippet allows you to detect duplicate external IDs in your project using the SDK. This functionality enables users to identify data inconsistencies and maintain a clean, reliable dataset by highlighting assets with non-unique external IDs.

{% code lineNumbers="true" fullWidth="false" %}

```python
import os
from dotenv import load_dotenv
from collections import Counter
from imerit_ango.sdk import SDK

load_dotenv('variables.env')

api_key = os.getenv('API_KEY')
project_id = os.getenv('PROJECT_ID')

ango_sdk = SDK(api_key)

page = 1
num_tasks = 1
task_list = []
while len(task_list) < num_tasks:
    response = ango_sdk.get_tasks(project_id=project_id, include_answer=False, page=page, limit=50, fields="externalId")
    tasks = response.get('data', {}).get('tasks', [])
    num_tasks = response.get('data', {}).get('total', 0)

    task_list.extend(tasks)
    page += 1

print(str(len(task_list)) + " tasks were retrieved.")

external_id_list = []
for asset in task_list:
    external_id_list.append(asset['externalId'])

duplicates = [item for item, count in Counter(external_id_list).items() if count > 1]

if len(duplicates) == 0:
    print("No duplicate assets were found.")
else:
    print(str(len(duplicates)) + " duplicate assets were found.")
    print("Duplicate assets: ")
    for duplicate_asset in duplicates:
        print(duplicate_asset)
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.imerit.net/sdk/useful-sdk-snippets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
