Metadata-Version: 2.4
Name: smart_session
Version: 1.7
Summary: Sync HTTP session wrapper with cache modes, response validation, introspection, and Mongo/network helpers
Author-email: dharmik.vadher@xbyte.io
Maintainer-email: dharmik.vadher@xbyte.io
License-Expression: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests
Requires-Dist: loguru
Dynamic: license-file

# smart_session

`smart_session` wraps sync HTTP clients with disk-backed cache modes, response validation, runtime introspection, and bundled Mongo/network helper utilities.

## Install

```bash
pip install smart_session
```

Prebuilt wheels are intended for Windows x64 CPython 3.10+.

## Import note

The package root currently exports the Mongo helper module eagerly. In the current source layout that means a top-level import also expects:

- `pymongo`
- `python-dotenv`
- a `config.py` file beside your entry script with `FEED`, `MONGO_URI`, and `MONGO_DB`

If those pieces are missing, `import smart_session` will fail before you create a session wrapper.

## Session wrapper

Wrap either a session class or an already-created sync session object:

```python
import requests
from smart_session import session_wrapper

sess = session_wrapper(requests.Session)
resp = sess.get(
    "https://example.com/data.json",
    mode="r",
    filepath="cache/data.json",
    conditions=[lambda r: r.status_code == 200],
)
```

The wrapper supports libraries that expose `.request()` or `.execute_request()`, including `requests`, `curl_cffi`, `cloudscraper`, `tls_client`, `httpx.Client`, and compatible custom clients.

## What changes and what stays the same

- Without `mode`, requests pass straight through to the wrapped session.
- If you pass `filepath` without `mode`, the wrapper defaults to `mode="w"`.
- All original session attributes and methods remain available through the wrapper.
- `sess.docs` prints instance-specific usage help.
- `sess.supported` prints the wrapped session's detected verbs, methods, and attributes.
- `debug_mode=True` logs cache decisions and writes through `loguru`.
- Async sessions are not supported.

## Cache modes

Modes are case-insensitive.

| Mode | Binary mode | Behavior |
|------|-------------|----------|
| `r` | `rb` | Return cache if present, otherwise fetch and save |
| `w` | `wb` | Always fetch live data and overwrite the cache |
| `rr` | `rrb` | Read from cache only and raise if the file is missing |

Supported cache file extensions:

`html`, `json`, `txt`, `xml`, `pdf`, `png`, `jpg`, `jpeg`, `gif`, `csv`, `bin`

## Conditions

`conditions` is a list of callables that run only on live responses before the cache is written.

```python
resp = sess.post(
    "https://example.com/api",
    json={"page": 1},
    mode="w",
    filepath="cache/api.json",
    conditions=[
        lambda r: r.status_code == 200,
        lambda r: len(r.content) > 100,
        lambda r: "error" not in r.text.lower(),
    ],
)
```

If any condition fails, a `ValueError` is raised and nothing is written to disk.

## Cached response behavior

- Live requests return the wrapped client's native response object.
- Cache hits and `rr` replays return a synthesized `requests.Response`.
- Replayed responses are rebuilt from disk content with `status_code = 200`.
- Text cache hits are decoded as UTF-8.
- JSON text cache hits also expose `resp.json()`.

## Public API

```python
from smart_session import (
    session_wrapper,
    info,
    insert_to_db,
    get_local_ip,
    mount_path,
)
```

- `session_wrapper` is the exported `SmartSession` wrapper class.
- `info()` prints package-level help.
- `insert_to_db()` inserts cleaned records into MongoDB.
- `get_local_ip()` returns a cached private LAN IP when available.
- `mount_path()` mounts a UNC share with `net use`.

## Mongo helper utilities

### `insert_to_db`

`insert_to_db(data, output_col, input_field, page_save, feed=FEED, **kwargs)` accepts a single dict or a list of dicts.

Behavior:

- `output_col` can be a `pymongo` collection or a string collection suffix.
- String collections are expanded to `f"{feed}_{output_col}"`.
- Flat fields are cleaned and stored as strings.
- Nested dicts and lists of dicts are inserted recursively into child collections.
- `page_save` must be a relative filename and must match `input_field`.
- `_id` is generated deterministically from the cleaned payload.
- `_datetime` and `_ip` are added automatically.
- Duplicate `_id` inserts are logged and treated as success.

Example:

```python
from smart_session import insert_to_db

insert_to_db(
    {"parcel": "123", "owner": "Jane Doe"},
    output_col="properties",
    input_field="123",
    page_save="123.html",
    source="county_site",
)
```

### `get_local_ip`

Returns the first private IPv4 address found on the host, or `127.0.0.1` as a fallback. The result is cached for the process lifetime.

### `mount_path`

Mounts a UNC share by running Windows `net use` against the share root:

```python
from smart_session import mount_path

mount_path(r"\\server\share\folder", user="admin", pwd="secret")
```

## Introspection helpers

```python
from smart_session import info

info()            # package overview
sess.docs         # detailed session wrapper help
sess.supported    # detected verbs, methods, and attributes
```

## Contact

Dharmik Vadher  
dharmik.vadher@xbyte.io
