### Development Setup and Testing with uv Source: https://github.com/alanbato/nauyaca/blob/main/README.md This bash script outlines the steps for setting up the development environment for the Nauyaca project using 'uv'. It includes cloning the repository, installing dependencies, running tests with pytest, linting with ruff, and type checking with mypy. These commands are essential for verifying the setup and ensuring code quality. ```bash # Clone the repository git clone https://github.com/alanbato/nauyaca.git cd nauyaca # Install dependencies with uv uv sync # Run tests to verify setup uv run pytest # Run linting uv run ruff check src/ tests/ # Run type checking uv run mypy src/ ``` -------------------------------- ### Start Gemini Server with Full Configuration (Python) Source: https://context7.com/alanbato/nauyaca/llms.txt Starts a production-ready Gemini server using Python. This example demonstrates configuring host, port, document root, TLS certificates, directory listing, logging, rate limiting, and access control. It requires asyncio and nauyaca libraries. ```python import asyncio from pathlib import Path from nauyaca.server.server import start_server from nauyaca.server.config import ServerConfig from nauyaca.server.middleware import RateLimitConfig, AccessControlConfig async def run_server(): # Create server configuration config = ServerConfig( host="0.0.0.0", port=1965, document_root=Path("./capsule"), certfile=Path("./certs/cert.pem"), keyfile=Path("./certs/key.pem") ) # Configure rate limiting rate_limit_config = RateLimitConfig( capacity=20, # Max burst: 20 requests refill_rate=2.0, # 2 requests per second retry_after=30 # Wait 30s when limited ) # Configure access control access_control_config = AccessControlConfig( allow_list=["192.168.1.0/24", "10.0.0.1"], deny_list=["203.0.113.0/24"], default_allow=True ) # Start server with all features await start_server( config, enable_directory_listing=False, log_level="INFO", log_file=Path("/var/log/gemini/server.log"), json_logs=False, enable_rate_limiting=True, rate_limit_config=rate_limit_config, access_control_config=access_control_config ) # Run server asyncio.run(run_server()) ``` -------------------------------- ### Verify Development Setup Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Commands to verify the development setup by running tests, linting with Ruff, and type checking with mypy using 'uv run'. ```bash uv run pytest uv run ruff check src/ tests/ uv run mypy src/ ``` -------------------------------- ### Install Nauyaca CLI Tool Source: https://github.com/alanbato/nauyaca/blob/main/README.md Installs the Nauyaca project as a standalone Command Line Interface (CLI) tool. This is the recommended installation method for general use. ```bash uv tool install nauyaca ``` -------------------------------- ### Install Nauyaca from Source Source: https://github.com/alanbato/nauyaca/blob/main/README.md Clones the Nauyaca project repository and installs dependencies using uv. This method is intended for developers who want to work with the source code directly. ```bash git clone https://github.com/alanbato/nauyaca.git cd nauyaca uv sync ``` -------------------------------- ### Run Nauyaca Server Examples Source: https://github.com/alanbato/nauyaca/blob/main/README.md Demonstrates various ways to run the Nauyaca server, including serving a directory, specifying host and port, using a configuration file, and with TLS certificates. ```bash # Minimal - serve current directory (uses auto-generated cert) nauyaca serve ./capsule # With custom host/port nauyaca serve ./capsule --host 0.0.0.0 --port 1965 # With configuration file nauyaca serve --config config.toml # With TLS certificates nauyaca serve ./capsule --cert cert.pem --key key.pem ``` -------------------------------- ### Install Dependencies with uv Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Command to install all project dependencies, including development dependencies, using the 'uv' package manager. ```bash uv sync ``` -------------------------------- ### Full TOML Server Configuration Example Source: https://github.com/alanbato/nauyaca/blob/main/README.md A comprehensive TOML configuration for the Nauyaca server, including server details, rate limiting, and access control lists. This example shows how to specify host, port, certificate paths, and define allow/deny lists for access control. ```toml [server] host = "0.0.0.0" port = 1965 document_root = "./capsule" certfile = "./certs/cert.pem" keyfile = "./certs/key.pem" [rate_limit] enabled = true capacity = 10 # Max burst size (requests) refill_rate = 1.0 # Requests per second retry_after = 30 # Seconds to wait when limited [access_control] # IP-based access control (supports CIDR notation) allow_list = ["192.168.1.0/24", "10.0.0.1"] deny_list = ["203.0.113.0/24"] default_allow = true # Default policy when no lists match ``` -------------------------------- ### Install uv Package Manager Source: https://github.com/alanbato/nauyaca/blob/main/README.md Installs the uv package manager, a fast Python package manager recommended for this project. This command is typically run once to set up the development environment. ```bash # Install uv if you haven't already curl -LsSf https://astral.sh/uv/install.sh | sh ``` -------------------------------- ### Nauyaca Server Command-Line Usage Source: https://github.com/alanbato/nauyaca/blob/main/README.md Examples of how to run the Nauyaca server using the command line. Demonstrates loading configuration from a file, overriding settings, and running without a configuration file. ```bash # Load configuration from file nauyaca serve --config config.toml # Override specific settings nauyaca serve --config config.toml --host 0.0.0.0 --port 11965 # Without config file (all settings from CLI) nauyaca serve ./capsule --host localhost --port 1965 ``` -------------------------------- ### Install Pre-commit Hooks Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Sets up pre-commit hooks using 'uv run' to automate code quality checks before committing changes. ```bash uv run pre-commit install ``` -------------------------------- ### Conventional Commits Examples Source: https://github.com/alanbato/nauyaca/blob/main/README.md Examples demonstrating the Conventional Commits specification for commit messages. This convention helps in organizing commit history and automating changelog generation. The examples cover different types of changes like features, fixes, documentation, tests, and refactoring. ```text feat: Add client certificate support fix: Handle edge case in URL parsing docs: Update API reference test: Add integration tests for server refactor: Simplify protocol parsing logic ``` -------------------------------- ### Python Function with Google Style Docstring Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Example of a Python function illustrating the required Google style docstring, including Args, Returns, Raises, and Example sections. ```python def fetch_gemini(url: str, timeout: int = 30) -> GeminiResponse: """Fetch a resource from a Gemini server. Args: url: The Gemini URL to fetch timeout: Request timeout in seconds Returns: A GeminiResponse object containing the server's response Raises: ValueError: If the URL is invalid TimeoutError: If the request times out Example: >>> response = fetch_gemini("gemini://example.com/") >>> print(response.status) 20 """ ... ``` -------------------------------- ### Create Feature Branch Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Example command to create a new Git branch for developing a feature, following the 'feat/description' naming convention. ```bash git checkout -b feat/client-certificate-support ``` -------------------------------- ### Systemd Service Management Commands Source: https://github.com/alanbato/nauyaca/blob/main/README.md A collection of bash commands to manage the Nauyaca systemd service. These commands allow enabling, starting, checking the status, and viewing the logs of the Nauyaca server after its service file has been installed. ```bash # Enable and start the service sudo systemctl enable nauyaca sudo systemctl start nauyaca # Check status sudo systemctl status nauyaca # View logs sudo journalctl -u nauyaca -f ``` -------------------------------- ### Conventional Commits: Feature Example Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md An example of a feature commit message adhering to the Conventional Commits specification. It demonstrates the use of `feat:` type, a scope (`client`), a concise subject, and a detailed body explaining the change and referencing an issue. ```text feat(client): add support for client certificates Implement client certificate authentication for requests that require them. This allows servers to verify client identity. Closes #123 ``` -------------------------------- ### Python Function with Type Hints Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Example of a Python function demonstrating correct usage of type hints for function arguments and return values, as enforced by mypy. ```python # Good def parse_url(url: str) -> ParsedURL: ... # Bad - missing type hints def parse_url(url): ... ``` -------------------------------- ### Basic Gemini Client Usage with Nauyaca Source: https://github.com/alanbato/nauyaca/blob/main/README.md Demonstrates how to create a Gemini client using Nauyaca, make a simple GET request, and handle different response types (success, redirect, input required, error). It utilizes asynchronous programming with asyncio. ```python import asyncio from nauyaca.client import GeminiClient async def main(): # Create client with TOFU validation enabled (default) async with GeminiClient() as client: # Simple GET request response = await client.get("gemini://geminiprotocol.net/") # Check response status if response.is_success(): print(f"Content-Type: {response.meta}") print(response.body) elif response.is_redirect(): print(f"Redirect to: {response.redirect_url}") elif 10 <= response.status < 20: # Input required (status 1x) print(f"Input requested: {response.meta}") else: print(f"Error {response.status}: {response.meta}") asyncio.run(main()) ``` -------------------------------- ### GeminiClient with Custom TOFU and SSL Settings in Python Source: https://context7.com/alanbato/nauyaca/llms.txt Illustrates advanced configuration of the GeminiClient, including specifying a custom path for the TOFU database and configuring SSL settings. This example shows how to fetch a resource without following redirects and how to access the character set from the response. It's designed for scenarios requiring more control over the client's security and network behavior. ```python import asyncio from pathlib import Path from nauyaca.client import GeminiClient async def fetch_with_custom_tofu(): # Use custom TOFU database location custom_db = Path.home() / ".config" / "my-app" / "tofu.db" async with GeminiClient( timeout=60, max_redirects=3, trust_on_first_use=True, tofu_db_path=custom_db ) as client: # Fetch without following redirects response = await client.get( "gemini://example.com/resource", follow_redirects=False ) if response.is_success(): # Parse charset from response charset = response.charset # Defaults to utf-8 print(f"Charset: {charset}") print(f"Body length: {len(response.body)} bytes") asyncio.run(fetch_with_custom_tofu()) ``` -------------------------------- ### Generate SSL Certificates with Nauyaca Source: https://github.com/alanbato/nauyaca/blob/main/README.md Provides commands to generate SSL certificates using Nauyaca. It includes an example for self-signed certificates for testing and a command for production certificates with a specified hostname and validity period. ```bash # Generate self-signed certificate for testing nauyaca cert generate --hostname localhost --output ./certs # For production (with proper hostname) nauyaca cert generate --hostname gemini.example.com --days 365 ``` -------------------------------- ### Conventional Commits: Fix Example Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md An example of a bug fix commit message following the Conventional Commits specification. It uses the `fix:` type, specifies a scope (`server`), provides a clear subject, and details the solution including the use of `Path.resolve()` and references a fix. ```text fix(server): prevent path traversal in static file handler Use Path.resolve() to canonicalize paths and validate they remain within the document root. Fixes #456 ``` -------------------------------- ### Pytest Unit and Integration Tests for Nauyaca Client Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Example Python code demonstrating how to write unit and integration tests using pytest for the Nauyaca client. It shows the use of pytest markers for test categorization and asynchronous testing. Assumes the existence of `parse_request` and `GeminiClient` from the `nauyaca` library. ```python import pytest from nauyaca.client import GeminiClient # Assume parse_request is defined elsewhere or imported def parse_request(request_string): # Mock implementation for demonstration parts = request_string.strip().split(" ", 1) host_path = parts[1].split("/", 1) return type('obj', (object,), { 'host': host_path[0], 'path': "/" + host_path[1] if len(host_path) > 1 else "/" })() @pytest.mark.unit def test_request_parsing(): """Test that requests are parsed correctly.""" request = parse_request("gemini://example.com/path\r\n") assert request.host == "example.com" assert request.path == "/path" @pytest. பயன்படுத்து.mark.integration @pytest.mark.asyncio async def test_full_request_cycle(): """Test a complete client-server interaction.""" async with GeminiClient() as client: response = await client.fetch("gemini://localhost:1965/") assert response.status == 20 ``` -------------------------------- ### Run Specific Pytest Test Categories Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Examples of running specific categories of tests (unit, integration, excluding slow tests) using pytest markers. ```bash uv run pytest -m unit uv run pytest -m integration uv run pytest -m "not slow" ``` -------------------------------- ### IP-Based Access Control Middleware (Python) Source: https://context7.com/alanbato/nauyaca/llms.txt Illustrates the creation and usage of IP-based access control middleware using AccessControl and AccessControlConfig. It shows examples for both private servers (whitelist only) and public servers (with blacklist support), including testing with various IP addresses and CIDR notation. ```python import asyncio from nauyaca.server.middleware import AccessControl, AccessControlConfig # Example 1: Private server (whitelist only) private_config = AccessControlConfig( allow_list=["192.168.1.0/24", "10.0.0.5"], deny_list=None, default_allow=False # Deny all except whitelist ) private_access = AccessControl(private_config) # Example 2: Public server with blacklist public_config = AccessControlConfig( allow_list=None, deny_list=["203.0.113.0/24", "198.51.100.50"], default_allow=True # Allow all except blacklist ) public_access = AccessControl(public_config) async def test_access(): # Test private server test_ips = [ "192.168.1.100", # In whitelist "10.0.0.5", # In whitelist "203.0.113.10", # Not in whitelist ] for ip in test_ips: allow, response = await private_access.process_request( "gemini://example.com/", ip ) status = "ALLOWED" if allow else "DENIED" print(f"{ip}: {status}") print() # Test public server test_ips = [ "8.8.8.8", # Not in blacklist "203.0.113.10", # In blacklist subnet "198.51.100.50", # In blacklist ] for ip in test_ips: allow, response = await public_access.process_request( "gemini://example.com/", ip ) status = "ALLOWED" if allow else "DENIED" print(f"{ip}: {status}") asyncio.run(test_access()) ``` -------------------------------- ### Configure Access Control with TOML Source: https://github.com/alanbato/nauyaca/blob/main/SECURITY.md TOML configuration examples for defining access control rules. Includes settings for whitelist mode (default_allow = false) and blacklist mode (default_allow = true). ```toml # Whitelist Mode (recommended for private capsules) [access_control] allow_list = ["192.168.1.0/24", "trusted-proxy-ip"] default_allow = false # Blacklist Mode (public servers with known bad actors) [access_control] deny_list = ["abusive-ip", "spam-network/24"] default_allow = true ``` -------------------------------- ### Token Bucket Rate Limiting Middleware (Python) Source: https://context7.com/alanbato/nauyaca/llms.txt Implements a per-IP rate limiting middleware using the token bucket algorithm for a Gemini server. It automatically cleans up idle client entries. This example requires asyncio and nauyaca libraries for RateLimiter and RateLimitConfig. ```python import asyncio from nauyaca.server.middleware import RateLimiter, RateLimitConfig # Note: This snippet shows the import and configuration of RateLimiter. # The actual integration within the server would involve passing # rate_limit_config to the start_server function as shown in the # 'Start Gemini Server with Full Configuration' example. ``` -------------------------------- ### Configure Rate Limiting with TOML Source: https://github.com/alanbato/nauyaca/blob/main/SECURITY.md TOML configuration snippets for setting rate limiting parameters (capacity and refill rate). Examples are provided for personal, public, and high-traffic servers. ```toml # Personal capsule (conservative) [rate_limit] capacity = 5 refill_rate = 0.5 # Public server (generous) [rate_limit] capacity = 20 refill_rate = 2.0 # High-traffic server (very generous) [rate_limit] capacity = 50 refill_rate = 5.0 ``` -------------------------------- ### Use Nauyaca Client Commands Source: https://github.com/alanbato/nauyaca/blob/main/README.md Illustrates how to use the Nauyaca CLI client to fetch resources, view verbose output including headers, and manage the TOFU (Trust On First Use) database for trusted hosts. ```bash # Get a resource nauyaca get gemini://geminiprotocol.net/ # Get with verbose output showing response headers nauyaca get gemini://geminiprotocol.net/ --verbose # Manage TOFU database nauyaca tofu list nauyaca tofu trust geminiprotocol.net nauyaca tofu export backup.toml nauyaca tofu import backup.toml nauyaca tofu revoke example.com ``` -------------------------------- ### Clone Nauyaca Repository Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Instructions to fork and clone the Nauyaca repository from GitHub. This is the first step in setting up the development environment. ```bash git clone https://github.com/YOUR_USERNAME/nauyaca.git cd nauyaca ``` -------------------------------- ### Nauyaca Client TOFU Configuration Commands Source: https://github.com/alanbato/nauyaca/blob/main/README.md Bash commands for managing the Nauyaca client's TOFU (Trust-On-First-Use) database. Includes commands to list, export, import, revoke, and manually trust hosts. ```bash # TOFU database location ~/.nauyaca/known_hosts.db # List known hosts nauyaca tofu list # Export known hosts for backup nauyaca tofu export backup.toml # Import known hosts nauyaca tofu import backup.toml # Revoke trust for a host nauyaca tofu revoke example.com # Manually trust a host (connects and retrieves certificate) nauyaca tofu trust example.com ``` -------------------------------- ### TOFU (Trust-On-First-Use) Management with Nauyaca CLI Source: https://github.com/alanbato/nauyaca/blob/main/README.md Provides command-line interface commands for managing TOFU certificate validation. This includes listing known hosts, exporting/importing certificates, revoking trust, and manually trusting certificates. ```bash # List all known hosts with fingerprints nauyaca tofu list # Export for backup/sharing nauyaca tofu export backup.toml # Import from backup nauyaca tofu import backup.toml # Revoke trust for compromised host nauyaca tofu revoke example.com # Manually trust a certificate (connects and retrieves it) nauyaca tofu trust example.com ``` -------------------------------- ### Nauyaca Client Library Usage (Python) Source: https://github.com/alanbato/nauyaca/blob/main/README.md A Python code snippet demonstrating how to use the `GeminiClient` from the Nauyaca library to fetch a Gemini resource asynchronously. It includes handling successful responses, redirects, and errors. ```python import asyncio from nauyaca.client import GeminiClient async def main(): # Simple fetch with TOFU validation async with GeminiClient() as client: response = await client.get("gemini://geminiprotocol.net/") if response.is_success(): print(f"Content-Type: {response.meta}") 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()) ``` -------------------------------- ### Run All Pre-commit Hooks Manually Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Command to manually trigger all pre-commit hooks across the entire project for code quality checks. ```bash uv run pre-commit run --all-files ``` -------------------------------- ### Create Rate Limiter with Custom Configuration Source: https://context7.com/alanbato/nauyaca/llms.txt Demonstrates how to create a RateLimiter instance with a custom configuration, including capacity, refill rate, and retry after settings. It then simulates requests to test the rate limiting behavior and starts/stops a background cleanup task. ```python from nauyaca.rate_limit import RateLimitConfig, RateLimiter import asyncio config = RateLimitConfig( capacity=5, # Max 5 requests in burst refill_rate=0.5, # 1 request every 2 seconds retry_after=60 # Wait 60s when limited ) rate_limiter = RateLimiter(config) rate_limiter.start() # Start background cleanup task async def simulate_requests(): client_ip = "192.168.1.100" # Simulate multiple requests from same IP for i in range(10): allow, error_response = await rate_limiter.process_request( f"gemini://example.com/page{i}", client_ip ) if allow: print(f"Request {i+1}: Allowed") else: print(f"Request {i+1}: Rate limited") print(f"Response: {error_response.strip()}") await asyncio.sleep(0.1) # Stop cleanup task await rate_limiter.stop() asyncio.run(simulate_requests()) ``` -------------------------------- ### Minimal TOML Server Configuration Source: https://github.com/alanbato/nauyaca/blob/main/README.md A basic TOML configuration file for the Nauyaca server. It requires the 'document_root' to be set. Other settings like host, port, and TLS will use default values. ```toml [server] # Required: Path to your gemini content document_root = "./capsule" # All other settings use sensible defaults: # - host: localhost # - port: 1965 # - TLS: auto-generated self-signed certificate (for testing only!) # - Rate limiting: enabled with default limits # - Access control: allow all ``` -------------------------------- ### Manage TOFU Certificate Database with TOFUDatabase in Python Source: https://context7.com/alanbato/nauyaca/llms.txt Shows how to interact with the TOFUDatabase class for managing trusted Gemini host certificates. This includes listing known hosts and their details, exporting the database to TOML format for backup, and importing from a TOML file with conflict resolution. It also demonstrates revoking trust for a specific host, crucial for security. ```python from pathlib import Path from nauyaca.security.tofu import TOFUDatabase # Initialize TOFU database (uses ~/.nauyaca/tofu.db by default) tofu_db = TOFUDatabase() # List all known hosts hosts = tofu_db.list_hosts() for host in hosts: print(f"{host['hostname']}:{host['port']}") print(f" Fingerprint: {host['fingerprint']}") print(f" First seen: {host['first_seen']}") print(f" Last seen: {host['last_seen']}") # Export database to TOML for backup backup_path = Path("tofu_backup.toml") count = tofu_db.export_toml(backup_path) print(f"Exported {count} hosts to {backup_path}") # Import from TOML (merge with existing) def on_conflict(hostname, port, old_fp, new_fp): print(f"Conflict for {hostname}:{port}") print(f" Old: {old_fp}") print(f" New: {new_fp}") return False # Skip conflicts by default added, updated, skipped = tofu_db.import_toml( backup_path, merge=True, on_conflict=on_conflict ) print(f"Added: {added}, Updated: {updated}, Skipped: {skipped}") # Revoke trust for a compromised host revoked = tofu_db.revoke("example.com", 1965) if revoked: print("Host removed from TOFU database") ``` -------------------------------- ### Run Ruff Linting and Auto-fix Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Commands to run Ruff for linting the source and test files, and to automatically fix identified linting issues. ```bash uv run ruff check src/ tests/ uv run ruff check --fix src/ tests/ ``` -------------------------------- ### Run Pytest with Coverage Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Command to run all tests and generate an HTML coverage report using pytest and the --cov flag. ```bash uv run pytest --cov=src/nauyaca --cov-report=html ``` -------------------------------- ### Fetch Gemini Resource using GeminiClient in Python Source: https://context7.com/alanbato/nauyaca/llms.txt Demonstrates how to use the high-level GeminiClient API to fetch a resource over the Gemini protocol. It includes automatic TOFU validation, redirect following, and handling of different response types (success, redirect, input required, error). The client is initialized with default settings and run within an asyncio event loop. ```python import asyncio from nauyaca.client import GeminiClient async def fetch_gemini_resource(): # Create client with TOFU validation enabled (default) async with GeminiClient(timeout=30, max_redirects=5) as client: # Simple GET request response = await client.get("gemini://geminiprotocol.net/") # Check response status if response.is_success(): print(f"Status: {response.status}") print(f"MIME Type: {response.mime_type}") print(f"Content:\n{response.body}") elif response.is_redirect(): print(f"Redirect to: {response.redirect_url}") elif 10 <= response.status < 20: # Input required (status 1x) print(f"Input requested: {response.meta}") else: # Error response print(f"Error {response.status}: {response.meta}") asyncio.run(fetch_gemini_resource()) ``` -------------------------------- ### Run All Pytest Tests Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Command to execute the entire test suite using pytest, invoked via 'uv run'. ```bash uv run pytest ``` -------------------------------- ### Load Server Configuration from TOML (Python) Source: https://context7.com/alanbato/nauyaca/llms.txt Loads server configuration from a TOML file using Python. This is useful for production deployments where settings are externalized. It handles potential FileNotFoundError and ValueError exceptions during loading and validation. Requires pathlib and nauyaca libraries. ```python from pathlib import Path from nauyaca.server.config import ServerConfig # Example config.toml: # [server] # host = "0.0.0.0" # port = 1965 # document_root = "./capsule" # certfile = "./certs/cert.pem" # keyfile = "./certs/key.pem" # # [rate_limit] # enabled = true # capacity = 10 # refill_rate = 1.0 # retry_after = 30 # # [access_control] # allow_list = ["192.168.1.0/24"] # deny_list = [] # default_allow = true try: # Load configuration from file config = ServerConfig.from_toml(Path("config.toml")) # Validate configuration config.validate() print(f"Server: {config.host}:{config.port}") print(f"Document root: {config.document_root}") # Get middleware configurations rate_limit = config.get_rate_limit_config() print(f"Rate limit: {rate_limit.capacity} capacity, " f"{rate_limit.refill_rate} refill/sec") access_control = config.get_access_control_config() if access_control: print(f"Access control: {len(access_control.allow_list or [])} allowed") except FileNotFoundError as e: print(f"Configuration file not found: {e}") except ValueError as e: print(f"Invalid configuration: {e}") ``` -------------------------------- ### Composable Request Processing with MiddlewareChain Source: https://context7.com/alanbato/nauyaca/llms.txt Illustrates building a request processing pipeline using Nauyaca's MiddlewareChain. It demonstrates how to combine RateLimiter and AccessControl middleware to filter incoming requests based on IP address and request frequency. Dependencies include asyncio, RateLimiter, AccessControl, RateLimitConfig, and AccessControlConfig. ```python import asyncio from nauyaca.server.middleware import ( MiddlewareChain, RateLimiter, AccessControl, RateLimitConfig, AccessControlConfig ) async def demo_middleware_chain(): # Create middleware components rate_limiter = RateLimiter(RateLimitConfig( capacity=10, refill_rate=1.0, retry_after=30 )) rate_limiter.start() access_control = AccessControl(AccessControlConfig( allow_list=["192.168.0.0/16"], deny_list=["192.168.1.50"], default_allow=False )) # Chain middleware (executes in order) middleware_chain = MiddlewareChain([ access_control, # Check access first rate_limiter # Then check rate limit ]) # Test requests test_cases = [ ("192.168.1.100", "Allowed IP, first request"), ("192.168.1.100", "Allowed IP, second request"), ("192.168.1.50", "Denied IP (blacklist)"), ("10.0.0.1", "Not in whitelist"), ] for ip, description in test_cases: allow, response = await middleware_chain.process_request( "gemini://example.com/", ip ) if allow: print(f"✓ {description}: ALLOWED") else: print(f"✗ {description}: BLOCKED") print(f" Response: {response.strip()}") await rate_limiter.stop() asyncio.run(demo_middleware_chain()) ``` -------------------------------- ### Systemd Service Configuration for Nauyaca Source: https://github.com/alanbato/nauyaca/blob/main/README.md This INI configuration file sets up a systemd service for the Nauyaca Gemini Protocol Server. It specifies the description, dependencies, user, working directory, execution command, restart policy, and security hardening options. This is intended for production deployments on Linux systems. ```ini [Unit] Description=Nauyaca Gemini Protocol Server After=network.target [Service] Type=simple User=nauyaca Group=nauyaca WorkingDirectory=/opt/nauyaca ExecStart=/usr/local/bin/nauyaca serve --config /etc/nauyaca/config.toml Restart=always RestartSec=10 # Security hardening NoNewPrivileges=true PrivateTmp=true ProtectSystem=strict ProtectHome=true ReadWritePaths=/opt/nauyaca/capsule [Install] WantedBy=multi-user.target ``` -------------------------------- ### Advanced Gemini Client Configuration in Nauyaca Source: https://github.com/alanbato/nauyaca/blob/main/README.md Shows how to configure the Gemini client with custom timeouts and redirect limits, and how to disable redirect following. These options allow fine-grained control over network requests. ```python from nauyaca.client import GeminiClient # Custom timeout and redirect settings async with GeminiClient(timeout=60, max_redirects=3) as client: response = await client.get("gemini://geminiprotocol.net/") # Disable redirect following async with GeminiClient() as client: response = await client.get( "gemini://geminiprotocol.net/", follow_redirects=False ) ``` -------------------------------- ### Run Mypy Type Checking Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Command to perform static type checking on the project's source code using mypy. ```bash uv run mypy src/ ``` -------------------------------- ### Running Pytest with Different Flags Source: https://github.com/alanbato/nauyaca/blob/main/README.md Commands to run Pytest tests with various options. Includes options for verbose output, filtering by marks (unit, integration), and using pytest-watch for continuous testing. ```bash uv run pytest -v uv run pytest -m unit uv run pytest -m integration uv run ptw ``` -------------------------------- ### Add Nauyaca as a Library Source: https://github.com/alanbato/nauyaca/blob/main/README.md Adds the Nauyaca project as a library dependency to an existing Python project using uv. This allows for programmatic use of Nauyaca's features. ```bash # Add to existing project uv add nauyaca # Or start a new project uv init my-gemini-project cd my-gemini-project uv add nauyaca ``` -------------------------------- ### URL Routing with Multiple Match Types (Python) Source: https://context7.com/alanbato/nauyaca/llms.txt Implements URL routing for a Gemini server using Python, supporting exact, prefix, and regex matching. It allows defining handler functions for different routes and a default handler for unmatched paths. Requires nauyaca libraries for request, response, and router components. ```python from nauyaca.server.router import Router, RouteType from nauyaca.protocol.request import GeminiRequest from nauyaca.protocol.response import GeminiResponse # Create router router = Router() # Handler functions def index_handler(request: GeminiRequest) -> GeminiResponse: return GeminiResponse( status=20, meta="text/gemini", body="# Welcome to Gemini\n\nThis is the homepage." ) def blog_handler(request: GeminiRequest) -> GeminiResponse: return GeminiResponse( status=20, meta="text/gemini", body=f"# Blog\n\nRequested: {request.path}" ) def user_handler(request: GeminiRequest) -> GeminiResponse: user_id = request.path.split('/')[-1] return GeminiResponse( status=20, meta="text/gemini", body=f"# User Profile\n\nUser ID: {user_id}" ) def not_found_handler(request: GeminiRequest) -> GeminiResponse: return GeminiResponse( status=51, meta="text/gemini", body=f"# Not Found\n\nThe path {request.path} was not found." ) # Register routes router.add_route("/", index_handler, route_type=RouteType.EXACT) router.add_route("/blog/", blog_handler, route_type=RouteType.PREFIX) router.add_route(r"^/user/\d+$", user_handler, route_type=RouteType.REGEX) router.set_default_handler(not_found_handler) # Route a request request = GeminiRequest.from_line("gemini://example.com/blog/post-1") response = router.route(request) print(response.body) ``` -------------------------------- ### Run Pytest Tests Source: https://github.com/alanbato/nauyaca/blob/main/README.md Commands for running tests in the Nauyaca project using pytest. Includes options for running all tests, generating a coverage report, and running specific test files or functions. ```bash # Run all tests uv run pytest # Run with coverage report uv run pytest --cov=src/nauyaca --cov-report=html # Run specific test file uv run pytest tests/test_protocol/test_request.py # Run specific test function uv run pytest tests/test_server/test_handler.py::test_static_file_serving ``` -------------------------------- ### Pull Request Template Markdown Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md A Markdown template for creating pull requests. It includes sections for a description, type of change, testing details, and a checklist to ensure all contribution requirements are met before submission. ```markdown ## Description Brief description of what this PR does ## Type of Change - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Testing Describe the tests you added or how you tested your changes ## Checklist - [ ] My code follows the project's code style - [ ] I have added tests that prove my fix/feature works - [ ] All tests pass locally - [ ] I have updated the documentation accordingly - [ ] My changes generate no new warnings ``` -------------------------------- ### Nauyaca Gemini Response Handling Source: https://context7.com/alanbato/nauyaca/llms.txt Demonstrates creating and inspecting different types of Gemini responses using the GeminiResponse class, including success, redirect, input, and error responses. It shows how to access attributes like status, meta, body, and check response types. ```python success_response = GeminiResponse( status=20, meta="text/gemini; charset=utf-8", body="# Welcome\n\nThis is gemtext content.", url="gemini://example.com/" ) print(f"Is success: {success_response.is_success()}") print(f"MIME type: {success_response.mime_type}") print(f"Charset: {success_response.charset}") print(f"Body preview: {success_response.body[:50]}...") # Redirect response redirect_response = GeminiResponse( status=31, meta="gemini://new-location.com/page", url="gemini://example.com/old" ) print(f"\nIs redirect: {redirect_response.is_redirect()}") print(f"Redirect URL: {redirect_response.redirect_url}") # Input request response input_response = GeminiResponse( status=10, meta="Enter your search query", url="gemini://example.com/search" ) print(f"\nStatus code: {input_response.status}") print(f"Prompt: {input_response.meta}") # Error response error_response = GeminiResponse( status=51, meta="Not found", url="gemini://example.com/missing" ) print(f"\nError: {error_response.status} - {error_response.meta}") print(error_response) ``` -------------------------------- ### Gemini Protocol Request Parsing (Python) Source: https://context7.com/alanbato/nauyaca/llms.txt Demonstrates parsing Gemini protocol request lines using the GeminiRequest class. It shows how to extract various components of a request URL, including scheme, hostname, port, path, and query parameters, and handles potential validation errors. ```python from nauyaca.protocol.request import GeminiRequest # Parse a request line try: request = GeminiRequest.from_line("gemini://example.com/blog/post-1?tag=python") print(f"Raw URL: {request.raw_url}") print(f"Scheme: {request.scheme}") print(f"Hostname: {request.hostname}") print(f"Port: {request.port}") print(f"Path: {request.path}") print(f"Query: {request.query}") print(f"Normalized: {request.normalized_url}") except ValueError as e: print(f"Invalid request: {e}") # Parse request without query request2 = GeminiRequest.from_line("gemini://gemini.circumlunar.space/") print(f"\nPath: {request2.path}") print(f"Query: '{request2.query}'") # Empty string if no query ``` -------------------------------- ### Run Pytest Tests in Parallel Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Command to speed up test execution by running pytest tests in parallel using the '-n auto' option. ```bash uv run pytest -n auto ``` -------------------------------- ### Generating Test Coverage Report Source: https://github.com/alanbato/nauyaca/blob/main/README.md Command to generate a detailed HTML test coverage report for the Nauyaca project using Pytest and coverage.py. This helps in identifying areas with low test coverage. ```bash uv run pytest --cov=src/nauyaca --cov-report=html ``` -------------------------------- ### Nauyaca TOFU CLI Commands Source: https://github.com/alanbato/nauyaca/blob/main/SECURITY.md Provides command-line interface commands for managing Trust-On-First-Use (TOFU) certificate validation. These commands allow listing, trusting, revoking, exporting, and importing host fingerprints. ```bash # List known hosts nauyaca tofu list # Trust a specific host nauyaca tofu trust example.com --fingerprint # Revoke trust for a host nauyaca tofu revoke example.com # Export known hosts nauyaca tofu export known_hosts_backup.json # Import known hosts nauyaca tofu import known_hosts_backup.json ``` -------------------------------- ### Run Specific Pytest File or Function Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Commands to execute a particular test file or a specific test function within a file using pytest. ```bash uv run pytest tests/test_server/test_handler.py uv run pytest tests/test_server/test_handler.py::test_static_file_serving ``` -------------------------------- ### Gemini Protocol Response Handling (Python) Source: https://context7.com/alanbato/nauyaca/llms.txt This snippet is intended to demonstrate the creation and manipulation of Gemini protocol responses using the GeminiResponse class, including status checking and metadata extraction. (Note: The provided text does not contain the actual code for this snippet.) ```python from nauyaca.protocol.response import GeminiResponse ``` -------------------------------- ### Secure File Permissions with Bash Source: https://github.com/alanbato/nauyaca/blob/main/SECURITY.md Bash commands to set appropriate file permissions for configuration files, certificate files, and document roots to enhance security. Sensitive files should have restricted read/write access. ```bash # Configuration files chmod 600 config.toml # Certificate files chmod 600 cert.pem key.pem # Document root (publicly readable) chmod 755 capsule/ ``` -------------------------------- ### Generate Self-Signed TLS Certificate (Python) Source: https://context7.com/alanbato/nauyaca/llms.txt Provides Python code to generate self-signed TLS certificates for Gemini servers. It includes functions for generating the certificate and key, saving them to files, loading the certificate, and retrieving its fingerprint and detailed information. ```python from pathlib import Path from nauyaca.security.certificates import ( generate_self_signed_cert, get_certificate_fingerprint, load_certificate, get_certificate_info ) import asyncio import os # Generate self-signed certificate cert_pem, key_pem = generate_self_signed_cert( hostname="gemini.example.com", key_size=2048, valid_days=365 ) # Save to files cert_path = Path("cert.pem") key_path = Path("key.pem") cert_path.write_bytes(cert_pem) key_path.write_bytes(key_pem) print(f"Certificate saved to: {cert_path}") print(f"Private key saved to: {key_path}") # Load certificate and get info cert = load_certificate(cert_path) fingerprint = get_certificate_fingerprint(cert) print(f"Fingerprint: {fingerprint}") # Get detailed certificate information info = get_certificate_info(cert) print(f"Subject: {info['subject']}") print(f"Issuer: {info['issuer']}") print(f"Valid from: {info['not_before']}") print(f"Valid until: {info['not_after']}") print(f"SHA-256: {info['fingerprint_sha256']}") print(f"Expired: {info['expired']}") if info['san']: print(f"SAN: {info['san']}") # Set file permissions for private key (Unix only) os.chmod(key_path, 0o600) print(f"Private key permissions set to 0600") ``` -------------------------------- ### Enforcing TLS 1.2+ with Nauyaca Source: https://github.com/alanbato/nauyaca/blob/main/README.md Configures the SSL context to enforce a minimum TLS version of 1.2. This ensures that all Gemini connections made through Nauyaca use a secure and up-to-date TLS protocol. ```python # Automatic strong TLS configuration ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2 ``` -------------------------------- ### Conventional Commits Message Structure Source: https://github.com/alanbato/nauyaca/blob/main/CONTRIBUTING.md Illustrates the structure of commit messages following the Conventional Commits specification. This standardizes commit messages for better readability and automated tooling integration. It includes placeholders for type, scope, subject, body, and footer. ```text ():