PTAB Appeals Example

  1"""Example usage of the pyUSPTO module for PTAB Appeals API.
  2
  3This example demonstrates how to use the PTABAppealsClient to interact with the USPTO PTAB
  4(Patent Trial and Appeal Board) Appeals API. It shows how to search for ex parte appeal
  5decisions using various search criteria.
  6
  7PTAB Appeals include ex parte appeals from patent application examinations to the Board.
  8"""
  9
 10import os
 11
 12from pyUSPTO import PTABAppealsClient
 13from pyUSPTO.config import USPTOConfig
 14
 15# --- Initialization ---
 16# Initialize the client with direct API key
 17print("Initialize with direct API key")
 18api_key = os.environ.get("USPTO_API_KEY", "YOUR_API_KEY_HERE")
 19if api_key == "YOUR_API_KEY_HERE":
 20    raise ValueError(
 21        "WARNING: API key is not set. Please replace 'YOUR_API_KEY_HERE' or set USPTO_API_KEY environment variable."
 22    )
 23config = USPTOConfig(api_key=api_key)
 24client = PTABAppealsClient(config=config)
 25
 26
 27print("\nBeginning PTAB Appeals API requests with configured client:")
 28# =============================================================================
 29# 1. Search Appeal Decisions by Technology Center
 30# =============================================================================
 31
 32print("\n" + "=" * 80)
 33print("1. Searching for appeal decisions by technology center")
 34print("=" * 80)
 35
 36try:
 37    # Search for decisions from Technology Center 3600 (Business Methods/Software)
 38    response = client.search_decisions(
 39        technology_center_number_q="3600",
 40        decision_date_from_q="2023-01-01",
 41        decision_date_to_q="2023-12-31",
 42        limit=5,
 43    )
 44
 45    print(f"\nFound {response.count} appeal decisions from TC 3600 in 2023")
 46    print(f"Displaying first {len(response.patent_appeal_data_bag)} results:")
 47
 48    for decision in response.patent_appeal_data_bag:
 49        print(f"\n  Appeal Number: {decision.appeal_number}")
 50
 51        if decision.appeal_meta_data:
 52            meta = decision.appeal_meta_data
 53            print(f"  Application Type: {meta.application_type_category}")
 54            print(f"  Filing Date: {meta.appeal_filing_date}")
 55
 56        if decision.appellant_data:
 57            appellant = decision.appellant_data
 58            print(f"  Application Number: {appellant.application_number_text}")
 59            print(f"  Technology Center: {appellant.technology_center_number}")
 60
 61            if appellant.inventor_name:
 62                print(f"  Inventor: {appellant.inventor_name}")
 63
 64        if decision.decision_data:
 65            dec = decision.decision_data
 66            print(f"  Decision Type: {dec.decision_type_category}")
 67            print(f"  Decision Date: {dec.decision_issue_date}")
 68
 69except Exception as e:
 70    print(f"Error searching appeal decisions: {e}")
 71
 72# =============================================================================
 73# 2. Search by Decision Type
 74# =============================================================================
 75
 76print("\n" + "=" * 80)
 77print("2. Searching for 'Affirmed' decisions")
 78print("=" * 80)
 79
 80try:
 81    # Search for decisions where the examiner was affirmed
 82    response = client.search_decisions(
 83        decision_type_category_q="Decision",
 84        decision_date_from_q="2024-01-01",
 85        limit=5,
 86    )
 87
 88    print(f"\nFound {response.count} 'Decision's since 2024")
 89    print(f"Displaying first {len(response.patent_appeal_data_bag)} results:")
 90
 91    for decision in response.patent_appeal_data_bag:
 92        print(f"\n  Appeal Number: {decision.appeal_number}")
 93
 94        if decision.appellant_data:
 95            print(f"  Application: {decision.appellant_data.application_number_text}")
 96            print(f"  Inventor: {decision.appellant_data.inventor_name or 'N/A'}")
 97
 98        if decision.decision_data:
 99            print(f"  Decision: {decision.decision_data.decision_type_category}")
