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