AdaptsAPI Client
A Python client library and CLI for the Adapts API: chat with your codebase wikis, generate wiki docs, and read / generate release notes.
Features
- 🚀
AdaptsClient— high-level client withchat(),list_chat_enabled_wikis(),list_all_wikis(),list_git_connections(),list_git_repos(),generate_wiki(),list_release_notes(),get_release_note() - 💬 Chat with wikis — async start, poll for status, multi-wiki, same-thread follow-ups
- 📝 Read release notes — list by org/wiki and fetch markdown content
- 📄 Generate wiki docs — list connections → list repos →
generate_wiki - 🔑 Token loading via
ADAPTS_API_TOKEN,ADAPTS_API_KEY,config.json, or interactive prompt - 📦 CLI:
adaptsapi (--chat | … | --list-git-connections | --list-git-repos | --generatedoc | --releasenotes) … - ✅ Validation: Pydantic models for chat, git list, wiki generate, and release-notes read payloads
- 🧪 Test suite with high coverage; integration demos under
tests/integ/
Installation
From PyPI
pip install adaptsapi
From Source
git clone https://github.com/AdaptsAI/adapts_api_client.git
cd adapts_api_client
pip install -e .
Quick Start
1. Set up your API token
load_token() resolves credentials in this order:
ADAPTS_API_TOKENorADAPTS_API_KEY(recommended for CI/CD)tokenin./config.json- Interactive prompt (CLI saves
tokentoconfig.json)
export ADAPTS_API_TOKEN="your-api-token-here"
# or: export ADAPTS_API_KEY="your-api-token-here"
Optional config.json (same directory you run the CLI from) for base URL and per-operation paths:
{
"token": "your-api-token-here",
"base_url": "https://prod.api.adapts.ai",
"generate_wiki_docs_metadata": {
"path": "/generate_wiki_docs"
},
"generate_release_notes_metadata": {
"path": "/generate_release_notes"
},
"list_release_notes_metadata": {
"path": "/list_release_notes"
},
"get_release_note_metadata": {
"path": "/get_release_note"
},
"list_git_connections_metadata": {
"path": "/list_git_connections"
},
"list_git_repos_metadata": {
"path": "/list_git_repos"
}
}
You can set a full URL per operation with "url" instead of "path". Legacy endpoint (full generate-docs URL, or host-only base) is still supported—see Configuration.
First-time CLI without env or token in config:
adaptsapi --generatedoc --data '{"test": "payload"}'
# Prompts for token and merges into config.json
2. Using the Python client
from adaptsapi import AdaptsClient
client = AdaptsClient() # uses ADAPTS_API_KEY env var
# List wikis available for chat
wikis = client.list_chat_enabled_wikis()
# Chat (blocks until response is ready)
response = client.chat("What does this repo do?", wiki_name="my-repo_main")
print(response["response"])
# Chat across multiple wikis
response = client.chat("Compare these repos.", wiki_names=["wiki_a", "wiki_b"])
# Async chat (returns immediately, poll manually)
started = client.chat_async("Explain the auth flow.", wiki_name="my-repo_main")
status = client.poll_chat_status(started["thread_id"], started["created_on"])
# List all wiki generation requests
all_wikis = client.list_all_wikis()
# List release notes (org-wide, paginated)
page = client.list_release_notes(limit=10)
for row in page["rows"]:
note = client.get_release_note(row["wiki_id"], row["release_id"])
print(note["content"])
# Filter by wiki
client.list_release_notes(wiki_id="my-org/my-repo", limit=5)
# Generate wiki documentation
connections = client.list_git_connections()
connection_id = connections[0]["connection_id"]
repos = client.list_git_repos(connection_id)
client.generate_wiki(
connection_id=connection_id,
repo_url=repos[0]["repo_url"],
branch="main",
wiki_name="my-repo_main",
)
3. Using the CLI
Omit --endpoint when config.json supplies defaults (see above).
Generate docs:
adaptsapi --list-git-connections
adaptsapi --list-git-repos --data '{"connection_id":"GIT_github_org"}'
adaptsapi --generatedoc \
--endpoint "https://prod.api.adapts.ai/generate_wiki_docs" \
--data '{"connection_id":"GIT_github_org","repo_url":"https://github.com/org/repo","branch":"main","wiki_name":"repo_main"}'
Generate docs (payload file):
adaptsapi --generatedoc \
--endpoint "https://prod.api.adapts.ai/generate_wiki_docs" \
--payload-file payload.json
Chat:
adaptsapi --chat --data '{"user_prompt":"What does this do?","wiki_name":"my-repo_main"}'
adaptsapi --chat-status --data '{"thread_id":"...","created_on":"..."}'
adaptsapi --chat-enabled-wikis
adaptsapi --list-wikis
Read release notes:
adaptsapi --list-release-notes
adaptsapi --list-release-notes --data '{"limit":10}'
adaptsapi --list-release-notes --data '{"wiki_id":"my-org/my-repo","limit":5}'
adaptsapi --get-release-note --data '{"wiki_id":"...","release_id":"..."}'
Generate release notes (same payload as wiki docs; uses config default or --endpoint):
adaptsapi --releasenotes --payload-file payload.json
Testing
The suite includes unit tests, CLI/config tests, and optional integration demos.
Running tests
# Full check (pytest + lint + mypy) — same as `make test`
python run_tests.py --type all
# Makefile (uses `.venv/bin/python` when present)
make test
Pytest only:
python -m pytest
python -m pytest -v
python -m pytest tests/test_generate_docs.py
python -m pytest --cov=src/adaptsapi --cov-report=html
Test runner:
python run_tests.py --type unit
python run_tests.py --type integration # needs ADAPTS_API_TOKEN / ADAPTS_API_KEY for live calls
python run_tests.py --type coverage
python run_tests.py --type integration --api-key "your-api-key"
Categories
- Unit: mocked HTTP and fast paths
- Integration / API: real calls when marked
@pytest.mark.integrationor@pytest.mark.apiand credentials are set tests/integ/: runnable demos (test_chat_demo.py,test_get_list_of_all_wikis_demo.py,test_generate_docs_demo.py,test_workflow.py)
Test Coverage
The test suite covers:
- ✅ Payload Validation: All validation logic and error cases
- ✅ Metadata Population: Automatic metadata generation
- ✅ API Calls: HTTP request handling and error management
- ✅ CLI Functionality: Command-line argument parsing and file handling
- ✅ Configuration: Token loading and config file management
Integration demos
Runnable modules under tests/integ/ (pytest or python tests/integ/...):
test_chat_demo.py— chat validation, mocked POST, optional live calltest_get_list_of_all_wikis_demo.py— list wikis, mocked POST, optional live calltest_generate_docs_demo.py— validation, metadata, optional live generate-docs calltest_workflow.py— end-to-end style walkthrough
Set ADAPTS_API_TOKEN or ADAPTS_API_KEY for live requests.
Usage
Command Line Options
adaptsapi (--chat | --chat-status | --chat-enabled-wikis | --list-wikis | --list-release-notes | --get-release-note | --generatedoc | --releasenotes) [OPTIONS]
| Option | Description | Required |
|---|---|---|
--chat |
POST a chat request (user_prompt, wiki_name/wiki_names) |
One mode required |
--chat-status |
Poll chat status (thread_id, created_on) |
One mode required |
--chat-enabled-wikis |
List wikis available for chat (no payload) | One mode required |
--list-wikis |
List all wiki generation requests (no payload) | One mode required |
--list-release-notes |
List release notes (optional --data: wiki_id, limit, next_token) |
One mode required |
--get-release-note |
Get one release note (wiki_id, release_id required) |
One mode required |
--list-git-connections |
List git connections for wiki generate (no payload) | One mode required |
--list-git-repos |
List repos for a connection (connection_id required) |
One mode required |
--generatedoc |
POST a generate-wiki payload | One mode required |
--releasenotes |
POST a nested generate-release-notes payload | One mode required |
--endpoint URL |
Full API URL | No (defaults from config.json) |
--data JSON |
Inline JSON payload string | Yes (or --payload-file; not needed for list modes without body) |
--payload-file FILE |
Path to JSON payload file | Yes (or --data) |
--timeout SECONDS |
Request timeout in seconds (default: 30) | No |
Payload Structure
Generate wiki (--generatedoc):
{
"connection_id": "GIT_github_org",
"repo_url": "https://github.com/org/my-repo",
"branch": "main",
"wiki_name": "my-repo_main",
"service_name": "optional",
"directory_name": "optional/subdir"
}
Use --list-git-connections then --list-git-repos to discover valid connection_id / repo_url values.
Generate release notes (--releasenotes) — nested body (unchanged):
{
"email_address": "user@example.com",
"user_name": "github_username",
"repo_object": {
"repository_name": "my-repo",
"source": "github",
"repository_url": "https://github.com/user/my-repo",
"branch": "main",
"size": "12345",
"language": "python",
"is_private": false,
"git_provider_type": "github",
"refresh_token": "github_token_here"
}
}
GitHub Actions Integration
This package is designed to work seamlessly with GitHub Actions for automated documentation generation. Here's an example workflow:
name: Generate Wiki Docs
on:
pull_request:
branches: [ main ]
types: [ closed ]
jobs:
call-adapts-api:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install adaptsapi
run: pip install adaptsapi
- name: Generate documentation
env:
ADAPTS_API_TOKEN: ${{ secrets.ADAPTS_API_TOKEN }}
ADAPTS_CONNECTION_ID: ${{ secrets.ADAPTS_CONNECTION_ID }}
run: |
python -c "
import os
from adaptsapi import AdaptsClient
client = AdaptsClient()
client.generate_wiki(
connection_id=os.environ['ADAPTS_CONNECTION_ID'],
repo_url='${{ github.event.repository.html_url }}',
branch='main',
wiki_name='${{ github.event.repository.name }}_main',
)
print('Documentation generation submitted')
"
Setting up GitHub Secrets
- Go to your repository on GitHub
- Click Settings → Secrets and variables → Actions
- Click New repository secret
- Add
ADAPTS_API_TOKEN(recommended) orADAPTS_API_KEYwith your API token value
If the repository already stores the token under ADAPTS_API_KEY, map it in the workflow: ADAPTS_API_TOKEN: ${{ secrets.ADAPTS_API_KEY }}.
Configuration
config.json
Placed in the current working directory. Common keys:
| Key | Purpose |
|---|---|
token |
API key (if not using env) |
base_url / api_base_url |
API host; paths below are appended |
generate_wiki_docs_metadata |
{ "url": "..." } or { "path": "/generate_wiki_docs" } |
generate_release_notes_metadata |
{ "url": "..." } or { "path": "/generate_release_notes" } |
list_release_notes_metadata |
{ "url": "..." } or { "path": "/list_release_notes" } |
get_release_note_metadata |
{ "url": "..." } or { "path": "/get_release_note" } |
endpoint |
Legacy full generate-docs URL, or host-only base |
Override the host with ADAPTS_API_BASE_URL.
Example (paths + base):
{
"token": "your-api-token-here",
"base_url": "https://prod.api.adapts.ai",
"generate_wiki_docs_metadata": { "path": "/generate_wiki_docs" }
}
Example (legacy single endpoint):
{
"token": "your-api-token-here",
"endpoint": "https://prod.api.adapts.ai/generate_wiki_docs"
}
Environment variables
| Variable | Purpose |
|---|---|
ADAPTS_API_TOKEN / ADAPTS_API_KEY |
API key (load_token() checks both) |
ADAPTS_API_BASE_URL |
Base URL when not set in config.json |
Error Handling
The library provides comprehensive error handling:
- PayloadValidationError: Raised when payload validation fails
- ConfigError: Raised when no token can be found or loaded
- requests.RequestException: Raised on network failures
- JSONDecodeError: Raised for invalid JSON in config files
Common Error Scenarios
- Missing token: CLI prompts for interactive token input
- Invalid JSON: Shows JSON parsing errors
- API errors: Displays HTTP status codes and error messages
- Payload validation: Shows specific validation failures with field names
Development
Prerequisites
- Python 3.12+
- pip
Setup Development Environment
git clone https://github.com/AdaptsAI/adapts_api_client.git
cd adapts_api_client
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
pip install -r requirements-dev.txt
pip install -e .
Development Dependencies
Install development dependencies for testing and code quality:
pip install -r requirements-dev.txt
This includes:
pytest- Testing frameworkpytest-cov- Coverage reportingpytest-mock- Mocking utilitiesflake8- Code lintingmypy- Type checkingblack- Code formattingisort- Import sorting
Running tests
python -m pytest
python -m pytest --cov=src/adaptsapi --cov-report=html
python -m pytest -m "not integration"
python -m pytest -m "integration"
python run_tests.py --type all
make test # same as run_tests.py --type all
make build # test then python -m build
Code Quality
# Lint code
flake8 src/adaptsapi tests/
# Type checking
mypy src/adaptsapi/
# Format code
black src/adaptsapi tests/
isort src/adaptsapi tests/
Publishing to PyPI
Prerequisites
Before publishing to PyPI, ensure you have:
- PyPI Account: Create an account at pypi.org
- TestPyPI Account: Create an account at test.pypi.org
- API Tokens: Generate API tokens for both PyPI and TestPyPI
- Build Tools: Install required build tools
pip install build twine
Build Configuration
The project uses pyproject.toml for build configuration. Key settings:
[project]
name = "adaptsapi"
version = "0.2.0"
description = "Python client library and CLI for the Adapts API"
readme = { file = "README.md", content-type = "text/markdown" }
requires-python = ">=3.12"
authors = [
{ name = "VerifyAI Inc.", email = "dev@adapts.ai" }
]
dependencies = [
"requests",
"pydantic[email]>=2.4",
]
Publishing Steps
1. Prepare for Release
# Clean previous builds
rm -rf build/ dist/ *.egg-info src/*.egg-info
# Update version in pyproject.toml and setup.py
# Edit version numbers in both files
# Run all tests to ensure everything works
python run_tests.py --type all
# Check code quality
flake8 src/adaptsapi tests/
mypy src/adaptsapi/
2. Build Distribution Packages
# Build source distribution and wheel
python -m build
# Verify the built packages
ls -la dist/
# Should show: adaptsapi-0.2.0.tar.gz and adaptsapi-0.2.0-py3-none-any.whl
3. Test on TestPyPI (Recommended)
# Upload to TestPyPI first
python -m twine upload --repository testpypi dist/*
# Test installation from TestPyPI
pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ adaptsapi
# Test the installed package
python -c "from adaptsapi.generate_docs import post; print('✅ Package works!')"
4. Publish to PyPI
# Upload to PyPI
python -m twine upload dist/*
# Verify installation from PyPI
pip install adaptsapi
# Test the installed package
python -c "from adaptsapi.generate_docs import post; print('✅ Package published successfully!')"
Automated Publishing with GitHub Actions
Create .github/workflows/publish.yml:
name: Publish to PyPI
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: |
pip install build twine
pip install -r requirements-dev.txt
- name: Run tests
run: |
python run_tests.py --type unit
- name: Build package
run: python -m build
- name: Publish to TestPyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.TEST_PYPI_API_TOKEN }}
run: |
python -m twine upload --repository testpypi dist/*
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
python -m twine upload dist/*
Environment Variables for CI/CD
Set these secrets in your GitHub repository:
PYPI_API_TOKEN: Your PyPI API tokenTEST_PYPI_API_TOKEN: Your TestPyPI API token
Version Management
Semantic Versioning
Follow semantic versioning:
- MAJOR.MINOR.PATCH (e.g., 0.2.0)
- MAJOR: Breaking changes
- MINOR: New features, backward compatible
- PATCH: Bug fixes, backward compatible
Update Version Numbers
Update version in these files:
-
pyproject.toml:
[project] version = "0.2.1" # Update this
-
setup.py:
setup( name="adaptsapi", version="0.2.1", # Update this # ... )
Pre-release Checklist
Before publishing, ensure:
- All tests pass:
python run_tests.py --type all - Code is linted:
flake8 src/adaptsapi tests/ - Type checking passes:
mypy src/adaptsapi/ - Documentation is updated
- Version numbers are updated in
pyproject.toml,setup.py,setup.cfg, andsrc/adaptsapi/__init__.py - CHANGELOG is updated
- Package builds successfully:
python -m build - Package installs correctly:
pip install dist/*.whl
Troubleshooting
Common Issues
-
"File already exists" error:
# Clean previous builds rm -rf build/ dist/ *.egg-info src/*.egg-info python -m build
-
Authentication errors:
# Check your API token python -m twine check dist/*
-
Package not found after upload:
- Wait a few minutes for PyPI to process
- Check the package page: https://pypi.org/project/adaptsapi/
-
Import errors after installation:
# Verify package structure pip show adaptsapi python -c "import adaptsapi; print(adaptsapi.__file__)"
Rollback Strategy
If you need to rollback a release:
-
Delete the release (if within 24 hours):
# Use PyPI web interface to delete the release # Go to: https://pypi.org/manage/project/adaptsapi/releases/
-
Yank the release (recommended):
python -m twine delete --username __token__ --password $PYPI_API_TOKEN adaptsapi 0.2.0
-
Publish a new patch version with fixes
Security Best Practices
- Use API tokens instead of username/password
- Store tokens securely in environment variables or secrets
- Use TestPyPI for testing before production
- Verify package contents before uploading
- Keep dependencies updated and secure
Package Verification
After publishing, verify the package:
pip install adaptsapi
python -c "
from adaptsapi import AdaptsClient, __version__
from adaptsapi.chat import post_chat
from adaptsapi.generate_docs import post
print(f'adaptsapi {__version__} — all imports OK')
"
adaptsapi --help
API reference
adaptsapi.generate_docs
post(endpoint, token, payload, timeout=30)— Wiki generate (connection_id,repo_url,branch,wiki_name, …); POST withx-api-key.default_generate_docs_url()— Generate-docs URL from config (load_default_endpoint()), orNone.
Nested helpers _validate_payload / _populate_metadata remain for release notes only.
adaptsapi.list_git_connections / adaptsapi.list_git_repos
post(...)— List connections (empty body) or repos (connection_id).
adaptsapi.release_notes
post(endpoint, token, payload, timeout=30)— Nested release-notes body (action:generate_release_notes).default_release_notes_url()— Release-notes URL from config (load_release_notes_endpoint()), orNone.
adaptsapi.chat
post_chat(endpoint, token, payload)— Start a chat (returnsthread_id+created_on).post_chat_status(endpoint, token, payload)— Poll for chat response.post_chat_enabled_wikis(endpoint, token)— List wikis available for chat.
adaptsapi.get_list_of_all_wikis
post(endpoint, token)— List all wiki generation requests.
adaptsapi.config
load_token()—ADAPTS_API_TOKEN/ADAPTS_API_KEY, thenconfig.jsontoken, then prompt.load_api_base_url()—ADAPTS_API_BASE_URL, then config, then default prod base.load_chat_url(),load_chat_status_url(),load_chat_enabled_wikis_url(),load_get_list_of_all_wikis_url(),load_list_release_notes_url(),load_get_release_note_url(),load_list_git_connections_url(),load_list_git_repos_url()— Endpoint URLs from config or defaults.
CLI
adaptsapi.cli.main()— Entry point; requires one of--chat,--chat-status,--chat-enabled-wikis,--list-wikis,--list-git-connections,--list-git-repos,--list-release-notes,--get-release-note,--generatedoc, or--releasenotes.
Project structure
adapts_api_client/
├── src/adaptsapi/
│ ├── __init__.py # AdaptsClient, AdaptsAPIError, __version__
│ ├── client.py # High-level AdaptsClient
│ ├── chat.py # Chat API (post_chat, post_chat_status, post_chat_enabled_wikis)
│ ├── get_list_of_all_wikis.py
│ ├── read_release_notes.py # List / get release notes
│ ├── generate_docs.py # Wiki-docs client
│ ├── list_git_connections.py
│ ├── list_git_repos.py
│ ├── release_notes.py # Generate release notes (nested)
│ ├── cli.py
│ ├── config.py
│ └── models/ # Pydantic models (ChatRequest, ListReleaseNotesRequest, …)
├── tests/
│ ├── conftest.py
│ ├── integ/ # Demos: chat, list_wikis, generate_docs, workflow
│ ├── test_chat.py
│ ├── test_client.py
│ ├── test_get_list_of_all_wikis.py
│ ├── test_read_release_notes.py
│ ├── test_generate_docs.py
│ ├── test_release_notes.py
│ ├── test_cli.py
│ └── test_config.py
├── Makefile
├── run_tests.py
├── requirements-dev.txt
├── pytest.ini
└── TESTING.md
License
This software is licensed under the Adapts API Use-Only License v1.0. See LICENSE for details.
Key restrictions:
- ✅ Use the software as-is
- ❌ No modifications allowed
- ❌ No redistribution allowed
- ❌ Commercial use restrictions apply
Support
- 📧 Email: dev@adapts.ai
- 🐛 Issues: GitHub Issues
- 📖 Documentation: This README and TESTING.md
Changelog
v0.2.2 (latest)
- Wiki generate:
generate_wiki/generate_docs/--generatedocwithconnection_id,repo_url,branch,wiki_name(+ optional fields) - Git helpers:
list_git_connections,list_git_repos - Release notes generate stays nested
v0.2.1
- Read release notes:
list_release_notes,get_release_noteonAdaptsClient - CLI:
--list-release-notes,--get-release-note - Low-level:
adaptsapi.read_release_noteswith PydanticListReleaseNotesRequest/GetReleaseNoteRequest
v0.2.0
AdaptsClient— high-level client (chat,chat_async,poll_chat_status,list_chat_enabled_wikis,list_all_wikis,generate_docs)- Chat API:
post_chat,post_chat_status,post_chat_enabled_wikisinadaptsapi.chat get_list_of_all_wikismodule- CLI:
--chat,--chat-status,--chat-enabled-wikis,--list-wikis - Pydantic models:
ChatRequest,ChatStatusRequest
v0.1.9
- Prompt API client, Pydantic models,
config.jsonmetadata blocks - Release notes module, CLI
--releasenotes load_token()acceptsADAPTS_API_TOKENorADAPTS_API_KEY
v0.1.4 and earlier
- Generate-docs client, CLI, tests, and legacy
endpoint-only configuration
© 2025 AdaptsAI All rights reserved.
Release files for adaptsapi 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| adaptsapi-0.2.2.tar.gz | 45.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| adaptsapi-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 77.9 kB
Release files / adaptsapi-0.2.2.tar.gz
| Download URL | adaptsapi-0.2.2.tar.gz |
|---|---|
| Size | 45.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
232ba628d5ee9b492939db3749210e115136980f57afacce4d39e9068331513e
|
|
BLAKE2b-256 checksum How to use checksums |
6de278b2f0aa967275af70e6ade144ef0a7b491e0942987fda10dc5f5736af18
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|
Release files / adaptsapi-0.2.2-py3-none-any.whl
| Download URL | adaptsapi-0.2.2-py3-none-any.whl |
|---|---|
| Size | 32.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ea0775df6aea62dceaf87ffbf8d0cc985defb1dcf5a279eee7de7c0a33403a82
|
|
BLAKE2b-256 checksum How to use checksums |
7c02773c593c2bcbbd987f18834beba96d2dee39034e808bc9950f9979eca4c8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.13
|