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 PDF document...")
160                print(json.dumps(document_to_download.to_dict(), indent=2))
161                downloaded_path = client.download_document(
162                    document=document_to_download,
163                    format="PDF",
164                    destination=DEST_PATH,
165                    overwrite=True,
166                )
167                print(f"Downloaded document to: {downloaded_path}")
168            else:
169                print(
170                    "No downloadable formats available for the first document or document identifier missing."
171                )
172        else:
173            print("No documents listed for this application.")
174
175        # Example: Download publication XML (grant or pgpub)
176        print("\nChecking for publication files (grant/pgpub XML)...")
177        if patent_wrapper_detail.grant_document_meta_data:
178            grant_metadata = patent_wrapper_detail.grant_document_meta_data
179            print(f"Grant document available: {grant_metadata.xml_file_name}")
180            print(f"  Product: {grant_metadata.product_identifier}")
181            print(f"  Created: {grant_metadata.file_create_date_time}")
182
183            # Download grant XML to downloads folder with auto-generated filename
184            print("\nDownloading grant XML...")
185            grant_path = client.download_publication(
186                printed_metadata=grant_metadata,
187                destination=DEST_PATH,
188                overwrite=True,
189            )
190            print(f"Downloaded grant XML to: {grant_path}")
191
192        if patent_wrapper_detail.pgpub_document_meta_data:
193            pgpub_metadata = patent_wrapper_detail.pgpub_document_meta_data
194            print(f"\nPre-grant publication available: {pgpub_metadata.xml_file_name}")
195
196            # Download with custom filename
197            pgpub_path = client.download_publication(
198                printed_metadata=pgpub_metadata,
199                file_name="my_pgpub.xml",
200                destination=DEST_PATH,
201                overwrite=True,
202            )
203            print(f"Downloaded pgpub XML to: {pgpub_path}")
204
205        if patent_wrapper_detail.assignment_bag:
206            print("\nAssignments:")
207            for assignment in patent_wrapper_detail.assignment_bag:
208                for assignee in assignment.assignee_bag:
209                    print(
210                        f"  - {assignee.assignee_name_text} (Recorded: {assignment.assignment_recorded_date})"
211                    )
212                    print(f"    Conveyance: {assignment.conveyance_text}")
213    else:
214        print(f"Could not retrieve details for application {app_no_to_fetch}")
215
216except Exception as e:
217    print(f"Error retrieving or processing patent application {app_no_to_fetch}: {e}")
218
219# Search for a specific patent by patent number (using search_applications)
220target_patent_number = "10000000"
221try:
222    print(f"\nSearching for patent US {target_patent_number} B2...")
223    patent_search_response = client.search_applications(
224        patent_number_q=target_patent_number, limit=1
225    )
226
227    if (
228        patent_search_response.count > 0
229        and patent_search_response.patent_file_wrapper_data_bag
230    ):
231        found_patent_wrapper = patent_search_response.patent_file_wrapper_data_bag[0]
232        if (
233            found_patent_wrapper.application_meta_data
234            and found_patent_wrapper.application_meta_data.patent_number
235        ):
236            print(
237                f"Retrieved patent: US {found_patent_wrapper.application_meta_data.patent_number}"
238            )
239        else:
240            print(
241                f"Retrieved patent application: {found_patent_wrapper.application_number_text}"
242            )
243
244        if found_patent_wrapper.patent_term_adjustment_data:
245            pta = found_patent_wrapper.patent_term_adjustment_data
246            print(f"Patent Term Adjustment: {pta.adjustment_total_quantity} days")
247            if pta.a_delay_quantity is not None:
248                print(f"  A Delay: {pta.a_delay_quantity} days")
249            if pta.b_delay_quantity is not None:
250                print(f"  B Delay: {pta.b_delay_quantity} days")
251            if pta.c_delay_quantity is not None:
252                print(f"  C Delay: {pta.c_delay_quantity} days")
253            if pta.applicant_day_delay_quantity is not None:
254                print(f"  Applicant Delay: {pta.applicant_day_delay_quantity} days")
255
256        # Example of getting continuity data (assuming it's part of the wrapper)
257        continuity_data = ApplicationContinuityData.from_wrapper(
258            wrapper=found_patent_wrapper
259        )
260        if continuity_data.parent_continuity_bag:
261            print("\nParent Applications:")
262            for p_continuity in continuity_data.parent_continuity_bag:
263                print(f"  - App No: {p_continuity.parent_application_number_text}")
264                print(
265                    f"    Type: {p_continuity.claim_parentage_type_code_description_text}"
266                )
267                print(f"    Filing Date: {p_continuity.parent_application_filing_date}")
268
269        if continuity_data.child_continuity_bag:
270            print("\nChild Applications:")
271            for c_continuity in continuity_data.child_continuity_bag:
272                print(f"  - App No: {c_continuity.child_application_number_text}")
273                print(
274                    f"    Type: {c_continuity.claim_parentage_type_code_description_text}"
275                )
276                print(f"    Filing Date: {c_continuity.child_application_filing_date}")
277    else:
278        print(f"No patents found with patent number: {target_patent_number}")
279
280except Exception as e:
281    print(f"Error retrieving patent by number {target_patent_number}: {e}")
282
283# Example of POST search for applications
284try:
285    print("\nAttempting POST search for applications with 'AI' in title...")
286    post_search_body = {
287        "q": "applicationMetaData.inventionTitle:AI",
288        "pagination": {"offset": 0, "limit": 2},
289    }
290    post_response = client.search_applications(post_body=post_search_body)
291    print(
292        f"Found {post_response.count} applications via POST search (showing up to 2)."
293    )
294    for patent_wrapper in post_response.patent_file_wrapper_data_bag:
295        if patent_wrapper.application_meta_data:
296            print(
297                f"  - App No: {patent_wrapper.application_number_text}, Title: {patent_wrapper.application_meta_data.invention_title}"
298            )
299except Exception as e:
300    print(f"Error with POST search: {e}")
301
302
303# Example of getting status codes
304try:
305    print("\nGetting first 5 status codes...")
306    status_code_response = client.get_status_codes(params={"limit": 5})
307    print(
308        f"Retrieved {len(status_code_response.status_code_bag)} status codes (out of {status_code_response.count} total)."
309    )
310    for code_obj in status_code_response.status_code_bag:
311        print(f"  - Code: {code_obj.code}, Description: {code_obj.description}")
312except Exception as e:
313    print(f"Error getting status codes: {e}")