Metadata-Version: 2.4
Name: ctfbridge
Version: 0.6.0
Summary: A Python library for interacting with multiple CTF platforms.
Author-email: bjornmorten <bjornmdev@proton.me>
License: MIT
Project-URL: Documentation, https://ctfbridge.readthedocs.io
Project-URL: Repository, https://github.com/bjornmorten/ctfbridge/
Project-URL: Issues, https://github.com/bjornmorten/ctfbridge/issues
Keywords: ctf
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: <3.13,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: beautifulsoup4<5.0,>=4.9
Requires-Dist: pydantic<3.0,>=2.0
Requires-Dist: httpx>=0.28
Provides-Extra: cli
Requires-Dist: typer[all]==0.19.2; extra == "cli"
Provides-Extra: dev
Requires-Dist: mypy; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Requires-Dist: pytest-mock; extra == "dev"
Requires-Dist: pytest-httpx; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: types-beautifulsoup4; extra == "dev"
Requires-Dist: pre-commit; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: build; extra == "dev"
Provides-Extra: docs
Requires-Dist: mkdocs; extra == "docs"
Requires-Dist: mkdocs-material; extra == "docs"
Requires-Dist: mkdocstrings[python]; extra == "docs"
Requires-Dist: griffe-pydantic; extra == "docs"
Requires-Dist: pydantic; extra == "docs"
Requires-Dist: pymdown-extensions; extra == "docs"
Dynamic: license-file

<h1 align="center">
  CTFBridge
</h1>

<h4 align="center">A unified Python interface for all major CTF platforms </h4>

<p align="center">
  <a href="https://pypi.org/project/ctfbridge/"><img src="https://img.shields.io/pypi/v/ctfbridge" alt="PyPI"></a>
  <a href="https://pypi.org/project/ctfbridge/"><img src="https://img.shields.io/pypi/pyversions/ctfbridge" alt="Python Versions"></a>
  <a href="https://ctfbridge.readthedocs.io"><img src="https://img.shields.io/badge/docs-readthedocs-blue.svg" alt="Docs"></a>
  <a href="https://github.com/bjornmorten/ctfbridge/actions/workflows/ci.yml"><img src="https://github.com/bjornmorten/ctfbridge/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
  <img src="https://img.shields.io/github/license/bjornmorten/ctfbridge" alt="License">
</p>

<p align="center">
  <a href="#-features">Features</a> •
  <a href="#-installation">Install</a> •
  <a href="#-quickstart">Quickstart</a> •
  <a href="#-documentation">Docs</a> •
  <a href="#-license">License</a>
</p>

---

## ✨ Features

- ✅ **Unified API** for multiple CTF platforms
- 🧠 **Auto-detect platform type** from just a URL
- 🔐 **Clean auth flow** with support for credentials and API tokens
- 🧩 **Challenge enrichment** — parses services and attachments from descriptions
- 🔄 **Persistent sessions** — save/load session state with ease
- 🤖 **Async-first design** — perfect for scripts, tools, and automation

## 📦 Installation

```bash
pip install ctfbridge
```

## 🚀 Quickstart

<!-- QUICKSTART_START -->
```python
import asyncio

from ctfbridge import create_client


async def main():
    # Connect and authenticate
    client = await create_client("https://demo.ctfd.io")
    await client.auth.login(username="admin", password="password")

    # Get challenges
    challenges = await client.challenges.get_all()
    for chal in challenges:
        print(f"[{chal.category}] {chal.name} ({chal.value} points)")

    # Submit a flag
    await client.challenges.submit(challenge_id=1, flag="CTF{flag}")

    # View the scoreboard
    scoreboard = await client.scoreboard.get_top(5)
    for entry in scoreboard:
        print(f"[+] {entry.rank}. {entry.name} - {entry.score} points")


if __name__ == "__main__":
    asyncio.run(main())
```
<!-- QUICKSTART_END -->

## 🧩 Supported Platforms

CTFBridge works out of the box with:

<!-- PLATFORMS_TABLE_START -->
| Platform | Login | Challenges | Submit Flags | Scoreboard |
| :--- | :---: | :---: | :---: | :---: |
| **CTFd** | ✅ | ✅ | ✅ | ✅ |
| **rCTF** | ✅ | ✅ | ✅ | ✅ |
| **GZCTF** | ✅ | ✅ | ✅ | ✅ |
| **Berg** | ❌ | ✅ | ❌ | ❌ |
| **EPT** | ❌ | ✅ | ❌ | ❌ |
|_More..._|🚧|🚧|🚧|🚧|
<!-- PLATFORMS_TABLE_END -->

📖 See [docs](https://ctfbridge.readthedocs.io/latest/getting-started/platforms/) for details.

## 📚 Documentation

All guides and API references are available at: **[ctfbridge.readthedocs.io](https://ctfbridge.readthedocs.io/)**

## 🤝 Contributing

Contributions are welcome! We appreciate any help, from bug reports and feature requests to code enhancements and documentation improvements.

Please read our [Contributing Guidelines](CONTRIBUTING.md) to get started.

## 🛠️ Projects Using CTFBridge

| Project | Description |
|---------|-------------|
| [**ctf-dl**](https://github.com/bjornmorten/ctf-dl) | 🗃️ A CTF challenge bulk downloader |
| [**ctf-sniper**](https://github.com/bjornmorten/ctf-sniper) | 🎯 An automated flag submission tool |
| [**pwnv**](https://github.com/CarixoHD/pwnv) | 🧠 A CTF workspace management tool |

Using CTFBridge in the wild? [Send a PR](https://github.com/bjornmorten/ctfbridge/edit/main/README.md) to feature it here!

## 📄 License

MIT License © 2025 [bjornmorten](https://github.com/bjornmorten)
