
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Python client library for IDTAP - Interactive Digital Transcription and Analysis Platform for Hindustani music
Python client library for IDTAP (Interactive Digital Transcription and Analysis Platform) - a web-based research platform developed at UC Santa Cruz for transcribing, analyzing, and archiving Hindustani (North Indian classical) music recordings using trajectory-based notation designed specifically for oral melodic traditions.
IDTAP represents a paradigm shift in musical transcription and analysis. Rather than forcing oral traditions into Western notational frameworks, it uses trajectories as the fundamental musical unit—archetypal paths between pitches that capture the continuous melodic movement central to Hindustani music.
Key Innovation: Instead of discrete notes, IDTAP models music through:
pip install idtap
For enhanced Linux keyring support:
pip install idtap[linux]
For development:
pip install idtap[dev]
from idtap import SwaraClient, Piece, Instrument
# Initialize client - connects to swara.studio platform
client = SwaraClient() # Automatic OAuth via Google
# Browse available transcriptions
transcriptions = client.get_viewable_transcriptions()
print(f"Found {len(transcriptions)} transcriptions")
# Load a Hindustani music transcription
piece_data = client.get_piece("transcription-id")
piece = Piece.from_json(piece_data)
print(f"Transcription: {piece.title}")
print(f"Raga: {piece.raga.name if piece.raga else 'Unknown'}")
print(f"Instrument: {piece.instrumentation}")
print(f"Trajectories: {sum(len(p.trajectories) for p in piece.phrases)}")
# Analyze trajectory-based musical structure
for phrase in piece.phrases:
print(f"Phrase {phrase.phrase_number}: {len(phrase.trajectories)} trajectories")
# Examine individual trajectories (fundamental units of IDTAP)
for traj in phrase.trajectories:
if traj.pitch_array:
# Each trajectory contains continuous pitch movement
start_pitch = traj.pitch_array[0].pitch_number
end_pitch = traj.pitch_array[-1].pitch_number
print(f" Trajectory {traj.traj_number}: {start_pitch:.2f} → {end_pitch:.2f}")
# Check for articulations (performance techniques)
if traj.articulation:
techniques = [art.stroke for art in traj.articulation if art.stroke]
print(f" Articulations: {', '.join(techniques)}")
# Raga analysis (theoretical framework)
if piece.raga:
print(f"Raga: {piece.raga.name}")
if hasattr(piece.raga, 'aroha') and piece.raga.aroha:
print(f"Aroha (ascending): {piece.raga.aroha}")
if hasattr(piece.raga, 'avaroha') and piece.raga.avaroha:
print(f"Avaroha (descending): {piece.raga.avaroha}")
# Download audio in different formats
audio_bytes = client.download_audio("audio-id", format="wav")
with open("recording.wav", "wb") as f:
f.write(audio_bytes)
# Download all audio associated with a transcription
client.download_and_save_transcription_audio(piece, directory="./audio/")
# Export transcription data
excel_data = client.excel_data(piece_id)
with open("analysis.xlsx", "wb") as f:
f.write(excel_data)
json_data = client.json_data(piece_id)
with open("transcription.json", "wb") as f:
f.write(json_data)
from idtap import Piece, Phrase, Trajectory, Pitch, Raga, Instrument
# Example: Analyze a sitar transcription
sitar_pieces = [t for t in transcriptions if t.get('instrumentation') == 'Sitar']
for trans_meta in sitar_pieces[:3]: # First 3 sitar pieces
piece = Piece.from_json(client.get_piece(trans_meta['_id']))
# Count different types of trajectories (IDTAP's innovation)
trajectory_types = {}
for phrase in piece.phrases:
for traj in phrase.trajectories:
traj_type = getattr(traj, 'curve_type', 'straight')
trajectory_types[traj_type] = trajectory_types.get(traj_type, 0) + 1
print(f"{piece.title}:")
print(f" Raga: {piece.raga.name if piece.raga else 'Unknown'}")
print(f" Trajectory types: {trajectory_types}")
# Analyze articulation patterns (performance techniques)
articulations = []
for phrase in piece.phrases:
for traj in phrase.trajectories:
if traj.articulation:
articulations.extend([art.stroke for art in traj.articulation])
unique_arts = list(set(articulations))
print(f" Articulations used: {', '.join(unique_arts[:5])}") # First 5
The main HTTP client for interacting with the IDTAP server.
Key Methods:
get_viewable_transcriptions()
- List accessible transcriptionsget_piece(id)
- Load transcription datasave_piece(data)
- Save transcriptionexcel_data(id)
/ json_data(id)
- Export datadownload_audio(id, format)
- Download audio filesget_waiver_text()
- Display the research waiver text that must be readagree_to_waiver(i_agree=True)
- Accept research waiver (required for first-time users)has_agreed_to_waiver()
- Check if waiver has been acceptedPiece
- Central transcription container with metadata, audio association, and musical contentPhrase
- Musical phrase containing trajectory data and categorizationsTrajectory
- Detailed pitch movement data with timing and articulationsPitch
- Individual pitch points with frequency and timing informationRaga
- Indian musical scale/mode definitions with theoretical rulesSection
- Large structural divisions (alap, composition, etc.)Meter
- Rhythmic cycle and tempo informationArticulation
- Performance technique annotations (meend, andolan, etc.)The client uses OAuth 2.0 flow with Google authentication. On first use, it will:
First-time users must agree to a research waiver before accessing transcription data. If you haven't agreed yet, you'll see an error when trying to access transcriptions:
client = SwaraClient()
transcriptions = client.get_viewable_transcriptions() # Will raise RuntimeError
# First, read the waiver text
waiver_text = client.get_waiver_text()
print("Research Waiver:")
print(waiver_text)
# After reading, agree to the waiver
client.agree_to_waiver(i_agree=True)
transcriptions = client.get_viewable_transcriptions() # Now works
# Check waiver status
if client.has_agreed_to_waiver():
print("Waiver agreed - full access available")
# Initialize without auto-login
client = SwaraClient(auto_login=False)
# Login manually when needed
from idtap import login_google
login_google()
# Process multiple transcriptions
transcriptions = client.get_viewable_transcriptions()
for trans in transcriptions:
if trans.get('instrumentation') == 'Sitar':
piece = Piece.from_json(client.get_piece(trans['_id']))
# Analyze sitar-specific features
total_meends = sum(
len([art for art in traj.articulation if art.stroke == 'meend'])
for phrase in piece.phrases
for traj in phrase.trajectories
)
print(f"{piece.title}: {total_meends} meends")
# Raga analysis across corpus
raga_stats = {}
for trans in transcriptions:
piece = Piece.from_json(client.get_piece(trans['_id']))
if piece.raga:
raga_name = piece.raga.name
raga_stats[raga_name] = raga_stats.get(raga_name, 0) + 1
print("Raga distribution:", raga_stats)
# Unit tests
pytest idtap/tests/
# Integration tests (requires authentication)
python api_testing/api_test.py
📖 Complete documentation is available at idtap-python-api.readthedocs.io
MIT License - see LICENSE file for details.
If you use IDTAP in academic research, please cite the ISMIR 2025 paper:
@inproceedings{myers2025beyond,
title={Beyond Notation: A Digital Platform for Transcribing and Analyzing Oral Melodic Traditions},
author={Myers, Jonathan and Neuman, Dard},
booktitle={Proceedings of the 26th International Society for Music Information Retrieval Conference},
pages={},
year={2025},
address={Daejeon, South Korea},
url={https://swara.studio}
}
IDTAP was developed at UC Santa Cruz with support from the National Endowment for the Humanities. The platform challenges Western-centric approaches to music representation by creating tools designed specifically for oral melodic traditions, enabling scholars to study Hindustani music on its own terms while applying cutting-edge computational methodologies.
FAQs
Python client library for IDTAP - Interactive Digital Transcription and Analysis Platform for Hindustani music
We found that idtap demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.