আমি 2021 সালে প্রথম Diffbot আবিষ্কার করেছি যখন আমি Adobe ডেভেলপার ব্লগের জন্য তাদের API-এর একটি ডেমো তৈরি করেছিলাম ( "Natural Language Processing, Adobe PDF Extract, and Deep PDF Intelligence" )।
সেই সময়ে, ডিফবটের API কতটা সহজ ছিল এবং এটি কত দ্রুত সাড়া দিয়েছিল তাতে আমি মুগ্ধ হয়েছিলাম। আমি কিছুক্ষণের মধ্যে তাদের API এর দিকে তাকাইনি, কিন্তু কিছু দিন আগে, তারা পাঠ্যের সংক্ষিপ্তসারের জন্য নতুন সমর্থন ঘোষণা করেছে। আমি ভেবেছিলাম এটি Adobe PDF Extract API এর সাথে একত্রিত করা একটি দুর্দান্ত জিনিস হবে। এখানে আমি কি খুঁজে পেয়েছি.
প্রথমত, আপনি যদি এটি নিজে চেষ্টা করতে চান তবে আপনার প্রয়োজন হবে:
ঠিক আছে, আসুন দেখি কিভাবে একটি সারাংশ ফ্লো কাজ করতে পারে।
Extract API (দুঃখিত, "Adobe PDF Extract API", অপেক্ষা করুন, এটি আমার ব্লগ, আমি জিনিস ছোট করতে পারি!) বেশ শক্তিশালী। নথিতে প্রতিটি উপাদানের বিশদ সঠিকভাবে খুঁজে পেতে এটি বুদ্ধিমত্তার সাথে একটি PDF পার্স করতে AI ব্যবহার করে।
তাই টেক্সট, ফন্ট, রং, অবস্থান, এবং তাই ঘোষণা. এটি ইমেজ এবং ট্যাবুলার ডেটাও খুঁজে পেতে পারে যা কিছু চমত্কার শক্তিশালী ব্যবহারের ক্ষেত্রে নিয়ে যায়। (এর একটি ভালো উদাহরণের জন্য, আমার ব্লগ পোস্টটি দেখুন যেখানে আমি জ্যোতির্বিদ্যা সংক্রান্ত তথ্য সংগ্রহ এবং একত্রিত করতে এবং প্রতিবেদন তৈরি করতে একাধিক বৈজ্ঞানিক জার্নাল স্ক্যান করি।)
এই ডেমো জন্য, আমরা আক্ষরিক শুধু পাঠ্য প্রয়োজন. এর জন্য, আমি REST API ব্যবহার করব। উপলব্ধ পিডিএফ পরিষেবাগুলির প্রায় সমস্ত দিকগুলির জন্য "প্রবাহ" হল:
মনে রাখবেন যে আপনি ব্যবহার করতে পারেন এমন SDKও আছে, কিন্তু আমি আমাদের REST APIগুলিকে এত সহজ পেয়েছি যে আমি সরাসরি শেষ পয়েন্টগুলিতে আঘাত করি। এক্সট্রাক্ট প্রক্রিয়াটি করতে আমি যে স্ক্রিপ্টটি লিখেছি তা এখানে। এটি মূলত সবকিছুই যা আমি উপরে বলেছি এবং আমার স্থানীয় ফাইল সিস্টেমের একটি উত্স পিডিএফের দিকে নির্দেশ করছি।
/* This demo is a two step process. This file, step one, handles extracting and storing the JSON from a PDF. */ import 'dotenv/config'; import fs from 'fs'; import { Readable } from 'stream'; import { finished } from 'stream/promises'; const SOURCE_PDF = '../../source_pdfs/boring_adobe_security_doc.pdf'; const REST_API = "https://pdf-services.adobe.io/"; const CLIENT_ID = process.env.CLIENT_ID; const CLIENT_SECRET = process.env.CLIENT_SECRET; async function delay(x) { return new Promise(resolve => { setTimeout(() => resolve(), x); }); } async function getAccessToken(id, secret) { const params = new URLSearchParams(); params.append('client_id', id); params.append('client_secret', secret); let resp = await fetch('https://pdf-services-ue1.adobe.io/token', { method: 'POST', headers: { 'Content-Type':'application/x-www-form-urlencoded' }, body:params }); let data = await resp.json(); return data.access_token; } async function getUploadData(mediaType, token, clientId) { let body = { 'mediaType': mediaType }; body = JSON.stringify(body); let req = await fetch(REST_API+'assets', { method:'post', headers: { 'X-API-Key':clientId, 'Authorization':`Bearer ${token}`, 'Content-Type':'application/json' }, body: body }); let data = await req.json(); return data; } async function uploadFile(url, filePath, mediaType) { let stream = fs.createReadStream(filePath); let stats = fs.statSync(filePath); let fileSizeInBytes = stats.size; let upload = await fetch(url, { method:'PUT', redirect:'follow', headers: { 'Content-Type':mediaType, 'Content-Length':fileSizeInBytes }, duplex:'half', body:stream }); if(upload.status === 200) return; else { throw('Bad result, handle later.'); } } async function pollJob(url, token, clientId) { let status = null; let asset; while(status !== 'done') { let req = await fetch(url, { method:'GET', headers: { 'X-API-Key':clientId, 'Authorization':`Bearer ${token}`, } }); let res = await req.json(); status = res.status; if(status === 'done') { asset = res; } else { await delay(2000); } } return asset; } async function downloadFile(url, filePath) { let res = await fetch(url); const body = Readable.fromWeb(res.body); const download_write_stream = fs.createWriteStream(filePath); return await finished(body.pipe(download_write_stream)); } async function extractJob(asset, token, clientId) { let body = { 'assetID': asset.assetID } let resp = await fetch(REST_API + 'operation/extractpdf', { method: 'POST', headers: { 'Authorization':`Bearer ${token}`, 'X-API-KEY':clientId, 'Content-Type':'application/json' }, body:JSON.stringify(body) }); return resp.headers.get('location'); } let accessToken = await getAccessToken(CLIENT_ID, CLIENT_SECRET); console.log('Got our access token.'); let uploadedAsset = await getUploadData('application/pdf', accessToken, CLIENT_ID); await uploadFile(uploadedAsset.uploadUri, SOURCE_PDF, 'application/pdf'); console.log('Source PDF Uploaded.'); let job = await extractJob(uploadedAsset, accessToken, CLIENT_ID); console.log('Job created. Now to poll it.'); let result = await pollJob(job, accessToken, CLIENT_ID); console.log('Job is done.'); await downloadFile(result.content.downloadUri, 'extract.json'); console.log('All done.');
ঠিক আছে, আশা করি, আপনি এখনও পড়ছেন। সাধারণভাবে, আমি এইরকম কোডের বিশাল ব্লক পোস্ট করা এড়াতে চেষ্টা করি, কিন্তু আপনি যদি শেষের লাইনগুলিতে ফোকাস করেন, আপনি দেখতে পাবেন যে আমি কেবলমাত্র ইউটিলিটি ফাংশনগুলিকে আঘাত করছি যা আমি উপরের প্রবাহে যা বর্ণনা করেছি। প্রমাণীকরণ করুন, একটি পিডিএফ আপলোড করতে বলুন, একটি কাজ শুরু করুন, এটি পরীক্ষা করুন এবং ফলাফল ডাউনলোড করুন।
একটি নোট আমি যোগ করব. নিষ্কাশন একটি JSON ফলাফল সেট ধারণকারী একটি জিপ ফাইল প্রদান করে, এবং ঐচ্ছিকভাবে, টেবিল এবং ছবি। REST API সম্পর্কে একটি চমৎকার জিনিস হল যে আমি সরাসরি JSON-এ যেতে পারি এবং এটি সংরক্ষণ করতে পারি।
JSON ফলাফল বেশ বিশাল হতে পারে। তিন পৃষ্ঠার আমার সোর্স পিডিএফ (একটি অবিশ্বাস্যভাবে বিরক্তিকর Adobe নিরাপত্তা নথি) এর জন্য, ফলস্বরূপ JSON 4560 লাইন দীর্ঘ। আপনি এখানে আমার সোর্স পিডিএফ এবং এক্সট্র্যাক্ট থেকে কাঁচা আউটপুট এখানে খুঁজে পেতে পারেন।
এখানে সমস্ত 4.5k লাইন রাখার পরিবর্তে, আমাকে একটি স্নিপেট দেখান - API দ্বারা পাওয়া দুটি অনন্য উপাদান:
{ "Bounds": [ 44.62139892578125, 756.9429931640625, 245.0037841796875, 766.3184967041016 ], "Font": { "alt_family_name": "* Arial", "embedded": true, "encoding": "Identity-H", "family_name": "* Arial", "font_type": "CIDFontType0", "italic": false, "monospaced": false, "name": "*Arial-6539", "subset": false, "weight": 400 }, "HasClip": false, "Lang": "en", "Page": 0, "Path": "//Document/Sect/P", "Text": "Adobe Vendor Security Review Program White Paper ", "TextSize": 8.5, "attributes": { "SpaceAfter": 18 } }, { "Bounds": [ 0.0, 0.0, 630.0, 820.7799987792969 ], "ClipBounds": [ 548.72802734375, 739.1929931640625, 602.5444488525391, 820.7799987792969 ], "Page": 0, "Path": "//Document/Sect/Figure", "attributes": { "BBox": [ 548.9779999999737, 739.4429999999993, 587.61599999998, 790.920999999973 ], "Placement": "Block" } },
উপরের নমুনায়, আপনি দেখতে পাচ্ছেন প্রথম উপাদানটি পাঠ্য এবং এতে একটি Text
বৈশিষ্ট্য রয়েছে, যখন দ্বিতীয়টি একটি চিত্র। আমার ডেমোর জন্য, আমাকে Text
সম্পত্তি ব্যবহার করতে হবে যখন এটি বিদ্যমান থাকে। চলুন এটি কর্মে দেখা যাক।
আমি আগে উল্লেখ করেছি যে Diffbot API ব্যবহার করা মোটামুটি সহজ ছিল। আমাকে যে প্রদর্শন করা যাক.
প্রথমে, আমি কিছু ভেরিয়েবল সেট আপ করব এবং JSON-এ পড়ব যা আমি প্রথম ধাপ থেকে পেয়েছি। স্পষ্ট করে বলতে গেলে, আমি এক প্রক্রিয়ায় সবকিছু করতে পারতাম, কিন্তু এক্সট্রাক্ট একবারের বেশি চালানোর সত্যিই কোন মানে নেই। চমৎকার কি - আমি আসলে ফলাফলে একাধিক কল করতে পারি।
উদাহরণ হিসাবে, ডিফবটের আরেকটি দুর্দান্ত বৈশিষ্ট্য হল পাঠ্য থেকে সত্তা পাওয়া, অর্থাৎ, একটি নথি কী সম্পর্কে কথা বলছে (মানুষ, স্থান, ইত্যাদি)। যাইহোক, এখানে শুরু:
/* In this file, we take the result from our Extract operation and pass it to Diffbot */ import 'dotenv/config'; import fs from 'fs'; const DIFFBOT_KEY = process.env.DIFFBOT_KEY; const SOURCE_JSON = './extract.json'; const data = JSON.parse(fs.readFileSync(SOURCE_JSON, 'utf8')); console.log(`Read in source data from ${SOURCE_JSON}.`);
এর পরে, আমাকে এক্সট্রাক্ট ফলাফল থেকে পাঠ্যটি বিশ্লেষণ করতে হবে:
let text = data.elements.reduce((text, el) => { if(el.Text) text += el.Text + '\n'; return text; },'');
এর পরে, আমি ডিফবটকে একটি HTTP অনুরোধ তৈরি করি। আরো তথ্যের জন্য তাদের ডক্স চেক করুন.
let fields = 'summary'; let url = `https://nl.diffbot.com/v1/?fields=${fields}&token=${DIFFBOT_KEY}`; let body = [{ content:text, lang:'en', format:'plain text' }]; console.log('Passing text to Diffbot.'); let req = await fetch(url, { method:'POST', body:JSON.stringify(body), headers: { 'Content-Type':'application/json' } }); let result = await req.json();
এবং এটাই. একটি চূড়ান্ত পদক্ষেপ হিসাবে, আমি কেবল এটি আউটপুট:
console.log(`Summary of PDF:\n${result[0].summary}`);
উত্স পিডিএফ দেওয়া, চূড়ান্ত ফলাফল হল:
Adobe has a vendor security review program that evaluates vendors that collect, store, process, transmit, or dispose of Adobe data outside of Adobe-controlled physical offices or data center locations. The VSR program includes requirements for vendors to follow when handling sensitive data and assigns a risk level score to vendors based on their compliance with Adobe standards. If a vendor fails the VSR program, Adobe holds discussions with the business owner to understand the details of the vendor's security practices and determine whether or not to continue working with them.
আমার তিন পৃষ্ঠার পিডিএফ এখন একটি সহজ অনুচ্ছেদ। লক্ষ লক্ষ নথি সহ সংস্থাগুলির জন্য এটি কতটা কার্যকর হবে তা আপনি কল্পনা করতে পারেন৷ এটিকে অন্যান্য পরিষেবাগুলির সাথে একত্রিত করুন (যেমন সত্তা বৈশিষ্ট্যগুলি আমি আগে উল্লেখ করেছি), এবং এটি বড় লাইব্রেরির সাথে কাজ করা আরও সহজ করে তোলে।
আপনি যদি এটি নিজেই পরীক্ষা করতে চান তবে আপনি এখানে সমস্ত কোড ধরতে পারেন: https://github.com/cfjedimaster/document-services-demos/tree/main/random_demos/extract_diffbot_summary । আমি বলেছি, এখানে সবকিছু বিনামূল্যে পরীক্ষা করা যেতে পারে, তাই এটি একটি শট দিন, এবং নীচের একটি মন্তব্যে আপনি কি মনে করেন তা আমাকে জানান।