Metadata-Version: 2.4
Name: apify-nike-client
Version: 0.1.1
Summary: Python client for the rl1987/nike-api-scraper Apify Actor — Nike.com listings and full product detail.
Author-email: rl1987 <rimantas@keyspace.lt>
License: MIT
Project-URL: Homepage, https://apify.com/rl1987/nike-api-scraper
Project-URL: Source, https://apify.com/rl1987/nike-api-scraper
Keywords: apify,web-scraping,api-client
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests>=2.28
Dynamic: license-file

# apify-nike-client

**Nike.com listings (PLP) and full product detail (PDP), straight from the api.nike.com consumer API.**

Python client for the [`rl1987/nike-api-scraper`](https://apify.com/rl1987/nike-api-scraper) [Apify](https://apify.com) Actor. No local scraping, no proxy management, no anti-bot maintenance — the Actor runs on Apify's infrastructure and this package just starts it, waits, and hands you back the dataset as plain Python dicts.

[Install](#install) · [Quickstart](#quickstart) · [Getting an API token](#getting-an-api-token) · [Input reference](#input-reference) · [Output fields](#output-fields) · [Error handling](#error-handling) · [Pricing](#pricing) · [Async / long-running runs](#advanced-longer-timeouts--polling) · [Links](#links)

## Install

```bash
pip install apify-nike-client
```

Requires Python 3.9+. Only dependency is [`requests`](https://pypi.org/project/requests/).

## Quickstart

```python
from apify_nike_client import NikeClient

client = NikeClient(api_token="apify_api_...")  # see "Getting an API token" below
items = client.run({"searchTerms": ["air force 1"], "fetchProductDetails": True, "maxItems": 20})

for item in items:
    print(item)
```

Real output from the example above (trimmed to a few fields):

```python
{"title": "Nike Air Force 1 '07", "colorDescription": "White/Black", "currentPrice": 115, "url": "https://www.nike.com/t/air-force-1-07-mens-shoes-jBrhbr/CT2302-100"}
```

`run()` blocks until the Actor finishes (usually a few seconds to ~30s depending on `maxItems`) and returns a plain `list[dict]` — the Actor's dataset, one dict per result row.

## Getting an API token

1. Sign up for a free account at [console.apify.com](https://console.apify.com).
2. Go to **Settings → Integrations** and copy your **Personal API token**.
3. Pass it to the client: `NikeClient(api_token="...")`, or read it from an environment variable:

   ```python
   import os
   client = NikeClient(api_token=os.environ["APIFY_TOKEN"])
   ```

Never hardcode the token in source control — use an environment variable or secrets manager.

## Input reference

`run()` takes a single `dict` matching the Actor's input schema. Full/authoritative schema: the **Input** tab on [the Actor's Apify page](https://apify.com/rl1987/nike-api-scraper).

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `categoryUrls` | list[str] | — | Nike category or search-results page URLs (PLP), paginated to the end. |
| `searchTerms` | list[str] | — | Free-text searches, e.g. `["air force 1"]`. |
| `productUrls` | list[str] | — | Individual Nike product page URLs (PDP). |
| `styleColors` | list[str] | — | Bare Nike style codes, e.g. `"CW2288-111"`. |
| `fetchProductDetails` | bool | `False` | Fetch full PDP detail for every listing product. |
| `fetchSizeAvailability` | bool | `False` | Attach live per-size stock to listing products. |
| `maxProductsPerCategory` | int | `0` | Cap per category/search. `0` = all. |
| `maxItems` | int | `0` | Global cap on output rows. `0` = no cap. |
| `country` | str | `"US"` | Marketplace — affects price, currency, and stock. |

At least one of `categoryUrls`, `searchTerms`, `productUrls`, or `styleColors` is required.

## Output fields

Each dict in the returned list is one row from the Actor's dataset. Common fields:

`title`, `subtitle`, `colorDescription`, `styleColor`, `currentPrice`, `fullPrice`, `discountPercentage`, `isOnSale`, `imageUrl`, `url`, `categoryUrl`; PDP rows add `description`, `sizes[]` (with `gtin`, `available`), `colors[]`, `galleryImageUrls`.

Exact field availability can vary by input flags (see table above) — treat unfamiliar/missing keys as optional and use `.get()` rather than `[...]` indexing.

## Error handling

```python
from apify_nike_client import NikeClient, ApifyActorError
import requests

client = NikeClient(api_token="...")

try:
    items = client.run({"searchTerms": ["air force 1"], "fetchProductDetails": True, "maxItems": 20})
except ApifyActorError as e:
    # The Actor run itself failed, timed out, or was aborted on the Apify side.
    print(f"Actor run did not succeed: {e}")
except requests.HTTPError as e:
    # Bad token, malformed input, rate limiting, etc. — an HTTP-level error
    # calling the Apify API (not the Actor run).
    print(f"Apify API request failed: {e}")
```

`ApifyActorError` is raised when the run reaches a terminal non-success status (`FAILED`, `TIMED-OUT`, `ABORTED`) or doesn't finish within `timeout_secs` (default 300s — raise it for `run()` calls with a large `maxItems`, e.g. `NikeClient(api_token="...", timeout_secs=900)`).

## Pricing

Pay-per-event: $0.001/listing row, $0.002/full-detail row, $0.001/product enriched with live size availability. No subscription — see the [Actor's pricing tab](https://apify.com/rl1987/nike-api-scraper) for current rates. Apify also includes a free monthly usage tier that covers light use.

## Advanced: longer timeouts & polling

```python
client = NikeClient(api_token="...", timeout_secs=900)  # allow up to 15 min
items = client.run(actor_input, poll_interval_secs=3.0)   # poll less aggressively
```

## Links

- [Nike API Scraper on Apify](https://apify.com/rl1987/nike-api-scraper) — Actor page, input schema, pricing
- [PyPI package](https://pypi.org/project/apify-nike-client/)
- [Apify API reference](https://docs.apify.com/api/v2) — what this client wraps under the hood

## License

MIT
