Skip to main content

USPTO Open Data Portal Client

Project description

uspto_odp_python_logo

Python wrapper for the USPTO Open Data Portal (ODP)

Simple, lightweight python client library to support access to the USPTO Open Data Portal (ODP)

Documentation PyPI version

Python Version Build Status
3.9 Python 3.9
3.10 Python 3.10
3.11 Python 3.11
3.12 Python 3.12
3.13 Python 3.13

This library is designed to support access to the USPTO Open Data Portal (ODP) and is built on top of the USPTO API.

This library is not designed to be a full-featured ORM or database mapper. It is designed to be a simple, easy-to-use library for accessing the USPTO API with limited dependencies.

This library will seek to maintain backwards compatibility as much as possible as the ODP evolves.

Note: You must have an API key to use this library. You can learn more about how to get an API key at getting-started. For up-to-date USPTO information regarding the Open Data Portal, please visit USPTO Open Data Portal.

API Endpoint Support Status

Patent Application Endpoints

Endpoint API Methods Support Library Method
.../search GET, POST ✅ GET, POST search_patent_applications() (POST)
search_patent_applications_get() (GET)
.../search/download GET, POST ✅ GET, POST search_patent_applications_download() (POST)
search_patent_applications_download_get() (GET)
.../{appNumber} GET ✅ GET get_patent_wrapper()
.../{appNumber}/meta-data GET ✅ GET get_app_metadata() (direct endpoint)
get_app_metadata_from_patent_number() (convenience: uses search + meta-data)
.../{appNumber}/adjustment GET ✅ GET get_adjustment()
.../{appNumber}/assignment GET ✅ GET get_patent_assignments()
.../{appNumber}/attorney GET ✅ GET get_attorney()
.../{appNumber}/continuity GET ✅ GET get_continuity()
.../{appNumber}/foreign-priority GET ✅ GET get_foreign_priority()
.../{appNumber}/transactions GET ✅ GET get_patent_transactions()
.../{appNumber}/documents GET ✅ GET get_patent_documents()
.../{appNumber}/associated-documents GET ✅ GET get_associated_documents()

Note: All endpoints begin with /api/v1/patent/applications

Additional Library Methods:

  • get_app_metadata_from_patent_number() - This is a convenience method (not a USPTO endpoint) that searches for an application number using a patent number, then calls the /meta-data endpoint. It uses the /search endpoint internally to find the application number before making the meta-data request.

Other Patent Endpoints

Endpoint API Methods Support Library Method
/api/v1/patent/status-codes GET, POST ✅ GET, POST search_status_codes_get() (GET)
search_status_codes() (POST)

Bulk Datasets Endpoints

Endpoint API Methods Support Library Method
/api/v1/datasets/products/search GET ✅ GET search_dataset_products_get()
/api/v1/datasets/products/{productIdentifier} GET ✅ GET get_dataset_product()
/api/v1/datasets/products/files/{productIdentifier}/{fileName} GET ✅ GET get_dataset_file()

Petition Decisions Endpoints

Endpoint API Methods Support Library Method
/api/v1/petition/decisions/search GET, POST ✅ GET, POST search_petition_decisions() (POST)
search_petition_decisions_get() (GET)
/api/v1/petition/decisions/search/download GET, POST ✅ GET, POST search_petition_decisions_download() (POST)
search_petition_decisions_download_get() (GET)
/api/v1/petition/decisions/{petitionDecisionRecordIdentifier} GET ✅ GET get_petition_decision()

PTAB Trials - Proceedings Endpoints

Endpoint API Methods Support Library Method
/api/v1/patent/trials/proceedings/search GET, POST ✅ GET, POST search_trial_proceedings() (POST)
search_trial_proceedings_get() (GET)
/api/v1/patent/trials/proceedings/search/download GET, POST ✅ GET, POST search_trial_proceedings_download() (POST)
search_trial_proceedings_download_get() (GET)
/api/v1/patent/trials/proceedings/{trialNumber} GET ✅ GET get_trial_proceeding()

