PTAB Appeals Example — pyUSPTO 0.2.3.dev1+g2c5d89b38.d20251125 documentation

# PTAB Appeals Example

      1"""
      2Example usage of the pyUSPTO module for PTAB Appeals API
      3
      4This example demonstrates how to use the PTABAppealsClient to interact with the USPTO PTAB
      5(Patent Trial and Appeal Board) Appeals API. It shows how to search for ex parte appeal
      6decisions using various search criteria.
      7
      8PTAB Appeals include ex parte appeals from patent application examinations to the Board.
      9"""
     10
     11import os
     12
     13from pyUSPTO import PTABAppealsClient, USPTOConfig
     14
     15# --- Initialization ---
     16# Choose one method to initialize the client.
     17# For this example, Method 1 is active. Replace "YOUR_API_KEY_HERE" with your actual key.
     18
     19# Method 1: Initialize the client with direct API key
     20print("Method 1: Initialize with direct API key")
     21api_key = os.environ.get("USPTO_API_KEY", "YOUR_API_KEY_HERE")
     22if api_key == "YOUR_API_KEY_HERE":
     23    raise ValueError(
     24        "WARNING: API key is not set. Please replace 'YOUR_API_KEY_HERE' or set USPTO_API_KEY environment variable."
     25    )
     26client = PTABAppealsClient(api_key=api_key)
     27
     28# Method 2: Initialize the client with USPTOConfig (alternative)
     29# print("\nMethod 2: Initialize with USPTOConfig")
     30# config_obj = USPTOConfig(
     31#     api_key="YOUR_API_KEY_HERE",  # Replace with your actual API key
     32#     ptab_base_url="https://api.uspto.gov",  # Optional, uses default if not set
     33# )
     34# client = PTABAppealsClient(config=config_obj)
     35
     36# Method 3: Initialize the client with environment variables (recommended for production)
     37# print("\nMethod 3: Initialize with environment variables")
     38# # Ensure USPTO_API_KEY is set in your environment
     39# try:
     40#     config_from_env = USPTOConfig.from_env()
     41#     client = PTABAppealsClient(config=config_from_env)
     42# except ValueError as e:
     43#     print(f"Error initializing from environment: {e}")
     44#     print("Please ensure USPTO_API_KEY environment variable is set.")
     45
     46print("\nBeginning PTAB Appeals API requests with configured client:")
     47
     48# =============================================================================
     49# 1. Search Appeal Decisions by Technology Center
     50# =============================================================================
     51
     52print("\n" + "=" * 80)
     53print("1. Searching for appeal decisions by technology center")
     54print("=" * 80)
     55
     56try:
     57    # Search for decisions from Technology Center 3600 (Business Methods/Software)
     58    response = client.search_decisions(
     59        technology_center_number_q="3600",
     60        decision_date_from_q="2023-01-01",
     61        decision_date_to_q="2023-12-31",
     62        limit=5,
     63    )
     64
     65    print(f"\nFound {response.count} appeal decisions from TC 3600 in 2023")
     66    print(f"Displaying first {len(response.patent_appeal_data_bag)} results:")
     67
     68    for decision in response.patent_appeal_data_bag:
     69        print(f"\n  Appeal Number: {decision.appeal_number}")
     70
     71        if decision.appeal_meta_data:
     72            meta = decision.appeal_meta_data
     73            print(f"  Application Type: {meta.application_type_category}")
     74            print(f"  Filing Date: {meta.appeal_filing_date}")
     75
     76        if decision.appellant_data:
     77            appellant = decision.appellant_data
     78            print(f"  Application Number: {appellant.application_number_text}")
     79            print(f"  Technology Center: {appellant.technology_center_number}")
     80
     81            if appellant.inventor_name:
     82                print(f"  Inventor: {appellant.inventor_name}")
     83
     84        if decision.decision_data:
     85            dec = decision.decision_data
     86            print(f"  Decision Type: {dec.decision_type_category}")
     87            print(f"  Decision Date: {dec.decision_issue_date}")
     88
     89except Exception as e:
     90    print(f"Error searching appeal decisions: {e}")
     91
     92# =============================================================================
     93# 2. Search by Decision Type
     94# =============================================================================
     95
     96print("\n" + "=" * 80)
     97print("2. Searching for 'Affirmed' decisions")
     98print("=" * 80)
     99
    100try:
    101    # Search for decisions where the examiner was affirmed
    102    response = client.search_decisions(
    103        decision_type_category_q="Affirmed",
    104        decision_date_from_q="2024-01-01",
    105        limit=5,
    106    )
    107
    108    print(f"\nFound {response.count} 'Affirmed' decisions since 2024")
    109    print(f"Displaying first {len(response.patent_appeal_data_bag)} results:")
    110
    111    for decision in response.patent_appeal_data_bag:
    112        print(f"\n  Appeal Number: {decision.appeal_number}")
    113
    114        if decision.appellant_data:
    115            print(f"  Application: {decision.appellant_data.application_number_text}")
    116            print(f"  Inventor: {decision.appellant_data.inventor_name or 'N/A'}")
    117
    118        if decision.decision_data:
    119            print(f"  Decision: {decision.decision_data.decision_type_category}")
    120            print(f"  Date: {decision.decision_data.decision_issue_date}")
    121
    122except Exception as e:
    123    print(f"Error searching by decision type: {e}")
    124
    125# =============================================================================
    126# 3. Search by Application Number
    127# =============================================================================
    128
    129print("\n" + "=" * 80)
    130print("3. Searching for decisions by application number pattern")
    131print("=" * 80)
    132
    133try:
    134    # Search for decisions related to applications starting with "15/"
    135    response = client.search_decisions(
    136        application_number_text_q="15/*",
    137        decision_date_from_q="2023-01-01",
    138        limit=3,
    139    )
    140
    141    print(f"\nFound {response.count} decisions for applications starting with '15/'")
    142    print(f"Displaying first {len(response.patent_appeal_data_bag)} results:")
    143
    144    for decision in response.patent_appeal_data_bag:
    145        print(f"\n  Appeal Number: {decision.appeal_number}")
    146
    147        if decision.appellant_data:
    148            print(f"  Application: {decision.appellant_data.application_number_text}")
    149            print(f"  TC Number: {decision.appellant_data.technology_center_number}")
    150
    151        if decision.document_data:
    152            doc = decision.document_data
    153            print(f"  Document Name: {doc.document_name}")
    154            if doc.file_download_uri:
    155                print(f"  Download URL: {doc.file_download_uri}")
    156
    157except Exception as e:
    158    print(f"Error searching by application number: {e}")
    159
    160# =============================================================================
    161# 4. Pagination Example
    162# =============================================================================
    163
    164print("\n" + "=" * 80)
    165print("4. Paginating through appeal decisions")
    166print("=" * 80)
    167
    168try:
    169    print("\nIterating through first 10 appeal decisions from 2024...")
    170    count = 0
    171    for decision in client.paginate_decisions(
    172        decision_date_from_q="2024-01-01",
    173        limit=5,  # Fetch 5 per page
    174    ):
    175        count += 1
    176        decision_type = (
    177            decision.decision_data.decision_type_category
    178            if decision.decision_data
    179            else "N/A"
    180        )
    181        print(f"{count}. {decision.appeal_number} - {decision_type}")
    182
    183        if count >= 10:  # Stop after 10 results for this example
    184            break
    185
    186    print(f"\nDisplayed {count} decisions using pagination")
    187
    188except Exception as e:
    189    print(f"Error paginating decisions: {e}")
    190
    191# =============================================================================
    192# 5. Advanced Search with Multiple Criteria
    193# =============================================================================
    194
    195print("\n" + "=" * 80)
    196print("5. Advanced search with multiple criteria")
    197print("=" * 80)
    198
    199try:
    200    # Search with multiple convenience parameters
    201    response = client.search_decisions(
    202        technology_center_number_q="2100",  # Electronics
    203        decision_type_category_q="Reversed",
    204        decision_date_from_q="2023-01-01",
    205        decision_date_to_q="2023-12-31",
    206        sort="decisionDate desc",
    207        limit=3,
    208    )
    209
    210    print(
    211        f"\nFound {response.count} 'Reversed' decisions from TC 2100 (Electronics) in 2023"
    212    )
    213    print(f"Displaying first {len(response.patent_appeal_data_bag)} results:")
    214
    215    for decision in response.patent_appeal_data_bag:
    216        print(f"\n  Appeal Number: {decision.appeal_number}")
    217
    218        if decision.appellant_data:
    219            print(f"  Application: {decision.appellant_data.application_number_text}")
    220
    221        if decision.decision_data:
    222            print(f"  Decision: {decision.decision_data.decision_type_category}")
    223            print(f"  Date: {decision.decision_data.decision_issue_date}")
    224
    225except Exception as e:
    226    print(f"Error with advanced search: {e}")
    227
    228# =============================================================================
    229# 6. Direct Query String Example
    230# =============================================================================
    231
    232print("\n" + "=" * 80)
    233print("6. Using direct query string for complex searches")
    234print("=" * 80)
    235
    236try:
    237    # Use a direct query string for more complex searches
    238    response = client.search_decisions(
    239        query="technologyCenterNumber:3600 AND decisionTypeCategory:(Affirmed OR Reversed)",
    240        limit=3,
    241    )
    242
    243    print(f"\nFound {response.count} Affirmed/Reversed decisions from TC 3600")
    244    print(f"Displaying first {len(response.patent_appeal_data_bag)} results:")
    245
    246    for decision in response.patent_appeal_data_bag:
    247        print(f"\n  Appeal Number: {decision.appeal_number}")
    248
    249        if decision.decision_data:
    250            print(f"  Decision: {decision.decision_data.decision_type_category}")
    251
    252except Exception as e:
    253    print(f"Error with direct query: {e}")
    254
    255# =============================================================================
    256# 7. Error Handling Example
    257# =============================================================================
    258
    259print("\n" + "=" * 80)
    260print("7. Error handling demonstration")
    261print("=" * 80)
    262
    263try:
    264    # Attempt a search that might return no results
    265    print("\nAttempting search with unlikely parameters...")
    266    response = client.search_decisions(
    267        appeal_number_q="INVALID-APPEAL-NUMBER",
    268        limit=1,
    269    )
    270
    271    if response.count == 0:
    272        print("No results found for the given search criteria")
    273    else:
    274        print(f"Found {response.count} results")
    275
    276except Exception as e:
    277    print(f"Expected error occurred: {type(e).__name__}: {e}")
    278
    279print("\n" + "=" * 80)
    280print("PTAB Appeals API example completed successfully!")
    281print("=" * 80)