Skip to main content

NotPixel Python SDK (notpixel)

Official Python SDK for NotPixel — privacy-first contextual monetization for LLM applications, agents, and backends (FastAPI, Django, Flask, LangChain, LlamaIndex, CrewAI).

Installation

pip install "notpixel>=0.3.0"

Quick Start (Async — FastAPI / LangChain)

from notpixel import AsyncAds

# Ad matching uses local embeddings automatically.
# Prompt text is not sent to the NotPixel API.
ads = AsyncAds(publisher_id="pub_10565")

# 1. Fetch a contextual ad + run your LLM in parallel (best-effort)
result = await ads.respond(
    input="How do I optimize PostgreSQL queries with indexes?",
    llm=lambda: call_my_llm("How do I optimize PostgreSQL queries with indexes?"),
)
print(result.text)  # LLM response + sponsored ad block (if matched)

# 2. Track events
if result.ad:
    await ads.impression(result.ad)
    await ads.track_click(result.ad, metadata={"source": "fastapi_chat"})
    await ads.track_conversion(
        result.ad,
        type="signup",
        value_cents=2900,
        external_id="order_12345",
    )

Synchronous Usage (Django WSGI / Scripts)

from notpixel import Ads

ads = Ads(publisher_id="pub_10565")
ad = ads.get_ad(input="Best serverless Postgres database")
if ad:
    print(ad.text)
    ads.track_click(ad)

Privacy

Ad matching uses local embeddings automatically. The SDK sends a numerical vector to NotPixel instead of the prompt text. No privacy flag is needed.

If the local model cannot generate an embedding, get_ad() reports the error through on_error and returns None, without sending the prompt to NotPixel.

Your LLM calls remain under your application's control and follow your provider's own data handling rules. Keep personal data out of optional context and event metadata.

All-in-one inference

from notpixel import Ads, AsyncAds

# Set NOTPIXEL_MODEL=provider/model and its API key, or pass model= explicitly.
ads = Ads(publisher_id="pub_xxx", model="openai/your-model")
result = ads.offer(input="How can I optimize PostgreSQL?")
print(result.text)

# Same contract, asynchronous I/O.
async_ads = AsyncAds(publisher_id="pub_xxx", model="anthropic/your-model")
result = await async_ads.offer(input="How can I optimize PostgreSQL?")

offer() runs inference and ad selection concurrently. The original prompt goes only to your selected LLM provider. Only a local embedding goes to NotPixel. A sponsored block is appended after inference; no ad is injected into the LLM prompt. When no ad is available, the exact LLM output is returned unchanged.

Supported prefixes: openai, openrouter, anthropic, google, xai, deepseek, groq, mistral, perplexity, together, github, nvidia, alibaba, minimax, llama, lmstudio, vercel, netlify. Unknown prefixes and identifiers without a prefix route through OpenRouter. Gateway model suffixes may contain slashes. Availability of any particular model depends on your provider account.

Streaming

from contextlib import aclosing, closing

with closing(ads.stream(input="Explain database indexes")) as stream:
    for chunk in stream:
        if chunk.type == "text":
            print(chunk.content, end="", flush=True)
        elif chunk.type == "ad":
            print(chunk.content)  # Structured ad is also available in chunk.ad.

async with aclosing(async_ads.stream(input="Explain database indexes")) as stream:
    async for chunk in stream:
        if chunk.type == "text":
            print(chunk.content, end="", flush=True)

Events are text, then optionally one ad, then done. Provider failures emit an error event and raise LLMError when iteration resumes, without a successful done. Configuration errors raise before streaming starts. Ad failures never interrupt LLM output. An ad is emitted only after the text stream finishes.

Use closing/aclosing when breaking out early. Cancelling the consuming asyncio task closes upstream HTTP streams and releases ad work owned by that consumer. Shared ad requests continue while another consumer is waiting. A synchronous thread already computing an embedding cannot be forcibly interrupted; it finishes in the background when its work/network timeout completes.

The default ad timeout is 1,500 ms; inference uses a separate configurable llm_timeout_ms=60000 network timeout. Inference is never automatically retried, including after partial output. The ad retries option applies only to NotPixel requests and preserves the request ID across attempts.

Batch, prefetch and callbacks

batch = ads.ads_batch(inputs=["SQL indexes", "Cloud hosting"], limit=1)
batch = await async_ads.ads_batch(inputs=["SQL indexes", "Cloud hosting"],
                                  max_concurrency=8, dedupe=True)
await async_ads.prefetch(["SQL indexes", "Cloud hosting"])
await async_ads.embedding.preload()

Both batch clients default to eight concurrent operations, preserve input order, count every outcome before deduplication, and apply limit only to the final ad list. Empty lists return empty results. Prefetch enables cache automatically; ads.cache.stats(), clear() and cleanup() are available on both clients.

