idtap-api


Nameidtap-api JSON
Version 0.1.3 PyPI version JSON
download
home_pageNone
SummaryPython client library for IDTAP - Interactive Digital Transcription and Analysis Platform for Hindustani music
upload_time2025-07-24 23:30:28
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords music transcription hindustani indian-classical musicology ethnomusicology raga pitch-analysis audio-analysis
VCS
bugtrack_url
requirements requests requests-toolbelt pyhumps keyring cryptography PyJWT secretstorage
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # IDTAP Python API

[![PyPI version](https://badge.fury.io/py/idtap-api.svg)](https://badge.fury.io/py/idtap-api)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

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.

## About IDTAP

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:
- **Trajectory-based notation** - Continuous pitch contours rather than fixed notes
- **Microtonal precision** - Cent-based tuning with flexible raga systems  
- **Idiomatic articulations** - Performance techniques specific to each instrument
- **Hierarchical segmentation** - Phrases, sections, and formal structures

## Features

- **Trajectory-Based Data Access** - Load and analyze transcriptions using the trajectory notation system
- **Hindustani Music Analysis** - Work with raga-aware transcriptions and microtonal pitch data
- **Audio Download** - Retrieve associated audio recordings in multiple formats
- **Secure Authentication** - OAuth integration with encrypted token storage

## Installation

```bash
pip install idtap-api
```

### Optional Dependencies

For enhanced Linux keyring support:
```bash
pip install idtap-api[linux]
```

For development:
```bash
pip install idtap-api[dev]
```

## Quick Start

### Authentication & Basic Usage

```python
from idtap_api 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)}")
```

### Working with Trajectory-Based Transcriptions

```python
# 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}")
```

### Audio Handling

```python
# 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/")
```

### Data Export

```python
# 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)
```

### Working with Hindustani Music Data

```python
from idtap_api 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
```

## Key Classes

### SwaraClient
The main HTTP client for interacting with the IDTAP server.

**Key Methods:**
- `get_viewable_transcriptions()` - List accessible transcriptions
- `get_piece(id)` - Load transcription data
- `save_piece(data)` - Save transcription
- `excel_data(id)` / `json_data(id)` - Export data
- `download_audio(id, format)` - Download audio files
- `get_waiver_text()` - Display the research waiver text that must be read
- `agree_to_waiver(i_agree=True)` - Accept research waiver (required for first-time users)
- `has_agreed_to_waiver()` - Check if waiver has been accepted

### Musical Data Models

- **`Piece`** - Central transcription container with metadata, audio association, and musical content
- **`Phrase`** - Musical phrase containing trajectory data and categorizations
- **`Trajectory`** - Detailed pitch movement data with timing and articulations
- **`Pitch`** - Individual pitch points with frequency and timing information
- **`Raga`** - Indian musical scale/mode definitions with theoretical rules
- **`Section`** - Large structural divisions (alap, composition, etc.)
- **`Meter`** - Rhythmic cycle and tempo information
- **`Articulation`** - Performance technique annotations (meend, andolan, etc.)

### Specialized Features

- **Microtonal Pitch System** - Precise cent-based pitch representation
- **Hindustani Music Theory** - Raga rules, sargam notation, gharana traditions
- **Performance Analysis** - Ornament detection, phrase categorization
- **Multi-Track Support** - Simultaneous transcription of melody and drone

## Authentication

The client uses OAuth 2.0 flow with Google authentication. On first use, it will:

1. Open a browser for Google OAuth login
2. Securely store the authentication token using:
   - OS keyring (preferred)
   - Encrypted local file (fallback)
   - Plain text (legacy, discouraged)

### Research Waiver Requirement

**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:

```python
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")
```

### Manual Token Management

```python
# Initialize without auto-login
client = SwaraClient(auto_login=False)

# Login manually when needed
from idtap_api import login_google
login_google()
```

## Advanced Usage

### Batch Processing

```python
# 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")
```

### Research Applications

```python
# 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)
```

## Development

### Running Tests

```bash
# Unit tests
pytest idtap_api/tests/

# Integration tests (requires authentication)
python api_testing/api_test.py
```

### Contributing

1. Fork the repository
2. Create a feature branch
3. Add tests for new functionality
4. Ensure all tests pass
5. Submit a pull request

## Documentation

- **API Reference**: Full documentation of all classes and methods
- **Musical Concepts**: Guide to Hindustani music terminology and theory
- **Research Examples**: Academic use cases and analysis workflows

## Platform Access

- **IDTAP Web Platform**: [swara.studio](https://swara.studio)
- **Source Code**: [github.com/jon-myers/idtap](https://github.com/jon-myers/idtap)
- **Research Paper**: "Beyond Notation: A Digital Platform for Transcribing and Analyzing Oral Melodic Traditions" (ISMIR 2025)

## Support

- **GitHub Issues**: [Report bugs and request features](https://github.com/jon-myers/idtap/issues)
- **Research Contact**: Jonathan Myers & Dard Neuman, UC Santa Cruz
- **Platform**: [swara.studio](https://swara.studio)

## License

MIT License - see LICENSE file for details.

## Citation

If you use IDTAP in academic research, please cite the ISMIR 2025 paper:

```bibtex
@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.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "idtap-api",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": "Jon Myers <jon@swara.studio>",
    "keywords": "music, transcription, hindustani, indian-classical, musicology, ethnomusicology, raga, pitch-analysis, audio-analysis",
    "author": null,
    "author_email": "Jon Myers <jon@swara.studio>",
    "download_url": "https://files.pythonhosted.org/packages/b5/f8/53563a55eb8ad144c8e86bd3c5263ea3c1070d9a77f064c24195356ed3fd/idtap_api-0.1.3.tar.gz",
    "platform": null,
    "description": "# IDTAP Python API\n\n[![PyPI version](https://badge.fury.io/py/idtap-api.svg)](https://badge.fury.io/py/idtap-api)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nPython 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.\n\n## About IDTAP\n\nIDTAP 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\u2014archetypal paths between pitches that capture the continuous melodic movement central to Hindustani music.\n\n**Key Innovation**: Instead of discrete notes, IDTAP models music through:\n- **Trajectory-based notation** - Continuous pitch contours rather than fixed notes\n- **Microtonal precision** - Cent-based tuning with flexible raga systems  \n- **Idiomatic articulations** - Performance techniques specific to each instrument\n- **Hierarchical segmentation** - Phrases, sections, and formal structures\n\n## Features\n\n- **Trajectory-Based Data Access** - Load and analyze transcriptions using the trajectory notation system\n- **Hindustani Music Analysis** - Work with raga-aware transcriptions and microtonal pitch data\n- **Audio Download** - Retrieve associated audio recordings in multiple formats\n- **Secure Authentication** - OAuth integration with encrypted token storage\n\n## Installation\n\n```bash\npip install idtap-api\n```\n\n### Optional Dependencies\n\nFor enhanced Linux keyring support:\n```bash\npip install idtap-api[linux]\n```\n\nFor development:\n```bash\npip install idtap-api[dev]\n```\n\n## Quick Start\n\n### Authentication & Basic Usage\n\n```python\nfrom idtap_api import SwaraClient, Piece, Instrument\n\n# Initialize client - connects to swara.studio platform\nclient = SwaraClient()  # Automatic OAuth via Google\n\n# Browse available transcriptions\ntranscriptions = client.get_viewable_transcriptions()\nprint(f\"Found {len(transcriptions)} transcriptions\")\n\n# Load a Hindustani music transcription\npiece_data = client.get_piece(\"transcription-id\")\npiece = Piece.from_json(piece_data)\n\nprint(f\"Transcription: {piece.title}\")\nprint(f\"Raga: {piece.raga.name if piece.raga else 'Unknown'}\")\nprint(f\"Instrument: {piece.instrumentation}\")\nprint(f\"Trajectories: {sum(len(p.trajectories) for p in piece.phrases)}\")\n```\n\n### Working with Trajectory-Based Transcriptions\n\n```python\n# Analyze trajectory-based musical structure\nfor phrase in piece.phrases:\n    print(f\"Phrase {phrase.phrase_number}: {len(phrase.trajectories)} trajectories\")\n    \n    # Examine individual trajectories (fundamental units of IDTAP)\n    for traj in phrase.trajectories:\n        if traj.pitch_array:\n            # Each trajectory contains continuous pitch movement\n            start_pitch = traj.pitch_array[0].pitch_number\n            end_pitch = traj.pitch_array[-1].pitch_number\n            print(f\"  Trajectory {traj.traj_number}: {start_pitch:.2f} \u2192 {end_pitch:.2f}\")\n            \n            # Check for articulations (performance techniques)\n            if traj.articulation:\n                techniques = [art.stroke for art in traj.articulation if art.stroke]\n                print(f\"    Articulations: {', '.join(techniques)}\")\n\n# Raga analysis (theoretical framework)\nif piece.raga:\n    print(f\"Raga: {piece.raga.name}\")\n    if hasattr(piece.raga, 'aroha') and piece.raga.aroha:\n        print(f\"Aroha (ascending): {piece.raga.aroha}\")\n    if hasattr(piece.raga, 'avaroha') and piece.raga.avaroha:  \n        print(f\"Avaroha (descending): {piece.raga.avaroha}\")\n```\n\n### Audio Handling\n\n```python\n# Download audio in different formats\naudio_bytes = client.download_audio(\"audio-id\", format=\"wav\")\nwith open(\"recording.wav\", \"wb\") as f:\n    f.write(audio_bytes)\n\n# Download all audio associated with a transcription\nclient.download_and_save_transcription_audio(piece, directory=\"./audio/\")\n```\n\n### Data Export\n\n```python\n# Export transcription data\nexcel_data = client.excel_data(piece_id)\nwith open(\"analysis.xlsx\", \"wb\") as f:\n    f.write(excel_data)\n\njson_data = client.json_data(piece_id)\nwith open(\"transcription.json\", \"wb\") as f:\n    f.write(json_data)\n```\n\n### Working with Hindustani Music Data\n\n```python\nfrom idtap_api import Piece, Phrase, Trajectory, Pitch, Raga, Instrument\n\n# Example: Analyze a sitar transcription\nsitar_pieces = [t for t in transcriptions if t.get('instrumentation') == 'Sitar']\n\nfor trans_meta in sitar_pieces[:3]:  # First 3 sitar pieces\n    piece = Piece.from_json(client.get_piece(trans_meta['_id']))\n    \n    # Count different types of trajectories (IDTAP's innovation)\n    trajectory_types = {}\n    for phrase in piece.phrases:\n        for traj in phrase.trajectories:\n            traj_type = getattr(traj, 'curve_type', 'straight')\n            trajectory_types[traj_type] = trajectory_types.get(traj_type, 0) + 1\n    \n    print(f\"{piece.title}:\")\n    print(f\"  Raga: {piece.raga.name if piece.raga else 'Unknown'}\")\n    print(f\"  Trajectory types: {trajectory_types}\")\n    \n    # Analyze articulation patterns (performance techniques)  \n    articulations = []\n    for phrase in piece.phrases:\n        for traj in phrase.trajectories:\n            if traj.articulation:\n                articulations.extend([art.stroke for art in traj.articulation])\n    \n    unique_arts = list(set(articulations))\n    print(f\"  Articulations used: {', '.join(unique_arts[:5])}\")  # First 5\n```\n\n## Key Classes\n\n### SwaraClient\nThe main HTTP client for interacting with the IDTAP server.\n\n**Key Methods:**\n- `get_viewable_transcriptions()` - List accessible transcriptions\n- `get_piece(id)` - Load transcription data\n- `save_piece(data)` - Save transcription\n- `excel_data(id)` / `json_data(id)` - Export data\n- `download_audio(id, format)` - Download audio files\n- `get_waiver_text()` - Display the research waiver text that must be read\n- `agree_to_waiver(i_agree=True)` - Accept research waiver (required for first-time users)\n- `has_agreed_to_waiver()` - Check if waiver has been accepted\n\n### Musical Data Models\n\n- **`Piece`** - Central transcription container with metadata, audio association, and musical content\n- **`Phrase`** - Musical phrase containing trajectory data and categorizations\n- **`Trajectory`** - Detailed pitch movement data with timing and articulations\n- **`Pitch`** - Individual pitch points with frequency and timing information\n- **`Raga`** - Indian musical scale/mode definitions with theoretical rules\n- **`Section`** - Large structural divisions (alap, composition, etc.)\n- **`Meter`** - Rhythmic cycle and tempo information\n- **`Articulation`** - Performance technique annotations (meend, andolan, etc.)\n\n### Specialized Features\n\n- **Microtonal Pitch System** - Precise cent-based pitch representation\n- **Hindustani Music Theory** - Raga rules, sargam notation, gharana traditions\n- **Performance Analysis** - Ornament detection, phrase categorization\n- **Multi-Track Support** - Simultaneous transcription of melody and drone\n\n## Authentication\n\nThe client uses OAuth 2.0 flow with Google authentication. On first use, it will:\n\n1. Open a browser for Google OAuth login\n2. Securely store the authentication token using:\n   - OS keyring (preferred)\n   - Encrypted local file (fallback)\n   - Plain text (legacy, discouraged)\n\n### Research Waiver Requirement\n\n**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:\n\n```python\nclient = SwaraClient()\ntranscriptions = client.get_viewable_transcriptions()  # Will raise RuntimeError\n\n# First, read the waiver text\nwaiver_text = client.get_waiver_text()\nprint(\"Research Waiver:\")\nprint(waiver_text)\n\n# After reading, agree to the waiver\nclient.agree_to_waiver(i_agree=True)\ntranscriptions = client.get_viewable_transcriptions()  # Now works\n\n# Check waiver status\nif client.has_agreed_to_waiver():\n    print(\"Waiver agreed - full access available\")\n```\n\n### Manual Token Management\n\n```python\n# Initialize without auto-login\nclient = SwaraClient(auto_login=False)\n\n# Login manually when needed\nfrom idtap_api import login_google\nlogin_google()\n```\n\n## Advanced Usage\n\n### Batch Processing\n\n```python\n# Process multiple transcriptions\ntranscriptions = client.get_viewable_transcriptions()\n\nfor trans in transcriptions:\n    if trans.get('instrumentation') == 'Sitar':\n        piece = Piece.from_json(client.get_piece(trans['_id']))\n        \n        # Analyze sitar-specific features\n        total_meends = sum(\n            len([art for art in traj.articulation if art.stroke == 'meend'])\n            for phrase in piece.phrases\n            for traj in phrase.trajectories\n        )\n        print(f\"{piece.title}: {total_meends} meends\")\n```\n\n### Research Applications\n\n```python\n# Raga analysis across corpus\nraga_stats = {}\nfor trans in transcriptions:\n    piece = Piece.from_json(client.get_piece(trans['_id']))\n    if piece.raga:\n        raga_name = piece.raga.name\n        raga_stats[raga_name] = raga_stats.get(raga_name, 0) + 1\n\nprint(\"Raga distribution:\", raga_stats)\n```\n\n## Development\n\n### Running Tests\n\n```bash\n# Unit tests\npytest idtap_api/tests/\n\n# Integration tests (requires authentication)\npython api_testing/api_test.py\n```\n\n### Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Add tests for new functionality\n4. Ensure all tests pass\n5. Submit a pull request\n\n## Documentation\n\n- **API Reference**: Full documentation of all classes and methods\n- **Musical Concepts**: Guide to Hindustani music terminology and theory\n- **Research Examples**: Academic use cases and analysis workflows\n\n## Platform Access\n\n- **IDTAP Web Platform**: [swara.studio](https://swara.studio)\n- **Source Code**: [github.com/jon-myers/idtap](https://github.com/jon-myers/idtap)\n- **Research Paper**: \"Beyond Notation: A Digital Platform for Transcribing and Analyzing Oral Melodic Traditions\" (ISMIR 2025)\n\n## Support\n\n- **GitHub Issues**: [Report bugs and request features](https://github.com/jon-myers/idtap/issues)\n- **Research Contact**: Jonathan Myers & Dard Neuman, UC Santa Cruz\n- **Platform**: [swara.studio](https://swara.studio)\n\n## License\n\nMIT License - see LICENSE file for details.\n\n## Citation\n\nIf you use IDTAP in academic research, please cite the ISMIR 2025 paper:\n\n```bibtex\n@inproceedings{myers2025beyond,\n  title={Beyond Notation: A Digital Platform for Transcribing and Analyzing Oral Melodic Traditions},\n  author={Myers, Jonathan and Neuman, Dard},\n  booktitle={Proceedings of the 26th International Society for Music Information Retrieval Conference},\n  pages={},\n  year={2025},\n  address={Daejeon, South Korea},\n  url={https://swara.studio}\n}\n```\n\n---\n\n**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.\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python client library for IDTAP - Interactive Digital Transcription and Analysis Platform for Hindustani music",
    "version": "0.1.3",
    "project_urls": {
        "Bug Tracker": "https://github.com/UCSC-IDTAP/Python-API/issues",
        "Documentation": "https://github.com/UCSC-IDTAP/Python-API",
        "Homepage": "https://swara.studio",
        "Repository": "https://github.com/UCSC-IDTAP/Python-API"
    },
    "split_keywords": [
        "music",
        " transcription",
        " hindustani",
        " indian-classical",
        " musicology",
        " ethnomusicology",
        " raga",
        " pitch-analysis",
        " audio-analysis"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9b3804fe93ce23cdcc1ddb49a8a4aca2a7233583515f2743b35725ebc39cd74a",
                "md5": "325ff7af68117d8bab312bbd6e269d37",
                "sha256": "f83d66670c535f9d9471943bc594c10857818f5b91fe4bfd1fadfe525611f2bb"
            },
            "downloads": -1,
            "filename": "idtap_api-0.1.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "325ff7af68117d8bab312bbd6e269d37",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 85700,
            "upload_time": "2025-07-24T23:30:27",
            "upload_time_iso_8601": "2025-07-24T23:30:27.311499Z",
            "url": "https://files.pythonhosted.org/packages/9b/38/04fe93ce23cdcc1ddb49a8a4aca2a7233583515f2743b35725ebc39cd74a/idtap_api-0.1.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b5f853563a55eb8ad144c8e86bd3c5263ea3c1070d9a77f064c24195356ed3fd",
                "md5": "37af62723308fef14756a1180181e415",
                "sha256": "cefad8d3ee4efb6e2c9082e30909deb3144fa3da646b3e17e3f2169a6a67d5e8"
            },
            "downloads": -1,
            "filename": "idtap_api-0.1.3.tar.gz",
            "has_sig": false,
            "md5_digest": "37af62723308fef14756a1180181e415",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 81216,
            "upload_time": "2025-07-24T23:30:28",
            "upload_time_iso_8601": "2025-07-24T23:30:28.267334Z",
            "url": "https://files.pythonhosted.org/packages/b5/f8/53563a55eb8ad144c8e86bd3c5263ea3c1070d9a77f064c24195356ed3fd/idtap_api-0.1.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-24 23:30:28",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "UCSC-IDTAP",
    "github_project": "Python-API",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "requests",
            "specs": [
                [
                    ">=",
                    "2.31.0"
                ]
            ]
        },
        {
            "name": "requests-toolbelt",
            "specs": [
                [
                    ">=",
                    "1.0.1"
                ]
            ]
        },
        {
            "name": "pyhumps",
            "specs": [
                [
                    ">=",
                    "3.8.0"
                ]
            ]
        },
        {
            "name": "keyring",
            "specs": [
                [
                    ">=",
                    "24.0.0"
                ]
            ]
        },
        {
            "name": "cryptography",
            "specs": [
                [
                    ">=",
                    "41.0.0"
                ]
            ]
        },
        {
            "name": "PyJWT",
            "specs": [
                [
                    ">=",
                    "2.8.0"
                ]
            ]
        },
        {
            "name": "secretstorage",
            "specs": [
                [
                    ">=",
                    "3.3.0"
                ]
            ]
        }
    ],
    "lcname": "idtap-api"
}
        
Elapsed time: 2.02116s