Skip to content
Closed
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7e6629f
refactor: restructure monorepo to organize packages by language
fahreddinozcan Dec 8, 2025
1fcce65
feat: add python sdk
fahreddinozcan Dec 8, 2025
f3a18a0
feat: add sync client
fahreddinozcan Dec 8, 2025
237bb99
finalize async-sync client seperation
fahreddinozcan Dec 8, 2025
124b612
fmt
fahreddinozcan Dec 8, 2025
da7a086
fmt
fahreddinozcan Dec 8, 2025
d930d81
fix client tests types
fahreddinozcan Dec 8, 2025
1260d08
docs: update import package name
fahreddinozcan Dec 8, 2025
10c1baf
docs: update import package name
fahreddinozcan Dec 8, 2025
2f3db99
refactor: restructure packages directory layout
fahreddinozcan Jan 6, 2026
a6a5fdf
feat: simplify sdk api
fahreddinozcan Jan 6, 2026
bdf8970
fix: update python workflow paths and skip changeset for python changes
fahreddinozcan Jan 6, 2026
4609891
fix: correct package directories and format python code
fahreddinozcan Jan 6, 2026
8814e26
chore: update pnpm lockfile
fahreddinozcan Jan 6, 2026
3f05fa2
fix: correct tsconfig extends path for mcp package
fahreddinozcan Jan 6, 2026
b3ec354
Merge branch 'master' of https://github.com/upstash/context7 into CTX…
fahreddinozcan Jan 6, 2026
bc2ad96
refactor: remove unused pagination headers from Python SDK
fahreddinozcan Jan 6, 2026
9137d7e
refactor: remove unused GetContextOptions and Context7ValidationError
fahreddinozcan Jan 6, 2026
5e6a9e5
Merge branch 'master' of https://github.com/upstash/context7 into CTX…
fahreddinozcan Jan 9, 2026
36da4b8
chore: update readme for python sdk
fahreddinozcan Jan 9, 2026
8e8ab4c
feat: update default response type to json from txt
fahreddinozcan Jan 9, 2026
22b9c04
docs: add python sdk docs
fahreddinozcan Jan 9, 2026
2482260
chore: remove changeset workflow
fahreddinozcan Jan 9, 2026
1140e59
fmt: python sdk
fahreddinozcan Jan 9, 2026
fd8a26a
Merge remote-tracking branch 'origin' into CTX7-907
enesgules Jan 19, 2026
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
16 changes: 14 additions & 2 deletions .github/workflows/changeset-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,20 @@ jobs:
{ encoding: 'utf-8' }
);

const hasChangeset = diff
.split('\n')
const changedFiles = diff.split('\n').filter(f => f.length > 0);

// Skip changeset check if only Python files or workflow files are changed
Comment thread
fahreddinozcan marked this conversation as resolved.
Resolved
const onlyPythonChanges = changedFiles.every(file =>
file.startsWith('packages/python/') ||
file.startsWith('.github/workflows/')
);

if (onlyPythonChanges && changedFiles.length > 0) {
console.log('Skipping changeset check - only Python package changes detected');
return;
}

const hasChangeset = changedFiles
.some(file => file.startsWith('.changeset/') && file.endsWith('.md') && !file.includes('README'));

if (!hasChangeset) {
Expand Down
96 changes: 96 additions & 0 deletions .github/workflows/python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
name: Python CI

on:
push:
branches: [main, master]
paths:
- "packages/python/**"
- ".github/workflows/python-ci.yml"
pull_request:
branches: [main, master]
paths:
- "packages/python/**"
- ".github/workflows/python-ci.yml"

defaults:
run:
working-directory: packages/python

jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"

- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}

- name: Install dependencies
run: uv sync --all-packages

- name: Run linting
run: uv run ruff check .

- name: Run formatting check
run: uv run ruff format --check .

- name: Run type checking
run: uv run mypy sdk/src/context7

- name: Run tests
env:
CONTEXT7_API_KEY: ${{ secrets.CONTEXT7_API_KEY }}
run: uv run pytest sdk/tests -v --cov=context7 --cov-report=xml

build:
runs-on: ubuntu-latest
needs: test

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4

- name: Build package
working-directory: packages/python/sdk
run: uv build

- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: python-sdk-dist
path: packages/python/sdk/dist/

publish:
runs-on: ubuntu-latest
needs: [test, build]
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
environment: pypi

steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4

- name: Download build artifacts
uses: actions/download-artifact@v4
with:
name: python-sdk-dist
path: packages/python/sdk/dist/

