Skip to content

Commit

Permalink
Merge pull request #742 from ftnext/action-flake8
Browse files Browse the repository at this point in the history
  • Loading branch information
ftnext authored Apr 2, 2024
2 parents 8bc8e2c + e1c457a commit 53c994f
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 83 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Static analysis

on:
push:
branches:
- master
pull_request:
branches:
- master

jobs:
flake8:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install flake8
- name: Run flake8
run: |
# ignore errors for long lines and multi-statement lines
python -m flake8 --ignore=E501,E701,W503 speech_recognition tests examples setup.py
35 changes: 0 additions & 35 deletions .travis.yml

This file was deleted.

20 changes: 11 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ To hack on this library, first make sure you have all the requirements listed in
- Documentation can be found in the ``reference/`` `directory <https://github.com/Uberi/speech_recognition/tree/master/reference>`__.
- Third-party libraries, utilities, and reference material are in the ``third-party/`` `directory <https://github.com/Uberi/speech_recognition/tree/master/third-party>`__.

To install/reinstall the library locally, run ``python setup.py install`` in the project `root directory <https://github.com/Uberi/speech_recognition>`__.
To install/reinstall the library locally, run ``python -m pip install -e .[dev]`` in the project `root directory <https://github.com/Uberi/speech_recognition>`__.

Before a release, the version number is bumped in ``README.rst`` and ``speech_recognition/__init__.py``. Version tags are then created using ``git config gpg.program gpg2 && git config user.signingkey DB45F6C431DE7C2DCD99FF7904882258A4063489 && git tag -s VERSION_GOES_HERE -m "Version VERSION_GOES_HERE"``.

Expand All @@ -291,17 +291,19 @@ To run all the tests:
python -m unittest discover --verbose
Testing is also done automatically by TravisCI, upon every push. To set up the environment for offline/local Travis-like testing on a Debian-like system:
To run static analysis:

