|
|
|
""" |
|
ASL Gloss Converter using Claude API |
|
|
|
This script converts English text input and convert it to ASL gloss format. |
|
ASL gloss is a written representation of sign language |
|
that preserves the spatial and grammatical structure of ASL. |
|
""" |
|
|
|
import os |
|
import sys |
|
import argparse |
|
from typing import Optional, Dict, Any |
|
from pathlib import Path |
|
|
|
try: |
|
import anthropic |
|
except ImportError: |
|
print("Error: anthropic package not found. Please install it with:") |
|
print("pip install anthropic") |
|
sys.exit(1) |
|
|
|
|
|
class ASLGlossConverter: |
|
""" |
|
Converts English text to ASL gloss using Claude's API. |
|
|
|
ASL gloss preserves the spatial and grammatical structure of American Sign Language, |
|
including features like: |
|
- Topic-comment structure |
|
- Spatial referencing |
|
- Non-manual markers (facial expressions, head movements) |
|
- Classifier predicates |
|
- Time indicators |
|
""" |
|
|
|
def __init__(self, api_key: Optional[str] = None): |
|
""" |
|
Initialize the ASL gloss converter. |
|
|
|
Args: |
|
api_key: Anthropic API key. If not provided, will look for ANTHROPIC_API_KEY env var. |
|
""" |
|
self.api_key = api_key or os.getenv('ANTHROPIC_API_KEY') |
|
if not self.api_key: |
|
raise ValueError( |
|
"API key not provided. Set ANTHROPIC_API_KEY environment variable " |
|
"or pass api_key parameter." |
|
) |
|
|
|
self.client = anthropic.Anthropic(api_key=self.api_key) |
|
|
|
|
|
self.system_prompt = """You are an expert in American Sign Language (ASL) and ASL gloss. Your task is to convert English text to ASL gloss format with bracketed phrases. |
|
|
|
ASL GLOSS RULES: |
|
1. Use ALL CAPS for all signs |
|
2. Group related words/concepts into bracketed phrases [PHRASE] |
|
3. Use underscores (_) to connect words within a phrase that are signed together |
|
4. Use classifiers (CL:1, CL:3, CL:C, etc.) for spatial relationships |
|
5. Use pronouns: I (first person), YOU (second person), HE/SHE/THEY (third person) |
|
6. Use time indicators: PAST, FUTURE, NOW, ALWAYS, NEVER |
|
7. Use topic-comment structure: TOPIC COMMENT |
|
8. Use rhetorical questions: RHQ |
|
9. Use conditional markers: IF-THEN |
|
10. Use negation: NOT, NONE, CAN'T, DON'T-WANT |
|
11. Use aspect markers: FINISH, CONTINUE, REPEAT |
|
12. Use directional verbs: GIVE-TO, TELL-TO, ASK-TO |
|
13. Use location markers: HERE, THERE, WHERE |
|
14. Use manner adverbs: FAST, SLOW, CAREFUL, HARD |
|
|
|
PHRASE GROUPING GUIDELINES: |
|
- Group compound expressions: [GOOD_MORNING], [THANK_YOU], [HOW_ARE_YOU] |
|
- Keep names as single phrases: [JOHN], [NATALIIA], [CHRISTOPHER_ROBIN] |
|
- Group related concepts: [MY_NAME], [YOUR_HOUSE], [LAST_WEEK] |
|
- Keep simple words separate: [I] [LOVE] [YOU] |
|
|
|
IMPORTANT: Output ONLY the bracketed ASL phrases. Each phrase should be in ALL CAPS with underscores connecting related words. |
|
|
|
EXAMPLES: |
|
- "Good morning, Brian" β [GOOD_MORNING] [BRIAN] |
|
- "My name is Nataliia" β [I] [NAME] [NATALIIA] |
|
- "I love you" β [I] [LOVE] [YOU] |
|
- "What is your name?" β [YOU] [NAME] [WHAT] |
|
- "I don't understand" β [I] [UNDERSTAND] [NOT] |
|
- "Where is the bathroom?" β [BATHROOM] [WHERE] |
|
- "I want to go home" β [I] [WANT] [GO] [HOME] |
|
- "The cat is sleeping" β [CAT] [SLEEP] |
|
- "I finished my homework" β [I] [HOMEWORK] [FINISH] |
|
- "Do you want coffee?" β [YOU] [WANT] [COFFEE] |
|
- "I can't hear you" β [I] [HEAR] [YOU] [CAN'T] |
|
- "The weather is nice today" β [TODAY] [WEATHER] [NICE] |
|
- "Thank you very much" β [THANK_YOU] [VERY_MUCH] |
|
- "How are you doing?" β [HOW_ARE_YOU] [DOING] |
|
- "See you later" β [SEE_YOU_LATER] |
|
- "I work at Google" β [I] [WORK] [GOOGLE] |
|
|
|
Convert the given English text to proper ASL gloss format with bracketed phrases, maintaining the meaning and intent while following ASL grammar and structure.""" |
|
|
|
def convert_text(self, english_text: str) -> str: |
|
""" |
|
Convert English text to ASL gloss using Anthropic v1.x messages API. |
|
""" |
|
try: |
|
message = self.client.messages.create( |
|
model="claude-3-5-sonnet-20240620", |
|
max_tokens=1000, |
|
system=self.system_prompt, |
|
messages=[ |
|
{"role": "user", "content": f"Convert this English text to ASL gloss:\n\n{english_text}"} |
|
] |
|
) |
|
return message.content[0].text.strip() |
|
except Exception as e: |
|
raise Exception(f"Error converting text to ASL gloss: {str(e)}") |
|
|
|
def convert_file(self, input_file: str, output_file: Optional[str] = None) -> str: |
|
""" |
|
Convert text from a file to ASL gloss. |
|
|
|
Args: |
|
input_file: Path to input text file |
|
output_file: Path to output file (optional) |
|
|
|
Returns: |
|
The ASL gloss text |
|
""" |
|
try: |
|
|
|
with open(input_file, 'r', encoding='utf-8') as f: |
|
english_text = f.read().strip() |
|
|
|
if not english_text: |
|
raise ValueError("Input file is empty") |
|
|
|
|
|
asl_gloss = self.convert_text(english_text) |
|
|
|
|
|
if output_file: |
|
with open(output_file, 'w', encoding='utf-8') as f: |
|
f.write(asl_gloss) |
|
print(f"ASL gloss saved to: {output_file}") |
|
|
|
return asl_gloss |
|
|
|
except FileNotFoundError: |
|
raise Exception(f"Input file not found: {input_file}") |
|
except Exception as e: |
|
raise Exception(f"Error processing file: {str(e)}") |
|
|
|
def batch_convert(self, input_files: list, output_dir: Optional[str] = None) -> Dict[str, str]: |
|
""" |
|
Convert multiple files to ASL gloss. |
|
|
|
Args: |
|
input_files: List of input file paths |
|
output_dir: Directory to save output files (optional) |
|
|
|
Returns: |
|
Dictionary mapping input files to their ASL gloss |
|
""" |
|
results = {} |
|
|
|
for input_file in input_files: |
|
try: |
|
print(f"Converting: {input_file}") |
|
|
|
if output_dir: |
|
|
|
input_path = Path(input_file) |
|
output_filename = f"{input_path.stem}_asl_gloss{input_path.suffix}" |
|
output_file = Path(output_dir) / output_filename |
|
else: |
|
output_file = None |
|
|
|
asl_gloss = self.convert_file(input_file, str(output_file) if output_file else None) |
|
results[input_file] = asl_gloss |
|
|
|
print(f"β Completed: {input_file}") |
|
|
|
except Exception as e: |
|
print(f"β Error processing {input_file}: {str(e)}") |
|
results[input_file] = f"ERROR: {str(e)}" |
|
|
|
return results |
|
|
|
|
|
def main(): |
|
"""Main function for command-line usage.""" |
|
parser = argparse.ArgumentParser( |
|
description="Convert English text to ASL gloss using Claude's API", |
|
formatter_class=argparse.RawDescriptionHelpFormatter, |
|
epilog=""" |
|
Examples: |
|
# Convert text directly |
|
python asl_gloss.py "Hello, how are you?" |
|
|
|
# Convert from file |
|
python asl_gloss.py -f input.txt |
|
|
|
# Convert from file with output |
|
python asl_gloss.py -f input.txt -o output.txt |
|
|
|
# Batch convert multiple files |
|
python asl_gloss.py -b file1.txt file2.txt -d output_dir/ |
|
|
|
# Interactive mode |
|
python asl_gloss.py -i |
|
""" |
|
) |
|
|
|
parser.add_argument( |
|
'text', |
|
nargs='?', |
|
help='English text to convert to ASL gloss' |
|
) |
|
|
|
parser.add_argument( |
|
'-f', '--file', |
|
help='Input file containing English text' |
|
) |
|
|
|
parser.add_argument( |
|
'-o', '--output', |
|
help='Output file for ASL gloss' |
|
) |
|
|
|
parser.add_argument( |
|
'-b', '--batch', |
|
nargs='+', |
|
help='Batch convert multiple files' |
|
) |
|
|
|
parser.add_argument( |
|
'-d', '--output-dir', |
|
help='Output directory for batch conversion' |
|
) |
|
|
|
parser.add_argument( |
|
'-i', '--interactive', |
|
action='store_true', |
|
help='Run in interactive mode' |
|
) |
|
|
|
parser.add_argument( |
|
'--api-key', |
|
help='Anthropic API key (or set ANTHROPIC_API_KEY env var)' |
|
) |
|
|
|
args = parser.parse_args() |
|
|
|
try: |
|
|
|
converter = ASLGlossConverter(api_key=args.api_key) |
|
|
|
if args.interactive: |
|
print("ASL Gloss Converter - Interactive Mode") |
|
print("Enter English text to convert to ASL gloss (or 'quit' to exit):") |
|
print("-" * 50) |
|
|
|
while True: |
|
try: |
|
text = input("\nEnglish text: ").strip() |
|
if text.lower() in ['quit', 'exit', 'q']: |
|
break |
|
|
|
if not text: |
|
continue |
|
|
|
print("Converting...") |
|
asl_gloss = converter.convert_text(text) |
|
print(f"ASL Gloss: {asl_gloss}") |
|
|
|
except KeyboardInterrupt: |
|
print("\nExiting...") |
|
break |
|
except Exception as e: |
|
print(f"Error: {str(e)}") |
|
|
|
elif args.batch: |
|
if not args.batch: |
|
print("Error: No files specified for batch conversion") |
|
return 1 |
|
|
|
print(f"Batch converting {len(args.batch)} files...") |
|
results = converter.batch_convert(args.batch, args.output_dir) |
|
|
|
print("\nResults:") |
|
for input_file, result in results.items(): |
|
print(f"\n{input_file}:") |
|
print(result) |
|
|
|
elif args.file: |
|
asl_gloss = converter.convert_file(args.file, args.output) |
|
if not args.output: |
|
print("ASL Gloss:") |
|
print(asl_gloss) |
|
|
|
elif args.text: |
|
asl_gloss = converter.convert_text(args.text) |
|
print("ASL Gloss:") |
|
print(asl_gloss) |
|
|
|
if args.output: |
|
with open(args.output, 'w', encoding='utf-8') as f: |
|
f.write(asl_gloss) |
|
print(f"\nSaved to: {args.output}") |
|
|
|
else: |
|
parser.print_help() |
|
return 1 |
|
|
|
return 0 |
|
|
|
except Exception as e: |
|
print(f"Error: {str(e)}") |
|
return 1 |
|
|
|
|
|
if __name__ == "__main__": |
|
sys.exit(main()) |
|
|