- name: Publish to PyPI
working-directory: packages/python/sdk
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_TOKEN }}
run: uv publish
17 changes: 17 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -182,3 +182,20 @@ prompt.txt
reports
reports-old
src/test/questions*

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
.venv/
venv/
ENV/
.mypy_cache/
.ruff_cache/
.pytest_cache/
*.egg-info/
dist/
build/
uv.lock
12 changes: 10 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"version": "1.0.0",
"description": "Context7 monorepo - Documentation tools and SDKs",
"workspaces": [
"packages/*"
"packages/*",
"!packages/python"
],
"scripts": {
"build": "pnpm -r run build",
Expand All @@ -21,7 +22,14 @@
"format": "pnpm -r run format",
"format:check": "pnpm -r run format:check",
"release": "pnpm build && changeset publish",
"release:snapshot": "changeset version --snapshot canary && pnpm build && changeset publish --tag canary --no-git-tag"
"release:snapshot": "changeset version --snapshot canary && pnpm build && changeset publish --tag canary --no-git-tag",
"py:install": "cd packages/python && uv sync --all-packages",
"py:test": "cd packages/python && uv run pytest sdk/tests -v",
"py:lint": "cd packages/python && uv run ruff check .",
"py:format": "cd packages/python && uv run ruff format .",
"py:typecheck": "cd packages/python && uv run mypy sdk/src/context7",
"py:build": "cd packages/python/sdk && uv build",
"py:clean": "rm -rf packages/python/.venv packages/python/uv.lock packages/python/sdk/dist"
},
"repository": {
"type": "git",
Expand Down
1 change: 1 addition & 0 deletions packages/python/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.11
48 changes: 48 additions & 0 deletions packages/python/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
[project]
name = "context7-workspace"
version = "0.0.0"
description = "Context7 Python packages workspace"
requires-python = ">=3.9"
license = "MIT"

[tool.uv]
package = false

[tool.uv.workspace]
members = ["sdk"]

[tool.ruff]
line-length = 100
target-version = "py39"

[tool.ruff.lint]
select = ["E", "F", "I", "UP", "B", "SIM", "TCH"]
ignore = ["E501"]

[tool.ruff.format]
quote-style = "double"

[tool.pytest.ini_options]
testpaths = ["sdk/tests"]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"

[tool.mypy]
python_version = "3.9"
strict = true
warn_return_any = true
warn_unused_ignores = true

[tool.pyright]
pythonVersion = "3.9"
typeCheckingMode = "strict"

[dependency-groups]
dev = [
"mypy>=1.19.0",
"pytest>=8.4.2",
"pytest-asyncio>=1.2.0",
"pytest-cov>=7.0.0",
"python-dotenv>=1.2.1",
"ruff>=0.14.8",
]
67 changes: 67 additions & 0 deletions packages/python/sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Context7 Python SDK

Python SDK for Context7 - Documentation retrieval for AI agents.

## Installation

```bash
pip install context7
```

Or with uv:

```bash
uv add context7
```

## Quick Start

```python
import asyncio
from context7-sdk import Context7

async def main():
async with Context7(api_key="ctx7sk_...") as client:
# Search for libraries
results = await client.search_library("react")
for lib in results.results:
print(f"{lib.id}: {lib.title}")

# Get documentation
docs = await client.get_docs("/facebook/react")
Comment thread
fahreddinozcan marked this conversation as resolved.
Resolved
for snippet in docs.snippets:
print(f"{snippet.code_title}: {snippet.code_description}")

asyncio.run(main())
```

## API Reference

### `Context7(api_key=None, base_url=None)`

Initialize the Context7 client.

- `api_key`: API key for authentication. Falls back to `CONTEXT7_API_KEY` environment variable.
- `base_url`: Optional custom base URL for the API.

### `await client.search_library(query: str) -> SearchLibraryResponse`

Search for libraries by name or description.

### `await client.get_docs(library_id: str, **options) -> DocsResponse`

Get documentation for a library.

**Parameters:**

- `library_id`: Library identifier in format `/owner/repo` (e.g., `/facebook/react`)
- `version`: Optional library version (e.g., `"18.0.0"`)
- `page`: Page number for pagination
- `topic`: Filter docs by topic
- `limit`: Number of results per page
- `mode`: Type of documentation - `"code"` (default) or `"info"`
- `format`: Response format - `"json"` (default) or `"txt"`

## License

MIT
56 changes: 56 additions & 0 deletions packages/python/sdk/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
[project]
name = "context7"
version = "0.1.0"
description = "Python SDK for Context7 - Documentation retrieval for AI agents"
readme = "README.md"
requires-python = ">=3.9"
license = "MIT"
authors = [
{ name = "Upstash", email = "support@upstash.com" }
]
keywords = ["context7", "sdk", "documentation", "ai", "llm", "mcp", "upstash"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Typing :: Typed",
]

dependencies = [
"httpx>=0.27.0",
"pydantic>=2.0.0",
]

[project.optional-dependencies]
dev = [
"pytest>=8.0.0",
"pytest-asyncio>=0.24.0",
"pytest-cov>=5.0.0",
"mypy>=1.11.0",
"ruff>=0.6.0",
]

[project.urls]
Homepage = "https://context7.com"
Documentation = "https://context7.com/docs"
Repository = "https://github.com/upstash/context7"
Issues = "https://github.com/upstash/context7/issues"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/context7"]

[tool.hatch.build.targets.sdist]
include = [
"/src",
"/tests",
]
41 changes: 41 additions & 0 deletions packages/python/sdk/src/context7/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""
Context7 Python SDK - Documentation retrieval for AI agents.

This SDK provides a simple interface to search for libraries and retrieve
documentation from Context7, optimized for AI agents and LLMs.

Example:
```python
import asyncio
from context7 import Context7

async def main():
async with Context7(api_key="ctx7sk_...") as client:
# Search for libraries
libraries = await client.search_library_async(
"I need a UI library", "react"
)

# Get documentation context
context = await client.get_context_async(
"How to use hooks", "/facebook/react"
)
print(context)

asyncio.run(main())
```
"""

from context7.client import Context7
from context7.errors import Context7APIError, Context7Error
from context7.models import Documentation, Library

__all__ = [
"Context7",
"Context7Error",
"Context7APIError",
"Library",
"Documentation",
]

__version__ = "0.1.0"
Loading
Loading