100            print(f"  Outcome: {decision.decision_data.appeal_outcome_category}")
101            print(f"  Date: {decision.decision_data.decision_issue_date}")
102
103except Exception as e:
104    print(f"Error searching by decision type: {e}")
105
106# =============================================================================
107# 3. Search by Application Number
108# =============================================================================
109
110print("\n" + "=" * 80)
111print("3. Searching for decisions by application number pattern")
112print("=" * 80)
113
114try:
115    # Search for decisions related to applications starting with "15"
116    response = client.search_decisions(
117        application_number_text_q="15*",
118        decision_date_from_q="2023-01-01",
119        limit=3,
120    )
121
122    print(f"\nFound {response.count} decisions for applications starting with '15/'")
123    print(f"Displaying first {len(response.patent_appeal_data_bag)} results:")
124
125    for decision in response.patent_appeal_data_bag:
126        print(f"\n  Appeal Number: {decision.appeal_number}")
127
128        if decision.appellant_data:
129            print(f"  Application: {decision.appellant_data.application_number_text}")
130            print(f"  TC Number: {decision.appellant_data.technology_center_number}")
131
132        if decision.document_data:
133            doc = decision.document_data
134            print(f"  Document Name: {doc.document_name}")
135            if doc.file_download_uri:
136                print(f"  Download URL: {doc.file_download_uri}")
137
138except Exception as e:
139    print(f"Error searching by application number: {e}")
140
141# =============================================================================
142# 4. Pagination Example
143# =============================================================================
144
145print("\n" + "=" * 80)
146print("4. Paginating through appeal decisions")
147print("=" * 80)
148
149try:
150    print("\nIterating through first 10 appeal decisions from 2024...")
151    count = 0
152    for decision in client.paginate_decisions(
153        decision_date_from_q="2024-01-01",
154        limit=5,  # Fetch 5 per page
155    ):
156        count += 1
157        decision_type = (
158            decision.decision_data.decision_type_category
159            if decision.decision_data
160            else "N/A"
161        )
162        print(f"{count}. {decision.appeal_number} - {decision_type}")
163
164        if count >= 10:  # Stop after 10 results for this example
165            break
166
167    print(f"\nDisplayed {count} decisions using pagination")
168
169except Exception as e:
170    print(f"Error paginating decisions: {e}")
171
172# =============================================================================
173# 5. Advanced Search with Multiple Criteria
174# =============================================================================
175
176print("\n" + "=" * 80)
177print("5. Advanced search with multiple criteria")
178print("=" * 80)
179
180try:
181    # Search with multiple convenience parameters
182    response = client.search_decisions(
183        technology_center_number_q="2100",  # Electronics
184        decision_type_category_q="Decision",
185        decision_date_from_q="2023-01-01",
186        decision_date_to_q="2023-12-31",
187        sort="decisionData.decisionIssueDate desc",
188        limit=3,
189    )
190
191    print(f"\nFound {response.count} Decisions from TC 2100 (Electronics) in 2023")
192    print(f"Displaying first {len(response.patent_appeal_data_bag)} results:")
193
194    for decision in response.patent_appeal_data_bag:
195        print(f"\n  Appeal Number: {decision.appeal_number}")
196
197        if decision.appellant_data:
198            print(f"  Application: {decision.appellant_data.application_number_text}")
199
200        if decision.decision_data:
201            print(f"  Decision: {decision.decision_data.decision_type_category}")
202            print(f"  Date: {decision.decision_data.decision_issue_date}")
203
204except Exception as e:
205    print(f"Error with advanced search: {e}")
206
207# =============================================================================
208# 6. Direct Query String Example
209# =============================================================================
210
211print("\n" + "=" * 80)
212print("6. Using direct query string for complex searches")
213print("=" * 80)
214
215try:
216    # Use a direct query string for more complex searches
217    response = client.search_decisions(
218        query="appellantData.technologyCenterNumber:3600 AND decisionData.appealOutcomeCategory:(Affirmed OR Reversed)",
219        limit=10,
220    )
221
222    print(f"\nFound {response.count} Affirmed/Reversed decisions from TC 3600")
223    print(f"Displaying first {len(response.patent_appeal_data_bag)} results:")
224
225    for decision in response.patent_appeal_data_bag:
226        print(f"\n  Appeal Number: {decision.appeal_number}")
227        print(f"  >App. Number: {decision.appellant_data.application_number_text}")  # type: ignore
228        if decision.decision_data:
229            print(f"  >Decision: {decision.decision_data.decision_type_category}")
230            print(f"  >Outcome: {decision.decision_data.appeal_outcome_category}")
231
232except Exception as e:
233    print(f"Error with direct query: {e}")
234
235# =============================================================================
236# 7. Error Handling Example
237# =============================================================================
238
239print("\n" + "=" * 80)
240print("7. Error handling demonstration")
241print("=" * 80)
242
243try:
244    # Attempt a search that might return no results
245    print("\nAttempting search with unlikely parameters...")
246    response = client.search_decisions(
247        appeal_number_q="INVALID-APPEAL-NUMBER",
248        limit=1,
249    )
250
251    if response.count == 0:
252        print("No results found for the given search criteria")
253    else:
254        print(f"Found {response.count} results")
255
256except Exception as e:
257    print(f"Expected error occurred: {type(e).__name__}: {e}")
258
259print("\n" + "=" * 80)
260print("PTAB Appeals API example completed successfully!")
261print("=" * 80)