PTAB Trials - Decisions Endpoints

Endpoint API Methods Support Library Method
/api/v1/patent/trials/decisions/search GET, POST ✅ GET, POST search_trial_decisions() (POST)
search_trial_decisions_get() (GET)
/api/v1/patent/trials/decisions/search/download GET, POST ✅ GET, POST search_trial_decisions_download() (POST)
search_trial_decisions_download_get() (GET)
/api/v1/patent/trials/decisions/{documentIdentifier} GET ✅ GET get_trial_decision()
/api/v1/patent/trials/{trialNumber}/decisions GET ✅ GET get_trial_decisions_by_trial()

PTAB Trials - Documents Endpoints

Endpoint API Methods Support Library Method
/api/v1/patent/trials/documents/search GET, POST ✅ GET, POST search_trial_documents() (POST)
search_trial_documents_get() (GET)
/api/v1/patent/trials/documents/search/download GET, POST ✅ GET, POST search_trial_documents_download() (POST)
search_trial_documents_download_get() (GET)
/api/v1/patent/trials/documents/{documentIdentifier} GET ✅ GET get_trial_document()
/api/v1/patent/trials/{trialNumber}/documents GET ✅ GET get_trial_documents_by_trial()

PTAB Appeals - Decisions Endpoints

Endpoint API Methods Support Library Method
/api/v1/patent/appeals/decisions/search GET, POST ✅ GET, POST search_appeal_decisions() (POST)
search_appeal_decisions_get() (GET)
/api/v1/patent/appeals/decisions/search/download GET, POST ✅ GET, POST search_appeal_decisions_download() (POST)
search_appeal_decisions_download_get() (GET)
/api/v1/patent/appeals/decisions/{documentIdentifier} GET ✅ GET get_appeal_decision()
/api/v1/patent/appeals/{appealNumber}/decisions GET ✅ GET get_appeal_decisions_by_appeal()

PTAB Interferences - Decisions Endpoints

Endpoint API Methods Support Library Method
/api/v1/patent/interferences/decisions/search GET, POST ✅ GET, POST search_interference_decisions() (POST)
search_interference_decisions_get() (GET)
/api/v1/patent/interferences/decisions/search/download GET, POST ✅ GET, POST search_interference_decisions_download() (POST)
search_interference_decisions_download_get() (GET)
/api/v1/patent/interferences/{interferenceNumber}/decisions GET ✅ GET get_interference_decisions_by_interference()
/api/v1/patent/interferences/decisions/{documentIdentifier} GET ✅ GET get_interference_decision()

Coverage Summary

  • Total Methods Available: 53
  • Fully Supported: 53 (100%)
  • Partially Supported: 0 (0%)
  • Not Supported: 0 (0%)

Legend

  • ✅ Fully Implemented and Available
  • ⚠️ Partially Supported (workaround implementation)
  • 🚧 Planned for Future Implementation

Note on Convenience Methods: Some library methods (like get_app_metadata_from_patent_number()) are convenience wrappers that combine multiple USPTO API calls. These are not direct USPTO endpoints but provide a simpler interface for common use cases. The implementation details are documented in the method docstrings.

Installation

Prerequisites

  • Python 3.9 or higher
  • pip (Python package installer)

From PyPI (Recommended)

pip install uspto_odp

From Source

  1. Clone the repository:
git clone https://github.com/KennethThompson/uspto_odp.git
cd uspto_odp
  1. Install the package in development mode:
pip install -e .

Development Installation

If you plan to contribute or modify the code, install with development dependencies:

pip install -e ".[dev]"

API Key Required

Before using the library, you'll need to obtain an API key from the USPTO Developer Hub. Visit USPTO Developer Hub to request your API key.

Verify Installation

You can verify the installation by running:

import uspto_odp
print(uspto_odp.__version__)

Usage

Quick Example

