Patent Data Examples

  1"""Example usage of the uspto_api module for patent data.
  2
  3This example demonstrates how to use the PatentDataClient to interact with the USPTO Patent Data API.
  4It shows how to retrieve patent applications, search for patents by various criteria, and access
  5detailed patent information including inventors, applicants, assignments, and more.
  6"""
  7
  8import json
  9import os
 10
 11from pyUSPTO.clients.patent_data import PatentDataClient
 12from pyUSPTO.models.patent_data import ApplicationContinuityData
 13
 14# --- Initialization ---
 15# Initialize the client with API key from ENV Var.
 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 = PatentDataClient(api_key=api_key)
 23
 24DEST_PATH = "./download-example"
 25
 26print("\nBeginning API requests with configured client:")
 27
 28# Get some patent applications (default is 25)
 29try:
 30    print("\nAttempting to get some patent applications (default search)...")
 31    # Calling with no specific query, relying on API defaults or client defaults (e.g., limit)
 32    response = client.search_applications(limit=5)  # Example: get 5 results
 33    print(
 34        f"Found {response.count} total patent applications matching default/broad criteria."
 35    )
 36    print(
 37        f"Displaying first {len(response.patent_file_wrapper_data_bag)} applications from response:"
 38    )
 39
 40    for patent_wrapper in response.patent_file_wrapper_data_bag:
 41        app_meta = patent_wrapper.application_meta_data
 42        if app_meta:
 43            print(f"\n  Application: {patent_wrapper.application_number_text}")
 44            print(f"  Title: {app_meta.invention_title}")
 45            print(f"  Status: {app_meta.application_status_description_text}")
 46            print(f"  Filing Date: {app_meta.filing_date}")
 47
 48            if app_meta.patent_number:
 49                print(f"  Patent Number: {app_meta.patent_number}")
 50                print(f"  Grant Date: {app_meta.grant_date}")
 51
 52            if app_meta.inventor_bag:
 53                print("  Inventors:")
 54                for inventor in app_meta.inventor_bag:
 55                    name_parts = [
 56                        part
 57                        for part in [inventor.first_name, inventor.last_name]
 58                        if part
 59                    ]
 60                    print(f"    - {' '.join(name_parts).strip()}")
 61                    if inventor.correspondence_address_bag:
 62                        address = inventor.correspondence_address_bag[0]
 63                        if address.city_name and address.geographic_region_code:
 64                            print(
 65                                f"      ({address.city_name}, {address.geographic_region_code})"
 66                            )
 67
 68            if app_meta.applicant_bag:
 69                print("  Applicants:")
 70                for applicant in app_meta.applicant_bag:
 71                    print(f"    - {applicant.applicant_name_text}")
 72        print("-" * 20)
 73
 74    # Example of using the to_csv method from PatentDataResponse
 75    if response.count > 0:
 76        print("\nGenerating CSV for the current response (first few rows shown):")
 77        csv_data = response.to_csv()
 78        # You could save this csv_data to a file:
 79        # with open("patent_search_results.csv", "w", newline="", encoding="utf-8") as f:
 80        # f.write(csv_data)
 81        # print("\nFull CSV data saved to patent_search_results.csv (example).")
 82
 83
 84except Exception as e:
 85    print(f"Error getting patent applications: {e}")
 86
 87# Search for patents by inventor name using convenience _q parameter
 88try:
 89    print("\nSearching for patents with 'Smith' as inventor...")
 90    # Changed from search_patents to search_applications with inventor_name_q
 91    inventor_search_response = client.search_applications(
 92        inventor_name_q="Smith", limit=2
 93    )
 94    print(
 95        f"Found {inventor_search_response.count} patents with 'Smith' as inventor (showing up to 2)."
 96    )
 97    for patent_wrapper in inventor_search_response.patent_file_wrapper_data_bag:
 98        if patent_wrapper.application_meta_data:
 99            print(
100                f"  - App No: {patent_wrapper.application_number_text}, Title: {patent_wrapper.application_meta_data.invention_title}"
101            )
102except Exception as e:
103    print(f"Error searching by inventor: {e}")
104
105
106# Search for patents filed in a date range using convenience _q parameters
107try:
108    print("\nSearching for patents filed in 2020...")
109    date_search_response = client.search_applications(
110        filing_date_from_q="2020-01-01", filing_date_to_q="2020-12-31", limit=2
111    )
112    print(
113        f"Found {date_search_response.count} patents filed in 2020 (showing up to 2)."
114    )
115    for patent_wrapper in date_search_response.patent_file_wrapper_data_bag:
116        if patent_wrapper.application_meta_data:
117            print(
118                f"  - App No: {patent_wrapper.application_number_text}, Filing Date: {patent_wrapper.application_meta_data.filing_date}"
119            )
120except Exception as e:
121    print(f"Error searching by date range: {e}")
122
123# Get a specific patent by application number
124app_no_to_fetch = "18045436"  # Known application number, ensure it's valid
125try:
126    print(f"\nAttempting to retrieve patent application: {app_no_to_fetch}")
127    patent_wrapper_detail = client.get_application_by_number(
128        application_number=app_no_to_fetch
129    )
130    if patent_wrapper_detail:
131        print(
132            f"Successfully retrieved: {patent_wrapper_detail.application_number_text}"
133        )
134        if patent_wrapper_detail.application_meta_data:
135            print(
136                f"Title: {patent_wrapper_detail.application_meta_data.invention_title}"
137            )
138
139        print("\nRetrieving document information...")
140        documents_bag = client.get_application_documents(
141            application_number=app_no_to_fetch
142        )
143        print(f"Found {len(documents_bag)} documents for application {app_no_to_fetch}")
144
145        if documents_bag.documents:
146            document_to_download = documents_bag.documents[0]  # Example: first document
147            print("\nFirst document details:")
148            print(f"  Document ID: {document_to_download.document_identifier}")
149            print(
150                f"  Document Type: {document_to_download.document_code} - {document_to_download.document_code_description_text}"
151            )
152            print(f"  Date: {document_to_download.official_date}")
153            print(f"  Direction: {document_to_download.direction_category}")
154
155            if (
156                document_to_download.document_formats
157                and document_to_download.document_identifier
158            ):
159                print("\nAttempting to download first document...")
160                print(json.dumps(document_to_download.to_dict(), indent=2))
161                downloaded_path = client.download_document(
162                    document_format=document_to_download.document_formats[0],
163                    destination_path=DEST_PATH,
164                    overwrite=True,
165                )
166                print(f"Downloaded document to: {downloaded_path}")
167            else:
168                print(
169                    "No downloadable formats available for the first document or document identifier missing."
170                )
171        else:
172            print("No documents listed for this application.")
173
174        # Example: Download publication XML (grant or pgpub)
175        print("\nChecking for publication files (grant/pgpub XML)...")
176        if patent_wrapper_detail.grant_document_meta_data:
177            grant_metadata = patent_wrapper_detail.grant_document_meta_data
178            print(f"Grant document available: {grant_metadata.xml_file_name}")
179            print(f"  Product: {grant_metadata.product_identifier}")
180            print(f"  Created: {grant_metadata.file_create_date_time}")
181
182            # Download grant XML to downloads folder with auto-generated filename
183            print("\nDownloading grant XML...")
184            grant_path = client.download_publication(
185                printed_metadata=grant_metadata,
186                destination_path=DEST_PATH,
187                overwrite=True,
188            )
189            print(f"Downloaded grant XML to: {grant_path}")
190
191        if patent_wrapper_detail.pgpub_document_meta_data:
192            pgpub_metadata = patent_wrapper_detail.pgpub_document_meta_data
193            print(f"\nPre-grant publication available: {pgpub_metadata.xml_file_name}")
194
195            # Download with custom filename
196            pgpub_path = client.download_publication(
197                printed_metadata=pgpub_metadata,
198                file_name="my_pgpub.xml",
199                destination_path=DEST_PATH,
200                overwrite=True,
201            )
202            print(f"Downloaded pgpub XML to: {pgpub_path}")
203
204        if patent_wrapper_detail.assignment_bag:
205            print("\nAssignments:")
206            for assignment in patent_wrapper_detail.assignment_bag:
207                for assignee in assignment.assignee_bag:
208                    print(
209                        f"  - {assignee.assignee_name_text} (Recorded: {assignment.assignment_recorded_date})"
210                    )
211                    print(f"    Conveyance: {assignment.conveyance_text}")
212    else:
213        print(f"Could not retrieve details for application {app_no_to_fetch}")
214
215except Exception as e:
216    print(f"Error retrieving or processing patent application {app_no_to_fetch}: {e}")
217
218# Search for a specific patent by patent number (using search_applications)
219target_patent_number = "10000000"
220try:
221    print(f"\nSearching for patent US {target_patent_number} B2...")
222    patent_search_response = client.search_applications(
223        patent_number_q=target_patent_number, limit=1
224    )
225
226    if (
227        patent_search_response.count > 0
228        and patent_search_response.patent_file_wrapper_data_bag
229    ):
230        found_patent_wrapper = patent_search_response.patent_file_wrapper_data_bag[0]
231        if (
232            found_patent_wrapper.application_meta_data
233            and found_patent_wrapper.application_meta_data.patent_number
234        ):
235            print(
236                f"Retrieved patent: US {found_patent_wrapper.application_meta_data.patent_number}"
237            )
238        else:
239            print(
240                f"Retrieved patent application: {found_patent_wrapper.application_number_text}"
241            )
242
243        if found_patent_wrapper.patent_term_adjustment_data:
244            pta = found_patent_wrapper.patent_term_adjustment_data
245            print(f"Patent Term Adjustment: {pta.adjustment_total_quantity} days")
246            if pta.a_delay_quantity is not None:
247                print(f"  A Delay: {pta.a_delay_quantity} days")
248            if pta.b_delay_quantity is not None:
249                print(f"  B Delay: {pta.b_delay_quantity} days")
250            if pta.c_delay_quantity is not None:
251                print(f"  C Delay: {pta.c_delay_quantity} days")
252            if pta.applicant_day_delay_quantity is not None:
253                print(f"  Applicant Delay: {pta.applicant_day_delay_quantity} days")
254
255        # Example of getting continuity data (assuming it's part of the wrapper)
256        continuity_data = ApplicationContinuityData.from_wrapper(
257            wrapper=found_patent_wrapper
258        )
259        if continuity_data.parent_continuity_bag:
260            print("\nParent Applications:")
261            for p_continuity in continuity_data.parent_continuity_bag:
262                print(f"  - App No: {p_continuity.parent_application_number_text}")
263                print(
264                    f"    Type: {p_continuity.claim_parentage_type_code_description_text}"
265                )
266                print(f"    Filing Date: {p_continuity.parent_application_filing_date}")
267
268        if continuity_data.child_continuity_bag:
269            print("\nChild Applications:")
270            for c_continuity in continuity_data.child_continuity_bag:
271                print(f"  - App No: {c_continuity.child_application_number_text}")
272                print(
273                    f"    Type: {c_continuity.claim_parentage_type_code_description_text}"
274                )
275                print(f"    Filing Date: {c_continuity.child_application_filing_date}")
276    else:
277        print(f"No patents found with patent number: {target_patent_number}")
278
279except Exception as e:
280    print(f"Error retrieving patent by number {target_patent_number}: {e}")
281
282# Example of POST search for applications
283try:
284    print("\nAttempting POST search for applications with 'AI' in title...")
285    post_search_body = {
286        "q": "applicationMetaData.inventionTitle:AI",
287        "pagination": {"offset": 0, "limit": 2},
288    }
289    post_response = client.search_applications(post_body=post_search_body)
290    print(
291        f"Found {post_response.count} applications via POST search (showing up to 2)."
292    )
293    for patent_wrapper in post_response.patent_file_wrapper_data_bag:
294        if patent_wrapper.application_meta_data:
295            print(
296                f"  - App No: {patent_wrapper.application_number_text}, Title: {patent_wrapper.application_meta_data.invention_title}"
297            )
298except Exception as e:
299    print(f"Error with POST search: {e}")
300
301
302# Example of getting status codes
303try:
304    print("\nGetting first 5 status codes...")
305    status_code_response = client.get_status_codes(params={"limit": 5})
306    print(
307        f"Retrieved {len(status_code_response.status_code_bag)} status codes (out of {status_code_response.count} total)."
308    )
309    for code_obj in status_code_response.status_code_bag:
310        print(f"  - Code: {code_obj.code}, Description: {code_obj.description}")
311except Exception as e:
312    print(f"Error getting status codes: {e}")