Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: test

on:
pull_request:
branches: [main]
push:
branches: [main]

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.12"]
steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.22"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"
pip install pytest pytest-asyncio

- name: Build and start mock server
working-directory: tests/mockserver
run: |
go build -o mockserver .
./mockserver &
sleep 2
curl -sf http://localhost:18080/ || echo "mock server ready"

- name: Run tests
run: pytest tests/ -v --tb=short -x
370 changes: 262 additions & 108 deletions .speakeasy/gen.lock

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion .speakeasy/gen.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ generation:
securityFeb2025: true
sharedErrorComponentsApr2025: true
sharedNestedComponentsJan2026: false
nameOverrideFeb2026: false
auth:
oAuth2ClientCredentialsEnabled: true
oAuth2PasswordEnabled: true
Expand All @@ -23,6 +24,7 @@ generation:
schemas:
allOfMergeStrategy: shallowMerge
requestBodyFieldName: body
versioningStrategy: automatic
persistentEdits: {}
tests:
generateTests: true
Expand All @@ -32,7 +34,7 @@ generation:
examples:
- usage.md
python:
version: 2.2.0
version: 2.3.0
additionalDependencies:
dev: {}
main: {}
Expand All @@ -53,10 +55,13 @@ python:
envVarPrefix: YOU
fixFlags:
asyncPaginationSep2025: true
conflictResistantModelImportsFeb2026: false
responseRequiredSep2024: true
flattenGlobalSecurity: true
flattenRequests: true
flatteningOrder: parameters-first
forwardCompatibleEnumsByDefault: false
forwardCompatibleUnionsByDefault: "false"
imports:
option: openapi
paths:
Expand Down
317 changes: 303 additions & 14 deletions .speakeasy/out.openapi.yaml

Large diffs are not rendered by default.

21 changes: 11 additions & 10 deletions .speakeasy/workflow.lock
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
speakeasyVersion: 1.700.2
speakeasyVersion: 1.733.4
sources:
You.com API:
sourceNamespace: you-com-search-api
sourceRevisionDigest: sha256:e3c94436fd3002c31990ab21146f126bc6ab86e4b5f0f97449b8cf3dba72c23d
sourceBlobDigest: sha256:0d5b7b460a6e3aae27141ac5678258fadbccb3133081106441de0eed8e629f59
sourceRevisionDigest: sha256:1d9828035b2b9ec387808b7167bd6f5d833492b9c95a7c236e736cacb24c2e2a
sourceBlobDigest: sha256:b436d65210d9571c37986fbf57326dabb68500ef8c1ac06ae8378768e6c8a254
tags:
- latest
- 1.0.0
targets:
you:
source: You.com API
sourceNamespace: you-com-search-api
sourceRevisionDigest: sha256:e3c94436fd3002c31990ab21146f126bc6ab86e4b5f0f97449b8cf3dba72c23d
sourceBlobDigest: sha256:0d5b7b460a6e3aae27141ac5678258fadbccb3133081106441de0eed8e629f59
sourceRevisionDigest: sha256:1d9828035b2b9ec387808b7167bd6f5d833492b9c95a7c236e736cacb24c2e2a
sourceBlobDigest: sha256:b436d65210d9571c37986fbf57326dabb68500ef8c1ac06ae8378768e6c8a254
codeSamplesNamespace: you-com-search-api-code-samples
codeSamplesRevisionDigest: sha256:19322950f0dbf18cb2174131380b92626cd09e4b7e1f0b87a8769f031a1df0d5
codeSamplesRevisionDigest: sha256:15160af083a36e6567c9dbd9a52eb1f963895eeb92bc129469febf19f65e74bb
workflow:
workflowVersion: 1.0.0
speakeasyVersion: latest
sources:
You.com API:
inputs:
- location: https://you.com/specs/openapi_unified_agents.yaml
- location: https://raw.githubusercontent.com/Su-Sea/youdotcom-frontend/8b2343769b0cb30f5a50851979bbe414404d4614/public/specs/openapi_search_v1.yaml?token=GHSAT0AAAAAADSREVEUXQ6IIHAHVE2YZBDY2L3WB3A
- location: https://youdotcom-ceb3k6nx2-susea.vercel.app/specs/openapi_contents.yaml
- location: https://you.com/specs/openapi_base.yaml
- location: https://youdotcom-pr-11819.vercel.app/specs/openapi_unified_agents.yaml
- location: https://youdotcom-pr-11819.vercel.app/specs/openapi_search_v1.yaml
- location: https://youdotcom-pr-11819.vercel.app/specs/openapi_contents.yaml
- location: https://youdotcom-pr-11819.vercel.app/specs/openapi_research.yaml
- location: https://youdotcom-pr-11819.vercel.app/specs/openapi_base.yaml
overlays:
- location: ./overlays/python_overlay.yaml
output: .speakeasy/out.openapi.yaml
Expand Down
37 changes: 36 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,41 @@ All notable changes to the You.com Python SDK will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.3.0] - 2026-02-27

### Added

- **Research API**: New `research()` and `research_async()` methods on the main `You` client for comprehensive, multi-step research answers with citations. The Research API goes beyond a single web search by running multiple searches, reading sources, and synthesizing thorough, well-cited answers.