.. code:: bash
sudo docker run --volume "$(pwd):/speech_recognition" --interactive --tty quay.io/travisci/travis-python:latest /bin/bash
su - travis && cd /speech_recognition
sudo apt-get update && sudo apt-get install swig libpulse-dev
pip install --user pocketsphinx && pip install --user flake8 rstcheck && pip install --user -e .
python -m unittest discover --verbose # run unit tests
python -m flake8 --ignore=E501,E701 speech_recognition tests examples setup.py # ignore errors for long lines and multi-statement lines
python -m rstcheck README.rst reference/*.rst # ensure RST is well-formed
python -m flake8 --ignore=E501,E701,W503 speech_recognition tests examples setup.py
To ensure RST is well-formed:

.. code:: bash
python -m rstcheck README.rst reference/*.rst
Testing is also done automatically by GitHub Actions, upon every push.

FLAC Executables
~~~~~~~~~~~~~~~~
Expand Down
4 changes: 2 additions & 2 deletions examples/microphone_recognition.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@
except sr.UnknownValueError:
print("Whisper could not understand audio")
except sr.RequestError as e:
print("Could not request results from Whisper")
print(f"Could not request results from Whisper; {e}")

# recognize speech using Whisper API
OPENAI_API_KEY = "INSERT OPENAI API KEY HERE"
try:
print(f"Whisper API thinks you said {r.recognize_whisper_api(audio, api_key=OPENAI_API_KEY)}")
except sr.RequestError as e:
print("Could not request results from Whisper API")
print(f"Could not request results from Whisper API; {e}")
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
universal=1

[options.extras_require]
dev =
flake8
rstcheck
whisper-local =
openai-whisper
soundfile
Expand Down
11 changes: 7 additions & 4 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,15 @@ def run(self):
if os.path.basename(output_path) in FILES_TO_MARK_EXECUTABLE:
log.info("setting executable permissions on {}".format(output_path))
stat_info = os.stat(output_path)
OWNER_CAN_READ_EXECUTE = stat.S_IRUSR | stat.S_IXUSR
GROUP_CAN_READ_EXECUTE = stat.S_IRGRP | stat.S_IXGRP
OTHERS_CAN_READ_EXECUTE = stat.S_IROTH | stat.S_IXOTH
os.chmod(
output_path,
stat_info.st_mode |
stat.S_IRUSR | stat.S_IXUSR | # owner can read/execute
stat.S_IRGRP | stat.S_IXGRP | # group can read/execute
stat.S_IROTH | stat.S_IXOTH # everyone else can read/execute
stat_info.st_mode
| OWNER_CAN_READ_EXECUTE
| GROUP_CAN_READ_EXECUTE
| OTHERS_CAN_READ_EXECUTE,
)


Expand Down
45 changes: 19 additions & 26 deletions speech_recognition/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,8 @@ def recognize_amazon(self, audio_data, bucket_name=None, access_key_id=None, sec
aws_secret_access_key=secret_access_key,
region_name=region)

s3 = boto3.client('s3',
s3 = boto3.client(
's3',
aws_access_key_id=access_key_id,
aws_secret_access_key=secret_access_key,
region_name=region)
Expand All @@ -1107,7 +1108,6 @@ def recognize_amazon(self, audio_data, bucket_name=None, access_key_id=None, sec
except ClientError as exc:
print('Error creating bucket %s: %s' % (bucket_name, exc))
s3res = session.resource('s3')
bucket = s3res.Bucket(bucket_name)
if audio_data is not None:
print('Uploading audio data...')
wav_data = audio_data.get_wav_data()
Expand All @@ -1124,7 +1124,7 @@ def recognize_amazon(self, audio_data, bucket_name=None, access_key_id=None, sec
try:
status = transcribe.get_transcription_job(TranscriptionJobName=job_name)
except ClientError as exc:
print('!'*80)
print('!' * 80)
print('Error getting job:', exc.response)
if exc.response['Error']['Code'] == 'BadRequestException' and "The requested job couldn't be found" in str(exc):
# Some error caused the job we recorded to not exist on AWS.
Expand All @@ -1137,7 +1137,7 @@ def recognize_amazon(self, audio_data, bucket_name=None, access_key_id=None, sec
else:
# Some other error happened, so re-raise.
raise

job = status['TranscriptionJob']
if job['TranscriptionJobStatus'] in ['COMPLETED'] and 'TranscriptFileUri' in job['Transcript']:

Expand All @@ -1152,12 +1152,12 @@ def recognize_amazon(self, audio_data, bucket_name=None, access_key_id=None, sec
confidences.append(float(item['alternatives'][0]['confidence']))
confidence = 0.5
if confidences:
confidence = sum(confidences)/float(len(confidences))
confidence = sum(confidences) / float(len(confidences))
transcript = d['results']['transcripts'][0]['transcript']

# Delete job.
try:
transcribe.delete_transcription_job(TranscriptionJobName=job_name) # cleanup
transcribe.delete_transcription_job(TranscriptionJobName=job_name) # cleanup
except Exception as exc:
print('Warning, could not clean up transcription: %s' % exc)
traceback.print_exc()
Expand All @@ -1167,17 +1167,17 @@ def recognize_amazon(self, audio_data, bucket_name=None, access_key_id=None, sec

return transcript, confidence
elif job['TranscriptionJobStatus'] in ['FAILED']:

# Delete job.
try:
transcribe.delete_transcription_job(TranscriptionJobName=job_name) # cleanup
transcribe.delete_transcription_job(TranscriptionJobName=job_name) # cleanup
except Exception as exc:
print('Warning, could not clean up transcription: %s' % exc)
traceback.print_exc()

# Delete S3 file.
s3.delete_object(Bucket=bucket_name, Key=filename)

exc = TranscriptionFailed()
exc.job_name = None
exc.file_key = None
Expand All @@ -1193,11 +1193,6 @@ def recognize_amazon(self, audio_data, bucket_name=None, access_key_id=None, sec
else:

# Launch the transcription job.
# try:
# transcribe.delete_transcription_job(TranscriptionJobName=job_name) # pre-cleanup
# except:
# # It's ok if this fails because the job hopefully doesn't exist yet.
# pass
try:
transcribe.start_transcription_job(
TranscriptionJobName=job_name,
Expand All @@ -1210,7 +1205,7 @@ def recognize_amazon(self, audio_data, bucket_name=None, access_key_id=None, sec
exc.file_key = None
raise exc
except ClientError as exc:
print('!'*80)
print('!' * 80)
print('Error starting job:', exc.response)
if exc.response['Error']['Code'] == 'LimitExceededException':
# Could not start job. Cancel everything.
Expand Down Expand Up @@ -1277,9 +1272,7 @@ def read_file(filename, chunk_size=5242880):

# Queue file for transcription.
endpoint = "https://api.assemblyai.com/v2/transcript"
json = {
"audio_url": upload_url
}
json = {"audio_url": upload_url}
headers = {
"authorization": api_token,
"content-type": "application/json"
Expand Down Expand Up @@ -1436,23 +1429,23 @@ def recognize_whisper(self, audio_data, model="base", show_dict=False, load_opti
return result
else:
return result["text"]

def recognize_vosk(self, audio_data, language='en'):
from vosk import KaldiRecognizer, Model

assert isinstance(audio_data, AudioData), "Data must be audio data"

if not hasattr(self, 'vosk_model'):
if not os.path.exists("model"):
return "Please download the model from https://github.com/alphacep/vosk-api/blob/master/doc/models.md and unpack as 'model' in the current folder."
exit (1)
exit(1)
self.vosk_model = Model("model")

rec = KaldiRecognizer(self.vosk_model, 16000);
rec.AcceptWaveform(audio_data.get_raw_data(convert_rate=16000, convert_width=2));
rec = KaldiRecognizer(self.vosk_model, 16000)

rec.AcceptWaveform(audio_data.get_raw_data(convert_rate=16000, convert_width=2))
finalRecognition = rec.FinalResult()

return finalRecognition


Expand Down
6 changes: 3 additions & 3 deletions speech_recognition/audio.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ def get_raw_data(self, convert_rate=None, convert_width=None):
audioop.error
): # this version of audioop doesn't support 24-bit audio (probably Python 3.3 or less)
raw_data = b"".join(
raw_data[i + 1 : i + 4]
raw_data[i + 1: i + 4]
for i in range(0, len(raw_data), 4)
) # since we're in little endian, we discard the first byte from each 32-bit sample to get a 24-bit sample
else: # 24-bit audio fully supported, we don't need to shim anything
Expand Down Expand Up @@ -188,8 +188,8 @@ def get_aiff_data(self, convert_rate=None, convert_width=None):
): # ``audioop.byteswap`` was only added in Python 3.4
raw_data = audioop.byteswap(raw_data, sample_width)
else: # manually reverse the bytes of each sample, which is slower but works well enough as a fallback
raw_data = raw_data[sample_width - 1 :: -1] + b"".join(
raw_data[i + sample_width : i : -1]
raw_data = raw_data[sample_width - 1:: -1] + b"".join(
raw_data[i + sample_width: i: -1]
for i in range(sample_width - 1, len(raw_data), sample_width)
)

Expand Down
2 changes: 1 addition & 1 deletion tests/recognizers/test_google.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ def test_parse_without_confidence(

@patch(f"{CLASS_UNDER_TEST}.find_best_hypothesis")
@patch(f"{CLASS_UNDER_TEST}.convert_to_result")
def test_parse_without_confidence(
def test_parse_with_confidence(
self, convert_to_result, find_best_hypothesis
):
convert_to_result.return_value = {"alternative": "dummy3"}
Expand Down
2 changes: 1 addition & 1 deletion tests/recognizers/test_whisper.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_recognize_pass_arguments(self, OpenAI, BytesIO, environ):
recognizer = MagicMock(spec=Recognizer)
audio_data = MagicMock(spec=AudioData)

actual = whisper.recognize_whisper_api(
_ = whisper.recognize_whisper_api(
recognizer, audio_data, model="x-whisper", api_key="OPENAI_API_KEY"
)

Expand Down
2 changes: 0 additions & 2 deletions tests/test_recognition.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import http
import os
import unittest
from unittest.mock import patch, MagicMock

import speech_recognition as sr

Expand Down

0 comments on commit 53c994f

Please sign in to comment.