-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsend_data_to_api.py
215 lines (170 loc) · 6.46 KB
/
send_data_to_api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/usr/bin/env python3
"""
Oliver API Client
This script provides functionality to send audio files to the Oliver API,
process them, and save the results and extracted features.
"""
# Standard library imports
import os
import json
import time
import argparse
# Third-party imports
import requests
# Local imports
import feature_extraction
# Constants
REALTIME_RATIO = 10
BASE_URL = "https://api.behavioralsignals.com/v5"
CONFIG_FILE = "oliver_api.config"
# Load configuration
with open(CONFIG_FILE) as f:
config = json.load(f)
PROJECT_ID = config["project_id"]
API_TOKEN = config["api_token"]
# API endpoints
UPLOAD_URL = f"{BASE_URL}/clients/{PROJECT_ID}/processes/audio"
# Request headers
HEADERS = {
"X-Auth-Token": API_TOKEN
}
def send_audio_file(file_path, file_name):
"""
Upload an audio file to the Oliver API.
Args:
file_path (str): Path to the audio file
file_name (str): Name to use for the uploaded file
Returns:
dict: JSON response from the API or None if upload failed
"""
try:
with open(file_path, "rb") as audio_file:
files = {
"file": audio_file,
"name": (None, file_name)
}
response = requests.post(UPLOAD_URL, headers=HEADERS, files=files)
response.raise_for_status()
print("Upload successful!")
return response.json()
except requests.exceptions.RequestException as e:
print(f"Failed to upload: {e}")
if hasattr(e, 'response') and e.response:
print(f"Status code: {e.response.status_code}")
print(f"Error message: {e.response.text}")
return None
def check_process(process_id, client_id):
"""
Check the status of a processing job.
Args:
process_id (str): Process ID to check
client_id (str): Client ID
Returns:
dict: JSON response with process status
"""
process_url = f"{BASE_URL}/clients/{client_id}/processes/{process_id}"
response = requests.get(process_url, headers=HEADERS)
return response.json()
def send_audio_and_get_response(file_path, file_name):
"""
Send an audio file to the API, monitor processing, and get results.
Args:
file_path (str): Path to the audio file
file_name (str): Name to use for the uploaded file
Returns:
dict: JSON response with processing results or None if processing failed
"""
print("Sending audio file to API...")
upload_response = send_audio_file(file_path, file_name)
if not upload_response:
return None
print("Processing audio file:")
start_time = time.time()
while True:
process_response = check_process(upload_response["pid"], PROJECT_ID)
# Status 2 means processing is complete
if process_response["status"] == 2:
break
# Status 1 means processing is in progress
elif process_response["status"] == 1:
current_time = time.time()
duration = process_response["duration"]
elapsed = current_time - start_time
# Calculate progress percentage
percentage_processed = min(1.0, elapsed * REALTIME_RATIO / duration)
print(f"Please wait... {100 * percentage_processed:.1f}% completed", end="\r")
elif process_response["status"] == 0: # API busy with another job:
print("API is busy, waiting...")
time.sleep(0.5)
end_time = time.time()
processing_time = end_time - start_time
duration = process_response["duration"]
print("DONE ")
print(f"Audio duration: {duration:.1f} seconds")
print(f"Processing took {processing_time:.1f} seconds")
realtime_ratio = duration / processing_time
print(f"Real-time ratio: {realtime_ratio:.1f}")
# Get the results
results_url = f"{BASE_URL}/clients/{PROJECT_ID}/processes/{process_response['pid']}/results"
results_response = requests.get(results_url, headers=HEADERS)
return results_response.json()
def send_audio_and_save_response(file_path):
"""
Send an audio file to the API, get results, and save them to JSON files.
Args:
file_path (str): Path to the audio file
Returns:
dict: JSON response with processing results or None if processing failed
"""
response = send_audio_and_get_response(file_path, os.path.basename(file_path))
if not response:
print(f"Failed to process {file_path}")
return None
# Save raw API response
json_file = file_path.replace(".wav", ".json")
with open(json_file, "w") as f:
json.dump(response, f, indent=4)
print(f"Results saved in: {json_file}")
# Extract and save features
features_json = feature_extraction.extract_segment_features(response)
json_features_file = file_path.replace(".wav", "_features.json")
with open(json_features_file, "w") as f:
json.dump(features_json, f, indent=4, ensure_ascii=False)
print(f"Features saved in: {json_features_file}")
return response
def main():
"""Main function to parse arguments and process audio files."""
parser = argparse.ArgumentParser(
description="Send audio files to Oliver API for processing"
)
parser.add_argument(
"--input", "-i",
type=str,
required=True,
help="Path to the audio file or folder with audio files"
)
args = parser.parse_args()
if not args.input:
parser.print_help()
return
if os.path.isfile(args.input):
# Process a single file
if not args.input.endswith(".wav"):
print("Error: Input file must be a .wav file")
return
send_audio_and_save_response(args.input)
elif os.path.isdir(args.input):
# Process all .wav files in a directory
wav_files = [f for f in os.listdir(args.input) if f.endswith(".wav")]
if not wav_files:
print(f"No .wav files found in {args.input}")
return
print(f"Found {len(wav_files)} .wav files to process")
for file in wav_files:
file_path = os.path.join(args.input, file)
print(f"\nProcessing: {file_path}")
send_audio_and_save_response(file_path)
else:
print(f"Error: Invalid input path '{args.input}'")
if __name__ == "__main__":
main()