Files
gh-k-dense-ai-claude-scient…/skills/uspto-database/scripts/peds_client.py
2025-11-30 08:30:10 +08:00

254 lines
8.3 KiB
Python

#!/usr/bin/env python3
"""
USPTO Patent Examination Data System (PEDS) Helper
Provides functions for retrieving patent examination data using the
uspto-opendata-python library.
Requires:
- uspto-opendata-python: pip install uspto-opendata-python
Note: This script provides a simplified interface to PEDS data.
For full functionality, use the uspto-opendata-python library directly.
"""
import sys
import json
from typing import Dict, List, Optional, Any
from datetime import datetime
try:
from uspto.peds import PEDSClient as OriginalPEDSClient
HAS_USPTO_LIB = True
except ImportError:
HAS_USPTO_LIB = False
print("Warning: uspto-opendata-python not installed.", file=sys.stderr)
print("Install with: pip install uspto-opendata-python", file=sys.stderr)
class PEDSHelper:
"""Helper class for accessing PEDS data."""
def __init__(self):
"""Initialize PEDS client."""
if not HAS_USPTO_LIB:
raise ImportError("uspto-opendata-python library required")
self.client = OriginalPEDSClient()
def get_application(self, application_number: str) -> Optional[Dict]:
"""
Get patent application data by application number.
Args:
application_number: Application number (e.g., "16123456")
Returns:
Application data dictionary with:
- title: Application title
- filing_date: Filing date
- status: Current status
- transactions: List of prosecution events
- inventors: List of inventors
- assignees: List of assignees
"""
try:
result = self.client.get_application(application_number)
return self._format_application_data(result)
except Exception as e:
print(f"Error retrieving application {application_number}: {e}", file=sys.stderr)
return None
def get_patent(self, patent_number: str) -> Optional[Dict]:
"""
Get patent data by patent number.
Args:
patent_number: Patent number (e.g., "11234567")
Returns:
Patent data dictionary
"""
try:
result = self.client.get_patent(patent_number)
return self._format_application_data(result)
except Exception as e:
print(f"Error retrieving patent {patent_number}: {e}", file=sys.stderr)
return None
def get_transaction_history(self, application_number: str) -> List[Dict]:
"""
Get transaction history for an application.
Args:
application_number: Application number
Returns:
List of transactions with date, code, and description
"""
app_data = self.get_application(application_number)
if app_data and 'transactions' in app_data:
return app_data['transactions']
return []
def get_office_actions(self, application_number: str) -> List[Dict]:
"""
Get office actions for an application.
Args:
application_number: Application number
Returns:
List of office actions with dates and types
"""
transactions = self.get_transaction_history(application_number)
# Filter for office action transaction codes
oa_codes = ['CTNF', 'CTFR', 'AOPF', 'NOA']
office_actions = [
trans for trans in transactions
if trans.get('code') in oa_codes
]
return office_actions
def get_status_summary(self, application_number: str) -> Dict[str, Any]:
"""
Get a summary of application status.
Args:
application_number: Application number
Returns:
Dictionary with status summary:
- current_status: Current application status
- filing_date: Filing date
- status_date: Status date
- is_patented: Boolean indicating if patented
- patent_number: Patent number if granted
- pendency_days: Days since filing
"""
app_data = self.get_application(application_number)
if not app_data:
return {}
filing_date = app_data.get('filing_date')
if filing_date:
filing_dt = datetime.strptime(filing_date, '%Y-%m-%d')
pendency_days = (datetime.now() - filing_dt).days
else:
pendency_days = None
return {
'current_status': app_data.get('app_status'),
'filing_date': filing_date,
'status_date': app_data.get('app_status_date'),
'is_patented': app_data.get('patent_number') is not None,
'patent_number': app_data.get('patent_number'),
'issue_date': app_data.get('patent_issue_date'),
'pendency_days': pendency_days,
'title': app_data.get('title'),
'inventors': app_data.get('inventors', []),
'assignees': app_data.get('assignees', [])
}
def analyze_prosecution(self, application_number: str) -> Dict[str, Any]:
"""
Analyze prosecution history.
Args:
application_number: Application number
Returns:
Dictionary with prosecution analysis:
- total_office_actions: Count of office actions
- rejections: Count of rejections
- allowance: Boolean if allowed
- response_count: Count of applicant responses
- examination_duration: Days from filing to allowance/abandonment
"""
transactions = self.get_transaction_history(application_number)
app_summary = self.get_status_summary(application_number)
if not transactions:
return {}
analysis = {
'total_office_actions': 0,
'non_final_rejections': 0,
'final_rejections': 0,
'allowance': False,
'responses': 0,
'abandonment': False
}
for trans in transactions:
code = trans.get('code', '')
if code == 'CTNF':
analysis['non_final_rejections'] += 1
analysis['total_office_actions'] += 1
elif code == 'CTFR':
analysis['final_rejections'] += 1
analysis['total_office_actions'] += 1
elif code in ['AOPF', 'OA']:
analysis['total_office_actions'] += 1
elif code == 'NOA':
analysis['allowance'] = True
elif code == 'WRIT':
analysis['responses'] += 1
elif code == 'ABND':
analysis['abandonment'] = True
analysis['status'] = app_summary.get('current_status')
analysis['pendency_days'] = app_summary.get('pendency_days')
return analysis
def _format_application_data(self, raw_data: Dict) -> Dict:
"""Format raw PEDS data into cleaner structure."""
# This is a placeholder - actual implementation depends on
# the structure returned by uspto-opendata-python
return raw_data
def main():
"""Command-line interface for PEDS data."""
if len(sys.argv) < 2:
print("Usage:")
print(" python peds_client.py <application_number>")
print(" python peds_client.py --patent <patent_number>")
print(" python peds_client.py --status <application_number>")
print(" python peds_client.py --analyze <application_number>")
sys.exit(1)
if not HAS_USPTO_LIB:
print("Error: uspto-opendata-python library not installed")
print("Install with: pip install uspto-opendata-python")
sys.exit(1)
helper = PEDSHelper()
try:
if sys.argv[1] == "--patent":
result = helper.get_patent(sys.argv[2])
elif sys.argv[1] == "--status":
result = helper.get_status_summary(sys.argv[2])
elif sys.argv[1] == "--analyze":
result = helper.analyze_prosecution(sys.argv[2])
else:
result = helper.get_application(sys.argv[1])
if result:
print(json.dumps(result, indent=2))
else:
print("No data found", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == "__main__":
main()