1 Architecture
Hirad edited this page 2026-07-23 10:23:39 +03:30

Srtx Architecture

Scope

The current Srtx implementation supports one end-to-end workflow: translating one local SRT file through the regular Gemini Developer API.

The implementation deliberately excludes resume state, streaming, audio context, transcription, FFmpeg extraction, multiple API keys, and token reports.

Package layers

Public caller or Typer CLI
          |
          v
     srtx.api / Srtx
          |
          v
   SubtitleTranslator
     |      |      |
     v      v      v
 SRT I/O  Batcher  Prompt builder
                    |
                    v
          TextGenerationProvider
                    |
                    v
              GeminiProvider

Public API layer

src/srtx/api.py provides the simple configure() and translate() facade. src/srtx/app.py provides the explicit object-oriented Srtx facade.

This layer resolves API keys and constructs the Gemini provider. Environment variables are not read by lower-level services.

Translation service

SubtitleTranslator coordinates the workflow:

  1. Resolve input and output paths.
  2. Read and validate the source SRT.
  3. Divide subtitle entries into deterministic batches.
  4. Build a provider-independent translation prompt.
  5. Ask the configured provider for JSON.
  6. Validate response count, indexes, order, schema, HTML tags, line breaks, and empty text.
  7. Apply translated text without changing timestamps.
  8. Apply RTL embedding when translated text is predominantly RTL.
  9. Write the output SRT.
  10. Return TranslationResult.
  11. Emit progress events throughout the workflow.

The service does not know about Typer, Rich, Gemini SDK classes, or terminal rendering.

Provider boundary

TextGenerationProvider is a small protocol:

class TextGenerationProvider(Protocol):
    def generate_json(self, prompt: TranslationPrompt) -> str: ...

SubtitleTranslator depends on this protocol rather than GeminiProvider. This allows tests and embedding applications to supply fake or custom providers.

The Gemini adapter owns:

  • Creating google.genai.Client
  • Constructing Gemini request configuration
  • Requesting structured JSON
  • Converting SDK errors into Srtx exceptions
  • Releasing Gemini client resources

Gemini SDK objects do not enter domain or service models.

Domain layer

Important immutable domain objects include:

  • SubtitleLine
  • TranslationItem
  • TranslationBatch
  • ProgressEvent
  • TranslationResult

External Gemini JSON is validated with Pydantic before it is converted into domain objects.

File I/O

SubtitleFileRepository is responsible for parsing and writing SRT data.

It preserves:

  • Subtitle indexes
  • Source order
  • Start and end timestamps
  • Internal line breaks
  • Empty subtitle text
  • Formatting contained in subtitle text

Path validation and default output naming belong to io/paths.py.

Progress reporting

Core services emit ProgressEvent instances to the ProgressSink protocol.

Available sinks include:

  • NullProgressSink
  • MemoryProgressSink
  • CLI-only RichProgressSink

Core services never render terminal output directly.

Error boundaries

Expected failures derive from SrtxError.

The library raises typed errors. The CLI catches SrtxError, displays a user-facing message, and exits with a non-zero status.

Unexpected programming errors are not silently hidden.