Metadata-Version: 2.4
Name: thegenesis-api-client
Version: 0.1.0
Summary: Genesis publisher API client for Python.
Author: Genesis
License-Expression: MIT
Project-URL: Documentation, https://docs.thegenesis.com/sdk/python
Project-URL: Homepage, https://thegenesis.com
Project-URL: Issues, https://github.com/thegenesis/genesis/issues
Project-URL: Repository, https://github.com/thegenesis/genesis
Keywords: genesis,advertising,ai-agents,sponsored-offers
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Dynamic: license-file

# Genesis Python API Client

Publisher-side client for requesting offers, recording optional signals, and tracking impressions or clicks.

```python
from genesis import GenesisClient, GenesisConfig, OfferRequest, hash_identifier

client = GenesisClient(
    GenesisConfig(
        api_key="gn_test_...",
        mode="test",
        tracking_proxy_base_url="https://app.example.com/genesis-track",
    )
)

response = client.request_offers(
    OfferRequest(
        placement_id="chat_recommendation_after_answer",
        app_id="app_docs_quickstart",
        user_id_hash=hash_identifier("internal-user-id"),
        message="I need a SOC 2 monitoring tool for a seed-stage SaaS company.",
        categories=["security_compliance", "developer_tools"],
        conversation_context=[
            {"role": "user", "content": "Compare SOC 2 monitoring tools."}
        ],
        locale="en-US",
        country="US",
        workflow_state="post_answer",
        device={"type": "server"},
        max_offers=2,
        allowed_categories=["developer_tools", "security_compliance"],
        blocked_categories=["finance_operations"],
        allowed_advertiser_ids=["adv_example"],
        blocked_advertiser_ids=["adv_blocked"],
        allow_formats=["action_card", "lead_form"],
        disable_tracking=False,
        allow_restricted_categories=False,
        require_disclosure=True,
        signals=[
            {
                "type": "recommendation_request",
                "confidence": 0.84,
                "subject": "SOC 2 monitoring",
                "related_subjects": ["evidence automation"],
                "value": "security_compliance",
                "placement_id": "chat_recommendation_after_answer",
                "purpose": "offer_request_context",
            }
        ],
        metadata={"integration": "readme"},
    )
)
```

Request several placements with shared context:

```python
batch = client.request_offers_batch(
    {
        "placements": [
            {
                "placement_id": "chat_inline_offer",
                "app_id": "app_docs_quickstart",
                "agent_type": "conversational_assistant",
                "surface": "chat",
            },
            {
                "placement_id": "chat_sidebar_offer",
                "app_id": "app_docs_quickstart",
                "agent_type": "conversational_assistant",
                "surface": "chat",
            },
        ],
        "message": "Compare SOC 2 monitoring tools.",
        "categories": ["security_compliance", "developer_tools"],
        "max_offers": 1,
    }
)
```

Network failures return a safe no-fill response by default so publisher applications can continue without blocking the user experience. Transient HTTP failures are retried according to `GenesisConfig.retries`. Request fields are normalized to the public `/v1/offers` schema, and fields outside that schema are omitted. Offer responses expose hosted tracking URLs, `variant`, `experimentId`, `compositionId`, `rendererKey`, `noFill`, `latencyMs`, and timeout diagnostics when the API returns them.

Release a reservation only if the offer was not rendered:

```python
result = client.release_reservation(response["offers"][0], idempotency_key="release-for-my-request")
```

The offer needs its placement token and request ID. Retries reuse the same key;
the optional explicit key also lets a caller reuse it across separate attempts.
Failures and rendered-offer conflicts raise rather than reporting a false release.

Prompt weaving supports `none`, `separate_section`, `inline_when_relevant`,
`offers_only`, and `always_disclose`:

```python
from genesis import get_referenced_offer_tracking_urls, weave_offers_into_prompt

woven = weave_offers_into_prompt(response["offers"], mode="separate_section")
if woven["has_offers"]:
    prompt = woven["text"]
    impression_urls = get_referenced_offer_tracking_urls(rendered_text, woven["offers"])
```

Select `inline_when_relevant` only after confirming relevance. Sponsored text
always carries disclosure, and returned references preserve hosted click and
impression URLs. Fire an impression only after the end user sees a rendered
response that actually references the offer.

Set `tracking_proxy_base_url` only when your publisher app forwards Genesis
hosted tracking through a first-party route. The client rewrites Genesis
`/v1/track/...` impression and click URLs while leaving the reviewed advertiser
destination URL unchanged.
