Docs

SDK Examples

This comprehensive guide demonstrates how to effectively use the Sentor JavaScript SDK.

Installation

# Using npm
npm install sentor-sdk

Usage

import { SentorClient } from 'sentor-sdk';

// Initialize the client
const client = new SentorClient('your-api-key');

// Analyze sentiment
const input = 
{
  "docs": [
    {
      "doc": "In the competitive landscape of consumer electronics, Apple and Samsung continue to lead the market with innovative products and strong brand loyalty. While Apple focuses on a tightly integrated ecosystem with devices like the iPhone, iPad, and Mac, Samsung excels in offering a wide range of options across various price points, especially in its Galaxy smartphone lineup. Both companies push the boundaries of technology, from cutting-edge chipsets to advanced camera systems, often setting industry trends that others follow.",
      "doc_id": "0",
      "entities": [
        "Apple",
        "Samsung",
        "camera"
      ]
    },
    {
      "doc": "Apple's new iPhone is amazing!",
      "doc_id": "1",
      "entities": [
        "Apple",
        "iPhone"
      ]
    },
    {
      "doc": "Samsung's new phone is amazing!",
      "doc_id": "2",
      "entities": [
        "Samsung",
        "phone"
      ]
    }
  ]
}
const result = await client.predict(input);
console.log(result);

Sample Output

{
  "results": [
    {
      "doc_id": "0",
      "predicted_class": 2,
      "predicted_label": "positive",
      "probabilities": {
        "negative": 0.00007679959526285529,
        "neutral": 0.0002924697764683515,
        "positive": 0.9996306896209717
      },
      "details": [
        {
          "sentence_index": 0,
          "sentence_text": "In the competitive landscape of consumer electronics, Apple and Samsung continue to lead the market with innovative products and strong brand loyalty.",
          "predicted_class": 2,
          "predicted_label": "positive",
          "probabilities": {
            "negative": 0.00009389198385179043,
            "neutral": 0.00032428017584607005,
            "positive": 0.9995818734169006
          }
        },
        {
          "sentence_index": 1,
          "sentence_text": "While Apple focuses on a tightly integrated ecosystem with devices like the iPhone, iPad, and Mac, Samsung excels in offering a wide range of options across various price points, especially in its Galaxy smartphone lineup.",
          "predicted_class": 2,
          "predicted_label": "positive",
          "probabilities": {
            "negative": 0.00005746580063714646,
            "neutral": 0.00012963586777914315,
            "positive": 0.99981290102005
          }
        },
        {
          "sentence_index": 2,
          "sentence_text": "Both companies push the boundaries of technology, from cutting-edge chipsets to advanced camera systems, often setting industry trends that others follow.",
          "predicted_class": 2,
          "predicted_label": "positive",
          "probabilities": {
            "negative": 0.00006366783054545522,
            "neutral": 0.00044553453335538507,
            "positive": 0.9994907379150391
          }
        }
      ]
    },
    {
      "doc_id": "1",
      "predicted_class": 2,
      "predicted_label": "positive",
      "probabilities": {
        "negative": 0.00010637375817168504,
        "neutral": 0.0002509312762413174,
        "positive": 0.9996427297592163
      },
      "details": [
        {
          "sentence_index": 0,
          "sentence_text": "Apple's new iPhone is amazing!",
          "predicted_class": 2,
          "predicted_label": "positive",
          "probabilities": {
            "negative": 0.00010637375817168504,
            "neutral": 0.0002509312762413174,
            "positive": 0.9996427297592163
          }
        }
      ]
    },
    {
      "doc_id": "2",
      "predicted_class": 2,
      "predicted_label": "positive",
      "probabilities": {
        "negative": 0.00010637375817168504,
        "neutral": 0.0002509312762413174,
        "positive": 0.9996427297592163
      },
      "details": [
        {
          "sentence_index": 0,
          "sentence_text": "Samsung's new phone is amazing!",
          "predicted_class": 2,
          "predicted_label": "positive",
          "probabilities": {
            "negative": 0.00010637375817168504,
            "neutral": 0.0002509312762413174,
            "positive": 0.9996427297592163
          }
        }
      ]
    }
  ]
}

Clustering Documents

import { SentorClient } from 'sentor-sdk';

const client = new SentorClient('your-api-key');

// Prepare documents for clustering
const documents = [
  {
    doc_id: "doc1",
    text: "Apple announced new iPhone features with improved camera.",
    entities: ["Apple", "iPhone", "camera"]
  },
  {
    doc_id: "doc2",
    text: "Samsung launched Galaxy with advanced AI capabilities.",
    entities: ["Samsung", "Galaxy", "AI"]
  },
  {
    doc_id: "doc3",
    text: "Apple plans to integrate AI into iOS ecosystem.",
    entities: ["Apple", "AI", "iOS"]
  },
  {
    doc_id: "doc4",
    text: "SpaceX successfully launched Starlink satellites.",
    entities: ["SpaceX", "Starlink", "satellites"]
  },
  {
    doc_id: "doc5",
    text: "Bitcoin price surged after ETF approval.",
    entities: ["Bitcoin", "ETF"]
  }
];

// Cluster documents
const clusteringResult = await client.cluster({ documents }, 'en');

