From patent-client-agents
Provides async Python clients for patent/IP research from USPTO, EPO, JPO. Use for patent lookups by number/keyword, status checks, family/citations, assignments, full-text, and MPEP/CPC.
npx claudepluginhub parkerhancock/patent-client-agents --plugin patent-client-agentsThis skill uses the workspace's default tool permissions.
Async Python clients for patent and IP data. All clients use `async with` context
__init__.pyinstall.shreferences/cache.mdreferences/cpc.mdreferences/epo_ops.mdreferences/google_patents.mdreferences/jpo.mdreferences/mpep.mdreferences/uspto_applications.mdreferences/uspto_assignments.mdreferences/uspto_bulkdata.mdreferences/uspto_odp.mdreferences/uspto_office_actions.mdreferences/uspto_petitions.mdreferences/uspto_publications.mdAccesses USPTO APIs like PatentSearch, PEDS, TSDR for patent/trademark searches, examination history, assignments, citations, office actions. Supports IP analysis, prior art searches, and portfolio review.
Accesses USPTO patent data via PatentsView REST API and Google Patents BigQuery. Searches by inventor, assignee, CPC, keywords; analyzes portfolios, tracks trends for prior art search, competitor monitoring, and biotech IP analysis.
Accesses USPTO APIs for patent/trademark searches by keywords/inventors/assignees, PEDS examination history, assignments, citations, office actions, TSDR status; enables IP analysis and prior art searches.
Share bugs, ideas, or general feedback.
Async Python clients for patent and IP data. All clients use async with context
managers. All shared scaffolding (HTTP, cache, retry, errors) lives in
law_tools_core, shipped in the same wheel.
| Task | Client / Module | Reference |
|---|---|---|
| Patent lookup / search by keywords | google_patents.GooglePatentsClient | google_patents.md |
| USPTO application status + file wrapper | uspto_odp.ApplicationsClient | uspto_odp.md |
| USPTO application high-level API | patent_client_agents.uspto_applications | uspto_applications.md |
| USPTO PTAB (IPR/PGR/CBM, ex parte appeals, interferences) | uspto_odp.PtabTrialsClient / PtabAppealsClient / PtabInterferencesClient | uspto_odp.md |
| USPTO petitions | uspto_odp.PetitionsClient or patent_client_agents.uspto_petitions | uspto_petitions.md |
| USPTO bulk data products | uspto_odp.BulkDataClient or patent_client_agents.uspto_bulkdata | uspto_bulkdata.md |
| USPTO assignments | uspto_assignments.AssignmentCenterClient | uspto_assignments.md |
| USPTO publications (PPUBS) full-text | uspto_publications.PublicSearchClient | uspto_publications.md |
| USPTO office actions | patent_client_agents.uspto_office_actions | uspto_office_actions.md |
| EPO bibliographic / family / legal events | epo_ops.EpoOpsClient | epo_ops.md |
| JPO application status | jpo.JpoClient | jpo.md |
| MPEP search + section lookup | patent_client_agents.mpep | mpep.md |
| CPC lookup / search / mapping | patent_client_agents.cpc | cpc.md |
from patent_client_agents.google_patents import GooglePatentsClient
async with GooglePatentsClient() as client:
patent = await client.get_patent_data("US10123456B2")
from patent_client_agents.uspto_odp import ApplicationsClient
async with ApplicationsClient() as client: # Requires USPTO_ODP_API_KEY
results = await client.search(query="inventionTitle:laser", limit=25)
for record in results.applicationBag:
print(record.applicationNumberText, record.filingDate)
from patent_client_agents.uspto_odp import PtabTrialsClient
async with PtabTrialsClient() as client:
proceedings = await client.search_proceedings(query="patent:US10123456")
from patent_client_agents.mpep import SearchInput, search
response = await search(SearchInput(query="obviousness rejection", per_page=10))
for hit in response.hits:
print(hit.section_id, hit.title)
from patent_client_agents.cpc import retrieve_cpc
entry = await retrieve_cpc(symbol="H04L63/08", ancestors=True)
All clients raise typed exceptions from law_tools_core.exceptions. ApiError
and its subclasses include a path to the log file in their string representation
so agents can inspect stacktraces without keeping them in context.
from law_tools_core.exceptions import (
LawToolsCoreError,
NotFoundError,
RateLimitError,
)
try:
async with GooglePatentsClient() as client:
patent = await client.get_patent_data("US99999999")
except NotFoundError as e:
print(e) # "... (HTTP 404, details: ~/.cache/patent_client_agents/patent_client_agents.log)"
except RateLimitError as e:
if e.retry_after:
await asyncio.sleep(e.retry_after)
except LawToolsCoreError as e:
print(e) # Fallback for any other typed error
Exception hierarchy (from law_tools_core.exceptions):
| Exception | When |
|---|---|
NotFoundError | Resource not found (404) |
RateLimitError | Rate limit exceeded (429); retry_after set if server supplied it |
AuthenticationError | Bad or missing API credentials (401/403) |
ServerError | Remote API 5xx |
ApiError | Other HTTP errors (base for all HTTP-level errors; appends log path) |
ParseError | Failed to parse response data |
ConfigurationError | Missing API key / invalid config |
ValidationError | Invalid input; also inherits ValueError |
LawToolsCoreError | Base for all typed errors |
Log file: ~/.cache/patent_client_agents/patent_client_agents.log — full tracebacks, request/response
details, debug info. Read this when concise error messages aren't enough.
| Variable | Required For |
|---|---|
USPTO_ODP_API_KEY | All USPTO ODP clients (Applications, PTAB, BulkData, Petitions, Office Actions) |
EPO_OPS_API_KEY | EPO OPS, CPC (CPC uses EPO OPS under the hood) |
EPO_OPS_API_SECRET | EPO OPS, CPC |
JPO_API_USERNAME | JPO client |
JPO_API_PASSWORD | JPO client |
USPTO Publications, USPTO Assignments, Google Patents, and MPEP require no API key.
All clients cache HTTP responses to ~/.cache/patent_client_agents/ using hishel with a
SQLite backend and WAL pragmas. See cache.md for TTL,
invalidation, and statistics APIs.
Source: parkerhancock/ip_tools
Report bugs with version, minimal reproduction code, and relevant API response if applicable.