Skip to main content

Modern Gemini protocol server and client implementation using asyncio

Project description

Nauyaca - Gemini Protocol Server & Client

Python 3.14+ License: MIT Code style: Ruff Type checked: mypy Documentation

A modern, high-performance implementation of the Gemini protocol in Python. Nauyaca (pronounced "now-YAH-kah", meaning "serpent" in Nahuatl) uses asyncio's low-level Protocol/Transport pattern for efficient, non-blocking network I/O with both server and client capabilities.

Key Features

  • High Performance - asyncio Protocol/Transport pattern for maximum efficiency
  • Security First - Mandatory TLS 1.2+, TOFU certificate validation, rate limiting, and access control
  • Production Ready - TOML configuration, middleware system, and systemd integration
  • Developer Friendly - Full type hints, comprehensive tests, and modern tooling with uv

Read the full documentation

Quick Start

Installation

# As a CLI tool (recommended)
uv tool install nauyaca

# As a library
uv add nauyaca

# From source (for development)
git clone https://github.com/alanbato/nauyaca.git
cd nauyaca && uv sync

Run a Server

# Serve content from a directory
nauyaca serve ./capsule

# With configuration file
nauyaca serve --config config.toml

# With hot-reload for development
nauyaca serve ./capsule --reload

Fetch Content

# Get a Gemini resource
nauyaca get gemini://geminiprotocol.net/

# With verbose output
nauyaca get gemini://geminiprotocol.net/ --verbose

Use as a Library

import asyncio
from nauyaca.client import GeminiClient

async def main():
    async with GeminiClient() as client:
        response = await client.get("gemini://geminiprotocol.net/")

        if response.is_success():
            print(response.body)
        elif response.is_redirect():
            print(f"Redirect to: {response.redirect_url}")
        else:
            print(f"Error {response.status}: {response.meta}")

asyncio.run(main())

Advanced Features

Location-Based Routing

Nauyaca supports flexible routing with multiple handlers per server. Configure different URL paths to use different handlers (static files, proxy, etc.):

# Proxy API requests to backend server
[[locations]]
prefix = "/api/"
handler = "proxy"
upstream = "gemini://backend.example.com:1965"
strip_prefix = true  # /api/resource → /resource on backend
timeout = 30

# Serve static content for everything else
[[locations]]
prefix = "/"
handler = "static"
document_root = "./capsule"

Reverse Proxy

Use Nauyaca as a reverse proxy to aggregate multiple Gemini capsules:

# Forward blog requests to blog server
[[locations]]
prefix = "/blog/"
handler = "proxy"
upstream = "gemini://blog.example.com"
strip_prefix = true

# Forward wiki requests to wiki server
[[locations]]
prefix = "/wiki/"
handler = "proxy"
upstream = "gemini://wiki.example.com"
strip_prefix = true

# Serve homepage from local files
[[locations]]
prefix = "/"
handler = "static"
document_root = "./homepage"

See config.example.toml for more configuration examples.

Documentation

nauyaca.readthedocs.io

Section Description
Installation Setup and requirements
Quick Start Get running in 5 minutes
Tutorials Step-by-step guides
How-to Guides Task-oriented recipes
Reference CLI, configuration, API
Explanation Architecture and concepts

Contributing

# Setup
git clone https://github.com/alanbato/nauyaca.git
cd nauyaca && uv sync

# Test
uv run pytest

# Lint & Type Check
uv run ruff check src/ tests/
uv run mypy src/

See CONTRIBUTING.md for guidelines.

License

MIT License - see LICENSE for details.

Resources

Acknowledgments

  • Solderpunk for creating the Gemini protocol
  • The Gemini community for feedback and inspiration

Status: Active development (pre-1.0). Core protocol and security features are stable.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nauyaca-0.8.1.tar.gz (62.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nauyaca-0.8.1-py3-none-any.whl (78.2 kB view details)

Uploaded Python 3

File details

Details for the file nauyaca-0.8.1.tar.gz.

File metadata

  • Download URL: nauyaca-0.8.1.tar.gz
  • Upload date:
  • Size: 62.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nauyaca-0.8.1.tar.gz
Algorithm Hash digest
SHA256 f207ef7563d0125ccd239256d8757fdaaccd12eca045b263cad0c4e92b84de40
MD5 fbb8cda800aca29c3fde08441ce1362c
BLAKE2b-256 ae6c7503fdeec030b621ba8d09e3cceb871ff04a0e0fca9ba766c3317bbea847

See more details on using hashes here.

Provenance

The following attestation bundles were made for nauyaca-0.8.1.tar.gz:

Publisher: release-pypi.yml on alanbato/nauyaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nauyaca-0.8.1-py3-none-any.whl.

File metadata

  • Download URL: nauyaca-0.8.1-py3-none-any.whl
  • Upload date:
  • Size: 78.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for nauyaca-0.8.1-py3-none-any.whl
Algorithm Hash digest
SHA256 8ce9e60e15971e7a8c3750ca15b399eb60c58dfa36d768fd77de989bbbf5b226
MD5 3456f5dce2477f09d378f39bf0759a9e
BLAKE2b-256 c6a73a5959c88e9eae6638b0202935989186c3e0ea16c6cd3932504de62b0d53

See more details on using hashes here.

Provenance

The following attestation bundles were made for nauyaca-0.8.1-py3-none-any.whl:

Publisher: release-pypi.yml on alanbato/nauyaca

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page