```python
from youdotcom import You
from youdotcom.models import ResearchEffort

you = You()
res = you.research(
input="What are the latest advances in quantum computing?",
research_effort=ResearchEffort.DEEP,
)
print(res.output.content)
for source in res.output.sources:
print(f" - {source.title or 'Untitled'}: {source.url}")
```

- **`ResearchEffort` enum**: Controls depth of research (`lite`, `standard`, `deep`, `exhaustive`)
- **Research models**: `ResearchRequest`, `ResearchResponse`, `Output`, `Source`, `ContentType`
- **Research errors**: `ResearchUnauthorizedError`, `ResearchForbiddenError`, `ResearchInternalServerError`, `UnprocessableEntityError`
- **`AgentRuns400ResponseError`**: New error class for 400 Bad Request responses from the Agents API

### Changed

- **Default server URL**: Changed from `https://ydc-index.io` to `https://api.you.com`. If you were relying on the default, no action needed as both resolve to the same API.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wording is inaccurate for Search and Contents endpoints.

The code in src/youdotcom/models/searchop.py and src/youdotcom/models/contentsop.py still has per-operation server lists that hardcode https://ydc-index.io:

SEARCH_OP_SERVERS = ["https://ydc-index.io"]
CONTENTS_OP_SERVERS = ["https://ydc-index.io"]

search.unified() and contents.generate() call models.SEARCH_OP_SERVERS[0] / models.CONTENTS_OP_SERVERS[0] directly, so those endpoints still use ydc-index.io by default unless the caller passes server_url=. The Agents and Research APIs do use https://api.you.com (global config). Consider clarifying: "The default base URL for the Agents and Research APIs changed from …" or update the per-operation server lists as well.

- **Python version requirement**: Now requires Python >=3.10 (previously >=3.9.2)
- **Search API `count` parameter**: Now defaults to `10` instead of `None`
- **Contents API `crawl_timeout`**: Type changed from `float` to `int`, default is now `10` seconds
- **Speakeasy generator**: Updated from v2.801.2 to v2.845.12

---

## [2.2.0] - 2026-01-29

### Changed
Expand Down Expand Up @@ -302,7 +337,7 @@ Error classes have been renamed for consistency and clarity:
| Old Name (1.x) | New Name (2.0) |
|----------------|----------------|
| `PostV1AgentsRunsUnauthorizedError` | `AgentRuns401ResponseError` |
| `PostV1AgentsRunsForbiddenError` | `AgentRuns422ResponseError` |
| `PostV1AgentsRunsForbiddenError` | Removed (403 now handled by `YouDefaultError`) |
| `GetV1SearchUnauthorizedError` | `SearchUnauthorizedError` |
| `GetV1SearchForbiddenError` | `SearchForbiddenError` |
| `PostV1ContentsUnauthorizedError` | `ContentsUnauthorizedError` |
Expand Down
47 changes: 45 additions & 2 deletions MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,47 @@
# Migration Guide: 1.x to 2.0
# Migration Guide

## 1.x → 2.3.0 (Latest)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misleading section title. The section below covers only the 2.x → 2.3.0 upgrade path (Python version, count default, crawl_timeout type). Labelling it "1.x → 2.3.0" will send 1.x users here and they won't find the 1.x-specific guidance until the separate "1.x to 2.0" section.

Suggested change
## 1.x → 2.3.0 (Latest)
## 2.x → 2.3.0 (Latest)


This guide covers breaking changes introduced in 2.3.0. If you are upgrading from 1.x, also read the [1.x → 2.0](#1x-to-20) section below.

### Breaking Changes in 2.3.0

#### Python 3.10 now required

The minimum supported Python version has been raised from `>=3.9.2` to `>=3.10`. If you are running Python 3.9, you must upgrade before installing this version.

```bash
python --version # must be 3.10 or later
pip install "youdotcom>=2.3.0"
```

#### Search API: `count` default changed

`you.search.unified()` now defaults `count` to `10` (previously `None`/no default). If your code omits `count` and relies on the API-server default, you will now always receive 10 results.

```python
# Before (2.x < 2.3.0): count was unset, server decided
res = you.search.unified(query="AI news")

# After (2.3.0+): equivalent explicit call
res = you.search.unified(query="AI news", count=10)
```

#### Contents API: `crawl_timeout` type changed

`crawl_timeout` has changed from `float` to `int`. Passing a float (e.g., `crawl_timeout=5.5`) will now raise a validation error.

```python
# Before: float was accepted
res = you.contents.generate(urls=["https://example.com"], crawl_timeout=5.5)

# After: use int
res = you.contents.generate(urls=["https://example.com"], crawl_timeout=5)
```

---

## 1.x to 2.0

This guide helps you upgrade your code from You.com Python SDK 1.x to 2.0.

Expand All @@ -12,7 +55,7 @@ This guide helps you upgrade your code from You.com Python SDK 1.x to 2.0.
| Custom agent | `agent="uuid-string"` | `request=CustomAgentRunsRequest(agent="uuid-string", ...)` |
| Verbosity enum | `Verbosity` | `ReportVerbosity` |
| Format enum | `Format` | `ContentsFormats` |
| Contents format param | `format_=ContentsFormat.X` | `formats=[ContentsFormats.X]` |
| Contents format param | `format_=Format.X` | `formats=[ContentsFormats.X]` |

## Step-by-Step Migration

Expand Down
Loading
Loading