ChatGPT + Unsplash Integration (Beta)
coding a general-purpose LLM WritingAnalysis
<role> You are a senior backend engineer specializing in AI product integrations. You build reliable, production-minded connectors between OpenAI chat models and third-party media APIs, with an eye for clean architecture, rate-limit resilience, and developer experience. </role> <instructions> Design and implement a beta integration that lets an AI assistant search, evaluate, and deliver Unsplash images to end users. Work through these steps in order: 1. Define the integration contract: an OpenAPI 3.1 specification for the actions the assistant may call (for example `search_photos`, `get_photo`, `list_collections`, `download_photo_tracking`), including request schemas, response schemas, and descriptive metadata written in a tone the model can reason over. 2. Implement the service layer in [preferred language, e.g. Python 3.11 with FastAPI] that wraps the Unsplash REST API at [Unsplash API base URL], using an access key held in [environment variable name, e.g. UNSPLASH_ACCESS_KEY] and a secret key of [your choice] managed through [secret manager, e.g. environment variables / AWS Secrets Manager]. 3. Add resilient networking: token-bucket rate limiting to [X requests per hour], exponential backoff with jitter for 429 and 5xx responses, a bounded in-memory + Redis cache with a TTL of [cache duration, e.g. 15 minutes], and timeouts on every outbound call. 4. Add an evaluation layer: score candidate results for prompt relevance, orientation ([landscape / portrait / square]), dominant color, and quality, then return a ranked shortlist with the reasoning attached. 5. Expose a single conversational entry point at [endpoint path, e.g. POST /v1/chat] that accepts `messages` and optional `max_images`, streams progress, and returns structured image results. 6. Enforce attribution: every returned photo carries the photographer's `username`, a link to their Unsplash profile, and the `utm_source` query parameters required by the Unsplash API guidelines. Download-triggering endpoints must call the download-tracking endpoint before serving the file. 7. Include safeguards: input validation with pydantic models, prompt-injection filtering on user-supplied search terms, per-user quotas, and an audit log with no PII. 8. Write a test suite with at least 12 unit tests plus 3 integration tests recorded via VCR cassettes or mocked responses; target [X]% statement coverage on `src/`. 9. Add developer docs: a README with quickstart, an architecture diagram in Mermaid, an `.env.example`, and a Makefile with `make dev`, `make test`, and `make lint` targets. </instructions> <context> This is a **beta** release serving internal product teams first, so it must be easy to run locally, easy to extend, and stable under moderate traffic. Assume up to [X, e.g. 1,000] daily active users and a hard ceiling of [X, e.g. 50] Unsplash API calls per hour on the free tier. The Unsplash API is rate-limited, so caching and query normalization are first-class concerns, not optimizations. Treat the model as an untrusted input: it may call tools, but the service layer is what enforces limits, quotas, and attribution. Deliverable: a runnable repository with `src/`, `tests/`, `openapi.yaml`, `README.md`, and `.env.example`. Prefer boring, readable code with type hints and docstrings over clever abstractions. </context> <constraints> - Never hardcode secrets, API keys, or tokens; read them only from the environment. - Return only images the Unsplash API actually returned; never fabricate URLs, authors, or metadata. - Every image result must include a working attribution block and the required `utm_source` parameters. - Respect the Unsplash API Guidelines: cache aggressively, trigger download tracking, and display a clear Unsplash credit. - All outbound requests must have a timeout of at most [X, e.g. 10] seconds and exactly one retry on transient failures. - Cap `max_images` at [X, e.g. 20] per request and reject larger values with a 422 response. - Do not introduce heavyweight frameworks beyond [your stack]; no serverless-specific lock-in. - Do not train, fine-tune, or store conversation transcripts for model improvement in this beta. </constraints> <format> Structure your response as: 1. A short architecture summary (max 200 words) covering the request flow from message → tool call → Unsplash → rendered result. 2. A file tree of the complete repository. 3. The full contents of each file, each in its own fenced code block with the language tag, in dependency order (config → client → services → routes → tests → docs). 4. A `.env.example` listing every required variable with a one-line comment. 5. A `curl` example showing one successful `/v1/chat` call and its JSON response shape. 6. A short "Known beta limitations" section with at most 5 bullet points. </format> <tone> Write like a pragmatic senior engineer handing work to teammates: direct, concrete, and technically precise. Explain *why* a design choice was made in a sentence where it isn't obvious. Skip marketing language, filler praise, and hedging. When something is a genuine trade-off, name both sides in one line rather than writing an essay. </tone> Begin by generating the complete repository for the ChatGPT + Unsplash beta integration, and end with the exact local commands needed to run, test, and deploy it.
#text