Patent Data Examples

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