respond() continues to accept your own LLM callable. Its optional context, publisher_id and request_id are forwarded to ad selection. AsyncAds awaits async LLM/callback functions and moves synchronous LLM work off the event loop. Analytics hooks can be synchronous in both clients or asynchronous in AsyncAds. Async hooks finish before the operation returns; hook failures do not fail serving. The synchronous client requires synchronous callbacks.

Configuration and adapters

Precedence is call arguments, then constructor configuration, then environment (where an environment equivalent exists). Input has no environment default.

Variable Purpose
NOTPIXEL_MODEL Default provider/model
NOTPIXEL_LOCALE Default locale (pt)
NOTPIXEL_BASE_URL NotPixel API origin
NOTPIXEL_TIMEOUT_MS Ad HTTP timeout (default 1500)
NOTPIXEL_RETRIES Ad retries (default 0)
NOTPIXEL_MIN_SCORE Optional lexical post-filter (default 0, disabled)
NOTPIXEL_MOCK 1 mocks ads; LLM inference still uses its configured transport
NOTPIXEL_LOG 1 opts into console inference logs

Provider keys: OPENAI_API_KEY, OPENROUTER_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY (or GEMINI_API_KEY), XAI_API_KEY, DEEPSEEK_API_KEY, GROQ_API_KEY, MISTRAL_API_KEY, PERPLEXITY_API_KEY, TOGETHER_API_KEY, GITHUB_TOKEN, NVIDIA_API_KEY, DASHSCOPE_API_KEY, MINIMAX_API_KEY, LLAMA_API_KEY, VERCEL_API_KEY, NETLIFY_API_KEY. LM Studio needs no key.

For custom endpoints or per-call credentials, use provider_respond() / async_provider_respond() with provider, model, input, api_key and optional base_url. Named helpers such as anthropic_respond() and async_anthropic_respond() share that contract. openai_respond_http() uses Responses; openai_respond(client, ...) accepts an existing provider SDK client. openai_compatible_respond(base_url="https://host/v1", ...) and its async counterpart support arbitrary OpenAI-compatible endpoints and custom headers.

For connection pooling, pass llm_client=httpx.Client(...) or AsyncClient(...) to the constructor and close it in your application lifecycle. Injected clients are owned by your application. The existing transport option remains exclusively for NotPixel ad/event requests. No provider SDK is a runtime dependency.

logger=callback receives typed LogEvent objects. Logs are off by default and contain prompts/output when enabled. API keys and raw HTTP error bodies are never included in SDK-generated inference errors or log events.

PrivacyConfig(dtype="q8" | "fp16" | "fp32", on_progress=callback) selects the default BGE artifact. Progress reports loading/ready/error states, not downloaded byte counts. Custom FastEmbed models use their registered precision; unsupported overrides fail explicitly. Custom embedder callables retain responsibility for their own precision. Backend/model compatibility is required for custom vectors.

auto_track="server" (default) documents the API's serving-time impression; auto_track="manual" is available for explicit impression() calls. This option does not change server billing or imply viewability measurement. Track impressions only when appropriate to your integration's lifecycle.

Examples and validation

See FastAPI streaming, Django view, and the backend parity matrix. Install example dependencies using the dev extra. These examples keep credentials and inference in your backend.

The contract suite runs against simulated HTTP transports and embeddings. It does not certify live provider/model availability or production serving. Version 0.3.0 provides the backend capabilities described in the parity matrix.

Metadata

Release files for notpixel 0.3.0

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

Source distribution (sdist)

Source distribution for notpixel 0.3.0
File Size Uploaded Provenance
notpixel-0.3.0.tar.gz 40.1 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for notpixel 0.3.0
File Interpreter ABI Platform
notpixel-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 67.4 kB

Release files / notpixel-0.3.0.tar.gz

Download URL notpixel-0.3.0.tar.gz
Size 40.1 kB
Tags Source
SHA-256 checksum
How to use checksums
2f226ebe39f88b2345a4970ca5ba7be9a3caf862df3e0ae0036e966352223230
BLAKE2b-256 checksum
How to use checksums
a7d11908197e52024692ededb6450d99f28696d55f9fb7f5327589888156734c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Oct 23, 2026.

Transparency log

Release files / notpixel-0.3.0-py3-none-any.whl

Download URL notpixel-0.3.0-py3-none-any.whl
Size 27.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
48737f567031170328f78f4787cf54341575f0f9fbf60f1812f2daea914aa8b5
BLAKE2b-256 checksum
How to use checksums
dd5b8df4fa95b45398e008ecace8deebf0bfca8b3388b9a78b453e20b0a5b309
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 Oct 23, 2026.

Transparency log

Security for notpixel 0.3.0

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for notpixel-0.3.0.tar.gz

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 Oct 23, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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