ATP - استخراج زمینه اختراع از فایل متنی (POST /api/v1/extract)
Endpoint
POST /api/v1/extract
هدف آزمون
استخراج ساختیافته InventionContext از افشای اختراع بهصورت فایل .txt.
شرایط آزمون
- سرویس ai-workflow در حال اجرا باشد
- کلید LLM (AVALAI_API_KEY یا OPENAI_API_KEY) تنظیم شده باشد
- فایل نمونه UTF-8 با پسوند .txt آماده باشد
فرآیند آزمون
- آمادهسازی فایل disclosure.txt
- ارسال POST multipart با فیلد file
- دریافت ExtractResponse
- بررسی context، missing_questions و metrics
معرفی ویژگی
endpoint HTTP برای استخراج موازی بخشهای A–F و تبدیل به InventionContext. ورودی فقط متن ساده است؛ پردازش PDF/DOCX در سرویس info-extraction انجام میشود.
- فرمت ورودی: فقط .txt با encoding UTF-8
- حداکثر حجم: محدود به API_MAX_UPLOAD_MB (پیشفرض ۵MB)
- خروجی: context JSON، missing_questions، metrics
- case_id اختیاری: query parameter برای شناسه پرونده
- Worker async: رویداد ContextExtractionRequested با schema_version 2؛ نیازمند workspace_id و command_generation
- شکاف outstanding: gaps با severity برابر BLOCKING یا HIGH مانع completed میشوند و questions_required منتشر میشود (MEDIUM/LOW کافی نیستند)
- completeness_summary: شامل blocking_gap_count و outstanding_gap_count؛ پس از max rounds با forced_complete_after_max_rounds تکمیل اجباری میشود
- دفاع artifact key: کلیدهای input/prior_snapshot باید زیر workspaces/{workspace_id}/ باشند؛ traversal و absolute path رد میشوند
سناریوی آزمون
سناریو 1: استخراج موفق فایل txt
- آمادهسازی فایل disclosure.txt با متن فارسی/انگلیسی
- ارسال POST به
/api/v1/extractبا multipart file - دریافت کد 200
- بررسی وجود فیلد context و profile
سناریو 2: خطا — پسوند نامعتبر
- آپلود فایل با پسوند .pdf
- ارسال POST
- دریافت کد 415 با پیام Only .txt files are supported
سناریو 3: Worker — کلید artifact نامعتبر
- انتشار ContextExtractionRequested با input_artifact_keys حاوی
../evil.txt - عدم فراخوانی storage.get_object_text
- دریافت context.extraction.failed با error_code=INVALID_ARTIFACT_KEY
- error_category=validation و retryable=false
سناریو 4: Worker — کلید artifact خارج از workspace
- انتشار رویداد با workspace_id=W و کلید زیر workspaces/{other}/...
- دریافت failed با error_code=INVALID_ARTIFACT_KEY
- عدم دسترسی به object خارج از tenancy
سناریو 5: Worker — questions_required برای gap با severity=HIGH
- اجرای extraction با missing_questions شامل فقط gap با severity=HIGH
- انتشار context.extraction.questions_required (نه completed)
- بررسی snapshot.readiness_state برابر questions_required
- بررسی completeness_summary.outstanding_gap_count >= 1 و blocking_gap_count=0
- بررسی question_round.questions[].severity برابر recommended
سناریو 6: Worker — تکمیل اجباری پس از حداکثر دور سؤال
- وجود outstanding gaps پس از رسیدن به max question rounds
- انتشار context.extraction.completed با force_ready
- بررسی completeness_summary.forced_complete_after_max_rounds=true
- بررسی unresolved_gap_count برابر تعداد outstanding باقیمانده
سناریو 7: استخراج موفق همراه case_id
- آمادهسازی فایل UTF-8 معتبر
- ارسال درخواست با query برابر
case_id=case-001 - دریافت کد 200
- بررسی انتساب شناسه پرونده در خروجی context یا case_record
سناریو 8: خطا — فایل خالی
- ساخت فایل empty.txt با محتوای خالی یا فقط whitespace
- ارسال فایل به endpoint
- دریافت کد 400
- بررسی پیام
Uploaded file is empty.
سناریو 9: خطا — متن UTF-8 نامعتبر
- ساخت فایل .txt شامل بایتهای نامعتبر UTF-8
- ارسال فایل به endpoint
- دریافت کد 400
- بررسی پیام
File must be valid UTF-8 text.
سناریو 10: خطا — حجم بیش از حد مجاز
- تنظیم مقدار مشخص برای
API_MAX_UPLOAD_MB - ساخت فایل بزرگتر از محدودیت
- ارسال فایل به endpoint
- دریافت کد 413 و اشاره پیام به محدودیت حجم
سناریو 11: خطا — فایل ارسال نشده
- ارسال POST بدون بخش multipart با نام file
- دریافت کد 422
- بررسی خطای validation مربوط به فیلد file
سناریو 12: خطا — کلید LLM تنظیم نشده
- حذف کلید فعال متناسب با LLM_PROVIDER
- ارسال فایل txt معتبر
- دریافت کد 503
- بررسی اشاره پیام به AVALAI_API_KEY یا OPENAI_API_KEY
سناریو 13: خطا — شکست pipeline استخراج
- شبیهسازی خطای داخلی ExtractionError در pipeline
- ارسال فایل txt معتبر
- دریافت کد 500
- بررسی ثبت خطا و عدم بازگشت context ناقص
قالب API
| مولفه | نوع | نوع داده | اجباری | توضیحات |
|---|---|---|---|---|
| file | Body | file | بله | فایل افشا؛ multipart/form-data؛ فقط .txt |
| case_id | Query | string | خیر | شناسه اختیاری پرونده |
Swagger
post:
summary: Extract invention context from a .txt disclosure file
responses:
200:
description: Extraction completed
400:
description: Invalid or empty file
413:
description: File too large
415:
description: Unsupported media type
422:
description: Validation error
503:
description: LLM API key not configured
500:
description: Extraction failed
نمونه ورودی
curl -X POST "http://127.0.0.1:8000/api/v1/extract" \
-F "file=@disclosure.txt;type=text/plain" \
--get --data-urlencode "case_id=case-001"
نمونه خروجی
{
"context": { "schema_version": "...", "meta": {} },
"profile": "sectioned-device-parallel-fulltext",
"missing_questions": [],
"warnings": [],
"metrics": { "duration_seconds": 12.5 }
}
Status Codes
- 200: استخراج با موفقیت انجام شد
- 400: فایل خالی یا UTF-8 نامعتبر
- 413: حجم فایل بیش از حد مجاز
- 415: فقط فایل .txt پشتیبانی میشود
- 422: خطای اعتبارسنجی ورودی استخراج
- 503: کلید LLM تنظیم نشده
- 500: خطای داخلی pipeline استخراج
نتیجه مورد انتظار
در محیط پیکربندیشده، پاسخ JSON با context کامل و کد 200.
روال صحتسنجی
- بررسی کد 200 برای فایل txt معتبر
- بررسی وجود فیلد context در پاسخ
- بررسی 415 برای پسوند غیر txt
- بررسی 503 بدون کلید API
توضیحات
- مسیر async محصول از طریق RabbitMQ context.extraction.requested انجام میشود؛ worker قبل از I/O ذخیرهسازی کلید artifact را validate میکند
- کلیدهای traversal (
..)، absolute، backslash و percent-encoding با error_code=INVALID_ARTIFACT_KEY (non-retryable) رد میشوند - رویدادهای completed/questions_required/failed همیشه schema_version 2 منتشر میکنند
- outstanding_missing_questions فقط BLOCKING و HIGH را در نظر میگیرد؛ severity سؤال: BLOCKING→blocking و HIGH→recommended
- Swagger در محیط docker ممکن است غیرفعال باشد؛ از ATP استفاده کنید