Patent Data Examples — pyUSPTO 0.2.3.dev1+g2c5d89b38.d20251125 documentation

# Patent Data Examples

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