improve unit-testing

use config class which reads from .env file
remove obsolete functions
update requirements
This commit is contained in:
aceisace 2023-01-11 22:24:39 +01:00
parent 9fa2f4a003
commit 8e754cb6cd
16 changed files with 237 additions and 197 deletions

View File

@ -0,0 +1 @@
from config import Config

35
inkycal/tests/config.py Normal file
View File

@ -0,0 +1,35 @@
#!python
"""
Tests config
"""
import os
from enum import Enum
from dotenv import load_dotenv
# relative import
basedir = os.path.abspath(os.path.dirname(__file__))
# load config from corresponding file
load_dotenv(os.path.join(basedir, '.env'))
class Config:
get = os.environ.get
# show generated images via preview?
USE_PREVIEW = False
# ical_parser_test
OPENWEATHERMAP_API_KEY = get("OPENWEATHERMAP_API_KEY")
TEST_ICAL_URL = get("TEST_ICAL_URL")
# inkycal_agenda_test & inkycal_calendar_test
SAMPLE_ICAL_URL = get("SAMPLE_ICAL_URL")
# inkycal_todoist_test
TODOIST_API_KEY = get("TODOIST_API_KEY")

View File

@ -1,24 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
Helper functions for inkycal tests.
Copyright by aceisace
"""
import logging
import sys
from os.path import exists
from inkycal.modules.inky_image import Inkyimage
preview = Inkyimage.preview
merge = Inkyimage.merge
def get_environment():
# Check if this is running on the Raspberry Pi
environment = None
envir_path = '/sys/firmware/devicetree/base/model'
if exists(envir_path):
with open(envir_path) as file:
if 'Raspberry' in file.read():
environment = 'Raspberry'
return environment

View File

@ -1,20 +1,19 @@
#!python3 #!python3
""" """
iCalendar parser test (ical_parser) iCalendar parser test (ical_parser)
Copyright by aceisace
""" """
import logging
import os import os
import arrow import sys
import unittest import unittest
from urllib.request import urlopen from urllib.request import urlopen
import arrow
from inkycal.modules.ical_parser import iCalendar from inkycal.modules.ical_parser import iCalendar
from helper_functions import * from inkycal.tests import Config
ical = iCalendar() ical = iCalendar()
test_ical = 'https://calendar.google.com/calendar/ical/en.usa%23holiday%40group.v.calendar.google.com/public/basic.ics' test_ical = Config.TEST_ICAL_URL
class ical_parser_test(unittest.TestCase): class ical_parser_test(unittest.TestCase):
@ -42,7 +41,7 @@ class ical_parser_test(unittest.TestCase):
def test_laod_from_file(self): def test_laod_from_file(self):
print('testing loading from file...', end="") print('testing loading from file...', end="")
dummy = str(urlopen(test_ical).read().decode()) dummy = str(urlopen(test_ical).read().decode())
with open('dummy.ical', mode="w") as file: with open('dummy.ical', mode="w", encoding="utf-8") as file:
file.write(dummy) file.write(dummy)
ical.load_from_file('dummy.ical') ical.load_from_file('dummy.ical')
print('OK') print('OK')

View File

@ -1,19 +1,18 @@
#!python3 #!python3
""" """
Agenda test (inkycal_agenda) inkycal_agenda unittest
Copyright by aceisace
""" """
import logging
import sys
import unittest import unittest
from inkycal.modules import Agenda as Module from inkycal.modules import Agenda as Module
from helper_functions import *
environment = get_environment() from inkycal.modules.inky_image import Inkyimage
from inkycal.tests import Config
preview = Inkyimage.preview
merge = Inkyimage.merge
# Set to True to preview images. Only works on Raspberry Pi OS with Desktop sample_url = Config.SAMPLE_ICAL_URL
use_preview = False
sample_url = "https://www.officeholidays.com/ics-fed/usa"
tests = [ tests = [
{ {
@ -74,7 +73,7 @@ class module_test(unittest.TestCase):
module = Module(test) module = Module(test)
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
print('OK') print('OK')
if use_preview == True and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))

View File

@ -1,20 +1,19 @@
#!python3 #!python3
""" """
Calendar test (inkycal_calendar) inkycal_calendar unittest
Copyright by aceisace
""" """
import logging
import sys
import unittest import unittest
from inkycal.modules import Calendar as Module from inkycal.modules import Calendar as Module
from helper_functions import *
environment = get_environment() from inkycal.modules.inky_image import Inkyimage
from inkycal.tests import Config
preview = Inkyimage.preview
merge = Inkyimage.merge
# Set to True to preview images. Only works on Raspberry Pi OS with Desktop sample_url = Config.SAMPLE_ICAL_URL
use_preview = False
sample_url = "https://www.officeholidays.com/ics-fed/usa"
tests = [ tests = [
{ {
@ -80,7 +79,7 @@ class module_test(unittest.TestCase):
module = Module(test) module = Module(test)
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
print('OK') print('OK')
if use_preview and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))

View File

@ -1,18 +1,16 @@
#!python3 #!python3
""" """
Feeds test (inykcal_feeds) inkycal_feeds unittest
Copyright by aceisace
""" """
import logging
import sys
import unittest import unittest
from inkycal.modules import Feeds as Module from inkycal.modules import Feeds as Module
from helper_functions import * from inkycal.modules.inky_image import Inkyimage
from inkycal.tests import Config
environment = get_environment() preview = Inkyimage.preview
merge = Inkyimage.merge
# Set to True to preview images. Only works on Raspberry Pi OS with Desktop
use_preview = False
tests = [ tests = [
{ {
@ -57,7 +55,7 @@ class module_test(unittest.TestCase):
module = Module(test) module = Module(test)
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
print('OK') print('OK')
if use_preview and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))
im = merge(im_black, im_colour) im = merge(im_black, im_colour)
im.show() im.show()

View File

@ -1,23 +1,21 @@
#!python3 #!python3
""" """
Image test (inkycal_image) inkycal_image unittest
Copyright by aceisace
""" """
import logging
import sys
import unittest import unittest
import requests import requests
from PIL import Image from PIL import Image
from inkycal.modules import Inkyimage as Module from inkycal.modules import Inkyimage as Module
from inkycal.custom import top_level
from helper_functions import *
environment = get_environment() from inkycal.modules.inky_image import Inkyimage
from inkycal.tests import Config
# Set to True to preview images. Only works on Raspberry Pi OS with Desktop preview = Inkyimage.preview
use_preview = False merge = Inkyimage.merge
url = "https://github.com/aceisace/Inkycal/raw/assets/Repo/coffee.png" url = "https://github.com/aceisace/Inkycal/raw/assets/Repo/coffee.png"
@ -118,7 +116,7 @@ class module_test(unittest.TestCase):
module = Module(test) module = Module(test)
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
print('OK') print('OK')
if use_preview == True and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))

View File

@ -1,62 +1,70 @@
#!python3 #!python3
""" """
Jokes test (inkycal_jokes) inkycal_jokes unittest
Copyright by aceisace
""" """
import logging
import sys
import unittest import unittest
from inkycal.modules import Jokes as Module from inkycal.modules import Jokes as Module
from helper_functions import * from inkycal.modules.inky_image import Inkyimage
environment = get_environment() from inkycal.tests import Config
# Set to True to preview images. Only works on Raspberry Pi OS with Desktop
use_preview = False
preview = Inkyimage.preview
merge = Inkyimage.merge
tests = [ tests = [
{ {
"name": "Jokes", "name": "Jokes",
"config": { "config": {
"size": [300, 60], "size": [300, 60],
"padding_x": 10, "padding_y": 10, "fontsize": 12, "language": "en" "padding_x": 10,
} "padding_y": 10,
}, "fontsize": 12,
{ "language": "en"
"name": "Jokes", }
"config": { },
"size": [300, 30], {
"padding_x": 10, "padding_y": 10, "fontsize": 12, "language": "en" "name": "Jokes",
} "config": {
}, "size": [300, 30],
{ "padding_x": 10,
"name": "Jokes", "padding_y": 10,
"config": { "fontsize": 12,
"size": [100, 800], "language": "en"
"padding_x": 10, "padding_y": 10, "fontsize": 18, "language": "en" }
} },
}, {
"name": "Jokes",
"config": {
"size": [100, 800],
"padding_x": 10,
"padding_y": 10,
"fontsize": 18,
"language": "en"
}
},
] ]
class module_test(unittest.TestCase):
def test_get_config(self):
print('getting data for web-ui...', end = "")
Module.get_config()
print('OK')
def test_generate_image(self): class module_test(unittest.TestCase):
for test in tests: def test_get_config(self):
print(f'test {tests.index(test)+1} generating image..') print('getting data for web-ui...', end="")
module = Module(test) Module.get_config()
im_black, im_colour = module.generate_image() print('OK')
print('OK')
if use_preview == True and environment == 'Raspberry': def test_generate_image(self):
preview(merge(im_black, im_colour)) for test in tests:
print(f'test {tests.index(test) + 1} generating image..')
module = Module(test)
im_black, im_colour = module.generate_image()
print('OK')
if Config.USE_PREVIEW:
preview(merge(im_black, im_colour))
if __name__ == '__main__': if __name__ == '__main__':
logger = logging.getLogger()
logger.level = logging.DEBUG
logger.addHandler(logging.StreamHandler(sys.stdout))
logger = logging.getLogger() unittest.main()
logger.level = logging.DEBUG
logger.addHandler(logging.StreamHandler(sys.stdout))
unittest.main()

View File

@ -2,22 +2,20 @@
""" """
Slideshow test (inkycal_slideshow) Slideshow test (inkycal_slideshow)
Copyright by aceisace
""" """
import logging
import os import os
import sys
import unittest import unittest
import requests import requests
from PIL import Image from PIL import Image
from inkycal.modules import Slideshow as Module from inkycal.modules import Slideshow as Module
from inkycal.custom import top_level from inkycal.modules.inky_image import Inkyimage
from helper_functions import * from inkycal.tests import Config
environment = get_environment() preview = Inkyimage.preview
merge = Inkyimage.merge
# Set to True to preview images. Only works on Raspberry Pi OS with Desktop
use_preview = False
if not os.path.exists("tmp"): if not os.path.exists("tmp"):
os.mkdir("tmp") os.mkdir("tmp")
@ -42,7 +40,10 @@ tests = [
"palette": "bwy", "palette": "bwy",
"autoflip": True, "autoflip": True,
"orientation": "vertical", "orientation": "vertical",
"padding_x": 10, "padding_y": 10, "fontsize": 12, "language": "en" "padding_x": 10,
"padding_y": 10,
"fontsize": 12,
"language": "en"
} }
}, },
{ {
@ -53,7 +54,10 @@ tests = [
"palette": "bw", "palette": "bw",
"autoflip": True, "autoflip": True,
"orientation": "vertical", "orientation": "vertical",
"padding_x": 10, "padding_y": 10, "fontsize": 12, "language": "en" "padding_x": 10,
"padding_y": 10,
"fontsize": 12,
"language": "en"
} }
}, },
{ {
@ -64,7 +68,10 @@ tests = [
"palette": "bwr", "palette": "bwr",
"autoflip": False, "autoflip": False,
"orientation": "vertical", "orientation": "vertical",
"padding_x": 10, "padding_y": 10, "fontsize": 12, "language": "en" "padding_x": 10,
"padding_y": 10,
"fontsize": 12,
"language": "en"
} }
}, },
{ {
@ -75,7 +82,10 @@ tests = [
"palette": "bwy", "palette": "bwy",
"autoflip": True, "autoflip": True,
"orientation": "vertical", "orientation": "vertical",
"padding_x": 10, "padding_y": 10, "fontsize": 12, "language": "en" "padding_x": 10,
"padding_y": 10,
"fontsize": 12,
"language": "en"
} }
}, },
{ {
@ -86,7 +96,10 @@ tests = [
"palette": "bwy", "palette": "bwy",
"autoflip": True, "autoflip": True,
"orientation": "horizontal", "orientation": "horizontal",
"padding_x": 10, "padding_y": 10, "fontsize": 12, "language": "en" "padding_x": 10,
"padding_y": 10,
"fontsize": 12,
"language": "en"
} }
}, },
{ {
@ -97,7 +110,10 @@ tests = [
"palette": "bw", "palette": "bw",
"autoflip": True, "autoflip": True,
"orientation": "vertical", "orientation": "vertical",
"padding_x": 0, "padding_y": 0, "fontsize": 12, "language": "en" "padding_x": 0,
"padding_y": 0,
"fontsize": 12,
"language": "en"
} }
}, },
{ {
@ -109,7 +125,10 @@ tests = [
"palette": "bwr", "palette": "bwr",
"autoflip": True, "autoflip": True,
"orientation": "vertical", "orientation": "vertical",
"padding_x": 20, "padding_y": 20, "fontsize": 12, "language": "en" "padding_x": 20,
"padding_y": 20,
"fontsize": 12,
"language": "en"
} }
}, },
] ]
@ -127,22 +146,22 @@ class module_test(unittest.TestCase):
module = Module(test) module = Module(test)
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
print('OK') print('OK')
if use_preview == True and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))
def test_switch_to_next_image(self): def test_switch_to_next_image(self):
print(f'testing switching to next images..') print(f'testing switching to next images..')
module = Module(tests[0]) module = Module(tests[0])
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
if use_preview == True and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
if use_preview == True and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
if use_preview == True and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))
print('OK') print('OK')

View File

@ -1,18 +1,16 @@
#!python3 #!python3
""" """
Stocks test (inkycal_stocks) inkycal_stocks unittest
Copyright by aceisace
""" """
import logging
import sys
import unittest import unittest
from inkycal.modules import Stocks as Module from inkycal.modules import Stocks as Module
from helper_functions import *
environment = get_environment() from inkycal.modules.inky_image import Inkyimage
from inkycal.tests import Config
# Set to True to preview images. Only works on Raspberry Pi OS with Desktop preview = Inkyimage.preview
use_preview = False merge = Inkyimage.merge
tests = [ tests = [
{ {
@ -46,7 +44,7 @@ class module_test(unittest.TestCase):
module = Module(test) module = Module(test)
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
print('OK') print('OK')
if use_preview == True and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))

View File

@ -1,24 +1,30 @@
#!python3 #!python3
import os """
inkycal_todoist unittest
"""
import logging
import sys
import unittest import unittest
from inkycal.modules import Todoist as Module from inkycal.modules import Todoist as Module
from helper_functions import *
environment = get_environment() from inkycal.modules.inky_image import Inkyimage
from inkycal.tests import Config
preview = Inkyimage.preview
merge = Inkyimage.merge
# Set to True to preview images. Only works on Raspberry Pi OS with Desktop api_key = Config.TODOIST_API_KEY
use_preview = False
api_key = os.environ["TODOIST_API_KEY"] or ""
tests = [ tests = [
{ {
"name": "Todoist", "name": "Todoist",
"config": { "config": {
"size": [500, 200], "size": [400, 1000],
"api_key": api_key, "api_key": api_key,
"project_filter": None, "project_filter": None,
"padding_x": 10, "padding_y": 10, "fontsize": 12, "language": "en" "padding_x": 10,
"padding_y": 10,
"fontsize": 12,
"language": "en"
} }
}, },
] ]
@ -38,8 +44,9 @@ class module_test(unittest.TestCase):
module = Module(test) module = Module(test)
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
print('OK') print('OK')
if use_preview and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))
merge(im_black, im_colour).show()
else: else:
print('No api key given, omitting test') print('No api key given, omitting test')

View File

@ -1,15 +1,18 @@
#!python3 #!python3
import os """
inkycal_weather unittest
"""
import logging
import sys
import unittest import unittest
from inkycal.modules import Weather as Module from inkycal.modules import Weather as Module
from helper_functions import *
environment = get_environment() from inkycal.modules.inky_image import Inkyimage
from inkycal.tests import Config
preview = Inkyimage.preview
merge = Inkyimage.merge
# Set to True to preview images. Only works on Raspberry Pi OS with Desktop owm_api_key = Config.OPENWEATHERMAP_API_KEY
use_preview = False
secret_key = os.environ["OPENWEATHERMAP_API_KEY"] or ""
location = 'Stuttgart, DE' location = 'Stuttgart, DE'
tests = [ tests = [
@ -18,7 +21,7 @@ tests = [
"name": "Weather", "name": "Weather",
"config": { "config": {
"size": [500, 100], "size": [500, 100],
"api_key": secret_key, "api_key": owm_api_key,
"location": location, "location": location,
"round_temperature": True, "round_temperature": True,
"round_windspeed": True, "round_windspeed": True,
@ -37,7 +40,7 @@ tests = [
"name": "Weather", "name": "Weather",
"config": { "config": {
"size": [500, 150], "size": [500, 150],
"api_key": secret_key, "api_key": owm_api_key,
"location": "2643123", "location": "2643123",
"round_temperature": True, "round_temperature": True,
"round_windspeed": True, "round_windspeed": True,
@ -56,7 +59,7 @@ tests = [
"name": "Weather", "name": "Weather",
"config": { "config": {
"size": [500, 200], "size": [500, 200],
"api_key": secret_key, "api_key": owm_api_key,
"location": location, "location": location,
"round_temperature": False, "round_temperature": False,
"round_windspeed": True, "round_windspeed": True,
@ -75,7 +78,7 @@ tests = [
"name": "Weather", "name": "Weather",
"config": { "config": {
"size": [500, 100], "size": [500, 100],
"api_key": secret_key, "api_key": owm_api_key,
"location": location, "location": location,
"round_temperature": True, "round_temperature": True,
"round_windspeed": False, "round_windspeed": False,
@ -94,7 +97,7 @@ tests = [
"name": "Weather", "name": "Weather",
"config": { "config": {
"size": [500, 150], "size": [500, 150],
"api_key": secret_key, "api_key": owm_api_key,
"location": location, "location": location,
"round_temperature": True, "round_temperature": True,
"round_windspeed": True, "round_windspeed": True,
@ -113,7 +116,7 @@ tests = [
"name": "Weather", "name": "Weather",
"config": { "config": {
"size": [500, 150], "size": [500, 150],
"api_key": secret_key, "api_key": owm_api_key,
"location": location, "location": location,
"round_temperature": True, "round_temperature": True,
"round_windspeed": True, "round_windspeed": True,
@ -132,7 +135,7 @@ tests = [
"name": "Weather", "name": "Weather",
"config": { "config": {
"size": [500, 100], "size": [500, 100],
"api_key": secret_key, "api_key": owm_api_key,
"location": location, "location": location,
"round_temperature": True, "round_temperature": True,
"round_windspeed": True, "round_windspeed": True,
@ -151,7 +154,7 @@ tests = [
"name": "Weather", "name": "Weather",
"config": { "config": {
"size": [500, 100], "size": [500, 100],
"api_key": secret_key, "api_key": owm_api_key,
"location": location, "location": location,
"round_temperature": True, "round_temperature": True,
"round_windspeed": True, "round_windspeed": True,
@ -175,16 +178,14 @@ class module_test(unittest.TestCase):
print('OK') print('OK')
def test_generate_image(self): def test_generate_image(self):
if secret_key: for test in tests:
for test in tests: print(f'test {tests.index(test) + 1} generating image..')
print(f'test {tests.index(test) + 1} generating image..') module = Module(test)
module = Module(test) im_black, im_colour = module.generate_image()
im_black, im_colour = module.generate_image() print('OK')
print('OK') if Config.USE_PREVIEW:
if use_preview and environment == 'Raspberry': preview(merge(im_black, im_colour))
preview(merge(im_black, im_colour))
else:
print('No key given, omitted testing')
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -1,8 +1,6 @@
#!python3 #!python3
""" """
Main test (main) Inkycal main unittest
Copyright by aceisace
""" """
import os import os
import unittest import unittest
@ -63,7 +61,7 @@ class ModuleTest(unittest.TestCase):
# Check if settings.json file exists in current directory # Check if settings.json file exists in current directory
if not os.path.exists("settings.json"): if not os.path.exists("settings.json"):
# Create temporary json settings file with the config from above # Create temporary json settings file with the config from above
with open('settings.json', mode="w") as file: with open('settings.json', mode="w", encoding="utf-8") as file:
file.write(test_config) file.write(test_config)
print('testing Inkycal in non-render-mode...', end="") print('testing Inkycal in non-render-mode...', end="")
inky = Inkycal('settings.json', render=False) inky = Inkycal('settings.json', render=False)

View File

@ -1,13 +1,14 @@
#!python3 #!python3
import logging
import os import os
import sys
import unittest import unittest
from inkycal.modules import TextToDisplay as Module from inkycal.modules import TextToDisplay as Module
from helper_functions import *
environment = get_environment() from inkycal.modules.inky_image import Inkyimage
from inkycal.tests import Config
# Set to True to preview images. Only works on Raspberry Pi OS with Desktop preview = Inkyimage.preview
use_preview = False merge = Inkyimage.merge
file_path = None file_path = None
@ -78,6 +79,7 @@ tests = [
class TestTextToDisplay(unittest.TestCase): class TestTextToDisplay(unittest.TestCase):
def test_get_config(self): def test_get_config(self):
print('getting data for web-ui...', end="") print('getting data for web-ui...', end="")
Module.get_config() Module.get_config()
@ -91,7 +93,7 @@ class TestTextToDisplay(unittest.TestCase):
print("Filepath does not exist. Creating dummy file") print("Filepath does not exist. Creating dummy file")
tmp_path = "tmp.txt" tmp_path = "tmp.txt"
with open(tmp_path, mode="w") as file: with open(tmp_path, mode="w", encoding="utf-8") as file:
file.writelines(dummy_data) file.writelines(dummy_data)
# update tests with new temp path # update tests with new temp path
@ -99,7 +101,7 @@ class TestTextToDisplay(unittest.TestCase):
test["config"]["filepath"] = tmp_path test["config"]["filepath"] = tmp_path
else: else:
make_request = True if file_path.startswith("https://") else False make_request = bool(file_path.startswith("https://"))
if not make_request and not os.path.exists(file_path): if not make_request and not os.path.exists(file_path):
raise FileNotFoundError("Your text file could not be found") raise FileNotFoundError("Your text file could not be found")
@ -108,7 +110,7 @@ class TestTextToDisplay(unittest.TestCase):
module = Module(test) module = Module(test)
im_black, im_colour = module.generate_image() im_black, im_colour = module.generate_image()
print('OK') print('OK')
if use_preview and environment == 'Raspberry': if Config.USE_PREVIEW:
preview(merge(im_black, im_colour)) preview(merge(im_black, im_colour))
im = merge(im_black, im_colour) im = merge(im_black, im_colour)
im.show() im.show()

View File

@ -27,4 +27,6 @@ six==1.16.0
todoist-api-python==2.0.2 todoist-api-python==2.0.2
typing_extensions==4.4.0 typing_extensions==4.4.0
urllib3==1.26.13 urllib3==1.26.13
yfinance==0.2.3 yfinance==0.2.3
python-dotenv~=0.21.0
setuptools==65.6.3