1"""
2Example usage of the pyUSPTO module for PTAB Interferences API
3
4This example demonstrates how to use the PTABInterferencesClient to interact with the USPTO PTAB
5(Patent Trial and Appeal Board) Interferences API. It shows how to search for interference
6decisions using various search criteria.
7
8PTAB Interferences are proceedings to determine priority of invention when two or more parties
9claim the same patentable invention.
10"""
11
12import os
13
14from pyUSPTO import PTABInterferencesClient, USPTOConfig
15
16# --- Initialization ---
17# Choose one method to initialize the client.
18# For this example, Method 1 is active. Replace "YOUR_API_KEY_HERE" with your actual key.
19
20# Method 1: Initialize the client with direct API key
21print("Method 1: Initialize with direct API key")
22api_key = os.environ.get("USPTO_API_KEY", "YOUR_API_KEY_HERE")
23if api_key == "YOUR_API_KEY_HERE":
24 raise ValueError(
25 "WARNING: API key is not set. Please replace 'YOUR_API_KEY_HERE' or set USPTO_API_KEY environment variable."
26 )
27client = PTABInterferencesClient(api_key=api_key)
28
29# Method 2: Initialize the client with USPTOConfig (alternative)
30# print("\nMethod 2: Initialize with USPTOConfig")
31# config_obj = USPTOConfig(
32# api_key="YOUR_API_KEY_HERE", # Replace with your actual API key
33# ptab_base_url="https://api.uspto.gov", # Optional, uses default if not set
34# )
35# client = PTABInterferencesClient(config=config_obj)
36
37# Method 3: Initialize the client with environment variables (recommended for production)
38# print("\nMethod 3: Initialize with environment variables")
39# # Ensure USPTO_API_KEY is set in your environment
40# try:
41# config_from_env = USPTOConfig.from_env()
42# client = PTABInterferencesClient(config=config_from_env)
43# except ValueError as e:
44# print(f"Error initializing from environment: {e}")
45# print("Please ensure USPTO_API_KEY environment variable is set.")
46
47print("\nBeginning PTAB Interferences API requests with configured client:")
48
49# =============================================================================
50# 1. Search Interference Decisions
51# =============================================================================
52
53print("\n" + "=" * 80)
54print("1. Searching for interference decisions")
55print("=" * 80)
56
57try:
58 # Search for recent interference decisions
59 response = client.search_decisions(
60 decision_date_from_q="2023-01-01",
61 limit=5,
62 )
63
64 print(f"\nFound {response.count} interference decisions since 2023")
65 print(f"Displaying first {len(response.patent_interference_data_bag)} results:")
66
67 for decision in response.patent_interference_data_bag:
68 print(f"\n Interference Number: {decision.interference_number}")
69
70 if decision.interference_meta_data:
71 meta = decision.interference_meta_data
72 print(f" Style Name: {meta.interference_style_name}")
73 print(f" Last Modified: {meta.interference_last_modified_date}")
74
75 if decision.senior_party_data:
76 senior = decision.senior_party_data
77 print(f" Senior Party: {senior.patent_owner_name}")
78 if senior.patent_number:
79 print(f" Senior Patent: {senior.patent_number}")
80
81 if decision.junior_party_data:
82 junior = decision.junior_party_data
83 print(f" Junior Party: {junior.patent_owner_name}")
84 if junior.publication_number:
85 print(f" Junior Publication: {junior.publication_number}")
86
87 if decision.document_data:
88 doc = decision.document_data
89 print(f" Outcome: {doc.interference_outcome_category}")
90 print(f" Decision Type: {doc.decision_type_category}")
91
92except Exception as e:
93 print(f"Error searching interference decisions: {e}")
94
95# =============================================================================
96# 2. Search by Interference Outcome
97# =============================================================================
98
99print("\n" + "=" * 80)
100print("2. Searching for decisions by outcome")
101print("=" * 80)
102
103try:
104 # Search for decisions with specific outcomes
105 response = client.search_decisions(
106 interference_outcome_category_q="Priority to Senior Party",
107 decision_date_from_q="2022-01-01",
108 limit=3,
109 )
110
111 print(
112 f"\nFound {response.count} decisions awarding priority to the senior party since 2022"
113 )
114 print(f"Displaying first {len(response.patent_interference_data_bag)} results:")
115
116 for decision in response.patent_interference_data_bag:
117 print(f"\n Interference Number: {decision.interference_number}")
118
119 if decision.senior_party_data:
120 print(f" Senior Party: {decision.senior_party_data.patent_owner_name}")
121 print(
122 f" Senior Application: {decision.senior_party_data.application_number_text}"
123 )
124
125 if decision.junior_party_data:
126 print(f" Junior Party: {decision.junior_party_data.patent_owner_name}")
127
128 if decision.document_data:
129 print(f" Outcome: {decision.document_data.interference_outcome_category}")
130 print(f" Decision Date: {decision.document_data.decision_issue_date}")
131
132except Exception as e:
133 print(f"Error searching by outcome: {e}")
134
135# =============================================================================
136# 3. Search by Party Name
137# =============================================================================
138
139print("\n" + "=" * 80)
140print("3. Searching for decisions by party name")
141print("=" * 80)
142
143try:
144 # Search for decisions involving a specific senior party
145 response = client.search_decisions(
146 senior_party_name_q="*Corp*", # Any company with "Corp" in the name
147 limit=3,
148 )
149
150 print(f"\nFound {response.count} decisions with 'Corp' in senior party name")
151 print(f"Displaying first {len(response.patent_interference_data_bag)} results:")
152
153 for decision in response.patent_interference_data_bag:
154 print(f"\n Interference Number: {decision.interference_number}")
155
156 if decision.senior_party_data:
157 senior = decision.senior_party_data
158 print(f" Senior Party: {senior.patent_owner_name}")
159 if senior.counsel_name:
160 print(f" Senior Counsel: {senior.counsel_name}")
161
162 if decision.junior_party_data:
163 junior = decision.junior_party_data
164 print(f" Junior Party: {junior.patent_owner_name}")
165 if junior.counsel_name:
166 print(f" Junior Counsel: {junior.counsel_name}")
167
168except Exception as e:
169 print(f"Error searching by party name: {e}")
170
171# =============================================================================
172# 4. Search by Application Numbers
173# =============================================================================
174
175print("\n" + "=" * 80)
176print("4. Searching for decisions by application numbers")
177print("=" * 80)
178
179try:
180 # Search for decisions involving specific application numbers
181 response = client.search_decisions(
182 senior_party_application_number_q="12/*", # Applications starting with 12/
183 limit=3,
184 )
185
186 print(
187 f"\nFound {response.count} decisions with senior applications starting with '12/'"
188 )
189 print(f"Displaying first {len(response.patent_interference_data_bag)} results:")
190
191 for decision in response.patent_interference_data_bag:
192 print(f"\n Interference Number: {decision.interference_number}")
193
194 if decision.senior_party_data:
195 print(
196 f" Senior Application: {decision.senior_party_data.application_number_text}"
197 )
198
199 if decision.junior_party_data:
200 print(
201 f" Junior Publication: {decision.junior_party_data.publication_number}"
202 )
203
204 if decision.document_data:
205 print(f" Decision Type: {decision.document_data.decision_type_category}")
206
207except Exception as e:
208 print(f"Error searching by application numbers: {e}")
209
210# =============================================================================
211# 5. Pagination Example
212# =============================================================================
213
214print("\n" + "=" * 80)
215print("5. Paginating through interference decisions")
216print("=" * 80)
217
218try:
219 print("\nIterating through first 5 interference decisions from 2023...")
220 count = 0
221 for decision in client.paginate_decisions(
222 decision_date_from_q="2023-01-01",
223 limit=3, # Fetch 3 per page
224 ):
225 count += 1
226 outcome = (
227 decision.document_data.interference_outcome_category
228 if decision.document_data
229 else "N/A"
230 )
231 print(f"{count}. {decision.interference_number} - {outcome}")
232
233 if count >= 5: # Stop after 5 results for this example
234 break
235
236 print(f"\nDisplayed {count} decisions using pagination")
237
238except Exception as e:
239 print(f"Error paginating decisions: {e}")
240
241# =============================================================================
242# 6. Advanced Search with Multiple Criteria
243# =============================================================================
244
245print("\n" + "=" * 80)
246print("6. Advanced search with multiple criteria")
247print("=" * 80)
248
249try:
250 # Search with multiple convenience parameters
251 response = client.search_decisions(
252 decision_type_category_q="Final Decision",
253 decision_date_from_q="2020-01-01",
254 decision_date_to_q="2023-12-31",
255 sort="decisionDate desc",
256 limit=3,
257 )
258
259 print(f"\nFound {response.count} Final Decisions between 2020-2023")
260 print(f"Displaying first {len(response.patent_interference_data_bag)} results:")
261
262 for decision in response.patent_interference_data_bag:
263 print(f"\n Interference Number: {decision.interference_number}")
264
265 if decision.interference_meta_data:
266 print(f" Style: {decision.interference_meta_data.interference_style_name}")
267
268 if decision.document_data:
269 print(f" Decision Type: {decision.document_data.decision_type_category}")
270 print(f" Decision Date: {decision.document_data.decision_issue_date}")
271 print(f" Outcome: {decision.document_data.interference_outcome_category}")
272
273 # Show additional parties if present
274 if decision.additional_party_data_bag:
275 print(f" Additional Parties: {len(decision.additional_party_data_bag)}")
276 for party in decision.additional_party_data_bag:
277 print(f" - {party.additional_party_name}")
278
279except Exception as e:
280 print(f"Error with advanced search: {e}")
281
282# =============================================================================
283# 7. Direct Query String Example
284# =============================================================================
285
286print("\n" + "=" * 80)
287print("7. Using direct query string for complex searches")
288print("=" * 80)
289
290try:
291 # Use a direct query string for more complex searches
292 response = client.search_decisions(
293 query='interferenceOutcomeCategory:"Priority to Senior Party" OR interferenceOutcomeCategory:"Priority to Junior Party"',
294 limit=3,
295 )
296
297 print(f"\nFound {response.count} decisions awarding priority to either party")
298 print(f"Displaying first {len(response.patent_interference_data_bag)} results:")
299
300 for decision in response.patent_interference_data_bag:
301 print(f"\n Interference Number: {decision.interference_number}")
302
303 if decision.document_data:
304 print(f" Outcome: {decision.document_data.interference_outcome_category}")
305
306except Exception as e:
307 print(f"Error with direct query: {e}")
308
309# =============================================================================
310# 8. Error Handling Example
311# =============================================================================
312
313print("\n" + "=" * 80)
314print("8. Error handling demonstration")
315print("=" * 80)
316
317try:
318 # Attempt a search that might return no results
319 print("\nAttempting search with unlikely parameters...")
320 response = client.search_decisions(
321 interference_number_q="999999", # Very unlikely interference number
322 limit=1,
323 )
324
325 if response.count == 0:
326 print("No results found for the given search criteria")
327 else:
328 print(f"Found {response.count} results")
329
330except Exception as e:
331 print(f"Expected error occurred: {type(e).__name__}: {e}")
332
333print("\n" + "=" * 80)
334print("PTAB Interferences API example completed successfully!")
335print("=" * 80)