pyUSPTO 0.5.7__tar.gz → 0.6.0__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.
Files changed (175) hide show
  1. {pyuspto-0.5.7 → pyuspto-0.6.0}/.github/workflows/python-tests.yml +1 -1
  2. {pyuspto-0.5.7 → pyuspto-0.6.0}/ADVANCED.md +1 -1
  3. {pyuspto-0.5.7 → pyuspto-0.6.0}/CHANGELOG.md +47 -0
  4. {pyuspto-0.5.7 → pyuspto-0.6.0}/CONTRIBUTING.md +3 -3
  5. {pyuspto-0.5.7/src/pyUSPTO.egg-info → pyuspto-0.6.0}/PKG-INFO +28 -18
  6. {pyuspto-0.5.7 → pyuspto-0.6.0}/README.md +25 -13
  7. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/about.rst +7 -4
  8. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/configuration.rst +1 -1
  9. pyuspto-0.6.0/docs/source/examples/oa_rejections.rst +6 -0
  10. pyuspto-0.6.0/docs/source/installation.rst +42 -0
  11. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/ifw_example.py +1 -1
  12. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/petition_decisions_example.py +26 -14
  13. {pyuspto-0.5.7 → pyuspto-0.6.0}/pyproject.toml +3 -5
  14. {pyuspto-0.5.7 → pyuspto-0.6.0}/requirements-dev.txt +30 -32
  15. {pyuspto-0.5.7 → pyuspto-0.6.0}/requirements.txt +5 -5
  16. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/__init__.py +6 -2
  17. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/__init__.py +5 -1
  18. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/base.py +91 -59
  19. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/bulk_data.py +5 -0
  20. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/patent_data.py +50 -19
  21. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/petition_decisions.py +142 -50
  22. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/ptab_appeals.py +11 -3
  23. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/ptab_interferences.py +7 -2
  24. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/ptab_trials.py +9 -3
  25. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/config.py +1 -1
  26. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/exceptions.py +6 -2
  27. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/patent_data.py +8 -7
  28. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/petition_decisions.py +75 -55
  29. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/ptab.py +1 -6
  30. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/utils.py +6 -6
  31. {pyuspto-0.5.7 → pyuspto-0.6.0/src/pyUSPTO.egg-info}/PKG-INFO +28 -18
  32. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO.egg-info/requires.txt +0 -4
  33. pyuspto-0.6.0/src/pyUSPTO.egg-info/scm_version.json +8 -0
  34. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/test_base.py +258 -62
  35. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/test_bulk_data_clients.py +40 -6
  36. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/test_patent_data_clients.py +77 -13
  37. pyuspto-0.6.0/tests/clients/test_petition_decision_clients.py +1760 -0
  38. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/test_ptab_appeals_client.py +6 -6
  39. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/test_ptab_interferences_client.py +6 -6
  40. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/test_ptab_trials_client.py +10 -10
  41. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/conftest.py +39 -0
  42. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/test_bulk_data_integration.py +18 -0
  43. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/test_patent_data_integration.py +66 -2
  44. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/test_petition_decisions_integration.py +325 -158
  45. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/models/test_patent_data_models.py +14 -15
  46. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/models/test_petition_decision_models.py +76 -55
  47. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/models/test_ptab_models.py +6 -49
  48. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/models/test_utils.py +13 -15
  49. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/test_exceptions.py +24 -0
  50. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/test_http_config.py +0 -13
  51. {pyuspto-0.5.7 → pyuspto-0.6.0}/tox.ini +2 -4
  52. pyuspto-0.5.7/docs/source/examples/oa_rejections.rst +0 -6
  53. pyuspto-0.5.7/docs/source/installation.rst +0 -14
  54. pyuspto-0.5.7/src/pyUSPTO.egg-info/scm_version.json +0 -8
  55. pyuspto-0.5.7/tests/clients/test_petition_decision_clients.py +0 -938
  56. {pyuspto-0.5.7 → pyuspto-0.6.0}/.devcontainer/devcontainer-lock.json +0 -0
  57. {pyuspto-0.5.7 → pyuspto-0.6.0}/.devcontainer/devcontainer.json +0 -0
  58. {pyuspto-0.5.7 → pyuspto-0.6.0}/.github/ISSUE_TEMPLATE/bug-report.yml +0 -0
  59. {pyuspto-0.5.7 → pyuspto-0.6.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  60. {pyuspto-0.5.7 → pyuspto-0.6.0}/.github/ISSUE_TEMPLATE/documentation-updates.yml +0 -0
  61. {pyuspto-0.5.7 → pyuspto-0.6.0}/.github/ISSUE_TEMPLATE/feature-request.yml +0 -0
  62. {pyuspto-0.5.7 → pyuspto-0.6.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  63. {pyuspto-0.5.7 → pyuspto-0.6.0}/.github/dependabot.yml +0 -0
  64. {pyuspto-0.5.7 → pyuspto-0.6.0}/.github/workflows/codeql.yml +0 -0
  65. {pyuspto-0.5.7 → pyuspto-0.6.0}/.github/workflows/publish-docs.yaml +0 -0
  66. {pyuspto-0.5.7 → pyuspto-0.6.0}/.github/workflows/publish-to-test-pypi.yml +0 -0
  67. {pyuspto-0.5.7 → pyuspto-0.6.0}/.gitignore +0 -0
  68. {pyuspto-0.5.7 → pyuspto-0.6.0}/.readthedocs.yaml +0 -0
  69. {pyuspto-0.5.7 → pyuspto-0.6.0}/CODE_OF_CONDUCT.md +0 -0
  70. {pyuspto-0.5.7 → pyuspto-0.6.0}/LICENSE +0 -0
  71. {pyuspto-0.5.7 → pyuspto-0.6.0}/_version.pyi +0 -0
  72. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/Makefile +0 -0
  73. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/_static/.gitkeep +0 -0
  74. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/advanced.rst +0 -0
  75. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/bulk_data.rst +0 -0
  76. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/enriched_citations.rst +0 -0
  77. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/index.rst +0 -0
  78. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/oa_actions.rst +0 -0
  79. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/oa_citations.rst +0 -0
  80. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/oa_rejections.rst +0 -0
  81. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/patent_data.rst +0 -0
  82. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/petition_decisions.rst +0 -0
  83. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/ptab_appeals.rst +0 -0
  84. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/ptab_interferences.rst +0 -0
  85. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/clients/ptab_trials.rst +0 -0
  86. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/config/config.rst +0 -0
  87. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/config/http_config.rst +0 -0
  88. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/config/index.rst +0 -0
  89. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/exceptions.rst +0 -0
  90. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/index.rst +0 -0
  91. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/base.rst +0 -0
  92. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/bulk_data.rst +0 -0
  93. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/enriched_citations.rst +0 -0
  94. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/index.rst +0 -0
  95. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/oa_actions.rst +0 -0
  96. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/oa_citations.rst +0 -0
  97. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/oa_rejections.rst +0 -0
  98. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/patent_data.rst +0 -0
  99. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/petition_decisions.rst +0 -0
  100. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/ptab.rst +0 -0
  101. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/models/utils.rst +0 -0
  102. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/api/warnings.rst +0 -0
  103. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/conf.py +0 -0
  104. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/development.rst +0 -0
  105. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/bulk_data.rst +0 -0
  106. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/enriched_citations.rst +0 -0
  107. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/ifw_example.rst +0 -0
  108. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/index.rst +0 -0
  109. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/oa_actions.rst +0 -0
  110. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/oa_citations.rst +0 -0
  111. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/patent_data.rst +0 -0
  112. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/petition_decisions.rst +0 -0
  113. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/ptab_appeals.rst +0 -0
  114. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/ptab_interferences.rst +0 -0
  115. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/examples/ptab_trials.rst +0 -0
  116. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/index.rst +0 -0
  117. {pyuspto-0.5.7 → pyuspto-0.6.0}/docs/source/quickstart.rst +0 -0
  118. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/bulk_data_example.py +0 -0
  119. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/enriched_citations_example.py +0 -0
  120. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/error_handling_example.py +0 -0
  121. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/oa_actions_example.py +0 -0
  122. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/oa_citations_example.py +0 -0
  123. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/oa_rejections_example.py +0 -0
  124. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/patent_data_example.py +0 -0
  125. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/ptab_appeals_example.py +0 -0
  126. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/ptab_interferences_example.py +0 -0
  127. {pyuspto-0.5.7 → pyuspto-0.6.0}/examples/ptab_trials_example.py +0 -0
  128. {pyuspto-0.5.7 → pyuspto-0.6.0}/pyUSPTO.code-workspace +0 -0
  129. {pyuspto-0.5.7 → pyuspto-0.6.0}/setup.cfg +0 -0
  130. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/enriched_citations.py +0 -0
  131. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/oa_actions.py +0 -0
  132. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/oa_citations.py +0 -0
  133. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/clients/oa_rejections.py +0 -0
  134. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/http_config.py +0 -0
  135. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/__init__.py +0 -0
  136. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/base.py +0 -0
  137. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/bulk_data.py +0 -0
  138. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/enriched_citations.py +0 -0
  139. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/oa_actions.py +0 -0
  140. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/oa_citations.py +0 -0
  141. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/models/oa_rejections.py +0 -0
  142. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/py.typed +0 -0
  143. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/utils/__init__.py +0 -0
  144. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO/warnings.py +0 -0
  145. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO.egg-info/SOURCES.txt +0 -0
  146. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO.egg-info/dependency_links.txt +0 -0
  147. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO.egg-info/scm_file_list.json +0 -0
  148. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO.egg-info/top_level.txt +0 -0
  149. {pyuspto-0.5.7 → pyuspto-0.6.0}/src/pyUSPTO.egg-info/zip-safe +0 -0
  150. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/__init__.py +0 -0
  151. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/__init__.py +0 -0
  152. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/test_enriched_citation_clients.py +0 -0
  153. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/test_oa_actions_clients.py +0 -0
  154. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/test_oa_citations_clients.py +0 -0
  155. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/clients/test_oa_rejections_clients.py +0 -0
  156. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/__init__.py +0 -0
  157. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/conftest.py +0 -0
  158. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/test_enriched_citations_integration.py +0 -0
  159. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/test_oa_actions_integration.py +0 -0
  160. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/test_oa_citations_integration.py +0 -0
  161. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/test_oa_rejections_integration.py +0 -0
  162. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/test_ptab_appeals_integration.py +0 -0
  163. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/test_ptab_interferences_integration.py +0 -0
  164. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/integration/test_ptab_trials_integration.py +0 -0
  165. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/models/__init__.py +0 -0
  166. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/models/test_bulk_data_models.py +0 -0
  167. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/models/test_enriched_citation_models.py +0 -0
  168. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/models/test_oa_actions_models.py +0 -0
  169. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/models/test_oa_citations_models.py +0 -0
  170. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/models/test_oa_rejections_models.py +0 -0
  171. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/test_config.py +0 -0
  172. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/test_edge_cases.py +0 -0
  173. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/test_init.py +0 -0
  174. {pyuspto-0.5.7 → pyuspto-0.6.0}/tests/test_version.py +0 -0
  175. {pyuspto-0.5.7 → pyuspto-0.6.0}/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.10", "3.11", "3.12", "3.13", "3.14"]
14
+ python-version: ["3.11", "3.12", "3.13", "3.14", "3.15"]
15
15
 
16
16
  steps:
17
17
  - uses: actions/checkout@v7
@@ -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 = FinalPetitionDecisionsClient(config=petition_config)
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.10 and above
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.5.7
3
+ Version: 0.6.0
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.10
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
  [![PyPI version](https://badge.fury.io/py/pyUSPTO.svg)](https://badge.fury.io/py/pyUSPTO)
71
69
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
72
- [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
70
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
73
71
  [![Read the Docs](https://img.shields.io/readthedocs/pyuspto)](https://pyuspto.readthedocs.io/en/latest/)
74
72
  [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyuspto?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLUE&right_color=GREY&left_text=downloads)](https://pepy.tech/projects/pyuspto)
75
73
 
76
- A Python client library for interacting with the United Stated Patent and Trademark Office (USPTO) [Open Data Portal](https://data.uspto.gov/home) APIs.
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, Final 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.
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 is in the process of moving their Developer API. This package is only concerned with the new API. The [old API](https://developer.uspto.gov/) was officially retired at the end of 2025; however, some products have not yet been fully transitioned to the Open Data Portal API. The USPTO expects the remaining products to be transitioned to the Open Data Portal in early 2026.
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.10
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/myodp/landing).
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
- FinalPetitionDecisionsClient,
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 = FinalPetitionDecisionsClient(config=config)
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. [Final Petition Decisions API](#final-petition-decisions-api)
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
- ### Final Petition Decisions API
232
+ ### Petition Decisions API
235
233
 
236
234
  ```python
237
- from pyUSPTO import FinalPetitionDecisionsClient, USPTOConfig
235
+ from pyUSPTO import PetitionDecisionsClient, USPTOConfig
238
236
 
239
237
  config = USPTOConfig(api_key="your_api_key_here")
240
- client = FinalPetitionDecisionsClient(config=config)
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.decision_type_code}")
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
  [![PyPI version](https://badge.fury.io/py/pyUSPTO.svg)](https://badge.fury.io/py/pyUSPTO)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
5
+ [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
6
6
  [![Read the Docs](https://img.shields.io/readthedocs/pyuspto)](https://pyuspto.readthedocs.io/en/latest/)
7
7
  [![PyPI Downloads](https://static.pepy.tech/personalized-badge/pyuspto?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLUE&right_color=GREY&left_text=downloads)](https://pepy.tech/projects/pyuspto)
8
8
 
9
- A Python client library for interacting with the United Stated Patent and Trademark Office (USPTO) [Open Data Portal](https://data.uspto.gov/home) APIs.
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, Final 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.
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 is in the process of moving their Developer API. This package is only concerned with the new API. The [old API](https://developer.uspto.gov/) was officially retired at the end of 2025; however, some products have not yet been fully transitioned to the Open Data Portal API. The USPTO expects the remaining products to be transitioned to the Open Data Portal in early 2026.
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.10
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/myodp/landing).
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
- FinalPetitionDecisionsClient,
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 = FinalPetitionDecisionsClient(config=config)
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. [Final Petition Decisions API](#final-petition-decisions-api)
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
- ### Final Petition Decisions API
167
+ ### Petition Decisions API
168
168
 
169
169
  ```python
170
- from pyUSPTO import FinalPetitionDecisionsClient, USPTOConfig
170
+ from pyUSPTO import PetitionDecisionsClient, USPTOConfig
171
171
 
172
172
  config = USPTOConfig(api_key="your_api_key_here")
173
- client = FinalPetitionDecisionsClient(config=config)
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.decision_type_code}")
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 at the
20
- `USPTO Open Data Portal <https://data.uspto.gov/myodp/landing>`_.
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
- - Search and retrieve Final Petition Decisions issued by the USPTO Director.
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.10 or higher
60
+ - Python 3.11 or higher
58
61
  - A USPTO Open Data Portal API key
@@ -4,4 +4,4 @@ Configuration
4
4
  .. include:: ../../README.md
5
5
  :parser: myst_parser.sphinx_
6
6
  :start-after: ## Configuration
7
- :end-before: ## API Usage Examples
7
+ :end-before: ## Client Usage Examples
@@ -0,0 +1,6 @@
1
+ OA Rejections Example
2
+ =====================
3
+
4
+ .. literalinclude:: ../../../examples/oa_rejections_example.py
5
+ :language: python
6
+ :linenos:
@@ -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 = "*20150157873*"
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 Final Petition Decisions.
1
+ """Example usage of pyUSPTO for Petition Decisions.
2
2
 
3
- Demonstrates the FinalPetitionDecisionsClient for searching decisions,
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 FinalPetitionDecisionsClient, PetitionDecisionDownloadResponse, USPTOConfig
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 = FinalPetitionDecisionsClient(config=config)
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.decision_type_code}")
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="decisionTypeCode:C", limit=3)
57
- print(f"Found {response.count} decisions with C type.")
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.decision_type_code}"
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(f" Decision Type: {decision.decision_type_code}")
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=10, query="decisionDate:[2023-01-01 TO 2023-12-31]"
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.10"
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 = "py310"
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)