# How it works

## HTTP traffic interception

In a nutshell, `pook` uses `unittest.mock` standard Python package in order to patch external library objects, allowing `pook` HTTP interceptor adaptor to patch any third-party packages and intercept specific function calls.

`pook` entirely relies on this interception strategy, therefore in the meantime `pook` is active, any outgoing HTTP traffic intercepted by the supported HTTP clients won’t imply any real TCP networking, except if you enabled the real networking mode via `pook.enable_network()`, which in that case real network traffic can be established.

Worth clarifying that `pook` only works at Python programmatic runtime level. There’s no network/socket programming involved.

## HTTP request matching

Outgoing HTTP traffic is intercepted and matched against a pool of mock matchers defined in your mock expectations.

Matching process in sequential and executed as FIFO order, meaning the first has always preference.

For instance, if you declare multiple identical mocks, the first one will be matched first and the others will be ignored. Once the first one expires, the subsequent mock definition in the chain will be matched instead.

## Real networking mode

By default, real networking mode is disabled. This basically means that real networking will not happen unless you explicitly enable it.

This behaviour has been adopted to improve predictability, control and mitigate developers fear between behaviour boundaries and expectations.

`pook` will prevent you to communicate with real HTTP servers unless you enable it via: `pook.enable_network()`.

Also, you can partially restrict the real networking by filtering only certain hosts. You can do that via `pook.use_network_filter()`.

## Volatile vs Persistent mocks

By default, mocks are volatile. This means that once a mock has been matched, and therefore consumed, it will be flushed.

You can modify this behaviour via:

Explicitly defining the TTL of each mock, so effectively the number of times the mock can be matched and consumed:

    # Match a mock up to 5 times, then flush it
    pook.get('server.com/api').times(5)

    # The above is equivalent to
    pook.get('server.com/api', times=5)

Explicitly defining a persistent mock:

    # Make a mock definition persistent, so it won't ever be flushed
    pook.get('server.com/api').persist()

    # The above is equivalent to
    pook.get('server.com/api', persist=True)