console.log(`Total clusters: ${clusteringResult.total_clusters}`);
console.log(`Outliers: ${clusteringResult.outliers}`);

clusteringResult.clusters.forEach(cluster => {
  console.log(`\nCluster ${cluster.cluster_id}:`);
  console.log(`  Documents: ${cluster.documents.length}`);
  console.log(`  Top words: ${cluster.top_words.slice(0, 5).join(', ')}`);
  console.log(`  Entities: ${cluster.entities.slice(0, 5).join(', ')}`);
});

Generating Topic Names

import { SentorClient } from 'sentor-sdk';

const client = new SentorClient('your-api-key');

// After clustering, generate topic names for each cluster
const clusteringResult = await client.cluster({ documents }, 'en');

// Process all clusters in parallel
const topicPromises = clusteringResult.clusters.map(cluster =>
  client.generateTopicName({
    cluster_id: cluster.cluster_id,
    documents: cluster.documents,
    entities: cluster.entities,
    top_words: cluster.top_words
  }, 'en')
);

const topicResults = await Promise.all(topicPromises);

topicResults.forEach(topic => {
  console.log(`Cluster ${topic.cluster_id}: ${topic.topic_name}`);
});

Complete Workflow Example

import { SentorClient } from 'sentor-sdk';

const client = new SentorClient('your-api-key');

// Step 1: Analyze sentiment
const inputData = {
  docs: [
    {
      doc: "Apple's new iPhone camera is incredible, but battery life is disappointing.",
      doc_id: "review1",
      entities: ["Apple", "iPhone", "camera", "battery life"]
    },
    {
      doc: "Samsung Galaxy has amazing features and great performance.",
      doc_id: "review2",
      entities: ["Samsung", "Galaxy", "features", "performance"]
    }
    // ... more reviews
  ]
};

const sentimentResults = await client.predict(inputData);

// Step 2: Extract documents for clustering
const clusterDocuments = sentimentResults.results.map((result, index) => ({
  doc_id: result.doc_id,
  text: inputData.docs[index].doc,
  entities: inputData.docs[index].entities
}));

// Step 3: Cluster documents (if enough documents)
if (clusterDocuments.length >= 5) {
  const clusteringResult = await client.cluster({ documents: clusterDocuments });
  
  // Step 4: Generate topic names in parallel
  const topicResults = await Promise.all(
    clusteringResult.clusters.map(cluster =>
      client.generateTopicName({
        cluster_id: cluster.cluster_id,
        documents: cluster.documents,
        entities: cluster.entities,
        top_words: cluster.top_words
      })
    )
  );
  
  // Display results
  topicResults.forEach((topic, index) => {
    const cluster = clusteringResult.clusters[index];
    console.log(`\n=== ${topic.topic_name} ===`);
    console.log(`Documents in cluster: ${cluster.documents.length}`);
    
    // Calculate sentiment distribution
    const sentiments = { positive: 0, neutral: 0, negative: 0 };
    cluster.documents.forEach(doc => {
      const sentimentData = sentimentResults.results.find(
        r => r.doc_id === doc.doc_id
      );
      if (sentimentData) {
        sentiments[sentimentData.predicted_label]++;
      }
    });
    
    console.log(`Sentiment distribution:`, sentiments);
  });
}

Error Handling with TypeScript

import { SentorClient, SentorAPIError, RateLimitError } from 'sentor-sdk';

const client = new SentorClient('your-api-key');

async function analyzeWithRetry(data: any, maxRetries = 3): Promise<any> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await client.predict(data);
    } catch (error) {
      if (error instanceof RateLimitError && attempt < maxRetries - 1) {
        console.log(`Rate limit hit. Waiting ${error.retryAfter} seconds...`);
        await new Promise(resolve => 
          setTimeout(resolve, error.retryAfter * 1000)
        );
      } else if (error instanceof SentorAPIError) {
        console.error(`API Error ${error.code}: ${error.message}`);
        throw error;
      } else {
        throw error;
      }
    }
  }
  throw new Error('Max retries exceeded');
}

// Use it
try {
  const result = await analyzeWithRetry(yourData);
  console.log(result);
} catch (error) {
  console.error('Failed to analyze:', error);
}

React/Next.js Integration Example

'use client';

import { useState } from 'react';
import { SentorClient } from 'sentor-sdk';

export default function SentimentAnalyzer() {
  const [result, setResult] = useState(null);
  const [loading, setLoading] = useState(false);

  const analyzeSentiment = async (text: string, entities: string[]) => {
    setLoading(true);
    try {
      const client = new SentorClient(process.env.NEXT_PUBLIC_SENTOR_API_KEY!);
      const response = await client.predict({
        docs: [{
          doc: text,
          doc_id: crypto.randomUUID(),
          entities
        }]
      });
      setResult(response.results[0]);
    } catch (error) {
      console.error('Analysis failed:', error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      {/* Your UI components */}
      {result && (
        <div>
          <p>Sentiment: {result.predicted_label}</p>
          <p>Confidence: {(result.probabilities[result.predicted_label] * 100).toFixed(1)}%</p>
        </div>
      )}
    </div>
  );
}

For more examples and detailed documentation, please refer to: