Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install -r requirements-dev.txt
pip install -e .
pip install -e ".[test]"

- name: Run tests
run: |
Expand All @@ -46,12 +45,12 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.10"
python-version: "3.14"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ruff mypy
pip install -e ".[lint]"

- name: Lint with ruff
run: |
Expand Down
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ cd pyUSPTO

### Set Up Development Environment

> **Note:** Python 3.11+ is required for the development environment. Some dev dependencies (e.g. `myst-parser`) do not support Python 3.10. The package itself supports Python 3.10+.

```bash
# Create and activate a virtual environment
python -m venv venv
Expand Down
42 changes: 40 additions & 2 deletions examples/ifw_example.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
"""Example usage of pyUSPTO for IFW data.

This example demonstrates how to use the PatentDataClient to interact with the USPTO Patent Data API.
It shows how to retrieve IFW based on various identifying values.
This example demonstrates how to use the PatentDataClient to retrieve Image File
Wrapper (IFW) data from the USPTO Patent Data API. It covers:

- get_IFW_metadata(): retrieve a PatentFileWrapper (with populated document_bag)
using any of the five supported identifiers:
- application_number
- patent_number
- publication_number
- PCT_app_number
- PCT_pub_number

- get_IFW(): retrieve metadata AND bulk-download all prosecution history documents
(PDF preferred, DOCX fallback; XML and formatless docs are skipped). Returns an
IFWResult with:
- wrapper: the PatentFileWrapper
- output_path: path to the ZIP archive (as_zip=True, default) or output directory
- downloaded_documents: dict mapping document_identifier -> filename, allowing
each Document in document_bag to be linked to its downloaded file

- download_archive() / download_publication(): download the pgpub or grant XML
archive from PrintedMetaData.
"""

import json
Expand Down Expand Up @@ -61,6 +80,25 @@
print(f" - IFW Found based on PCT Pub No: {PCT_pub_number}")


print("\nGet IFW + download all prosecution docs as a ZIP archive -->")
ifw_result = client.get_IFW(application_number=application_number, destination="./download-example", overwrite=True)
if ifw_result:
print(f"Title: {ifw_result.wrapper.application_meta_data.invention_title if ifw_result.wrapper.application_meta_data else 'N/A'}")
print(f"Output: {ifw_result.output_path}")
doc_bag = ifw_result.wrapper.document_bag or []
print(f"Documents downloaded: {len(ifw_result.downloaded_documents)} of {len(doc_bag)}")
for doc in doc_bag:
if doc.document_identifier:
filename = ifw_result.downloaded_documents.get(doc.document_identifier)
status = f"-> {filename}" if filename else "(skipped)"
print(f" {doc.document_code} [{doc.document_identifier}] {status}")

print("\nGet IFW + download all prosecution docs as a directory (no ZIP) -->")
ifw_dir_result = client.get_IFW(application_number=application_number, destination="./download-example", overwrite=True, as_zip=False)
if ifw_dir_result:
print(f"Output directory: {ifw_dir_result.output_path}")


print("\nNow let's download the Patent Publication Text -->")
if app_no_ifw and app_no_ifw.pgpub_document_meta_data:
pgpub_archive = app_no_ifw.pgpub_document_meta_data
Expand Down
22 changes: 22 additions & 0 deletions examples/patent_data_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,28 @@
print(f"Error with POST search: {e}")


# Search by CPC classification code
# CPC codes containing spaces or slashes are automatically quoted for the Lucene query.
# cpc_classification_bag on ApplicationMetaData is a list[str] of all CPC codes assigned
# to the application, so each result may have multiple codes.
try:
print("\nSearching by CPC classification code 'H10D 64/667'...")
cpc_response = client.search_applications(
classification_q="H10D 64/667", limit=3
)
print(f"Found {cpc_response.count} applications with CPC code H10D 64/667.")
for patent_wrapper in cpc_response.patent_file_wrapper_data_bag:
app_meta = patent_wrapper.application_meta_data
if app_meta:
print(
f" - App No: {patent_wrapper.application_number_text}, Title: {app_meta.invention_title}"
)
if app_meta.cpc_classification_bag:
print(f" CPC codes: {', '.join(app_meta.cpc_classification_bag)}")
except Exception as e:
print(f"Error searching by CPC classification: {e}")


# Example of getting status codes
try:
print("\nGetting first 5 status codes...")
Expand Down
25 changes: 9 additions & 16 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,17 @@ dependencies = [
dynamic = ["version"]

[project.optional-dependencies]
dev = [
# Testing
"pytest>=9.0.2",
"pytest-cov>=7.0.0",
"pytest-mock>=3.15.1",
# Documentation
"sphinx==8.1.3",
"sphinx-rtd-theme>=3.0.0",
"sphinx_immaterial>=0.13.8",
"sphinx-autodoc-typehints==3.0.1",
test = ["pytest>=9.0.2", "pytest-cov>=7.0.0", "pytest-mock>=3.15.1", "typing_extensions>=4.15.0"]
docs = [
"sphinx>=9.1.0",
"sphinx-rtd-theme>=3.1.0",
"sphinx_immaterial>=0.13.9",
"sphinx-autodoc-typehints>=3.9.5",
"sphinx-copybutton>=0.5.2",
"myst-parser>=4.0.1",
# Type checking
"mypy>=1.19.0",
"types-requests>=2.32.4",
# Code quality and formatting
"ruff>=0.15.0",
"myst-parser>=5.0.0",
]
lint = ["mypy>=1.19.0", "types-requests>=2.32.4", "ruff>=0.15.0"]
dev = ["pyUSPTO[test]", "pyUSPTO[docs]", "pyUSPTO[lint]"]

[project.urls]
GitHub = "https://github.com/DunlapCoddingPC/pyUSPTO"
Expand Down
48 changes: 29 additions & 19 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ colorama==0.4.6
# sphinx
coverage==7.13.4
# via pytest-cov
docutils==0.21.2
docutils==0.22.4
# via
# myst-parser
# sphinx
# sphinx-rtd-theme
idna==3.11
# via requests
imagesize==1.4.1
imagesize==2.0.0
# via sphinx
iniconfig==2.3.0
# via pytest
Expand All @@ -39,7 +39,7 @@ jinja2==3.1.6
# sphinx
librt==0.8.1
# via mypy
markdown-it-py==3.0.0
markdown-it-py==4.0.0
# via
# mdit-py-plugins
# myst-parser
Expand All @@ -52,11 +52,11 @@ mdit-py-plugins==0.5.0
mdurl==0.1.2
# via markdown-it-py
mypy==1.19.1
# via pyUSPTO (pyproject.toml)
# via pyuspto
mypy-extensions==1.1.0
# via mypy
myst-parser==4.0.1
# via pyUSPTO (pyproject.toml)
myst-parser==5.0.0
# via pyuspto
packaging==26.0
# via
# pytest
Expand All @@ -81,41 +81,48 @@ pygments==2.19.2
# sphinx
pytest==9.0.2
# via
# pyUSPTO (pyproject.toml)
# pytest-cov
# pytest-mock
# pyuspto
pytest-cov==7.0.0
# via pyUSPTO (pyproject.toml)
# via pyuspto
pytest-mock==3.15.1
# via pyUSPTO (pyproject.toml)
# via pyuspto
pyuspto @ file:///C:/Users/andrewp/Documents/GitHub/pyUSPTO
# via
# pyUSPTO (pyproject.toml)
# pyuspto
pyyaml==6.0.3
# via myst-parser
requests==2.32.5
# via
# pyUSPTO (pyproject.toml)
# pyuspto
# sphinx
# sphinx-immaterial
roman-numerals==4.1.0
# via sphinx
ruff==0.15.4
# via pyUSPTO (pyproject.toml)
# via pyuspto
snowballstemmer==3.0.1
# via sphinx
sphinx==8.1.3
sphinx==9.1.0
# via
# myst-parser
# pyUSPTO (pyproject.toml)
# pyuspto
# sphinx-autodoc-typehints
# sphinx-copybutton
# sphinx-immaterial
# sphinx-rtd-theme
# sphinxcontrib-jquery
sphinx-autodoc-typehints==3.0.1
# via pyUSPTO (pyproject.toml)
sphinx-autodoc-typehints==3.9.6
# via pyuspto
sphinx-copybutton==0.5.2
# via pyUSPTO (pyproject.toml)
# via pyuspto
sphinx-immaterial==0.13.9
# via pyUSPTO (pyproject.toml)
# via pyuspto
sphinx-rtd-theme==3.1.0
# via pyUSPTO (pyproject.toml)
# via pyuspto
sphinxcontrib-applehelp==2.0.0
# via sphinx
sphinxcontrib-devhelp==2.0.0
Expand All @@ -131,19 +138,22 @@ sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
# via sphinx
types-requests==2.32.4.20260107
# via pyUSPTO (pyproject.toml)
# via pyuspto
typing-extensions==4.15.0
# via
# mypy
# pydantic
# pydantic-core
# pydantic-extra-types
# pyuspto
# sphinx-immaterial
# typing-inspection
typing-inspection==0.4.2
# via pydantic
tzdata==2025.3
# via pyUSPTO (pyproject.toml)
# via
# pyUSPTO (pyproject.toml)
# pyuspto
urllib3==2.6.3
# via
# requests
Expand Down
Loading
Loading