import asyncio
from uspto_odp.controller.uspto_odp_client import USPTOClient

async def main():
    # Initialize the client with your API key
    client = USPTOClient(api_key="your-api-key-here")
    
    # Search for patent applications
    results = await client.search_patent_applications_get(
        q="applicationNumberText:14412875"
    )
    
    # Get patent metadata
    metadata = await client.get_app_metadata("14412875")
    print(f"Application: {metadata.application_number}")
    
    # Clean up
    await client.session.close()

asyncio.run(main())

Common Examples

Here are practical examples for the most common use cases:

1. Get Patent File Wrapper

Retrieve complete patent application information including inventors, title, events, and metadata:

import asyncio
from uspto_odp.controller.uspto_odp_client import USPTOClient

async def get_file_wrapper():
    client = USPTOClient(api_key="your-api-key-here")
    
    # Get complete file wrapper for an application
    wrapper = await client.get_patent_wrapper("14412875")
    
    print(f"Application Number: {wrapper.application_number}")
    print(f"Title: {wrapper.title}")
    print(f"Inventors: {[inv.name for inv in wrapper.inventors]}")
    
    # Access application events/history
    for event in wrapper.events:
        print(f"Event: {event.event_code} - {event.event_description}")
    
    await client.session.close()

asyncio.run(get_file_wrapper())

2. Get Application Metadata

Retrieve essential application metadata including filing date, patent number, and status:

import asyncio
from uspto_odp.controller.uspto_odp_client import USPTOClient

async def get_metadata():
    client = USPTOClient(api_key="your-api-key-here")
    
    # Get metadata by application number
    metadata = await client.get_app_metadata("14412875")
    
    print(f"Application Number: {metadata.application_number}")
    print(f"Filing Date: {metadata.metadata.filing_date}")
    print(f"Patent Number: {metadata.metadata.patent_number}")
    print(f"Application Type: {metadata.metadata.application_type}")
    print(f"Status: {metadata.metadata.status}")
    
    await client.session.close()

asyncio.run(get_metadata())

3. Search for Application Number Using Patent Number

Find an application serial number when you only have a patent number:

import asyncio
from uspto_odp.controller.uspto_odp_client import USPTOClient

async def find_app_from_patent():
    client = USPTOClient(api_key="your-api-key-here")
    
    # Method 1: Use convenience method (recommended)
    # This searches for the app number and returns metadata
    metadata = await client.get_app_metadata_from_patent_number("9022434")
    
    if metadata:
        print(f"Found Application: {metadata.application_number}")
        print(f"Filing Date: {metadata.metadata.filing_date}")
    else:
        print("Patent number not found")
    
    # Method 2: Manual search approach
    # Search for applications with this patent number
    search_results = await client.search_patent_applications_get(
        q="applicationMetaData.patentNumber:9022434",
        limit=1
    )
    
    if search_results.get('totalNumFound', 0) > 0:
        app_data = search_results['patentFileWrapperDataBag'][0]
        app_number = app_data.get('applicationNumberText')
        print(f"Application Number: {app_number}")
        
        # Now get full metadata
        metadata = await client.get_app_metadata(app_number)
        print(f"Filing Date: {metadata.metadata.filing_date}")
    
    await client.session.close()

asyncio.run(find_app_from_patent())

4. Download a Patent Document

Retrieve and download documents from a patent application:

import asyncio
import os
from uspto_odp.controller.uspto_odp_client import USPTOClient

async def download_document():
    client = USPTOClient(api_key="your-api-key-here")
    
    # First, get the list of documents for an application
    app_number = "14412875"
    documents = await client.get_patent_documents(app_number)
    
    print(f"Found {len(documents.documents)} documents")
    
    # Create download directory
    download_dir = "./downloads"
    os.makedirs(download_dir, exist_ok=True)
    
    # Download the first document as PDF
    if documents.documents:
        doc = documents.documents[0]
        print(f"Downloading: {doc.document_code} - {doc.document_name}")
        
        # Download as PDF
        file_path = await client.download_document(
            document=doc,
            save_path=download_dir,
            mime_type="PDF"  # Options: "PDF", "MS_WORD", "XML"
        )
        
        print(f"Downloaded to: {file_path}")
        
        # Check available formats
        print("Available formats:")
        for option in doc.download_options:
            print(f"  - {option.mime_type}")
    
    await client.session.close()

