nanonets
Version:
Node.js SDK for the Nanonets API: OCR, document extraction, and workflow automation.
449 lines (411 loc) • 11.5 kB
JavaScript
// Nanonets Node.js SDK
// Minimum Node.js version: 14.0.0 (for async/await and optional chaining support)
// Mirrors the Go SDK structure and methods
const axios = require('axios');
class NanonetsClient {
constructor(apiKey, baseURL = 'https://app.nanonets.com/api/v4') {
this.apiKey = apiKey;
this.baseURL = baseURL;
this.client = axios.create({
baseURL,
auth: {
username: apiKey,
password: ''
}
});
// Initialize namespaces
this.workflows = new Workflows(this);
this.documents = new Documents(this);
this.moderation = new Moderation(this);
}
// Helper methods
_handleError(error) {
if (error.response) {
throw new Error(`API Error: ${error.response.status} - ${JSON.stringify(error.response.data)}`);
}
throw error;
}
}
class Workflows {
constructor(client) {
this.client = client;
}
async list() {
try {
const response = await this.client.client.get('/workflows');
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async get(workflowID) {
try {
const response = await this.client.client.get(`/workflows/${workflowID}`);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async getTypes() {
try {
const response = await this.client.client.get('/workflow_types');
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async create({ description, workflow_type }) {
try {
const response = await this.client.client.post('/workflows', {
description,
workflow_type
});
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async setFields(workflowID, { fields, table_headers }) {
try {
const response = await this.client.client.put(`/workflows/${workflowID}/fields`, {
fields,
table_headers
});
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async updateField(workflowID, fieldID, { name }) {
try {
const response = await this.client.client.patch(`/workflows/${workflowID}/fields/${fieldID}`, {
name
});
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async deleteField(workflowID, fieldID) {
try {
const response = await this.client.client.delete(`/workflows/${workflowID}/fields/${fieldID}`);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async updateMetadata(workflowID, { description }) {
try {
const response = await this.client.client.patch(`/workflows/${workflowID}`, {
description
});
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async updateSettings(workflowID, { table_capture }) {
try {
const response = await this.client.client.patch(`/workflows/${workflowID}/settings`, {
table_capture
});
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
}
class Documents {
constructor(client) {
this.client = client;
}
async upload(workflowID, { file, url, async, metadata }) {
const FormData = require('form-data');
const fs = require('fs');
const form = new FormData();
if (file) {
form.append('file', fs.createReadStream(file));
} else if (url) {
form.append('url', url);
} else {
throw new Error('Either file or url must be provided');
}
form.append('async', String(Boolean(async)));
if (metadata) {
Object.keys(metadata).forEach(key => {
form.append(key, metadata[key]);
});
}
try {
const axios = require('axios');
const response = await axios.post(
`${this.client.baseURL}/workflows/${workflowID}/documents`,
form,
{
auth: {
username: this.client.apiKey,
password: ''
},
headers: form.getHeaders()
}
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async get(workflowID, documentID) {
try {
const response = await this.client.client.get(`/workflows/${workflowID}/documents/${documentID}`);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async list(workflowID, { page = 1, limit = 10 }) {
try {
const response = await this.client.client.get(`/workflows/${workflowID}/documents`, {
params: { page, limit }
});
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async delete(workflowID, documentID) {
try {
const response = await this.client.client.delete(`/workflows/${workflowID}/documents/${documentID}`);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async getFields(workflowID, documentID) {
try {
const response = await this.client.client.get(`/workflows/${workflowID}/documents/${documentID}/fields`);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async getTables(workflowID, documentID) {
try {
const response = await this.client.client.get(`/workflows/${workflowID}/documents/${documentID}/tables`);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async getOriginalFile(workflowID, documentID) {
try {
const response = await this.client.client.get(`/workflows/${workflowID}/documents/${documentID}/original`, {
responseType: 'arraybuffer'
});
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
}
class Moderation {
constructor(client) {
this.client = client;
}
async updateField(workflowID, documentID, pageID, { field_data_id, value }) {
try {
const response = await this.client.client.patch(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/fields/${field_data_id}`,
{ value }
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async addField(workflowID, documentID, pageID, {
field_name,
value,
bbox,
confidence,
verification_status,
verification_message
}) {
try {
const response = await this.client.client.post(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/fields`,
{
field_name,
value,
bbox,
confidence,
verification_status,
verification_message
}
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async deleteField(workflowID, documentID, pageID, fieldDataID) {
try {
const response = await this.client.client.delete(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/fields/${fieldDataID}`
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async addTable(workflowID, documentID, pageID, {
bbox,
headers,
verification_status,
verification_message,
cells
}) {
try {
const response = await this.client.client.post(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/tables`,
{
bbox,
headers,
verification_status,
verification_message,
cells
}
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async deleteTable(workflowID, documentID, pageID, tableID) {
try {
const response = await this.client.client.delete(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/tables/${tableID}`
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async updateTableCell(workflowID, documentID, pageID, tableID, cellID, { value }) {
try {
const response = await this.client.client.patch(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/tables/${tableID}/cells/${cellID}`,
{ value }
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async addTableCell(workflowID, documentID, pageID, tableID, {
row,
col,
header,
text,
bbox,
verification_status,
verification_message
}) {
try {
const response = await this.client.client.post(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/tables/${tableID}/cells`,
{
row,
col,
header,
text,
bbox,
verification_status,
verification_message
}
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async deleteTableCell(workflowID, documentID, pageID, tableID, cellID) {
try {
const response = await this.client.client.delete(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/tables/${tableID}/cells/${cellID}`
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async verifyField(workflowID, documentID, pageID, fieldDataID, {
verification_status,
verification_message
}) {
try {
const response = await this.client.client.post(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/fields/${fieldDataID}/verify`,
{
verification_status,
verification_message
}
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async verifyTableCell(workflowID, documentID, pageID, tableID, cellID, {
verification_status,
verification_message
}) {
try {
const response = await this.client.client.post(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/tables/${tableID}/cells/${cellID}/verify`,
{
verification_status,
verification_message
}
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async verifyTable(workflowID, documentID, pageID, tableID, {
verification_status,
verification_message
}) {
try {
const response = await this.client.client.post(
`/workflows/${workflowID}/documents/${documentID}/pages/${pageID}/tables/${tableID}/verify`,
{
verification_status,
verification_message
}
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
async verifyDocument(workflowID, documentID, {
verification_status,
verification_message
}) {
try {
const response = await this.client.client.post(
`/workflows/${workflowID}/documents/${documentID}/verify`,
{
verification_status,
verification_message
}
);
return response.data;
} catch (error) {
this.client._handleError(error);
}
}
}
module.exports = NanonetsClient;
module.exports.default = NanonetsClient;