pyUSPTO 0.5.7__tar.gz → 0.6.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.github/workflows/publish-docs.yaml +1 -1
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.github/workflows/python-tests.yml +2 -2
- {pyuspto-0.5.7 → pyuspto-0.6.1}/ADVANCED.md +1 -1
- {pyuspto-0.5.7 → pyuspto-0.6.1}/CHANGELOG.md +47 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/CONTRIBUTING.md +3 -3
- {pyuspto-0.5.7/src/pyUSPTO.egg-info → pyuspto-0.6.1}/PKG-INFO +28 -18
- {pyuspto-0.5.7 → pyuspto-0.6.1}/README.md +25 -13
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/about.rst +7 -4
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/configuration.rst +1 -1
- pyuspto-0.6.1/docs/source/examples/oa_rejections.rst +6 -0
- pyuspto-0.6.1/docs/source/installation.rst +42 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/ifw_example.py +1 -1
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/petition_decisions_example.py +26 -14
- {pyuspto-0.5.7 → pyuspto-0.6.1}/pyproject.toml +3 -5
- {pyuspto-0.5.7 → pyuspto-0.6.1}/requirements-dev.txt +35 -37
- {pyuspto-0.5.7 → pyuspto-0.6.1}/requirements.txt +6 -6
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/__init__.py +6 -2
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/__init__.py +5 -1
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/base.py +91 -59
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/bulk_data.py +5 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/patent_data.py +50 -19
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/petition_decisions.py +142 -50
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/ptab_appeals.py +11 -3
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/ptab_interferences.py +7 -2
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/ptab_trials.py +9 -3
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/config.py +1 -1
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/exceptions.py +6 -2
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/patent_data.py +8 -7
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/petition_decisions.py +75 -55
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/ptab.py +1 -6
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/utils.py +6 -6
- {pyuspto-0.5.7 → pyuspto-0.6.1/src/pyUSPTO.egg-info}/PKG-INFO +28 -18
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO.egg-info/requires.txt +0 -4
- pyuspto-0.6.1/src/pyUSPTO.egg-info/scm_version.json +8 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/test_base.py +258 -62
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/test_bulk_data_clients.py +40 -6
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/test_patent_data_clients.py +77 -13
- pyuspto-0.6.1/tests/clients/test_petition_decision_clients.py +1760 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/test_ptab_appeals_client.py +6 -6
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/test_ptab_interferences_client.py +6 -6
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/test_ptab_trials_client.py +10 -10
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/conftest.py +39 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/test_bulk_data_integration.py +18 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/test_patent_data_integration.py +66 -2
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/test_petition_decisions_integration.py +325 -158
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/models/test_patent_data_models.py +14 -15
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/models/test_petition_decision_models.py +76 -55
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/models/test_ptab_models.py +6 -49
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/models/test_utils.py +13 -15
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/test_exceptions.py +24 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/test_http_config.py +0 -13
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tox.ini +2 -4
- pyuspto-0.5.7/docs/source/examples/oa_rejections.rst +0 -6
- pyuspto-0.5.7/docs/source/installation.rst +0 -14
- pyuspto-0.5.7/src/pyUSPTO.egg-info/scm_version.json +0 -8
- pyuspto-0.5.7/tests/clients/test_petition_decision_clients.py +0 -938
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.devcontainer/devcontainer-lock.json +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.devcontainer/devcontainer.json +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.github/ISSUE_TEMPLATE/documentation-updates.yml +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.github/dependabot.yml +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.github/workflows/codeql.yml +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.github/workflows/publish-to-test-pypi.yml +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.gitignore +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/.readthedocs.yaml +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/CODE_OF_CONDUCT.md +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/LICENSE +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/_version.pyi +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/Makefile +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/_static/.gitkeep +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/advanced.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/bulk_data.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/enriched_citations.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/index.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/oa_actions.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/oa_citations.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/oa_rejections.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/patent_data.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/petition_decisions.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/ptab_appeals.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/ptab_interferences.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/clients/ptab_trials.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/config/config.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/config/http_config.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/config/index.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/exceptions.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/index.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/base.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/bulk_data.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/enriched_citations.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/index.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/oa_actions.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/oa_citations.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/oa_rejections.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/patent_data.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/petition_decisions.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/ptab.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/models/utils.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/api/warnings.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/conf.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/development.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/bulk_data.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/enriched_citations.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/ifw_example.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/index.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/oa_actions.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/oa_citations.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/patent_data.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/petition_decisions.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/ptab_appeals.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/ptab_interferences.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/examples/ptab_trials.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/index.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/docs/source/quickstart.rst +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/bulk_data_example.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/enriched_citations_example.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/error_handling_example.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/oa_actions_example.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/oa_citations_example.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/oa_rejections_example.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/patent_data_example.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/ptab_appeals_example.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/ptab_interferences_example.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/examples/ptab_trials_example.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/pyUSPTO.code-workspace +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/setup.cfg +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/enriched_citations.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/oa_actions.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/oa_citations.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/clients/oa_rejections.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/http_config.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/__init__.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/base.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/bulk_data.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/enriched_citations.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/oa_actions.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/oa_citations.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/models/oa_rejections.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/py.typed +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/utils/__init__.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO/warnings.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO.egg-info/SOURCES.txt +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO.egg-info/dependency_links.txt +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO.egg-info/scm_file_list.json +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO.egg-info/top_level.txt +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/src/pyUSPTO.egg-info/zip-safe +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/__init__.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/__init__.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/test_enriched_citation_clients.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/test_oa_actions_clients.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/test_oa_citations_clients.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/clients/test_oa_rejections_clients.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/__init__.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/conftest.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/test_enriched_citations_integration.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/test_oa_actions_integration.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/test_oa_citations_integration.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/test_oa_rejections_integration.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/test_ptab_appeals_integration.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/test_ptab_interferences_integration.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/integration/test_ptab_trials_integration.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/models/__init__.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/models/test_bulk_data_models.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/models/test_enriched_citation_models.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/models/test_oa_actions_models.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/models/test_oa_citations_models.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/models/test_oa_rejections_models.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/test_config.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/test_edge_cases.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/test_init.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/test_version.py +0 -0
- {pyuspto-0.5.7 → pyuspto-0.6.1}/tests/utils/__init__.py +0 -0
|
@@ -11,7 +11,7 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
strategy:
|
|
13
13
|
matrix:
|
|
14
|
-
python-version: ["3.
|
|
14
|
+
python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"]
|
|
15
15
|
|
|
16
16
|
steps:
|
|
17
17
|
- uses: actions/checkout@v7
|
|
@@ -45,7 +45,7 @@ jobs:
|
|
|
45
45
|
- name: Set up Python
|
|
46
46
|
uses: actions/setup-python@v7
|
|
47
47
|
with:
|
|
48
|
-
python-version: "3.
|
|
48
|
+
python-version: "3.15"
|
|
49
49
|
|
|
50
50
|
- name: Install dependencies
|
|
51
51
|
run: |
|
|
@@ -80,7 +80,7 @@ patent_config = USPTOConfig(api_key="key1", http_config=http_config)
|
|
|
80
80
|
petition_config = USPTOConfig(api_key="key2", http_config=http_config)
|
|
81
81
|
|
|
82
82
|
patent_client = PatentDataClient(config=patent_config)
|
|
83
|
-
petition_client =
|
|
83
|
+
petition_client = PetitionDecisionsClient(config=petition_config)
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
## Environment Variables Reference
|
|
@@ -5,6 +5,53 @@ All notable changes to the pyUSPTO package will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.6.0]
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Python 3.15 support.
|
|
13
|
+
- `PetitionDecision` fields from USPTO ODP Release 5.0: `decided_petition_type_code`, `decided_petition_type_code_description_text`, `decision_mail_date`, `application_status_date`, `application_status_description_text`, `final_petition_decision_indicator`, `ocr_search_text`, `all_searchable_fields`, and `last_modified_date_time`. Also `decision_petition_type_code_description_text`, which the API returned but the model never read.
|
|
14
|
+
- `PetitionDecisionsClient.search_decisions(decided_petition_type_code_q=...)` filters on `decidedPetitionTypeCode`.
|
|
15
|
+
- `BaseUSPTOClient.paginate_results(count_is_total=False)` paginates APIs whose `count` is the size of the current page rather than the total.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **Breaking:** `FinalPetitionDecisionsClient` is renamed `PetitionDecisionsClient`. Since USPTO ODP Release 5.0 the Petition Decisions API returns final and non-final decisions, so the old name no longer fit. `FinalPetitionDecisionsClient` is now a subclass that restricts every search, pagination, and `download_decisions` call to final decisions (`finalPetitionDecisionIndicator` true) and returns `None` from `get_decision_by_id` for a non-final decision. Code that used `FinalPetitionDecisionsClient` for all decisions must switch to `PetitionDecisionsClient`.
|
|
20
|
+
- `DecisionTypeCode` now covers all four decided types: `GRANTED` (`A`), `GRANTED_IN_PART` (`B`), `DENIED` (`C`), and `DISMISSED` (`D`).
|
|
21
|
+
- **Breaking:** `PetitionDecision.decision_petition_type_code` is now a `str`, matching the API.
|
|
22
|
+
- `DocumentMimeType` is now a `StrEnum`. `str()` and f-strings return the value (`"PDF"`) instead of `"DocumentMimeType.PDF"`. Equality with plain strings and `.value` are unchanged.
|
|
23
|
+
- `PetitionDecisionsClient.search_decisions(sort=...)` accepts a list of sort keys, sent as repeated `sort` parameters (the API rejects comma-joined keys).
|
|
24
|
+
- `ifw_example.py` looks up its publication number as plain digits; the library adds the search wildcards itself.
|
|
25
|
+
- **Breaking:** `paginate_*` methods yield nothing for a search with no matches instead of raising `USPTOApiNotFoundError` (the search endpoints answer no-match with HTTP 404), matching `get_patent` and the other single lookups. Code that caught that exception around a pagination loop can drop the `try`.
|
|
26
|
+
|
|
27
|
+
### Removed
|
|
28
|
+
|
|
29
|
+
- **Breaking:** Dropped support for Python 3.10, which has reached end of life. The minimum supported version is now Python 3.11.
|
|
30
|
+
- `typing-extensions` is no longer a dependency; `Self` is imported from `typing` directly.
|
|
31
|
+
- **Breaking:** `PetitionDecision.decision_type_code`, `decision_type_code_description_text`, and `last_ingestion_datetime`, and `search_decisions(decision_type_code_q=...)`. USPTO ODP Release 5.0 replaced `decisionTypeCode` with `decidedPetitionTypeCode`, and the API sends `lastModifiedDateTime` instead of `lastIngestionDateTime`, so these were always `None` and the filter never matched. Use the new fields under Added.
|
|
32
|
+
- **Breaking:** `PetitionDecisionDocument.direction_category` and the `DocumentDirectionCategory` enum. Petition decision documents have no `directionCategory` (none of the roughly 1.1 million decisions), so the attribute was always `None`.
|
|
33
|
+
- **Breaking:** the `include_documents` parameter of `get_decision_by_id` on both petition clients. The API returns a decision's documents without it.
|
|
34
|
+
- **Breaking:** `PetitionDecisionDocument.application_number_text`. The API never returns it: none of the roughly 1.1 million decisions has a document with `applicationNumberText`. `PetitionDecision.application_number_text` is unchanged.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- `Document.direction_category` (patent application documents) was always `None`. The model read `documentDirectionCategory`, but the API sends `directionCategory`. `to_dict()` now emits `directionCategory`, and `DirectionCategory` gains `INTERNAL`, which the API uses for about a fifth of documents.
|
|
39
|
+
- `earliestPublicationNumber_q` (used by `search_applications`, `get_publication`, and `get_IFW_metadata(publication_number=...)`) is now reduced to its digits and searched with wildcards, so bare digits (`20210138233`), `US`-prefixed forms, kind codes, and separators (`US 2021/0138233 A1`) all match the stored `USyyyyNNNNNNNAn` value. Previously the value was sent verbatim and bare digits never matched. Values already containing `*` pass through unchanged.
|
|
40
|
+
- **Breaking:** `get_patent`, `get_publication`, `get_pct` (publication form), and the search-based branches of `get_IFW_metadata` now return `None` on no match, as documented. The search endpoint answers no-match with HTTP 404, which previously surfaced as `USPTOApiNotFoundError`. Code that caught that exception from these methods should check for `None` instead.
|
|
41
|
+
- Unit tests no longer depend on `USPTO_*` variables set in the developer's shell. An autouse fixture in `tests/conftest.py` clears every variable `USPTOConfig` reads (`USPTO_API_KEY`, the `USPTO_*_BASE_URL` variables, and the HTTP-setting variables such as `USPTO_REQUEST_TIMEOUT`) before each unit test.
|
|
42
|
+
- `petition_decisions_example.py` no longer fails when rerun (its document download now passes `overwrite=True`), and its pagination example prints each decision under a page header.
|
|
43
|
+
- Pagination on clients whose `count` is the total (every client except bulk data) requested one page past the end when the total number of results was an exact multiple of the page size. The petition API answers that request with a 404.
|
|
44
|
+
- `BulkDataClient.paginate_products` returned at most two pages of products (for example 20 of 47 with `limit=10`). The bulk data API's `count` is the size of the current page, not the total, so pagination now stops on a short page, or on the 404 the API returns past the last product.
|
|
45
|
+
- POST pagination in `paginate_applications`, `paginate_decisions` (petitions, PTAB appeals, PTAB interferences), and `paginate_proceedings` failed with a 400 unless `post_body` already had a `pagination` dict, because the API rejects top-level `offset`/`limit`. Offset and limit now always go in `post_body["pagination"]`, and a top-level `limit` raises `ValueError`.
|
|
46
|
+
- `paginate_decisions` repeated and skipped decisions (about 1 in 5) because the API orders tied records differently on each request. It now appends `petitionDecisionRecordIdentifier asc` to the sort.
|
|
47
|
+
- Docstring examples that failed against the API: a top-level `limit` in POST bodies (petitions, PTAB appeals, PTAB interferences), an unknown `download_decisions` argument, dead decision IDs, a string `fields` in the `paginate_applications` POST body, and PTAB queries on field names the API doesn't have.
|
|
48
|
+
- Documented the `filters` syntax for petition and PTAB searches: `"field value"` with a space, not a colon (the API rejects the colon form), and PTAB field names are nested (e.g. `decisionData.decisionTypeCategory`). Unit tests now use valid filter strings.
|
|
49
|
+
- `get_decision_by_id(..., include_documents=...)` returned an unrelated decision, with only a `USPTODataMismatchWarning`: any query parameter on that endpoint, including the documented `includeDocuments`, makes the API ignore the ID.
|
|
50
|
+
- The contributor docs implied the development environment runs on Python 3.11, but its documentation tools (Sphinx 9.1) need 3.12+. `CONTRIBUTING.md` and the installation page now state 3.12+ as the development minimum.
|
|
51
|
+
- An API error whose JSON body isn't an object (a list, string, or number) raised `AttributeError` while the exception was being built. It now falls back to the HTTP reason and the response text, like any other body without error fields.
|
|
52
|
+
- Archive downloads now extract only regular files from a TAR. Named pipes and device files are skipped, and the archive's permission bits and ownership are no longer applied, so a setuid flag is dropped and files get default permissions. Previously Python 3.11–3.13 recreated these entries as stored, and Python 3.14 stopped partway with `tarfile.SpecialFileError`.
|
|
53
|
+
- A ZIP download holding one file whose stored name contains `..` (e.g. `a/../b.txt`) returned a path that didn't exist. It now returns the path the file was written to.
|
|
54
|
+
|
|
8
55
|
## [0.5.5] - 2026-07-22
|
|
9
56
|
|
|
10
57
|
### Added
|
|
@@ -22,8 +22,6 @@ cd pyUSPTO
|
|
|
22
22
|
|
|
23
23
|
### Set Up Development Environment
|
|
24
24
|
|
|
25
|
-
> **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+.
|
|
26
|
-
|
|
27
25
|
```bash
|
|
28
26
|
# Create and activate a virtual environment
|
|
29
27
|
python -m venv venv
|
|
@@ -33,6 +31,8 @@ source venv/bin/activate # On Windows: venv\Scripts\activate
|
|
|
33
31
|
pip install -e ".[dev]"
|
|
34
32
|
```
|
|
35
33
|
|
|
34
|
+
> **Note:** The development environment requires Python 3.12+, because the documentation tools in the `dev` extra (Sphinx 9.1) don't support Python 3.11. The package itself supports Python 3.11+.
|
|
35
|
+
|
|
36
36
|
### Create a Branch
|
|
37
37
|
|
|
38
38
|
```bash
|
|
@@ -110,7 +110,7 @@ Types include:
|
|
|
110
110
|
|
|
111
111
|
1. Update the README.md or documentation with details of changes if appropriate
|
|
112
112
|
2. Update the CHANGELOG.md with details of changes
|
|
113
|
-
3. The PR should work for Python 3.
|
|
113
|
+
3. The PR should work for Python 3.11 and above
|
|
114
114
|
4. PRs require approval from at least one maintainer
|
|
115
115
|
5. Once approved, a maintainer will merge your PR
|
|
116
116
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyUSPTO
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.1
|
|
4
4
|
Summary: A Modern Python client for accessing the United States Patent and Trademark Office (USPTO) Open Data Portal (ODP) APIs.
|
|
5
5
|
Author-email: Andrew Piechocki <apiechocki@dunlapcodding.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -11,11 +11,11 @@ Project-URL: Documentation, https://pyuspto.readthedocs.io/en/latest/
|
|
|
11
11
|
Project-URL: releasenotes, https://github.com/DunlapCoddingPC/pyUSPTO/releases/latest
|
|
12
12
|
Keywords: uspto,patent,odp,client,bulk data,patent data
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
19
19
|
Classifier: Operating System :: OS Independent
|
|
20
20
|
Classifier: Development Status :: 5 - Production/Stable
|
|
21
21
|
Classifier: Environment :: Console
|
|
@@ -37,18 +37,16 @@ Classifier: Topic :: Office/Business
|
|
|
37
37
|
Classifier: Topic :: Scientific/Engineering :: Interface Engine/Protocol Translator
|
|
38
38
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
39
39
|
Classifier: Topic :: Utilities
|
|
40
|
-
Requires-Python: >=3.
|
|
40
|
+
Requires-Python: >=3.11
|
|
41
41
|
Description-Content-Type: text/markdown
|
|
42
42
|
License-File: LICENSE
|
|
43
43
|
Requires-Dist: requests>=2.32.5
|
|
44
|
-
Requires-Dist: typing-extensions>=4.15.0; python_version < "3.11"
|
|
45
44
|
Requires-Dist: tzdata>=2026.1
|
|
46
45
|
Requires-Dist: urllib3>=2.0.0
|
|
47
46
|
Provides-Extra: test
|
|
48
47
|
Requires-Dist: pytest>=9.0.2; extra == "test"
|
|
49
48
|
Requires-Dist: pytest-cov>=7.0.0; extra == "test"
|
|
50
49
|
Requires-Dist: pytest-mock>=3.15.1; extra == "test"
|
|
51
|
-
Requires-Dist: typing_extensions>=4.15.0; extra == "test"
|
|
52
50
|
Provides-Extra: docs
|
|
53
51
|
Requires-Dist: sphinx>=9.1.0; extra == "docs"
|
|
54
52
|
Requires-Dist: sphinx-rtd-theme>=3.1.0; extra == "docs"
|
|
@@ -69,27 +67,27 @@ Dynamic: license-file
|
|
|
69
67
|
|
|
70
68
|
[](https://badge.fury.io/py/pyUSPTO)
|
|
71
69
|
[](https://opensource.org/licenses/MIT)
|
|
72
|
-
[](https://www.python.org/downloads/)
|
|
73
71
|
[](https://pyuspto.readthedocs.io/en/latest/)
|
|
74
72
|
[](https://pepy.tech/projects/pyuspto)
|
|
75
73
|
|
|
76
|
-
A Python client library for interacting with the United
|
|
74
|
+
A Python client library for interacting with the United States Patent and Trademark Office (USPTO) [Open Data Portal](https://data.uspto.gov/home) APIs.
|
|
77
75
|
|
|
78
|
-
This package provides clients for interacting with the USPTO Bulk Data API, Patent Data API,
|
|
76
|
+
This package provides clients for interacting with the USPTO Bulk Data API, Patent Data API, Petition Decisions API, PTAB (Patent Trial and Appeal Board) APIs, Enriched Citations API, Office Action Text Retrieval API, Office Action Rejections API, and Office Action Citations API.
|
|
79
77
|
|
|
80
78
|
> [!IMPORTANT]
|
|
81
|
-
> The USPTO
|
|
79
|
+
> The USPTO has moved the Developer API to the Open Data Portal. This package is only concerned with the USPTO Open Data Portal API. The old API (`https://developer.uspto.gov/`) was formally decommissioned on June 5, 2026.
|
|
82
80
|
|
|
83
81
|
## Quick Start
|
|
84
82
|
|
|
85
|
-
**Requirements**: Python ≥3.
|
|
83
|
+
**Requirements**: Python ≥3.11
|
|
86
84
|
|
|
87
85
|
```bash
|
|
88
86
|
pip install pyUSPTO
|
|
89
87
|
```
|
|
90
88
|
|
|
91
89
|
> [!IMPORTANT]
|
|
92
|
-
> You must have an API key for the [USPTO Open Data Portal API](https://data.uspto.gov/
|
|
90
|
+
> You must have an API key for the [USPTO Open Data Portal](https://data.uspto.gov/home) APIs. You can get one from the [Manage API Key](https://data.uspto.gov/apikey) page.
|
|
93
91
|
|
|
94
92
|
```python
|
|
95
93
|
from pyUSPTO import PatentDataClient, USPTOConfig
|
|
@@ -128,7 +126,7 @@ from pyUSPTO import (
|
|
|
128
126
|
OACitationsClient,
|
|
129
127
|
OARejectionsClient,
|
|
130
128
|
PatentDataClient,
|
|
131
|
-
|
|
129
|
+
PetitionDecisionsClient,
|
|
132
130
|
PTABTrialsClient,
|
|
133
131
|
PTABAppealsClient,
|
|
134
132
|
PTABInterferencesClient,
|
|
@@ -140,7 +138,7 @@ config = USPTOConfig.from_env()
|
|
|
140
138
|
|
|
141
139
|
patent_client = PatentDataClient(config=config)
|
|
142
140
|
bulk_client = BulkDataClient(config=config)
|
|
143
|
-
petition_client =
|
|
141
|
+
petition_client = PetitionDecisionsClient(config=config)
|
|
144
142
|
trials_client = PTABTrialsClient(config=config)
|
|
145
143
|
appeals_client = PTABAppealsClient(config=config)
|
|
146
144
|
interferences_client = PTABInterferencesClient(config=config)
|
|
@@ -167,7 +165,7 @@ config = USPTOConfig(api_key="your_api_key_here")
|
|
|
167
165
|
|
|
168
166
|
1. [Patent Data API](#patent-data-api)
|
|
169
167
|
2. [Bulk Data API](#bulk-data-api)
|
|
170
|
-
3. [
|
|
168
|
+
3. [Petition Decisions API](#petition-decisions-api)
|
|
171
169
|
4. [PTAB Trials API](#ptab-trials-api)
|
|
172
170
|
5. [PTAB Appeals API](#ptab-appeals-api)
|
|
173
171
|
6. [PTAB Interferences API](#ptab-interferences-api)
|
|
@@ -231,13 +229,13 @@ print(f"Product: {product.product_title_text}")
|
|
|
231
229
|
|
|
232
230
|
See [`examples/bulk_data_example.py`](examples/bulk_data_example.py) for detailed examples including file downloads and archive extraction.
|
|
233
231
|
|
|
234
|
-
###
|
|
232
|
+
### Petition Decisions API
|
|
235
233
|
|
|
236
234
|
```python
|
|
237
|
-
from pyUSPTO import
|
|
235
|
+
from pyUSPTO import PetitionDecisionsClient, USPTOConfig
|
|
238
236
|
|
|
239
237
|
config = USPTOConfig(api_key="your_api_key_here")
|
|
240
|
-
client =
|
|
238
|
+
client = PetitionDecisionsClient(config=config)
|
|
241
239
|
|
|
242
240
|
# Search for petition decisions
|
|
243
241
|
response = client.search_decisions(
|
|
@@ -250,7 +248,19 @@ response = client.search_decisions(limit=1)
|
|
|
250
248
|
if response.count > 0:
|
|
251
249
|
decision_id = response.petition_decision_data_bag[0].petition_decision_record_identifier
|
|
252
250
|
decision = client.get_decision_by_id(decision_id)
|
|
253
|
-
print(f"Decision Type: {decision.
|
|
251
|
+
print(f"Decision Type: {decision.decided_petition_type_code_description_text}")
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
`PetitionDecisionsClient` returns final and non-final decisions. For final decisions only, use `FinalPetitionDecisionsClient`, which restricts every search, pagination, and `download_decisions` call to final decisions and returns `None` from `get_decision_by_id` for a non-final decision:
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
from pyUSPTO import FinalPetitionDecisionsClient
|
|
258
|
+
|
|
259
|
+
final_client = FinalPetitionDecisionsClient(config=config)
|
|
260
|
+
response = final_client.search_decisions(
|
|
261
|
+
decision_date_from_q="2023-01-01", decision_date_to_q="2023-12-31", limit=5
|
|
262
|
+
)
|
|
263
|
+
print(f"Found {response.count} final decisions from 2023.")
|
|
254
264
|
```
|
|
255
265
|
|
|
256
266
|
See [`examples/petition_decisions_example.py`](examples/petition_decisions_example.py) for detailed examples including downloading decision documents.
|
|
@@ -2,27 +2,27 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/py/pyUSPTO)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://www.python.org/downloads/)
|
|
6
6
|
[](https://pyuspto.readthedocs.io/en/latest/)
|
|
7
7
|
[](https://pepy.tech/projects/pyuspto)
|
|
8
8
|
|
|
9
|
-
A Python client library for interacting with the United
|
|
9
|
+
A Python client library for interacting with the United States Patent and Trademark Office (USPTO) [Open Data Portal](https://data.uspto.gov/home) APIs.
|
|
10
10
|
|
|
11
|
-
This package provides clients for interacting with the USPTO Bulk Data API, Patent Data API,
|
|
11
|
+
This package provides clients for interacting with the USPTO Bulk Data API, Patent Data API, Petition Decisions API, PTAB (Patent Trial and Appeal Board) APIs, Enriched Citations API, Office Action Text Retrieval API, Office Action Rejections API, and Office Action Citations API.
|
|
12
12
|
|
|
13
13
|
> [!IMPORTANT]
|
|
14
|
-
> The USPTO
|
|
14
|
+
> The USPTO has moved the Developer API to the Open Data Portal. This package is only concerned with the USPTO Open Data Portal API. The old API (`https://developer.uspto.gov/`) was formally decommissioned on June 5, 2026.
|
|
15
15
|
|
|
16
16
|
## Quick Start
|
|
17
17
|
|
|
18
|
-
**Requirements**: Python ≥3.
|
|
18
|
+
**Requirements**: Python ≥3.11
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
pip install pyUSPTO
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
> [!IMPORTANT]
|
|
25
|
-
> You must have an API key for the [USPTO Open Data Portal API](https://data.uspto.gov/
|
|
25
|
+
> You must have an API key for the [USPTO Open Data Portal](https://data.uspto.gov/home) APIs. You can get one from the [Manage API Key](https://data.uspto.gov/apikey) page.
|
|
26
26
|
|
|
27
27
|
```python
|
|
28
28
|
from pyUSPTO import PatentDataClient, USPTOConfig
|
|
@@ -61,7 +61,7 @@ from pyUSPTO import (
|
|
|
61
61
|
OACitationsClient,
|
|
62
62
|
OARejectionsClient,
|
|
63
63
|
PatentDataClient,
|
|
64
|
-
|
|
64
|
+
PetitionDecisionsClient,
|
|
65
65
|
PTABTrialsClient,
|
|
66
66
|
PTABAppealsClient,
|
|
67
67
|
PTABInterferencesClient,
|
|
@@ -73,7 +73,7 @@ config = USPTOConfig.from_env()
|
|
|
73
73
|
|
|
74
74
|
patent_client = PatentDataClient(config=config)
|
|
75
75
|
bulk_client = BulkDataClient(config=config)
|
|
76
|
-
petition_client =
|
|
76
|
+
petition_client = PetitionDecisionsClient(config=config)
|
|
77
77
|
trials_client = PTABTrialsClient(config=config)
|
|
78
78
|
appeals_client = PTABAppealsClient(config=config)
|
|
79
79
|
interferences_client = PTABInterferencesClient(config=config)
|
|
@@ -100,7 +100,7 @@ config = USPTOConfig(api_key="your_api_key_here")
|
|
|
100
100
|
|
|
101
101
|
1. [Patent Data API](#patent-data-api)
|
|
102
102
|
2. [Bulk Data API](#bulk-data-api)
|
|
103
|
-
3. [
|
|
103
|
+
3. [Petition Decisions API](#petition-decisions-api)
|
|
104
104
|
4. [PTAB Trials API](#ptab-trials-api)
|
|
105
105
|
5. [PTAB Appeals API](#ptab-appeals-api)
|
|
106
106
|
6. [PTAB Interferences API](#ptab-interferences-api)
|
|
@@ -164,13 +164,13 @@ print(f"Product: {product.product_title_text}")
|
|
|
164
164
|
|
|
165
165
|
See [`examples/bulk_data_example.py`](examples/bulk_data_example.py) for detailed examples including file downloads and archive extraction.
|
|
166
166
|
|
|
167
|
-
###
|
|
167
|
+
### Petition Decisions API
|
|
168
168
|
|
|
169
169
|
```python
|
|
170
|
-
from pyUSPTO import
|
|
170
|
+
from pyUSPTO import PetitionDecisionsClient, USPTOConfig
|
|
171
171
|
|
|
172
172
|
config = USPTOConfig(api_key="your_api_key_here")
|
|
173
|
-
client =
|
|
173
|
+
client = PetitionDecisionsClient(config=config)
|
|
174
174
|
|
|
175
175
|
# Search for petition decisions
|
|
176
176
|
response = client.search_decisions(
|
|
@@ -183,7 +183,19 @@ response = client.search_decisions(limit=1)
|
|
|
183
183
|
if response.count > 0:
|
|
184
184
|
decision_id = response.petition_decision_data_bag[0].petition_decision_record_identifier
|
|
185
185
|
decision = client.get_decision_by_id(decision_id)
|
|
186
|
-
print(f"Decision Type: {decision.
|
|
186
|
+
print(f"Decision Type: {decision.decided_petition_type_code_description_text}")
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
`PetitionDecisionsClient` returns final and non-final decisions. For final decisions only, use `FinalPetitionDecisionsClient`, which restricts every search, pagination, and `download_decisions` call to final decisions and returns `None` from `get_decision_by_id` for a non-final decision:
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
from pyUSPTO import FinalPetitionDecisionsClient
|
|
193
|
+
|
|
194
|
+
final_client = FinalPetitionDecisionsClient(config=config)
|
|
195
|
+
response = final_client.search_decisions(
|
|
196
|
+
decision_date_from_q="2023-01-01", decision_date_to_q="2023-12-31", limit=5
|
|
197
|
+
)
|
|
198
|
+
print(f"Found {response.count} final decisions from 2023.")
|
|
187
199
|
```
|
|
188
200
|
|
|
189
201
|
See [`examples/petition_decisions_example.py`](examples/petition_decisions_example.py) for detailed examples including downloading decision documents.
|
|
@@ -16,8 +16,9 @@ grants, bulk data downloads, PTAB proceedings, Office Actions, and more.
|
|
|
16
16
|
|
|
17
17
|
.. note::
|
|
18
18
|
|
|
19
|
-
An API key is required to use the ODP APIs. You can register for one
|
|
20
|
-
`
|
|
19
|
+
An API key is required to use the ODP APIs. You can register for one on the
|
|
20
|
+
`Manage API Key <https://data.uspto.gov/apikey>`_ page of the
|
|
21
|
+
`USPTO Open Data Portal <https://data.uspto.gov/home>`_.
|
|
21
22
|
|
|
22
23
|
Available Clients
|
|
23
24
|
-----------------
|
|
@@ -34,8 +35,10 @@ pyUSPTO provides the following clients:
|
|
|
34
35
|
- Search patent applications and grants, retrieve file wrappers and Image File Wrapper (IFW) documents, and download individual documents and publications.
|
|
35
36
|
* - :class:`~pyUSPTO.BulkDataClient`
|
|
36
37
|
- Search and download bulk data products from the ODP Bulk Dataset Directory, including patent grants, applications, assignments, and research datasets.
|
|
38
|
+
* - :class:`~pyUSPTO.PetitionDecisionsClient`
|
|
39
|
+
- Search and retrieve petition decisions issued by the USPTO.
|
|
37
40
|
* - :class:`~pyUSPTO.FinalPetitionDecisionsClient`
|
|
38
|
-
-
|
|
41
|
+
- Same as PetitionDecisionsClient, limited to final petition decisions.
|
|
39
42
|
* - :class:`~pyUSPTO.PTABTrialsClient`
|
|
40
43
|
- Search PTAB trial proceedings (IPR, PGR, CBM, and derivation), documents, and decisions.
|
|
41
44
|
* - :class:`~pyUSPTO.PTABAppealsClient`
|
|
@@ -54,5 +57,5 @@ pyUSPTO provides the following clients:
|
|
|
54
57
|
Requirements
|
|
55
58
|
------------
|
|
56
59
|
|
|
57
|
-
- Python 3.
|
|
60
|
+
- Python 3.11 or higher
|
|
58
61
|
- A USPTO Open Data Portal API key
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
Installation
|
|
2
|
+
============
|
|
3
|
+
|
|
4
|
+
pyUSPTO requires Python 3.11 or higher. Install the latest release from
|
|
5
|
+
`PyPI <https://pypi.org/project/pyUSPTO/>`_:
|
|
6
|
+
|
|
7
|
+
.. code-block:: bash
|
|
8
|
+
|
|
9
|
+
pip install pyUSPTO
|
|
10
|
+
|
|
11
|
+
If you use `uv <https://docs.astral.sh/uv/>`_, add pyUSPTO to your project
|
|
12
|
+
with:
|
|
13
|
+
|
|
14
|
+
.. code-block:: bash
|
|
15
|
+
|
|
16
|
+
uv add pyUSPTO
|
|
17
|
+
|
|
18
|
+
or install it into a virtual environment with ``uv pip install pyUSPTO``.
|
|
19
|
+
|
|
20
|
+
To use the library you will also need a USPTO Open Data Portal API key — see
|
|
21
|
+
:doc:`about` for how to get one.
|
|
22
|
+
|
|
23
|
+
Development Installation
|
|
24
|
+
------------------------
|
|
25
|
+
|
|
26
|
+
To work on pyUSPTO itself, clone the repository and install it in editable
|
|
27
|
+
mode with the development dependencies:
|
|
28
|
+
|
|
29
|
+
.. code-block:: bash
|
|
30
|
+
|
|
31
|
+
git clone https://github.com/DunlapCoddingPC/pyUSPTO.git
|
|
32
|
+
cd pyUSPTO
|
|
33
|
+
pip install -e ".[dev]"
|
|
34
|
+
|
|
35
|
+
.. note::
|
|
36
|
+
|
|
37
|
+
The development environment requires Python 3.12+, because the
|
|
38
|
+
documentation tools in the ``dev`` extra (Sphinx 9.1) don't support
|
|
39
|
+
Python 3.11. The package itself supports Python 3.11+.
|
|
40
|
+
|
|
41
|
+
See the :doc:`contributing guidelines <development>` for the full development
|
|
42
|
+
workflow, including running tests and linting.
|
|
@@ -39,7 +39,7 @@ if pat_no_ifw and pat_no_ifw.application_meta_data:
|
|
|
39
39
|
print(f" IFW found via patent number: {patent_number}")
|
|
40
40
|
|
|
41
41
|
# Publication number
|
|
42
|
-
publication_number = "
|
|
42
|
+
publication_number = "20150157873"
|
|
43
43
|
pub_no_ifw = client.get_IFW_metadata(publication_number=publication_number)
|
|
44
44
|
if pub_no_ifw and pub_no_ifw.application_meta_data:
|
|
45
45
|
print(f"Title: {pub_no_ifw.application_meta_data.invention_title}")
|
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
"""Example usage of pyUSPTO for
|
|
1
|
+
"""Example usage of pyUSPTO for Petition Decisions.
|
|
2
2
|
|
|
3
|
-
Demonstrates the
|
|
3
|
+
Demonstrates the PetitionDecisionsClient for searching decisions,
|
|
4
4
|
downloading decision data, and paginating results.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import json
|
|
8
8
|
import os
|
|
9
9
|
|
|
10
|
-
from pyUSPTO import
|
|
10
|
+
from pyUSPTO import (
|
|
11
|
+
PetitionDecisionDownloadResponse,
|
|
12
|
+
PetitionDecisionsClient,
|
|
13
|
+
USPTOConfig,
|
|
14
|
+
)
|
|
11
15
|
|
|
12
16
|
DEST_PATH = "./notes/download-example"
|
|
13
17
|
|
|
@@ -18,7 +22,7 @@ if api_key == "YOUR_API_KEY_HERE":
|
|
|
18
22
|
"API key is not set. Set the USPTO_API_KEY environment variable."
|
|
19
23
|
)
|
|
20
24
|
config = USPTOConfig(api_key=api_key)
|
|
21
|
-
client =
|
|
25
|
+
client = PetitionDecisionsClient(config=config)
|
|
22
26
|
|
|
23
27
|
print("-" * 40)
|
|
24
28
|
print("Example 1: Basic search")
|
|
@@ -31,7 +35,7 @@ print(f"Displaying first {len(response.petition_decision_data_bag)} decisions:")
|
|
|
31
35
|
for decision in response.petition_decision_data_bag:
|
|
32
36
|
print(f"\n Decision ID: {decision.petition_decision_record_identifier}")
|
|
33
37
|
print(f" Application Number: {decision.application_number_text}")
|
|
34
|
-
print(f" Decision Type: {decision.
|
|
38
|
+
print(f" Decision Type: {decision.decided_petition_type_code_description_text}")
|
|
35
39
|
print(f" Decision Date: {decision.decision_date}")
|
|
36
40
|
print(f" Technology Center: {decision.technology_center}")
|
|
37
41
|
|
|
@@ -53,13 +57,13 @@ print("-" * 40)
|
|
|
53
57
|
print("Example 2: Search with custom query")
|
|
54
58
|
print("-" * 40)
|
|
55
59
|
|
|
56
|
-
response = client.search_decisions(query="
|
|
57
|
-
print(f"Found {response.count} decisions
|
|
60
|
+
response = client.search_decisions(query="decidedPetitionTypeCode:C", limit=3)
|
|
61
|
+
print(f"Found {response.count} DENIED decisions.")
|
|
58
62
|
print(f"Showing {len(response.petition_decision_data_bag)} results:")
|
|
59
63
|
|
|
60
64
|
for decision in response.petition_decision_data_bag:
|
|
61
65
|
print(
|
|
62
|
-
f" - {decision.petition_decision_record_identifier}: {decision.
|
|
66
|
+
f" - {decision.petition_decision_record_identifier}: {decision.decided_petition_type_code}"
|
|
63
67
|
)
|
|
64
68
|
|
|
65
69
|
print("-" * 40)
|
|
@@ -96,7 +100,9 @@ if response.count > 0:
|
|
|
96
100
|
print(f" ID: {decision.petition_decision_record_identifier}")
|
|
97
101
|
print(f" Application: {decision.application_number_text}")
|
|
98
102
|
print(f" Patent: {decision.patent_number}")
|
|
99
|
-
print(
|
|
103
|
+
print(
|
|
104
|
+
f" Decision Type: {decision.decided_petition_type_code_description_text}"
|
|
105
|
+
)
|
|
100
106
|
print(f" Decision Date: {decision.decision_date}")
|
|
101
107
|
print(f" Technology Center: {decision.technology_center}")
|
|
102
108
|
print(f" Group Art Unit: {decision.group_art_unit_number}")
|
|
@@ -117,7 +123,6 @@ if response.count > 0:
|
|
|
117
123
|
print(f" - Doc ID: {doc.document_identifier}")
|
|
118
124
|
print(f" Date: {doc.official_date}")
|
|
119
125
|
print(f" Doc. Code: {doc.document_code_description_text}")
|
|
120
|
-
print(f" Direction: {doc.direction_category}")
|
|
121
126
|
if doc.download_option_bag:
|
|
122
127
|
print(
|
|
123
128
|
f" Download Options: {len(doc.download_option_bag)}"
|
|
@@ -157,11 +162,19 @@ print("Example 6: Paginate through results")
|
|
|
157
162
|
print("-" * 40)
|
|
158
163
|
|
|
159
164
|
max_items = 30
|
|
165
|
+
page_size = 10
|
|
160
166
|
count = 0
|
|
161
167
|
for decision in client.paginate_decisions(
|
|
162
|
-
limit=
|
|
168
|
+
limit=page_size, query="decisionDate:[2023-01-01 TO 2023-12-31]"
|
|
163
169
|
):
|
|
170
|
+
if count % page_size == 0:
|
|
171
|
+
print(f" Page {count // page_size + 1} (offset {count}):")
|
|
164
172
|
count += 1
|
|
173
|
+
print(
|
|
174
|
+
f" {count}. {decision.application_number_text} - "
|
|
175
|
+
f"{decision.decided_petition_type_code_description_text}"
|
|
176
|
+
)
|
|
177
|
+
|
|
165
178
|
if count >= max_items:
|
|
166
179
|
print(f" ... (stopping at {max_items} items)")
|
|
167
180
|
break
|
|
@@ -177,9 +190,7 @@ response = client.search_decisions(limit=20)
|
|
|
177
190
|
|
|
178
191
|
document_found = False
|
|
179
192
|
for decision in response.petition_decision_data_bag:
|
|
180
|
-
d = client.get_decision_by_id(
|
|
181
|
-
decision.petition_decision_record_identifier, include_documents=True
|
|
182
|
-
)
|
|
193
|
+
d = client.get_decision_by_id(decision.petition_decision_record_identifier)
|
|
183
194
|
print(
|
|
184
195
|
f"Getting docs for patent: {d.invention_title} with id: {d.petition_decision_record_identifier}"
|
|
185
196
|
) # type: ignore
|
|
@@ -198,6 +209,7 @@ for decision in response.petition_decision_data_bag:
|
|
|
198
209
|
file_path = client.download_petition_document(
|
|
199
210
|
download_option=download_option,
|
|
200
211
|
destination=DEST_PATH,
|
|
212
|
+
overwrite=True,
|
|
201
213
|
)
|
|
202
214
|
print(f"Downloaded to: {file_path}")
|
|
203
215
|
|
|
@@ -9,16 +9,16 @@ authors = [
|
|
|
9
9
|
{ name = "Andrew Piechocki", email = "apiechocki@dunlapcodding.com" },
|
|
10
10
|
]
|
|
11
11
|
readme = "README.md"
|
|
12
|
-
requires-python = ">=3.
|
|
12
|
+
requires-python = ">=3.11"
|
|
13
13
|
license = "MIT"
|
|
14
14
|
license-files = ["LICENSE*"]
|
|
15
15
|
classifiers = [
|
|
16
16
|
"Programming Language :: Python :: 3",
|
|
17
|
-
"Programming Language :: Python :: 3.10",
|
|
18
17
|
"Programming Language :: Python :: 3.11",
|
|
19
18
|
"Programming Language :: Python :: 3.12",
|
|
20
19
|
"Programming Language :: Python :: 3.13",
|
|
21
20
|
"Programming Language :: Python :: 3.14",
|
|
21
|
+
"Programming Language :: Python :: 3.15",
|
|
22
22
|
"Operating System :: OS Independent",
|
|
23
23
|
"Development Status :: 5 - Production/Stable",
|
|
24
24
|
"Environment :: Console",
|
|
@@ -45,7 +45,6 @@ classifiers = [
|
|
|
45
45
|
keywords = ["uspto", "patent", "odp", "client", "bulk data", "patent data"]
|
|
46
46
|
dependencies = [
|
|
47
47
|
"requests>=2.32.5",
|
|
48
|
-
"typing-extensions>=4.15.0; python_version < '3.11'",
|
|
49
48
|
"tzdata>=2026.1",
|
|
50
49
|
"urllib3>=2.0.0",
|
|
51
50
|
]
|
|
@@ -56,7 +55,6 @@ test = [
|
|
|
56
55
|
"pytest>=9.0.2",
|
|
57
56
|
"pytest-cov>=7.0.0",
|
|
58
57
|
"pytest-mock>=3.15.1",
|
|
59
|
-
"typing_extensions>=4.15.0",
|
|
60
58
|
]
|
|
61
59
|
docs = [
|
|
62
60
|
"sphinx>=9.1.0",
|
|
@@ -89,7 +87,7 @@ pyUSPTO = ["py.typed"]
|
|
|
89
87
|
|
|
90
88
|
[tool.ruff]
|
|
91
89
|
line-length = 88
|
|
92
|
-
target-version = "
|
|
90
|
+
target-version = "py311"
|
|
93
91
|
|
|
94
92
|
[tool.ruff.lint]
|
|
95
93
|
# Enable pycodestyle (E), Pyflakes (F), pydocstyle (D), isort (I), and pyupgrade (UP)
|