Romeo and Juliet Text Extraction with LangExtract¶
This notebook demonstrates extracting characters, emotions, and relationships from Shakespeare's Romeo and Juliet using LangExtract.
Setup¶
In [8]:
# Install LangExtract
%pip install -q langextract
Note: you may need to restart the kernel to use updated packages.
In [9]:
# Set up your Gemini API key
# Get your key from: https://aistudio.google.com/app/apikey
import os
from getpass import getpass
if 'GEMINI_API_KEY' not in os.environ:
os.environ['GEMINI_API_KEY'] = getpass('Enter your Gemini API key: ')
Define Extraction Task¶
In [10]:
import langextract as lx
import textwrap
# Define the extraction task
prompt = textwrap.dedent("""\
Extract characters, emotions, and relationships in order of appearance.
Use exact text for extractions. Do not paraphrase or overlap entities.
Provide meaningful attributes for each entity to add context.""")
# Provide a high-quality example
examples = [
lx.data.ExampleData(
text="ROMEO. But soft! What light through yonder window breaks? It is the east, and Juliet is the sun.",
extractions=[
lx.data.Extraction(
extraction_class="character",
extraction_text="ROMEO",
attributes={"emotional_state": "wonder"}
),
lx.data.Extraction(
extraction_class="emotion",
extraction_text="But soft!",
attributes={"feeling": "gentle awe"}
),
lx.data.Extraction(
extraction_class="relationship",
extraction_text="Juliet is the sun",
attributes={"type": "metaphor"}
),
]
)
]
Extract from Sample Text¶
In [11]:
# Simple extraction from a short text
input_text = "Lady Juliet gazed longingly at the stars, her heart aching for Romeo"
result = lx.extract(
text_or_documents=input_text,
prompt_description=prompt,
examples=examples,
model_id="gemini-2.5-flash",
)
# Display results
print(f"Extracted {len(result.extractions)} entities:\n")
for extraction in result.extractions:
print(f"• {extraction.extraction_class}: '{extraction.extraction_text}'")
if extraction.attributes:
for key, value in extraction.attributes.items():
print(f" - {key}: {value}")
LangExtract: model=gemini-2.5-flash, current=68 chars, processed=68 chars: [00:01]
✓ Extraction processing complete ✓ Extracted 3 entities (3 unique types) • Time: 1.96s • Speed: 35 chars/sec • Chunks: 1 Extracted 3 entities: • character: 'Lady Juliet' - emotional_state: longing • emotion: 'gazed longingly at the stars, her heart aching' - feeling: melancholy longing • relationship: 'her heart aching for Romeo' - type: romantic
Interactive Visualization¶
In [12]:
# Save results to JSONL
lx.io.save_annotated_documents([result], output_name="romeo_juliet.jsonl", output_dir=".")
# Generate interactive visualization
html_content = lx.visualize("romeo_juliet.jsonl")
# Display in notebook
print("Interactive visualization (hover over highlights to see attributes):")
html_content
LangExtract: Saving to romeo_juliet.jsonl: 1 docs [00:00, 995.33 docs/s]
✓ Saved 1 documents to romeo_juliet.jsonl
LangExtract: Loading romeo_juliet.jsonl: 100%|██████████| 961/961 [00:00<00:00, 2.49MB/s]
✓ Loaded 1 documents from romeo_juliet.jsonl Interactive visualization (hover over highlights to see attributes):
Out[12]:
Highlights Legend: character emotion relationship
Lady Juliet gazed longingly at the stars, her heart aching for Romeo
Entity 1/3 |
Pos [0-11]
In [13]:
# Save visualization to file (for downloading)
with open("romeo_juliet_visualization.html", "w") as f:
# Handle both Jupyter (HTML object) and non-Jupyter (string) environments
if hasattr(html_content, 'data'):
f.write(html_content.data)
else:
f.write(html_content)
print("✓ Visualization saved to romeo_juliet_visualization.html")
print("You can download this file from the Files panel on the left.")
✓ Visualization saved to romeo_juliet_visualization.html You can download this file from the Files panel on the left.
Try Your Own Text¶
Experiment with your own Shakespeare quotes or any literary text!
In [14]:
# Try your own text
your_text = """
JULIET: O Romeo, Romeo! wherefore art thou Romeo?
Deny thy father and refuse thy name;
Or, if thou wilt not, be but sworn my love,
And I'll no longer be a Capulet.
"""
custom_result = lx.extract(
text_or_documents=your_text,
prompt_description=prompt,
examples=examples,
model_id="gemini-2.5-flash",
)
print("Extractions from your text:\n")
for e in custom_result.extractions:
print(f"• {e.extraction_class}: '{e.extraction_text}'")
if e.attributes:
for key, value in e.attributes.items():
print(f" - {key}: {value}")
LangExtract: model=gemini-2.5-flash, current=163 chars, processed=163 chars: [00:05]
✓ Extraction processing complete ✓ Extracted 6 entities (3 unique types) • Time: 5.84s • Speed: 28 chars/sec • Chunks: 1 Extractions from your text: • character: 'JULIET' - emotional_state: longing • emotion: 'O Romeo, Romeo! wherefore art thou Romeo?' - feeling: desperate questioning • relationship: 'thy father' - type: familial • relationship: 'thy name' - type: lineage • relationship: 'my love' - type: romantic bond • relationship: 'Capulet' - type: family affiliation