Skip to main content

python-epo-ops-client

PyPI PyPI - Python Version GHA Codecov

python-epo-ops-client is an Apache2 licensed client library for accessing the European Patent Office's ("EPO") Open Patent Services ("OPS") v3.2 (based on v1.3.16 of the reference guide).

import epo_ops

# Instantiate client.
client = epo_ops.Client(key="abc", secret="xyz")

# Retrieve bibliography data.
response = client.published_data(

  # publication, application, priority
  reference_type="publication",

  # docdb, epodoc
  input=epo_ops.models.Docdb("1000000", "EP", "A1"),

  # optional, defaults to biblio in case of published_data
  endpoint="biblio",

  # optional, list of constituents
  constituents=[],
)

# Retrieve description.
response = client.published_data(
  reference_type="publication",
  input=epo_ops.models.Docdb("1000000", "EP", "A1"),
  endpoint="description",
)

# Retrieve claims.
response = client.published_data(
  reference_type="publication",
  input=epo_ops.models.Docdb("1000000", "EP", "A1"),
  endpoint="claims",
)

Features

python-epo-ops-client abstracts away the complexities of accessing EPO OPS:

  • Format the requests properly
  • Bubble up quota problems as proper HTTP errors
  • Handle token authentication and renewals automatically
  • Handle throttling properly
  • Add optional caching to minimize impact on the OPS servers

There are two main layers to python-epo-ops-client: Client and Middleware.

Client

The Client contains all the formatting and token handling logic and is what you'll interact with mostly.

When you issue a request, the response is a requests.Response object. If response.status_code != 200 then a requests.HTTPError exception will be raised — it's your responsibility to handle those exceptions if you want to. This default can be disabled by passing raise_for_status=False when constructing the client. The one case that's handled is when the access token has expired: in this case, the client will automatically handle the HTTP 400 status and renew the token.

Note that the Client does not attempt to interpret the data supplied by OPS, so it's your responsibility to parse the XML or JSON payload for your own purpose.

The following custom exceptions are raised for cases when OPS quotas are exceeded, they are all in the epo_ops.exceptions module and are subclasses of requests.HTTPError, and therefore offer the same behaviors:

  • IndividualQuotaPerHourExceeded
  • RegisteredQuotaPerWeekExceeded

Again, it's up to you to parse the response and decide what to do.

Currently the Client knows how to issue request for the following services:

Client method API end point throttle
family(reference_type, input, endpoint=None, constituents=None) family inpadoc
image(path, range=1, extension='tiff') published-data/images images
legal(reference_type, input) legal other
number(reference_type, input, output_format) number-service other
published_data(reference_type, input, endpoint='biblio', constituents=None) published-data retrieval
published_data_search(cql, range_begin=1, range_end=25, constituents=None) published-data/search search
register(reference_type, input, constituents=['biblio']) register other
register_search(cql, range_begin=1, range_end=25) register/search other

Bulk operations can be achieved by passing a list of valid models to the published_data input field.

See the OPS guide or use the Developer's Area for more information on how to use each service.

Please submit pull requests for the following services by enhancing the epo_ops.api.Client class:

  • Legal service

Middleware

All requests and responses are passed through each middleware object listed in client.middlewares. Requests are processed in the order listed, and responses are processed in the reverse order.

Each middleware should subclass middlewares.Middleware and implement the process_request and process_response methods.

There are two middleware classes out of the box: Throttler and Dogpile. Throttler is in charge of the OPS throttling rules and will delay requests accordingly. Dogpile is an optional cache which will cache all HTTP status 200, 404, 405, and 413 responses.

By default, only the Throttler middleware is enabled, if you want to enable caching:

import epo_ops

middlewares = [
    epo_ops.middlewares.Dogpile(),
    epo_ops.middlewares.Throttler(),
]
client = epo_ops.Client(
    key='key',
    secret='secret',
    middlewares=middlewares,
)

You'll also need to install caching dependencies in your projects, such as pip install dogpile.cache.

Note that caching middleware should be first in most cases.

Dogpile

Dogpile is based on (surprise) dogpile.cache. By default it is instantiated with a DBMBackend region with timeout of 2 weeks.

Dogpile takes three optional instantiation parameters:

  • region: You can pass whatever valid dogpile.cache Region you want to backend the cache
  • kwargs_handlers: A list of keyword argument handlers, which it will use to process the kwargs passed to the request object in order to extract elements for generating the cache key. Currently one handler is implemented (and instantiated by default) to make sure that the range request header is part of the cache key.
  • http_status_codes: A list of HTTP status codes that you would like to have cached. By default 200, 404, 405, and 413 responses are cached.

Note: dogpile.cache is not installed by default, if you want to use it, pip install dogpile.cache in your project.

Throttler

Throttler contains all the logic for handling different throttling scenarios. Since OPS throttling is based on a one minute rolling window, we must persist historical (at least for the past minute) throtting data in order to know what the proper request frequency is. Each Throttler must be instantiated with a Storage object.

Storage

The Storage object is responsible for:

  1. Knowing how to update the historical record with each request (Storage.update()), making sure to observe the one minute rolling window rule.
  2. Calculating how long to wait before issuing the next request (Storage.delay_for()).

Currently the only Storage backend provided is SQLite, but you can easily write your own Storage backend (such as file, Redis, etc.). To use a custom Storage type, just pass the Storage object when you're instantiating a Throttler object. See epo_ops.middlewares.throttle.storages.Storage for more implementation details.

Release files for python-epo-ops-client 4.2.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for python-epo-ops-client 4.2.2
File Size Uploaded
python_epo_ops_client-4.2.2.tar.gz 31.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for python-epo-ops-client 4.2.2
File Interpreter ABI Platform
python_epo_ops_client-4.2.2-py3-none-any.whl Python 3 none any Details

Total release size: 54.8 kB

Release files / python_epo_ops_client-4.2.2.tar.gz

Download URL python_epo_ops_client-4.2.2.tar.gz
Size 31.8 kB
Tags Source
SHA-256 checksum
How to use checksums
2d2d3ee5a64fdfe7d18e829de59400fa6f0d6bf462ab9180c1d75dd0f390d0a4
BLAKE2b-256 checksum
How to use checksums
4ec908895d361947f1397d957c8f0f472b24988b9f1d8da9d199feb3eed4afec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 16, 2026.

Transparency log

Release files / python_epo_ops_client-4.2.2-py3-none-any.whl

Download URL python_epo_ops_client-4.2.2-py3-none-any.whl
Size 23.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fd4c78a911124b0dba230c8db1b247358a832f8776702ad94bcd15180905a1fe
BLAKE2b-256 checksum
How to use checksums
53f24da87620bfcb3c0cd8afb7d062c38173dde958e1c8d2ba0eb1202ec546ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 16, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

4.2.2 This release

2 release files

4.2.1

2 release files

4.2.0

2 release files

4.1.0

2 release files

4.0.0

2 release files

3.1.3

2 release files

3.1.2

2 release files

3.1.1

2 release files

3.1.0

2 release files

3.0.0

2 release files

2.3.2

2 release files

2.3.1

2 release files

2.3.0

2 release files

2.2.0

2 release files

2.1.0

2 release files

2.0.0

2 release files

1.0.0

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

1 release file

0.1.0

1 release file

0.0.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page