asyncio.run(download_document())

5. Advanced Search Examples

Search for applications using various criteria:

import asyncio
from uspto_odp.controller.uspto_odp_client import USPTOClient

async def advanced_search():
    client = USPTOClient(api_key="your-api-key-here")
    
    # Example 1: Search by inventor name
    results = await client.search_patent_applications_get(
        q="applicationMetaData.inventorBag.inventorNameText:Smith",
        limit=25
    )
    print(f"Found {results.get('totalNumFound', 0)} applications")
    
    # Example 2: Search with filters and date range
    results = await client.search_patent_applications_get(
        q="applicationMetaData.applicationTypeCode:UTL",
        filters="applicationMetaData.applicationTypeCode UTL",
        range_filters="applicationMetaData.filingDate 2020-01-01:2024-01-01",
        sort="applicationMetaData.filingDate desc",
        limit=50
    )
    print(f"Found {results.get('totalNumFound', 0)} utility applications")
    
    # Example 3: Search by patent number (to find application number)
    patent_number = "12345678"
    results = await client.search_patent_applications_get(
        q=f"applicationMetaData.patentNumber:{patent_number}",
        limit=1
    )
    
    if results.get('totalNumFound', 0) > 0:
        app_number = results['patentFileWrapperDataBag'][0].get('applicationNumberText')
        print(f"Patent {patent_number} corresponds to Application {app_number}")
    
    await client.session.close()

asyncio.run(advanced_search())

Error Handling

Always handle errors appropriately:

import asyncio
from uspto_odp.controller.uspto_odp_client import USPTOClient, USPTOError

async def search_with_error_handling():
    client = USPTOClient(api_key="your-api-key-here")
    
    try:
        wrapper = await client.get_patent_wrapper("invalid-number")
    except USPTOError as e:
        if e.code == 404:
            print("Application not found")
        elif e.code == 403:
            print("Access forbidden - check your API key")
        elif e.code == 400:
            print(f"Bad request: {e.error_details}")
        else:
            print(f"Error {e.code}: {e.error}")
    except Exception as e:
        print(f"Unexpected error: {e}")
    finally:
        await client.session.close()

asyncio.run(search_with_error_handling())

Documentation

For comprehensive documentation, examples, and API reference, visit:

📚 Full Documentation

The documentation includes:

License

This project is licensed under the MIT License. See the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uspto_odp-1.0.0.tar.gz (40.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uspto_odp-1.0.0-py3-none-any.whl (59.6 kB view details)

Uploaded Python 3

File details

Details for the file uspto_odp-1.0.0.tar.gz.

File metadata

  • Download URL: uspto_odp-1.0.0.tar.gz
  • Upload date:
  • Size: 40.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for uspto_odp-1.0.0.tar.gz
Algorithm Hash digest
SHA256 b03ef2a1b83fd565a726e922fe36a407b8cf33e893b93742512eae1fa7e3e9ca
MD5 22767c1961708cb590c69f16048d72ab
BLAKE2b-256 95ea0a530658e76a7ca8544f69ea61d3905f41f87f4a2134930269f7fc1d235d

See more details on using hashes here.

File details

Details for the file uspto_odp-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: uspto_odp-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 59.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.25

File hashes

Hashes for uspto_odp-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0435310e1f05af96866805a8ad6800b0cf73dccdc5edd3ed2095d557db90de6f
MD5 54830cc10c4cd1b70b17faf38e1635ff
BLAKE2b-256 6668ab621f2fc28a168afecde7adbb67983def32bc9465e59d41e532e56709a1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page