Skip to content

Quick Start Guide

This guide will help you get started with EncypherAI for embedding and extracting metadata from AI-generated text.

Basic Usage

This example demonstrates the fundamental workflow: embedding metadata with a digital signature and then verifying it.

1. Imports and Key Setup

First, import the necessary components and set up your cryptographic keys. For this example, we'll generate a key pair on the fly. In a real application, you would load a securely stored private key.

import time
from typing import Dict, Optional, Union


from encypher.core.keys import generate_ed25519_key_pair
from encypher.core.payloads import BasicPayload, ManifestPayload
from encypher.core.unicode_metadata import UnicodeMetadata

# --- Key Management ---
# In a real application, you would manage keys securely.
private_key: Ed25519PrivateKey
public_key: Ed25519PublicKey
private_key, public_key = generate_ed25519_key_pair()
signer_id = "quickstart-signer-001"

# Create a simple key store and a provider function to look up public keys by ID.
# This function is passed to the verification method.
public_keys_store = {signer_id: public_key}

def public_key_resolver(key_id: str):
    return public_keys_store.get(key_id)
# --------------------

2. Embed Metadata

Now, embed the metadata into your text. The embed_metadata method signs the payload and invisibly encodes it.

# Original AI-generated text
text = "This is AI-generated content that will contain invisible metadata."

# Embed metadata into the text
encoded_text = UnicodeMetadata.embed_metadata(
    text=text,
    private_key=private_key,
    signer_id=signer_id,
    timestamp=int(time.time()),
    custom_metadata={
        "model_id": "gpt-4o",
        "version": "2.3.0",
        "organization": "EncypherAI"
    },
    metadata_format="basic",  # 'basic' is a simple key-value format
    target="whitespace"       # Embed metadata after whitespace characters
)

# The encoded_text looks identical to the original text when displayed.
print(f"Original text:  {text}")
print(f"Encoded text:   {encoded_text}")

3. Extract and Verify Metadata

To ensure the text is authentic and unmodified, use the verify_metadata method with your public_key_provider.

# Verify the metadata using the public key provider
is_valid: bool
extracted_signer_id: Optional[str]
verified_payload: Union[BasicPayload, ManifestPayload, None]
is_valid, extracted_signer_id, verified_payload = UnicodeMetadata.verify_metadata(
    text=encoded_text,
    public_key_provider=public_key_provider
)

print(f"\nSignature valid: {is_valid}")
if is_valid and verified_payload:
    print(f"Verified Signer ID: {extracted_signer_id}")
    print(f"Verified Timestamp: {verified_payload.timestamp}")
    print(f"Verified Custom Metadata: {verified_payload.custom_metadata}")
else:
    print("Metadata validation failed - content may have been tampered with.")

# You can also extract the payload without verification, but this is not recommended
# for security-sensitive applications as it does not guarantee authenticity.
unverified_payload = UnicodeMetadata.extract_metadata(encoded_text)
print(f"\nExtracted (unverified) payload: {unverified_payload}")

Streaming Support

EncypherAI fully supports streaming, allowing you to process and embed metadata in real-time as text chunks are generated by an LLM.

from encypher.streaming.handlers import StreamingHandler

# --- Assuming key setup from the previous example ---

# Create a streaming handler with the same metadata components
streaming_handler = StreamingHandler(
    private_key=private_key,
    signer_id=signer_id,
    timestamp=int(time.time()),
    custom_metadata={
        "model_id": "gpt-4o-stream",
        "source": "quickstart_streaming_example"
    },
    # encode_first_chunk_only=True is the default and most common for streaming
)

# Simulate receiving chunks from an LLM
streaming_response_chunks = [
    "This is the first chunk ",
    "of a streamed response, ",
    "and this is the final part."
]

# Process each chunk and build the full response
full_encoded_response = ""
print("\nSimulating stream output:")
for chunk in streaming_response_chunks:
    encoded_chunk = streaming_handler.process_chunk(chunk=chunk)
    if encoded_chunk:  # May be None if buffering
        print(encoded_chunk, end="")
        full_encoded_response += encoded_chunk

# Finalize the stream to process any remaining buffer and embed the metadata
final_chunk = streaming_handler.finalize_stream()
if final_chunk:
    print(final_chunk, end="")
    full_encoded_response += final_chunk
print("\n--- End of Stream ---")

# Verify the complete streamed text
is_stream_valid, stream_signer_id, stream_payload = UnicodeMetadata.verify_metadata(
    text=full_encoded_response,
    public_key_provider=public_key_provider
)

print(f"\nStreamed text signature valid: {is_stream_valid}")
if is_stream_valid and stream_payload:
    print(f"Verified Stream Signer ID: {stream_signer_id}")
    print(f"Verified Stream Payload: {stream_payload.custom_metadata}")
else:
    print("Streamed metadata validation failed.")

Next Steps

Explore more advanced features in the User Guide: