import requests import pyttsx3 import time import logging """ Bitcoin Price TTS This script continuously fetches the current Bitcoin price from the Binance public API and announces it using text-to-speech with a feminine voice. The RateLimiter class controls the request rate to adhere to any rate limits imposed by the API. To run this script, be sure to install the required modules: 1. requests: Used for making HTTP requests. Install with: pip install requests 2. pyttsx3: Text-to-speech library for Python. Install with: pip install pyttsx3 Author: J2897 with help from ChatGPT. """ sleep_time = 30 # Adjust the sleep time as needed segmented = True # Only say the price in $10 segments (less specific, but quieter during low volatility). # Set up logging configuration to exclude INFO messages logging.basicConfig(level=logging.WARNING) class RateLimiter: def __init__(self, rate_limit): """ Initializes the RateLimiter with a specified rate limit. :param rate_limit: The time interval (in seconds) between consecutive requests. """ self.rate_limit = rate_limit self.last_request_time = 0 def wait(self): """ Enforces rate limiting by pausing the execution if the time since the last request is less than the specified rate limit. """ current_time = time.time() time_since_last_request = current_time - self.last_request_time if time_since_last_request < self.rate_limit: time.sleep(self.rate_limit - time_since_last_request) self.last_request_time = time.time() def get_bitcoin_price(rate_limiter): """ Fetches the current Bitcoin price from the Binance public API. :param rate_limiter: An instance of the RateLimiter class to control the request rate. :return: The current Bitcoin price or None if an error occurs. """ symbol = "BTCUSDT" binance_api_url = f"https://api.binance.com/api/v3/ticker/price?symbol={symbol}" try: # Enforce rate limiting rate_limiter.wait() response = requests.get(binance_api_url) response.raise_for_status() # Raise an HTTPError for bad responses data = response.json() # Check if the response contains the required data if 'symbol' in data and 'price' in data: return float(data['price']) else: logging.ERROR("Unexpected data structure in the Binance ticker response.") return None except requests.exceptions.RequestException as err: logging.ERROR(f"Request failed: {err}") return None def speak_price(price, voice_index=0): """ Announces the Bitcoin price using text-to-speech. :param price: The Bitcoin price to be announced. :param voice_index: Index of the voice (default is 1, often a female voice). """ engine = pyttsx3.init() voices = engine.getProperty('voices') if 0 <= voice_index < len(voices): engine.setProperty('voice', voices[voice_index].id) else: logging.WARNING("Invalid voice index. Using the default voice.") price_str = f"{int(price)}" engine.say(price_str) engine.runAndWait() def main(): """ Main function to continuously fetch and announce the Bitcoin price. """ rate_limiter = RateLimiter(rate_limit=1) # Set a rate limit of 1 second for Binance last_price = get_bitcoin_price(rate_limiter) # Update last_price for the first iteration while True: current_price = get_bitcoin_price(rate_limiter) if current_price is not None: current_price_seg = int(current_price / 10) last_price_seg = int(last_price / 10) print(f"The current Bitcoin price is ${current_price:.2f}") if segmented: if current_price_seg != last_price_seg: speak_price(current_price_seg * 10, voice_index=0) else: speak_price(current_price, voice_index=1) last_price = current_price # Update last_price for the next iteration time.sleep(sleep_time) if __name__ == "__main__": main()