diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..2ab8bab Binary files /dev/null and b/.DS_Store differ diff --git a/README.md b/README.md index d2b66ee..e230dfa 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,155 @@ [![Python package](https://github.com/SermetPekin/evdspy-repo/actions/workflows/python-package.yml/badge.svg)](https://github.com/SermetPekin/evdspy-repo/actions/workflows/python-package.yml) [![PyPI](https://img.shields.io/pypi/v/evdspy)](https://img.shields.io/pypi/v/evdspy) [![Supported Python Versions](https://img.shields.io/pypi/pyversions/evdspy)](https://pypi.org/project/evdspy/) [![Downloads](https://pepy.tech/badge/evdspy/week)](https://pepy.tech/project/evdspy) ## evdspy -### Updated on this version - * get_df_datagroup function was added -![image](https://user-images.githubusercontent.com/96650846/201921534-22ef45f0-85cf-4982-b160-2fe37a21d491.png) +### Updated on 1.1.17 + + * The API key parameter has been moved to the HTTP header as required by recent updates from EDDS data provider. + This change enhances security by ensuring that sensitive information is not exposed in URLs. + * get_series function was added + +```python + + from evdspy import get_series , default_start_date_fnc , default_end_date_fnc + balance_of_pay1 = "TP.ODEMGZS.BDTTOPLAM", "TP.ODEMGZS.ABD" + balance_of_pay2 = """ + + TP.ODEMGZS.BDTTOPLAM # + TP.ODEMGZS.ABD # + + """ + cache = True + + df = get_series(balance_of_pay2, + frequency="weekly", + start_date=default_start_date_fnc(), + end_date=default_end_date_fnc(), + aggregation=("avg",), + # proxy="http://127.0.0.1:8000", + # proxies={"http": "http://127.0.0.1:8000"}, + cache=cache, + debug=False) + print(df) + + + +``` -### Updated on 1.1.6 +## example usages - * Fixed type error on json result. - * Some more type hints and refactoring. +```python + +from evdspy import get_series + +template = ''' + TP.ODEMGZS.BDTTOPLAM + TP.ODEMGZS.ABD + TP.ODEMGZS.ARJANTIN + + ''' + +df = get_series(index=template) +df1 = get_series(index=template, start_date="01-01-2000", frequency="monthly") +df2a = get_series(index='TP.ODEMGZS.BDTTOPLAM', start_date="01-01-2000", frequency="monthly", cache=True) +df2b = get_series(index=('TP.ODEMGZS.BDTTOPLAM', 'TP.ODEMGZS.ARJANTIN',), + start_date="01-01-2000", + frequency="monthly", + cache=True) + +df3 = get_series(template, start_date="01-01-2000", frequency="monthly", formulas="avg") +df4 = get_series(template, start_date="01-01-2000", frequency="monthly", formulas=("avg", "min", "avg")) +df5 = get_series(template, proxy="http://proxy.example.com:80") +df6 = get_series(template, proxies={ + 'http': "http://proxy.example.com:80", + 'https': "http://proxy.example.com:80", +}) + + + +``` +## get_series all params + +```python +from typing import Union +import pandas as pd +def get_series( + index: Union[str, tuple[str]], + start_date: str = '01-01-2000', + end_date: str = '01-01-2100', + frequency: str = None, # monthly | weekly | annually | semimonthly | semiannually | business + formulas: str = None, # level | percentage_change | difference | year_to_year_percent_change | year_to_year_differences | + aggregation: str = None, # avg |min | max | first | last | sum + cache: bool = False, + proxy: str = None, + proxies: dict = None, + debug: bool = False + +) -> pd.DataFrame: + ... + + +""" Formulas + + percentage_change = 1 + difference = 2 + year_to_year_percent_change = 3 + year_to_year_differences = 4 + percentage_change_compared = 5 + difference_compared = 6 + moving_average = 7 + moving_sum = 8 + +""" +"""Frequency + daily = 1 + business = 2 + weekly = 3 # Friday + semimonthly = 4 + monthly = 5 + quarterly = 6 + semiannually = 7 + annual = 8 + annually = 8 + + +""" + +""" Aggregation + avg : "avg" + min : "min" + max : "max" + first : "first" + last : "last" + sum : "sum" +""" +"""proxy +proxy = "http://proxy.example.com:80" +""" + +"""proxies +proxies = { + 'http': "http://proxy.example.com:80", + 'https': "http://proxy.example.com:80", + } +""" + +``` + +### Updated on 1.1.16 + * get_df_datagroup function was added + +```python + from evdspy.main import * + + df = get_df_datagroup( + datagroup="bie_gsyhgycf", + start_date="01-01-1998", + end_date="01-01-2030", + + ) + + print(df) +``` ### Updated on 1.1.1 diff --git a/evdspy/.gitignore b/evdspy/.gitignore new file mode 100644 index 0000000..4dba0e1 --- /dev/null +++ b/evdspy/.gitignore @@ -0,0 +1,215 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class +--APIKEY_FOLDER/ +APIKEY_FOLDER/ +APIKEY*/ +API*/ +API*.* +arch.txt +*h.txt + +SeriesData/ +logs/ +pickles/ +tests/ +test.py +unit_tests/ +other_tests/ +OTHER_TESTS/ + +dev/ +---/ +--*.* +--*/ +*ignore*/ +*ignore*.* +ignore_*.* +ignore_*/ +ignore/ +ignore* +*IO/ +setup_config.py + +p/ +tox.ini +api_key.txt +apikey.txt +*.pickle +*proxy*/ + +.idea +*series.cfg +options.cfg +# C extensions +*.so + +.vscode/ +*.*DS_Store + +.DS_Store + +# Distribution / packaging +.Python +*APIKEY_FOLDER/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + + +*.xls +*.xlsx +*.csv +*.txt +*.cmd +*.cfg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ +/_version.py +/EVDSlocal/APIKEY_FOLDER/ diff --git a/evdspy/EVDSlocal/__init__.py b/evdspy/EVDSlocal/__init__.py index d5d4473..5ef3e99 100644 --- a/evdspy/EVDSlocal/__init__.py +++ b/evdspy/EVDSlocal/__init__.py @@ -1 +1 @@ -import evdspy +import evdspy diff --git a/evdspy/EVDSlocal/__version__.py b/evdspy/EVDSlocal/__version__.py new file mode 100644 index 0000000..a763037 --- /dev/null +++ b/evdspy/EVDSlocal/__version__.py @@ -0,0 +1 @@ +#1.1.17 \ No newline at end of file diff --git a/evdspy/EVDSlocal/common/colors.py b/evdspy/EVDSlocal/common/colors.py index 0e009d6..f1a28aa 100644 --- a/evdspy/EVDSlocal/common/colors.py +++ b/evdspy/EVDSlocal/common/colors.py @@ -1,352 +1,352 @@ -import functools -import random - -from rich.console import Console -from rich.theme import Theme -from rich.style import Style - -custom_theme = Theme({ - "info": "dim cyan", - "warning": "magenta", - "danger": "bold red" -}) -console = Console(theme=custom_theme) -# console.print("This is information", style="info") -# console.print("[warning]The pod bay doors are locked[/warning]") -# console.print("Something terrible happened!", style="danger") -colors_style = { - "red": "danger", - "yellow": "warning", - "blue": "info", - -} - -""" - 44 ? "dark_turquoise" ? #00d7d7 ? rgb(0,215,215) ? -? ? 45 ? "turquoise2" ? #00d7ff ? rgb(0,215,255) ? -? ? 46 ? "green1" ? #00ff00 ? rgb(0,255,0) ? -? ? 47 ? "spring_green2" ? #00ff5f ? rgb(0,255,95) ? -? ? 48 ? "spring_green1" ? #00ff87 ? rgb(0,255,135) ? -? ? 49 ? "medium_spring_green" ? #00ffaf ? rgb(0,255,175) ? -""" - -default_styles = { - "default": Style(color="magenta", bgcolor="yellow", italic=True), - "requesting": Style(color="black", bgcolor="magenta", italic=True), - "creating": Style(color="magenta", bgcolor="black", italic=True), - "updating": Style(color="blue", bgcolor="black", italic=True), - "deleting": Style(color="white", bgcolor="red", italic=True), - - "failure2": Style(color="red", bgcolor="black", italic=True), - "failure3": Style(color="magenta", bgcolor="black", italic=True), - "failure4": Style(color="deep_pink1", bgcolor="black", italic=True), - "failure5": Style(color="cyan", bgcolor="black", italic=True), - - "success": Style(color="white", bgcolor="black", italic=True), - "success2": Style(color="medium_turquoise", bgcolor="black", italic=True), - "success3": Style(color="spring_green2", bgcolor="black", italic=True), - "success4": Style(color="spring_green1", bgcolor="black", italic=True), - "success5": Style(color="medium_spring_green", bgcolor="black", italic=True), - "success6": Style(color="turquoise2", bgcolor="black", italic=True), - "success7": Style(color="blue_violet", bgcolor="black", italic=True), - # "info": Style(color="blue", bgcolor="black", italic=True), - "info2": Style(color="deep_sky_blue2", bgcolor="black", italic=True), - "info3": Style(color="turquoise2", bgcolor="black", italic=True), - "info4": Style(color="medium_turquoise", bgcolor="black", italic=True), - "input": Style(color="deep_pink1", bgcolor="black", italic=True), - "menu_item": Style(color="turquoise2", bgcolor="black", italic=True), - -} - -# success_stories = (default_styles["success"], default_styles["success2"], default_styles["creating"]) -# -from typing import Tuple, Any - -from typing import Any - - -def make_flat(x: tuple, y: tuple) -> tuple: - return tuple([x1 for x1 in x] + [y1 for y1 in y]) - - -def combine_similar_ones(*item_list: any) -> tuple: - if len(item_list) > 1 and isinstance(item_list[0], (tuple, list,)): - combined_list = [x for x in item_list] - combined_list = functools.reduce(lambda x, p: make_flat(x, p), combined_list, []) - else: - combined_list = list(item_list[0]) - list_ = [] - - for item in combined_list: - list_.append(default_styles[item]) - return tuple(list_) - - -def get_list_of_keys(key_word: str = "success"): - return tuple([x for x in default_styles.keys() if key_word in x]) - - -success_stories = combine_similar_ones(get_list_of_keys("success"), get_list_of_keys("info")) -failure_stories = combine_similar_ones(get_list_of_keys("fail")) -info_stories = combine_similar_ones(get_list_of_keys("info")) - -def get_style(name: str = "default") -> None: - return default_styles[name] - - -def print_with_color(msg: str, color: str) -> None: - if isinstance(color, str): - color = colors_style[color] - - console.print(msg, style=color) - - -def print_with_style(*msg, style: Style = get_style()) -> None: - console.print(*msg, style=style) - - -def print_with_updating_style(*msg: str) -> None: - print_with_style(*msg, style=default_styles["updating"]) - - -def print_with_deleting_style(*msg: str) -> None: - print_with_style(*msg, style=default_styles["deleting"]) - - -def print_with_creating_style(*msg: str) -> None: - print_with_style(*msg, style=default_styles["creating"]) - - -def print_with_failure_style(*msg: str) -> None: - print_with_style(*msg, style=random.choice(failure_stories)) - - -def print_with_success_style(*msg: str): - # print_with_style(*msg, style=default_styles["success"]) - print_with_style(*msg, style=random.choice(success_stories)) - - -def print_with_info_style(*msg: str): - # print_with_style(*msg, style=default_styles["info"]) - print_with_style(*msg, style=random.choice(info_stories)) - -def print_excel_created_style(*msg: str): - print_with_style(*msg, style=default_styles["success"]) - - -def print_get_input_style(*msg: str): - print_with_style(*msg, style=default_styles["input"]) - - -def print_menu_item_style(*msg: str): - print_with_style(*msg, style=default_styles["menu_item"]) - - -rf""" -???????????????????????????????????????????????????????????????????????????? -? ? 0 ? "black" ? ? ? -? ? 1 ? "red" ? ? ? -? ? 2 ? "green" ? ? ? -? ? 3 ? "yellow" ? ? ? -? ? 4 ? "blue" ? ? ? -? ? 5 ? "magenta" ? ? ? -? ? 6 ? "cyan" ? ? ? -? ? 7 ? "white" ? ? ? -? ? 8 ? "bright_black" ? ? ? -? ? 9 ? "bright_red" ? ? ? -? ? 10 ? "bright_green" ? ? ? -? ? 11 ? "bright_yellow" ? ? ? -? ? 12 ? "bright_blue" ? ? ? -? ? 13 ? "bright_magenta" ? ? ? -? ? 14 ? "bright_cyan" ? ? ? -? ? 15 ? "bright_white" ? ? ? -? ? 16 ? "grey0" ? #000000 ? rgb(0,0,0) ? -? ? 17 ? "navy_blue" ? #00005f ? rgb(0,0,95) ? -? ? 18 ? "dark_blue" ? #000087 ? rgb(0,0,135) ? -? ? 20 ? "blue3" ? #0000d7 ? rgb(0,0,215) ? -? ? 21 ? "blue1" ? #0000ff ? rgb(0,0,255) ? -? ? 22 ? "dark_green" ? #005f00 ? rgb(0,95,0) ? -? ? 25 ? "deep_sky_blue4" ? #005faf ? rgb(0,95,175) ? -? ? 26 ? "dodger_blue3" ? #005fd7 ? rgb(0,95,215) ? -? ? 27 ? "dodger_blue2" ? #005fff ? rgb(0,95,255) ? -? ? 28 ? "green4" ? #008700 ? rgb(0,135,0) ? -? ? 29 ? "spring_green4" ? #00875f ? rgb(0,135,95) ? -? ? 30 ? "turquoise4" ? #008787 ? rgb(0,135,135) ? -? ? 32 ? "deep_sky_blue3" ? #0087d7 ? rgb(0,135,215) ? -? ? 33 ? "dodger_blue1" ? #0087ff ? rgb(0,135,255) ? -? ? 36 ? "dark_cyan" ? #00af87 ? rgb(0,175,135) ? -? ? 37 ? "light_sea_green" ? #00afaf ? rgb(0,175,175) ? -? ? 38 ? "deep_sky_blue2" ? #00afd7 ? rgb(0,175,215) ? -? ? 39 ? "deep_sky_blue1" ? #00afff ? rgb(0,175,255) ? -? ? 40 ? "green3" ? #00d700 ? rgb(0,215,0) ? -? ? 41 ? "spring_green3" ? #00d75f ? rgb(0,215,95) ? -? ? 43 ? "cyan3" ? #00d7af ? rgb(0,215,175) ? -? ? 44 ? "dark_turquoise" ? #00d7d7 ? rgb(0,215,215) ? -? ? 45 ? "turquoise2" ? #00d7ff ? rgb(0,215,255) ? -? ? 46 ? "green1" ? #00ff00 ? rgb(0,255,0) ? -? ? 47 ? "spring_green2" ? #00ff5f ? rgb(0,255,95) ? -? ? 48 ? "spring_green1" ? #00ff87 ? rgb(0,255,135) ? -? ? 49 ? "medium_spring_green" ? #00ffaf ? rgb(0,255,175) ? -? ? 50 ? "cyan2" ? #00ffd7 ? rgb(0,255,215) ? -? ? 51 ? "cyan1" ? #00ffff ? rgb(0,255,255) ? -? ? 55 ? "purple4" ? #5f00af ? rgb(95,0,175) ? -? ? 56 ? "purple3" ? #5f00d7 ? rgb(95,0,215) ? -? ? 57 ? "blue_violet" ? #5f00ff ? rgb(95,0,255) ? -? ? 59 ? "grey37" ? #5f5f5f ? rgb(95,95,95) ? -? ? 60 ? "medium_purple4" ? #5f5f87 ? rgb(95,95,135) ? -? ? 62 ? "slate_blue3" ? #5f5fd7 ? rgb(95,95,215) ? -? ? 63 ? "royal_blue1" ? #5f5fff ? rgb(95,95,255) ? -? ? 64 ? "chartreuse4" ? #5f8700 ? rgb(95,135,0) ? -? ? 66 ? "pale_turquoise4" ? #5f8787 ? rgb(95,135,135) ? -? ? 67 ? "steel_blue" ? #5f87af ? rgb(95,135,175) ? -? ? 68 ? "steel_blue3" ? #5f87d7 ? rgb(95,135,215) ? -? ? 69 ? "cornflower_blue" ? #5f87ff ? rgb(95,135,255) ? -? ? 71 ? "dark_sea_green4" ? #5faf5f ? rgb(95,175,95) ? -? ? 73 ? "cadet_blue" ? #5fafaf ? rgb(95,175,175) ? -? ? 74 ? "sky_blue3" ? #5fafd7 ? rgb(95,175,215) ? -? ? 76 ? "chartreuse3" ? #5fd700 ? rgb(95,215,0) ? -? ? 78 ? "sea_green3" ? #5fd787 ? rgb(95,215,135) ? -? ? 79 ? "aquamarine3" ? #5fd7af ? rgb(95,215,175) ? -? ? 80 ? "medium_turquoise" ? #5fd7d7 ? rgb(95,215,215) ? -? ? 81 ? "steel_blue1" ? #5fd7ff ? rgb(95,215,255) ? -? ? 83 ? "sea_green2" ? #5fff5f ? rgb(95,255,95) ? -? ? 85 ? "sea_green1" ? #5fffaf ? rgb(95,255,175) ? -? ? 87 ? "dark_slate_gray2" ? #5fffff ? rgb(95,255,255) ? -? ? 88 ? "dark_red" ? #870000 ? rgb(135,0,0) ? -? ? 91 ? "dark_magenta" ? #8700af ? rgb(135,0,175) ? -? ? 94 ? "orange4" ? #875f00 ? rgb(135,95,0) ? -? ? 95 ? "light_pink4" ? #875f5f ? rgb(135,95,95) ? -? ? 96 ? "plum4" ? #875f87 ? rgb(135,95,135) ? -? ? 98 ? "medium_purple3" ? #875fd7 ? rgb(135,95,215) ? -? ? 99 ? "slate_blue1" ? #875fff ? rgb(135,95,255) ? -? ? 101 ? "wheat4" ? #87875f ? rgb(135,135,95) ? -? ? 102 ? "grey53" ? #878787 ? rgb(135,135,135) ? -? ? 103 ? "light_slate_grey" ? #8787af ? rgb(135,135,175) ? -? ? 104 ? "medium_purple" ? #8787d7 ? rgb(135,135,215) ? -? ? 105 ? "light_slate_blue" ? #8787ff ? rgb(135,135,255) ? -? ? 106 ? "yellow4" ? #87af00 ? rgb(135,175,0) ? -? ? 108 ? "dark_sea_green" ? #87af87 ? rgb(135,175,135) ? -? ? 110 ? "light_sky_blue3" ? #87afd7 ? rgb(135,175,215) ? -? ? 111 ? "sky_blue2" ? #87afff ? rgb(135,175,255) ? -? ? 112 ? "chartreuse2" ? #87d700 ? rgb(135,215,0) ? -? ? 114 ? "pale_green3" ? #87d787 ? rgb(135,215,135) ? -? ? 116 ? "dark_slate_gray3" ? #87d7d7 ? rgb(135,215,215) ? -? ? 117 ? "sky_blue1" ? #87d7ff ? rgb(135,215,255) ? -? ? 118 ? "chartreuse1" ? #87ff00 ? rgb(135,255,0) ? -? ? 120 ? "light_green" ? #87ff87 ? rgb(135,255,135) ? -? ? 122 ? "aquamarine1" ? #87ffd7 ? rgb(135,255,215) ? -? ? 123 ? "dark_slate_gray1" ? #87ffff ? rgb(135,255,255) ? -? ? 125 ? "deep_pink4" ? #af005f ? rgb(175,0,95) ? -? ? 126 ? "medium_violet_red" ? #af0087 ? rgb(175,0,135) ? -? ? 128 ? "dark_violet" ? #af00d7 ? rgb(175,0,215) ? -? ? 129 ? "purple" ? #af00ff ? rgb(175,0,255) ? -? ? 133 ? "medium_orchid3" ? #af5faf ? rgb(175,95,175) ? -? ? 134 ? "medium_orchid" ? #af5fd7 ? rgb(175,95,215) ? -? ? 136 ? "dark_goldenrod" ? #af8700 ? rgb(175,135,0) ? -? ? 138 ? "rosy_brown" ? #af8787 ? rgb(175,135,135) ? -? ? 139 ? "grey63" ? #af87af ? rgb(175,135,175) ? -? ? 140 ? "medium_purple2" ? #af87d7 ? rgb(175,135,215) ? -? ? 141 ? "medium_purple1" ? #af87ff ? rgb(175,135,255) ? -? ? 143 ? "dark_khaki" ? #afaf5f ? rgb(175,175,95) ? -? ? 144 ? "navajo_white3" ? #afaf87 ? rgb(175,175,135) ? -? ? 145 ? "grey69" ? #afafaf ? rgb(175,175,175) ? -? ? 146 ? "light_steel_blue3" ? #afafd7 ? rgb(175,175,215) ? -? ? 147 ? "light_steel_blue" ? #afafff ? rgb(175,175,255) ? -? ? 149 ? "dark_olive_green3" ? #afd75f ? rgb(175,215,95) ? -? ? 150 ? "dark_sea_green3" ? #afd787 ? rgb(175,215,135) ? -? ? 152 ? "light_cyan3" ? #afd7d7 ? rgb(175,215,215) ? -? ? 153 ? "light_sky_blue1" ? #afd7ff ? rgb(175,215,255) ? -? ? 154 ? "green_yellow" ? #afff00 ? rgb(175,255,0) ? -? ? 155 ? "dark_olive_green2" ? #afff5f ? rgb(175,255,95) ? -? ? 156 ? "pale_green1" ? #afff87 ? rgb(175,255,135) ? -? ? 157 ? "dark_sea_green2" ? #afffaf ? rgb(175,255,175) ? -? ? 159 ? "pale_turquoise1" ? #afffff ? rgb(175,255,255) ? -? ? 160 ? "red3" ? #d70000 ? rgb(215,0,0) ? -? ? 162 ? "deep_pink3" ? #d70087 ? rgb(215,0,135) ? -? ? 164 ? "magenta3" ? #d700d7 ? rgb(215,0,215) ? -? ? 166 ? "dark_orange3" ? #d75f00 ? rgb(215,95,0) ? -? ? 167 ? "indian_red" ? #d75f5f ? rgb(215,95,95) ? -? ? 168 ? "hot_pink3" ? #d75f87 ? rgb(215,95,135) ? -? ? 169 ? "hot_pink2" ? #d75faf ? rgb(215,95,175) ? -? ? 170 ? "orchid" ? #d75fd7 ? rgb(215,95,215) ? -? ? 172 ? "orange3" ? #d78700 ? rgb(215,135,0) ? -? ? 173 ? "light_salmon3" ? #d7875f ? rgb(215,135,95) ? -? ? 174 ? "light_pink3" ? #d78787 ? rgb(215,135,135) ? -? ? 175 ? "pink3" ? #d787af ? rgb(215,135,175) ? -? ? 176 ? "plum3" ? #d787d7 ? rgb(215,135,215) ? -? ? 177 ? "violet" ? #d787ff ? rgb(215,135,255) ? -? ? 178 ? "gold3" ? #d7af00 ? rgb(215,175,0) ? -? ? 179 ? "light_goldenrod3" ? #d7af5f ? rgb(215,175,95) ? -? ? 180 ? "tan" ? #d7af87 ? rgb(215,175,135) ? -? ? 181 ? "misty_rose3" ? #d7afaf ? rgb(215,175,175) ? -? ? 182 ? "thistle3" ? #d7afd7 ? rgb(215,175,215) ? -? ? 183 ? "plum2" ? #d7afff ? rgb(215,175,255) ? -? ? 184 ? "yellow3" ? #d7d700 ? rgb(215,215,0) ? -? ? 185 ? "khaki3" ? #d7d75f ? rgb(215,215,95) ? -? ? 187 ? "light_yellow3" ? #d7d7af ? rgb(215,215,175) ? -? ? 188 ? "grey84" ? #d7d7d7 ? rgb(215,215,215) ? -? ? 189 ? "light_steel_blue1" ? #d7d7ff ? rgb(215,215,255) ? -? ? 190 ? "yellow2" ? #d7ff00 ? rgb(215,255,0) ? -? ? 192 ? "dark_olive_green1" ? #d7ff87 ? rgb(215,255,135) ? -? ? 193 ? "dark_sea_green1" ? #d7ffaf ? rgb(215,255,175) ? -? ? 194 ? "honeydew2" ? #d7ffd7 ? rgb(215,255,215) ? -? ? 195 ? "light_cyan1" ? #d7ffff ? rgb(215,255,255) ? -? ? 196 ? "red1" ? #ff0000 ? rgb(255,0,0) ? -? ? 197 ? "deep_pink2" ? #ff005f ? rgb(255,0,95) ? -? ? 199 ? "deep_pink1" ? #ff00af ? rgb(255,0,175) ? -? ? 200 ? "magenta2" ? #ff00d7 ? rgb(255,0,215) ? -? ? 201 ? "magenta1" ? #ff00ff ? rgb(255,0,255) ? -? ? 202 ? "orange_red1" ? #ff5f00 ? rgb(255,95,0) ? -? ? 204 ? "indian_red1" ? #ff5f87 ? rgb(255,95,135) ? -? ? 206 ? "hot_pink" ? #ff5fd7 ? rgb(255,95,215) ? -? ? 207 ? "medium_orchid1" ? #ff5fff ? rgb(255,95,255) ? -? ? 208 ? "dark_orange" ? #ff8700 ? rgb(255,135,0) ? -? ? 209 ? "salmon1" ? #ff875f ? rgb(255,135,95) ? -? ? 210 ? "light_coral" ? #ff8787 ? rgb(255,135,135) ? -? ? 211 ? "pale_violet_red1" ? #ff87af ? rgb(255,135,175) ? -? ? 212 ? "orchid2" ? #ff87d7 ? rgb(255,135,215) ? -? ? 213 ? "orchid1" ? #ff87ff ? rgb(255,135,255) ? -? ? 214 ? "orange1" ? #ffaf00 ? rgb(255,175,0) ? -? ? 215 ? "sandy_brown" ? #ffaf5f ? rgb(255,175,95) ? -? ? 216 ? "light_salmon1" ? #ffaf87 ? rgb(255,175,135) ? -? ? 217 ? "light_pink1" ? #ffafaf ? rgb(255,175,175) ? -? ? 218 ? "pink1" ? #ffafd7 ? rgb(255,175,215) ? -? ? 219 ? "plum1" ? #ffafff ? rgb(255,175,255) ? -? ? 220 ? "gold1" ? #ffd700 ? rgb(255,215,0) ? -? ? 222 ? "light_goldenrod2" ? #ffd787 ? rgb(255,215,135) ? -? ? 223 ? "navajo_white1" ? #ffd7af ? rgb(255,215,175) ? -? ? 224 ? "misty_rose1" ? #ffd7d7 ? rgb(255,215,215) ? -? ? 225 ? "thistle1" ? #ffd7ff ? rgb(255,215,255) ? -? ? 226 ? "yellow1" ? #ffff00 ? rgb(255,255,0) ? -? ? 227 ? "light_goldenrod1" ? #ffff5f ? rgb(255,255,95) ? -? ? 228 ? "khaki1" ? #ffff87 ? rgb(255,255,135) ? -? ? 229 ? "wheat1" ? #ffffaf ? rgb(255,255,175) ? -? ? 230 ? "cornsilk1" ? #ffffd7 ? rgb(255,255,215) ? -? ? 231 ? "grey100" ? #ffffff ? rgb(255,255,255) ? -? ? 232 ? "grey3" ? #080808 ? rgb(8,8,8) ? -? ? 233 ? "grey7" ? #121212 ? rgb(18,18,18) ? -? ? 234 ? "grey11" ? #1c1c1c ? rgb(28,28,28) ? -? ? 235 ? "grey15" ? #262626 ? rgb(38,38,38) ? -? ? 236 ? "grey19" ? #303030 ? rgb(48,48,48) ? -? ? 237 ? "grey23" ? #3a3a3a ? rgb(58,58,58) ? -? ? 238 ? "grey27" ? #444444 ? rgb(68,68,68) ? -? ? 239 ? "grey30" ? #4e4e4e ? rgb(78,78,78) ? -? ? 240 ? "grey35" ? #585858 ? rgb(88,88,88) ? -? ? 241 ? "grey39" ? #626262 ? rgb(98,98,98) ? -? ? 242 ? "grey42" ? #6c6c6c ? rgb(108,108,108) ? -? ? 243 ? "grey46" ? #767676 ? rgb(118,118,118) ? -? ? 244 ? "grey50" ? #808080 ? rgb(128,128,128) ? -? ? 245 ? "grey54" ? #8a8a8a ? rgb(138,138,138) ? -? ? 246 ? "grey58" ? #949494 ? rgb(148,148,148) ? -? ? 247 ? "grey62" ? #9e9e9e ? rgb(158,158,158) ? -? ? 248 ? "grey66" ? #a8a8a8 ? rgb(168,168,168) ? -? ? 249 ? "grey70" ? #b2b2b2 ? rgb(178,178,178) ? -? ? 250 ? "grey74" ? #bcbcbc ? rgb(188,188,188) ? -? ? 251 ? "grey78" ? #c6c6c6 ? rgb(198,198,198) ? -? ? 252 ? "grey82" ? #d0d0d0 ? rgb(208,208,208) ? -? ? 253 ? "grey85" ? #dadada ? rgb(218,218,218) ? -? ? 254 ? "grey89" ? #e4e4e4 ? rgb(228,228,228) ? -? ? 255 ? "grey93" ? #eeeeee ? rgb(238,238,238) ? -???????????????????????????????????????????????????????????????????????????? - -""" +import functools +import random + +from rich.console import Console +from rich.theme import Theme +from rich.style import Style + +custom_theme = Theme({ + "info": "dim cyan", + "warning": "magenta", + "danger": "bold red" +}) +console = Console(theme=custom_theme) +# console.print("This is information", style="info") +# console.print("[warning]The pod bay doors are locked[/warning]") +# console.print("Something terrible happened!", style="danger") +colors_style = { + "red": "danger", + "yellow": "warning", + "blue": "info", + +} + +""" + 44 ? "dark_turquoise" ? #00d7d7 ? rgb(0,215,215) ? +? ? 45 ? "turquoise2" ? #00d7ff ? rgb(0,215,255) ? +? ? 46 ? "green1" ? #00ff00 ? rgb(0,255,0) ? +? ? 47 ? "spring_green2" ? #00ff5f ? rgb(0,255,95) ? +? ? 48 ? "spring_green1" ? #00ff87 ? rgb(0,255,135) ? +? ? 49 ? "medium_spring_green" ? #00ffaf ? rgb(0,255,175) ? +""" + +default_styles = { + "default": Style(color="magenta", bgcolor="yellow", italic=True), + "requesting": Style(color="black", bgcolor="magenta", italic=True), + "creating": Style(color="magenta", bgcolor="black", italic=True), + "updating": Style(color="blue", bgcolor="black", italic=True), + "deleting": Style(color="white", bgcolor="red", italic=True), + + "failure2": Style(color="red", bgcolor="black", italic=True), + "failure3": Style(color="magenta", bgcolor="black", italic=True), + "failure4": Style(color="deep_pink1", bgcolor="black", italic=True), + "failure5": Style(color="cyan", bgcolor="black", italic=True), + + "success": Style(color="white", bgcolor="black", italic=True), + "success2": Style(color="medium_turquoise", bgcolor="black", italic=True), + "success3": Style(color="spring_green2", bgcolor="black", italic=True), + "success4": Style(color="spring_green1", bgcolor="black", italic=True), + "success5": Style(color="medium_spring_green", bgcolor="black", italic=True), + "success6": Style(color="turquoise2", bgcolor="black", italic=True), + "success7": Style(color="blue_violet", bgcolor="black", italic=True), + # "info": Style(color="blue", bgcolor="black", italic=True), + "info2": Style(color="deep_sky_blue2", bgcolor="black", italic=True), + "info3": Style(color="turquoise2", bgcolor="black", italic=True), + "info4": Style(color="medium_turquoise", bgcolor="black", italic=True), + "input": Style(color="deep_pink1", bgcolor="black", italic=True), + "menu_item": Style(color="turquoise2", bgcolor="black", italic=True), + +} + +# success_stories = (default_styles["success"], default_styles["success2"], default_styles["creating"]) +# +from typing import Tuple, Any + +from typing import Any + + +def make_flat(x: tuple, y: tuple) -> tuple: + return tuple([x1 for x1 in x] + [y1 for y1 in y]) + + +def combine_similar_ones(*item_list: any) -> tuple: + if len(item_list) > 1 and isinstance(item_list[0], (tuple, list,)): + combined_list = [x for x in item_list] + combined_list = functools.reduce(lambda x, p: make_flat(x, p), combined_list, []) + else: + combined_list = list(item_list[0]) + list_ = [] + + for item in combined_list: + list_.append(default_styles[item]) + return tuple(list_) + + +def get_list_of_keys(key_word: str = "success"): + return tuple([x for x in default_styles.keys() if key_word in x]) + + +success_stories = combine_similar_ones(get_list_of_keys("success"), get_list_of_keys("info")) +failure_stories = combine_similar_ones(get_list_of_keys("fail")) +info_stories = combine_similar_ones(get_list_of_keys("info")) + +def get_style(name: str = "default") -> None: + return default_styles[name] + + +def print_with_color(msg: str, color: str) -> None: + if isinstance(color, str): + color = colors_style[color] + + console.print(msg, style=color) + + +def print_with_style(*msg, style: Style = get_style()) -> None: + console.print(*msg, style=style) + + +def print_with_updating_style(*msg: str) -> None: + print_with_style(*msg, style=default_styles["updating"]) + + +def print_with_deleting_style(*msg: str) -> None: + print_with_style(*msg, style=default_styles["deleting"]) + + +def print_with_creating_style(*msg: str) -> None: + print_with_style(*msg, style=default_styles["creating"]) + + +def print_with_failure_style(*msg: str) -> None: + print_with_style(*msg, style=random.choice(failure_stories)) + + +def print_with_success_style(*msg: str): + # print_with_style(*msg, style=default_styles["success"]) + print_with_style(*msg, style=random.choice(success_stories)) + + +def print_with_info_style(*msg: str): + # print_with_style(*msg, style=default_styles["info"]) + print_with_style(*msg, style=random.choice(info_stories)) + +def print_excel_created_style(*msg: str): + print_with_style(*msg, style=default_styles["success"]) + + +def print_get_input_style(*msg: str): + print_with_style(*msg, style=default_styles["input"]) + + +def print_menu_item_style(*msg: str): + print_with_style(*msg, style=default_styles["menu_item"]) + + +rf""" +???????????????????????????????????????????????????????????????????????????? +? ? 0 ? "black" ? ? ? +? ? 1 ? "red" ? ? ? +? ? 2 ? "green" ? ? ? +? ? 3 ? "yellow" ? ? ? +? ? 4 ? "blue" ? ? ? +? ? 5 ? "magenta" ? ? ? +? ? 6 ? "cyan" ? ? ? +? ? 7 ? "white" ? ? ? +? ? 8 ? "bright_black" ? ? ? +? ? 9 ? "bright_red" ? ? ? +? ? 10 ? "bright_green" ? ? ? +? ? 11 ? "bright_yellow" ? ? ? +? ? 12 ? "bright_blue" ? ? ? +? ? 13 ? "bright_magenta" ? ? ? +? ? 14 ? "bright_cyan" ? ? ? +? ? 15 ? "bright_white" ? ? ? +? ? 16 ? "grey0" ? #000000 ? rgb(0,0,0) ? +? ? 17 ? "navy_blue" ? #00005f ? rgb(0,0,95) ? +? ? 18 ? "dark_blue" ? #000087 ? rgb(0,0,135) ? +? ? 20 ? "blue3" ? #0000d7 ? rgb(0,0,215) ? +? ? 21 ? "blue1" ? #0000ff ? rgb(0,0,255) ? +? ? 22 ? "dark_green" ? #005f00 ? rgb(0,95,0) ? +? ? 25 ? "deep_sky_blue4" ? #005faf ? rgb(0,95,175) ? +? ? 26 ? "dodger_blue3" ? #005fd7 ? rgb(0,95,215) ? +? ? 27 ? "dodger_blue2" ? #005fff ? rgb(0,95,255) ? +? ? 28 ? "green4" ? #008700 ? rgb(0,135,0) ? +? ? 29 ? "spring_green4" ? #00875f ? rgb(0,135,95) ? +? ? 30 ? "turquoise4" ? #008787 ? rgb(0,135,135) ? +? ? 32 ? "deep_sky_blue3" ? #0087d7 ? rgb(0,135,215) ? +? ? 33 ? "dodger_blue1" ? #0087ff ? rgb(0,135,255) ? +? ? 36 ? "dark_cyan" ? #00af87 ? rgb(0,175,135) ? +? ? 37 ? "light_sea_green" ? #00afaf ? rgb(0,175,175) ? +? ? 38 ? "deep_sky_blue2" ? #00afd7 ? rgb(0,175,215) ? +? ? 39 ? "deep_sky_blue1" ? #00afff ? rgb(0,175,255) ? +? ? 40 ? "green3" ? #00d700 ? rgb(0,215,0) ? +? ? 41 ? "spring_green3" ? #00d75f ? rgb(0,215,95) ? +? ? 43 ? "cyan3" ? #00d7af ? rgb(0,215,175) ? +? ? 44 ? "dark_turquoise" ? #00d7d7 ? rgb(0,215,215) ? +? ? 45 ? "turquoise2" ? #00d7ff ? rgb(0,215,255) ? +? ? 46 ? "green1" ? #00ff00 ? rgb(0,255,0) ? +? ? 47 ? "spring_green2" ? #00ff5f ? rgb(0,255,95) ? +? ? 48 ? "spring_green1" ? #00ff87 ? rgb(0,255,135) ? +? ? 49 ? "medium_spring_green" ? #00ffaf ? rgb(0,255,175) ? +? ? 50 ? "cyan2" ? #00ffd7 ? rgb(0,255,215) ? +? ? 51 ? "cyan1" ? #00ffff ? rgb(0,255,255) ? +? ? 55 ? "purple4" ? #5f00af ? rgb(95,0,175) ? +? ? 56 ? "purple3" ? #5f00d7 ? rgb(95,0,215) ? +? ? 57 ? "blue_violet" ? #5f00ff ? rgb(95,0,255) ? +? ? 59 ? "grey37" ? #5f5f5f ? rgb(95,95,95) ? +? ? 60 ? "medium_purple4" ? #5f5f87 ? rgb(95,95,135) ? +? ? 62 ? "slate_blue3" ? #5f5fd7 ? rgb(95,95,215) ? +? ? 63 ? "royal_blue1" ? #5f5fff ? rgb(95,95,255) ? +? ? 64 ? "chartreuse4" ? #5f8700 ? rgb(95,135,0) ? +? ? 66 ? "pale_turquoise4" ? #5f8787 ? rgb(95,135,135) ? +? ? 67 ? "steel_blue" ? #5f87af ? rgb(95,135,175) ? +? ? 68 ? "steel_blue3" ? #5f87d7 ? rgb(95,135,215) ? +? ? 69 ? "cornflower_blue" ? #5f87ff ? rgb(95,135,255) ? +? ? 71 ? "dark_sea_green4" ? #5faf5f ? rgb(95,175,95) ? +? ? 73 ? "cadet_blue" ? #5fafaf ? rgb(95,175,175) ? +? ? 74 ? "sky_blue3" ? #5fafd7 ? rgb(95,175,215) ? +? ? 76 ? "chartreuse3" ? #5fd700 ? rgb(95,215,0) ? +? ? 78 ? "sea_green3" ? #5fd787 ? rgb(95,215,135) ? +? ? 79 ? "aquamarine3" ? #5fd7af ? rgb(95,215,175) ? +? ? 80 ? "medium_turquoise" ? #5fd7d7 ? rgb(95,215,215) ? +? ? 81 ? "steel_blue1" ? #5fd7ff ? rgb(95,215,255) ? +? ? 83 ? "sea_green2" ? #5fff5f ? rgb(95,255,95) ? +? ? 85 ? "sea_green1" ? #5fffaf ? rgb(95,255,175) ? +? ? 87 ? "dark_slate_gray2" ? #5fffff ? rgb(95,255,255) ? +? ? 88 ? "dark_red" ? #870000 ? rgb(135,0,0) ? +? ? 91 ? "dark_magenta" ? #8700af ? rgb(135,0,175) ? +? ? 94 ? "orange4" ? #875f00 ? rgb(135,95,0) ? +? ? 95 ? "light_pink4" ? #875f5f ? rgb(135,95,95) ? +? ? 96 ? "plum4" ? #875f87 ? rgb(135,95,135) ? +? ? 98 ? "medium_purple3" ? #875fd7 ? rgb(135,95,215) ? +? ? 99 ? "slate_blue1" ? #875fff ? rgb(135,95,255) ? +? ? 101 ? "wheat4" ? #87875f ? rgb(135,135,95) ? +? ? 102 ? "grey53" ? #878787 ? rgb(135,135,135) ? +? ? 103 ? "light_slate_grey" ? #8787af ? rgb(135,135,175) ? +? ? 104 ? "medium_purple" ? #8787d7 ? rgb(135,135,215) ? +? ? 105 ? "light_slate_blue" ? #8787ff ? rgb(135,135,255) ? +? ? 106 ? "yellow4" ? #87af00 ? rgb(135,175,0) ? +? ? 108 ? "dark_sea_green" ? #87af87 ? rgb(135,175,135) ? +? ? 110 ? "light_sky_blue3" ? #87afd7 ? rgb(135,175,215) ? +? ? 111 ? "sky_blue2" ? #87afff ? rgb(135,175,255) ? +? ? 112 ? "chartreuse2" ? #87d700 ? rgb(135,215,0) ? +? ? 114 ? "pale_green3" ? #87d787 ? rgb(135,215,135) ? +? ? 116 ? "dark_slate_gray3" ? #87d7d7 ? rgb(135,215,215) ? +? ? 117 ? "sky_blue1" ? #87d7ff ? rgb(135,215,255) ? +? ? 118 ? "chartreuse1" ? #87ff00 ? rgb(135,255,0) ? +? ? 120 ? "light_green" ? #87ff87 ? rgb(135,255,135) ? +? ? 122 ? "aquamarine1" ? #87ffd7 ? rgb(135,255,215) ? +? ? 123 ? "dark_slate_gray1" ? #87ffff ? rgb(135,255,255) ? +? ? 125 ? "deep_pink4" ? #af005f ? rgb(175,0,95) ? +? ? 126 ? "medium_violet_red" ? #af0087 ? rgb(175,0,135) ? +? ? 128 ? "dark_violet" ? #af00d7 ? rgb(175,0,215) ? +? ? 129 ? "purple" ? #af00ff ? rgb(175,0,255) ? +? ? 133 ? "medium_orchid3" ? #af5faf ? rgb(175,95,175) ? +? ? 134 ? "medium_orchid" ? #af5fd7 ? rgb(175,95,215) ? +? ? 136 ? "dark_goldenrod" ? #af8700 ? rgb(175,135,0) ? +? ? 138 ? "rosy_brown" ? #af8787 ? rgb(175,135,135) ? +? ? 139 ? "grey63" ? #af87af ? rgb(175,135,175) ? +? ? 140 ? "medium_purple2" ? #af87d7 ? rgb(175,135,215) ? +? ? 141 ? "medium_purple1" ? #af87ff ? rgb(175,135,255) ? +? ? 143 ? "dark_khaki" ? #afaf5f ? rgb(175,175,95) ? +? ? 144 ? "navajo_white3" ? #afaf87 ? rgb(175,175,135) ? +? ? 145 ? "grey69" ? #afafaf ? rgb(175,175,175) ? +? ? 146 ? "light_steel_blue3" ? #afafd7 ? rgb(175,175,215) ? +? ? 147 ? "light_steel_blue" ? #afafff ? rgb(175,175,255) ? +? ? 149 ? "dark_olive_green3" ? #afd75f ? rgb(175,215,95) ? +? ? 150 ? "dark_sea_green3" ? #afd787 ? rgb(175,215,135) ? +? ? 152 ? "light_cyan3" ? #afd7d7 ? rgb(175,215,215) ? +? ? 153 ? "light_sky_blue1" ? #afd7ff ? rgb(175,215,255) ? +? ? 154 ? "green_yellow" ? #afff00 ? rgb(175,255,0) ? +? ? 155 ? "dark_olive_green2" ? #afff5f ? rgb(175,255,95) ? +? ? 156 ? "pale_green1" ? #afff87 ? rgb(175,255,135) ? +? ? 157 ? "dark_sea_green2" ? #afffaf ? rgb(175,255,175) ? +? ? 159 ? "pale_turquoise1" ? #afffff ? rgb(175,255,255) ? +? ? 160 ? "red3" ? #d70000 ? rgb(215,0,0) ? +? ? 162 ? "deep_pink3" ? #d70087 ? rgb(215,0,135) ? +? ? 164 ? "magenta3" ? #d700d7 ? rgb(215,0,215) ? +? ? 166 ? "dark_orange3" ? #d75f00 ? rgb(215,95,0) ? +? ? 167 ? "indian_red" ? #d75f5f ? rgb(215,95,95) ? +? ? 168 ? "hot_pink3" ? #d75f87 ? rgb(215,95,135) ? +? ? 169 ? "hot_pink2" ? #d75faf ? rgb(215,95,175) ? +? ? 170 ? "orchid" ? #d75fd7 ? rgb(215,95,215) ? +? ? 172 ? "orange3" ? #d78700 ? rgb(215,135,0) ? +? ? 173 ? "light_salmon3" ? #d7875f ? rgb(215,135,95) ? +? ? 174 ? "light_pink3" ? #d78787 ? rgb(215,135,135) ? +? ? 175 ? "pink3" ? #d787af ? rgb(215,135,175) ? +? ? 176 ? "plum3" ? #d787d7 ? rgb(215,135,215) ? +? ? 177 ? "violet" ? #d787ff ? rgb(215,135,255) ? +? ? 178 ? "gold3" ? #d7af00 ? rgb(215,175,0) ? +? ? 179 ? "light_goldenrod3" ? #d7af5f ? rgb(215,175,95) ? +? ? 180 ? "tan" ? #d7af87 ? rgb(215,175,135) ? +? ? 181 ? "misty_rose3" ? #d7afaf ? rgb(215,175,175) ? +? ? 182 ? "thistle3" ? #d7afd7 ? rgb(215,175,215) ? +? ? 183 ? "plum2" ? #d7afff ? rgb(215,175,255) ? +? ? 184 ? "yellow3" ? #d7d700 ? rgb(215,215,0) ? +? ? 185 ? "khaki3" ? #d7d75f ? rgb(215,215,95) ? +? ? 187 ? "light_yellow3" ? #d7d7af ? rgb(215,215,175) ? +? ? 188 ? "grey84" ? #d7d7d7 ? rgb(215,215,215) ? +? ? 189 ? "light_steel_blue1" ? #d7d7ff ? rgb(215,215,255) ? +? ? 190 ? "yellow2" ? #d7ff00 ? rgb(215,255,0) ? +? ? 192 ? "dark_olive_green1" ? #d7ff87 ? rgb(215,255,135) ? +? ? 193 ? "dark_sea_green1" ? #d7ffaf ? rgb(215,255,175) ? +? ? 194 ? "honeydew2" ? #d7ffd7 ? rgb(215,255,215) ? +? ? 195 ? "light_cyan1" ? #d7ffff ? rgb(215,255,255) ? +? ? 196 ? "red1" ? #ff0000 ? rgb(255,0,0) ? +? ? 197 ? "deep_pink2" ? #ff005f ? rgb(255,0,95) ? +? ? 199 ? "deep_pink1" ? #ff00af ? rgb(255,0,175) ? +? ? 200 ? "magenta2" ? #ff00d7 ? rgb(255,0,215) ? +? ? 201 ? "magenta1" ? #ff00ff ? rgb(255,0,255) ? +? ? 202 ? "orange_red1" ? #ff5f00 ? rgb(255,95,0) ? +? ? 204 ? "indian_red1" ? #ff5f87 ? rgb(255,95,135) ? +? ? 206 ? "hot_pink" ? #ff5fd7 ? rgb(255,95,215) ? +? ? 207 ? "medium_orchid1" ? #ff5fff ? rgb(255,95,255) ? +? ? 208 ? "dark_orange" ? #ff8700 ? rgb(255,135,0) ? +? ? 209 ? "salmon1" ? #ff875f ? rgb(255,135,95) ? +? ? 210 ? "light_coral" ? #ff8787 ? rgb(255,135,135) ? +? ? 211 ? "pale_violet_red1" ? #ff87af ? rgb(255,135,175) ? +? ? 212 ? "orchid2" ? #ff87d7 ? rgb(255,135,215) ? +? ? 213 ? "orchid1" ? #ff87ff ? rgb(255,135,255) ? +? ? 214 ? "orange1" ? #ffaf00 ? rgb(255,175,0) ? +? ? 215 ? "sandy_brown" ? #ffaf5f ? rgb(255,175,95) ? +? ? 216 ? "light_salmon1" ? #ffaf87 ? rgb(255,175,135) ? +? ? 217 ? "light_pink1" ? #ffafaf ? rgb(255,175,175) ? +? ? 218 ? "pink1" ? #ffafd7 ? rgb(255,175,215) ? +? ? 219 ? "plum1" ? #ffafff ? rgb(255,175,255) ? +? ? 220 ? "gold1" ? #ffd700 ? rgb(255,215,0) ? +? ? 222 ? "light_goldenrod2" ? #ffd787 ? rgb(255,215,135) ? +? ? 223 ? "navajo_white1" ? #ffd7af ? rgb(255,215,175) ? +? ? 224 ? "misty_rose1" ? #ffd7d7 ? rgb(255,215,215) ? +? ? 225 ? "thistle1" ? #ffd7ff ? rgb(255,215,255) ? +? ? 226 ? "yellow1" ? #ffff00 ? rgb(255,255,0) ? +? ? 227 ? "light_goldenrod1" ? #ffff5f ? rgb(255,255,95) ? +? ? 228 ? "khaki1" ? #ffff87 ? rgb(255,255,135) ? +? ? 229 ? "wheat1" ? #ffffaf ? rgb(255,255,175) ? +? ? 230 ? "cornsilk1" ? #ffffd7 ? rgb(255,255,215) ? +? ? 231 ? "grey100" ? #ffffff ? rgb(255,255,255) ? +? ? 232 ? "grey3" ? #080808 ? rgb(8,8,8) ? +? ? 233 ? "grey7" ? #121212 ? rgb(18,18,18) ? +? ? 234 ? "grey11" ? #1c1c1c ? rgb(28,28,28) ? +? ? 235 ? "grey15" ? #262626 ? rgb(38,38,38) ? +? ? 236 ? "grey19" ? #303030 ? rgb(48,48,48) ? +? ? 237 ? "grey23" ? #3a3a3a ? rgb(58,58,58) ? +? ? 238 ? "grey27" ? #444444 ? rgb(68,68,68) ? +? ? 239 ? "grey30" ? #4e4e4e ? rgb(78,78,78) ? +? ? 240 ? "grey35" ? #585858 ? rgb(88,88,88) ? +? ? 241 ? "grey39" ? #626262 ? rgb(98,98,98) ? +? ? 242 ? "grey42" ? #6c6c6c ? rgb(108,108,108) ? +? ? 243 ? "grey46" ? #767676 ? rgb(118,118,118) ? +? ? 244 ? "grey50" ? #808080 ? rgb(128,128,128) ? +? ? 245 ? "grey54" ? #8a8a8a ? rgb(138,138,138) ? +? ? 246 ? "grey58" ? #949494 ? rgb(148,148,148) ? +? ? 247 ? "grey62" ? #9e9e9e ? rgb(158,158,158) ? +? ? 248 ? "grey66" ? #a8a8a8 ? rgb(168,168,168) ? +? ? 249 ? "grey70" ? #b2b2b2 ? rgb(178,178,178) ? +? ? 250 ? "grey74" ? #bcbcbc ? rgb(188,188,188) ? +? ? 251 ? "grey78" ? #c6c6c6 ? rgb(198,198,198) ? +? ? 252 ? "grey82" ? #d0d0d0 ? rgb(208,208,208) ? +? ? 253 ? "grey85" ? #dadada ? rgb(218,218,218) ? +? ? 254 ? "grey89" ? #e4e4e4 ? rgb(228,228,228) ? +? ? 255 ? "grey93" ? #eeeeee ? rgb(238,238,238) ? +???????????????????????????????????????????????????????????????????????????? + +""" diff --git a/evdspy/EVDSlocal/common/common_imports.py b/evdspy/EVDSlocal/common/common_imports.py index a9db6f4..041902f 100644 --- a/evdspy/EVDSlocal/common/common_imports.py +++ b/evdspy/EVDSlocal/common/common_imports.py @@ -1,23 +1,23 @@ -from dataclasses import dataclass, field -from collections import namedtuple -import requests -import sys -import pandas as pd -from pathlib import Path -from rich import print, inspect -from typing import List, Dict, Optional -import os -from pathlib import Path -import time -from abc import ABC, abstractmethod -from typing import Optional -from typing import TypeVar -import base64 -from datetime import date, datetime -from enum import Enum -import functools - -from evdspy.EVDSlocal.helper.print_m import * - -from evdspy.EVDSlocal.log_classes.log_template import deb, deb2, debug - +from dataclasses import dataclass, field +from collections import namedtuple +import requests +import sys +import pandas as pd +from pathlib import Path +from rich import print, inspect +from typing import List, Dict, Optional +import os +from pathlib import Path +import time +from abc import ABC, abstractmethod +from typing import Optional +from typing import TypeVar +import base64 +from datetime import date, datetime +from enum import Enum +import functools + +from evdspy.EVDSlocal.helper.print_m import * + +from evdspy.EVDSlocal.log_classes.log_template import deb, deb2, debug + diff --git a/evdspy/EVDSlocal/common/files.py b/evdspy/EVDSlocal/common/files.py index d72e52c..226b9fa 100644 --- a/evdspy/EVDSlocal/common/files.py +++ b/evdspy/EVDSlocal/common/files.py @@ -1,165 +1,165 @@ -from .colors import * - -filename = 't.txt' -content = 'aaa' -from ..common.common_imports import * -from typing import Union -from pathlib import Path - - -class WriteContext: - def __init__(self, fname, content, msg, mode="w"): - self.mode = mode - self.fname = fname - self.content = content - self.msg = msg - - def __enter__(self): - self.file_ = open(self.fname, self.mode, encoding='utf-8') - self.file_.write(self.content) - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.file_.close() - if exc_tb: - print_with_failure_style(exc_tb) - print_with_failure_style(self.msg) - return True - - -def Write(fname="test.txt", content="test", msg="Error"): - info = f"{fname}" - - result = False, "File was not created" - with WriteContext(fname, content, msg): - result = True, f"File was created... : {info}" - return result, f"File was created.. : {info}" - - -def WriteAdd(fname="test.txt", content="test", msg="Error"): - info = f"{fname}" - content = "\n" + content - - result = False, "File was not created" - with WriteContext(fname, content, msg, mode="a"): - result = True, f"File was created... : {info}" - return result, f"File was created.. : {info}" - - -class ReadContext: - def __init__(self, fname, msg): - self.fname = fname - self.msg = msg - - def __enter__(self): - # self.file_ = open(self.fname, "r", encoding='utf-8') - self.file_ = open(self.fname, "r", encoding='utf_8_sig') - return self.file_ - - def __exit__(self, exc_type, exc_val, exc_tb): - self.file_.close() - if exc_tb: - print_with_failure_style(exc_tb) - print_with_failure_style(self.msg) - return False - return True - - -def Read(file_name: Union[str, Path], msg="Error"): - if isinstance(file_name, str): - file_name = Path(file_name) - content = "" - with ReadContext(file_name, msg) as file_: - content = file_.read() - return content - - -def create_folder(folder_name: Union[str, Path]): - if isinstance(folder_name, str): - folder_name = Path(folder_name) - try: - os.makedirs(folder_name) - except FileExistsError: - print_with_updating_style("folder {} already exists".format(folder_name)) - except Exception as e: - print_with_failure_style(e) - - -def is_file(path_: str): - d = Path(path_) - return d.is_file() - - -def is_dir(path_: str): - d = Path(path_) - return d.is_dir() - - -def WriteBytes(file_name: str, content_bytes: bytes): - with open(file_name, 'wb') as f: - f.write(content_bytes) - - -def WriteBytesAdd(file_name: str, content_bytes: bytes): - with open(file_name, 'ab') as f: - f.write(content_bytes) - - -def ReadBytes(file_name: str): - with open(file_name, "rb") as f: - return f.read() - - -def make_indented(content: str, indent=" " * 10) -> str: - content_tup: tuple = tuple(f"{indent}{x}" for x in content.splitlines()) - content = "\n".join(content_tup) - return content - - -def add_one_line(cont_tuple: tuple, line: str) -> tuple: - cont: list = list(cont_tuple) - new_cont = cont + [line] - return tuple(new_cont) - - -# def content_continues_line(content: str) -> str: -# content = make_indented(content) -# content = make_it_summary(content, add_continue=True) -# return content -def line_continues_fn(skipped=0): - def cont_fn(): - lns = "lines" - if skipped == 1: - lns = "line" - if skipped > 0: - msg = f"{skipped} {lns} more..." - # skipped_msg = "" if skipped > 0 else f"{skipped} line more..." - cont = "." * 15 + f"{msg}" + "." * 15 - print_with_style(f"{cont}\n") - ... - - return cont_fn - - -def make_it_summary(content: str, max_line_num: int = 10, add_continue: bool = False) -> tuple: - content_tup: tuple = tuple(f"{x}" for x in content.splitlines()) - new_content_tup: tuple = content_tup[0:max_line_num] - skipped_lines = len(content_tup) - max_line_num if len(content_tup) - max_line_num > 0 else 0 - new_content_tup = add_one_line(new_content_tup, "." * 15) - return "\n".join(new_content_tup), skipped_lines - - -def file_exists_show_and_return(file_name: Union[str, Path]) -> bool: - if isinstance(file_name, str): - file_name = Path(file_name) - if file_name.is_file(): - content_ = Read(file_name) - print_with_updating_style(f"file {file_name} exists, not replacing...\n") - print_with_color("content: \n -------\n", "blue") - cont_msg, skipped = make_it_summary(make_indented(content_), add_continue=False, max_line_num=10) - print(cont_msg) - """print fn will return """ - line_continues_fn(skipped)() - time.sleep(1) - return True - return False +from .colors import * + +filename = 't.txt' +content = 'aaa' +from ..common.common_imports import * +from typing import Union +from pathlib import Path + + +class WriteContext: + def __init__(self, fname, content, msg, mode="w"): + self.mode = mode + self.fname = fname + self.content = content + self.msg = msg + + def __enter__(self): + self.file_ = open(self.fname, self.mode, encoding='utf-8') + self.file_.write(self.content) + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.file_.close() + if exc_tb: + print_with_failure_style(exc_tb) + print_with_failure_style(self.msg) + return True + + +def Write(fname="test.txt", content="test", msg="Error"): + info = f"{fname}" + + result = False, "File was not created" + with WriteContext(fname, content, msg): + result = True, f"File was created... : {info}" + return result, f"File was created.. : {info}" + + +def WriteAdd(fname="test.txt", content="test", msg="Error"): + info = f"{fname}" + content = "\n" + content + + result = False, "File was not created" + with WriteContext(fname, content, msg, mode="a"): + result = True, f"File was created... : {info}" + return result, f"File was created.. : {info}" + + +class ReadContext: + def __init__(self, fname, msg): + self.fname = fname + self.msg = msg + + def __enter__(self): + # self.file_ = open(self.fname, "r", encoding='utf-8') + self.file_ = open(self.fname, "r", encoding='utf_8_sig') + return self.file_ + + def __exit__(self, exc_type, exc_val, exc_tb): + self.file_.close() + if exc_tb: + print_with_failure_style(exc_tb) + print_with_failure_style(self.msg) + return False + return True + + +def Read(file_name: Union[str, Path], msg="Error"): + if isinstance(file_name, str): + file_name = Path(file_name) + content = "" + with ReadContext(file_name, msg) as file_: + content = file_.read() + return content + + +def create_folder(folder_name: Union[str, Path]): + if isinstance(folder_name, str): + folder_name = Path(folder_name) + try: + os.makedirs(folder_name) + except FileExistsError: + print_with_updating_style("folder {} already exists".format(folder_name)) + except Exception as e: + print_with_failure_style(e) + + +def is_file(path_: str): + d = Path(path_) + return d.is_file() + + +def is_dir(path_: str): + d = Path(path_) + return d.is_dir() + + +def WriteBytes(file_name: str, content_bytes: bytes): + with open(file_name, 'wb') as f: + f.write(content_bytes) + + +def WriteBytesAdd(file_name: str, content_bytes: bytes): + with open(file_name, 'ab') as f: + f.write(content_bytes) + + +def ReadBytes(file_name: str): + with open(file_name, "rb") as f: + return f.read() + + +def make_indented(content: str, indent=" " * 10) -> str: + content_tup: tuple = tuple(f"{indent}{x}" for x in content.splitlines()) + content = "\n".join(content_tup) + return content + + +def add_one_line(cont_tuple: tuple, line: str) -> tuple: + cont: list = list(cont_tuple) + new_cont = cont + [line] + return tuple(new_cont) + + +# def content_continues_line(content: str) -> str: +# content = make_indented(content) +# content = make_it_summary(content, add_continue=True) +# return content +def line_continues_fn(skipped=0): + def cont_fn(): + lns = "lines" + if skipped == 1: + lns = "line" + if skipped > 0: + msg = f"{skipped} {lns} more..." + # skipped_msg = "" if skipped > 0 else f"{skipped} line more..." + cont = "." * 15 + f"{msg}" + "." * 15 + print_with_style(f"{cont}\n") + ... + + return cont_fn + + +def make_it_summary(content: str, max_line_num: int = 10, add_continue: bool = False) -> tuple: + content_tup: tuple = tuple(f"{x}" for x in content.splitlines()) + new_content_tup: tuple = content_tup[0:max_line_num] + skipped_lines = len(content_tup) - max_line_num if len(content_tup) - max_line_num > 0 else 0 + new_content_tup = add_one_line(new_content_tup, "." * 15) + return "\n".join(new_content_tup), skipped_lines + + +def file_exists_show_and_return(file_name: Union[str, Path]) -> bool: + if isinstance(file_name, str): + file_name = Path(file_name) + if file_name.is_file(): + content_ = Read(file_name) + print_with_updating_style(f"file {file_name} exists, not replacing...\n") + print_with_color("content: \n -------\n", "blue") + cont_msg, skipped = make_it_summary(make_indented(content_), add_continue=False, max_line_num=10) + print(cont_msg) + """print fn will return """ + line_continues_fn(skipped)() + time.sleep(1) + return True + return False diff --git a/evdspy/EVDSlocal/common/folder_name_checks.py b/evdspy/EVDSlocal/common/folder_name_checks.py index b8fc529..9e694e9 100644 --- a/evdspy/EVDSlocal/common/folder_name_checks.py +++ b/evdspy/EVDSlocal/common/folder_name_checks.py @@ -1,24 +1,24 @@ -#------------------------------------check_remove_back_slash---------------- -# back_slash = r"\"" # u"\92" -# back_slash = back_slash.replace('"' , "") -back_slash = "\\" - -def check_remove_back_slash(folder_name): - if str(folder_name).startswith(back_slash): - folder_name = folder_name[1:] - return folder_name - - -reg_relative = '^[a-zA-Z0-9_/\\\\]*$' -reg_absolute_and_relative = '^[a-zA-Z0-9_/\\\\:]*$' - -import re - - -def is_relative(folder): - result = re.match(reg_relative, folder) - # if result: - # print(f"checked ok {folder}") - # else: - # print(f"not ok {folder}") - return result +#------------------------------------check_remove_back_slash---------------- +# back_slash = r"\"" # u"\92" +# back_slash = back_slash.replace('"' , "") +back_slash = "\\" + +def check_remove_back_slash(folder_name): + if str(folder_name).startswith(back_slash): + folder_name = folder_name[1:] + return folder_name + + +reg_relative = '^[a-zA-Z0-9_/\\\\]*$' +reg_absolute_and_relative = '^[a-zA-Z0-9_/\\\\:]*$' + +import re + + +def is_relative(folder): + result = re.match(reg_relative, folder) + # if result: + # print(f"checked ok {folder}") + # else: + # print(f"not ok {folder}") + return result diff --git a/evdspy/EVDSlocal/common/prog.py b/evdspy/EVDSlocal/common/prog.py index ef7e7e6..1e9ad5c 100644 --- a/evdspy/EVDSlocal/common/prog.py +++ b/evdspy/EVDSlocal/common/prog.py @@ -1,7 +1,7 @@ -from rich import print -import time -from rich.progress import track - -def rich_sim(num , msg ): - for i in track(range(num), description=msg): +from rich import print +import time +from rich.progress import track + +def rich_sim(num , msg ): + for i in track(range(num), description=msg): time.sleep(1) \ No newline at end of file diff --git a/evdspy/EVDSlocal/common/table.py b/evdspy/EVDSlocal/common/table.py index 28b0cc5..a60ed0f 100644 --- a/evdspy/EVDSlocal/common/table.py +++ b/evdspy/EVDSlocal/common/table.py @@ -1,73 +1,73 @@ -from dataclasses import dataclass -from rich.console import Console -from rich.table import Table - - -def split_wisely(line: str, sep: str, num: int): - parts = line.split(sep) - return parts[0:num] - - -@dataclass -class Table_: - - def get_color(self, items): - for item in items: - if 'false' in item.lower(): - return 'red' - return 'green' - - def show(self, content: str, title: str, columns: tuple, skiprow=1): - - table = Table(title=title) - column_num = len(columns) - for column in columns: - table.add_column(column, justify="left", style="cyan", no_wrap=True) - lines = content.splitlines() - if not lines: - return - for item in lines[skiprow:]: - parts = split_wisely(item, ":", column_num) - color_condit = self.get_color(parts) - table.add_row(*parts, style=color_condit) - - console = Console() - console.print(table) - - -import typing as t -from typing import List - -import typing as t - - -@dataclass -class Table2_: - - def get_color(self, items): - for item in items: - if 'false' in str(item).lower(): - return 'red' - return 'green' - - def show(self, list_: List[tuple], title: str, columns: t.Union[tuple, None], skiprow=1): - - table = Table(title=title) - if columns is None: - columns = ('key', 'value') - column_num = len(columns) - for column in columns: - table.add_column(column, justify="left", style="cyan", no_wrap=True) - lines = list_ - if not lines: - return - for item in lines: - # parts = split_wisely(item, ":", column_num) - parts = item - color_condit = self.get_color(parts) - table.add_row(*parts, style=color_condit) - - console = Console() - console.print(table) - -# Table2_.show(list_ = [] , title = '' ,columns = () , skiprow=0 ) +from dataclasses import dataclass +from rich.console import Console +from rich.table import Table + + +def split_wisely(line: str, sep: str, num: int): + parts = line.split(sep) + return parts[0:num] + + +@dataclass +class Table_: + + def get_color(self, items): + for item in items: + if 'false' in item.lower(): + return 'red' + return 'green' + + def show(self, content: str, title: str, columns: tuple, skiprow=1): + + table = Table(title=title) + column_num = len(columns) + for column in columns: + table.add_column(column, justify="left", style="cyan", no_wrap=True) + lines = content.splitlines() + if not lines: + return + for item in lines[skiprow:]: + parts = split_wisely(item, ":", column_num) + color_condit = self.get_color(parts) + table.add_row(*parts, style=color_condit) + + console = Console() + console.print(table) + + +import typing as t +from typing import List + +import typing as t + + +@dataclass +class Table2_: + + def get_color(self, items): + for item in items: + if 'false' in str(item).lower(): + return 'red' + return 'green' + + def show(self, list_: List[tuple], title: str, columns: t.Union[tuple, None], skiprow=1): + + table = Table(title=title) + if columns is None: + columns = ('key', 'value') + column_num = len(columns) + for column in columns: + table.add_column(column, justify="left", style="cyan", no_wrap=True) + lines = list_ + if not lines: + return + for item in lines: + # parts = split_wisely(item, ":", column_num) + parts = item + color_condit = self.get_color(parts) + table.add_row(*parts, style=color_condit) + + console = Console() + console.print(table) + +# Table2_.show(list_ = [] , title = '' ,columns = () , skiprow=0 ) diff --git a/evdspy/EVDSlocal/common/url_clean.py b/evdspy/EVDSlocal/common/url_clean.py index e6e763f..2915092 100644 --- a/evdspy/EVDSlocal/common/url_clean.py +++ b/evdspy/EVDSlocal/common/url_clean.py @@ -1,6 +1,6 @@ -def remove_api_key(url): - if "key=" not in url: - return url - separator = "&" - new_parts = (x for x in url.split(separator) if "key=" not in x) - return separator.join(new_parts) + "&key=xxxOMITTEDforSec" +def remove_api_key(url): + if "key=" not in url: + return url + separator = "&" + new_parts = (x for x in url.split(separator) if "key=" not in x) + return separator.join(new_parts) + "&key=xxxOMITTEDforSec" diff --git a/evdspy/EVDSlocal/components/api_params.py b/evdspy/EVDSlocal/components/api_params.py index be75bdc..5ccf953 100644 --- a/evdspy/EVDSlocal/components/api_params.py +++ b/evdspy/EVDSlocal/components/api_params.py @@ -1,235 +1,238 @@ -from dataclasses import dataclass, field -from abc import ABC, abstractmethod -from enum import Enum -from typing import Callable, List, Tuple, Union -from datetime import datetime - -from .api_params_enums import * - -default_api_domain = "https://evds2.tcmb.gov.tr/service/evds/" - - -@dataclass -class ApiDomain(ABC): - domain: str - - -@dataclass -class EVDSApiDomain(ApiDomain): - domain: str = default_api_domain - - def __repr__(self): - return self.domain - - -@dataclass -class EVDSApiDomainCategories(ApiDomain): - domain: str = f"{default_api_domain}categories/" - - def __repr__(self): - return self.domain - - -@dataclass -class EVDSApiDomainDatagroups(ApiDomain): - domain: str = f"{default_api_domain}datagroups/" - - def __repr__(self): - return self.domain - - -@dataclass -class EVDSApiDomainDatagroupIndividual(ApiDomain): - domain: str = f"{default_api_domain}" # datagroup=bie_yssk - - def __repr__(self): - return self.domain -#GeneralIndexesDatagroupSeriesList - -@dataclass -class EVDSApiDominDatagroupSeriesList(ApiDomain): - domain: str = f"{default_api_domain}serieList/" # serieList/key=xxx&type=json&code=bieyssk - - def __repr__(self): - return self.domain - -@dataclass -class UrlParam(ABC): - """UrlParam class """ - value: Union[str, datetime, int, Tuple[str], Callable, Enum, List[str]] - initial: str = "anything" - number_of_repeat: int = 1 - disp_value: str = "" - required: bool = True - obscured: bool = False - - def __str__(self) -> str: - return f"{self.disp_value}" - - def __repr__(self) -> str: - return f"{self.disp_value}" - - def __post_init__(self): - self.create_disp_value() - - def create_disp_value(self): - if not self.value and str(self.value) != "0": - self.disp_value = f"{self.initial}=Noneapi.params.103" - return - - # if isinstance(self.value, Enum) : - if hasattr(self.value, "value"): - self.disp_value = f"{self.initial}={self.value.value}" - if isinstance(self.value, (tuple, list,)): - value: str = "-".join(self.value) - self.disp_value = f"{self.initial}={value}" - return - if isinstance(self.value, (str, int,)): - self.disp_value = f"{self.initial}={self.value}" - return - if not self.value: - if self.required: - raise f"{self.__class__.__name__} parameter is required" - return - self.disp_value = f"{self.initial}={self.value}" - - def reportable_value(self): - if self.obscured: - return f"{self.initial}=obscured_for_report" - return self.disp_value - - def explanation(self): - if self.obscured: - return f"{self.initial}: obscured_for_report" - if callable(self.value): - disp_value = f"{self.initial}: {self.value.__name__}" - return disp_value - if isinstance(self.value, (list, str,)): - disp_value = f"{self.initial}: {', '.join(self.value)}" - return disp_value - return f"{self.initial}: {self.value}" - - -from typing import Callable - - -@dataclass -class Apikey(UrlParam): - initial: str = "key" - obscured: bool = True - - -class DecimalSeparator(UrlParam): - value: Separator = Separator.period - initial: str = "DecimalSeparator" - - -@dataclass -class Series(UrlParam): - """ Frequency """ - value: Union[List[str], Tuple[str]] = () - initial: str = "series" - - -@dataclass -class DataGroup(UrlParam): - """ Frequency """ - value: str = '' - initial: str = "datagroup" - required: bool = True - - def create_disp_value(self): - self.disp_value = f"{self.initial}={self.value}" - - -@dataclass -class Frequency(UrlParam): - """ Frequency """ - # value: Union[str, datetime, int, Tuple, Callable, Enum] - initial: str = "frequency" - required: bool = False - - -@dataclass -class Formulas(UrlParam): - """ Formulas """ - initial: str = "formulas" - required: bool = False - - def create_disp_value(self): - repeat = "-".join([str(self.value) for x in range(self.number_of_repeat)]) - self.disp_value = f"{self.initial}={repeat}" - - -@dataclass -class Aggregations(UrlParam): - """ Aggregations """ - initial: str = "aggregationTypes" - required: bool = False - - def create_disp_value(self): - repeat = "-".join([str(self.value) for x in range(self.number_of_repeat)]) - self.disp_value = f"{self.initial}={repeat}" - - -@dataclass -class DateStart(UrlParam): - """ DateStart """ - value: str = "" - initial: str = "startDate" - - -@dataclass -class DateEnd(UrlParam): - """ DateEnd """ - value: str = "" - initial: str = "endDate" - - -@dataclass -class dataTypeParam(UrlParam): - value: dataTypeEnum = dataTypeEnum.csv - required = True - initial: str = "type" - - def create_disp_value(self): - self.disp_value = f"{self.initial}={self.value.value}" - - -@dataclass -class ModeParamDataGroups(UrlParam): - initial: str = "mode" - required = True - # def create_disp_value(self): - # self.disp_value = f"{self.initial}={self.value.value}" - - -@dataclass -class CodeParamDataGroups(UrlParam): - value = 0 - initial: str = "code" - required = True - - def create_disp_value(self): - if hasattr(self.value, "value"): - value = self.value.value - else: - value = self.value - self.disp_value = f"{self.initial}={value}" - - -def convert_list_params_to_str(alist: Union[List[UrlParam], Tuple[UrlParam]], fnc: Union[Callable, str] = str): - separator_char = "&" - if fnc == str: - alist = [str(x) for x in alist if x is not None] - alist_str: str = separator_char.join(alist) - else: - indent = " " * 10 - block = "-" * 25 - separator_char = "\n" + indent - if fnc == "report": - alist = [x.reportable_value() for x in alist if x.reportable_value() is not None] - if fnc == "explanation": - alist = [x.explanation() for x in alist if x.explanation() is not None] - alist_str: str = block + f"{fnc}" + block + "\n" + indent + separator_char.join(alist) - return alist_str +from dataclasses import dataclass, field +from abc import ABC, abstractmethod +from enum import Enum +from typing import Callable, List, Tuple, Union +from datetime import datetime + +from evdspy.EVDSlocal.components.api_params_enums import * + +default_api_domain = "https://evds2.tcmb.gov.tr/service/evds/" + + +@dataclass +class ApiDomain(ABC): + domain: str + + +@dataclass +class EVDSApiDomain(ApiDomain): + domain: str = default_api_domain + + def __repr__(self): + return self.domain + + +@dataclass +class EVDSApiDomainCategories(ApiDomain): + domain: str = f"{default_api_domain}categories/" + + def __repr__(self): + return self.domain + + +@dataclass +class EVDSApiDomainDatagroups(ApiDomain): + domain: str = f"{default_api_domain}datagroups/" + + def __repr__(self): + return self.domain + + +@dataclass +class EVDSApiDomainDatagroupIndividual(ApiDomain): + domain: str = f"{default_api_domain}" # datagroup=bie_yssk + + def __repr__(self): + return self.domain + + +# GeneralIndexesDatagroupSeriesList + +@dataclass +class EVDSApiDominDatagroupSeriesList(ApiDomain): + domain: str = f"{default_api_domain}serieList/" # serieList/key=xxx&type=json&code=bieyssk + + def __repr__(self): + return self.domain + + +@dataclass +class UrlParam(ABC): + """UrlParam class """ + value: Union[str, datetime, int, Tuple[str], Callable, Enum, List[str]] + initial: str = "anything" + number_of_repeat: int = 1 + disp_value: str = "" + required: bool = True + obscured: bool = False + + def __str__(self) -> str: + return f"{self.disp_value}" + + def __repr__(self) -> str: + return f"{self.disp_value}" + + def __post_init__(self): + self.create_disp_value() + + def create_disp_value(self): + if not self.value and str(self.value) != "0": + self.disp_value = f"{self.initial}=Noneapi.params.103" + return + + # if isinstance(self.value, Enum) : + if hasattr(self.value, "value"): + self.disp_value = f"{self.initial}={self.value.value}" + if isinstance(self.value, (tuple, list,)): + value: str = "-".join(self.value) + self.disp_value = f"{self.initial}={value}" + return + if isinstance(self.value, (str, int,)): + self.disp_value = f"{self.initial}={self.value}" + return + if not self.value: + if self.required: + raise f"{self.__class__.__name__} parameter is required" + return + self.disp_value = f"{self.initial}={self.value}" + + def reportable_value(self): + if self.obscured: + return f"{self.initial}=obscured_for_report" + return self.disp_value + + def explanation(self): + if self.obscured: + return f"{self.initial}: obscured_for_report" + if callable(self.value): + disp_value = f"{self.initial}: {self.value.__name__}" + return disp_value + if isinstance(self.value, (list, str,)): + disp_value = f"{self.initial}: {', '.join(self.value)}" + return disp_value + return f"{self.initial}: {self.value}" + + +from typing import Callable + + +@dataclass +class Apikey(UrlParam): + initial: str = "key" + obscured: bool = True + + +class DecimalSeparator(UrlParam): + value: Separator = Separator.period + initial: str = "DecimalSeparator" + + +@dataclass +class Series(UrlParam): + """ Frequency """ + value: Union[List[str], Tuple[str]] = () + initial: str = "series" + + +@dataclass +class DataGroup(UrlParam): + """ Frequency """ + value: str = '' + initial: str = "datagroup" + required: bool = True + + def create_disp_value(self): + self.disp_value = f"{self.initial}={self.value}" + + +@dataclass +class Frequency(UrlParam): + """ Frequency """ + # value: Union[str, datetime, int, Tuple, Callable, Enum] + initial: str = "frequency" + required: bool = False + + +@dataclass +class Formulas(UrlParam): + """ Formulas """ + initial: str = "formulas" + required: bool = False + + def create_disp_value(self): + repeat = "-".join([str(self.value) for x in range(self.number_of_repeat)]) + self.disp_value = f"{self.initial}={repeat}" + + +@dataclass +class Aggregations(UrlParam): + """ Aggregations """ + initial: str = "aggregationTypes" + required: bool = False + + def create_disp_value(self): + repeat = "-".join([str(self.value) for x in range(self.number_of_repeat)]) + self.disp_value = f"{self.initial}={repeat}" + + +@dataclass +class DateStart(UrlParam): + """ DateStart """ + value: str = "" + initial: str = "startDate" + + +@dataclass +class DateEnd(UrlParam): + """ DateEnd """ + value: str = "" + initial: str = "endDate" + + +@dataclass +class dataTypeParam(UrlParam): + value: dataTypeEnum = dataTypeEnum.csv + required = True + initial: str = "type" + + def create_disp_value(self): + self.disp_value = f"{self.initial}={self.value.value}" + + +@dataclass +class ModeParamDataGroups(UrlParam): + initial: str = "mode" + required = True + # def create_disp_value(self): + # self.disp_value = f"{self.initial}={self.value.value}" + + +@dataclass +class CodeParamDataGroups(UrlParam): + value = 0 + initial: str = "code" + required = True + + def create_disp_value(self): + if hasattr(self.value, "value"): + value = self.value.value + else: + value = self.value + self.disp_value = f"{self.initial}={value}" + + +def convert_list_params_to_str(alist: Union[List[UrlParam], Tuple[UrlParam]], fnc: Union[Callable, str] = str): + separator_char = "&" + if fnc == str: + alist = [str(x) for x in alist if x is not None] + alist_str: str = separator_char.join(alist) + else: + indent = " " * 10 + block = "-" * 25 + separator_char = "\n" + indent + if fnc == "report": + alist = [x.reportable_value() for x in alist if x.reportable_value() is not None] + if fnc == "explanation": + alist = [x.explanation() for x in alist if x.explanation() is not None] + alist_str: str = block + f"{fnc}" + block + "\n" + indent + separator_char.join(alist) + return alist_str diff --git a/evdspy/EVDSlocal/components/api_params_enums.py b/evdspy/EVDSlocal/components/api_params_enums.py index 6e878fd..53b322c 100644 --- a/evdspy/EVDSlocal/components/api_params_enums.py +++ b/evdspy/EVDSlocal/components/api_params_enums.py @@ -1,135 +1,135 @@ -import typing as t -from enum import Enum, auto - - -# ------------------------------------------------------- E N U M S ------------------------------------------------------- - -class EnumBase(Enum): - ... - -# --------------------------------FrequencyEnum--------------------- -class FrequencyEnum(Enum): - daily = 1 - business_day = 2 - weekly = 3 - semimonthly = 4 - monthly = 5 - quarterly = 6 - semi_annual = 7 - annual = 8 - default = 5 - - -# --------------------------------DomainParts--------------------- - -class DomainParts(Enum): - categories = auto() - datagroup = auto() - series = auto() - - -# --------------------------------AggregationEnum--------------------- - -class AggregationEnum(Enum): - average = "avg" - min = "min" - max = "max" - first = "first" - last = "last" - cumulative = "sum" - default = "avg" - - -# --------------------------------ModeEnumDatagroup--------------------- - -class ModeEnumDatagroup(Enum): - all_groups = 0 - data_group = 1 - subject_group = 2 -# --------------------------------CodeEnumDatagroup--------------------- - -# class CodeEnumDatagroup(Enum): -# code_int = 1 -# -# data_group = 1 -# subject_group = 2 - - -# --------------------------------Separator--------------------- - -class Separator(Enum): - period = "." - comma = "," - - -# --------------------------------dataTypeEnum--------------------- - -class dataTypeEnum(Enum): - csv: str = "csv" - json_type: str = "json" - - -# --------------------------------FormulasEnum--------------------- - -class FormulasEnum(Enum): - level = 0 - percentage_change = 1 - difference = 2 - yoy_percentage_change = 3 - yoy_difference = 4 - per_cha_com_end_of_pre_yea = 5 - dif_com_end_of_pre_yea = 6 - moving_average = 7 - moving_sum = 8 - default = 0 - - # ------------------------------------------------------- get_enum_with_value ------------------------------------------------------- - """ typical usages - get_enum_with_value( 5 , Frequency , Frequency.Monthly ) - - """ - - -""" - key: t.Union[Enum, str, int], - # enum_: t.Union[str, int, t.Callable , Enum ], - enum_: Enum, - default_value: t.Union[str, int, t.Callable] = None - - key: t.Union[Enum, str, int], - # enum_: t.Union[str, int, t.Callable , Enum ], - enum_: any, - default_value: any = None -""" - - -def get_enum_with_value( - key: t.Union[Enum, str, int], - enum_: t.Union[str, int, t.Callable , Enum ], - # enum_: Enum, - default_value: t.Union[str, int, t.Callable , Enum ] = None - -) -> Enum : - """ - - :rtype: object - """ - if isinstance(key, Enum): - return key - if isinstance(key, int): - key = str(key) - - if hasattr(default_value, "value"): - """otherwise probably None """ - default_value = getattr(default_value, "value", None) - - dd = {str(x.value): x for x in enum_} - enum_value: Enum = dd.get(key, None) - - if hasattr(enum_value, "value"): - v = getattr(enum_value, "value") - return v - if not default_value: - return getattr(default_value, "default") - return default_value -# ------------------------------------------------------- / get_enum_with_value ------------------------------------------------------- +import typing as t +from enum import Enum, auto + + +# ------------------------------------------------------- E N U M S ------------------------------------------------------- + +class EnumBase(Enum): + ... + +# --------------------------------FrequencyEnum--------------------- +class FrequencyEnum(Enum): + daily = 1 + business_day = 2 + weekly = 3 + semimonthly = 4 + monthly = 5 + quarterly = 6 + semi_annual = 7 + annual = 8 + default = 5 + + +# --------------------------------DomainParts--------------------- + +class DomainParts(Enum): + categories = auto() + datagroup = auto() + series = auto() + + +# --------------------------------AggregationEnum--------------------- + +class AggregationEnum(Enum): + average = "avg" + min = "min" + max = "max" + first = "first" + last = "last" + cumulative = "sum" + default = "avg" + + +# --------------------------------ModeEnumDatagroup--------------------- + +class ModeEnumDatagroup(Enum): + all_groups = 0 + data_group = 1 + subject_group = 2 +# --------------------------------CodeEnumDatagroup--------------------- + +# class CodeEnumDatagroup(Enum): +# code_int = 1 +# +# data_group = 1 +# subject_group = 2 + + +# --------------------------------Separator--------------------- + +class Separator(Enum): + period = "." + comma = "," + + +# --------------------------------dataTypeEnum--------------------- + +class dataTypeEnum(Enum): + csv: str = "csv" + json_type: str = "json" + + +# --------------------------------FormulasEnum--------------------- + +class FormulasEnum(Enum): + level = 0 + percentage_change = 1 + difference = 2 + yoy_percentage_change = 3 + yoy_difference = 4 + per_cha_com_end_of_pre_yea = 5 + dif_com_end_of_pre_yea = 6 + moving_average = 7 + moving_sum = 8 + default = 0 + + # ------------------------------------------------------- get_enum_with_value ------------------------------------------------------- + """ typical usages + get_enum_with_value( 5 , Frequency , Frequency.Monthly ) + + """ + + +""" + key: t.Union[Enum, str, int], + # enum_: t.Union[str, int, t.Callable , Enum ], + enum_: Enum, + default_value: t.Union[str, int, t.Callable] = None + + key: t.Union[Enum, str, int], + # enum_: t.Union[str, int, t.Callable , Enum ], + enum_: any, + default_value: any = None +""" + + +def get_enum_with_value( + key: t.Union[Enum, str, int], + enum_: t.Union[str, int, t.Callable , Enum ], + # enum_: Enum, + default_value: t.Union[str, int, t.Callable , Enum ] = None + +) -> Enum : + """ + + :rtype: object + """ + if isinstance(key, Enum): + return key + if isinstance(key, int): + key = str(key) + + if hasattr(default_value, "value"): + """otherwise probably None """ + default_value = getattr(default_value, "value", None) + + dd = {str(x.value): x for x in enum_} + enum_value: Enum = dd.get(key, None) + + if hasattr(enum_value, "value"): + v = getattr(enum_value, "value") + return v + if not default_value: + return getattr(default_value, "default") + return default_value +# ------------------------------------------------------- / get_enum_with_value ------------------------------------------------------- diff --git a/evdspy/EVDSlocal/components/bucket_from_series.py b/evdspy/EVDSlocal/components/bucket_from_series.py index 557c3e8..86b5cce 100644 --- a/evdspy/EVDSlocal/components/bucket_from_series.py +++ b/evdspy/EVDSlocal/components/bucket_from_series.py @@ -1,135 +1,135 @@ -from ..common.common_imports import * -from ..common.files import * -from dataclasses import dataclass -import os -from pathlib import Path -from evdspy.EVDSlocal.messages.error_classes import BucketFromSeriesFolderCreateError -from evdspy.EVDSlocal.config.config import * -from ..initial.start_args import Args -from ..components.options_class import Options, load_options, SingletonOptions -from evdspy.EVDSlocal.initial.start_options import default_data_folder_name -from evdspy.EVDSlocal.common.folder_name_checks import check_remove_back_slash -from dataclasses import dataclass -import os -from pathlib import Path - -from evdspy.EVDSlocal.components.api_params import FrequencyEnum, Frequency, AggregationEnum, Aggregations, \ - get_enum_with_value, FormulasEnum, Formulas - -# ------------------------------------------------------------------------------ -# /* -# BucketFromSeriesFile -# -# ------------------------------------------------------------------------------ -# */ -from evdspy.EVDSlocal.components.request_or_cache import RequestOrCacheResultInfo - - -@dataclass -class BucketFromSeriesFile: - folder_name: any - subject: str - frequency: str - formulas: str - aggregateType: str - prefix: str = Default_Prefix_ - NullType: bool = False - abs_path: any = None - xls_name_path: str = "test" - request_or_cache_resultInfo_: field(default_factory=RequestOrCacheResultInfo) = False - - def __post_init__(self): - """ Check 2 => after writing avoid \foldername\foldername instead of foldername\foldername - we previously checked while getting input from user but - we are checking if user added any absolute path by mistake - """ - - def get_defaults(item, default_value): - if item == "": - return default_value - return item - - # self.frequency = get_defaults(str(self.frequency), default_freq) - # self.formulas = get_defaults(self.formulas, default_formulas_) - # self.aggregateType = get_defaults(self.aggregateType, default_AggregateType_) - from evdspy.EVDSlocal.setup_project.user_series_config import default_freq, default_formulas_, \ - default_AggregateType_ - - self.frequency: str = get_defaults(str(self.frequency), default_freq) - self.frequency = get_enum_with_value(self.frequency, FrequencyEnum, FrequencyEnum.default) - - self.formulas: str = get_defaults(self.formulas, default_formulas_) - self.formulas: str = get_enum_with_value(self.formulas, FormulasEnum, FormulasEnum.default) - - self.aggregateType = get_defaults(self.aggregateType, default_AggregateType_) - self.aggregateType: str = get_enum_with_value(self.aggregateType, AggregationEnum, AggregationEnum.default) - - self.folder_name = check_remove_back_slash(self.folder_name) - self.abs_path = self.get_folder_name(self.folder_name) - self.xls_name_path = str(Path(self.abs_path) / (self.prefix + '_' + self.subject)) - - def __str__(self): - s = f""" -frequency : {self.frequency} -formulas : {self.formulas} -aggregateType : {self.aggregateType} -folder_name : {self.folder_name} -abs_path : {self.abs_path} -xls_name_path : {self.xls_name_path} - -""" - return s - - def get_folder_name(self, folder_name: str): - def adapt_folder_name(relative_folder, reduce=False): - if reduce: - relative_folder = Path(folder_name).stem - abs_modified = Path() / default_data_folder_name / relative_folder - return abs_modified - - if folder_name is None: - return "" - if Avoid_Absolute_Paths_ and SingletonOptions().options_.avoid_absolute_paths_user: - """ Namespace Protection is on """ - r""" - This is extra protection to prevent mismatching of unwanted paths and populating some files replacing - old files, if the user is sure absolute paths are correct they can modify - Avoid_Absolute_Paths_ variable in start_options.py file - avoids : C:Users\Userx\XdataFolderName - changes paths to correct form : ...WorkingDirectory..\SeriesData\XdataFolderName - """ - reduce = False - if Path(folder_name).is_absolute(): - reduce = True - return adapt_folder_name(folder_name, reduce=reduce) - """ Namespace Protection turned off by user """ - print("Avoid_Absolute_Paths_ was cancelled") - - if self.create_folder(): - """ now we will return absolute path if we can successfully create the folder""" - return self.abs_path - return adapt_folder_name(self.abs_path, reduce=True) - - def create_folder(self): - if is_dir(self.abs_path): - return True - try: - os.makedirs(self.abs_path) - return True - except: - if not config.current_mode_is_test: - print(f"could not create folder {self.abs_path} ") - # raise BucketFromSeriesFolderCreateError - return False - - -from evdspy.EVDSlocal.setup_project.user_series_config import default_freq, default_formulas_, \ - default_AggregateType_ - -null_BucketFromSeriesFile = BucketFromSeriesFile(folder_name=None, - subject="test", - frequency=default_freq, - formulas=default_formulas_, - aggregateType=default_AggregateType_, - prefix="EV_", - NullType=True) +from ..common.common_imports import * +from ..common.files import * +from dataclasses import dataclass +import os +from pathlib import Path +from evdspy.EVDSlocal.messages.error_classes import BucketFromSeriesFolderCreateError +from evdspy.EVDSlocal.config.config import * +from ..initial.start_args import Args +from ..components.options_class import Options, load_options, SingletonOptions +from evdspy.EVDSlocal.initial.start_options import default_data_folder_name +from evdspy.EVDSlocal.common.folder_name_checks import check_remove_back_slash +from dataclasses import dataclass +import os +from pathlib import Path + +from evdspy.EVDSlocal.components.api_params import FrequencyEnum, Frequency, AggregationEnum, Aggregations, \ + get_enum_with_value, FormulasEnum, Formulas + +# ------------------------------------------------------------------------------ +# /* +# BucketFromSeriesFile +# +# ------------------------------------------------------------------------------ +# */ +from evdspy.EVDSlocal.components.request_or_cache import RequestOrCacheResultInfo + + +@dataclass +class BucketFromSeriesFile: + folder_name: any + subject: str + frequency: str + formulas: str + aggregateType: str + prefix: str = Default_Prefix_ + NullType: bool = False + abs_path: any = None + xls_name_path: str = "test" + request_or_cache_resultInfo_: field(default_factory=RequestOrCacheResultInfo) = False + + def __post_init__(self): + """ Check 2 => after writing avoid \foldername\foldername instead of foldername\foldername + we previously checked while getting input from user but + we are checking if user added any absolute path by mistake + """ + + def get_defaults(item, default_value): + if item == "": + return default_value + return item + + # self.frequency = get_defaults(str(self.frequency), default_freq) + # self.formulas = get_defaults(self.formulas, default_formulas_) + # self.aggregateType = get_defaults(self.aggregateType, default_AggregateType_) + from evdspy.EVDSlocal.setup_project.user_series_config import default_freq, default_formulas_, \ + default_AggregateType_ + + self.frequency: str = get_defaults(str(self.frequency), default_freq) + self.frequency = get_enum_with_value(self.frequency, FrequencyEnum, FrequencyEnum.default) + + self.formulas: str = get_defaults(self.formulas, default_formulas_) + self.formulas: str = get_enum_with_value(self.formulas, FormulasEnum, FormulasEnum.default) + + self.aggregateType = get_defaults(self.aggregateType, default_AggregateType_) + self.aggregateType: str = get_enum_with_value(self.aggregateType, AggregationEnum, AggregationEnum.default) + + self.folder_name = check_remove_back_slash(self.folder_name) + self.abs_path = self.get_folder_name(self.folder_name) + self.xls_name_path = str(Path(self.abs_path) / (self.prefix + '_' + self.subject)) + + def __str__(self): + s = f""" +frequency : {self.frequency} +formulas : {self.formulas} +aggregateType : {self.aggregateType} +folder_name : {self.folder_name} +abs_path : {self.abs_path} +xls_name_path : {self.xls_name_path} + +""" + return s + + def get_folder_name(self, folder_name: str): + def adapt_folder_name(relative_folder, reduce=False): + if reduce: + relative_folder = Path(folder_name).stem + abs_modified = Path() / default_data_folder_name / relative_folder + return abs_modified + + if folder_name is None: + return "" + if Avoid_Absolute_Paths_ and SingletonOptions().options_.avoid_absolute_paths_user: + """ Namespace Protection is on """ + r""" + This is extra protection to prevent mismatching of unwanted paths and populating some files replacing + old files, if the user is sure absolute paths are correct they can modify + Avoid_Absolute_Paths_ variable in start_options.py file + avoids : C:Users\Userx\XdataFolderName + changes paths to correct form : ...WorkingDirectory..\SeriesData\XdataFolderName + """ + reduce = False + if Path(folder_name).is_absolute(): + reduce = True + return adapt_folder_name(folder_name, reduce=reduce) + """ Namespace Protection turned off by user """ + print("Avoid_Absolute_Paths_ was cancelled") + + if self.create_folder(): + """ now we will return absolute path if we can successfully create the folder""" + return self.abs_path + return adapt_folder_name(self.abs_path, reduce=True) + + def create_folder(self): + if is_dir(self.abs_path): + return True + try: + os.makedirs(self.abs_path) + return True + except: + if not config.current_mode_is_test: + print(f"could not create folder {self.abs_path} ") + # raise BucketFromSeriesFolderCreateError + return False + + +from evdspy.EVDSlocal.setup_project.user_series_config import default_freq, default_formulas_, \ + default_AggregateType_ + +null_BucketFromSeriesFile = BucketFromSeriesFile(folder_name=None, + subject="test", + frequency=default_freq, + formulas=default_formulas_, + aggregateType=default_AggregateType_, + prefix="EV_", + NullType=True) diff --git a/evdspy/EVDSlocal/components/evds_files.py b/evdspy/EVDSlocal/components/evds_files.py index 7c80fbf..0530621 100644 --- a/evdspy/EVDSlocal/components/evds_files.py +++ b/evdspy/EVDSlocal/components/evds_files.py @@ -1,320 +1,320 @@ -# ------------------------------------------------------------------------------ -import pandas as pd -from evdspy.EVDSlocal.initial.start_options import default_series_file_name - -from evdspy.EVDSlocal.config.config import * -from evdspy.EVDSlocal.components.excel_class import * -from ..requests_.request_error_classes import Internal -from ..utils.utils_general import * -from ..requests_.my_cache import MyCache -from ..components.options_class import Options, load_options -from ..components.evds_seri_files import EvdsSeriesRequest, test_series_ -from evdspy.EVDSlocal.requests_.ev_request import EVRequest -from ..config.credentials_file import Credentials -from ..initial.start_args import * -from ..config.apikey_class import * -from dataclasses import dataclass -from typing import Union, List, Tuple -from ..common.colors import * - -# ------------------------------------------------------------------------------ -m_cache = MyCache() -number = 0 -# ------------------------------------------------------------------------------ -# ------------------------------------------------------------------------------ -# /* -# EvdsSorgu -# -# ------------------------------------------------------------------------------ -# */ -from evdspy.EVDSlocal.components.evds_seri_files import BucketFromSeriesFile -from evdspy.EVDSlocal.components.request_or_cache import RequestOrCacheResultInfo -from evdspy.EVDSlocal.state.current_state import CurrentState -from evdspy.EVDSlocal.components.url_class import URLClass -from evdspy.EVDSlocal.components.api_params import Series, DateStart, DateEnd - -current_state = CurrentState() - - -class DfColumnsDoesNotMatch(BaseException): - """DfColumnsDoNotMatch""" - - -from evdspy.EVDSlocal.messages.error_classes import ApiKeyNotSetError - - -# field(default_factory=URLClass) - -@dataclass -class EvdsSorgu(ABC): - """ EVDS Genel Sınıf""" - options_: Options - session: any - series_: EvdsSeriesRequest = field( - default_factory=EvdsSeriesRequest) # field(default=test_series_) # None # test_series_ - file_name: Optional[str] = "test" - subject: str = "test_subject" - df: any = None - excel_out_ext: str = "xlsx" - args: Args = field(default_factory=Args) # Args(sys.argv) - url: Optional[str] = None - proxy: Optional[str] = False - bfs: BucketFromSeriesFile = None - df_checked: bool = False - request_or_cache_resultInfo_: RequestOrCacheResultInfo = field(default_factory=RequestOrCacheResultInfo) - - def __post_init__(self): - # self.URL_Instance = URLClass() - self.credentials = field(default_factory=Credentials) # Credentials(options_=self.options_) - self.address: str = '' # field(default=self.credentials.address) - self.EVRequest_: EVRequest = field(default_factory=EVRequest) # EVRequest(options_=self.options_, session=None) - self.parent_folder = Path(__file__).parent - self.core_file_name = self.file_name - self.file_name = str(Path().absolute() / "output" / self.file_name) - self.current_file_created = "" - self.display() - self.assign_results_to_state() - - if not self.check_api_key_first(): - print_with_failure_style("Api key") - - def assign_results_to_state(self): - """ - save result stats to state - to finally access from bfs - """ - current_state.set_result_dict(str(id(self.bfs)), self.request_or_cache_resultInfo_) - - def report(self): - m_cache.report() - ... - - def display(self, *args): - # global number - # number += 1 - items_series = (x.ID for x in self.series_.series_list) - dec = f""" ----------------------------------------- - Order item from '{default_series_file_name}' - Details : - bfs : {self.bfs} -___________________ - filename: {self.core_file_name} - subject : {self.subject} - series : - {", ".join(items_series)} - ----------------------------------------- -""" - print(dec) - return dec - - def check_api_key_first(self): - # TODO ApikeyClass().get_valid_api_key() - if not self.EVRequest_: - self.EVRequest_ = EVRequest(options_=load_options(), - session=None, - proxy=None, - args=Args(()) - ) - - try: - if ApikeyClass().get_valid_api_key(): - # self.EVRequest_.check_any_apikey() - return True - except ApiKeyNotSetError: - return False - - def create_url(self): - api_key = ApikeyClass().get_valid_api_key() - if not config.current_mode_is_test: - assert api_key is not False, "api_key is False " - self.complete_url_instance: URLClass = self.series_.complete_url_instance - self.request_or_cache_resultInfo_.url_instance = self.series_.complete_url_instance - self.complete_url_instance.refresh_url() - - self.request_or_cache_resultInfo_.safe_url = f"{self.complete_url_instance.create_report()}" - will_be_requested: Tuple = ( - self.complete_url_instance.url, - self.complete_url_instance.url_only_required, - ) - return will_be_requested - - def get_json(self, url: str): - """ Not implemented """ - raise NotImplementedError - # return self.EVRequest_.get_request_before_cache(f"{url}&type=json").json() - - def get_csv(self, url: str): - - if not hasattr(self.EVRequest_, 'URL_Instance'): - self.EVRequest_ = EVRequest(options_=load_options()) - self.EVRequest_.URL_Instance = URLClass() - - self.EVRequest_.URL_Instance = self.complete_url_instance - result = self.EVRequest_.get_request_before_cache(f"{url}&type=csv") - if hasattr(result, "text"): - self.csv = result.text - return result.text - - return False - - @staticmethod - def extract_values_from_line(line: str, sep=","): - return line.split(sep) - - @staticmethod - def line_gen(buffer: str): - if not buffer: - return False - for item in buffer.split("\n"): - yield item - - # @staticmethod - def get_columns_from_first_row(self): - first_row = self.csv.split("\n")[0].split(",") - return first_row - - def get_columns(self, df): - current_columns = df.columns # rangeIndex - if isinstance(current_columns, pd.RangeIndex): - current_columns_len = len([x for x in current_columns]) - else: - current_columns_len = len(current_columns) - potential_columns = self.get_columns_from_first_row() - if len(potential_columns) != current_columns_len: - raise DfColumnsDoesNotMatch() - df.columns = self.get_columns_from_first_row() - self.request_or_cache_resultInfo_.columns = df.columns - UnixTime = 'UNIXTIME' - if UnixTime in df.columns: - df.drop(UnixTime, axis=1, inplace=True) - if config.current_mode_is_test: - self.save_excel("testpytest2.xlsx") - return df - - @staticmethod - def list_to_df(items): - return pd.DataFrame(items) - - def make_df_float(self): - - def check_cols(x: str): - items = ( - "Tarih" not in x, - "WEEK" not in x, - "DAY" not in x, - ) - return all(items) - - columns = (x for x in self.df.columns if check_cols(x)) - other_cols = (x for x in self.df.columns if not check_cols(x)) - old_df = self.df - try: - self.df = self.df[columns].astype(float) - for other_column in other_cols: - self.df[other_column] = old_df[other_column] - except: - print_with_failure_style("Could not convert some columns to float type...") - - def convert_csv_df(self, csv_buffer: str): - if not csv_buffer: - return False - pd_rows = list( - map(self.extract_values_from_line, - (item for item in self.line_gen(csv_buffer)) - ) - ) - pd_rows.pop(0) - self.df_no_columns = self.list_to_df(pd_rows) - try: - self.df = self.get_columns(self.df_no_columns) - except DfColumnsDoesNotMatch: - print_with_failure_style("columns did not match returning df with no columns...") - self.df = self.df_no_columns - print(self.df.head()) - filename = "error_" + str(id(self.df)) + ".xlsx" - # self.df.to_excel(filename) - print_with_info_style("error: requested URL does not fit...") - time.sleep(1) - return False - except Exception as e: - print_with_failure_style(e) - pass - self.make_df_float() - - return self.df - - @property - def got_items(self): - if not self.check_api_key_first(): - return False - self.df_checked = True - return self.get_items_csv() - - def get_items_csv(self): - will_be_requested = self.create_url() - for item in will_be_requested: - try: - df = self.convert_csv_df(self.get_csv(item)) - except DfColumnsDoesNotMatch: - continue - except Internal: - continue - if isinstance(df, pd.DataFrame): - return df - return False - - def get_items_json(self): - """not implemented""" - # return self.convert_csv_df(self.get_json(self.create_url())) - - def save_excel(self, file_name=None): - deb("not writing... evds_files. 273") - return True - - -# ---------------------------------------------------------- / EvdsSorgu -# ------------------------------------------------------------------------------ -# /* -# EvdsSorguSeries -# -# ------------------------------------------------------------------------------ -# */ -@dataclass -class EvdsSorguSeries(EvdsSorgu): - """ Seriler için """ - - def summary(self): - if not self.check_api_key_first(): - return False - self.df = self.got_items - if not isinstance(self.df, pd.DataFrame): - return False - # print(self.df.head()) - return self.df.head() - - def save_excel(self, file_name=None): - if not self.df_checked: - self.df = self.got_items - file_name = self.bfs.xls_name_path - try: - os.makedirs(self.bfs.abs_path) - except: - pass - # assert file_name == "ttt" - if not isinstance(self.df, pd.DataFrame): - print_with_failure_style("df was not created") - self.request_or_cache_resultInfo_.excel_saved = False - return - self.ExcelSaveClass_ = ExcelSaveClass(self.df, file_name) - self.ExcelSaveClass_.save_excel__() - self.request_or_cache_resultInfo_.excel_saved = True - return True - - -# ---------------------------------------------------------- / EvdsSorguSeries -__all__ = [ - 'EvdsSorguSeries', - 'EvdsSorgu', -] +# ------------------------------------------------------------------------------ +import pandas as pd +from evdspy.EVDSlocal.initial.start_options import default_series_file_name + +from evdspy.EVDSlocal.config.config import * +from evdspy.EVDSlocal.components.excel_class import * +from ..requests_.request_error_classes import Internal +from ..utils.utils_general import * +from ..requests_.my_cache import MyCache +from ..components.options_class import Options, load_options +from ..components.evds_seri_files import EvdsSeriesRequest, test_series_ +from evdspy.EVDSlocal.requests_.ev_request import EVRequest +from ..config.credentials_file import Credentials +from ..initial.start_args import * +from ..config.apikey_class import * +from dataclasses import dataclass +from typing import Union, List, Tuple +from ..common.colors import * + +# ------------------------------------------------------------------------------ +m_cache = MyCache() +number = 0 +# ------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ +# /* +# EvdsSorgu +# +# ------------------------------------------------------------------------------ +# */ +from evdspy.EVDSlocal.components.evds_seri_files import BucketFromSeriesFile +from evdspy.EVDSlocal.components.request_or_cache import RequestOrCacheResultInfo +from evdspy.EVDSlocal.state.current_state import CurrentState +from evdspy.EVDSlocal.components.url_class import URLClass +from evdspy.EVDSlocal.components.api_params import Series, DateStart, DateEnd + +current_state = CurrentState() + + +class DfColumnsDoesNotMatch(BaseException): + """DfColumnsDoNotMatch""" + + +from evdspy.EVDSlocal.messages.error_classes import ApiKeyNotSetError + + +# field(default_factory=URLClass) + +@dataclass +class EvdsSorgu(ABC): + """ EVDS Genel Sınıf""" + options_: Options + session: any + series_: EvdsSeriesRequest = field( + default_factory=EvdsSeriesRequest) # field(default=test_series_) # None # test_series_ + file_name: Optional[str] = "test" + subject: str = "test_subject" + df: any = None + excel_out_ext: str = "xlsx" + args: Args = field(default_factory=Args) # Args(sys.argv) + url: Optional[str] = None + proxy: Optional[str] = False + bfs: BucketFromSeriesFile = None + df_checked: bool = False + request_or_cache_resultInfo_: RequestOrCacheResultInfo = field(default_factory=RequestOrCacheResultInfo) + + def __post_init__(self): + # self.URL_Instance = URLClass() + self.credentials = field(default_factory=Credentials) # Credentials(options_=self.options_) + self.address: str = '' # field(default=self.credentials.address) + self.EVRequest_: EVRequest = field(default_factory=EVRequest) # EVRequest(options_=self.options_, session=None) + self.parent_folder = Path(__file__).parent + self.core_file_name = self.file_name + self.file_name = str(Path().absolute() / "output" / self.file_name) + self.current_file_created = "" + self.display() + self.assign_results_to_state() + + if not self.check_api_key_first(): + print_with_failure_style("Api key") + + def assign_results_to_state(self): + """ + save result stats to state + to finally access from bfs + """ + current_state.set_result_dict(str(id(self.bfs)), self.request_or_cache_resultInfo_) + + def report(self): + m_cache.report() + ... + + def display(self, *args): + # global number + # number += 1 + items_series = (x.ID for x in self.series_.series_list) + dec = f""" +---------------------------------------- + Order item from '{default_series_file_name}' + Details : + bfs : {self.bfs} +___________________ + filename: {self.core_file_name} + subject : {self.subject} + series : + {", ".join(items_series)} + +---------------------------------------- +""" + print(dec) + return dec + + def check_api_key_first(self): + # TODO ApikeyClass().get_valid_api_key() + if not self.EVRequest_: + self.EVRequest_ = EVRequest(options_=load_options(), + session=None, + proxy=None, + args=Args(()) + ) + + try: + if ApikeyClass().get_valid_api_key(): + # self.EVRequest_.check_any_apikey() + return True + except ApiKeyNotSetError: + return False + + def create_url(self): + api_key = ApikeyClass().get_valid_api_key() + if not config.current_mode_is_test: + assert api_key is not False, "api_key is False " + self.complete_url_instance: URLClass = self.series_.complete_url_instance + self.request_or_cache_resultInfo_.url_instance = self.series_.complete_url_instance + self.complete_url_instance.refresh_url() + + self.request_or_cache_resultInfo_.safe_url = f"{self.complete_url_instance.create_report()}" + will_be_requested: Tuple = ( + self.complete_url_instance.url, + self.complete_url_instance.url_only_required, + ) + return will_be_requested + + def get_json(self, url: str): + """ Not implemented """ + raise NotImplementedError + # return self.EVRequest_.get_request_before_cache(f"{url}&type=json").json() + + def get_csv(self, url: str): + + if not hasattr(self.EVRequest_, 'URL_Instance'): + self.EVRequest_ = EVRequest(options_=load_options()) + self.EVRequest_.URL_Instance = URLClass() + + self.EVRequest_.URL_Instance = self.complete_url_instance + result = self.EVRequest_.get_request_before_cache(f"{url}&type=csv") + if hasattr(result, "text"): + self.csv = result.text + return result.text + + return False + + @staticmethod + def extract_values_from_line(line: str, sep=","): + return line.split(sep) + + @staticmethod + def line_gen(buffer: str): + if not buffer: + return False + for item in buffer.split("\n"): + yield item + + # @staticmethod + def get_columns_from_first_row(self): + first_row = self.csv.split("\n")[0].split(",") + return first_row + + def get_columns(self, df): + current_columns = df.columns # rangeIndex + if isinstance(current_columns, pd.RangeIndex): + current_columns_len = len([x for x in current_columns]) + else: + current_columns_len = len(current_columns) + potential_columns = self.get_columns_from_first_row() + if len(potential_columns) != current_columns_len: + raise DfColumnsDoesNotMatch() + df.columns = self.get_columns_from_first_row() + self.request_or_cache_resultInfo_.columns = df.columns + UnixTime = 'UNIXTIME' + if UnixTime in df.columns: + df.drop(UnixTime, axis=1, inplace=True) + if config.current_mode_is_test: + self.save_excel("testpytest2.xlsx") + return df + + @staticmethod + def list_to_df(items): + return pd.DataFrame(items) + + def make_df_float(self): + + def check_cols(x: str): + items = ( + "Tarih" not in x, + "WEEK" not in x, + "DAY" not in x, + ) + return all(items) + + columns = (x for x in self.df.columns if check_cols(x)) + other_cols = (x for x in self.df.columns if not check_cols(x)) + old_df = self.df + try: + self.df = self.df[columns].astype(float) + for other_column in other_cols: + self.df[other_column] = old_df[other_column] + except: + print_with_failure_style("Could not convert some columns to float type...") + + def convert_csv_df(self, csv_buffer: str): + if not csv_buffer: + return False + pd_rows = list( + map(self.extract_values_from_line, + (item for item in self.line_gen(csv_buffer)) + ) + ) + pd_rows.pop(0) + self.df_no_columns = self.list_to_df(pd_rows) + try: + self.df = self.get_columns(self.df_no_columns) + except DfColumnsDoesNotMatch: + print_with_failure_style("columns did not match returning df with no columns...") + self.df = self.df_no_columns + print(self.df.head()) + filename = "error_" + str(id(self.df)) + ".xlsx" + # self.df.to_excel(filename) + print_with_info_style("error: requested URL does not fit...") + time.sleep(1) + return False + except Exception as e: + print_with_failure_style(e) + pass + self.make_df_float() + + return self.df + + @property + def got_items(self): + if not self.check_api_key_first(): + return False + self.df_checked = True + return self.get_items_csv() + + def get_items_csv(self): + will_be_requested = self.create_url() + for item in will_be_requested: + try: + df = self.convert_csv_df(self.get_csv(item)) + except DfColumnsDoesNotMatch: + continue + except Internal: + continue + if isinstance(df, pd.DataFrame): + return df + return False + + def get_items_json(self): + """not implemented""" + # return self.convert_csv_df(self.get_json(self.create_url())) + + def save_excel(self, file_name=None): + deb("not writing... evds_files. 175") + return True + + +# ---------------------------------------------------------- / EvdsSorgu +# ------------------------------------------------------------------------------ +# /* +# EvdsSorguSeries +# +# ------------------------------------------------------------------------------ +# */ +@dataclass +class EvdsSorguSeries(EvdsSorgu): + """ Seriler için """ + + def summary(self): + if not self.check_api_key_first(): + return False + self.df = self.got_items + if not isinstance(self.df, pd.DataFrame): + return False + # print(self.df.head()) + return self.df.head() + + def save_excel(self, file_name=None): + if not self.df_checked: + self.df = self.got_items + file_name = self.bfs.xls_name_path + try: + os.makedirs(self.bfs.abs_path) + except: + pass + # assert file_name == "ttt" + if not isinstance(self.df, pd.DataFrame): + print_with_failure_style("df was not created") + self.request_or_cache_resultInfo_.excel_saved = False + return + self.ExcelSaveClass_ = ExcelSaveClass(self.df, file_name) + self.ExcelSaveClass_.save_excel__() + self.request_or_cache_resultInfo_.excel_saved = True + return True + + +# ---------------------------------------------------------- / EvdsSorguSeries +__all__ = [ + 'EvdsSorguSeries', + 'EvdsSorgu', +] diff --git a/evdspy/EVDSlocal/components/evds_seri_files.py b/evdspy/EVDSlocal/components/evds_seri_files.py index a493246..937ef32 100644 --- a/evdspy/EVDSlocal/components/evds_seri_files.py +++ b/evdspy/EVDSlocal/components/evds_seri_files.py @@ -1,138 +1,138 @@ -from ..common.common_imports import * -from ..common.files import * -from dataclasses import dataclass -import os -from pathlib import Path -from evdspy.EVDSlocal.messages.error_classes import BucketFromSeriesFolderCreateError -from evdspy.EVDSlocal.config.config import * -from ..config.apikey_class import ApikeyClass -from ..initial.start_args import Args -from ..components.options_class import Options, load_options, SingletonOptions, read_user_options_on_load -from evdspy.EVDSlocal.initial.start_options import default_data_folder_name, Default_Prefix_ -from evdspy.EVDSlocal.components.bucket_from_series import BucketFromSeriesFile, null_BucketFromSeriesFile -from evdspy.EVDSlocal.components.url_class import URLClass -from evdspy.EVDSlocal.components.api_params import Series, DateStart, DateEnd, dataTypeParam, dataTypeEnum -from typing import Tuple, Union, List -from rich import inspect - - -# ------------------------------------------------------------------------------ -# -------------------------------------------------EvdsSeri---------------------- -@dataclass -class EvdsSeri: - """ - EvdsSeri - """ - ID: str - bfs: BucketFromSeriesFile - name: str = "" - subject: str = "" - - def __repr__(self): - content = f""" - - ID : {self.ID} - name : {self.name} - subject : {self.subject} - bfs : {self.bfs} - -""" - # print(content) - return content - - -# ---------------------------------------------------------- / EvdsSeri -liste = ('TP.IHRACATBEC.9999', 'TP.IHRACATBEC.31', 'TP.IHRACATBEC.41') -seri_evds_test_objs = tuple(EvdsSeri(x, bfs=null_BucketFromSeriesFile) for x in liste) - - -# ------------------------------------------------------------------------------ -# /* -# EvdsSeriesRequest -# -# ------------------------------------------------------------------------------ -# */ -@dataclass -class EvdsSeriesRequest: - bfs: BucketFromSeriesFile - options_: Optional[Options] = load_options() - # series_list: field(default_factory=list) = field(default_factory=list[seri_evds_test_objs]) - series_list: field(default_factory=list) = tuple(seri_evds_test_objs) - complete_url_instance: URLClass = None - - def __post_init__(self): - read_user_options_on_load() - self.start_date: str = SingletonOptions().get_valid_value("default_start_date") - self.end_date: str = SingletonOptions().get_valid_value("default_end_date") - self.update_url_instance() - - def update_url_instance(self): - """_summary_ - update_url_instance - """ - - date_start: DateStart = DateStart(value=self.start_date) - date_end: DateEnd = DateEnd(value=self.end_date) - type_param = dataTypeParam(value=dataTypeEnum.csv) - - slist: Tuple[str] = tuple(x.ID for x in self.series_list) - series_instance = Series(slist) - full_list = [series_instance, date_start, date_end, type_param] - - complete_url_instance = URLClass(full_list) - - number_of_series = len(slist) - # ADD other params from file - complete_url_instance.add_formulas(self.bfs.formulas, number_of_series) - complete_url_instance.add_frequency(self.bfs.frequency) - complete_url_instance.add_aggtype(self.bfs.aggregateType, number_of_series) - api_key = ApikeyClass().get_valid_api_key() - complete_url_instance.add_apikey(api_key) - self.complete_url_instance = URLClass(complete_url_instance.url_items) - self.complete_url_instance.refresh_url() - self.complete_url_instance.create_report() - - -# ---------------------------------------------------------- / EvdsSeriesRequest -test_series_ = EvdsSeriesRequest(options_=load_options(), series_list=seri_evds_test_objs, - bfs=null_BucketFromSeriesFile) -# ------------------------------------------------------------------------------ -# /* -# EvdsSeriesRequestWrapper(s) -# -# ------------------------------------------------------------------------------ -# */ -from abc import ABC, abstractmethod - - -@dataclass -class EvdsSeriesRequestWrapper(): - name: str - subject: str - EvdsSeriesRequest_: EvdsSeriesRequest - bfs: BucketFromSeriesFile = None # field(default=null_BucketFromSeriesFile) - - # bfs: BucketFromSeriesFile = null_BucketFromSeriesFile - - def __post_init__(self): - self.EvdsSeriesRequest_.bfs = self.bfs - - -def EvdsSeriesRequestWrapperBasic(name: str, subject: str, EvdsSeriesRequest_: EvdsSeriesRequest): - bfs = BucketFromSeriesFile(name, subject, prefix=Default_Prefix_) - return EvdsSeriesRequestWrapper(name, subject, EvdsSeriesRequest_, bfs) - - -def EvdsSeriesRequestWrapperFromFile(bfs: BucketFromSeriesFile, EvdsSeriesRequest_: EvdsSeriesRequest): - return EvdsSeriesRequestWrapper(bfs.subject, bfs.subject, EvdsSeriesRequest_, bfs) - - -# ---------------------------------------------------------- / EvdsSeriesRequestWrapper -__all__ = [ - 'EvdsSeriesRequest', - 'test_series_', - 'EvdsSeri', - 'EvdsSeriesRequestWrapper', - 'EvdsSeriesRequestWrapperFromFile', - 'EvdsSeriesRequestWrapperBasic', -] +from ..common.common_imports import * +from ..common.files import * +from dataclasses import dataclass +import os +from pathlib import Path +from evdspy.EVDSlocal.messages.error_classes import BucketFromSeriesFolderCreateError +from evdspy.EVDSlocal.config.config import * +from ..config.apikey_class import ApikeyClass +from ..initial.start_args import Args +from ..components.options_class import Options, load_options, SingletonOptions, read_user_options_on_load +from evdspy.EVDSlocal.initial.start_options import default_data_folder_name, Default_Prefix_ +from evdspy.EVDSlocal.components.bucket_from_series import BucketFromSeriesFile, null_BucketFromSeriesFile +from evdspy.EVDSlocal.components.url_class import URLClass +from evdspy.EVDSlocal.components.api_params import Series, DateStart, DateEnd, dataTypeParam, dataTypeEnum +from typing import Tuple, Union, List +from rich import inspect + + +# ------------------------------------------------------------------------------ +# -------------------------------------------------EvdsSeri---------------------- +@dataclass +class EvdsSeri: + """ + EvdsSeri + """ + ID: str + bfs: BucketFromSeriesFile + name: str = "" + subject: str = "" + + def __repr__(self): + content = f""" + + ID : {self.ID} + name : {self.name} + subject : {self.subject} + bfs : {self.bfs} + +""" + # print(content) + return content + + +# ---------------------------------------------------------- / EvdsSeri +liste = ('TP.IHRACATBEC.9999', 'TP.IHRACATBEC.31', 'TP.IHRACATBEC.41') +seri_evds_test_objs = tuple(EvdsSeri(x, bfs=null_BucketFromSeriesFile) for x in liste) + + +# ------------------------------------------------------------------------------ +# /* +# EvdsSeriesRequest +# +# ------------------------------------------------------------------------------ +# */ +@dataclass +class EvdsSeriesRequest: + bfs: BucketFromSeriesFile + options_: Optional[Options] = load_options() + # series_list: field(default_factory=list) = field(default_factory=list[seri_evds_test_objs]) + series_list: field(default_factory=list) = tuple(seri_evds_test_objs) + complete_url_instance: URLClass = None + + def __post_init__(self): + read_user_options_on_load() + self.start_date: str = SingletonOptions().get_valid_value("default_start_date") + self.end_date: str = SingletonOptions().get_valid_value("default_end_date") + self.update_url_instance() + + def update_url_instance(self): + """_summary_ + update_url_instance + """ + + date_start: DateStart = DateStart(value=self.start_date) + date_end: DateEnd = DateEnd(value=self.end_date) + type_param = dataTypeParam(value=dataTypeEnum.csv) + + slist: Tuple[str] = tuple(x.ID for x in self.series_list) + series_instance = Series(slist) + full_list = [series_instance, date_start, date_end, type_param] + + complete_url_instance = URLClass(full_list) + + number_of_series = len(slist) + # ADD other params from file + complete_url_instance.add_formulas(self.bfs.formulas, number_of_series) + complete_url_instance.add_frequency(self.bfs.frequency) + complete_url_instance.add_aggtype(self.bfs.aggregateType, number_of_series) + api_key = ApikeyClass().get_valid_api_key() + complete_url_instance.add_apikey(api_key) + self.complete_url_instance = URLClass(complete_url_instance.url_items) + self.complete_url_instance.refresh_url() + self.complete_url_instance.create_report() + + +# ---------------------------------------------------------- / EvdsSeriesRequest +test_series_ = EvdsSeriesRequest(options_=load_options(), series_list=seri_evds_test_objs, + bfs=null_BucketFromSeriesFile) +# ------------------------------------------------------------------------------ +# /* +# EvdsSeriesRequestWrapper(s) +# +# ------------------------------------------------------------------------------ +# */ +from abc import ABC, abstractmethod + + +@dataclass +class EvdsSeriesRequestWrapper(): + name: str + subject: str + EvdsSeriesRequest_: EvdsSeriesRequest + bfs: BucketFromSeriesFile = None # field(default=null_BucketFromSeriesFile) + + # bfs: BucketFromSeriesFile = null_BucketFromSeriesFile + + def __post_init__(self): + self.EvdsSeriesRequest_.bfs = self.bfs + + +def EvdsSeriesRequestWrapperBasic(name: str, subject: str, EvdsSeriesRequest_: EvdsSeriesRequest): + bfs = BucketFromSeriesFile(name, subject, prefix=Default_Prefix_) + return EvdsSeriesRequestWrapper(name, subject, EvdsSeriesRequest_, bfs) + + +def EvdsSeriesRequestWrapperFromFile(bfs: BucketFromSeriesFile, EvdsSeriesRequest_: EvdsSeriesRequest): + return EvdsSeriesRequestWrapper(bfs.subject, bfs.subject, EvdsSeriesRequest_, bfs) + + +# ---------------------------------------------------------- / EvdsSeriesRequestWrapper +__all__ = [ + 'EvdsSeriesRequest', + 'test_series_', + 'EvdsSeri', + 'EvdsSeriesRequestWrapper', + 'EvdsSeriesRequestWrapperFromFile', + 'EvdsSeriesRequestWrapperBasic', +] diff --git a/evdspy/EVDSlocal/components/excel_class.py b/evdspy/EVDSlocal/components/excel_class.py index dfeb9cc..53ec197 100644 --- a/evdspy/EVDSlocal/components/excel_class.py +++ b/evdspy/EVDSlocal/components/excel_class.py @@ -1,51 +1,93 @@ -# ---------------------------------------------------------- ExcelSaveClass -from dataclasses import dataclass -import pandas as pd - -from evdspy.EVDSlocal.common.colors import print_with_creating_style, print_with_failure_style, \ - print_excel_created_style -from evdspy.EVDSlocal.utils.utils_general import * -from typing import List -from evdspy.EVDSlocal.common.common_imports import * -@dataclass -class ExcelSaveClass(): - df: pd.DataFrame - file_name: str - excel_out_ext: str = "xlsx" - def out_name_format(self, name): - return f"{name}.{self.excel_out_ext}" - def save_with_name(self): - self.current_file_created = self.out_name_format(self.file_name) - self.df.to_excel(self.current_file_created) - return True - def save_with_diff_name(self): - h = get_random_hash(5) - self.current_file_created = self.out_name_format(f"{self.file_name}-{h}") - self.df.to_excel(self.current_file_created) - return True - def try_in_order(self, f_list: List[callable]): - for index, f in enumerate(f_list): - result = self.try_this(f) - if result: - return index, result - return -1, False - def try_this(self, f): - try: - f() - return True - except Exception as exc: - print(exc) - return False - def save_excel__(self): - index, result = self.try_in_order( - [ - self.save_with_name, - self.save_with_diff_name - ] - ) - if index > -1: - print_excel_created_style(f"\n{indent}{self.current_file_created} was created...") - return True - print_with_failure_style(f"File {self.current_file_created} not created...\n\n\n") - return False -# ---------------------------------------------------------- / ExcelSaveClass +# ---------------------------------------------------------- ExcelSaveClass +from dataclasses import dataclass +import pandas as pd + +from evdspy.EVDSlocal.common.colors import print_with_creating_style, print_with_failure_style, \ + print_excel_created_style +from evdspy.EVDSlocal.utils.utils_general import * +from typing import List +from evdspy.EVDSlocal.common.common_imports import * + + +def replace_all(name, char, nchar): + if not char in name: + return name + name = name.replace(char, nchar) + return replace_all(name, char, nchar) + + +import time + + +def name_ext_format(name, ext): + if "." + ext in name: + return Path(f"{name}") + return Path(f"{name}.{ext}") + + +def correct_folder(name: str, ext="xlsx"): + name = name.replace('\\', '/') + name = name.replace('//', '/') + + parts = name.split("/") + + if len(parts) == 1: + return name_ext_format(name, ext) + folder = None + for part in parts: + if folder is None: + folder = Path(part) + else: + folder = folder / part + return name_ext_format(name, ext) + + +@dataclass +class ExcelSaveClass: + df: pd.DataFrame + file_name: str + excel_out_ext: str = "xlsx" + + def out_name_format(self, name): + return correct_folder(name, self.excel_out_ext) + # return f"{name}.{self.excel_out_ext}" + + def save_with_name(self): + self.current_file_created = self.out_name_format(self.file_name) + self.df.to_excel(self.current_file_created) + return True + + def save_with_diff_name(self): + h = get_random_hash(5) + self.current_file_created = self.out_name_format(f"{self.file_name}-{h}") + self.df.to_excel(self.current_file_created) + return True + + def try_in_order(self, f_list: List[callable]): + for index, f in enumerate(f_list): + result = self.try_this(f) + if result: + return index, result + return -1, False + + def try_this(self, f): + try: + f() + return True + except Exception as exc: + print(exc) + return False + + def save_excel__(self): + index, result = self.try_in_order( + [ + self.save_with_name, + self.save_with_diff_name + ] + ) + if index > -1: + print_excel_created_style(f"\n{indent}==>{self.current_file_created} was created...") + return True + print_with_failure_style(f"File {self.current_file_created} not created...\n\n\n") + return False +# ---------------------------------------------------------- / ExcelSaveClass diff --git a/evdspy/EVDSlocal/components/options_class.py b/evdspy/EVDSlocal/components/options_class.py index dd2a836..dc29d51 100644 --- a/evdspy/EVDSlocal/components/options_class.py +++ b/evdspy/EVDSlocal/components/options_class.py @@ -1,236 +1,236 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -from dataclasses import dataclass - -""" -Usage : - - SingletonOptions().set("default_start_date_user", "UserStartDate") - SingletonOptions().set("default_end_date_user", "UserEndDate") - SingletonOptions().set("default_cache_user", "UserCache") - - - SingletonOptions().get_valid_value("default_cache") - SingletonOptions().get_valid_value("default_start_date") - SingletonOptions().get_valid_value("default_end_date") - SingletonOptions().get_valid_value("Avoid_Absolute_Paths") - - - -""" - -if "__main__" == __name__: - if True: - default_series_file_name = "config_series.cfg" - default_data_folder_name = "SeriesData" - Avoid_Absolute_Paths_ = True - Default_Prefix_ = "EVPY_" - # options_folder_name = r"IO" - DEBUG_LOG_CANCEL = False - DEGUB_NOTICE = True - DEBUG_PRINT = False - - default_cache = "daily" # nocache / hourly - default_end_date = "01-12-2030" - default_start_date = "01-01-2019" - import os - # USERNAME = os.getenv("USERNAME") # or hard coded "Username" -else: - - from ..config.config import * - from ..initial.start_options import * - -from typing import Union, List - - -class Options: - - def __init__(self, - default_start_date: str, - default_start_date_user: Union[str, None], - default_end_date: str, - default_end_date_user, - default_cache: str, - default_cache_user: str, - avoid_absolute_paths: bool = True, - avoid_absolute_paths_user: bool = True, - - ): - self.default_start_date = default_start_date - self.default_start_date_user = default_start_date_user - self.default_end_date = default_end_date - self.default_end_date_user = default_end_date_user - self.default_cache = default_cache - self.default_cache_user = default_cache_user - self.avoid_absolute_paths = avoid_absolute_paths - self.avoid_absolute_paths_user = avoid_absolute_paths_user - - -# @dataclass -# class Options_old: -# default_start_date: str -# default_start_date_user: Union[str, None] -# default_end_date: str -# default_end_date_user: Union[str, None] -# default_cache: str -# default_cache_user: Union[str, None] -# avoid_absolute_paths: bool = True -# avoid_absolute_paths_user: bool = True - - -from pathlib import Path - - -def load_options(): - options_ = Options( - default_start_date=default_start_date, - default_start_date_user=None, - default_end_date=default_end_date, - default_end_date_user=None, - default_cache=default_cache, - default_cache_user=None, - avoid_absolute_paths=True, - avoid_absolute_paths_user=True - ) - return options_ - - -class SingletonOptions(object): - def __new__(cls): - if not hasattr(cls, 'instance'): - cls.instance = super(SingletonOptions, cls).__new__(cls) - cls.post_init(cls) - return cls.instance - - def post_init(cls): - cls.options_ = load_options() - # read_user_options_on_load() - - def check(cls): - disp_message = f""" - default_cache : {cls.options_.default_cache} - default_cache (User) : {cls.options_.default_cache_user} - default start date : {cls.options_.default_start_date} - default start (User) : {cls.options_.default_start_date_user} - default end date : {cls.options_.default_end_date} - default end date (User) : {cls.options_.default_end_date_user} - Avoid Absolute Paths : {cls.options_.avoid_absolute_paths} - Avoid Absolute Paths (User) : {cls.options_.avoid_absolute_paths_user} - -""" - return disp_message - - def getitem(cls, attr, default_value=None): - value = getattr(cls.options_, attr, default_value) - - return value - - def set(cls, attr, value): - setattr(cls.options_, attr, value) - - def __str__(self): - # print(self.options_.__dict__) - - return str(self.options_.__dict__) - - def display(self): - return str(self) - # cls.options_.(attr) = cls.options_.metadata.( attr) - - def get_valid_value(self, attr: str): - """ """ - user_preferred_value_or_default: str = self.getitem(f"{attr}_user", None) - if not user_preferred_value_or_default: - user_preferred_value_or_default = self.getitem(f"{attr}", None) - return user_preferred_value_or_default - - -from evdspy.EVDSlocal.common.files import Read, Write - -notsetyet = "not set yet OptionsClassfile" - - -class NotSetYet: - - def __str__(self): - return "not set yet" - - def __eq__(self, other): - return False - - def __and__(self, other): - return False - - def __bool__(self): - return False - - -def read_user_options_on_load(): - """below this file it will be called""" - opts = SingletonOptions() - file_name = "options.cfg" - if not Path(file_name).is_file(): - print(Path(file_name)) - cls = SingletonOptions() - SingletonOptions().set("default_cache_user", cls.options_.default_cache) - SingletonOptions().set("default_start_date_user", cls.options_.default_start_date) - SingletonOptions().set("default_end_date_user", cls.options_.default_end_date) - SingletonOptions().set("avoid_absolute_paths_user", cls.options_.avoid_absolute_paths_user) - - # raise "file" - print("user options file was not found. Program will continue with default options...") - return - - def read_options_file(): - cont = Read(file_name, "could not read ") - lines = [x for x in cont.splitlines() if not x.strip().startswith("#")] - lines = [x.split("#")[0] for x in lines] - return tuple(lines) - - def get_item_from_content(lines: tuple, item: str = None): - if item is None: - return None - for line in lines: - if item in line and ":" in line and line.split(":")[0].strip() == item: - return line.split(":")[1].strip() - return NotSetYet() - - lines = read_options_file() - default_cache_user = get_item_from_content(lines, "cache_freq") - default_start_date_user = get_item_from_content(lines, "gl_date_start") - default_end_date_user = get_item_from_content(lines, "gl_date_end") - default_Avoid_Absolute_Paths_user_string = str(get_item_from_content(lines, "avoid_absolute_paths")) - - default_avoid_absolute_paths_user = NotSetYet() - # default_avoid_absolute_paths_user = NotSetYet() # 'Not set yet' - if default_Avoid_Absolute_Paths_user_string.strip().lower() == "false": - default_avoid_absolute_paths_user = False - if default_Avoid_Absolute_Paths_user_string.strip().lower() == "true": - default_avoid_absolute_paths_user = True - SingletonOptions().set("default_cache_user", default_cache_user) - SingletonOptions().set("default_start_date_user", default_start_date_user) - SingletonOptions().set("default_end_date_user", default_end_date_user) - SingletonOptions().set("avoid_absolute_paths_user", default_avoid_absolute_paths_user) - - -def notest(): - a1 = SingletonOptions() - print(a1.display()) - - a2 = SingletonOptions() - a2.options_.default_cache = "smt else " - print(a1.display()) - print(a2.display()) - a3 = SingletonOptions() - print(a3.display()) - a3.set("default_start_date", "1212asd54") - print(a3.display()) - print(a3.get_valid_value("default_start_date")) - print(a3.get_valid_value("default_cache")) - - -# notest() - - -read_user_options_on_load() +#!/usr/bin/python +# -*- coding: utf-8 -*- + +from dataclasses import dataclass + +""" +Usage : + + SingletonOptions().set("default_start_date_user", "UserStartDate") + SingletonOptions().set("default_end_date_user", "UserEndDate") + SingletonOptions().set("default_cache_user", "UserCache") + + + SingletonOptions().get_valid_value("default_cache") + SingletonOptions().get_valid_value("default_start_date") + SingletonOptions().get_valid_value("default_end_date") + SingletonOptions().get_valid_value("Avoid_Absolute_Paths") + + + +""" + +if "__main__" == __name__: + if True: + default_series_file_name = "config_series.cfg" + default_data_folder_name = "SeriesData" + Avoid_Absolute_Paths_ = True + Default_Prefix_ = "EVPY_" + # options_folder_name = r"IO" + DEBUG_LOG_CANCEL = False + DEGUB_NOTICE = True + DEBUG_PRINT = False + + default_cache = "daily" # nocache / hourly + default_end_date = "01-12-2030" + default_start_date = "01-01-2019" + import os + # USERNAME = os.getenv("USERNAME") # or hard coded "Username" +else: + + from ..config.config import * + from ..initial.start_options import * + +from typing import Union, List + + +class Options: + + def __init__(self, + default_start_date: str, + default_start_date_user: Union[str, None], + default_end_date: str, + default_end_date_user, + default_cache: str, + default_cache_user: str, + avoid_absolute_paths: bool = True, + avoid_absolute_paths_user: bool = True, + + ): + self.default_start_date = default_start_date + self.default_start_date_user = default_start_date_user + self.default_end_date = default_end_date + self.default_end_date_user = default_end_date_user + self.default_cache = default_cache + self.default_cache_user = default_cache_user + self.avoid_absolute_paths = avoid_absolute_paths + self.avoid_absolute_paths_user = avoid_absolute_paths_user + + +# @dataclass +# class Options_old: +# default_start_date: str +# default_start_date_user: Union[str, None] +# default_end_date: str +# default_end_date_user: Union[str, None] +# default_cache: str +# default_cache_user: Union[str, None] +# avoid_absolute_paths: bool = True +# avoid_absolute_paths_user: bool = True + + +from pathlib import Path + + +def load_options(): + options_ = Options( + default_start_date=default_start_date, + default_start_date_user=None, + default_end_date=default_end_date, + default_end_date_user=None, + default_cache=default_cache, + default_cache_user=None, + avoid_absolute_paths=True, + avoid_absolute_paths_user=True + ) + return options_ + + +class SingletonOptions(object): + def __new__(cls): + if not hasattr(cls, 'instance'): + cls.instance = super(SingletonOptions, cls).__new__(cls) + cls.post_init(cls) + return cls.instance + + def post_init(cls): + cls.options_ = load_options() + # read_user_options_on_load() + + def check(cls): + disp_message = f""" + default_cache : {cls.options_.default_cache} + default_cache (User) : {cls.options_.default_cache_user} + default start date : {cls.options_.default_start_date} + default start (User) : {cls.options_.default_start_date_user} + default end date : {cls.options_.default_end_date} + default end date (User) : {cls.options_.default_end_date_user} + Avoid Absolute Paths : {cls.options_.avoid_absolute_paths} + Avoid Absolute Paths (User) : {cls.options_.avoid_absolute_paths_user} + +""" + return disp_message + + def getitem(cls, attr, default_value=None): + value = getattr(cls.options_, attr, default_value) + + return value + + def set(cls, attr, value): + setattr(cls.options_, attr, value) + + def __str__(self): + # print(self.options_.__dict__) + + return str(self.options_.__dict__) + + def display(self): + return str(self) + # cls.options_.(attr) = cls.options_.metadata.( attr) + + def get_valid_value(self, attr: str): + """ """ + user_preferred_value_or_default: str = self.getitem(f"{attr}_user", None) + if not user_preferred_value_or_default: + user_preferred_value_or_default = self.getitem(f"{attr}", None) + return user_preferred_value_or_default + + +from evdspy.EVDSlocal.common.files import Read, Write + +notsetyet = "not set yet OptionsClassfile" + + +class NotSetYet: + + def __str__(self): + return "not set yet" + + def __eq__(self, other): + return False + + def __and__(self, other): + return False + + def __bool__(self): + return False + + +def read_user_options_on_load(): + """below this file it will be called""" + opts = SingletonOptions() + file_name = "options.cfg" + if not Path(file_name).is_file(): + print(Path(file_name)) + cls = SingletonOptions() + SingletonOptions().set("default_cache_user", cls.options_.default_cache) + SingletonOptions().set("default_start_date_user", cls.options_.default_start_date) + SingletonOptions().set("default_end_date_user", cls.options_.default_end_date) + SingletonOptions().set("avoid_absolute_paths_user", cls.options_.avoid_absolute_paths_user) + + # raise "file" + print("user options file was not found. Program will continue with default options...") + return + + def read_options_file(): + cont = Read(file_name, "could not read ") + lines = [x for x in cont.splitlines() if not x.strip().startswith("#")] + lines = [x.split("#")[0] for x in lines] + return tuple(lines) + + def get_item_from_content(lines: tuple, item: str = None): + if item is None: + return None + for line in lines: + if item in line and ":" in line and line.split(":")[0].strip() == item: + return line.split(":")[1].strip() + return NotSetYet() + + lines = read_options_file() + default_cache_user = get_item_from_content(lines, "cache_freq") + default_start_date_user = get_item_from_content(lines, "gl_date_start") + default_end_date_user = get_item_from_content(lines, "gl_date_end") + default_Avoid_Absolute_Paths_user_string = str(get_item_from_content(lines, "avoid_absolute_paths")) + + default_avoid_absolute_paths_user = NotSetYet() + # default_avoid_absolute_paths_user = NotSetYet() # 'Not set yet' + if default_Avoid_Absolute_Paths_user_string.strip().lower() == "false": + default_avoid_absolute_paths_user = False + if default_Avoid_Absolute_Paths_user_string.strip().lower() == "true": + default_avoid_absolute_paths_user = True + SingletonOptions().set("default_cache_user", default_cache_user) + SingletonOptions().set("default_start_date_user", default_start_date_user) + SingletonOptions().set("default_end_date_user", default_end_date_user) + SingletonOptions().set("avoid_absolute_paths_user", default_avoid_absolute_paths_user) + + +def notest(): + a1 = SingletonOptions() + print(a1.display()) + + a2 = SingletonOptions() + a2.options_.default_cache = "smt else " + print(a1.display()) + print(a2.display()) + a3 = SingletonOptions() + print(a3.display()) + a3.set("default_start_date", "1212asd54") + print(a3.display()) + print(a3.get_valid_value("default_start_date")) + print(a3.get_valid_value("default_cache")) + + +# notest() + + +read_user_options_on_load() diff --git a/evdspy/EVDSlocal/components/request_or_cache.py b/evdspy/EVDSlocal/components/request_or_cache.py index c579345..620f7eb 100644 --- a/evdspy/EVDSlocal/components/request_or_cache.py +++ b/evdspy/EVDSlocal/components/request_or_cache.py @@ -1,53 +1,53 @@ -from dataclasses import dataclass, field -from enum import Enum -from evdspy.EVDSlocal.components.url_class import URLClass - - -class RequestType(Enum): - Request = "request" - Cache = "cache" - - -class RequestOrCacheResultInfo(): - safe_url: str = "" - request_type: RequestType - columns: tuple - excel_saved: bool - url_instance: URLClass - - def __init__(self, safe_url='', request_type=RequestType.Request, columns=(), excel_saved=False, url_instance=None): - self.safe_url = safe_url - if request_type is None: - request_type = RequestType.Request - if url_instance is None: - url_instance: URLClass = field(default_factory=URLClass) # URLClass([]) - - self.request_type = request_type - self.columns = columns - self.excel_saved = excel_saved - - def get_data(self): - content = f""" -url : {self.safe_url} -request or cache : {self.request_type.value} -columns : {self.columns} -excel file was saved ? : {self.excel_saved} -""" - return content - -# @dataclass -# class RequestOrCacheResultInfo(): -# safe_url: str = "" -# request_type: RequestType = field(default=RequestType.Request) -# columns: field(default_factory=tuple) = field(default_factory=tuple) -# excel_saved: bool = False -# url_instance: URLClass = URLClass(()) -# -# def get_data(self): -# content = f""" -# url : {self.safe_url} -# request or cache : {self.request_type.value} -# columns : {self.columns} -# excel file was saved ? : {self.excel_saved} -# """ -# return content +from dataclasses import dataclass, field +from enum import Enum +from evdspy.EVDSlocal.components.url_class import URLClass + + +class RequestType(Enum): + Request = "request" + Cache = "cache" + + +class RequestOrCacheResultInfo(): + safe_url: str = "" + request_type: RequestType + columns: tuple + excel_saved: bool + url_instance: URLClass + + def __init__(self, safe_url='', request_type=RequestType.Request, columns=(), excel_saved=False, url_instance=None): + self.safe_url = safe_url + if request_type is None: + request_type = RequestType.Request + if url_instance is None: + url_instance: URLClass = field(default_factory=URLClass) # URLClass([]) + + self.request_type = request_type + self.columns = columns + self.excel_saved = excel_saved + + def get_data(self): + content = f""" +url : {self.safe_url} +request or cache : {self.request_type.value} +columns : {self.columns} +excel file was saved ? : {self.excel_saved} +""" + return content + +# @dataclass +# class RequestOrCacheResultInfo(): +# safe_url: str = "" +# request_type: RequestType = field(default=RequestType.Request) +# columns: field(default_factory=tuple) = field(default_factory=tuple) +# excel_saved: bool = False +# url_instance: URLClass = URLClass(()) +# +# def get_data(self): +# content = f""" +# url : {self.safe_url} +# request or cache : {self.request_type.value} +# columns : {self.columns} +# excel file was saved ? : {self.excel_saved} +# """ +# return content diff --git a/evdspy/EVDSlocal/components/url_class.py b/evdspy/EVDSlocal/components/url_class.py index 4a2a46e..2c8609a 100644 --- a/evdspy/EVDSlocal/components/url_class.py +++ b/evdspy/EVDSlocal/components/url_class.py @@ -1,105 +1,107 @@ -from dataclasses import dataclass, field -from typing import List, Tuple, Union -from evdspy.EVDSlocal.components.api_params import UrlParam, convert_list_params_to_str, EVDSApiDomain, Apikey, \ - Frequency, \ - get_enum_with_value, FrequencyEnum, FormulasEnum, Formulas, AggregationEnum, Aggregations -from evdspy.EVDSlocal.components.api_params import * -import typing as t -from enum import Enum -from .api_params_enums import get_enum_with_value -from ..config.apikey_class import ApikeyClass - - -class ApiParamsNotExpectedFormat(BaseException): - """ApiParamsNotExpectedFormat""" - - -@dataclass -class URLClass: - url_items: Union[List[UrlParam], Tuple[UrlParam]] = field(default_factory=list) - url: str = None - url_only_required = None - url_items_required = None - url_report: str = "" - url_explanation: str = "" - domain: str = str(EVDSApiDomain()) - - def __post_init__(self): - self.url_items_required = tuple(x for x in self.url_items if x.required) - self.refresh_url() - - def safe_to_report_url(self, url_parts=None): - if url_parts is None: - url_parts = self.url_items - url_parts = [x for x in url_parts if not x.hidden] - url: str = str(self.domain) + convert_list_params_to_str(url_parts, str) - return url - - def create_report(self, url_parts=None): - if url_parts is None: - url_parts = self.url_items - self.url_report = convert_list_params_to_str(url_parts, "report") - self.url_explanation = convert_list_params_to_str(url_parts, "explanation") - return [self.url_report, self.url_explanation] - - def create_url(self, url_parts: Union[List, Tuple] = None): - """both for required and complete """ - if url_parts is None: - url_parts = self.url_items - url: str = str(self.domain) + convert_list_params_to_str(url_parts, str) - return url - - def refresh_required(self): - self.url_items_required = tuple(x for x in self.url_items if x.required) - - def refresh_url(self): - self.create_url_complete() - self.create_url_required() - # self.create_report() - - def create_url_complete(self): - self.url: str = self.create_url(self.url_items) - - def create_url_required(self): - self.url_only_required: str = self.create_url(self.url_items_required) - - def add_item(self, item: UrlParam) -> None: - - self.url_items = list(self.url_items) + [item] - self.refresh_required() - self.refresh_url() - - def add_frame(self, code_str: str): - self.add_item(DataGroup(code_str)) - self.refresh_url() - - def add_apikey(self, api_key=None): - if api_key is None: - api_key = ApikeyClass().get_valid_api_key() - self.add_item(Apikey(api_key)) - self.refresh_url() - - def add_mode(self, mode_enum: t.Union[Enum, str, int] = 1): - mode_enum = get_enum_with_value(mode_enum, ModeEnumDatagroup, ModeEnumDatagroup.all_groups) - self.add_item(ModeParamDataGroups(mode_enum)) - self.refresh_url() - - def add_code(self, code: t.Union[int, str]): - self.add_item(CodeParamDataGroups(code)) - self.refresh_url() - - def add_frequency(self, frequency: Union[int, str]): - if isinstance(frequency, str): - frequency = int(frequency) - self.add_item(Frequency(get_enum_with_value(frequency, FrequencyEnum))) - self.refresh_url() - - def add_formulas(self, formulas: Union[int, str], number_of_series: int): - if isinstance(formulas, str): - formulas = int(formulas) - self.add_item(Formulas(get_enum_with_value(formulas, FormulasEnum), number_of_repeat=number_of_series)) - self.refresh_url() - - def add_aggtype(self, aggtype: str, number_of_series: int): - self.add_item(Aggregations(get_enum_with_value(aggtype, AggregationEnum), number_of_repeat=number_of_series)) - self.refresh_url() +from dataclasses import dataclass, field +from typing import List, Tuple, Union +from evdspy.EVDSlocal.components.api_params import UrlParam, convert_list_params_to_str, EVDSApiDomain, Apikey, \ + Frequency, \ + get_enum_with_value, FrequencyEnum, FormulasEnum, Formulas, AggregationEnum, Aggregations +from evdspy.EVDSlocal.components.api_params import * +import typing as t +from enum import Enum +from .api_params_enums import get_enum_with_value +from ..config.apikey_class import ApikeyClass + + +class ApiParamsNotExpectedFormat(BaseException): + """ApiParamsNotExpectedFormat""" + + +@dataclass +class URLClass: + url_items: Union[List[UrlParam], Tuple[UrlParam]] = field(default_factory=list) + url: str = None + url_only_required = None + url_items_required = None + url_report: str = "" + url_explanation: str = "" + domain: str = str(EVDSApiDomain()) + + def __post_init__(self): + self.url_items_required = tuple(x for x in self.url_items if x.required) + self.refresh_url() + + def safe_to_report_url(self, url_parts=None): + if url_parts is None: + url_parts = self.url_items + url_parts = [x for x in url_parts if not x.hidden] + url: str = str(self.domain) + convert_list_params_to_str(url_parts, str) + return url + + def create_report(self, url_parts=None): + if url_parts is None: + url_parts = self.url_items + self.url_report = convert_list_params_to_str(url_parts, "report") + self.url_explanation = convert_list_params_to_str(url_parts, "explanation") + return [self.url_report, self.url_explanation] + + def create_url(self, url_parts: Union[List, Tuple] = None): + """both for required and complete """ + if url_parts is None: + url_parts = self.url_items + url: str = str(self.domain) + convert_list_params_to_str(url_parts, str) + return url + + def refresh_required(self): + self.url_items_required = tuple(x for x in self.url_items if x.required) + + def refresh_url(self): + self.create_url_complete() + self.create_url_required() + # self.create_report() + + def create_url_complete(self): + self.url: str = self.create_url(self.url_items) + + def create_url_required(self): + self.url_only_required: str = self.create_url(self.url_items_required) + + def add_item(self, item: UrlParam) -> None: + + self.url_items = list(self.url_items) + [item] + self.refresh_required() + self.refresh_url() + + def add_frame(self, code_str: str): + self.add_item(DataGroup(code_str)) + self.refresh_url() + + def add_apikey(self, api_key=None): + """ Not needed because apikey was moved to header """ + return + # if api_key is None: + # api_key = ApikeyClass().get_valid_api_key() + # self.add_item(Apikey(api_key)) + # self.refresh_url() + + def add_mode(self, mode_enum: t.Union[Enum, str, int] = 1): + mode_enum = get_enum_with_value(mode_enum, ModeEnumDatagroup, ModeEnumDatagroup.all_groups) + self.add_item(ModeParamDataGroups(mode_enum)) + self.refresh_url() + + def add_code(self, code: t.Union[int, str]): + self.add_item(CodeParamDataGroups(code)) + self.refresh_url() + + def add_frequency(self, frequency: Union[int, str]): + if isinstance(frequency, str): + frequency = int(frequency) + self.add_item(Frequency(get_enum_with_value(frequency, FrequencyEnum))) + self.refresh_url() + + def add_formulas(self, formulas: Union[int, str], number_of_series: int): + if isinstance(formulas, str): + formulas = int(formulas) + self.add_item(Formulas(get_enum_with_value(formulas, FormulasEnum), number_of_repeat=number_of_series)) + self.refresh_url() + + def add_aggtype(self, aggtype: str, number_of_series: int): + self.add_item(Aggregations(get_enum_with_value(aggtype, AggregationEnum), number_of_repeat=number_of_series)) + self.refresh_url() diff --git a/evdspy/EVDSlocal/config/apikey_class.py b/evdspy/EVDSlocal/config/apikey_class.py index a5a97b4..90f8f9e 100644 --- a/evdspy/EVDSlocal/config/apikey_class.py +++ b/evdspy/EVDSlocal/config/apikey_class.py @@ -1,122 +1,157 @@ -from ..common.common_imports import * -from dataclasses import dataclass, field -from typing import Union -from enum import Enum, auto -from ..config.config import config - - -class ApiKeyType(Enum): - runtime = auto() - from_file = auto() - from_file_options = auto() - - -@dataclass -class ApiKeyValue: - name: str - value: Union[str, bool] = False - type_: ApiKeyType = ApiKeyType.runtime - - -class ApiKeyDict: - runtime_apikey: ApiKeyValue - from_file_apikey: ApiKeyValue - from_file_options_api_key: ApiKeyValue - - def __init__(self): - self.runtime_apikey = ApiKeyValue("runtime", False, ApiKeyType.runtime) - self.from_file_apikey = ApiKeyValue("fromfile", False, ApiKeyType.from_file) - self.from_file_options_api_key = ApiKeyValue("fromfile_options", False, ApiKeyType.from_file_options) - - def set_value(self, type_: Union[str, ApiKeyType], value): - if type_ in ["runtime", ApiKeyType.runtime]: - self.runtime_apikey.value = value - return - if type_ in ["fromfile", ApiKeyType.from_file]: - self.from_file_apikey.value = value - return - self.from_file_options_api_key = value - - -# @dataclass(frozen=False) -# class ApiKeyDict_old: -# runtime_apikey: ApiKeyValue = field(default=ApiKeyValue("runtime", False, ApiKeyType.runtime)) -# from_file_apikey: ApiKeyValue = field(default=ApiKeyValue("fromfile", False, ApiKeyType.from_file)) -# from_file_options_api_key: ApiKeyValue = field( -# default=ApiKeyValue("fromfile_options", False, ApiKeyType.from_file_options)) -# -# def set_value(self, type_: Union[str, ApiKeyType], value): -# if type_ in ["runtime", ApiKeyType.runtime]: -# self.runtime_apikey.value = value -# return -# if type_ in ["fromfile", ApiKeyType.from_file]: -# self.from_file_apikey.value = value -# return -# self.from_file_options_api_key = value - - -class ApikeyClass(object): - def __new__(cls): - if not hasattr(cls, 'instance'): - cls.instance = super(ApikeyClass, cls).__new__(cls) - cls.post_init(cls) - return cls.instance - - def __repr__(cls): - return f""" - cls.now_testing_is_key_is_valid: {cls.now_testing_is_key_is_valid:} - cls.current_key_using : {cls.current_key_using} - cls.APIKEYDict : {cls.APIKEYDict} -""" - - def post_init(cls): - - cls.APIKEYDict: ApiKeyDict = ApiKeyDict() - cls.now_testing_is_key_is_valid: Union[str, bool] = False - cls.current_key_using: Union[str, bool] = cls.APIKEYDict.runtime_apikey.value - - def get_valid_api_key(cls): - - if config.current_mode_is_test: - return "VALID_KEY_FOR_TEST" - - if cls.now_testing_is_key_is_valid: - return cls.now_testing_is_key_is_valid - - key_objs = cls.get_api_keys() - if not key_objs: - return False - return key_objs[0].value - - def set_api_key_runtime(cls, value: str): - cls.instance.APIKEYDict.set_value(ApiKeyType.runtime, value) - return cls.instance.APIKEYDict.runtime_apikey.value - - def set_api_key_filetype(cls, value: str): - cls.instance.APIKEYDict.set_value(ApiKeyType.from_file, value) - - return cls.instance.APIKEYDict.from_file_apikey.value - - def set_api(cls, key: str): - print("set api not implemented") - raise "set api not implemented" - - def get_api_keys(cls): - keys = [ - cls.instance.APIKEYDict.runtime_apikey, - cls.instance.APIKEYDict.from_file_apikey, - cls.instance.APIKEYDict.from_file_options_api_key, - ] - return [x for x in keys if x.value is not False] - - def get_api_keys_dict(cls): - return cls.instance.APIKEYDict - - def get_api_key_runtime(cls): - return cls.instance.APIKEYDict.runtime_apikey.value - - def get_api_key_fromfile(cls): - return cls.instance.APIKEYDict.from_file_apikey.value - - def get_api_key_fromfile_options(cls): - return cls.instance.APIKEYDict.from_file_options_api_key +from ..common.common_imports import * +from dataclasses import dataclass, field +from typing import Union +from enum import Enum, auto +from ..config.config import config +from ..messages.error_classes import ApiKeyNotSetError + + +class ApiKeyType(Enum): + runtime = auto() + from_file = auto() + from_file_options = auto() + + +@dataclass +class ApiKeyValue: + name: str + value: Union[str, bool] = False + type_: ApiKeyType = ApiKeyType.runtime + + +class ApiKeyDict: + runtime_apikey: ApiKeyValue + from_file_apikey: ApiKeyValue + from_file_options_api_key: ApiKeyValue + + def __init__(self): + self.runtime_apikey = ApiKeyValue("runtime", False, ApiKeyType.runtime) + self.from_file_apikey = ApiKeyValue("fromfile", False, ApiKeyType.from_file) + self.from_file_options_api_key = ApiKeyValue("fromfile_options", False, ApiKeyType.from_file_options) + + def set_value(self, type_: Union[str, ApiKeyType], value): + if type_ in ["runtime", ApiKeyType.runtime]: + self.runtime_apikey.value = value + return + if type_ in ["fromfile", ApiKeyType.from_file]: + self.from_file_apikey.value = value + return + self.from_file_options_api_key = value + + +# @dataclass(frozen=False) +# class ApiKeyDict_old: +# runtime_apikey: ApiKeyValue = field(default=ApiKeyValue("runtime", False, ApiKeyType.runtime)) +# from_file_apikey: ApiKeyValue = field(default=ApiKeyValue("fromfile", False, ApiKeyType.from_file)) +# from_file_options_api_key: ApiKeyValue = field( +# default=ApiKeyValue("fromfile_options", False, ApiKeyType.from_file_options)) +# +# def set_value(self, type_: Union[str, ApiKeyType], value): +# if type_ in ["runtime", ApiKeyType.runtime]: +# self.runtime_apikey.value = value +# return +# if type_ in ["fromfile", ApiKeyType.from_file]: +# self.from_file_apikey.value = value +# return +# self.from_file_options_api_key = value + +import time + + +class ApikeyClass(object): + def __new__(cls): + if not hasattr(cls, 'instance'): + cls.instance = super(ApikeyClass, cls).__new__(cls) + cls.post_init(cls) + return cls.instance + + def __repr__(cls): + return f""" + cls.now_testing_is_key_is_valid: {cls.now_testing_is_key_is_valid:} + cls.current_key_using : {cls.current_key_using} + cls.APIKEYDict : {cls.APIKEYDict} +""" + + def post_init(cls): + + cls.APIKEYDict: ApiKeyDict = ApiKeyDict() + cls.now_testing_is_key_is_valid: Union[str, bool] = False + cls.current_key_using: Union[str, bool] = cls.APIKEYDict.runtime_apikey.value + + def no_api_msg(self): + template = f""" + + Api Key not set yet. + -------------------------------------------- + how to set api key? + -------------------------------------------- + Option 1 (from console) + $ evdspy save + Option 2 (python console with menu) + python> from evdspy import menu + python> menu() + Selection 10 + 10 | SAVE API KEY TO FILE + Option 3 (python console ) + python> from evdspy import save + python> save() + """ + print(template) + + def get_valid_api_key(cls, check=False): + + if cls.now_testing_is_key_is_valid: + return cls.now_testing_is_key_is_valid + + key_objs = cls.get_api_keys() + if not key_objs: + if check: + cls.no_api_msg() + time.sleep(4) + raise ApiKeyNotSetError("No valid API keys found") + + if config.current_mode_is_test: + return "VALID_KEY_FOR_TEST" + + return False + return key_objs[0].value + + @property + def key(self): + if config.current_mode_is_test: + return "VALID_KEY_FOR_TEST" + key = self.get_valid_api_key(check=True) + return key + + def set_api_key_runtime(cls, value: str): + cls.instance.APIKEYDict.set_value(ApiKeyType.runtime, value) + return cls.instance.APIKEYDict.runtime_apikey.value + + def set_api_key_filetype(cls, value: str): + cls.instance.APIKEYDict.set_value(ApiKeyType.from_file, value) + + return cls.instance.APIKEYDict.from_file_apikey.value + + def set_api(cls, key: str): + print("set api not implemented") + raise "set api not implemented" + + def get_api_keys(cls): + keys = [ + cls.instance.APIKEYDict.runtime_apikey, + cls.instance.APIKEYDict.from_file_apikey, + cls.instance.APIKEYDict.from_file_options_api_key, + ] + return [x for x in keys if x.value is not False] + + def get_api_keys_dict(cls): + return cls.instance.APIKEYDict + + def get_api_key_runtime(cls): + return cls.instance.APIKEYDict.runtime_apikey.value + + def get_api_key_fromfile(cls): + return cls.instance.APIKEYDict.from_file_apikey.value + + def get_api_key_fromfile_options(cls): + return cls.instance.APIKEYDict.from_file_options_api_key diff --git a/evdspy/EVDSlocal/config/config.py b/evdspy/EVDSlocal/config/config.py index c91f2b4..a98d84c 100644 --- a/evdspy/EVDSlocal/config/config.py +++ b/evdspy/EVDSlocal/config/config.py @@ -1,58 +1,67 @@ -from ..common.common_imports import * -from ..utils.utils_general import * -from ..initial.start_options import * -from ..common.files import Read -from ..common.colors import * - - -def get_develop_vers_main(): - parent = Path(__file__).parent - v = Read(Path(parent / ".." / ".." / "__version__.py")) - if isinstance(v , str ) : - v = v.replace("#" , "") - return v - - -def version_raw(): - v = get_develop_vers_main() - return v - - -def version_display(): - v = get_develop_vers_main() - import site - s = site.getsitepackages() - site_pack = "" - f = "" - if len(s) > 1: - site_pack = s[1] - f = "from" - # print_with_success_style(f"evdspy {v} {f} ") - # print_with_info_style(f"evdspy {v} {f} {site_pack}") - v = f"evdspy {v} {f} {site_pack}" - print_with_info_style(v) - - -@dataclass -class ConfigBase(ABC): - cancel_request_temp: bool = False - current_mode_is_test: bool = check_if_this_is_pytest() - projectName: str = 'evdspy' - interiorFolder = 'EVDSlocal' - runtime_file_name_root_path = get_current_dir() / '..' - runtime_file_name_path = get_current_dir() / '..' / "components" / "options.py" - user_options_file_name = Path.cwd() / 'IO' / 'options.py' - user_options_file_name_locked = Path.cwd() / 'IO' / 'options-locked.py' - version: str = version_raw() - temp_cancel_mock_request :bool = temp_cancel_mock_request - - def version_display(self): - version_display() - - -config = ConfigBase() - -__all__ = [ - 'ConfigBase', - 'config' -] +import warnings + +from ..common.common_imports import * +from ..utils.utils_general import * +from ..initial.start_options import * +from ..common.files import Read +from ..common.colors import * + + +def get_develop_vers_main(): + parent = Path(__file__).parent + v = Read(Path(parent / ".." / ".." / "__version__.py")) + if isinstance(v, str): + v = v.replace("#", "") + return v + + +def version_raw(): + v = get_develop_vers_main() + return v + + +def version_display(): + v = get_develop_vers_main() + import site + s = site.getsitepackages() + site_pack = "" + f = "" + if len(s) > 1: + site_pack = s[1] + f = "from" + # print_with_success_style(f"evdspy {v} {f} ") + # print_with_info_style(f"evdspy {v} {f} {site_pack}") + v = f"evdspy {v} {f} {site_pack}" + print_with_info_style(v) + + +import warnings + + +@dataclass +class ConfigBase(ABC): + cancel_request_temp: bool = False + current_mode_is_test: bool = check_if_this_is_pytest() + projectName: str = 'evdspy' + interiorFolder = 'EVDSlocal' + runtime_file_name_root_path = get_current_dir() / '..' + runtime_file_name_path = get_current_dir() / '..' / "components" / "options.py" + user_options_file_name = Path.cwd() / 'IO' / 'options.py' + user_options_file_name_locked = Path.cwd() / 'IO' / 'options-locked.py' + version: str = version_raw() + temp_cancel_mock_request: bool = temp_cancel_mock_request + + def __post_init__(self): + if self.cancel_request_temp: + warnings.warn("cancel_request_temp is set to True ") + + def version_display(self): + version_display() + + +config = ConfigBase() + +__all__ = [ + 'ConfigBase', + 'config' +] diff --git a/evdspy/EVDSlocal/config/credentials_file.py b/evdspy/EVDSlocal/config/credentials_file.py index d3900df..8f0b377 100644 --- a/evdspy/EVDSlocal/config/credentials_file.py +++ b/evdspy/EVDSlocal/config/credentials_file.py @@ -1,49 +1,49 @@ -from ..common.common_imports import * -from dataclasses import dataclass, field -from ..utils.utils_general import * -from ..components.options_class import Options -from ..messages.error_classes import OptionsFileNotLoadedError -from evdspy.EVDSlocal.initial_setup.api_key_save import get_api_key_from_file_improved - -from evdspy.EVDSlocal.config.apikey_class import * -from ..components.options_class import load_options - - -def get_if_attr_exist(pred, f): - if pred: - return f(pred) - return False - - -@dataclass -class Credentials: - options_: Options = field(default_factory=load_options) - apiKey: Optional[any] = False - proxy = False - address: str = "https://evds2.tcmb.gov.tr/service/evds/" - - def __post_init__(self): - self.apikeyobj = field(default_factory=ApikeyClass) # ApikeyClass() - self.get_api_keys() - - if hasattr(self.options_, "proxy_file"): - self.proxy = get_proxy_from_file(self.options_.proxy_file) - - def get_api_keys(self): - self.apikeyobj = ApikeyClass() - # from file - api_from_file = get_api_key_from_file_improved() - if api_from_file: - self.apikeyobj.set_api_key_filetype(api_from_file) - - def __repr__(self): - return f""" - apikey: obscured(read_successfully) - proxy : obscured(read_successfully) - adres:{self.address} - """ - - -__all__ = [ - 'Credentials' -] +from ..common.common_imports import * +from dataclasses import dataclass, field +from ..utils.utils_general import * +from ..components.options_class import Options +from ..messages.error_classes import OptionsFileNotLoadedError +from evdspy.EVDSlocal.initial_setup.api_key_save import get_api_key_from_file_improved + +from evdspy.EVDSlocal.config.apikey_class import * +from ..components.options_class import load_options + + +def get_if_attr_exist(pred, f): + if pred: + return f(pred) + return False + + +@dataclass +class Credentials: + options_: Options = field(default_factory=load_options) + apiKey: Optional[any] = False + proxy = False + address: str = "https://evds2.tcmb.gov.tr/service/evds/" + + def __post_init__(self): + self.apikeyobj = field(default_factory=ApikeyClass) # ApikeyClass() + self.get_api_keys() + + if hasattr(self.options_, "proxy_file"): + self.proxy = get_proxy_from_file(self.options_.proxy_file) + + def get_api_keys(self): + self.apikeyobj = ApikeyClass() + # from file + api_from_file = get_api_key_from_file_improved() + if api_from_file: + self.apikeyobj.set_api_key_filetype(api_from_file) + + def __repr__(self): + return f""" + apikey: obscured(read_successfully) + proxy : obscured(read_successfully) + adres:{self.address} + """ + + +__all__ = [ + 'Credentials' +] diff --git a/evdspy/EVDSlocal/console/menu.py b/evdspy/EVDSlocal/console/menu.py index d15b801..a732995 100644 --- a/evdspy/EVDSlocal/console/menu.py +++ b/evdspy/EVDSlocal/console/menu.py @@ -1,208 +1,208 @@ -from ..common.common_imports import * -from collections import namedtuple -from dataclasses import dataclass, field -from ..config.config import * -from evdspy.EVDSlocal.console.screen import * -from ..common.prog import rich_sim -from ..common.colors import * - -# from evdspy.utils.utils_general import * - -indent = " " * 15 - -# MenuItem = namedtuple("MenuItem", "func disp sleeptime clear") -# MenuItem = namedtuple("MenuItem", "func disp sleeptime clear") -from typing import Union, List, Tuple, Callable - -do_nothing = lambda: True - - -@dataclass -class MenuItem: - """ - MenuItem - """ - func: Union[Callable, str] - disp: str - sleeptime: int = 0 - clear: bool = False - name: str = "" - callable_func: Callable = do_nothing - - def __post_init__(self): - if callable(self.func): - self.name = self.func.__name__ - self.callable_func = self.func - elif isinstance(self.func, str): - self.name = self.func - else: - self.name = self.disp - - self.get_sleep_times() - self.get_screen_clear_bool() - - def get_sleep_times(self): - sleeptime_default = 1 - - obj = {"check": sleeptime_default, "setup": sleeptime_default, "get": sleeptime_default, - "get_categories_main": sleeptime_default} - self.sleeptime = obj.get(self.name, sleeptime_default) - - def get_screen_clear_bool(self): - obj = {"check": False, "get": False, "help_": False, "get_categories_main": False} - self.clear = obj.get(self.name, True) - - -@dataclass -class MenuMaker: - menu_items: field(default_factory=List[MenuItem]) - # menu_items_display : field(default_factory=list) - message: str = "\n" + " " * 25 + f"Selection ? " - exit_item: bool = True - exit_: bool = False - exit_menu_call_back: Callable = do_nothing - - def __post_init__(self): - self.add_exit_item() - Screen().clear() - - def exit(self): - self.exit_ = True - self.exit_menu_call_back() - return - # self.display() - - def menu_header(self): - width = 60 - - def make_indent(element, num=width): - indent = " " * (num - len(element)) - return f"{indent}{element}" - - def make_center(element, num=width): - left = " " * round((num - len(element)) / 2) - return f"{left}{element}" - - menu_title = make_center("M E N U") - reminder = "to get the latest version: pip install -U evdspy" - reminder = make_indent(reminder) - - version_line = make_indent(config.version) - logo = make_indent("evdspy @2022") - - line_1 = "-" * width - print_with_info_style(reminder) - header = f""" - -{line_1} -{version_line} -{line_1} -{logo} -{menu_title} -{line_1} - - -""" - return header - - def title(self): - - print("\n" * 2) - print(self.menu_header()) - - def add_exit_item(self): - if self.exit_item: - exit_menu_item = MenuItem(self.exit, "console") - self.menu_items = tuple(list(self.menu_items) + [exit_menu_item]) - - def make_table(self, items): - from rich.console import Console - from rich.table import Table - def get_color(item: str): - font_color = "green" - if "false" in item.lower(): - font_color = "red" - return font_color - - table = Table(title="M E N U ") - table.add_column("Select", justify="right", style="cyan", no_wrap=True) - table.add_column("Job / Request ", style="green") - table.add_column("Explanation ", justify="right", style="magenta") - - for index, item in enumerate(items): - font_color = get_color(item.disp) - table.add_row(f"{index + 1}", str(item.disp).upper(), "", style=font_color) - - console = Console() - console.print(table) - - def display(self): - - if self.exit_: - return - self.make_table(self.menu_items) - self.get_choice() - - def display_old(self): - - if self.exit_: - return - self.title() - for index, item in enumerate(self.menu_items): - dec = f"{indent}{index + 1}. {item.disp} " - print_menu_item_style(dec) - self.get_choice() - - def menu_exists_and_callable(self, a: str): - if str(a).isnumeric() and int(a) in (x for x in range(1, len(self.menu_items) + 1)): - menu_item: MenuItem = self.menu_items[int(a) - 1] - func = menu_item.func - return callable(func), menu_item.callable_func, menu_item - return False, False, False - - def get_choice(self): - if self.exit_: - return - if config.current_mode_is_test: - return - ans = input(self.message) - cond, func, menu_item = self.menu_exists_and_callable(ans) - - if cond: - wait_seconds = menu_item.sleeptime - - if menu_item.clear: - Screen().clear() - v = func() - if v == -1: - self.exit_ = True - rich_sim(wait_seconds, "completing") - else: - Screen().clear() - return self.display() - - -__all__ = [ - 'MenuItem', - 'MenuMaker', -] - - -def test_show(): - print("test") - - -def test_show2(): - print("test 2") - - -def test_show3(): - print("test 3") - - -def test_f(): - t1 = MenuItem(test_show, "test_show") - t2 = MenuItem(test_show2, "test_show2") - t3 = MenuItem(test_show3, "test_show3") - m = MenuMaker(menu_items=[t1, t2, t3]) - m.display() +from ..common.common_imports import * +from collections import namedtuple +from dataclasses import dataclass, field +from ..config.config import * +from evdspy.EVDSlocal.console.screen import * +from ..common.prog import rich_sim +from ..common.colors import * + +# from evdspy.utils.utils_general import * + +indent = " " * 15 + +# MenuItem = namedtuple("MenuItem", "func disp sleeptime clear") +# MenuItem = namedtuple("MenuItem", "func disp sleeptime clear") +from typing import Union, List, Tuple, Callable + +do_nothing = lambda: True + + +@dataclass +class MenuItem: + """ + MenuItem + """ + func: Union[Callable, str] + disp: str + sleeptime: int = 0 + clear: bool = False + name: str = "" + callable_func: Callable = do_nothing + + def __post_init__(self): + if callable(self.func): + self.name = self.func.__name__ + self.callable_func = self.func + elif isinstance(self.func, str): + self.name = self.func + else: + self.name = self.disp + + self.get_sleep_times() + self.get_screen_clear_bool() + + def get_sleep_times(self): + sleeptime_default = 1 + + obj = {"check": sleeptime_default, "setup": sleeptime_default, "get": sleeptime_default, + "get_categories_main": sleeptime_default} + self.sleeptime = obj.get(self.name, sleeptime_default) + + def get_screen_clear_bool(self): + obj = {"check": False, "get": False, "help_": False, "get_categories_main": False} + self.clear = obj.get(self.name, True) + + +@dataclass +class MenuMaker: + menu_items: field(default_factory=List[MenuItem]) + # menu_items_display : field(default_factory=list) + message: str = "\n" + " " * 25 + f"Selection ? " + exit_item: bool = True + exit_: bool = False + exit_menu_call_back: Callable = do_nothing + + def __post_init__(self): + self.add_exit_item() + Screen().clear() + + def exit(self): + self.exit_ = True + self.exit_menu_call_back() + return + # self.display() + + def menu_header(self): + width = 60 + + def make_indent(element, num=width): + indent = " " * (num - len(element)) + return f"{indent}{element}" + + def make_center(element, num=width): + left = " " * round((num - len(element)) / 2) + return f"{left}{element}" + + menu_title = make_center("M E N U") + reminder = "to get the latest version: pip install -U evdspy" + reminder = make_indent(reminder) + + version_line = make_indent(config.version) + logo = make_indent("evdspy @2022") + + line_1 = "-" * width + print_with_info_style(reminder) + header = f""" + +{line_1} +{version_line} +{line_1} +{logo} +{menu_title} +{line_1} + + +""" + return header + + def title(self): + + print("\n" * 2) + print(self.menu_header()) + + def add_exit_item(self): + if self.exit_item: + exit_menu_item = MenuItem(self.exit, "EXIT (console)") + self.menu_items = tuple(list(self.menu_items) + [exit_menu_item]) + + def make_table(self, items): + from rich.console import Console + from rich.table import Table + def get_color(item: str): + font_color = "green" + if "false" in item.lower(): + font_color = "red" + return font_color + + table = Table(title="M E N U ") + table.add_column("Select", justify="right", style="cyan", no_wrap=True) + table.add_column("Job / Request ", style="green") + table.add_column("Explanation ", justify="right", style="magenta") + + for index, item in enumerate(items): + font_color = get_color(item.disp) + table.add_row(f"{index + 1}", str(item.disp).upper(), "", style=font_color) + + console = Console() + console.print(table) + + def display(self): + + if self.exit_: + return + self.make_table(self.menu_items) + self.get_choice() + + def display_old(self): + + if self.exit_: + return + self.title() + for index, item in enumerate(self.menu_items): + dec = f"{indent}{index + 1}. {item.disp} " + print_menu_item_style(dec) + self.get_choice() + + def menu_exists_and_callable(self, a: str): + if str(a).isnumeric() and int(a) in (x for x in range(1, len(self.menu_items) + 1)): + menu_item: MenuItem = self.menu_items[int(a) - 1] + func = menu_item.func + return callable(func), menu_item.callable_func, menu_item + return False, False, False + + def get_choice(self): + if self.exit_: + return + if config.current_mode_is_test: + return + ans = input(self.message) + cond, func, menu_item = self.menu_exists_and_callable(ans) + + if cond: + wait_seconds = menu_item.sleeptime + + if menu_item.clear: + Screen().clear() + v = func() + if v == -1: + self.exit_ = True + rich_sim(wait_seconds, "completing") + else: + Screen().clear() + return self.display() + + +__all__ = [ + 'MenuItem', + 'MenuMaker', +] + + +def test_show(): + print("test") + + +def test_show2(): + print("test 2") + + +def test_show3(): + print("test 3") + + +def test_f(): + t1 = MenuItem(test_show, "test_show") + t2 = MenuItem(test_show2, "test_show2") + t3 = MenuItem(test_show3, "test_show3") + m = MenuMaker(menu_items=[t1, t2, t3]) + m.display() diff --git a/evdspy/EVDSlocal/console/menu_logo_header.py b/evdspy/EVDSlocal/console/menu_logo_header.py index 18ed12d..6ba63d8 100644 --- a/evdspy/EVDSlocal/console/menu_logo_header.py +++ b/evdspy/EVDSlocal/console/menu_logo_header.py @@ -1,59 +1,59 @@ -from evdspy.EVDSlocal.common.colors import print_with_info_style -from evdspy.EVDSlocal.config.config import config - -width = 60 - - -def make_indent(element, num=width): - indent = " " * (num - len(element)) - return f"{indent}{element}" - - -def make_center(element, num=width): - left = " " * round((num - len(element)) / 2) - return f"{left}{element}" - - -def menu_header(self): - menu_title = make_center("M E N U") - reminder = "to get the latest version: pip install -U evdspy" - reminder = make_indent(reminder) - version_line = make_indent(config.version) - logo = make_indent("evdspy @2022") - line_1 = "-" * width - print_with_info_style(reminder) - header = f""" - -{line_1} -{version_line} -{line_1} -{logo} -{menu_title} -{line_1} -""" - return header - - -def version_logo(): - # menu_title = make_center("M E N U") - reminder = "for the latest version: pip install -U evdspy" - reminder = make_indent(reminder) - version_line = make_indent(config.version, 15) - logo = make_indent("evdspy @2022", 30) - line_1 = "-" * width - - logo_version = f""" - {line_1} - {logo} {" " * 5} {version_line} - {line_1} - - """ - - logo_version2 = f""" - {line_1} - {version_line} - {line_1} - {logo} - """ - - return logo_version, reminder +from evdspy.EVDSlocal.common.colors import print_with_info_style +from evdspy.EVDSlocal.config.config import config + +width = 60 + + +def make_indent(element, num=width): + indent = " " * (num - len(element)) + return f"{indent}{element}" + + +def make_center(element, num=width): + left = " " * round((num - len(element)) / 2) + return f"{left}{element}" + + +def menu_header(self): + menu_title = make_center("M E N U") + reminder = "to get the latest version: pip install -U evdspy" + reminder = make_indent(reminder) + version_line = make_indent(config.version) + logo = make_indent("evdspy @2022") + line_1 = "-" * width + print_with_info_style(reminder) + header = f""" + +{line_1} +{version_line} +{line_1} +{logo} +{menu_title} +{line_1} +""" + return header + + +def version_logo(): + # menu_title = make_center("M E N U") + reminder = "for the latest version: pip install -U evdspy" + reminder = make_indent(reminder) + version_line = make_indent(config.version, 15) + logo = make_indent("evdspy @2022", 30) + line_1 = "-" * width + + logo_version = f""" + {line_1} + {logo} {" " * 5} {version_line} + {line_1} + + """ + + logo_version2 = f""" + {line_1} + {version_line} + {line_1} + {logo} + """ + + return logo_version, reminder diff --git a/evdspy/EVDSlocal/console/panel.py b/evdspy/EVDSlocal/console/panel.py new file mode 100644 index 0000000..01d7dd1 --- /dev/null +++ b/evdspy/EVDSlocal/console/panel.py @@ -0,0 +1,30 @@ +# from rich.console import Console +# from rich.layout import Layout +# +# console = Console() +# layout = Layout() +# +# # Divide the "screen" in to three parts +# layout.split( +# Layout(name="header", size=3), +# Layout(ratio=1, name="main"), +# Layout(size=10, name="footer"), +# ) +# # Divide the "main" layout in to "side" and "body" +# layout["main"].split( +# Layout(name="side"), +# Layout(name="body", ratio=2), +# +# ) +# # Divide the "side" layout in to two +# layout["side"].split(Layout(), Layout()) +# +# # console.print(layout) +# +# +# from rich.live import Live +# from time import sleep +# +# with Live(layout, screen=True): +# while True: +# sleep(1) \ No newline at end of file diff --git a/evdspy/EVDSlocal/console/screen.py b/evdspy/EVDSlocal/console/screen.py index af123ae..45044cc 100644 --- a/evdspy/EVDSlocal/console/screen.py +++ b/evdspy/EVDSlocal/console/screen.py @@ -1,21 +1,21 @@ -from ..common.common_imports import * -import os - -opsys_dict = { - 'nt': 'windows', - 'posix': 'linux/mac', - 'default': 'linux/mac' -} -opsys_name = opsys_dict.get(os.name, opsys_dict.get('default', None)) -clear_dict = { - 'windows': 'cls', - 'linux/mac': 'clear', - 'default': 'clear' -} -clear_command_name = clear_dict.get(opsys_name, clear_dict.get('default', None)) - - -class Screen: - def clear(self): - os.system(clear_command_name) - +from ..common.common_imports import * +import os + +opsys_dict = { + 'nt': 'windows', + 'posix': 'linux/mac', + 'default': 'linux/mac' +} +opsys_name = opsys_dict.get(os.name, opsys_dict.get('default', None)) +clear_dict = { + 'windows': 'cls', + 'linux/mac': 'clear', + 'default': 'clear' +} +clear_command_name = clear_dict.get(opsys_name, clear_dict.get('default', None)) + + +class Screen: + def clear(self): + os.system(clear_command_name) + diff --git a/evdspy/EVDSlocal/helper/print_m.py b/evdspy/EVDSlocal/helper/print_m.py index 11c0f18..727335b 100644 --- a/evdspy/EVDSlocal/helper/print_m.py +++ b/evdspy/EVDSlocal/helper/print_m.py @@ -1,31 +1,31 @@ -from inspect import getframeinfo, stack -import inspect as ins - -import sys -import builtins as __builtin__ -from evdspy.EVDSlocal.initial.start_options import * - - -if DEBUG_PRINT : - """ - Here we will overload print - see inital.start_options.py - """ - - def debugInfo(s="", *args, **kw): - caller = getframeinfo(stack()[2][0]) - msg = "---called from : {} - line number : {} -- {} ".format(caller.filename, caller.lineno, s) - return msg - - - - - - - def print(*args, **kwargs): - if DEBUG_PRINT: - d = debugInfo(*args) - __builtin__.print("XXX", d) - return __builtin__.print(*args, **kwargs) - - return __builtin__.print(*args, **kwargs) +from inspect import getframeinfo, stack +import inspect as ins + +import sys +import builtins as __builtin__ +from evdspy.EVDSlocal.initial.start_options import * + + +if DEBUG_PRINT : + """ + Here we will overload print + see inital.start_options.py + """ + + def debugInfo(s="", *args, **kw): + caller = getframeinfo(stack()[2][0]) + msg = "---called from : {} - line number : {} -- {} ".format(caller.filename, caller.lineno, s) + return msg + + + + + + + def print(*args, **kwargs): + if DEBUG_PRINT: + d = debugInfo(*args) + __builtin__.print("XXX", d) + return __builtin__.print(*args, **kwargs) + + return __builtin__.print(*args, **kwargs) diff --git a/evdspy/EVDSlocal/index_requests/categories.py b/evdspy/EVDSlocal/index_requests/categories.py index f561abd..ab34199 100644 --- a/evdspy/EVDSlocal/index_requests/categories.py +++ b/evdspy/EVDSlocal/index_requests/categories.py @@ -1,76 +1,76 @@ -from .index_classes import GeneralIndexesCategories -from ..components.options_class import load_options -from ..manual_requests.prepare import PrepareUrl -from evdspy.EVDSlocal.common.files import Write, Read -from ..requests_.ev_request import EVRequest - - -def get_categories() -> str: - """get_categories""" - # EVRequest_: EVRequest = EVRequest() - - return GeneralIndexesCategories(EVRequest_=EVRequest(options_=load_options())).create_url() - - -def get_categories_data() -> str: - """get_categories_data""" - csv = GeneralIndexesCategories(EVRequest_=EVRequest(options_=load_options())).get_csv() - # Write("categories_list.txt", csv) - return csv - - -def get_table_header(): - from rich.table import Table - table = Table(title="Categories / Kategoriler") - table.add_column("ID/Sayı", justify="right", style="cyan", no_wrap=True) - table.add_column("Title/Başlık (ENG)", style="magenta") - table.add_column("Title/Başlık (TR)", justify="right", style="green") - return table - - -from typing import List -import typing as t - - -def get_category_name(code: t.Union[int, str] = 1) -> t.Union[str, None]: - if isinstance(code, str): - code = int(code) - csv_buffer: str = get_categories_data() - lines = csv_buffer.splitlines() - list_of_categs = {} - for item in lines[1:]: - id, cat_eng, cat_tr = split_wisely(item) - list_of_categs.update({int(id): cat_tr}) - return list_of_categs.get(code, None) - - -def display_categories() -> t.Union[List[tuple], None]: - """display_categories""" - from rich.console import Console - csv_buffer: str = get_categories_data() - table = get_table_header() - lines = csv_buffer.splitlines() - list_of_categs = [] - if not lines: - return - for item in lines[1:]: - id, cat_eng, cat_tr = split_wisely(item) - list_of_categs.append((id, cat_eng, cat_tr,)) - table.add_row(id, cat_eng, cat_tr) - console = Console() - console.print(table) - return list_of_categs - - -def split_wisely(line: str) -> tuple: - """split_wisely""" - parts = line.split(",") - id, cat_eng, cat_tr = "", "", "" - if len(parts) == 3: - id, cat_eng, cat_tr = parts - if len(parts) == 4: - id, cat_eng, cat_tr, cat_tr2 = parts - cat_tr = f"{cat_tr}, {cat_tr2}" - if id: # '1.0' - id = id.split(".")[0] - return id, cat_eng, cat_tr +from .index_classes import GeneralIndexesCategories +from ..components.options_class import load_options +from ..manual_requests.prepare import PrepareUrl +from evdspy.EVDSlocal.common.files import Write, Read +from ..requests_.ev_request import EVRequest + + +def get_categories() -> str: + """get_categories""" + # EVRequest_: EVRequest = EVRequest() + + return GeneralIndexesCategories(EVRequest_=EVRequest(options_=load_options())).create_url() + + +def get_categories_data() -> str: + """get_categories_data""" + csv = GeneralIndexesCategories(EVRequest_=EVRequest(options_=load_options())).get_csv() + # Write("categories_list.txt", csv) + return csv + + +def get_table_header(): + from rich.table import Table + table = Table(title="Categories / Kategoriler") + table.add_column("ID/Sayı", justify="right", style="cyan", no_wrap=True) + table.add_column("Title/Başlık (ENG)", style="magenta") + table.add_column("Title/Başlık (TR)", justify="right", style="green") + return table + + +from typing import List +import typing as t + + +def get_category_name(code: t.Union[int, str] = 1) -> t.Union[str, None]: + if isinstance(code, str): + code = int(code) + csv_buffer: str = get_categories_data() + lines = csv_buffer.splitlines() + list_of_categs = {} + for item in lines[1:]: + id, cat_eng, cat_tr = split_wisely(item) + list_of_categs.update({int(id): cat_tr}) + return list_of_categs.get(code, None) + + +def display_categories() -> t.Union[List[tuple], None]: + """display_categories""" + from rich.console import Console + csv_buffer: str = get_categories_data() + table = get_table_header() + lines = csv_buffer.splitlines() + list_of_categs = [] + if not lines: + return + for item in lines[1:]: + id, cat_eng, cat_tr = split_wisely(item) + list_of_categs.append((id, cat_eng, cat_tr,)) + table.add_row(id, cat_eng, cat_tr) + console = Console() + console.print(table) + return list_of_categs + + +def split_wisely(line: str) -> tuple: + """split_wisely""" + parts = line.split(",") + id, cat_eng, cat_tr = "", "", "" + if len(parts) == 3: + id, cat_eng, cat_tr = parts + if len(parts) == 4: + id, cat_eng, cat_tr, cat_tr2 = parts + cat_tr = f"{cat_tr}, {cat_tr2}" + if id: # '1.0' + id = id.split(".")[0] + return id, cat_eng, cat_tr diff --git a/evdspy/EVDSlocal/index_requests/data_models.py b/evdspy/EVDSlocal/index_requests/data_models.py index ef65604..133bd3c 100644 --- a/evdspy/EVDSlocal/index_requests/data_models.py +++ b/evdspy/EVDSlocal/index_requests/data_models.py @@ -1,18 +1,18 @@ -from abc import ABC -from dataclasses import dataclass - - -@dataclass -class DataModel(ABC): - data: any - type_name: str = "" - - -@dataclass -class DataModelCSV(DataModel): - type_name: str = "csv" - - -@dataclass -class DataModelJSON(DataModel): - type_name: str = "json" +from abc import ABC +from dataclasses import dataclass + + +@dataclass +class DataModel(ABC): + data: any + type_name: str = "" + + +@dataclass +class DataModelCSV(DataModel): + type_name: str = "csv" + + +@dataclass +class DataModelJSON(DataModel): + type_name: str = "json" diff --git a/evdspy/EVDSlocal/index_requests/datagroup_individual.py b/evdspy/EVDSlocal/index_requests/datagroup_individual.py index 364bda9..e8e3b1e 100644 --- a/evdspy/EVDSlocal/index_requests/datagroup_individual.py +++ b/evdspy/EVDSlocal/index_requests/datagroup_individual.py @@ -1,118 +1,119 @@ -import pandas as pd - -from .datagroups_initial import data_models_dict, data_strategy -from .index_classes import GeneralIndexesDatagroups, GeneralIndexesDatagroupIndividual, \ - GeneralIndexesDatagroupSeriesList -from .error_classes_index import ContentFunctionError -from .df_operations import DFOperations -from .index_util_funcs import json_to_excel, json_to_df, make_df_float -from ..common.table import Table2_ -from ..components.api_params import DateStart, DateEnd -from ..components.options_class import SingletonOptions -from ..config.apikey_class import ApikeyClass -from ..config.config import ConfigBase -from ..initial.start_options import default_data_folder_name, Default_Prefix_ -from ..requests_.ev_request import EVRequest - -config = ConfigBase() - - -# EVDSApiDomainDatagroupIndividual - -def try_to_make_excel(json_content, file_name, try_float): - try: - json_to_excel(json_content, file_name, try_float=try_float) - from ..common.colors import print_with_success_style - print_with_success_style(f"{file_name} was created...") - except: - from ..common.colors import print_with_failure_style - print_with_failure_style(f"{file_name} could not be created...") - - -def get_datagroup_individual_with_code(code_str: str): - """get_datagroup_individual_with_code""" - json_content = get_datagroup_individual_with_code_helper(code_str) - # file_name = rf"SeriesData\EVPY_Data_{code_str}.xlsx" - file_name = rf"{default_data_folder_name}\{Default_Prefix_}{code_str}.xlsx" - if not json_content: - return False - if 'items' in json_content: - json_content = json_content['items'] - try_to_make_excel(json_content, file_name, try_float=True) - return json_content - - -def get_datagroup_individual_with_code_helper( - code_str: str, - start_date: str = None, - end_date: str = None -): - """get_datagroup_individual_with_code_helper""" - gid = GeneralIndexesDatagroupIndividual(code=0, EVRequest_=EVRequest( - options_=SingletonOptions())) # this number will be overriten . does not matter what number - gid.create_url_first_part() - gid.add_extra_params(code=code_str) - # start_date = SingletonOptions().get_valid_value("default_start_date") - # end_date = SingletonOptions().get_valid_value("default_end_date") - if not start_date: - start_date = SingletonOptions().get_valid_value("default_start_date") - if not end_date: - end_date = SingletonOptions().get_valid_value("default_end_date") - date_start: DateStart = DateStart(value=start_date) - date_end: DateEnd = DateEnd(value=end_date) - - gid.complete_url_instance.add_item(date_start) - gid.complete_url_instance.add_item(date_end) - gid.complete_url_instance.refresh_url() - gid.complete_url_instance.add_apikey() # this will get apikey itself if None given - json_content = gid.get_json() - - return json_content - - -def get_series_list_of_subject(code_str: str): - # https://evds2.tcmb.gov.tr/service/evds/serieList/key=XXXXX&type=csv&code=bie_yssk - gid = GeneralIndexesDatagroupSeriesList(code=0, EVRequest_=EVRequest( - options_=SingletonOptions())) # this number will be overriten . does not matter what number - gid.create_url_first_part() - gid.add_extra_params(code=code_str) - gid.complete_url_instance.refresh_url() - json_content = gid.get_json() - # file_name = rf"SeriesData\EVPY_Data_{code_str}_EXPLANATION.xlsx" - file_name = rf"{default_data_folder_name}\{Default_Prefix_}{code_str}_EXPLANATION.xlsx" - try_to_make_excel(json_content, file_name, try_float=False) - - return json_content - - -# ---------------------------------------------------------------------------------- -""" Functions to return DF """ - -""" - start_date = SingletonOptions().get_valid_value("default_start_date") - end_date = SingletonOptions().get_valid_value("default_end_date") -""" - - -def get_df_datagroup( - datagroup: str, - start_date: str = None, - end_date: str = None -): - """returns all series as df to extend - params: - ----------------------- - datagroup : str - e.g. `bie_yssk` - start_date : str - e.g. `31-01-2010` - end_date : str - e.g. `31-01-2030` - """ - - # https://evds2.tcmb.gov.tr/service/evds/datagroup=bie_yssk&startDate=01-06-2017&endDate=07-09-2017&type=csv&key=XXXX - json_content = get_datagroup_individual_with_code_helper(datagroup, start_date, end_date) - df = json_to_df(json_content) - df = make_df_float(df) - - return df +import pandas as pd + +from .datagroups_initial import data_models_dict, data_strategy +from .index_classes import GeneralIndexesDatagroups, GeneralIndexesDatagroupIndividual, \ + GeneralIndexesDatagroupSeriesList +from .error_classes_index import ContentFunctionError +from .df_operations import DFOperations +from .index_util_funcs import json_to_excel, json_to_df, make_df_float +from ..common.table import Table2_ +from ..components.api_params import DateStart, DateEnd +from ..components.options_class import SingletonOptions +from ..config.apikey_class import ApikeyClass +from ..config.config import ConfigBase +from ..initial.start_options import default_data_folder_name, Default_Prefix_ +from ..requests_.ev_request import EVRequest + +config = ConfigBase() + + +# EVDSApiDomainDatagroupIndividual + +def try_to_make_excel(json_content, file_name, try_float): + try: + json_to_excel(json_content, file_name, try_float=try_float) + from ..common.colors import print_with_success_style + print_with_success_style(f"{file_name} was created...") + except: + from ..common.colors import print_with_failure_style + print_with_failure_style(f"{file_name} could not be created...") + + +def get_datagroup_individual_with_code(code_str: str): + """get_datagroup_individual_with_code""" + json_content = get_datagroup_individual_with_code_helper(code_str) + # file_name = rf"SeriesData\EVPY_Data_{code_str}.xlsx" + file_name = rf"{default_data_folder_name}\{Default_Prefix_}{code_str}.xlsx" + if not json_content: + return False + if 'items' in json_content: + json_content = json_content['items'] + try_to_make_excel(json_content, file_name, try_float=True) + return json_content + + +def get_datagroup_individual_with_code_helper( + code_str: str, + start_date: str = None, + end_date: str = None +): + """get_datagroup_individual_with_code_helper""" + gid = GeneralIndexesDatagroupIndividual(code=0, EVRequest_=EVRequest( + options_=SingletonOptions())) # this number will be overwritten . does not matter what number + gid.create_url_first_part() + gid.add_extra_params(code=code_str) + # start_date = SingletonOptions().get_valid_value("default_start_date") + # end_date = SingletonOptions().get_valid_value("default_end_date") + if not start_date: + start_date = SingletonOptions().get_valid_value("default_start_date") + if not end_date: + end_date = SingletonOptions().get_valid_value("default_end_date") + date_start: DateStart = DateStart(value=start_date) + date_end: DateEnd = DateEnd(value=end_date) + + gid.complete_url_instance.add_item(date_start) + gid.complete_url_instance.add_item(date_end) + gid.complete_url_instance.refresh_url() + gid.complete_url_instance.add_apikey() # this will get apikey itself if None given + json_content = gid.get_json() + + return json_content + + +def get_series_list_of_subject(code_str: str): + # https://evds2.tcmb.gov.tr/service/evds/serieList/key=XXXXX&type=csv&code=bie_yssk + gid = GeneralIndexesDatagroupSeriesList(code=0, EVRequest_=EVRequest( + options_=SingletonOptions())) # this number will be overriten . does not matter what number + gid.create_url_first_part() + gid.add_extra_params(code=code_str) + gid.complete_url_instance.refresh_url() + json_content = gid.get_json() + # file_name = rf"SeriesData\EVPY_Data_{code_str}_EXPLANATION.xlsx" + file_name = rf"{default_data_folder_name}\{Default_Prefix_}{code_str}_EXPLANATION.xlsx" + try_to_make_excel(json_content, file_name, try_float=False) + + return json_content + + +# ---------------------------------------------------------------------------------- +""" Functions to return DF """ + +""" + start_date = SingletonOptions().get_valid_value("default_start_date") + end_date = SingletonOptions().get_valid_value("default_end_date") +""" + + +def get_df_datagroup( + datagroup: str, + start_date: str = None, + end_date: str = None +): + """returns all series as df to extend + params: + ----------------------- + datagroup : str + e.g. `bie_yssk` + start_date : str + e.g. `31-01-2010` + end_date : str + e.g. `31-01-2030` + """ + + # https://evds2.tcmb.gov.tr/service/evds/datagroup=bie_yssk&startDate=01-06-2017&endDate=07-09-2017&type=csv&key=XXXX + json_content = get_datagroup_individual_with_code_helper(datagroup, start_date, end_date) + df = json_to_df(json_content) + df = make_df_float(df) + + return df + diff --git a/evdspy/EVDSlocal/index_requests/datagroups.py b/evdspy/EVDSlocal/index_requests/datagroups.py index e02d040..496146b 100644 --- a/evdspy/EVDSlocal/index_requests/datagroups.py +++ b/evdspy/EVDSlocal/index_requests/datagroups.py @@ -1,103 +1,103 @@ -import pandas as pd - -from .datagroups_initial import data_models_dict, data_strategy -from .index_classes import GeneralIndexesDatagroups -from .error_classes_index import ContentFunctionError -from .df_operations import DFOperations -from ..common.table import Table2_ -from ..components.options_class import SingletonOptions -from ..config.config import ConfigBase -from ..requests_.ev_request import EVRequest - -config = ConfigBase() - - -# https://evds2.tcmb.gov.tr/service/evds/datagroup=bie_yssk&startDate=01-06-2017&endDate=07-09-2030&type=json&key=XXYYZZ - - -def get_datagroups_with_code(code=1): - gid = GeneralIndexesDatagroups(code=code , EVRequest_=EVRequest(options_=SingletonOptions())) # - json_content = gid.get_json() - return json_content - - -def get_keys() -> tuple: - keys = ('DATAGROUP_CODE', 'DATAGROUP_NAME_ENG', - 'DATAGROUP_NAME', 'FREQUENCY', - 'DATASOURCE_ENG', 'FREQUENCY_STR', - 'START_DATE', 'END_DATE' - ) - return keys - - -def get_title(item: dict) -> str: - return item['DATAGROUP_NAME_ENG'] - - -def get_value_from_datagroups_dict(item: dict, key: str) -> str: - value = item.get(key, None) # str(item[key]) - value = str(value) - return value - - -import typing as t - - -def get_titles_and_ids_for_selection(json_content: dict) -> t.List[t.Tuple[str, str]]: - new_list = [] - for item in json_content: - title: str = get_value_from_datagroups_dict(item, 'DATAGROUP_NAME_ENG') - code: str = get_value_from_datagroups_dict(item, 'DATAGROUP_CODE') - new_list.append((code, title)) - return new_list - - -def show_datagroups_summary(json_content: dict) -> None: - keys = get_keys() - for item in json_content: - new_list = [] - for key in keys: - value = get_value_from_datagroups_dict(item, key) - new_list.append((key, value,)) - title = get_title(item) - Table2_().show(list_=new_list, title=title, columns=('key', 'value'), skiprow=0) - - -def json_to_df(json_content: list, code: int) -> None: - df = pd.DataFrame.from_records(json_content) - file_name = f"dataGroupOut-{code}.xlsx" - try: - df.to_excel(file_name) - except: - print(f"could not write excel file {file_name}. =>file is probably open") - # data_model_type = data_models_dict['json'] - # process_datagroups(data_model_type, json_content) - - -def get_and_process_datagroups_with_code(code=1): - json_content: dict = get_datagroups_with_code(code) - show_datagroups_summary(json_content) - return get_titles_and_ids_for_selection(json_content) - # exit() - # json_to_df(json_content, code) - - -def get_all_groups(): - # numbers = (1, 2, 3, 4, 5, 12, 13, 14, 15, 18, 19, 20, 21, 22, 23, 6, 7, 24, 25, 26, 27, 28, 95,) - numbers = (18, 19,) - for num in numbers: - try: - get_and_process_datagroups_with_code(num) - except Exception as exc: - print(exc) - pass - - -def get_datagroups() -> str: - return GeneralIndexesDatagroups(EVRequest_=EVRequest(options_=SingletonOptions())).create_url() - -# def process_datagroups(data_model_type, content): -# df_op = DFOperations(data_model_type(data=content)) -# df_op.convert_to_df_abstract() -# df = pd.DataFrame.from_records(content) -# df.to_excel("t123.xlsx") +import pandas as pd + +from .datagroups_initial import data_models_dict, data_strategy +from .index_classes import GeneralIndexesDatagroups +from .error_classes_index import ContentFunctionError +from .df_operations import DFOperations +from ..common.table import Table2_ +from ..components.options_class import SingletonOptions +from ..config.config import ConfigBase +from ..requests_.ev_request import EVRequest + +config = ConfigBase() + + +# https://evds2.tcmb.gov.tr/service/evds/datagroup=bie_yssk&startDate=01-06-2017&endDate=07-09-2030&type=json&key=XXYYZZ + + +def get_datagroups_with_code(code=1): + gid = GeneralIndexesDatagroups(code=code , EVRequest_=EVRequest(options_=SingletonOptions())) # + json_content = gid.get_json() + return json_content + + +def get_keys() -> tuple: + keys = ('DATAGROUP_CODE', 'DATAGROUP_NAME_ENG', + 'DATAGROUP_NAME', 'FREQUENCY', + 'DATASOURCE_ENG', 'FREQUENCY_STR', + 'START_DATE', 'END_DATE' + ) + return keys + + +def get_title(item: dict) -> str: + return item['DATAGROUP_NAME_ENG'] + + +def get_value_from_datagroups_dict(item: dict, key: str) -> str: + value = item.get(key, None) # str(item[key]) + value = str(value) + return value + + +import typing as t + + +def get_titles_and_ids_for_selection(json_content: dict) -> t.List[t.Tuple[str, str]]: + new_list = [] + for item in json_content: + title: str = get_value_from_datagroups_dict(item, 'DATAGROUP_NAME_ENG') + code: str = get_value_from_datagroups_dict(item, 'DATAGROUP_CODE') + new_list.append((code, title)) + return new_list + + +def show_datagroups_summary(json_content: dict) -> None: + keys = get_keys() + for item in json_content: + new_list = [] + for key in keys: + value = get_value_from_datagroups_dict(item, key) + new_list.append((key, value,)) + title = get_title(item) + Table2_().show(list_=new_list, title=title, columns=('key', 'value'), skiprow=0) + + +def json_to_df(json_content: list, code: int) -> None: + df = pd.DataFrame.from_records(json_content) + file_name = f"dataGroupOut-{code}.xlsx" + try: + df.to_excel(file_name) + except: + print(f"could not write excel file {file_name}. =>file is probably open") + # data_model_type = data_models_dict['json'] + # process_datagroups(data_model_type, json_content) + + +def get_and_process_datagroups_with_code(code=1): + json_content: dict = get_datagroups_with_code(code) + show_datagroups_summary(json_content) + return get_titles_and_ids_for_selection(json_content) + # exit() + # json_to_df(json_content, code) + + +def get_all_groups(): + # numbers = (1, 2, 3, 4, 5, 12, 13, 14, 15, 18, 19, 20, 21, 22, 23, 6, 7, 24, 25, 26, 27, 28, 95,) + numbers = (18, 19,) + for num in numbers: + try: + get_and_process_datagroups_with_code(num) + except Exception as exc: + print(exc) + pass + + +def get_datagroups() -> str: + return GeneralIndexesDatagroups(EVRequest_=EVRequest(options_=SingletonOptions())).create_url() + +# def process_datagroups(data_model_type, content): +# df_op = DFOperations(data_model_type(data=content)) +# df_op.convert_to_df_abstract() +# df = pd.DataFrame.from_records(content) +# df.to_excel("t123.xlsx") diff --git a/evdspy/EVDSlocal/index_requests/datagroups_extra.py b/evdspy/EVDSlocal/index_requests/datagroups_extra.py new file mode 100644 index 0000000..6ca4ec4 --- /dev/null +++ b/evdspy/EVDSlocal/index_requests/datagroups_extra.py @@ -0,0 +1,31 @@ +from rich import inspect + +from .datagroups_initial import data_models_dict , data_strategy , GID_json , GID_csv +from .index_classes import GeneralIndexesDatagroups +from .error_classes_index import ContentFunctionError +from .df_operations import DFOperations +from evdspy.EVDSlocal.common.files import Write, Read +import typing as t +import json +from .datagroups import get_datagroups_df + + +def get_datagroups_data(data_strategy_type="json"): + # csv = GeneralIndexesDatagroups().get_csv() + buffer_function: t.Callable = data_strategy[data_strategy_type] # GeneralIndexesDatagroups().get_json + content_fn: t.Callable = buffer_function(1) + content: str | t.Callable = content_fn() + if callable(content): + # inspect(content, all=True) + content = content() + # raise "content" + if content: + inspect(content, all=True) + if isinstance(content, tuple([list, tuple])): + # content = "\n".join(content) + content = json.dumps(content) + Write("subject_list.txt", content) + else: + inspect(content) + get_datagroups_df(data_strategy_type, content) + return content \ No newline at end of file diff --git a/evdspy/EVDSlocal/index_requests/datagroups_initial.py b/evdspy/EVDSlocal/index_requests/datagroups_initial.py index 4d14943..4c144af 100644 --- a/evdspy/EVDSlocal/index_requests/datagroups_initial.py +++ b/evdspy/EVDSlocal/index_requests/datagroups_initial.py @@ -1,13 +1,13 @@ -from .index_classes import GeneralIndexesDatagroups -from evdspy.EVDSlocal.common.files import Write, Read -from .data_models import DataModel, DataModelCSV, DataModelJSON -from .df_operations import DFOperations -from .error_classes_index import ContentFunctionError -from ..components.options_class import SingletonOptions -from ..requests_.ev_request import EVRequest - -# GID_csv = lambda x: GeneralIndexesDatagroups().get_csv -# GID_json = lambda x: GeneralIndexesDatagroups().get_json -data_strategy = {"csv": GeneralIndexesDatagroups(EVRequest_=EVRequest(options_=SingletonOptions())).get_csv, - "json": GeneralIndexesDatagroups().get_json} -data_models_dict = {"csv": DataModelCSV, "json": DataModelJSON} +from .index_classes import GeneralIndexesDatagroups +from evdspy.EVDSlocal.common.files import Write, Read +from .data_models import DataModel, DataModelCSV, DataModelJSON +from .df_operations import DFOperations +from .error_classes_index import ContentFunctionError +from ..components.options_class import SingletonOptions +from ..requests_.ev_request import EVRequest + +# GID_csv = lambda x: GeneralIndexesDatagroups().get_csv +# GID_json = lambda x: GeneralIndexesDatagroups().get_json +data_strategy = {"csv": GeneralIndexesDatagroups(EVRequest_=EVRequest(options_=SingletonOptions())).get_csv, + "json": GeneralIndexesDatagroups().get_json} +data_models_dict = {"csv": DataModelCSV, "json": DataModelJSON} diff --git a/evdspy/EVDSlocal/index_requests/df_operations.py b/evdspy/EVDSlocal/index_requests/df_operations.py index bf47d78..a52cb6c 100644 --- a/evdspy/EVDSlocal/index_requests/df_operations.py +++ b/evdspy/EVDSlocal/index_requests/df_operations.py @@ -1,123 +1,123 @@ -import time -import pandas as pd -from ..components.evds_files import DfColumnsDoesNotMatch -from ..config.config import config -from ..common.colors import print_with_failure_style, print_with_updating_style, print_with_info_style -from .data_models import * -from dataclasses import dataclass - - -@dataclass -class DFOperations(): - data_model: DataModel - df: pd.DataFrame = None - - @staticmethod - def extract_values_from_line(line: str, sep=","): - return line.split(sep) - - @staticmethod - def line_gen(buffer: str): - if not buffer: - return False - for item in buffer.split("\n"): - yield item - - def get_columns_from_first_row(self): - first_row = self.data_model.data.split("\n")[0].split(",") - return first_row - - def get_columns(self, df): - current_columns = df.columns # rangeIndex - if isinstance(current_columns, pd.RangeIndex): - current_columns_len = len([x for x in current_columns]) - else: - current_columns_len = len(current_columns) - potential_columns = self.get_columns_from_first_row() - if len(potential_columns) != current_columns_len: - raise DfColumnsDoesNotMatch() - df.columns = self.get_columns_from_first_row() - UnixTime = 'UNIXTIME' - if UnixTime in df.columns: - df.drop(UnixTime, axis=1, inplace=True) - if config.current_mode_is_test: - ... - # self.save_excel("testpytest2.xlsx") - return df - - def save_excel(self, name): - if isinstance(self.df, pd.DataFrame): - self.df.to_excel(name) - - @staticmethod - def list_to_df(items): - return pd.DataFrame(items) - - def make_df_float(self): - - def check_cols(x: str): - items = ( - "Tarih" not in x, - "WEEK" not in x, - "DAY" not in x, - ) - return all(items) - - columns = (x for x in self.df.columns if check_cols(x)) - other_cols = (x for x in self.df.columns if not check_cols(x)) - old_df = self.df - try: - self.df = self.df[columns].astype(float) - - except: - print_with_failure_style("Could not convert some columns to float type...") - for other_column in other_cols: - self.df[other_column] = old_df[other_column] - - def convert_to_df_abstract(self): - from rich import inspect - inspect(self.data_model) - obj = { - "csv": self.convert_csv_df, - "json": self.convert_json__df - } - fn = obj[self.data_model.type_name] - fn() - - def convert_json__df(self, json_buffer: str = None): - # print("To be implemented soon...") - print(json_buffer) - exit() - # raise NotImplementedError - - def convert_csv_df(self, csv_buffer: str = None): - if csv_buffer is None: - csv_buffer = self.data_model.data - pd_rows = list( - map(self.extract_values_from_line, - (item for item in self.line_gen(csv_buffer)) - ) - ) - if not pd_rows: - # print("convert_csv_df get empty buffer ") - return - pd_rows.pop(0) - self.df_no_columns = self.list_to_df(pd_rows) - try: - self.df = self.get_columns(self.df_no_columns) - except DfColumnsDoesNotMatch: - print_with_failure_style("columns did not match returning df with no columns...") - self.df = self.df_no_columns - print(self.df.head()) - # filename = "error_" + str(id(self.df)) + ".xlsx" - # print_with_updating_style("file was saved", filename) - # self.df.to_excel(filename) - print_with_info_style("This error will be checked again...") - time.sleep(1) - return False - except Exception as e: - print_with_failure_style(e) - pass - self.make_df_float() - - return self.df +import time +import pandas as pd +from ..components.evds_files import DfColumnsDoesNotMatch +from ..config.config import config +from ..common.colors import print_with_failure_style, print_with_updating_style, print_with_info_style +from .data_models import * +from dataclasses import dataclass + + +@dataclass +class DFOperations(): + data_model: DataModel + df: pd.DataFrame = None + + @staticmethod + def extract_values_from_line(line: str, sep=","): + return line.split(sep) + + @staticmethod + def line_gen(buffer: str): + if not buffer: + return False + for item in buffer.split("\n"): + yield item + + def get_columns_from_first_row(self): + first_row = self.data_model.data.split("\n")[0].split(",") + return first_row + + def get_columns(self, df): + current_columns = df.columns # rangeIndex + if isinstance(current_columns, pd.RangeIndex): + current_columns_len = len([x for x in current_columns]) + else: + current_columns_len = len(current_columns) + potential_columns = self.get_columns_from_first_row() + if len(potential_columns) != current_columns_len: + raise DfColumnsDoesNotMatch() + df.columns = self.get_columns_from_first_row() + UnixTime = 'UNIXTIME' + if UnixTime in df.columns: + df.drop(UnixTime, axis=1, inplace=True) + if config.current_mode_is_test: + ... + # self.save_excel("testpytest2.xlsx") + return df + + def save_excel(self, name): + if isinstance(self.df, pd.DataFrame): + self.df.to_excel(name) + + @staticmethod + def list_to_df(items): + return pd.DataFrame(items) + + def make_df_float(self): + + def check_cols(x: str): + items = ( + "Tarih" not in x, + "WEEK" not in x, + "DAY" not in x, + ) + return all(items) + + columns = (x for x in self.df.columns if check_cols(x)) + other_cols = (x for x in self.df.columns if not check_cols(x)) + old_df = self.df + try: + self.df = self.df[columns].astype(float) + + except: + print_with_failure_style("Could not convert some columns to float type...") + for other_column in other_cols: + self.df[other_column] = old_df[other_column] + + def convert_to_df_abstract(self): + from rich import inspect + inspect(self.data_model) + obj = { + "csv": self.convert_csv_df, + "json": self.convert_json__df + } + fn = obj[self.data_model.type_name] + fn() + + def convert_json__df(self, json_buffer: str = None): + # print("To be implemented soon...") + print(json_buffer) + exit() + # raise NotImplementedError + + def convert_csv_df(self, csv_buffer: str = None): + if csv_buffer is None: + csv_buffer = self.data_model.data + pd_rows = list( + map(self.extract_values_from_line, + (item for item in self.line_gen(csv_buffer)) + ) + ) + if not pd_rows: + # print("convert_csv_df get empty buffer ") + return + pd_rows.pop(0) + self.df_no_columns = self.list_to_df(pd_rows) + try: + self.df = self.get_columns(self.df_no_columns) + except DfColumnsDoesNotMatch: + print_with_failure_style("columns did not match returning df with no columns...") + self.df = self.df_no_columns + print(self.df.head()) + # filename = "error_" + str(id(self.df)) + ".xlsx" + # print_with_updating_style("file was saved", filename) + # self.df.to_excel(filename) + print_with_info_style("This error will be checked again...") + time.sleep(1) + return False + except Exception as e: + print_with_failure_style(e) + pass + self.make_df_float() + + return self.df diff --git a/evdspy/EVDSlocal/index_requests/error_classes_index.py b/evdspy/EVDSlocal/index_requests/error_classes_index.py index f3dac27..06bc03f 100644 --- a/evdspy/EVDSlocal/index_requests/error_classes_index.py +++ b/evdspy/EVDSlocal/index_requests/error_classes_index.py @@ -1,4 +1,4 @@ -class ContentFunctionError(BaseException): - """ContentFunctionError this - this one happens when strategy function is not Callable - """ +class ContentFunctionError(BaseException): + """ContentFunctionError this + this one happens when strategy function is not Callable + """ diff --git a/evdspy/EVDSlocal/index_requests/get_series_indexes.py b/evdspy/EVDSlocal/index_requests/get_series_indexes.py new file mode 100644 index 0000000..8c2cf7d --- /dev/null +++ b/evdspy/EVDSlocal/index_requests/get_series_indexes.py @@ -0,0 +1,463 @@ +from requests import HTTPError +from evdspy.EVDSlocal.utils.utils_test import get_api_key_while_testing +from .index_util_funcs import json_to_df, make_df_float +from evdspy.EVDSlocal.requests_.real_requests import * +from ..utils.github_actions import PytestTesting +from ... import save_apikey + +m_cache = MyCache() + +from enum import Enum, auto +import typing as t +from dataclasses import dataclass +from typing import Union + + +def default_start_date_fnc(): + return "01-01-2000" + + +def default_end_date_fnc(): + return "01-01-2100" + + +class AggregationType(Enum): + """ + avg : "avg" + min : "min" + max : "max" + first : "first" + last : "last" + sum : "sum" + + + """ + avg = "avg" + min = "min" + max = "max" + first = "first" + last = "last" + sum = "sum" + + +class Formulas(Enum): + """Formulas + Level: 0 + Percentage change: 1 + Difference: 2 + Year-to-year Percent Change: 3 + Year-to-year Differences: 4 + Percentage Change Compared to End-of-Previous Year: 5 + Difference Compared to End-of-Previous Year : 6 + Moving Average: 7 + Moving Sum: 8 + + """ + level = 0 + percentage_change = 1 + difference = 2 + year_to_year_percent_change = 3 + year_to_year_differences = 4 + percentage_change_compared = 5 + difference_compared = 6 + moving_average = 7 + moving_sum = 8 + + +class Frequency(Enum): + daily = 1 + business = 2 + weekly = 3 # Friday + semimonthly = 4 + monthly = 5 + quarterly = 6 + semiannually = 7 + annual = 8 + annually = 8 + + def __str__(self): + return f"{self.value}" + + def __call__(self, *args, **kwargs): + return f"&frequency={self.value}" + + +def freq_enum(frequency: Union[str, int]) -> str: + def get_enum(value: str): + obj = { + "daily": Frequency.daily, + "business": Frequency.business, + "weekly": Frequency.weekly, + "semimonthly": Frequency.semimonthly, + "monthly": Frequency.monthly, + "quarterly": Frequency.quarterly, + "semiannually": Frequency.semiannually, + "annual": Frequency.annually, + "annually": Frequency.annually, + } + return obj.get(value, Frequency.daily) + + if isinstance(frequency, int): + return f"&frequency={frequency}" + return get_enum(frequency)() + + +def replaceAll(index: str, old: str, new: str): + if old in index: + index = index.replace(old, new) + return replaceAll(index, old, new) + return index + + +def test_replaceAll(): + assert replaceAll("aaa", "a", "b") == "bbb" + assert "aaa".replace("a", "b") == "bbb" + + +@dataclass +class UserRequest: + index: t.Union[str, tuple[str]] + start_date: str = default_start_date_fnc() + end_date: str = default_end_date_fnc() + frequency: str = None + formulas: str = None + aggregation: str = None + cache: bool = False + proxy: str = None + proxies: dict = None + cache_name: str = "" + + def get_proxies(self): + if self.proxies is None: + if self.proxy is None: + proxies = None + else: + proxies = self.get_proxies_helper() + else: + proxies = self.proxies + return proxies + + def get_proxies_helper(self): + + if self.proxy is None: + return None + proxy = self.proxy + proxies = { + 'http': proxy, + 'https': proxy, + } + return proxies + + def __post_init__(self): + # print("post_init called") + + self.check_index() + self.index = tuple([self.index]) if not isinstance(self.index, (tuple, list,)) else self.index + # self.cache_name = f"{'_'.join(self.index)}_{self.start_date}_{self.end_date}" + self.domain = domain_for_ind_series() + self.series_part = create_series_part(self) + self.formulas = self.correct_type_to_tuple(self.formulas) + self.aggregation = self.correct_type_to_tuple(self.aggregation) + # self.check_aggregation_type() + # self.check_formulas() + self.check() + + # @staticmethod + def correct_type_to_tuple(self, value: any) -> tuple: + + if value is None: + return None + if isinstance(value, (list, tuple)): + if len(value) == len(self.index): + return value + if isinstance(value, (str,)): + return tuple(value for _ in self.index) + + return tuple(value[0] for _ in self.index) + + # def get_cache_name(self): + # return self.hash + @property + def hash(self): + import hashlib + return str(int(hashlib.sha256(self.url.encode('utf-8')).hexdigest(), 16) % 10 ** 8) + + def dry_request(self): + api_key = self.get_api_key(check=False) + proxies = self.get_proxies() + print(f""" +--------------------------------- + [debug mode is turned on] + + api_key = {api_key} + proxies = {proxies} + url = {self.url} + ! request was not made because debug mode is turned on + in order to make the request run get_series(... , debug = False ) + +--------------------------------- +""") + return self + + def __eq__(self, other): + return self.index == other.index and \ + self.cache_name == other.cache_name \ + and self.url == other.url \ + and self.hash == other.hash + + def is_ok(self): + df = self() + ok = isinstance(df, pd.DataFrame) + if not ok: + self.dry_request() + raise ValueError("request Not Ok") + else: + print("") + print(df.shape) + return ok + + def is_response_ok(self, response): + + return isinstance(response, requests.Response) \ + and response.status_code == 200 + + # @property + def get_api_key(self, check=True): + if PytestTesting().is_testing(): + api_key = get_api_key_while_testing() + else: + api_key = ApikeyClass().get_valid_api_key(check=check) + + return api_key + + def request(self): + api_key = self.get_api_key() + + proxies = self.get_proxies() + + @m_cache.cache + def local_request_w_cache(url: str) -> requests.Response: + requester = RealRequestWithParam(url, + proxies=proxies, + api_key=api_key) + return requester.request() + + def local_request(url: str) -> requests.Response: + requester = RealRequestWithParam(url, + proxies=proxies, + api_key=api_key) + return requester.request() + + req_func = local_request + if self.cache: + req_func = local_request_w_cache + response = req_func(self.url) + if not self.is_response_ok(response): + print(response) + raise HTTPError(response=response) + # print(response) + return response.json() + + def get(self): + return self.get_data() + + def __call__(self, *args, **kwargs): + return self.get() + + def get_data(self): + json_content = self.request() + df = json_to_df(json_content) + df = make_df_float(df) + return df + + @staticmethod + def template_to_tuple(index: str): + def clean(string: str): + return string.split("#")[0].strip() if len(string.split("#")) > 0 else None + + index = replaceAll(index, "\t", "\n") + index_tuple = index.splitlines() + + t = tuple(clean(x) for x in index_tuple) + return tuple(x for x in t if x is not None and len(x) > 3) + + def check_index(self): + if isinstance(self.index, (int, float,)): + raise ValueError("index must be a string ot tuple of string ") + if "\n" in self.index or "\t" in self.index: + self.index = self.template_to_tuple(self.index) + + def basic_url(self): + + return f"{self.domain}/series={self.series_part}&startDate={self.start_date}&endDate={self.end_date}&type=json" + + def freq_str(self) -> str: + if self.frequency is None: + return "" + + if isinstance(self.frequency, int): + return f"&frequency={self.frequency}" + return freq_enum(self.frequency) + + def aggregation_type_to_str(self): + if self.aggregation is None: + return "" + + string = "-".join(self.aggregation) + return "&aggregationTypes=" + string + + def formulas_to_str(self): + if self.formulas is None: + return "" + index = tuple([self.index]) if not isinstance(self.index, (tuple, list,)) else self.index + formulas = self.formulas if isinstance(self.formulas, (tuple, list,)) else tuple(self.formulas for _ in index) + string = "-".join(formulas) + return f"&formulas={string}" + + def check(self): + if self.formulas is not None: + assert len(self.formulas) == len(self.index) + if self.aggregation is not None: + assert len(self.aggregation) == len(self.index) + + @property + def url(self): + if self.frequency is None and self.aggregation is None: + return self.basic_url() + formulas_str = self.formulas_to_str() + aggregation_type_str = self.aggregation_type_to_str() + freq_string = self.freq_str() + # series = TP.ODEMGZS.BDTTOPLAM + # "https://evds2.tcmb.gov.tr/service/evds/series=TP.ODEMGZS.BDTTOPLAM-TP.ODEMGZS.ABD-TP.ODEMGZS.ARJANTIN-TP.ODEMGZS.BREZILYA-TP.ODEMGZS.KANADA-TP.ODEMGZS.KOLOMBIYA-TP.ODEMGZS.MEKSIKA-TP.ODEMGZS.SILI&startDate=01-01-2019&endDate=01-12-2030&frequency=5&aggregationTypes=avg-avg-avg-avg-avg-avg-avg-avg&formulas=0-0-0-0-0-0-0-0&type=csv" + # &startDate=01-01-2019&endDate=01-12-2030&frequency=5&aggregationTypes=avg-avg-avg-avg-avg-avg-avg-avg&formulas=0-0-0-0-0-0-0-0&type=json" + # &startDate=01-01-2019&endDate=01-12-2030&type=json" + return f"{self.domain}/series={self.series_part}{freq_string}{formulas_str}{aggregation_type_str}&startDate={self.start_date}&endDate={self.end_date}&type=json" + + +def domain_for_ind_series(): + return "https://evds2.tcmb.gov.tr/service/evds" + + +def create_series_part(user_req): + # print("create_series_part") + indexes = user_req.index + if isinstance(indexes, str): + indexes = tuple([indexes]) + return "-".join(indexes) + + +def create_url_for_series(user_req: UserRequest) -> str: + # print("create_url_for_series") + domain = domain_for_ind_series() + series_part = create_series_part(user_req) + return f"{domain}/series={series_part}&startDate={user_req.start_date}&endDate={user_req.end_date}&type=json" + + +def get_series( + index: t.Union[str, tuple[str]], + start_date: str = default_start_date_fnc(), + end_date: str = default_end_date_fnc(), + frequency: str = None, + formulas: str = None, + aggregation: str = None, + cache: bool = False, + proxy: str = None, + proxies: dict = None, + debug: bool = False, + api_key: str = None + +) -> pd.DataFrame: + """ + returns all series as pandas DataFrame + + example usages + template = ''' + TP.ODEMGZS.BDTTOPLAM + TP.ODEMGZS.ABD + TP.ODEMGZS.ARJANTIN + + ''' + + df = get_series( template ) + + df1 = get_series( template , start_date = "01-01-2000" , frequency = "monthly" ) + + df2 = get_series('TP.ODEMGZS.BDTTOPLAM' , start_date = "01-01-2000" , frequency = "monthly" , cache = True ) + + df3 = get_series( template , start_date = "01-01-2000" , frequency = "monthly" , formulas = "avg" ) + + df3 = get_series( template , start_date = "01-01-2000" , frequency = "monthly" , formulas = ("avg" , "min" , "avg" ) ) + + + + + :param index: str or tuple[str] + :param start_date: str + :param end_date: str + :param frequency: str + :param formulas: str | tuple[str] + :param aggregation: str| tuple[str] + :param cache: bool True for using cached data when possible + :param proxy: str (default=None) + :param proxies: dict (default=None) + :param debug: bool True for debugging + :return: pd.DataFrame + + + + + + """ + if api_key: + if ApikeyClass().get_valid_api_key(check=False) is False: + save_apikey(api_key) + + user_req = UserRequest(index, + start_date=start_date, + end_date=end_date, + frequency=frequency, + formulas=formulas, + aggregation=aggregation, + cache=cache, + proxy=proxy, + proxies=proxies + ) + if debug: + return user_req.dry_request() + return user_req() + + +def test_aggr_types(capsys): + balance_of_pay1 = "TP.ODEMGZS.BDTTOPLAM", "TP.ODEMGZS.ABD" + + balance_of_pay2 = """ + + TP.ODEMGZS.BDTTOPLAM # + TP.ODEMGZS.ABD # + + """ + cache = True + with capsys.disabled(): + u1 = UserRequest(balance_of_pay1, + frequency="weekly", + start_date=default_start_date_fnc(), + end_date=default_end_date_fnc(), + aggregation=("avg",), + # proxy="http://127.0.0.1:8000", + # proxies={"http": "http://127.0.0.1:8000"}, + cache=cache, + ) + + u2 = UserRequest(balance_of_pay2, + frequency="weekly", + start_date=default_start_date_fnc(), + end_date=default_end_date_fnc(), + aggregation=("avg",), + # proxy="http://127.0.0.1:8000", + # proxies={"http": "http://127.0.0.1:8000"}, + cache=cache, + ) + assert u1 == u2 + + +__all__ = ['get_series'] diff --git a/evdspy/EVDSlocal/index_requests/index_classes.py b/evdspy/EVDSlocal/index_requests/index_classes.py index 26c0f36..97f037e 100644 --- a/evdspy/EVDSlocal/index_requests/index_classes.py +++ b/evdspy/EVDSlocal/index_requests/index_classes.py @@ -1,153 +1,153 @@ -from ..components.url_class import * -from ..components.api_params import * -from ..components.api_params import EVDSApiDomainCategories, ModeParamDataGroups, CodeParamDataGroups -from ..config.apikey_class import ApikeyClass -from dataclasses import dataclass -from ..requests_.ev_request import EVRequest -from ..messages.error_classes import ApiKeyNotSetError -from ..components.options_class import SingletonOptions -import typing as t - - -@dataclass -class GeneralIndexesBase(ABC): - """GeneralIndexesBase""" - domain: t.Union[str, EVDSApiDomain] - EVRequest_: EVRequest = None - type_param: dataTypeEnum = dataTypeEnum.csv # csv or json - mode: ModeEnumDatagroup = ModeEnumDatagroup.all_groups - code: int = 1 - - # EVRequest_: EVRequest = EVRequest() - - def __repr__(self): - res = f""" -class : [{self.__class__.__name__} ] -mode : [{self.mode}] -code : [{self.code}] -url : [{self.EVRequest_.URL_Instance.url}] -""" - return res - - def __str__(self): - res = f""" -class : [{self.__class__.__name__} ] -mode : [{self.mode}] -code : [{self.code}] -url : [{self.EVRequest_.URL_Instance.url}] -""" - return res - - def create_url_first_part(self): - self.api_key = ApikeyClass().get_valid_api_key() - full_list = [] - self.complete_url_instance = URLClass(full_list, domain=str(self.domain)) - self.complete_url_instance.add_apikey(self.api_key) - # self.complete_url_instance.add_item(dataTypeParam(self.type_param)) - - def create_url(self): - self.create_url_first_part() - self.add_extra_params() - self.complete_url_instance.refresh_url() - self.complete_url_instance.create_report() - self.EVRequest_.URL_Instance = self.complete_url_instance - if not self.api_key: - raise ApiKeyNotSetError - return self.complete_url_instance.url - - def add_extra_params(self, mode: int = 1, code: t.Union[int, str] = None): - ... - - def get_csv(self, url: str = None): - - self.create_url() - - if url is None: - url = self.EVRequest_.URL_Instance.url - self.EVRequest_.URL_Instance = self.complete_url_instance - result = self.EVRequest_.get_request_before_cache(f"{url}&type=csv") - if hasattr(result, "text"): - self.csv = result.text - return result.text - return False - - def get_json(self, url: str = None): - # raise NotImplementedError - self.create_url() - - if url is None: - url = self.EVRequest_.URL_Instance.url - self.EVRequest_.URL_Instance = self.complete_url_instance - result = self.EVRequest_.get_request_before_cache(f"{url}&type=json") - if hasattr(result, "json"): - self.csv = result.json() - return result.json() - - return False - - -class dataGroupsNeedsCode(BaseException): - """dataGroupsNeedsCode""" - - -@dataclass -class GeneralIndexesCategories(GeneralIndexesBase): - """GeneralIndexesCategories""" - domain: t.Union[str, EVDSApiDomain] = field(default_factory=EVDSApiDomainCategories) - - -@dataclass -class GeneralIndexesDatagroups(GeneralIndexesBase): - """GeneralIndexesDatagroups""" - domain: t.Union[str, EVDSApiDomain] = field(default_factory=EVDSApiDomainDatagroups) - - def add_extra_params(self, mode: int = 2, code: int = None): - self.complete_url_instance.add_mode(mode) - if code is None: - code = self.code - self.complete_url_instance.add_code(code) - - -@dataclass -class GeneralIndexesDatagroupIndividual(GeneralIndexesBase): - """GeneralIndexesDatagroups""" - domain: t.Union[str, EVDSApiDomain] = field(default_factory=EVDSApiDomainDatagroupIndividual) - - def add_extra_params(self, mode: int = 2, code: str = None): - ... - self.complete_url_instance.add_frame(code) - # self.complete_url_instance.add_mode(mode) - # if code is None: - # code = self.code - # self.complete_url_instance.add_code(code) - - def get_json(self, url: str = None): - - if url is None: - url = self.complete_url_instance.url - result = self.EVRequest_.get_request_before_cache(f"{url}&type=json") - if hasattr(result, "json"): - self.csv = result.json() - return result.json() - - return False - - -@dataclass -class GeneralIndexesDatagroupSeriesList(GeneralIndexesDatagroupIndividual): - """GeneralIndexesDatagroups""" - domain: t.Union[str, EVDSApiDomain] = field(default_factory=EVDSApiDominDatagroupSeriesList) - - def add_extra_params(self, mode: int = 2, code: str = None): - self.complete_url_instance.add_code(code) - - def get_json(self, url: str = None): - - if url is None: - url = self.complete_url_instance.url - result = self.EVRequest_.get_request_before_cache(f"{url}&type=json") - if hasattr(result, "json"): - self.csv = result.json() - return result.json() - - return False +from ..components.url_class import * +from ..components.api_params import * +from ..components.api_params import EVDSApiDomainCategories, ModeParamDataGroups, CodeParamDataGroups +from ..config.apikey_class import ApikeyClass +from dataclasses import dataclass +from ..requests_.ev_request import EVRequest +from ..messages.error_classes import ApiKeyNotSetError +from ..components.options_class import SingletonOptions +import typing as t + + +@dataclass +class GeneralIndexesBase(ABC): + """GeneralIndexesBase""" + domain: t.Union[str, EVDSApiDomain] + EVRequest_: EVRequest = None + type_param: dataTypeEnum = dataTypeEnum.csv # csv or json + mode: ModeEnumDatagroup = ModeEnumDatagroup.all_groups + code: int = 1 + + # EVRequest_: EVRequest = EVRequest() + + def __repr__(self): + res = f""" +class : [{self.__class__.__name__} ] +mode : [{self.mode}] +code : [{self.code}] +url : [{self.EVRequest_.URL_Instance.url}] +""" + return res + + def __str__(self): + res = f""" +class : [{self.__class__.__name__} ] +mode : [{self.mode}] +code : [{self.code}] +url : [{self.EVRequest_.URL_Instance.url}] +""" + return res + + def create_url_first_part(self): + self.api_key = ApikeyClass().get_valid_api_key() + full_list = [] + self.complete_url_instance = URLClass(full_list, domain=str(self.domain)) + self.complete_url_instance.add_apikey(self.api_key) + # self.complete_url_instance.add_item(dataTypeParam(self.type_param)) + + def create_url(self): + self.create_url_first_part() + self.add_extra_params() + self.complete_url_instance.refresh_url() + self.complete_url_instance.create_report() + self.EVRequest_.URL_Instance = self.complete_url_instance + if not self.api_key: + raise ApiKeyNotSetError + return self.complete_url_instance.url + + def add_extra_params(self, mode: int = 1, code: t.Union[int, str] = None): + ... + + def get_csv(self, url: str = None): + + self.create_url() + + if url is None: + url = self.EVRequest_.URL_Instance.url + self.EVRequest_.URL_Instance = self.complete_url_instance + result = self.EVRequest_.get_request_before_cache(f"{url}&type=csv") + if hasattr(result, "text"): + self.csv = result.text + return result.text + return False + + def get_json(self, url: str = None): + # raise NotImplementedError + self.create_url() + + if url is None: + url = self.EVRequest_.URL_Instance.url + self.EVRequest_.URL_Instance = self.complete_url_instance + result = self.EVRequest_.get_request_before_cache(f"{url}&type=json") + if hasattr(result, "json"): + self.csv = result.json() + return result.json() + + return False + + +class dataGroupsNeedsCode(BaseException): + """dataGroupsNeedsCode""" + + +@dataclass +class GeneralIndexesCategories(GeneralIndexesBase): + """GeneralIndexesCategories""" + domain: t.Union[str, EVDSApiDomain] = field(default_factory=EVDSApiDomainCategories) + + +@dataclass +class GeneralIndexesDatagroups(GeneralIndexesBase): + """GeneralIndexesDatagroups""" + domain: t.Union[str, EVDSApiDomain] = field(default_factory=EVDSApiDomainDatagroups) + + def add_extra_params(self, mode: int = 2, code: int = None): + self.complete_url_instance.add_mode(mode) + if code is None: + code = self.code + self.complete_url_instance.add_code(code) + + +@dataclass +class GeneralIndexesDatagroupIndividual(GeneralIndexesBase): + """GeneralIndexesDatagroups""" + domain: t.Union[str, EVDSApiDomain] = field(default_factory=EVDSApiDomainDatagroupIndividual) + + def add_extra_params(self, mode: int = 2, code: str = None): + ... + self.complete_url_instance.add_frame(code) + # self.complete_url_instance.add_mode(mode) + # if code is None: + # code = self.code + # self.complete_url_instance.add_code(code) + + def get_json(self, url: str = None): + + if url is None: + url = self.complete_url_instance.url + result = self.EVRequest_.get_request_before_cache(f"{url}&type=json") + if hasattr(result, "json"): + self.csv = result.json() + return result.json() + + return False + + +@dataclass +class GeneralIndexesDatagroupSeriesList(GeneralIndexesDatagroupIndividual): + """GeneralIndexesDatagroups""" + domain: t.Union[str, EVDSApiDomain] = field(default_factory=EVDSApiDominDatagroupSeriesList) + + def add_extra_params(self, mode: int = 2, code: str = None): + self.complete_url_instance.add_code(code) + + def get_json(self, url: str = None): + + if url is None: + url = self.complete_url_instance.url + result = self.EVRequest_.get_request_before_cache(f"{url}&type=json") + if hasattr(result, "json"): + self.csv = result.json() + return result.json() + + return False diff --git a/evdspy/EVDSlocal/index_requests/index_util_funcs.py b/evdspy/EVDSlocal/index_requests/index_util_funcs.py index ac8e327..d2f2315 100644 --- a/evdspy/EVDSlocal/index_requests/index_util_funcs.py +++ b/evdspy/EVDSlocal/index_requests/index_util_funcs.py @@ -1,69 +1,72 @@ -import pandas as pd -import typing as t - -from ..common.colors import print_with_failure_style - - -def make_date_first_column_helper(df, col_name): - if not col_name in df.columns: - return df - cols = [col_name] + [col for col in df if col != col_name] - df = df[cols] - return df - - -def make_date_first_column(df): - col_names = ('YEARWEEK', 'Tarih',) - for col_name in col_names: - df = make_date_first_column_helper(df, col_name) - return df - - -def drop_unix(df): - UnixTime = 'UNIXTIME' - if UnixTime in df.columns: - df.drop(UnixTime, axis=1, inplace=True) - return df - -def json_to_df(json_content: t.Union[list, dict]): - if hasattr(json_content, 'items'): - json_content = json_content['items'] - df = pd.DataFrame.from_records(json_content) - df = drop_unix(df) - df = make_date_first_column(df) - return df - - -def make_df_float(df): - def check_cols(x: str): - items = ( - "Tarih" not in x, - "WEEK" not in x, - "DAY" not in x, - "YEAR" not in x, - ) - return all(items) - - columns = (x for x in df.columns if check_cols(x)) - other_cols = (x for x in df.columns if not check_cols(x)) - old_df = df - try: - df = df[columns].astype(float) - - except: - print_with_failure_style("Could not convert some columns to float type...") - - for other_column in other_cols: - df[other_column] = old_df[other_column] - return df - - -def json_to_excel(json_content: list, file_name, try_float=True): - df = json_to_df(json_content) - if try_float: - df = make_df_float(df) - try: - df = make_date_first_column(df) - df.to_excel(file_name) - except: - print(f"could not write excel file {file_name}. =>file is probably open") +import pandas as pd +import typing as t + +from ..common.colors import print_with_failure_style +from ..components.excel_class import correct_folder + + +def make_date_first_column_helper(df, col_name): + if not col_name in df.columns: + return df + cols = [col_name] + [col for col in df if col != col_name] + df = df[cols] + return df + + +def make_date_first_column(df): + col_names = ('YEARWEEK', 'Tarih',) + for col_name in col_names: + df = make_date_first_column_helper(df, col_name) + return df + + +def drop_unix(df): + UnixTime = 'UNIXTIME' + if UnixTime in df.columns: + df.drop(UnixTime, axis=1, inplace=True) + return df + + +def json_to_df(json_content: t.Union[list, dict]): + if hasattr(json_content, 'items'): + json_content = json_content['items'] + df = pd.DataFrame.from_records(json_content) + df = drop_unix(df) + df = make_date_first_column(df) + return df + + +def make_df_float(df): + def check_cols(x: str): + items = ( + "Tarih" not in x, + "WEEK" not in x, + "DAY" not in x, + "YEAR" not in x, + ) + return all(items) + + columns = (x for x in df.columns if check_cols(x)) + other_cols = (x for x in df.columns if not check_cols(x)) + old_df = df + try: + df = df[columns].astype(float) + + except: + print_with_failure_style("Could not convert some columns to float type...") + + for other_column in other_cols: + df[other_column] = old_df[other_column] + return df + + +def json_to_excel(json_content: list, file_name, try_float=True): + file_name = correct_folder(file_name, "xlsx") + df = json_to_df(json_content) + if try_float: + df = make_df_float(df) + try: + df = make_date_first_column(df) + df.to_excel(file_name) + except: + print(f"could not write excel file {file_name}. =>file is probably open") diff --git a/evdspy/EVDSlocal/index_requests/real_reqs_tests.py b/evdspy/EVDSlocal/index_requests/real_reqs_tests.py new file mode 100644 index 0000000..c54de95 --- /dev/null +++ b/evdspy/EVDSlocal/index_requests/real_reqs_tests.py @@ -0,0 +1,46 @@ +def test1_real_reqs(): + from evdspy.EVDSlocal.index_requests.get_series_indexes import UserRequest, default_start_date_fnc, \ + default_end_date_fnc + + """ + + TP.BFTUKKRE.L001 TP.BFTUKKRE.L010 TP.BFTUKKRE.L011 TP.BFTUKKRE.L012 + + """ + + credits_template = ("TP.BFTUKKRE.L001", "TP.BFTUKKRE.L010", "TP.BFTUKKRE.L011", "TP.BFTUKKRE.L012",) + + ur = UserRequest("TP.ODEMGZS.BDTTOPLAM") + print(ur.url) + assert ur.url == "https://evds2.tcmb.gov.tr/service/evds/series=TP.ODEMGZS.BDTTOPLAM&startDate=01-01-2000&endDate=01-01-2100&type=json" + print(ur) + balance_of_pay = "TP.ODEMGZS.BDTTOPLAM", "TP.ODEMGZS.ABD" + cache = False + ur = UserRequest(balance_of_pay, + frequency="weekly", + start_date=default_start_date_fnc(), + end_date=default_end_date_fnc(), + aggregation=("avg",), + proxy="http://127.0.0.1:8000", + proxies={"http": "http://127.0.0.1:8000"}, + cache=cache) + ur.dry_request() + d1 = ur() + print(d1) + + ur = UserRequest(credits_template, + frequency="weekly", + start_date=default_start_date_fnc(), + end_date=default_end_date_fnc(), + aggregation=("avg",), + proxy="http://127.0.0.1:8000", + proxies={"http": "http://127.0.0.1:8000"}, + cache=cache) + + print(ur.url) + # result = ur.request() + ur.dry_request() + + d2 = ur() + print(d2) + return d1, d2 diff --git a/evdspy/EVDSlocal/initial/cmd_line_classes.py b/evdspy/EVDSlocal/initial/cmd_line_classes.py index dc65bc5..9f8f9c1 100644 --- a/evdspy/EVDSlocal/initial/cmd_line_classes.py +++ b/evdspy/EVDSlocal/initial/cmd_line_classes.py @@ -1,9 +1,9 @@ -from dataclasses import dataclass -import typing as t - - -@dataclass -class CommandLineCommandClass: - name_list: t.Tuple - func: t.Callable - +from dataclasses import dataclass +import typing as t + + +@dataclass +class CommandLineCommandClass: + name_list: t.Tuple + func: t.Callable + diff --git a/evdspy/EVDSlocal/initial/command_pictures.py b/evdspy/EVDSlocal/initial/command_pictures.py index 484adb9..b92e6f0 100644 --- a/evdspy/EVDSlocal/initial/command_pictures.py +++ b/evdspy/EVDSlocal/initial/command_pictures.py @@ -1,17 +1,17 @@ -from .load_commands_cmds_to_load import get_df_datagroup - - - -from evdspy import * - -df_exchange_rate = get_df_datagroup( - datagroup="bie_dkdovytl", - start_date='01-01-2010', - end_date='01-01-2030', -) - - - - - - +from .load_commands_cmds_to_load import get_df_datagroup + + + +from evdspy import * + +df_exchange_rate = get_df_datagroup( + datagroup="bie_dkdovytl", + start_date='01-01-2010', + end_date='01-01-2030', +) + + + + + + diff --git a/evdspy/EVDSlocal/initial/load_commands_.py b/evdspy/EVDSlocal/initial/load_commands_.py index 629ecd0..f229bd3 100644 --- a/evdspy/EVDSlocal/initial/load_commands_.py +++ b/evdspy/EVDSlocal/initial/load_commands_.py @@ -1,35 +1,35 @@ -from ..messages.error_messages import * -from .load_commands_cmds_to_load import * - -# ---------------------------------------------------------------/ MAIN LOAD - -__all__ = [ - 'easy_setup', - 'setup', - 'setup_series', - "setup_series_steps", - 'help_evds', - 'check', - 'get', - 'h', - 'help_evdspy', - 'help_', - 'create_series_file', - 'csf', - 'show', - 'get_df_test', - 'console', - 'menu', - 'menu_onload', - 'version', - 'save_apikey', - 'save', - 'remove_cache', - 'create_options_file', - 'cof', - 'console_main', - 'get_df_datagroup', - 'get_datagroups_with_code', - 'get_category_name' , - 'get_series_list_of_subject' -] +from ..messages.error_messages import * +from .load_commands_cmds_to_load import * + +# ---------------------------------------------------------------/ MAIN LOAD + +__all__ = [ + 'easy_setup', + 'setup', + 'setup_series', + "setup_series_steps", + 'help_evds', + 'check', + 'get', + 'h', + 'help_evdspy', + 'help_', + 'create_series_file', + 'csf', + 'show', + 'get_df_test', + 'console', + 'menu', + 'menu_onload', + 'version', + 'save_apikey', + 'save', + 'remove_cache', + 'create_options_file', + 'cof', + 'console_main', + 'get_df_datagroup', + 'get_datagroups_with_code', + 'get_category_name' , + 'get_series_list_of_subject' +] diff --git a/evdspy/EVDSlocal/initial/load_commands_cmds_to_load.py b/evdspy/EVDSlocal/initial/load_commands_cmds_to_load.py index 5756a41..fac6ba7 100644 --- a/evdspy/EVDSlocal/initial/load_commands_cmds_to_load.py +++ b/evdspy/EVDSlocal/initial/load_commands_cmds_to_load.py @@ -1,558 +1,558 @@ -# functions that will be loaded -import platform -import sys -import time - -import pandas as pd - -from evdspy.EVDSlocal.console.menu import MenuMaker, MenuItem -from .cmd_line_classes import CommandLineCommandClass -from evdspy.EVDSlocal.initial_setup.api_key_save import save_api_key_to_file -from typing import Callable -from ..common.prog import rich_sim -from ..common.table import Table2_ -from ..index_requests.categories import get_category_name -from ..index_requests.datagroup_individual import get_datagroup_individual_with_code, get_series_list_of_subject, \ - get_df_datagroup -from ..messages.error_messages import * -from ..messages.error_classes import * -from evdspy.EVDSlocal.initial.load_modules import LoadModulesClass -from ..initial_setup.initial_setups import * -from ..requests_.my_cache import delete_cache_folder -from ..setup_project.user_setup import start_setup_series, start_setup_config -from evdspy.EVDSlocal.initial_setup.setup_folders import check_folders_setup_necessary, check_setup -from ..messages.help_messages import welcome_message -from ..utils.utils_general import * -from ..index_requests.datagroups import get_datagroups_with_code - - -assert get_datagroups_with_code -assert get_category_name -assert get_series_list_of_subject - -""" -Loaded functions for DF -get_df_datagroup -""" -assert callable(get_df_datagroup) - - -def check_which_command_params(params, extra_params: dict): - create_series_cmd = CommandLineCommandClass(name_list=("create", "series",), - func=setup_series) - help_cmd = CommandLineCommandClass(name_list=("help",), - func=help_evds) - create_options_cmd = CommandLineCommandClass(name_list=("create", "options",), - func=create_options_file) - get_cmd = CommandLineCommandClass(name_list=("get",), func=get) - setup_cmd = CommandLineCommandClass(name_list=("setup",), func=setup) - menu_cmd = CommandLineCommandClass(name_list=("menu",), func=menu) - save_cmd = CommandLineCommandClass(name_list=("save",), func=save) - console_cmd = CommandLineCommandClass(name_list=("console",), func=console_load) - menu_list = (create_series_cmd, create_options_cmd, get_cmd, setup_cmd, menu_cmd, help_cmd, save_cmd, console_cmd) - - def check_item_exists(element, format_cmd_list): - return element in format_cmd_list - - def check_item_exists_wrapper(item): - return check_item_exists(item, params) - - def check_cmd_will_apply(cmd_class: CommandLineCommandClass): - # return check_item_exists, items - return all(map(check_item_exists_wrapper, cmd_class.name_list)) - - from itertools import compress - functions_will_apply_iter = tuple(map(check_cmd_will_apply, menu_list)) - functions_will_apply = list(compress(menu_list, functions_will_apply_iter)) - for fnc_class in functions_will_apply: - if callable(fnc_class.func): - fnc_class.func() - return functions_will_apply - - -def menu(*args, **kw): - menu_helper() - # if CurrentState().menu_will_open: - # menu_helper() - - -# -------------------------------- Entry point ---cmd line prompt------------------------------------ -def console_main(test_args=None): - # test_args = tuple(["series", "create"]) - if test_args: - params_command = test_args - else: - params_command = sys.argv[1:] - params_command_as_dict = arg_acc(params_command) - if not params_command: - welcome_message() - check_which_command_params(params_command, arg_acc()) - - -# -------------------------------- Entry point ---cmd line prompt------------------------------------ -def console_main_from_the_menu(): - welcome_message() - - -def easy_setup(): - setup() - - -def setup_again(): - setup() - - -def setup(): - SetupInitial().setup() - start_setup_config(onsetup=True) - create_series_text_example(onsetup=True) - - -def help_evds(): - display_help_messages() - - -def help_(): - return help_evds() - - -def h(): - return help_evds() - - -def help_evdspy(): - return help_evds() - - -def check(): - print_with_updating_style("checking....") - lmc = LoadModulesClass() - lmc.check() - - -def show(): - lmc = LoadModulesClass() - lmc.series_from_file() - lmc.summary() - - -def get_input(msg): - if config.current_mode_is_test: - return "test" - print_get_input_style(msg) - ans = input() - return str(ans) - - -def wait(num: int): - time.sleep(num) - - -def save_api_key_to_file_main(api_key): - @dataclass - class transfer(): - get_input: Callable = get_input - wait: Callable = wait - - save_api_key_to_file(instance=transfer(), api_key_answer=api_key) - - -def console_load(): - ... - - -def check_setup_runtime(): - return not check_folders_setup_necessary() - - -def check_if_api_set_before_get(): - if not check_api_key(): - print_with_failure_style(api_key_not_set_msg) - wait(2) - if not get_input("yes/no ? ").lower() in ["yes", "y"]: - wait(2) - return - # below the function checks - # if api key is valid then saves it - if not set_apikey_input(): - return False - print_with_success_style("finished") - return True - return True - - -def get(): - if not check_setup(): - print_with_updating_style("Checking setup...") - # setup_folders() - SetupInitial().setup() - if not check_if_api_set_before_get(): - return - try: - lmc = LoadModulesClass() - lmc.series_from_file() - # lmc.display_items(lmc.series_from_file()) - - lmc.summary() - # try: - # lmc.evds_list[0].df.plot(x='TP.ODEMGZS.BDTTOPLAM', y='Index', style='o') - # except: - # pass - except SeriesFileDoesNotExists: - print("...") - # print(SeriesFileDoesNotExists().message) - - -def get_df_test(): - LoadModulesClass().series_from_file() - LoadModulesClass().summary() - return LoadModulesClass().evds_list[0].df - - -from ..config.apikey_class import * -from evdspy.EVDSlocal.requests_.lower_energy import * -from rich import inspect - -from typing import List -from evdspy.EVDSlocal.index_requests.datagroups import get_and_process_datagroups_with_code, \ - get_all_groups, get_datagroups_with_code -from evdspy.EVDSlocal.index_requests.index_util_funcs import json_to_df - -import typing as t - -from functools import partial - - -def get_input_for_categs_data_groups(list_of_categs: List[tuple], display_fn, callback: t.Callable = None): - callback_forward = partial(get_input_for_categs_data_groups, list_of_categs, display_fn, None) - callables = (display_fn, callback_forward) - if config.current_mode_is_test: - return - ids = (str(x[0]) for x in list_of_categs) - - # print_with_success_style('Preparing the menu...') - # print("\n\n") - # time.sleep(2) - - ans = input("Choose a Category number [e/exit to go back] Selection Number==>") - if str(ans).lower().strip() in ('e', 'exit'): - if callable(callback): - print("now calling back ", display_fn, callback) - display_fn() - callback() - return - if str(ans) in ids: - codes_and_titles = get_and_process_datagroups_with_code(int(ans)) - get_input_for_categs_data_groups_deeper(codes_and_titles, callables) - - -def get_input_for_categs_data_groups_deeper(codes_and_titles: List[tuple], callables: t.Tuple[any, partial] = None): - codes = tuple(x[0] for x in codes_and_titles) - nums = tuple(str(x + 1) for x in range(len(codes_and_titles))) - titles = tuple(x[1] for x in codes_and_titles) - combine_list = list(zip(nums, codes, titles)) - if config.current_mode_is_test: - return - # print(codes_and_titles) - # print("\n\n") - Table2_().show(list_=combine_list, title='', columns=('Selection Number', 'code', 'title'), skiprow=0) - # print_with_success_style('Preparing the menu...') - - # time.sleep(2) - - ans = input("Choose a Category number [e/exit to go back] Selection Number==>") - if str(ans).lower().strip() in ('e', 'exit'): - if callables: - for callback in callables: - if callable(callback) or isinstance(callback, partial): - callback() - time.sleep(1) - return - if str(ans) in nums: - code_str = codes[int(ans) - 1] - try: - json_content = get_datagroup_individual_with_code(code_str) - # print(json_content) - df = json_to_df(json_content) - print(df.head()) - series_docs = get_series_list_of_subject(code_str) - - df_exp: pd.DataFrame = json_to_df(series_docs) - print_with_success_style( - "Getting explanations for the series...after this process both excel files will be created...[1-Data , 2-Explanations] " - ) - time.sleep(1) - print(df_exp.head()) - # print(series_docs) - except: - print_with_failure_style( - f"...json content is not proper to convert to a pd.DataFrame .. passing this one... code : {code_str}") - pass - - df_exp: pd.DataFrame = json_to_df(series_docs) - print_with_success_style( - "Getting explanations for the series...after this process both excel files will be created...[1-Data , 2-Explanations] " - ) - time.sleep(1) - print(df_exp.head()) - # print(series_docs) - - print(ans, " ... done.") - get_input_for_categs_data_groups_deeper(codes_and_titles, callables) - # codes_and_titles = get_and_process_datagroups_with_code(int(ans)) - # get_input_for_categs_data_groups_deeper(codes_and_titles) - - -def get_categories_main(): - if not check_if_api_set_before_get(): - return - # from ..index_requests.categories import get_categories_data - from ..index_requests.categories import display_categories - list_of_categs: List[tuple] = display_categories() # [( id , eng , tr ) , ( id , eng , tr ) ...] - get_input_for_categs_data_groups(list_of_categs, display_fn=display_categories) - - # categories = get_categories_data() - # inspect(categories, all=True) - # print_with_success_style(categories) - - -def get_datagroups_data_main(): - ... - # from ..index_requests.datagroups import get_datagroups_data - # categories = get_datagroups_data() - # inspect(categories, all=True) - # print_with_success_style(categories) - - -def check_api_key_with_low_energy(api_key_from_user): - # check api key with cache - # send => basic_for_test > performance.lower_energy - if not apikey_works(api_key_from_user): - print_with_failure_style(f"Api key did not work! => {api_key_from_user}") - return False - print_with_success_style(f"Api key works => {api_key_from_user}") - return True - - -def obvious_checks_of_api_key(api_key: str) -> bool: - conds: tuple = (isinstance(api_key, str), not len(api_key) < 10,) - return all(conds) - - -def save_apikey(api_key: str = None): - if api_key is None or not isinstance(api_key, str): - return set_apikey_input() - check_apikey_and_then_save(api_key) - - -def check_apikey_and_then_save(api_key_from_user): - if not obvious_checks_of_api_key(api_key_from_user): - print_with_failure_style( - f"The text you entered does not meet criteria to be an valid api key. \n" - f"{indent}(length of api key cannot be less then 10) {api_key_from_user}") - return False - """this function will save redundant requests by catching earlier check results """ - if not check_api_key_with_low_energy(api_key_from_user): - return False - """""" - """ SAVE IT TO FILE """ - save_api_key_to_file_main(api_key_from_user) - """ SAVE IT FOR RUNTIME """ - ApikeyClass().set_api_key_runtime(value=api_key_from_user) - show_apikey() - return True - - -def set_apikey_input(api_key=None, from_console=False): - exit_words = ["e", "exit"] - if config.current_mode_is_test: - print_with_updating_style("pytest returns ") - ans = "test" - else: - if not from_console: - ans = get_input("Api key [ `e` or `exit` to cancel] : ") - else: - ans = api_key - api_key_from_user = str(ans) - if api_key_from_user.lower() in exit_words: - print_with_updating_style("exited") - return False - return check_apikey_and_then_save(api_key_from_user) - - -from evdspy.EVDSlocal.initial_setup.api_key_save import check_api_key_on_load - - -def check_api_key(): - check_api_key_on_load() - apikeyobj = ApikeyClass() - return apikeyobj.get_valid_api_key() - - -def show_apikey(): - apikeyobj = ApikeyClass() - # k = apikeyobj.get_api_keys_dict() - valid = apikeyobj.get_valid_api_key() - disp = f""" - valid api key : {valid} -""" - print_with_success_style(disp) - - -from ..series_format.series_creator import * - - -def create_series_file(): - return create_series_text_example() - - -def csf(): - return create_series_file() - - -def setup_series(): - start_setup_series() - - -def setup_user_options(): - start_setup_config(onsetup=False) - - -def create_options_file(): - setup_user_options() - - -def cof(): - create_options_file() - - -def setup_series_steps(): - return setup_series() - - -def console(): - return -1 - - -def get_develop_vers_main(): - # print_with_updating_style(str(Path.cwd())) - parent = Path(__file__).parent - v = Read(Path(parent / ".." / ".." / "__version__.py")) # EVDSlocal/ version.py - return v - - -def version(): - from evdspy.EVDSlocal.console.menu_logo_header import version_logo - logo_version, reminder = version_logo() - print_with_success_style(logo_version) - print_with_info_style(reminder) - - -def py_version(): - from platform import python_version - # - # print_with_creating_style(sys.version_info) - # print_with_creating_style(python_version()) - print_with_creating_style(sys.version) - # print_with_creating_style(str(platform.python_version_tuple())) - - -def check_compat(): - v_tuple = platform.python_version_tuple() - # v_tuple = "3.6.0".split(".") - v_tuple = tuple(map(lambda x: int(x), v_tuple)) - v = sys.version # sys.version_info - if (3, 11, -1) < v_tuple: - print_with_failure_style( - f"Your python version is {v}. This program may break because it is currently only compatible with versions between 3.7 and 3.11") - elif (3, 7, 0) > v_tuple: - print_with_failure_style( - f"Your python version is {v}. This program may break because it is currently only compatible with versions between 3.7 and 3.11") - else: - print_with_success_style( - f"Your python version is {v} This program was tested with this version and runs properly. However, " - f"if you notice a bug or if your version breaks at runtime please feel free to open a PR on github.") - - -def save(*args): - return save_apikey(*args) - - -def remove_cache(): - # TODO activate - msg = "This will attempt to delete cache files in order to make new requests. \n " \ - "If you created your options file you may choose caching period to a more frequent one. \n" \ - "this function was added to force making new requests ignoring recent ones. \n" \ - "Proceed? (Y/n)" - ans = get_input(msg) - if not ans in ["y", "Y"]: - print_with_failure_style("exited without removing the cache") - return - print_with_success_style("removing cache...") - if delete_cache_folder(): - rich_sim(3, "processing...") - print_with_success_style("cahce folder removed...") - else: - print_with_failure_style("cahce folder coould not be removed...") - - -def testt_the_latest(): - get_all_groups() - # get_and_process_datagroups_with_code(3) - # def __(): - # *coming, last = get_datagroups_df('json', None, True) - # print(coming) - # print(last) - # print(last()) - - -def main_exit_function(): - ... - - -def menu_display(): - funcs = [ - ("check setup", check), - ("setup", setup), - ("create user options file", create_options_file), - ("create series file", create_series_file), - ("add new series group ", setup_series_steps), - ("get data", get), - ("get categories (get all series of a datagroup)", get_categories_main), # next version - # ("get data groups (on development) ", get_datagroups_data_main), # next version - ("help", help_), - ("show api key", show_apikey), - ("save api key to file", set_apikey_input), - ("remove cache folders", remove_cache), - ("evdspy as a command line prompt", console_main_from_the_menu), - ("version", version), - ("py version", py_version), - ("check compatibility of your python version", check_compat), - - ] - if 'NEXT_RELEASE' in str(Path().cwd()): - funcs.append(('test_the latest', testt_the_latest)) - menu_items = list(map(lambda x: MenuItem(x[1], x[0]), funcs)) - MenuMaker( - menu_items=menu_items, - exit_item=True, - exit_menu_call_back=main_exit_function - ).display() - - -def menu_helper(): - # TODO config - global menu_already_displayed - menu_already_displayed = True - menu_display() - - -def menu_onload(): - if CurrentState().menu_will_open: - menu_helper() - - -def show_menu(): - menu_helper() - -# get_df_datagroup = get_df_datagroup +# functions that will be loaded +import platform +import sys +import time + +import pandas as pd + +from evdspy.EVDSlocal.console.menu import MenuMaker, MenuItem +from .cmd_line_classes import CommandLineCommandClass +from evdspy.EVDSlocal.initial_setup.api_key_save import save_api_key_to_file +from typing import Callable +from ..common.prog import rich_sim +from ..common.table import Table2_ +from ..index_requests.categories import get_category_name +from ..index_requests.datagroup_individual import get_datagroup_individual_with_code, get_series_list_of_subject, \ + get_df_datagroup +from ..messages.error_messages import * +from ..messages.error_classes import * +from evdspy.EVDSlocal.initial.load_modules import LoadModulesClass +from ..initial_setup.initial_setups import * +from ..requests_.my_cache import delete_cache_folder +from ..setup_project.user_setup import start_setup_series, start_setup_config +from evdspy.EVDSlocal.initial_setup.setup_folders import check_folders_setup_necessary, check_setup +from ..messages.help_messages import welcome_message +from ..utils.utils_general import * +from ..index_requests.datagroups import get_datagroups_with_code + + +assert get_datagroups_with_code +assert get_category_name +assert get_series_list_of_subject + +""" +Loaded functions for DF +get_df_datagroup +""" +assert callable(get_df_datagroup) + + +def check_which_command_params(params, extra_params: dict): + create_series_cmd = CommandLineCommandClass(name_list=("create", "series",), + func=setup_series) + help_cmd = CommandLineCommandClass(name_list=("help",), + func=help_evds) + create_options_cmd = CommandLineCommandClass(name_list=("create", "options",), + func=create_options_file) + get_cmd = CommandLineCommandClass(name_list=("get",), func=get) + setup_cmd = CommandLineCommandClass(name_list=("setup",), func=setup) + menu_cmd = CommandLineCommandClass(name_list=("menu",), func=menu) + save_cmd = CommandLineCommandClass(name_list=("save",), func=save) + console_cmd = CommandLineCommandClass(name_list=("console",), func=console_load) + menu_list = (create_series_cmd, create_options_cmd, get_cmd, setup_cmd, menu_cmd, help_cmd, save_cmd, console_cmd) + + def check_item_exists(element, format_cmd_list): + return element in format_cmd_list + + def check_item_exists_wrapper(item): + return check_item_exists(item, params) + + def check_cmd_will_apply(cmd_class: CommandLineCommandClass): + # return check_item_exists, items + return all(map(check_item_exists_wrapper, cmd_class.name_list)) + + from itertools import compress + functions_will_apply_iter = tuple(map(check_cmd_will_apply, menu_list)) + functions_will_apply = list(compress(menu_list, functions_will_apply_iter)) + for fnc_class in functions_will_apply: + if callable(fnc_class.func): + fnc_class.func() + return functions_will_apply + + +def menu(*args, **kw): + menu_helper() + # if CurrentState().menu_will_open: + # menu_helper() + + +# -------------------------------- Entry point ---cmd line prompt------------------------------------ +def console_main(test_args=None): + # test_args = tuple(["series", "create"]) + if test_args: + params_command = test_args + else: + params_command = sys.argv[1:] + params_command_as_dict = arg_acc(params_command) + if not params_command: + welcome_message() + check_which_command_params(params_command, arg_acc()) + + +# -------------------------------- Entry point ---cmd line prompt------------------------------------ +def console_main_from_the_menu(): + welcome_message() + + +def easy_setup(): + setup() + + +def setup_again(): + setup() + + +def setup(): + SetupInitial().setup() + start_setup_config(onsetup=True) + create_series_text_example(onsetup=True) + + +def help_evds(): + display_help_messages() + + +def help_(): + return help_evds() + + +def h(): + return help_evds() + + +def help_evdspy(): + return help_evds() + + +def check(): + print_with_updating_style("checking....") + lmc = LoadModulesClass() + lmc.check() + + +def show(): + lmc = LoadModulesClass() + lmc.series_from_file() + lmc.summary() + + +def get_input(msg): + if config.current_mode_is_test: + return "test" + print_get_input_style(msg) + ans = input() + return str(ans) + + +def wait(num: int): + time.sleep(num) + + +def save_api_key_to_file_main(api_key): + @dataclass + class transfer(): + get_input: Callable = get_input + wait: Callable = wait + + save_api_key_to_file(instance=transfer(), api_key_answer=api_key) + + +def console_load(): + ... + + +def check_setup_runtime(): + return not check_folders_setup_necessary() + + +def check_if_api_set_before_get(): + if not check_api_key(): + print_with_failure_style(api_key_not_set_msg) + wait(2) + if not get_input("yes/no ? ").lower() in ["yes", "y"]: + wait(2) + return + # below the function checks + # if api key is valid then saves it + if not set_apikey_input(): + return False + print_with_success_style("finished") + return True + return True + + +def get(): + if not check_setup(): + print_with_updating_style("Checking setup...") + # setup_folders() + SetupInitial().setup() + if not check_if_api_set_before_get(): + return + try: + lmc = LoadModulesClass() + lmc.series_from_file() + # lmc.display_items(lmc.series_from_file()) + + lmc.summary() + # try: + # lmc.evds_list[0].df.plot(x='TP.ODEMGZS.BDTTOPLAM', y='Index', style='o') + # except: + # pass + except SeriesFileDoesNotExists: + print("...") + # print(SeriesFileDoesNotExists().message) + + +def get_df_test(): + LoadModulesClass().series_from_file() + LoadModulesClass().summary() + return LoadModulesClass().evds_list[0].df + + +from ..config.apikey_class import * +from evdspy.EVDSlocal.requests_.lower_energy import * +from rich import inspect + +from typing import List +from evdspy.EVDSlocal.index_requests.datagroups import get_and_process_datagroups_with_code, \ + get_all_groups, get_datagroups_with_code +from evdspy.EVDSlocal.index_requests.index_util_funcs import json_to_df + +import typing as t + +from functools import partial + + +def get_input_for_categs_data_groups(list_of_categs: List[tuple], display_fn, callback: t.Callable = None): + callback_forward = partial(get_input_for_categs_data_groups, list_of_categs, display_fn, None) + callables = (display_fn, callback_forward) + if config.current_mode_is_test: + return + ids = (str(x[0]) for x in list_of_categs) + + # print_with_success_style('Preparing the menu...') + # print("\n\n") + # time.sleep(2) + + ans = input("Choose a Category number [e/exit to go back] Selection Number==>") + if str(ans).lower().strip() in ('e', 'exit'): + if callable(callback): + print("now calling back ", display_fn, callback) + display_fn() + callback() + return + if str(ans) in ids: + codes_and_titles = get_and_process_datagroups_with_code(int(ans)) + get_input_for_categs_data_groups_deeper(codes_and_titles, callables) + + +def get_input_for_categs_data_groups_deeper(codes_and_titles: List[tuple], callables: t.Tuple[any, partial] = None): + codes = tuple(x[0] for x in codes_and_titles) + nums = tuple(str(x + 1) for x in range(len(codes_and_titles))) + titles = tuple(x[1] for x in codes_and_titles) + combine_list = list(zip(nums, codes, titles)) + if config.current_mode_is_test: + return + # print(codes_and_titles) + # print("\n\n") + Table2_().show(list_=combine_list, title='', columns=('Selection Number', 'code', 'title'), skiprow=0) + # print_with_success_style('Preparing the menu...') + + # time.sleep(2) + + ans = input("Choose a Category number [e/exit to go back] Selection Number==>") + if str(ans).lower().strip() in ('e', 'exit'): + if callables: + for callback in callables: + if callable(callback) or isinstance(callback, partial): + callback() + time.sleep(1) + return + if str(ans) in nums: + code_str = codes[int(ans) - 1] + try: + json_content = get_datagroup_individual_with_code(code_str) + # print(json_content) + df = json_to_df(json_content) + print(df.head()) + series_docs = get_series_list_of_subject(code_str) + + df_exp: pd.DataFrame = json_to_df(series_docs) + print_with_success_style( + "Getting explanations for the series...after this process both excel files will be created...[1-Data , 2-Explanations] " + ) + time.sleep(1) + print(df_exp.head()) + # print(series_docs) + except: + print_with_failure_style( + f"...json content is not proper to convert to a pd.DataFrame .. passing this one... code : {code_str}") + pass + + df_exp: pd.DataFrame = json_to_df(series_docs) + print_with_success_style( + "Getting explanations for the series...after this process both excel files will be created...[1-Data , 2-Explanations] " + ) + time.sleep(1) + print(df_exp.head()) + # print(series_docs) + + print(ans, " ... done.") + get_input_for_categs_data_groups_deeper(codes_and_titles, callables) + # codes_and_titles = get_and_process_datagroups_with_code(int(ans)) + # get_input_for_categs_data_groups_deeper(codes_and_titles) + + +def get_categories_main(): + if not check_if_api_set_before_get(): + return + # from ..index_requests.categories import get_categories_data + from ..index_requests.categories import display_categories + list_of_categs: List[tuple] = display_categories() # [( id , eng , tr ) , ( id , eng , tr ) ...] + get_input_for_categs_data_groups(list_of_categs, display_fn=display_categories) + + # categories = get_categories_data() + # inspect(categories, all=True) + # print_with_success_style(categories) + + +def get_datagroups_data_main(): + ... + # from ..index_requests.datagroups import get_datagroups_data + # categories = get_datagroups_data() + # inspect(categories, all=True) + # print_with_success_style(categories) + + +def check_api_key_with_low_energy(api_key_from_user): + # check api key with cache + # send => basic_for_test > performance.lower_energy + if not apikey_works(api_key_from_user): + print_with_failure_style(f"Api key did not work! => {api_key_from_user}") + return False + print_with_success_style(f"Api key works => {api_key_from_user}") + return True + + +def obvious_checks_of_api_key(api_key: str) -> bool: + conds: tuple = (isinstance(api_key, str), not len(api_key) < 10,) + return all(conds) + + +def save_apikey(api_key: str = None): + if api_key is None or not isinstance(api_key, str): + return set_apikey_input() + check_apikey_and_then_save(api_key) + + +def check_apikey_and_then_save(api_key_from_user): + if not obvious_checks_of_api_key(api_key_from_user): + print_with_failure_style( + f"The text you entered does not meet criteria to be an valid api key. \n" + f"{indent}(length of api key cannot be less then 10) {api_key_from_user}") + return False + """this function will save redundant requests by catching earlier check results """ + if not check_api_key_with_low_energy(api_key_from_user): + return False + """""" + """ SAVE IT TO FILE """ + save_api_key_to_file_main(api_key_from_user) + """ SAVE IT FOR RUNTIME """ + ApikeyClass().set_api_key_runtime(value=api_key_from_user) + show_apikey() + return True + + +def set_apikey_input(api_key=None, from_console=False): + exit_words = ["e", "exit"] + if config.current_mode_is_test: + print_with_updating_style("pytest returns ") + ans = "test" + else: + if not from_console: + ans = get_input("Api key [ `e` or `exit` to cancel] : ") + else: + ans = api_key + api_key_from_user = str(ans) + if api_key_from_user.lower() in exit_words: + print_with_updating_style("exited") + return False + return check_apikey_and_then_save(api_key_from_user) + + +from evdspy.EVDSlocal.initial_setup.api_key_save import check_api_key_on_load + + +def check_api_key(): + check_api_key_on_load() + apikeyobj = ApikeyClass() + return apikeyobj.get_valid_api_key() + + +def show_apikey(): + apikeyobj = ApikeyClass() + # k = apikeyobj.get_api_keys_dict() + valid = apikeyobj.get_valid_api_key() + disp = f""" + valid api key : {valid} +""" + print_with_success_style(disp) + + +from ..series_format.series_creator import * + + +def create_series_file(): + return create_series_text_example() + + +def csf(): + return create_series_file() + + +def setup_series(): + start_setup_series() + + +def setup_user_options(): + start_setup_config(onsetup=False) + + +def create_options_file(): + setup_user_options() + + +def cof(): + create_options_file() + + +def setup_series_steps(): + return setup_series() + + +def console(): + return -1 + + +def get_develop_vers_main(): + # print_with_updating_style(str(Path.cwd())) + parent = Path(__file__).parent + v = Read(Path(parent / ".." / ".." / "__version__.py")) # EVDSlocal/ version.py + return v + + +def version(): + from evdspy.EVDSlocal.console.menu_logo_header import version_logo + logo_version, reminder = version_logo() + print_with_success_style(logo_version) + print_with_info_style(reminder) + + +def py_version(): + from platform import python_version + # + # print_with_creating_style(sys.version_info) + # print_with_creating_style(python_version()) + print_with_creating_style(sys.version) + # print_with_creating_style(str(platform.python_version_tuple())) + + +def check_compat(): + v_tuple = platform.python_version_tuple() + # v_tuple = "3.6.0".split(".") + v_tuple = tuple(map(lambda x: int(x), v_tuple)) + v = sys.version # sys.version_info + if (3, 11, -1) < v_tuple: + print_with_failure_style( + f"Your python version is {v}. This program may break because it is currently only compatible with versions between 3.7 and 3.11") + elif (3, 7, 0) > v_tuple: + print_with_failure_style( + f"Your python version is {v}. This program may break because it is currently only compatible with versions between 3.7 and 3.11") + else: + print_with_success_style( + f"Your python version is {v} This program was tested with this version and runs properly. However, " + f"if you notice a bug or if your version breaks at runtime please feel free to open a PR on github.") + + +def save(*args): + return save_apikey(*args) + + +def remove_cache(): + # TODO activate + msg = "This will attempt to delete cache files in order to make new requests. \n " \ + "If you created your options file you may choose caching period to a more frequent one. \n" \ + "this function was added to force making new requests ignoring recent ones. \n" \ + "Proceed? (Y/n)" + ans = get_input(msg) + if not ans in ["y", "Y"]: + print_with_failure_style("exited without removing the cache") + return + print_with_success_style("removing cache...") + if delete_cache_folder(): + rich_sim(3, "processing...") + print_with_success_style("cahce folder removed...") + else: + print_with_failure_style("cahce folder coould not be removed...") + + +def testt_the_latest(): + get_all_groups() + # get_and_process_datagroups_with_code(3) + # def __(): + # *coming, last = get_datagroups_df('json', None, True) + # print(coming) + # print(last) + # print(last()) + + +def main_exit_function(): + ... + + +def menu_display(): + funcs = [ + ("check setup", check), + ("setup", setup), + ("create user options file", create_options_file), + ("create series file", create_series_file), + ("add new series group ", setup_series_steps), + ("get data", get), + ("get categories (get all series of a datagroup)", get_categories_main), # next version + # ("get data groups (on development) ", get_datagroups_data_main), # next version + ("help", help_), + ("show api key", show_apikey), + ("save api key to file", set_apikey_input), + ("remove cache folders", remove_cache), + ("evdspy as a command line prompt", console_main_from_the_menu), + ("version", version), + ("py version", py_version), + ("check compatibility of your python version", check_compat), + + ] + if 'NEXT_RELEASE' in str(Path().cwd()): + funcs.append(('test_the latest', testt_the_latest)) + menu_items = list(map(lambda x: MenuItem(x[1], x[0]), funcs)) + MenuMaker( + menu_items=menu_items, + exit_item=True, + exit_menu_call_back=main_exit_function + ).display() + + +def menu_helper(): + # TODO config + global menu_already_displayed + menu_already_displayed = True + menu_display() + + +def menu_onload(): + if CurrentState().menu_will_open: + menu_helper() + + +def show_menu(): + menu_helper() + +# get_df_datagroup = get_df_datagroup diff --git a/evdspy/EVDSlocal/initial/load_modules.py b/evdspy/EVDSlocal/initial/load_modules.py index f5d388b..637ec23 100644 --- a/evdspy/EVDSlocal/initial/load_modules.py +++ b/evdspy/EVDSlocal/initial/load_modules.py @@ -1,277 +1,277 @@ -# ------------------------------------------------------------------------- -# from evdspy.EVDSlocal.before_main_ import * -from evdspy.EVDSlocal.components.evds_files import EvdsSorguSeries -from evdspy.EVDSlocal.components.evds_seri_files import EvdsSeri, EvdsSeriesRequest, EvdsSeriesRequestWrapper -from evdspy.EVDSlocal.series_format.populate_series import PopulateSeries -from evdspy.EVDSlocal.series_format.series_creator import SeriesFileFormat, create_series_file_from_Wrapper, \ - create_series_text_file -from evdspy.EVDSlocal.initial.start_args import Args -from evdspy.EVDSlocal.components.options_class import * -from evdspy.EVDSlocal.components.evds_seri_files import test_series_ -from ..common.table import Table, Table_ -from ..initial_setup.setup_folders import check_setup -from ..messages.error_classes import * -from evdspy.EVDSlocal.log_classes.log_template import deb -from evdspy.EVDSlocal.config.config import ConfigBase - -from evdspy.EVDSlocal.manual_requests.prepare import basic_for_test, PrepareUrl - -from evdspy.EVDSlocal.config.apikey_class import ApikeyClass -from evdspy.EVDSlocal.utils.utils_general import * -from ..common.colors import print_with_info_style -import typing as t - - -@dataclass -class LoadModulesClass(): - options_: Optional[any] = field(default_factory=load_options) - args: Optional[Args] = field(default_factory=Args) # Args(sys.argv) - evds_list: field(default_factory=list) = field(default_factory=list) - series_filename: str = default_series_file_name - api_key_test: bool = False - item_pointer = 0 - - # TODO - """ - """ - - def placebo_item(self): - evds = EvdsSorguSeries( - options_=self.options_, - session=None, - subject="placebo", - series_=test_series_, - file_name="placebo", - args=self.args) - return evds - - def summary(self): - if not self.evds_list or not len(self.evds_list) > 0: - print("No EvdsSorguSeries yet") - return - for item in self.evds_list: - item.summary() - - def series_from_file_test(self): - """Reads series' code from given file name inside initial folder default :`series.txt` """ - return self.create_EVDSSorguSeries() - - def main(self): - return self.series_from_file() - - def series_from_file(self): - """ MAIN function """ - result = [] - try: - result: t.List[EvdsSorguSeries] = self.series_from_file_core() - # _ = list(x.display for x in result) - except SeriesFileDoesNotExists: - print(SeriesFileDoesNotExists().message) - - return result - - def convert_wrapperlist_to_text(self, wrapper_list: List[EvdsSeriesRequestWrapper]): - content = create_series_file_from_Wrapper(wrapper_list) - return content - - def create_locked_series_file(self): - wrapper_list = self.populate_evds_wrapperList() - content = self.convert_wrapperlist_to_text(wrapper_list) - file_name = default_series_file_name.split(".cfg")[0] + "-locked.cfg" - create_series_text_file(file_name, content) - - def create_EVDSSorguSeries(self): - return self.populate_evds_list() - - def populate_evds_wrapperList(self): - # return - # if self.api_key_test: - # """ api key already was tested here we are checking if it is valid """ - # self.series_filename = str( - # ConfigBase().runtime_file_name_root_path / "series_format" / "series_test_runtime.cfg") - # # self.series_filename = "series_format/series_test_runtime.cfg" - sff = SeriesFileFormat(self.series_filename) - return sff.EvdsSeriesRequestWrapperList - - def check_for_apikey_with_simple_wrapper(self, api_key): - - basic_for_test(api_key) - exit() - - self.api_key_test = True - self.evds_list = self.populate_evds_list() - if not self.evds_list: - return False - self.evds_list = [self.evds_list[0]] - return self.evds_to_excel(api_key_test=True) - - # return len(evds_list) and isinstance(evds_list[0], EvdsSorguSeries) - - def populate_evds_list(self): - """==>>>> (Deep ) PopulateSeries() => - (Surface) SeriesFileFormat .EvdsSeriesRequestWrapper_ - Reads series' code from given file name - inside initial folder default :`series.txt` - returns a list of wrapper - ( EvdsSeriesRequestWrapper1 , EvdsSeriesRequestWrapper2 , ... ) - EvdsSeriesRequestWrapper : - name - subject - EvdsSeriesRequest - """ - list_ = [] - EvdsSeriesRequestWrapperList = self.populate_evds_wrapperList() - for index, EvdsSeriesRequestWrapper_ in enumerate(EvdsSeriesRequestWrapperList): - evds = EvdsSorguSeries( - options_=self.options_, - session=None, - subject=EvdsSeriesRequestWrapper_.subject, - series_=EvdsSeriesRequestWrapper_.EvdsSeriesRequest_, - file_name=EvdsSeriesRequestWrapper_.name, - args=self.args, - bfs=EvdsSeriesRequestWrapper_.bfs, - ) - - list_.append(evds) - return list_ - - def evds_to_excel(self, api_key_test=False): - for evds in self.evds_list: - try: - - evds.save_excel() - evds.report() - except Exception as exc: - # print(exc) - # print(evds) - deb(str(exc)) - - return True - - # def display_items(self): - # _ = (x.display for x in self.evds_list) - # print(_) - - def series_from_file_core(self): - self.evds_list = self.create_EVDSSorguSeries() - self.display_items(self.evds_list) - - # print(self.evds_list ) - self.evds_to_excel() - self.create_locked_series_file() - return self.evds_list - - def display_messages(self, *msgs, wait_num=None): - if wait_num is None: - wait_num = {0: 3, 1: 2, 2: 1} - - def print_and_wait(): - for index, msg in enumerate(msgs): - print_with_info_style(msg) - time.sleep(wait_num.get(index, 2)) - - print_and_wait() - - def display_reading_message(self, len_): - from ..common.colors import print_with_info_style - msg2 = f""" - collecting... -""" - msg3 = f""" - collected {len_} items. -""" - wait_num = {0: 4, 1: 3, 2: 3} - - self.display_messages(msg2, msg3, wait_num=wait_num) - - def display_items(self, evds_list: t.List[EvdsSorguSeries]): - msg1 = f""" - Now reading `config_series.cfg` file... - - """ - self.display_messages(msg1) - - if not evds_list: - if not self.evds_list: - evds_list = () - else: - evds_list = self.evds_list - - if isinstance(evds_list, bool): - print(evds_list) - - self.display_reading_message(0) - return - if not evds_list: - return - self.display_reading_message(len(evds_list)) - for index, item in enumerate(evds_list): - item.display(index + 1) - time.sleep(1) - - def seri_ornek(self, options_, args): - liste = [ - 'TP.IHRACATBEC.9999', - 'TP.IHRACATBEC.31', - 'TP.IHRACATBEC.41', - ] - seri_evds_objs: list[EvdsSeri] = [EvdsSeri(x) for x in liste] - series_ = EvdsSeriesRequest(self.options_, seri_evds_objs) - file_name = "test34" - evds = EvdsSorguSeries( - session=None, - series_=series_, - file_name=file_name - ) - evds.save_excel(evds.file_name) - - def check(self): - evds_items = self.series_from_file_test() - if len(evds_items): - self.check_items(evds_items) - - def check_items(self, evds_items): - config = ConfigBase() - options_copy_file_name = config.runtime_file_name_path - user_options_file_name = config.user_options_file_name - deb(config) - # args = Args(sys.argv) - ps = PopulateSeries() - series_file_was_created = False - f = Path(ps.input_file_name) - if f.is_file(): - series_file_was_created = True - - folders_ok = False - if check_setup(): - folders_ok = True - api_key_is_ok = False - if ApikeyClass().get_valid_api_key(): - api_key_is_ok = True - - def display(): - options_file_name = "options.cfg" - options_file_created = Path(options_file_name).is_file() - options_display = SingletonOptions().check() - if not 'NEXT_RELEASE' in str(Path.cwd()): - workspace = str(Path.cwd()).replace(":", ".") - else: - workspace = r'test_area3' - hiddenok = f"hidden" - if not api_key_is_ok: - hiddenok = "" - msg = f""" -Workspace : {workspace} -Folders created :{folders_ok} -Series file was created :{series_file_was_created} {indent} {ps.input_file_name} -Options file was created :{options_file_created} {indent} {options_file_name} -Api key was set :{api_key_is_ok} {indent} {hiddenok} - {options_display} - """ - # print(msg) - Table_().show(content=msg, - title=" Checking installation and other setup requirements ", - columns=('', '',), - skiprow=1) - - display() +# ------------------------------------------------------------------------- +# from evdspy.EVDSlocal.before_main_ import * +from evdspy.EVDSlocal.components.evds_files import EvdsSorguSeries +from evdspy.EVDSlocal.components.evds_seri_files import EvdsSeri, EvdsSeriesRequest, EvdsSeriesRequestWrapper +from evdspy.EVDSlocal.series_format.populate_series import PopulateSeries +from evdspy.EVDSlocal.series_format.series_creator import SeriesFileFormat, create_series_file_from_Wrapper, \ + create_series_text_file +from evdspy.EVDSlocal.initial.start_args import Args +from evdspy.EVDSlocal.components.options_class import * +from evdspy.EVDSlocal.components.evds_seri_files import test_series_ +from ..common.table import Table, Table_ +from ..initial_setup.setup_folders import check_setup +from ..messages.error_classes import * +from evdspy.EVDSlocal.log_classes.log_template import deb +from evdspy.EVDSlocal.config.config import ConfigBase + +from evdspy.EVDSlocal.manual_requests.prepare import basic_for_test, PrepareUrl + +from evdspy.EVDSlocal.config.apikey_class import ApikeyClass +from evdspy.EVDSlocal.utils.utils_general import * +from ..common.colors import print_with_info_style +import typing as t + + +@dataclass +class LoadModulesClass(): + options_: Optional[any] = field(default_factory=load_options) + args: Optional[Args] = field(default_factory=Args) # Args(sys.argv) + evds_list: field(default_factory=list) = field(default_factory=list) + series_filename: str = default_series_file_name + api_key_test: bool = False + item_pointer = 0 + + # TODO + """ + """ + + def placebo_item(self): + evds = EvdsSorguSeries( + options_=self.options_, + session=None, + subject="placebo", + series_=test_series_, + file_name="placebo", + args=self.args) + return evds + + def summary(self): + if not self.evds_list or not len(self.evds_list) > 0: + print("No EvdsSorguSeries yet") + return + for item in self.evds_list: + item.summary() + + def series_from_file_test(self): + """Reads series' code from given file name inside initial folder default :`series.txt` """ + return self.create_EVDSSorguSeries() + + def main(self): + return self.series_from_file() + + def series_from_file(self): + """ MAIN function """ + result = [] + try: + result: t.List[EvdsSorguSeries] = self.series_from_file_core() + # _ = list(x.display for x in result) + except SeriesFileDoesNotExists: + print(SeriesFileDoesNotExists().message) + + return result + + def convert_wrapperlist_to_text(self, wrapper_list: List[EvdsSeriesRequestWrapper]): + content = create_series_file_from_Wrapper(wrapper_list) + return content + + def create_locked_series_file(self): + wrapper_list = self.populate_evds_wrapperList() + content = self.convert_wrapperlist_to_text(wrapper_list) + file_name = default_series_file_name.split(".cfg")[0] + "-locked.cfg" + create_series_text_file(file_name, content) + + def create_EVDSSorguSeries(self): + return self.populate_evds_list() + + def populate_evds_wrapperList(self): + # return + # if self.api_key_test: + # """ api key already was tested here we are checking if it is valid """ + # self.series_filename = str( + # ConfigBase().runtime_file_name_root_path / "series_format" / "series_test_runtime.cfg") + # # self.series_filename = "series_format/series_test_runtime.cfg" + sff = SeriesFileFormat(self.series_filename) + return sff.EvdsSeriesRequestWrapperList + + def check_for_apikey_with_simple_wrapper(self, api_key): + + basic_for_test(api_key) + exit() + + self.api_key_test = True + self.evds_list = self.populate_evds_list() + if not self.evds_list: + return False + self.evds_list = [self.evds_list[0]] + return self.evds_to_excel(api_key_test=True) + + # return len(evds_list) and isinstance(evds_list[0], EvdsSorguSeries) + + def populate_evds_list(self): + """==>>>> (Deep ) PopulateSeries() => + (Surface) SeriesFileFormat .EvdsSeriesRequestWrapper_ + Reads series' code from given file name + inside initial folder default :`series.txt` + returns a list of wrapper + ( EvdsSeriesRequestWrapper1 , EvdsSeriesRequestWrapper2 , ... ) + EvdsSeriesRequestWrapper : + name + subject + EvdsSeriesRequest + """ + list_ = [] + EvdsSeriesRequestWrapperList = self.populate_evds_wrapperList() + for index, EvdsSeriesRequestWrapper_ in enumerate(EvdsSeriesRequestWrapperList): + evds = EvdsSorguSeries( + options_=self.options_, + session=None, + subject=EvdsSeriesRequestWrapper_.subject, + series_=EvdsSeriesRequestWrapper_.EvdsSeriesRequest_, + file_name=EvdsSeriesRequestWrapper_.name, + args=self.args, + bfs=EvdsSeriesRequestWrapper_.bfs, + ) + + list_.append(evds) + return list_ + + def evds_to_excel(self, api_key_test=False): + for evds in self.evds_list: + try: + + evds.save_excel() + evds.report() + except Exception as exc: + # print(exc) + # print(evds) + deb(str(exc)) + + return True + + # def display_items(self): + # _ = (x.display for x in self.evds_list) + # print(_) + + def series_from_file_core(self): + self.evds_list = self.create_EVDSSorguSeries() + self.display_items(self.evds_list) + + # print(self.evds_list ) + self.evds_to_excel() + self.create_locked_series_file() + return self.evds_list + + def display_messages(self, *msgs, wait_num=None): + if wait_num is None: + wait_num = {0: 3, 1: 2, 2: 1} + + def print_and_wait(): + for index, msg in enumerate(msgs): + print_with_info_style(msg) + time.sleep(wait_num.get(index, 2)) + + print_and_wait() + + def display_reading_message(self, len_): + from ..common.colors import print_with_info_style + msg2 = f""" + collecting... +""" + msg3 = f""" + collected {len_} items. +""" + wait_num = {0: 4, 1: 3, 2: 3} + + self.display_messages(msg2, msg3, wait_num=wait_num) + + def display_items(self, evds_list: t.List[EvdsSorguSeries]): + msg1 = f""" + Now reading `config_series.cfg` file... + + """ + self.display_messages(msg1) + + if not evds_list: + if not self.evds_list: + evds_list = () + else: + evds_list = self.evds_list + + if isinstance(evds_list, bool): + print(evds_list) + + self.display_reading_message(0) + return + if not evds_list: + return + self.display_reading_message(len(evds_list)) + for index, item in enumerate(evds_list): + item.display(index + 1) + time.sleep(1) + + def seri_ornek(self, options_, args): + liste = [ + 'TP.IHRACATBEC.9999', + 'TP.IHRACATBEC.31', + 'TP.IHRACATBEC.41', + ] + seri_evds_objs: list[EvdsSeri] = [EvdsSeri(x) for x in liste] + series_ = EvdsSeriesRequest(self.options_, seri_evds_objs) + file_name = "test34" + evds = EvdsSorguSeries( + session=None, + series_=series_, + file_name=file_name + ) + evds.save_excel(evds.file_name) + + def check(self): + evds_items = self.series_from_file_test() + if len(evds_items): + self.check_items(evds_items) + + def check_items(self, evds_items): + config = ConfigBase() + options_copy_file_name = config.runtime_file_name_path + user_options_file_name = config.user_options_file_name + deb(config) + # args = Args(sys.argv) + ps = PopulateSeries() + series_file_was_created = False + f = Path(ps.input_file_name) + if f.is_file(): + series_file_was_created = True + + folders_ok = False + if check_setup(): + folders_ok = True + api_key_is_ok = False + if ApikeyClass().get_valid_api_key(): + api_key_is_ok = True + + def display(): + options_file_name = "options.cfg" + options_file_created = Path(options_file_name).is_file() + options_display = SingletonOptions().check() + if not 'NEXT_RELEASE' in str(Path.cwd()): + workspace = str(Path.cwd()).replace(":", ".") + else: + workspace = r'test_area3' + hiddenok = f"hidden" + if not api_key_is_ok: + hiddenok = "" + msg = f""" +Workspace : {workspace} +Folders created :{folders_ok} +Series file was created :{series_file_was_created} {indent} {ps.input_file_name} +Options file was created :{options_file_created} {indent} {options_file_name} +Api key was set :{api_key_is_ok} {indent} {hiddenok} + {options_display} + """ + # print(msg) + Table_().show(content=msg, + title=" Checking installation and other setup requirements ", + columns=('', '',), + skiprow=1) + + display() diff --git a/evdspy/EVDSlocal/initial/sample_series_content.py b/evdspy/EVDSlocal/initial/sample_series_content.py new file mode 100644 index 0000000..f50f9c6 --- /dev/null +++ b/evdspy/EVDSlocal/initial/sample_series_content.py @@ -0,0 +1,109 @@ +sample_series = f""" +file:visitors +subject:visitors +TP.ODEMGZS.BDTTOPLAM +TP.ODEMGZS.ABD +TP.ODEMGZS.ARJANTIN +TP.ODEMGZS.BREZILYA +TP.ODEMGZS.KANADA +TP.ODEMGZS.KOLOMBIYA +TP.ODEMGZS.MEKSIKA +TP.ODEMGZS.SILI +TP.ODEMGZS.VENEZUELLA +TP.ODEMGZS.DAMERIKA +TP.ODEMGZS.AMERIKATOP +TP.ODEMGZS.CEZAYIR +TP.ODEMGZS.FAS +TP.ODEMGZS.GAFRIKA +TP.ODEMGZS.LIBYA +TP.ODEMGZS.MISIR +TP.ODEMGZS.SUDAN +TP.ODEMGZS.TUNUS +TP.ODEMGZS.DAFRIKA +TP.ODEMGZS.AFRIKATOP +TP.ODEMGZS.BAE +TP.ODEMGZS.BAHREYN +TP.ODEMGZS.BANGLADES +TP.ODEMGZS.CIN +TP.ODEMGZS.ENDONEZYA +TP.ODEMGZS.FILIPINLER +TP.ODEMGZS.GKORE +TP.ODEMGZS.HINDISTAN +TP.ODEMGZS.IRAK +TP.ODEMGZS.IRAN +TP.ODEMGZS.ISRAIL +TP.ODEMGZS.JAPONYA +TP.ODEMGZS.KKTC +TP.ODEMGZS.KATAR +TP.ODEMGZS.KUVEYT +TP.ODEMGZS.LUBNAN +TP.ODEMGZS.MALEZYA +TP.ODEMGZS.PAKISTAN +TP.ODEMGZS.SINGAPUR +TP.ODEMGZS.SURIYE +TP.ODEMGZS.SUUDARABISTAN +TP.ODEMGZS.TAYLAND +TP.ODEMGZS.URDUN +TP.ODEMGZS.YEMEN +TP.ODEMGZS.DASYA +TP.ODEMGZS.ASYATOP +TP.ODEMGZS.AVUSTRALYA +TP.ODEMGZS.YENIZELLANDA +TP.ODEMGZS.OKYANUSYA +TP.ODEMGZS.MILLIYESIZ +TP.ODEMGZS.GTOPLAM +-- +file:visitors2 +subject:visitors2 +TP.ODEMGZS.BDTTOPLAM +TP.ODEMGZS.ABD +TP.ODEMGZS.ARJANTIN +TP.ODEMGZS.BREZILYA +TP.ODEMGZS.KANADA +TP.ODEMGZS.KOLOMBIYA +TP.ODEMGZS.MEKSIKA +TP.ODEMGZS.SILI +TP.ODEMGZS.VENEZUELLA +TP.ODEMGZS.DAMERIKA +TP.ODEMGZS.AMERIKATOP +TP.ODEMGZS.CEZAYIR +TP.ODEMGZS.FAS +TP.ODEMGZS.GAFRIKA +TP.ODEMGZS.LIBYA +TP.ODEMGZS.MISIR +TP.ODEMGZS.SUDAN +TP.ODEMGZS.TUNUS +TP.ODEMGZS.DAFRIKA +TP.ODEMGZS.AFRIKATOP +TP.ODEMGZS.BAE +TP.ODEMGZS.BAHREYN +TP.ODEMGZS.BANGLADES +TP.ODEMGZS.CIN +TP.ODEMGZS.ENDONEZYA +TP.ODEMGZS.FILIPINLER +TP.ODEMGZS.GKORE +TP.ODEMGZS.HINDISTAN +TP.ODEMGZS.IRAK +TP.ODEMGZS.IRAN +TP.ODEMGZS.ISRAIL +TP.ODEMGZS.JAPONYA +TP.ODEMGZS.KKTC +TP.ODEMGZS.KATAR +TP.ODEMGZS.KUVEYT +TP.ODEMGZS.LUBNAN +TP.ODEMGZS.MALEZYA +TP.ODEMGZS.PAKISTAN +TP.ODEMGZS.SINGAPUR +TP.ODEMGZS.SURIYE +TP.ODEMGZS.SUUDARABISTAN +TP.ODEMGZS.TAYLAND +TP.ODEMGZS.URDUN +TP.ODEMGZS.YEMEN +TP.ODEMGZS.DASYA +TP.ODEMGZS.ASYATOP +TP.ODEMGZS.AVUSTRALYA +TP.ODEMGZS.YENIZELLANDA +TP.ODEMGZS.OKYANUSYA +TP.ODEMGZS.MILLIYESIZ +TP.ODEMGZS.GTOPLAM +""" diff --git a/evdspy/EVDSlocal/initial/start_args.py b/evdspy/EVDSlocal/initial/start_args.py index 5db5352..dfc5bdb 100644 --- a/evdspy/EVDSlocal/initial/start_args.py +++ b/evdspy/EVDSlocal/initial/start_args.py @@ -1,42 +1,42 @@ -from ..common.common_imports import * -from dataclasses import dataclass -from ..log_classes.log_template import get_debugger - -Name_or_False = TypeVar('Name_or_False', str, bool) - -from typing import Optional - - -@dataclass -class Args: - args: field(default_factory=tuple) = field(default_factory=tuple) - # proxy: Name_or_False = False - proxy: Optional[str] = False - file_name: Name_or_False = Name_or_False - - def __post_init__(self): - self.populate_args() - - def populate_args(self): - self.proxy = self.extract_prop("--proxy") - self.file_name = self.extract_prop("--file") - - def extract_prop(self, prop): - for index, item in enumerate(self.args): - if prop in item: - if "=" in item: - v = item.split("=")[1] - else: - v = self.args[index + 1] - return v - return False - - -import sys - -test_args = Args(sys.argv) - -deb("test_args" + ",".join(list(sys.argv))) - -# print(debug.log_file_name, debug.log_file_path) -# print(debug) +from ..common.common_imports import * +from dataclasses import dataclass +from ..log_classes.log_template import get_debugger + +Name_or_False = TypeVar('Name_or_False', str, bool) + +from typing import Optional + + +@dataclass +class Args: + args: field(default_factory=tuple) = field(default_factory=tuple) + # proxy: Name_or_False = False + proxy: Optional[str] = False + file_name: Name_or_False = Name_or_False + + def __post_init__(self): + self.populate_args() + + def populate_args(self): + self.proxy = self.extract_prop("--proxy") + self.file_name = self.extract_prop("--file") + + def extract_prop(self, prop): + for index, item in enumerate(self.args): + if prop in item: + if "=" in item: + v = item.split("=")[1] + else: + v = self.args[index + 1] + return v + return False + + +import sys + +test_args = Args(sys.argv) + +deb("test_args" + ",".join(list(sys.argv))) + +# print(debug.log_file_name, debug.log_file_path) +# print(debug) diff --git a/evdspy/EVDSlocal/initial/start_options.py b/evdspy/EVDSlocal/initial/start_options.py index 1602bd9..32a14e3 100644 --- a/evdspy/EVDSlocal/initial/start_options.py +++ b/evdspy/EVDSlocal/initial/start_options.py @@ -1,72 +1,72 @@ -""" S T A R T O P T I O N S """ -# -# -# see SingletonOptions.py -# -from ..common.common_imports import * -from pathlib import Path -import sys - - -def check_if_this_is_pytest(): - def check(): - path_ = Path(sys.argv[0]) - return "pytest" in str(path_.stem) - - if len(sys.argv) > 0 and check(): - return True - else: - - return False - - -# -# -# -if True: - """temporarily cancel mock requests and do real requests""" - temp_cancel_mock_request = True - """series file name """ - default_series_file_name = "config_series.cfg" - """series data folder name """ - default_data_folder_name = "SeriesData" - """ for security as a default value it is True to avoid polluting existing folders with unwanted excel files """ - Avoid_Absolute_Paths_ = True - """ for security we define a prefix to name created excel files to diminish risk of removing existing excel files """ - Default_Prefix_ = "EVPY_" - # options_folder_name = r"IO" - """ debug option """ - DEBUG_LOG_CANCEL = False - """ debug notice """ - DEGUB_NOTICE = True - """verbose debug """ - DEBUG_PRINT = False # TODO less verbose debug plus conditional - """ api key tested hashes folder name """ - default_arch_folder_name = "APIKEY_FOLDER" - """ api key tested hashes file name """ - default_arch_file_name = "arch.txt" - """default_cache""" - default_cache = "daily" # nocache / hourly / monthly - """default_end_date""" - default_end_date = "01-12-2030" - """default_start_date""" - default_start_date = "01-01-2019" - import os - - # USERNAME = os.getenv("USERNAME") # or hard coded "Username" -# -# -# -# -# -# -# -# -# -# -""" / S T A R T O P T I O N S """ - -# pytest will set this True -current_mode_is_test = check_if_this_is_pytest() - -""" GLOBALS """ +""" S T A R T O P T I O N S """ +# +# +# see SingletonOptions.py +# +from ..common.common_imports import * +from pathlib import Path +import sys + + +def check_if_this_is_pytest(): + def check(): + path_ = Path(sys.argv[0]) + return "pytest" in str(path_.stem) + + if len(sys.argv) > 0 and check(): + return True + else: + + return False + + +# +# +# +if True: + """temporarily cancel mock requests and do real requests""" + temp_cancel_mock_request = True + """series file name """ + default_series_file_name = "config_series.cfg" + """series data folder name """ + default_data_folder_name = "SeriesData" + """ for security as a default value it is True to avoid polluting existing folders with unwanted excel files """ + Avoid_Absolute_Paths_ = True + """ for security we define a prefix to name created excel files to diminish risk of removing existing excel files """ + Default_Prefix_ = "EVPY_" + # options_folder_name = r"IO" + """ debug option """ + DEBUG_LOG_CANCEL = False + """ debug notice """ + DEGUB_NOTICE = True + """verbose debug """ + DEBUG_PRINT = False # TODO less verbose debug plus conditional + """ api key tested hashes folder name """ + default_arch_folder_name = "--APIKEY_FOLDER" + """ api key tested hashes file name """ + default_arch_file_name = "arch.txt" + """default_cache""" + default_cache = "daily" # nocache / hourly / monthly + """default_end_date""" + default_end_date = "01-12-2030" + """default_start_date""" + default_start_date = "01-01-2019" + import os + + # USERNAME = os.getenv("USERNAME") # or hard coded "Username" +# +# +# +# +# +# +# +# +# +# +""" / S T A R T O P T I O N S """ + +# pytest will set this True +current_mode_is_test = check_if_this_is_pytest() + +""" GLOBALS """ diff --git a/evdspy/EVDSlocal/initial/try_loading_initial_commands.py b/evdspy/EVDSlocal/initial/try_loading_initial_commands.py new file mode 100644 index 0000000..340887d --- /dev/null +++ b/evdspy/EVDSlocal/initial/try_loading_initial_commands.py @@ -0,0 +1,25 @@ +from ..messages.error_classes import * +from evdspy.EVDSlocal.helper.print_m import * +from evdspy.EVDSlocal.initial_setup.setup_folders import check_folders_setup_necessary + +if not check_folders_setup_necessary(): + print("setup checked...") + try: + + from .load_commands_ import * + + # help_evds() + # setup_now() + # help_evds() + + except OptionsFileNotLoadedError: + print("load_commands_ error trying setup") + time.sleep(3) + from ..initial_setup.initial_setups import * + SetupInitial().setup() + + +else: + from .load_commands_ import * + + # help_evds() diff --git a/evdspy/EVDSlocal/initial_setup/api_key_save.py b/evdspy/EVDSlocal/initial_setup/api_key_save.py index 4ea1ce5..fdac1bd 100644 --- a/evdspy/EVDSlocal/initial_setup/api_key_save.py +++ b/evdspy/EVDSlocal/initial_setup/api_key_save.py @@ -1,83 +1,83 @@ -from pathlib import Path -import os -from evdspy.EVDSlocal.common.files import Write, Read -import base64 - -api_key_folder_name = Path() / "APIKEY_FOLDER" -api_key_file_name = api_key_folder_name / "api_key.txt" - - -def decode(base64_bytes) -> str: - if isinstance(base64_bytes, str): - base64_bytes = str.encode(base64_bytes) - str_bytes = base64.b64decode(base64_bytes) - decoded = str_bytes.decode("ascii") - return decoded - - -def encode(text: str) -> bytes: - t_bytes = text.encode("ascii") - encoded = base64.b64encode(t_bytes) - return encoded - - -def WriteBytes(file_name: str, content_bytes: bytes): - with open(file_name, 'wb') as f: - f.write(content_bytes) - - -def ReadBytes(file_name: str): - with open(file_name, "rb") as f: - return f.read() - - -from evdspy.EVDSlocal.config.apikey_class import ApikeyClass - - -# def check_key_before_saving(instance, api_key_answer: str): -# ApikeyClass().now_testing_is_key_is_valid = api_key_answer -# return instance.check_api_key_with_simple_Wrapper() - - -def save_api_key_to_file(instance, api_key_answer): - instance.wait(1) - - if not api_key_folder_name.is_dir(): - os.makedirs(api_key_folder_name) - # api_key_answer = instance.get_input("Your api key : ") - # Write(api_key_file_name, str(encode(api_key_answer)), "") - - WriteBytes(str(api_key_file_name), encode(api_key_answer)) - # test for file api key for runtime (temp) - ApikeyClass().set_api_key_filetype(value=api_key_answer) - - # ApikeyClass().now_testing_is_key_is_valid = api_key_answer - print("your api file was saved...") - instance.wait(1) - # instance.set_apikey(api_key_answer) - api_key_from_file = get_api_key_from_file_improved() - return api_key_from_file - - -def get_api_key_from_file_improved(): - if not api_key_file_name.is_file(): - return False - - def read_api_file(): - content = ReadBytes(str(api_key_file_name)) - return content - - pot_key = read_api_file() - if pot_key: - return decode(pot_key) - return False - - -def check_api_key_on_load(): - """ not compatible 3.8-""" - # if api_key := get_api_key_from_file_improved(): - # ApikeyClass().set_api_key_filetype(value=api_key) - """changing to this""" - api_key = get_api_key_from_file_improved() - if api_key: - ApikeyClass().set_api_key_filetype(value=api_key) +from pathlib import Path +import os +from evdspy.EVDSlocal.common.files import Write, Read +import base64 + +api_key_folder_name = Path() / "APIKEY_FOLDER" +api_key_file_name = api_key_folder_name / "api_key.txt" + + +def decode(base64_bytes) -> str: + if isinstance(base64_bytes, str): + base64_bytes = str.encode(base64_bytes) + str_bytes = base64.b64decode(base64_bytes) + decoded = str_bytes.decode("ascii") + return decoded + + +def encode(text: str) -> bytes: + t_bytes = text.encode("ascii") + encoded = base64.b64encode(t_bytes) + return encoded + + +def WriteBytes(file_name: str, content_bytes: bytes): + with open(file_name, 'wb') as f: + f.write(content_bytes) + + +def ReadBytes(file_name: str): + with open(file_name, "rb") as f: + return f.read() + + +from evdspy.EVDSlocal.config.apikey_class import ApikeyClass + + +# def check_key_before_saving(instance, api_key_answer: str): +# ApikeyClass().now_testing_is_key_is_valid = api_key_answer +# return instance.check_api_key_with_simple_Wrapper() + + +def save_api_key_to_file(instance, api_key_answer): + instance.wait(1) + + if not api_key_folder_name.is_dir(): + os.makedirs(api_key_folder_name) + # api_key_answer = instance.get_input("Your api key : ") + # Write(api_key_file_name, str(encode(api_key_answer)), "") + + WriteBytes(str(api_key_file_name), encode(api_key_answer)) + # test for file api key for runtime (temp) + ApikeyClass().set_api_key_filetype(value=api_key_answer) + + # ApikeyClass().now_testing_is_key_is_valid = api_key_answer + print("your api file was saved...") + instance.wait(1) + # instance.set_apikey(api_key_answer) + api_key_from_file = get_api_key_from_file_improved() + return api_key_from_file + + +def get_api_key_from_file_improved(): + if not api_key_file_name.is_file(): + return False + + def read_api_file(): + content = ReadBytes(str(api_key_file_name)) + return content + + pot_key = read_api_file() + if pot_key: + return decode(pot_key) + return False + + +def check_api_key_on_load(): + """ not compatible 3.8-""" + # if api_key := get_api_key_from_file_improved(): + # ApikeyClass().set_api_key_filetype(value=api_key) + """changing to this""" + api_key = get_api_key_from_file_improved() + if api_key: + ApikeyClass().set_api_key_filetype(value=api_key) diff --git a/evdspy/EVDSlocal/initial_setup/initial_setups.py b/evdspy/EVDSlocal/initial_setup/initial_setups.py index af412de..987721e 100644 --- a/evdspy/EVDSlocal/initial_setup/initial_setups.py +++ b/evdspy/EVDSlocal/initial_setup/initial_setups.py @@ -1,14 +1,21 @@ -from evdspy.EVDSlocal.initial_setup.setup_folders import setup_folders -from ..series_format.series_creator import * - - -@dataclass -class SetupInitial(): - def setup(self): - setup_folders() - # create_setup_file() - # create_series_text_example() - - def create_series_text_ex(self): - create_series_text_example() - +# from ..before_main_ import * + +from evdspy.EVDSlocal.initial_setup.setup_folders import setup_folders + +# from ..setup_options import * +# from ..setup_options import copy_setup_file +from ..series_format.series_creator import * + + +@dataclass +class SetupInitial(): + def setup(self): + setup_folders() + # create_setup_file() + # create_series_text_example() + + def create_series_text_ex(self): + create_series_text_example() + + # def only_copy(self): + # copy_setup_file() \ No newline at end of file diff --git a/evdspy/EVDSlocal/initial_setup/setup_folders.py b/evdspy/EVDSlocal/initial_setup/setup_folders.py index 9402b96..69df163 100644 --- a/evdspy/EVDSlocal/initial_setup/setup_folders.py +++ b/evdspy/EVDSlocal/initial_setup/setup_folders.py @@ -1,40 +1,40 @@ -from evdspy.EVDSlocal.common.common_imports import * -from evdspy.EVDSlocal.utils.utils_general import * -from evdspy.EVDSlocal.initial.start_options import * -from ..common.colors import * -from evdspy.EVDSlocal.initial.start_options import default_data_folder_name - - -dirs = ("pickles", default_data_folder_name) - -cur_folder = Path() - -import time - - -def check_folders_setup_necessary(): - for item in dirs: - folder_ = cur_folder.absolute() / item - if not folder_.is_dir(): - return True - return False - - -def check_setup(): - return not check_folders_setup_necessary() - - -def setup_folders(): - if not check_folders_setup_necessary(): - deb(f"initial folders checked...{dirs} ") - # print_with_success_style("Setup => checked...") - # time.sleep(1) - return - - for item in dirs: - # folder_ = cur_folder.absolute() / ".." / item - folder_ = cur_folder.absolute() / item - - print_with_creating_style(f"Creating directory...{folder_}") - create_directory(str(folder_)) - time.sleep(0.8) +from evdspy.EVDSlocal.common.common_imports import * +from evdspy.EVDSlocal.utils.utils_general import * +from evdspy.EVDSlocal.initial.start_options import * +from ..common.colors import * +from evdspy.EVDSlocal.initial.start_options import default_data_folder_name + + +dirs = ("pickles", default_data_folder_name) + +cur_folder = Path() + +import time + + +def check_folders_setup_necessary(): + for item in dirs: + folder_ = cur_folder.absolute() / item + if not folder_.is_dir(): + return True + return False + + +def check_setup(): + return not check_folders_setup_necessary() + + +def setup_folders(): + if not check_folders_setup_necessary(): + deb(f"initial folders checked...{dirs} ") + # print_with_success_style("Setup => checked...") + # time.sleep(1) + return + + for item in dirs: + # folder_ = cur_folder.absolute() / ".." / item + folder_ = cur_folder.absolute() / item + + print_with_creating_style(f"Creating directory...{folder_}") + create_directory(str(folder_)) + time.sleep(0.8) diff --git a/evdspy/EVDSlocal/log_classes/log_template.py b/evdspy/EVDSlocal/log_classes/log_template.py index f32b6d1..2de37b7 100644 --- a/evdspy/EVDSlocal/log_classes/log_template.py +++ b/evdspy/EVDSlocal/log_classes/log_template.py @@ -1,146 +1,146 @@ -import logging -import sys -from logging.handlers import TimedRotatingFileHandler -import pathlib -import os - -from pathlib import Path - -NoteShown = False -from evdspy.EVDSlocal.initial.start_options import DEBUG_LOG_CANCEL, DEGUB_NOTICE - -FORMATTER = logging.Formatter("%(asctime)s — %(name)s — %(levelname)s — %(message)s ") -LOG_FILE = "LOG_" - -""" -This will stop or activate debugging -""" - - -class Log: - def __init__(self, name): - self.name = name - - def get_console_handler(self): - console_handler = logging.StreamHandler(sys.stdout) - console_handler.setFormatter(FORMATTER) - return console_handler - - def get_file_handler(self, logger_name): - log_file_path = Path() / "logs" / "log_files" # / "log-{}-{}.log" - if not os.path.exists(log_file_path): - os.makedirs(log_file_path) - log_file_name = log_file_path / "log-{}-{}.log".format(LOG_FILE, logger_name) - - # print(log_file_name) - self.log_file_path = log_file_path - self.log_file_name = log_file_name - - file_handler = TimedRotatingFileHandler(log_file_name, when='midnight', encoding="UTF-8") - - file_handler.setFormatter(FORMATTER) - return file_handler - - def __repr__(self): - repr = f""" ---------------------------------------- - LOG ---------------------------------------- -this is Log class -debug level set Debug -filename : {self.log_file_name} - ----------------------------------------- -""" - - return repr - - def get_logger(self, logger_name): - logger = logging.getLogger(logger_name) - logger.setLevel(logging.DEBUG) - logger.addHandler(self.get_file_handler(logger_name)) - logger.propagate = False - return logger - - def test(self): - my_logger = self.get_logger(".{}".format(__name__)) - my_logger.debug("a debug message") - - my_logger2 = self.get_logger(".2-{}".format(__name__)) - my_logger2.debug("a debug message") - v = "test" - obj = {"value": v} - - d = my_logger.debug - d(" ") - m = my_logger - l = my_logger - l.info(" test ") - my_logger.info(" hello dolly " + v + str(obj)) - - -from functools import partial, update_wrapper - -from inspect import getframeinfo, stack - - -def debugInfo(s="", *args, **kw): - caller = getframeinfo(stack()[2][0]) - msg = "---called from : {} - line number : {} -- {} ".format(caller.filename, caller.lineno, s) - return msg - - -def get_debugger(session=None): - def show_notice(*args): - if not DEGUB_NOTICE: - return - title = "=" * 50 + " DEBUG " + "=" * 50 - print(f"{title}\nInfo : DEBUG_LOG_CANCEL is True therefore debugging was cancelled.\n " - "You should modify `initial.start_options.py` file if you like to activate\n" - f"debugging and logging behavior. if DEGUB_NOTICE is False this message will not visible \n{title}") - - def do_nothing(*args): - pass - - def show_once(*args): - global NoteShown - if not NoteShown: - # show_notice_b = update_wrapper(partial(show_notice, *args), show_notice) - NoteShown = True - return show_notice - return do_nothing - - debugOBJ = Log("DEBUG_log_") - if session: - debugOBJ.logger = debugOBJ.get_logger("DEBUG_log_{}.-{}".format(__name__, session.hash)) - else: - debugOBJ.logger = debugOBJ.get_logger("DEBUG_log_{}".format(__name__)) - - deb = debugOBJ.logger.debug - deb2 = debugOBJ.get_logger("DEBUG_URGENT_{}".format(__name__)).debug - - def deb_multi(*args): - funcs = [] - d = debugInfo(*args) - args = args + tuple([d]) - for item in args: - deb(item) - - def deb_multi2(*args): - funcs = [] - - for item in args: - deb2(item) - - if DEBUG_LOG_CANCEL: - deb_multi = show_once - deb_multi2 = show_once - debug = None - return deb_multi, deb_multi2, debugOBJ - - -############## short function -deb, deb2, debug = get_debugger() - -if __name__ == "__main__": - Log("t").test() +import logging +import sys +from logging.handlers import TimedRotatingFileHandler +import pathlib +import os + +from pathlib import Path + +NoteShown = False +from evdspy.EVDSlocal.initial.start_options import DEBUG_LOG_CANCEL, DEGUB_NOTICE + +FORMATTER = logging.Formatter("%(asctime)s — %(name)s — %(levelname)s — %(message)s ") +LOG_FILE = "LOG_" + +""" +This will stop or activate debugging +""" + + +class Log: + def __init__(self, name): + self.name = name + + def get_console_handler(self): + console_handler = logging.StreamHandler(sys.stdout) + console_handler.setFormatter(FORMATTER) + return console_handler + + def get_file_handler(self, logger_name): + log_file_path = Path() / "logs" / "log_files" # / "log-{}-{}.log" + if not os.path.exists(log_file_path): + os.makedirs(log_file_path) + log_file_name = log_file_path / "log-{}-{}.log".format(LOG_FILE, logger_name) + + # print(log_file_name) + self.log_file_path = log_file_path + self.log_file_name = log_file_name + + file_handler = TimedRotatingFileHandler(log_file_name, when='midnight', encoding="UTF-8") + + file_handler.setFormatter(FORMATTER) + return file_handler + + def __repr__(self): + repr = f""" +--------------------------------------- + LOG +--------------------------------------- +this is Log class +debug level set Debug +filename : {self.log_file_name} + +---------------------------------------- +""" + + return repr + + def get_logger(self, logger_name): + logger = logging.getLogger(logger_name) + logger.setLevel(logging.DEBUG) + logger.addHandler(self.get_file_handler(logger_name)) + logger.propagate = False + return logger + + def test(self): + my_logger = self.get_logger(".{}".format(__name__)) + my_logger.debug("a debug message") + + my_logger2 = self.get_logger(".2-{}".format(__name__)) + my_logger2.debug("a debug message") + v = "test" + obj = {"value": v} + + d = my_logger.debug + d(" ") + m = my_logger + l = my_logger + l.info(" test ") + my_logger.info(" hello dolly " + v + str(obj)) + + +from functools import partial, update_wrapper + +from inspect import getframeinfo, stack + + +def debugInfo(s="", *args, **kw): + caller = getframeinfo(stack()[2][0]) + msg = "---called from : {} - line number : {} -- {} ".format(caller.filename, caller.lineno, s) + return msg + + +def get_debugger(session=None): + def show_notice(*args): + if not DEGUB_NOTICE: + return + title = "=" * 50 + " DEBUG " + "=" * 50 + print(f"{title}\nInfo : DEBUG_LOG_CANCEL is True therefore debugging was cancelled.\n " + "You should modify `initial.start_options.py` file if you like to activate\n" + f"debugging and logging behavior. if DEGUB_NOTICE is False this message will not visible \n{title}") + + def do_nothing(*args): + pass + + def show_once(*args): + global NoteShown + if not NoteShown: + # show_notice_b = update_wrapper(partial(show_notice, *args), show_notice) + NoteShown = True + return show_notice + return do_nothing + + debugOBJ = Log("DEBUG_log_") + if session: + debugOBJ.logger = debugOBJ.get_logger("DEBUG_log_{}.-{}".format(__name__, session.hash)) + else: + debugOBJ.logger = debugOBJ.get_logger("DEBUG_log_{}".format(__name__)) + + deb = debugOBJ.logger.debug + deb2 = debugOBJ.get_logger("DEBUG_URGENT_{}".format(__name__)).debug + + def deb_multi(*args): + funcs = [] + d = debugInfo(*args) + args = args + tuple([d]) + for item in args: + deb(item) + + def deb_multi2(*args): + funcs = [] + + for item in args: + deb2(item) + + if DEBUG_LOG_CANCEL: + deb_multi = show_once + deb_multi2 = show_once + debug = None + return deb_multi, deb_multi2, debugOBJ + + +############## short function +deb, deb2, debug = get_debugger() + +if __name__ == "__main__": + Log("t").test() diff --git a/evdspy/EVDSlocal/main_.py b/evdspy/EVDSlocal/main_.py index 43f67f9..03e57fc 100644 --- a/evdspy/EVDSlocal/main_.py +++ b/evdspy/EVDSlocal/main_.py @@ -1,81 +1,81 @@ -# ------------------------------------------------------ -# -# main_.py -# package: evdspy @2022 -# ------------------------------------------------------ -from .initial.start_args import * -import typing as t - - -def print_with_failure_style(msg): - print(msg) - - -def print_with_success_style(msg): - print(msg) - - - -def check_compat(): - import platform - - v_tuple = platform.python_version_tuple() - # v_tuple = "3.6.0".split(".") - v_tuple = tuple(map(lambda x: int(x), v_tuple)) - v = sys.version # sys.version_info - if (3, 12, -1) < v_tuple: - print_with_failure_style( - f"Your python version is {v}. This program may break because it is currently only compatible with versions between 3.7 and 3.11") - return False - elif (3, 7, 0) > v_tuple: - print_with_failure_style( - f"Your python version is {v}. This program may break because it is currently only compatible with versions between 3.7 and 3.11") - return False - else: - # print_with_success_style( - # f"Your python version is {v} This program was tested with this version and runs properly. However, " - # f"if you notice a bug or if your version breaks at runtime please feel free to open a PR on github.") - return True - - -if not check_compat(): - import sys - - sys.exit(0) - - -def register_actions(actions=None) -> tuple: - if actions is None: - actions = [] - """register_actions""" - from evdspy.EVDSlocal.initial_setup.initial_setups import SetupInitial - actions.append(SetupInitial().setup) - # actions.append( SetupInitial().create_series_text_ex ) - return tuple(actions) - - -def do_start(actions: t.Tuple[t.Callable]): - """CHECK => SETUP , START ==> or => START""" - from evdspy.EVDSlocal.initial_setup.setup_folders import check_folders_setup_necessary - if not check_folders_setup_necessary(): - for action in actions: - if callable(action): - deb(f"....setting up....starting..{action.__name__}") - action() - - -def initial_checks_after_first_run(): - """initial_checks_after_first_run""" - assert callable(check) - assert callable(get) - assert callable(menu) - - -# --------------------------------- M A I N --------- - - -do_start(register_actions()) -from evdspy.EVDSlocal.initial.load_commands_ import * - -initial_checks_after_first_run() -# --------------------------------- / M A I N --------- +# ------------------------------------------------------ +# +# main_.py +# package: evdspy @2022 +# ------------------------------------------------------ +from .initial.start_args import * +import typing as t + + +def print_with_failure_style(msg): + print(msg) + + +def print_with_success_style(msg): + print(msg) + + + +def check_compat(): + import platform + + v_tuple = platform.python_version_tuple() + # v_tuple = "3.6.0".split(".") + v_tuple = tuple(map(lambda x: int(x), v_tuple)) + v = sys.version # sys.version_info + if (3, 12, -1) < v_tuple: + print_with_failure_style( + f"Your python version is {v}. This program may break because it is currently only compatible with versions between 3.7 and 3.11") + return False + elif (3, 7, 0) > v_tuple: + print_with_failure_style( + f"Your python version is {v}. This program may break because it is currently only compatible with versions between 3.7 and 3.11") + return False + else: + # print_with_success_style( + # f"Your python version is {v} This program was tested with this version and runs properly. However, " + # f"if you notice a bug or if your version breaks at runtime please feel free to open a PR on github.") + return True + + +if not check_compat(): + import sys + + sys.exit(0) + + +def register_actions(actions=None) -> tuple: + if actions is None: + actions = [] + """register_actions""" + from evdspy.EVDSlocal.initial_setup.initial_setups import SetupInitial + actions.append(SetupInitial().setup) + # actions.append( SetupInitial().create_series_text_ex ) + return tuple(actions) + + +def do_start(actions: t.Tuple[t.Callable]): + """CHECK => SETUP , START ==> or => START""" + from evdspy.EVDSlocal.initial_setup.setup_folders import check_folders_setup_necessary + if not check_folders_setup_necessary(): + for action in actions: + if callable(action): + deb(f"....setting up....starting..{action.__name__}") + action() + + +def initial_checks_after_first_run(): + """initial_checks_after_first_run""" + assert callable(check) + assert callable(get) + assert callable(menu) + + +# --------------------------------- M A I N --------- + + +do_start(register_actions()) +from evdspy.EVDSlocal.initial.load_commands_ import * + +initial_checks_after_first_run() +# --------------------------------- / M A I N --------- diff --git a/evdspy/EVDSlocal/manual_requests/prepare.py b/evdspy/EVDSlocal/manual_requests/prepare.py index 5d50a9a..5e56439 100644 --- a/evdspy/EVDSlocal/manual_requests/prepare.py +++ b/evdspy/EVDSlocal/manual_requests/prepare.py @@ -1,151 +1,167 @@ -from dataclasses import dataclass, field -from typing import List, Union, Tuple -from evdspy.EVDSlocal.messages.error_classes import ApiKeyNotSetError, SeriesEmptyError -from evdspy.EVDSlocal.config.config import config -from rich import print, inspect - -CANCEL_REQUEST_TEMP = config.cancel_request_temp - - -def test(): - p = PrepareUrl(series=('TP_ODEMGZS_NORVEC-8',), frequency=5, api_key='api_key') - print(p.get_data()) - - - - -def basic_for_test(api_key): - url = "https://evds2.tcmb.gov.tr/service/evds/series=TP.ODEMGZS.BDTTOPLAM-TP.ODEMGZS.ABD-TP.ODEMGZS.ARJANTIN-TP.ODEMGZS.BREZILYA-TP.ODEMGZS.KANADA-TP.ODEMGZS.KOLOMBIYA-TP.ODEMGZS.MEKSIKA-TP.ODEMGZS.SILI&startDate=01-01-2019&endDate=01-12-2030&frequency=5&aggregationTypes=avg-avg-avg-avg-avg-avg-avg-avg&formulas=0-0-0-0-0-0-0-0&type=csv" - url = f"{url}&key={api_key}" - p_basic = PrepareUrl() - response = p_basic.get_data_with_url(url) - return response.status_code in (200,) - - -def basic_for_test2(api_key): - p_basic = PrepareUrl( - series=('TP.ODEAYRSUNUM6.Q1',), - api_key=api_key, - frequency=5, - basic=True) - print(p_basic.get_data()) - url = p_basic.get_data() - url = clean(url) - print(url) - return "..." - - - - -def basic_test_with_real_key(): - real_api_key = '' - return basic_for_test(real_api_key) - - -def clean(url): - import string - return url.translate({ord(c): None for c in string.whitespace}) - - -default_start_date = "01-01-2019" -default_end_date = "01-01-2030" - - -@dataclass -class PrepareUrl: - series: Tuple[str] = () - api_key: str = "" - frequency: Union[int, None] = None - aggregateType: Union[str, None] = "avg" - basic: bool = False - - def get_data(self, - series=None, - api_key=None, - startDate=default_start_date, - endDate=default_end_date, - frequency=None, - aggregateType=None - ): - if series is None: - series = self.series - if api_key is None: - api_key = self.api_key - if frequency is None: - frequency = self.frequency - - if self.basic: - self.create_url( - series=series, - api_key=api_key, - startDate=startDate, - endDate=endDate, - frequency=frequency, - aggregateType=aggregateType, - ) - return self.get( - self.create_url( - series=series, - api_key=api_key, - startDate=startDate, - endDate=endDate, - frequency=frequency, - aggregateType=aggregateType, - )) - - def get(self, url): - print(url) - return url - - def get_data_with_url(self, url): - return self.make_request(url) - - def series_to_str(self, series): - return "-".join(series) - - def create_url(self, series, api_key, startDate, endDate, frequency, aggregateType): - domain: str = "https://evds2.tcmb.gov.tr/service/evds/" - - if series is None: - raise SeriesEmptyError - if api_key is None: - raise ApiKeyNotSetError - - if frequency is None and aggregateType is None: - return f"{domain}series={self.series_to_str(series)}&startDate={startDate}&endDate={endDate}&type=csv&key={api_key}" - if frequency: - if aggregateType: - return f"{domain}series={self.series_to_str(series)}" \ - f"&frequency={frequency}" \ - f"&aggregationTypes={aggregateType}" \ - f"&type=csv" \ - f"&key={api_key}" - else: - return f"{domain}series={self.series_to_str(series)}" \ - f"&frequency={frequency}" \ - f"&aggregationTypes=avg" \ - f"&type=csv" \ - f"&key={api_key}" - - def make_request(self, url=None): - from ..messages.error_classes import ApiKeyNotSetError - - if url is None: - url = self.url - - if CANCEL_REQUEST_TEMP: - print("CANCEL_REQUEST_TEMP is True ...prepare.151") - return False - try: - self.response = requests.get(url) - except ApiKeyNotSetError: - ... - return - return self.response - - -import requests - - -def make_request(url: str): - return requests.get(url) +from dataclasses import dataclass, field +from typing import List, Union, Tuple +from evdspy.EVDSlocal.messages.error_classes import ApiKeyNotSetError, SeriesEmptyError +from evdspy.EVDSlocal.config.config import config +from evdspy.EVDSlocal.requests_.real_requests import RealRequestWithParam + +CANCEL_REQUEST_TEMP = config.cancel_request_temp + + +def test(): + p = PrepareUrl(series=('TP_ODEMGZS_NORVEC-8',), frequency=5, api_key='api_key') + print(p.get_data()) + + +from rich import print, inspect + + +def basic_for_test(api_key): + url = "https://evds2.tcmb.gov.tr/service/evds/series=TP.ODEMGZS.BDTTOPLAM-TP.ODEMGZS.ABD-TP.ODEMGZS.ARJANTIN-TP.ODEMGZS.BREZILYA-TP.ODEMGZS.KANADA-TP.ODEMGZS.KOLOMBIYA-TP.ODEMGZS.MEKSIKA-TP.ODEMGZS.SILI&startDate=01-01-2019&endDate=01-12-2030&frequency=5&aggregationTypes=avg-avg-avg-avg-avg-avg-avg-avg&formulas=0-0-0-0-0-0-0-0&type=csv" + # url = f"{url}&key={api_key}" + req = RealRequestWithParam(url, api_key=api_key) + response = req.request() + # p_basic = PrepareUrl() + # response = p_basic.get_data_with_url(url) + + return getattr(response, "status_code") and response.status_code in (200,) + + +def basic_for_testOLD(api_key): + url = "https://evds2.tcmb.gov.tr/service/evds/series=TP.ODEMGZS.BDTTOPLAM-TP.ODEMGZS.ABD-TP.ODEMGZS.ARJANTIN-TP.ODEMGZS.BREZILYA-TP.ODEMGZS.KANADA-TP.ODEMGZS.KOLOMBIYA-TP.ODEMGZS.MEKSIKA-TP.ODEMGZS.SILI&startDate=01-01-2019&endDate=01-12-2030&frequency=5&aggregationTypes=avg-avg-avg-avg-avg-avg-avg-avg&formulas=0-0-0-0-0-0-0-0&type=csv" + url = f"{url}&key={api_key}" + p_basic = PrepareUrl() + response = p_basic.get_data_with_url(url) + + return getattr(response, "status_code") and response.status_code in (200,) + + +def basic_for_test2(api_key): + p_basic = PrepareUrl( + series=('TP.ODEAYRSUNUM6.Q1',), + api_key=api_key, + frequency=5, + basic=True) + print(p_basic.get_data()) + url = p_basic.get_data() + url = clean(url) + print(url) + return "WHAT" + # make_request + return p_basic.response.status_code in (200,) + + +def basic_test_with_real_key(): + real_api_key = '' + return basic_for_test(real_api_key) + + +def clean(url): + import string + return url.translate({ord(c): None for c in string.whitespace}) + + +default_start_date = "01-01-2019" +default_end_date = "01-01-2030" + + +@dataclass +class PrepareUrl: + series: Tuple[str] = () + api_key: str = "" + frequency: Union[int, None] = None + aggregateType: Union[str, None] = "avg" + basic: bool = False + + def get_data(self, + series=None, + api_key=None, + startDate=default_start_date, + endDate=default_end_date, + frequency=None, + aggregateType=None + ): + if series is None: + series = self.series + if api_key is None: + api_key = self.api_key + if frequency is None: + frequency = self.frequency + + if self.basic: + self.create_url( + series=series, + api_key=api_key, + startDate=startDate, + endDate=endDate, + frequency=frequency, + aggregateType=aggregateType, + ) + return self.get( + self.create_url( + series=series, + api_key=api_key, + startDate=startDate, + endDate=endDate, + frequency=frequency, + aggregateType=aggregateType, + )) + + def get(self, url): + print(url) + return url + + def get_data_with_url(self, url): + return self.make_request(url) + + def series_to_str(self, series): + return "-".join(series) + + def create_url(self, series, api_key, startDate, endDate, frequency, aggregateType): + domain: str = "https://evds2.tcmb.gov.tr/service/evds/" + + if series is None: + raise SeriesEmptyError + if api_key is None: + raise ApiKeyNotSetError + + if frequency is None and aggregateType is None: + return f"{domain}series={self.series_to_str(series)}&startDate={startDate}&endDate={endDate}&type=csv&key={api_key}" + if frequency: + if aggregateType: + return f"{domain}series={self.series_to_str(series)}" \ + f"&frequency={frequency}" \ + f"&aggregationTypes={aggregateType}" \ + f"&type=csv" \ + f"&key={api_key}" + else: + return f"{domain}series={self.series_to_str(series)}" \ + f"&frequency={frequency}" \ + f"&aggregationTypes=avg" \ + f"&type=csv" \ + f"&key={api_key}" + + def make_request(self, url=None): + from ..messages.error_classes import ApiKeyNotSetError + + if url is None: + url = self.url + + if CANCEL_REQUEST_TEMP: + print("CANCEL_REQUEST_TEMP is True ...prepare.151") + return False + try: + # self.response = requests.get(url) + self.response = RealRequestWithParam(url).request() + + + except ApiKeyNotSetError: + ... + return + return self.response + + +import requests + + +def make_request(url: str): + return requests.get(url) diff --git a/evdspy/EVDSlocal/messages/cmd_formats.py b/evdspy/EVDSlocal/messages/cmd_formats.py index 1a6810d..f8dc8fd 100644 --- a/evdspy/EVDSlocal/messages/cmd_formats.py +++ b/evdspy/EVDSlocal/messages/cmd_formats.py @@ -1,5 +1,5 @@ - -setup_now_command = f""" \ - from evdspy.main import * - setup_now() + +setup_now_command = f""" \ + from evdspy.main import * + setup_now() """ \ No newline at end of file diff --git a/evdspy/EVDSlocal/messages/current_menu_message.py b/evdspy/EVDSlocal/messages/current_menu_message.py index 2e009a9..1c45d96 100644 --- a/evdspy/EVDSlocal/messages/current_menu_message.py +++ b/evdspy/EVDSlocal/messages/current_menu_message.py @@ -1,22 +1,22 @@ -current_menu_appears = f""" - Quickly setup your work environment run commands from the menu. - Currently you may choose one below or create your own functions and - add to this list following instructions on Readme.md - -------------------------------------------------- - M E N U - -------------------------------------------------- - 1. check setup - 2. setup - 3. create user options file - 4. create series file - 5. add new series group - 6. get data - 7. get categories - 8. help - 9. show api key - 10. save api key to file - 11. remove cache folders - 12. evdspy as a command line prompt - 13. version - 14. console +current_menu_appears = f""" + Quickly setup your work environment run commands from the menu. + Currently you may choose one below or create your own functions and + add to this list following instructions on Readme.md + -------------------------------------------------- + M E N U + -------------------------------------------------- + 1. check setup + 2. setup + 3. create user options file + 4. create series file + 5. add new series group + 6. get data + 7. get categories + 8. help + 9. show api key + 10. save api key to file + 11. remove cache folders + 12. evdspy as a command line prompt + 13. version + 14. console """ \ No newline at end of file diff --git a/evdspy/EVDSlocal/messages/error_classes.py b/evdspy/EVDSlocal/messages/error_classes.py index 87f36c8..cd28a62 100644 --- a/evdspy/EVDSlocal/messages/error_classes.py +++ b/evdspy/EVDSlocal/messages/error_classes.py @@ -1,39 +1,39 @@ -from ..common.common_imports import * - - -########################### Base Exception Class ########################### -class BaseException(Exception): - def __init__(self, message="Something happpened"): - self.message = message - super().__init__(self.message) - - def __str__(self): - return f' -> {self.message}' - - -########################### / Base Exception Class ########################### -class ApiKeyNotSetError(BaseException): - def __init__(self, message="Api key not set yet."): - self.message = message - -class SeriesEmptyError(BaseException): - def __init__(self, message="Series cannot be empty"): - self.message = message - -class OptionsFileNotLoadedError(BaseException): - def __init__(self, message="Options file not loaded..."): - self.message = message - - -class SeriesFileDoesNotExists(BaseException): - def __init__(self, message="Series file does not exist..."): - self.message = message - - -class BucketFromSeriesFolderCreateError(BaseException): - def __init__(self, message="BucketFromSeriesFolderCreateError folder problem"): - self.message = message - - -class ExceptionMixing(ABC): - ... +from ..common.common_imports import * + + +########################### Base Exception Class ########################### +class BaseException(Exception): + def __init__(self, message="Something happpened"): + self.message = message + super().__init__(self.message) + + def __str__(self): + return f' -> {self.message}' + + +########################### / Base Exception Class ########################### +class ApiKeyNotSetError(BaseException): + def __init__(self, message="Api key not set yet."): + self.message = message + +class SeriesEmptyError(BaseException): + def __init__(self, message="Series cannot be empty"): + self.message = message + +class OptionsFileNotLoadedError(BaseException): + def __init__(self, message="Options file not loaded..."): + self.message = message + + +class SeriesFileDoesNotExists(BaseException): + def __init__(self, message="Series file does not exist..."): + self.message = message + + +class BucketFromSeriesFolderCreateError(BaseException): + def __init__(self, message="BucketFromSeriesFolderCreateError folder problem"): + self.message = message + + +class ExceptionMixing(ABC): + ... diff --git a/evdspy/EVDSlocal/messages/error_messages.py b/evdspy/EVDSlocal/messages/error_messages.py index ef3ca75..a0cec0b 100644 --- a/evdspy/EVDSlocal/messages/error_messages.py +++ b/evdspy/EVDSlocal/messages/error_messages.py @@ -1,53 +1,53 @@ -from .help_messages import * -from .cmd_formats import * - -api_key_not_set_msg = f""" - --------------------------------------------------------------- - WARNING - --------------------------------------------------------------- - Api key not set . - --------------------------------------------------------------- - you may continue with saving your api key by answering - `yes` - - Program will store your api key in your work environment creating a folder `APIKEY_FOLDER` and read it when - it needs to request data from EVDS server. - - This key will be used when you run your requests and will be saved to your work environment - in a folder named APIKEY_FOLDER in a text file not as a plane text but in a obscured way. - If you are working in a public workspace we suggest that you delete this folder once you are finished making requests. - Program will not use or store your API key to any other folder therefore when you delete, remove or rename this folder - program will ask your API key again. - - Below, there are links of the institution's web service. Signing up or logining in you may find your API key on - your account. - - You may get your api key from your account on CBRT EVDS website. - - CBRT EVDS API (TCMB EVDS API) - ----------------- - - Sign up / Log in - https://evds2.tcmb.gov.tr/index.php?/evds/login - Main page - https://evds2.tcmb.gov.tr - Docs - https://evds2.tcmb.gov.tr/index.php?/evds/userDocs - - If you already have an API key may continue with saving your api key by answering - `yes` now and then your API key""" -you_need_to_run_setup_options = f""" - it looks like options.py not created. - try command below from command line in your project's root folder. - -{setup_now_command} - - -""" - -copying_options_msg = "Found an options file... Trying to copy it to temporary env." - -series_file_not_found_error_msg = f""" -create_series_file - -""" +from .help_messages import * +from .cmd_formats import * + +api_key_not_set_msg = f""" + --------------------------------------------------------------- + WARNING + --------------------------------------------------------------- + Api key not set . + --------------------------------------------------------------- + you may continue with saving your api key by answering + `yes` + + Program will store your api key in your work environment creating a folder `APIKEY_FOLDER` and read it when + it needs to request data from EVDS server. + + This key will be used when you run your requests and will be saved to your work environment + in a folder named APIKEY_FOLDER in a text file not as a plane text but in a obscured way. + If you are working in a public workspace we suggest that you delete this folder once you are finished making requests. + Program will not use or store your API key to any other folder therefore when you delete, remove or rename this folder + program will ask your API key again. + + Below, there are links of the institution's web service. Signing up or logining in you may find your API key on + your account. + + You may get your api key from your account on CBRT EVDS website. + + CBRT EVDS API (TCMB EVDS API) + ----------------- + + Sign up / Log in + https://evds2.tcmb.gov.tr/index.php?/evds/login + Main page + https://evds2.tcmb.gov.tr + Docs + https://evds2.tcmb.gov.tr/index.php?/evds/userDocs + + If you already have an API key may continue with saving your api key by answering + `yes` now and then your API key""" +you_need_to_run_setup_options = f""" + it looks like options.py not created. + try command below from command line in your project's root folder. + +{setup_now_command} + + +""" + +copying_options_msg = "Found an options file... Trying to copy it to temporary env." + +series_file_not_found_error_msg = f""" +create_series_file + +""" diff --git a/evdspy/EVDSlocal/messages/help_messages.py b/evdspy/EVDSlocal/messages/help_messages.py index 62b99e0..1dfe22f 100644 --- a/evdspy/EVDSlocal/messages/help_messages.py +++ b/evdspy/EVDSlocal/messages/help_messages.py @@ -1,158 +1,158 @@ -from .cmd_formats import * -from ..common.common_imports import * -from ..common.files import Read, ReadBytes - - -def display_help_messages_md(): - def ReadLocal(filename: str): - long_des = "" - - with open(filename, "r") as file_: - long_des = file_.read() - return long_des - - # return - from rich.console import Console - from rich.markdown import Markdown - print(Path().parent) - content_md = ReadLocal(str(Path() / Path().parent / "README.md")) - console = Console() - # print(content_md) - md = Markdown(content_md) - console.print(md) - return content_md - # content_md = str(content_md).encode('utf8') - # md = Markdown(str(content_md)) - # console.print(md) - - -def display_help_messages(): - from .current_menu_message import current_menu_appears - - """ Some help to show some useful commands of evdspy package """ - ############## commands ################# - msg = rf""" - - ---------importing ----- -from evdspy import * - -------------- - -menu() : -------------- - Quickly setup your work environment run commands from the menu. \ - Currently you may choose one below or create your own functions and \ - add to this list following instructions on Readme.md -${current_menu_appears} - - -help_evds() : -------------- - to see a list of initial commands - to check setup and reinitialize some installations. - -check(): -------------- - see current installation status - -setup() : -------------- - # this function helps you setup your project by asking your preferences step by step - setup() -get(): -------------- - # this will check for your current config_series.cfg file - # if proper data series codes are given it will either download them - # or use latest cache from your local environment - # to provide other cache options such as nocache / daily / hourly you may change your - # defaults or give arguments such as - - get(cache="daily") - get(cache = "nocache") - or to go with default from your option file - get() - -save("MyApiKey" ): -------------- - # saves your api key to use while requesting data from the server.\ - # creates an APIKEY_FOLDER and saves some hash function of your api key for security. - # If you are on a public computer we suggest you delete this folder when you are done requesting data. - - save("MyApiKey") - -save(): -------------- - When you call it with not argument program will ask for your key and do the same - above -create_series_file(): -------------- - # creates example `config_series.cfg` evdspy input file (EIF) formatted - # you may modify it accordingly, you may user separator of `--++--` between different series groups - - create_series_file() - # or - csf() - -menu() : -------------- - -Quickly setup your work environment run commands from the menu. -Currently you may choose one below or create your own functions and -add to this list following instructions on Readme.md -${current_menu_appears} - ------------------------------------------------------------------------ -# from evdspy import * #(if you have not imported evdspy yet ) -menu() # to see the menu() ------------------------------------------------------------------------ -""" - ############## END of commands ################# - - ################ p r i n t ############### - print(msg) - ################ ####### - - -from rich import print -from ..common.colors import * - - -def welcome_message(): - msg = f""" - Welcome to evsdpy python interface... - -------------------------------------------------------------------------------------------------- - This message appears when you use evdspy as a command line prompt. - This welcome and help message will show up when you use `evdspy` command with no parameters... - -------------------------------------------------------------------------------------------------- - Some parameters are listed below. If there is another command you are looking for you may check the menu option. - - $ evdspy setup - -------------- - creates initial folders for your environment to save data and caches - - $ evdspy menu - -------------- - Loads the menu - - $ evdspy create series - -------------- - Creates series file (leaves untouched if exists) - - $ evdspy create options - -------------- - creates options on the current folder - - $ evdspy save - -------------- - asks for your api key to save a file in your environment named `APIKEY_FOLDER` - - $ evdspy get - -------------- - makes request from EVDS API and creates excel files regarding information on your series file - - $ evdspy help - -------------- - shows help and some documentation from command line -""" - print_with_success_style(msg) +from .cmd_formats import * +from ..common.common_imports import * +from ..common.files import Read, ReadBytes + + +def display_help_messages_md(): + def ReadLocal(filename: str): + long_des = "" + + with open(filename, "r") as file_: + long_des = file_.read() + return long_des + + # return + from rich.console import Console + from rich.markdown import Markdown + print(Path().parent) + content_md = ReadLocal(str(Path() / Path().parent / "README.md")) + console = Console() + # print(content_md) + md = Markdown(content_md) + console.print(md) + return content_md + # content_md = str(content_md).encode('utf8') + # md = Markdown(str(content_md)) + # console.print(md) + + +def display_help_messages(): + from .current_menu_message import current_menu_appears + + """ Some help to show some useful commands of evdspy package """ + ############## commands ################# + msg = rf""" + + +--------importing ----- +from evdspy import * + +------------- + +menu() : +------------- + Quickly setup your work environment run commands from the menu. \ + Currently you may choose one below or create your own functions and \ + add to this list following instructions on Readme.md +${current_menu_appears} + + +help_evds() : +------------- + to see a list of initial commands + to check setup and reinitialize some installations. + +check(): +------------- + see current installation status + +setup() : +------------- + # this function helps you setup your project by asking your preferences step by step + setup() +get(): +------------- + # this will check for your current config_series.cfg file + # if proper data series codes are given it will either download them + # or use latest cache from your local environment + # to provide other cache options such as nocache / daily / hourly you may change your + # defaults or give arguments such as + + get(cache="daily") + get(cache = "nocache") + or to go with default from your option file + get() + +save("MyApiKey" ): +------------- + # saves your api key to use while requesting data from the server.\ + # creates an APIKEY_FOLDER and saves some hash function of your api key for security. + # If you are on a public computer we suggest you delete this folder when you are done requesting data. + + save("MyApiKey") + +save(): +------------- + When you call it with not argument program will ask for your key and do the same + above +create_series_file(): +------------- + # creates example `config_series.cfg` evdspy input file (EIF) formatted + # you may modify it accordingly, you may user separator of `--++--` between different series groups + + create_series_file() + # or + csf() + +menu() : +------------- + +Quickly setup your work environment run commands from the menu. +Currently you may choose one below or create your own functions and +add to this list following instructions on Readme.md +${current_menu_appears} + +----------------------------------------------------------------------- +# from evdspy import * #(if you have not imported evdspy yet ) +menu() # to see the menu() +----------------------------------------------------------------------- +""" + ############## END of commands ################# + + ################ p r i n t ############### + print(msg) + ################ ####### + + +from rich import print +from ..common.colors import * + + +def welcome_message(): + msg = f""" + Welcome to evsdpy python interface... + -------------------------------------------------------------------------------------------------- + This message appears when you use evdspy as a command line prompt. + This welcome and help message will show up when you use `evdspy` command with no parameters... + -------------------------------------------------------------------------------------------------- + Some parameters are listed below. If there is another command you are looking for you may check the menu option. + + $ evdspy setup + -------------- + creates initial folders for your environment to save data and caches + + $ evdspy menu + -------------- + Loads the menu + + $ evdspy create series + -------------- + Creates series file (leaves untouched if exists) + + $ evdspy create options + -------------- + creates options on the current folder + + $ evdspy save + -------------- + asks for your api key to save a file in your environment named `APIKEY_FOLDER` + + $ evdspy get + -------------- + makes request from EVDS API and creates excel files regarding information on your series file + + $ evdspy help + -------------- + shows help and some documentation from command line +""" + print_with_success_style(msg) diff --git a/evdspy/EVDSlocal/requests_/ev_request.py b/evdspy/EVDSlocal/requests_/ev_request.py index 681a8d2..90e5c7e 100644 --- a/evdspy/EVDSlocal/requests_/ev_request.py +++ b/evdspy/EVDSlocal/requests_/ev_request.py @@ -1,231 +1,241 @@ -# ------------------------------------------------------------------------------ -import requests as requests - -from evdspy.EVDSlocal.components.url_class import URLClass -from evdspy.EVDSlocal.utils.utils_general import * -from evdspy.EVDSlocal.requests_.my_cache import MyCache, save_pickle_for_test, lru_cache_patched, load_test_pickle -from evdspy.EVDSlocal.components.options_class import Options -from evdspy.EVDSlocal.config.credentials_file import Credentials -from evdspy.EVDSlocal.initial.start_options import current_mode_is_test -from evdspy.EVDSlocal.initial.start_args import Args -from evdspy.EVDSlocal.messages.error_classes import * -from evdspy.EVDSlocal.config.apikey_class import * -from evdspy.EVDSlocal.config.config import config -from evdspy.EVDSlocal.requests_.my_cache import load_pickle -from evdspy.EVDSlocal.stats.save_stats_of_requests import * -from evdspy.EVDSlocal.requests_.request_error_classes import REQUEST_ERROR_CODES -from evdspy.EVDSlocal.common.url_clean import remove_api_key - -from dataclasses import dataclass - -# ------------------------------------------------------------------------------ - -m_cache = MyCache() - -from evdspy.EVDSlocal.config.config import config - -CANCEL_REQUEST_TEMP = config.cancel_request_temp - - -def do_first_true_order(funcs, preds, url): - conds = zip(funcs, preds) - for func, pred in conds: - if isinstance(pred, bool) and pred: - v = func(url) - return v - return False - - -def mock_request(url, proxies=None) -> requests.models.Response: - """ pytest will get this mock response object""" - assert isinstance(url, str) - file_name = str(Path(__file__).parent / "test_reg_result") - assert Path(file_name + ".pickle").is_file(), f"file does not exist {file_name}" - return load_pickle(file_name) - - -def decide_request_for_test_real(url: str, proxies=None): - """ Finally ready to make request """ - if config.current_mode_is_test and not config.temp_cancel_mock_request: - """ pytest will get this mock response object""" - return mock_request(url, proxies) - # print(f"WARNING : mock results are coming {url}") - # return mock_request(url, proxies) - - if CANCEL_REQUEST_TEMP: - print("request was cancelled...") - return mock_request(url, proxies) - if proxies is None: - return requests.get(url) - - return requests.get(url, proxies=proxies) - - -@dataclass -class EVRequest: - options_: Options - session: any = None - proxy: Optional[str] = False - args: Args = field(default_factory=Args) # None # Args(tuple(sys.argv)) - last_url_checked: str = "NoneURL" - URL_Instance: field(default_factory=URLClass) = field(default_factory=URLClass) - - # report : post init - def __post_init__(self): - # self.URL_Instance = field(default_factory=URLClass) # None - - self.credentials = Credentials(self.options_) - """ - we are now reporting how many times - we requested new items and how many times we avoided making new - request by using cache results... - """ - self.report = Report("stats_requests.txt") - - def get_request_with_proxy(self, url: str, proxy: str): - proxies = { - 'http': proxy, - 'https': proxy, - } - return decide_request_for_test_real(url, proxies=proxies) - - def proxy_from_file(self, url: str): - print("using proxy from file") - return self.get_request_with_proxy(url, self.args.proxy) - - def proxy_from_cmd_line(self, url: str): - print("using proxy from commandline") - return self.get_request_with_proxy(url, self.args.proxy) - - def check_any_apikey(self): - if not config.current_mode_is_test: - return True - if not ApikeyClass().get_valid_api_key(): - raise ApiKeyNotSetError - return True - - def check_if_request_ok(self, status_code: int): - corrects = (200,) - if status_code in corrects: - self.report.add(f"{status_code} returned. ") - return True - - self.report.add(f"{status_code} returned. ") - ExceptionClass = REQUEST_ERROR_CODES.get(status_code, None) - if ExceptionClass: - print(ExceptionClass) - print(f"STATUS CODE : {status_code}\n url : {remove_api_key(self.last_url_checked)}") - time.sleep(2) - # raise ExceptionClass(self.__doc__) - else: - print( - f"Program was checking request status code and noticed " - f"{status_code} not included in `REQUEST_ERROR_CODES`" - ) - - self.report.add(f"{status_code} returned. ") - return False - - def post_urls(self, url: str) -> tuple: - - # url = url.translate({ord(c): None for c in string.whitespace}) - url = URL_temizle(url) # whitespace etc. - - no_apikey_url = remove_api_key(url) # remove key for logs - self.report.add(f"{no_apikey_url} will be requested. ") - - self.last_url_checked = url - - return (url, no_apikey_url) - - def get_request_alternatives(self, url): - result = do_first_true_order( - funcs=[ - self.proxy_from_cmd_line, - self.proxy_from_file, - decide_request_for_test_real - ], - preds=[ - self.args.proxy, - self.credentials.proxy, - True], - url=url - ) - return result - - def check_result(self, result): - if any( - ( - not hasattr(result, "status_code"), - not isinstance(result.status_code, int), - not self.check_if_request_ok(result.status_code) - ) - ): - print(f"request returned an error code {result.status_code} , url : {self.no_apikey_url}") - return False - return True - - def get_request_before_cache(self, url: str): - """ - decorated version of this function needs to be - welcomed by this func to check api key etc. - TODO - stats for apikey and results - warn user if there are many 500 status_code results for the certain api key - """ - no_apikey_url = remove_api_key(url) - # print("checking url ... ", no_apikey_url) - if not self.check_any_apikey(): - return False - - return self.get_request(url) - - def get_request(self, url: str): - """ - first will check cache if there is cache - below will not run at all - """ - - # if ApikeyClass().now_testing_is_key_is_valid : - # return self.get_request_by_checking_NO_CACHE(url) - return self.get_request_by_checking_cache(url) - - # return self.get_request_helper(url ) - - @lru_cache_patched - @m_cache.cache - def get_request_by_checking_cache(self, url: str): - """ - - """ - - return self.get_request_common(url) - - def get_request_by_checking_NO_CACHE(self, url: str): - """ - - """ - return self.get_request_common(url) - - def get_request_common(self, url: str): - """ - first will check cache if there is cache - below will not run at all - """ - - self.url, self.no_apikey_url = self.post_urls(url) - if current_mode_is_test: - print("Current Mode is test not requesting new data see initial.start_options") - return load_test_pickle() - """ if it is running we are definitely requesting """ - safe_url = remove_api_key(self.url) - print("requesting!!", safe_url) - """ Exception checks will happen in function below""" - result = self.get_request_alternatives(self.url) - # result = self.get_request_alternatives(self.no_apikey_url) - if not self.check_result(result): - return False - """ request looks solid we are ready to save """ - if result and self.check_if_request_ok(result.status_code): - save_pickle_for_test(result) - return result +# ------------------------------------------------------------------------------ +import requests as requests + +from evdspy.EVDSlocal.components.url_class import URLClass +from evdspy.EVDSlocal.utils.utils_general import * +from evdspy.EVDSlocal.requests_.my_cache import MyCache, save_pickle_for_test, lru_cache_patched, load_test_pickle +from evdspy.EVDSlocal.components.options_class import Options +from evdspy.EVDSlocal.config.credentials_file import Credentials +from evdspy.EVDSlocal.initial.start_options import current_mode_is_test +from evdspy.EVDSlocal.initial.start_args import Args +from evdspy.EVDSlocal.messages.error_classes import * +from evdspy.EVDSlocal.config.apikey_class import * +from evdspy.EVDSlocal.config.config import config +from evdspy.EVDSlocal.requests_.my_cache import load_pickle +from evdspy.EVDSlocal.stats.save_stats_of_requests import * +from evdspy.EVDSlocal.requests_.request_error_classes import REQUEST_ERROR_CODES +from evdspy.EVDSlocal.common.url_clean import remove_api_key + +from dataclasses import dataclass +from evdspy.EVDSlocal.requests_.mock_req import * +from evdspy.EVDSlocal.requests_.real_requests import * + +# ------------------------------------------------------------------------------ + +m_cache = MyCache() + +from evdspy.EVDSlocal.config.config import config + +CANCEL_REQUEST_TEMP = config.cancel_request_temp + + +def do_first_true_order(funcs, preds, url): + conds = zip(funcs, preds) + for func, pred in conds: + if isinstance(pred, bool) and pred: + v = func(url) + return v + return False + + +def decide_request_for_test_real(url: str, proxies=None): + """ Finally ready to make request """ + if config.current_mode_is_test and not config.temp_cancel_mock_request: + """ pytest will get this mock response object""" + return mock_request(url, proxies) + # print(f"WARNING : mock results are coming {url}") + # return mock_request(url, proxies) + + if CANCEL_REQUEST_TEMP: + print("request was cancelled...") + return mock_request(url, proxies) + if proxies is None: + return requests.get(url) + + return requests.get(url, proxies=proxies) + + +@dataclass +class EVRequest: + options_: Options + session: any = None + proxy: Optional[str] = False + args: Args = field(default_factory=Args) # None # Args(tuple(sys.argv)) + last_url_checked: str = "NoneURL" + URL_Instance: field(default_factory=URLClass) = field(default_factory=URLClass) + + # report : post init + def __post_init__(self): + # self.URL_Instance = field(default_factory=URLClass) # None + + self.credentials = Credentials(self.options_) + """ + we are now reporting how many times + we requested new items and how many times we avoided making new + request by using cache results... + """ + self.report = Report("stats_requests.txt") + + def get_request_with_proxy(self, url: str, proxy: str): + proxies = { + 'http': proxy, + 'https': proxy, + } + return decide_request_for_test_real(url, proxies=proxies) + + def get_proxies(self): + + if self.args.proxy is None: + return None + proxy = self.args.proxy + proxies = { + 'http': proxy, + 'https': proxy, + } + return proxies + + def proxy_from_file(self, url: str): + print("using proxy from file") + return self.get_request_with_proxy(url, self.args.proxy) + + def proxy_from_cmd_line(self, url: str): + print("using proxy from commandline") + return self.get_request_with_proxy(url, self.args.proxy) + + def check_any_apikey(self): + if not config.current_mode_is_test: + return True + if not ApikeyClass().get_valid_api_key(): + raise ApiKeyNotSetError + return True + + def check_if_request_ok(self, status_code: int): + corrects = (200,) + if status_code in corrects: + self.report.add(f"{status_code} returned. ") + return True + + self.report.add(f"{status_code} returned. ") + ExceptionClass = REQUEST_ERROR_CODES.get(status_code, None) + if ExceptionClass: + print(ExceptionClass) + print(f"STATUS CODE : {status_code}\n url : {remove_api_key(self.last_url_checked)}") + time.sleep(2) + # raise ExceptionClass(self.__doc__) + else: + print( + f"Program was checking request status code and noticed " + f"{status_code} not included in `REQUEST_ERROR_CODES`" + ) + + self.report.add(f"{status_code} returned. ") + return False + + def post_urls(self, url: str) -> tuple: + + # url = url.translate({ord(c): None for c in string.whitespace}) + url = URL_temizle(url) # whitespace etc. + + no_apikey_url = remove_api_key(url) # remove key for logs + self.report.add(f"{no_apikey_url} will be requested. ") + + self.last_url_checked = url + + return (url, no_apikey_url) + + def get_request_alternatives(self, url): + result = do_first_true_order( + funcs=[ + self.proxy_from_cmd_line, + self.proxy_from_file, + decide_request_for_test_real + ], + preds=[ + self.args.proxy, + self.credentials.proxy, + True], + url=url + ) + return result + + def check_result(self, result): + if any( + ( + not hasattr(result, "status_code"), + not isinstance(result.status_code, int), + not self.check_if_request_ok(result.status_code) + ) + ): + print(f"request returned an error code {result.status_code} , url : {self.no_apikey_url}") + return False + return True + + def get_request_before_cache(self, url: str): + """ + decorated version of this function needs to be + welcomed by this func to check api key etc. + TODO + stats for apikey and results + warn user if there are many 500 status_code results for the certain api key + """ + no_apikey_url = remove_api_key(url) + # print("checking url ... ", no_apikey_url) + if not self.check_any_apikey(): + return False + + return self.get_request(url) + + def get_request(self, url: str): + """ + first will check cache if there is cache + below will not run at all + """ + + # if ApikeyClass().now_testing_is_key_is_valid : + # return self.get_request_by_checking_NO_CACHE(url) + return self.get_request_by_checking_cache(url) + + # return self.get_request_helper(url ) + + @lru_cache_patched + @m_cache.cache + def get_request_by_checking_cache(self, url: str): + """ + + """ + + return self.get_request_common(url) + + def get_request_by_checking_NO_CACHE(self, url: str): + """ + + """ + return self.get_request_common(url) + + def get_request_w_param(self, url: str, proxies=None): + return RealRequestWithParam(url, proxies).request() + + def get_request_common(self, url: str): + """ + first will check cache if there is cache + below will not run at all + """ + + self.url, self.no_apikey_url = self.post_urls(url) + if current_mode_is_test: + print("Current Mode is test not requesting new data see initial.start_options") + return load_test_pickle() + """ if it is running we are definitely requesting """ + safe_url = remove_api_key(self.url) + print("requesting!!", safe_url) + """ Exception checks will happen in function below""" + result = self.get_request_w_param(self.url, self.get_proxies()) + + # result = self.get_request_alternatives(self.url) + # result = self.get_request_alternatives(self.no_apikey_url) + if not self.check_result(result): + return False + """ request looks solid we are ready to save """ + if result and self.check_if_request_ok(result.status_code): + save_pickle_for_test(result) + return result diff --git a/evdspy/EVDSlocal/requests_/lower_energy.py b/evdspy/EVDSlocal/requests_/lower_energy.py index b6103dd..8a6747e 100644 --- a/evdspy/EVDSlocal/requests_/lower_energy.py +++ b/evdspy/EVDSlocal/requests_/lower_energy.py @@ -1,240 +1,245 @@ -import functools -import random -import time - -# -------------------------------------------------------------------------------------- -if __name__ != "__main__": - from evdspy.EVDSlocal.common.files import WriteBytes, ReadBytes, WriteBytesAdd - from evdspy.EVDSlocal.config.config import ConfigBase, config - from evdspy.EVDSlocal.manual_requests.prepare import basic_for_test, PrepareUrl -else: - def WriteBytes(file_name: str, content_bytes: bytes): - with open(file_name, 'wb+') as f: - f.write(content_bytes) - - - def WriteBytesAdd(file_name: str, content_bytes: bytes): - with open(file_name, 'ab') as f: - f.write(content_bytes) - - - def ReadBytes(file_name: str): - with open(file_name, "rb") as f: - return f.read() -# -------------------------------------------------------------------------------------- -import base64 -import hashlib -import os -from pathlib import Path -from dataclasses import dataclass -from typing import List, Tuple -from typing import Union, Callable - -from evdspy.EVDSlocal.initial.start_options import default_arch_folder_name , default_arch_file_name -if config.current_mode_is_test: - default_arch_folder_name = f"EVDSlocal/{default_arch_folder_name}" - -item_sep = "\n" -item_sep_bytes = bytes(item_sep, encoding="utf8") - - -def get_pepper(): - """ trying to get extra sec by getting info that will be different for all users - but will not change often. - If it changes it will just result a new request until it changes - again though, so not a big burden. - """ - pepper = "The quick brown fox, why not" - import os - try: - u = os.environ.get("USERNAME") - except: - u = "any_user" - try: - p = Path() - except: - p = "path" - pepper = f"{pepper}-{u}-{p}" - return pepper - - -@dataclass -class ArchFile(): - path: Union[str, Path] = "" - file_name: Union[str, Path] = default_arch_file_name - - def __post_init__(self): - if isinstance(self.path, str): - self.path = Path.cwd() / default_arch_folder_name - self.file_name = self.path / default_arch_file_name - - -arch = ArchFile() - - -def create_folder_if_not_exist(): - if not arch.path.is_dir(): - os.makedirs(arch.path) - - -def setup_is_ok(): - return ArchFile().file_name.is_file() - - -def one_way(x, num=27): - x = x.encode("utf-8") - hasher = hashlib.sha1(x) - return base64.urlsafe_b64encode(hasher.digest()[:num]) - - -def with_pepper(x: str): - pepper = get_pepper() - return f"{pepper}{x}" - - -def name_format(api_key: str, status_code: Union[bool, int]) -> str: - status_code = convert_status_code(status_code) - return f"{api_key}-{get_pepper()}-{status_code}" - - -shuffle = True - - -def shuffle_content(old_content: bytes, bytes_api_key_pepper) -> bytes: - old_list: List[bytes] = old_content.split(item_sep_bytes) - new_list: List[bytes] = old_list + [bytes_api_key_pepper] - content: bytes = functools.reduce(lambda x, p: x + p + item_sep_bytes, new_list) - return content - - -def add_checked_hashes(api_key: str, status_code: Union[bool, int]): - status_code: int = convert_status_code(status_code) - create_folder_if_not_exist() - bytes_api_key_pepper = one_way(name_format(api_key, status_code)) - assert isinstance(status_code, bool) is False, "something w" - if shuffle: - if not setup_is_ok(): - old_content: bytes = bytes("start", encoding="utf-8") - new_content = bytes_api_key_pepper + item_sep_bytes - else: - old_content: bytes = ReadBytes(str(arch.file_name)) - new_content: bytes = shuffle_content(old_content, bytes_api_key_pepper + item_sep_bytes) - WriteBytes(str(arch.file_name), new_content) - else: - WriteBytesAdd(str(arch.file_name), bytes_api_key_pepper + item_sep_bytes) - - -def get_list_of_cache(): - content_byte: bytes = ReadBytes(arch.file_name) - item_list: List[bytes] = content_byte.split(item_sep_bytes) - item_list_str: Tuple[str] = tuple(map(str, item_list)) - return item_list_str - - -def convert_status_code(status_code_new: Union[bool, int]) -> int: - if isinstance(status_code_new, int) and not isinstance(status_code_new, bool): - return status_code_new - obj = {True: 200, False: 500} - status_code_new = obj[status_code_new] - return status_code_new - - -def check_api_key_hashes_opt(api_key, status_code: Union[bool, int]): - status_code: int = convert_status_code(status_code) - new_hash = one_way(name_format(api_key, status_code)) - return str(new_hash) in get_list_of_cache() - - -def populate_first_rand(): - if not setup_is_ok(): - create_folder_if_not_exist() - for item in range(100): - status_code = 500 # random.choice((200, 500)) - x_tuple = (f"test-{item}", status_code) - # add_checked_hashes(f"test-{item}", status_code) - add_checked_hashes(*x_tuple) - - -@dataclass -class Checked: - never_checked: bool - checked_before_and_passed: bool - checked_before_and_failed: bool - - -def check_if_api_key_was_checked_before(api_key: str) -> Checked: - """ - Every time user gives an api key to save - we need to check if it is working. - In earlier versions we were checking with - a new request each time without caching. - This version this will be a better solution which attempts to optimize - min request and min collision of one way hashing. - - Functions of this file are only for minimizing new request on setting api key. - @params - api_key : str - """ - checked_before_and_passed = check_api_key_hashes_opt(api_key, 200) - checked_before_and_failed = check_api_key_hashes_opt(api_key, 500) - never_checked = not any((checked_before_and_passed, checked_before_and_failed)) - return Checked(never_checked, checked_before_and_passed, checked_before_and_failed) - - -testing = False -test_apikeys_success = ("s1", "s2", "s3", "s4", 'testApiKeyMock') -test_apikeys_fails = ("f1", "f2") -common_test_words = ("test", "t", "api", "key", "apikey", "key", "tested") - -from ..common.colors import * - -def apikey_works(api_key, check_func_request: Callable = basic_for_test, testing_=False): - result = apikey_works_helper(**locals()) - msg_success = "Your api key was tested with success." - msg_fails = "Your api key was tested with success." - if result: - print_with_success_style(msg_success) - else: - print_with_failure_style(msg_fails) - return result - - -def apikey_works_helper(api_key, check_func_request: Callable = basic_for_test, testing_=False): - if not setup_is_ok(): - populate_first_rand() - ans: Checked = check_if_api_key_was_checked_before(api_key) - checked_before = not ans.never_checked - if checked_before: - if ans.checked_before_and_passed: - return True - if ans.checked_before_and_failed: - return False - raise "something wrong lower energy" - # check request - """ make request """ - if testing or \ - testing_ or \ - config.current_mode_is_test or \ - api_key in test_apikeys_success or \ - api_key in test_apikeys_fails or \ - api_key in common_test_words: - """ for testing """ - status_code_new: bool = api_key in test_apikeys_success # random.choice((200, 500,)) - print_with_creating_style("first part ", api_key, str(status_code_new)) - - else: - if api_key in common_test_words: - print_with_failure_style(f"api key does not look like a key. Returning...{api_key}") - return apikey_works_helper(api_key, testing_=True) - - print_with_updating_style("WARNING making a new request to test your Api key ") - time.sleep(2) - status_code_new: bool = check_func_request(api_key) - """ add one way comp. hash to archive """ - add_checked_hashes(api_key, status_code_new) - return status_code_new - - -__all__ = [ - 'apikey_works' -] +import functools +import random +import time + +# -------------------------------------------------------------------------------------- +if __name__ != "__main__": + from evdspy.EVDSlocal.common.files import WriteBytes, ReadBytes, WriteBytesAdd + from evdspy.EVDSlocal.config.config import ConfigBase, config + from evdspy.EVDSlocal.manual_requests.prepare import basic_for_test, PrepareUrl +else: + def WriteBytes(file_name: str, content_bytes: bytes): + with open(file_name, 'wb+') as f: + f.write(content_bytes) + + + def WriteBytesAdd(file_name: str, content_bytes: bytes): + with open(file_name, 'ab') as f: + f.write(content_bytes) + + + def ReadBytes(file_name: str): + with open(file_name, "rb") as f: + return f.read() +# -------------------------------------------------------------------------------------- +import base64 +import hashlib +import os +from pathlib import Path +from dataclasses import dataclass +from typing import List, Tuple +from typing import Union, Callable + +from evdspy.EVDSlocal.initial.start_options import default_arch_folder_name, default_arch_file_name + +if config.current_mode_is_test: + default_arch_folder_name = f"--Test--/{default_arch_folder_name}" + +item_sep = "\n" +item_sep_bytes = bytes(item_sep, encoding="utf8") + + +def get_pepper(): + """ trying to get extra sec by getting info that will be different for all users + but will not change often. + If it changes it will just result a new request until it changes + again though, so not a big burden. + """ + pepper = "The quick brown fox, why not" + import os + try: + u = os.environ.get("USERNAME") + except: + u = "any_user" + try: + p = Path() + except: + p = "path" + pepper = f"{pepper}-{u}-{p}" + return pepper + + +@dataclass +class ArchFile(): + path: Union[str, Path] = "" + file_name: Union[str, Path] = default_arch_file_name + + def __post_init__(self): + if isinstance(self.path, str): + self.path = Path.cwd() / default_arch_folder_name + self.file_name = self.path / default_arch_file_name + + +arch = ArchFile() + + +def create_folder_if_not_exist(): + if not arch.path.is_dir(): + os.makedirs(arch.path) + + +def setup_is_ok(): + return ArchFile().file_name.is_file() + + +def one_way(x, num=27): + x = x.encode("utf-8") + hasher = hashlib.sha1(x) + return base64.urlsafe_b64encode(hasher.digest()[:num]) + + +def with_pepper(x: str): + pepper = get_pepper() + return f"{pepper}{x}" + + +def name_format(api_key: str, status_code: Union[bool, int]) -> str: + status_code = convert_status_code(status_code) + return f"{api_key}-{get_pepper()}-{status_code}" + + +shuffle = True + + +def shuffle_content(old_content: bytes, bytes_api_key_pepper) -> bytes: + old_list: List[bytes] = old_content.split(item_sep_bytes) + new_list: List[bytes] = old_list + [bytes_api_key_pepper] + content: bytes = functools.reduce(lambda x, p: x + p + item_sep_bytes, new_list) + return content + + +def add_checked_hashes(api_key: str, status_code: Union[bool, int]): + status_code: int = convert_status_code(status_code) + create_folder_if_not_exist() + bytes_api_key_pepper = one_way(name_format(api_key, status_code)) + assert isinstance(status_code, bool) is False, "something w" + if shuffle: + if not setup_is_ok(): + old_content: bytes = bytes("start", encoding="utf-8") + new_content = bytes_api_key_pepper + item_sep_bytes + else: + old_content: bytes = ReadBytes(str(arch.file_name)) + new_content: bytes = shuffle_content(old_content, bytes_api_key_pepper + item_sep_bytes) + WriteBytes(str(arch.file_name), new_content) + else: + WriteBytesAdd(str(arch.file_name), bytes_api_key_pepper + item_sep_bytes) + + +def get_list_of_cache(): + content_byte: bytes = ReadBytes(arch.file_name) + item_list: List[bytes] = content_byte.split(item_sep_bytes) + item_list_str: Tuple[str] = tuple(map(str, item_list)) + return item_list_str + + +def convert_status_code(status_code_new: Union[bool, int]) -> int: + if isinstance(status_code_new, int) and not isinstance(status_code_new, bool): + return status_code_new + obj = {True: 200, False: 500} + status_code_new = obj[status_code_new] + return status_code_new + + +def check_api_key_hashes_opt(api_key, status_code: Union[bool, int]): + status_code: int = convert_status_code(status_code) + new_hash = one_way(name_format(api_key, status_code)) + return str(new_hash) in get_list_of_cache() + + +def populate_first_rand(): + if not setup_is_ok(): + create_folder_if_not_exist() + for item in range(100): + status_code = 500 # random.choice((200, 500)) + x_tuple = (f"test-{item}", status_code) + # add_checked_hashes(f"test-{item}", status_code) + add_checked_hashes(*x_tuple) + + +@dataclass +class Checked: + never_checked: bool + checked_before_and_passed: bool + checked_before_and_failed: bool + + +def check_if_api_key_was_checked_before(api_key: str) -> Checked: + """ + Every time user gives an api key to save + we need to check if it is working. + In earlier versions we were checking with + a new request each time without caching. + This version this will be a better solution which attempts to optimize + min request and min collision of one way hashing. + + Functions of this file are only for minimizing new request on setting api key. + @params + api_key : str + """ + checked_before_and_passed = check_api_key_hashes_opt(api_key, 200) + checked_before_and_failed = check_api_key_hashes_opt(api_key, 500) + never_checked = not any((checked_before_and_passed, checked_before_and_failed)) + return Checked(never_checked, checked_before_and_passed, checked_before_and_failed) + + +testing = False +test_apikeys_success = ("s1", "s2", "s3", "s4", 'testApiKeyMock') +test_apikeys_fails = ("f1", "f2") +common_test_words = ("test", "t", "api", "key", "apikey", "key", "tested") + +from ..common.colors import * + + +def apikey_works(api_key, check_func_request: Callable = basic_for_test, testing_=False): + result = apikey_works_helper(**locals()) + msg_success = "Your api key was tested with success." + msg_fails = "Your api key was tested with success." + if result: + print_with_success_style(msg_success) + else: + print_with_failure_style(msg_fails) + return result + + +def apikey_works_helper(api_key, check_func_request: Callable = basic_for_test, testing_=False): + if not setup_is_ok(): + populate_first_rand() + ans: Checked = check_if_api_key_was_checked_before(api_key) + checked_before = not ans.never_checked + if checked_before: + if ans.checked_before_and_passed: + return True + if ans.checked_before_and_failed: + return False + raise "something wrong lower energy" + # check request + """ make request """ + if testing or \ + testing_ or \ + config.current_mode_is_test or \ + api_key in test_apikeys_success or \ + api_key in test_apikeys_fails or \ + api_key in common_test_words: + """ for testing """ + status_code_new: bool = api_key in test_apikeys_success # random.choice((200, 500,)) + print_with_creating_style("first part ", api_key, status_code_new) + + else: + if api_key in common_test_words: + print_with_failure_style(f"api key does not look like a key. Returning...{api_key}") + return apikey_works_helper(api_key, testing_=True) + # raise "cannot make a new request" + # temp test forced + # print("temp test forced") + # return apikey_works_helper(api_key, testing_=True) + print_with_updating_style("WARNING making a new request to test your Api key ") + time.sleep(2) + status_code_new: bool = check_func_request(api_key) + """ add one way comp. hash to archive """ + add_checked_hashes(api_key, status_code_new) + return status_code_new + + +__all__ = [ + 'apikey_works' +] diff --git a/evdspy/EVDSlocal/requests_/mock_req.py b/evdspy/EVDSlocal/requests_/mock_req.py new file mode 100644 index 0000000..e8bc904 --- /dev/null +++ b/evdspy/EVDSlocal/requests_/mock_req.py @@ -0,0 +1,35 @@ +# ------------------------------------------------------------------------------ +import requests as requests + +from evdspy.EVDSlocal.components.url_class import URLClass +from evdspy.EVDSlocal.utils.utils_general import * +from evdspy.EVDSlocal.requests_.my_cache import MyCache, save_pickle_for_test, lru_cache_patched, load_test_pickle +from evdspy.EVDSlocal.components.options_class import Options +from evdspy.EVDSlocal.config.credentials_file import Credentials +from evdspy.EVDSlocal.initial.start_options import current_mode_is_test +from evdspy.EVDSlocal.initial.start_args import Args +from evdspy.EVDSlocal.messages.error_classes import * +from evdspy.EVDSlocal.config.apikey_class import * +from evdspy.EVDSlocal.config.config import config +from evdspy.EVDSlocal.requests_.my_cache import load_pickle +from evdspy.EVDSlocal.stats.save_stats_of_requests import * +from evdspy.EVDSlocal.requests_.request_error_classes import REQUEST_ERROR_CODES +from evdspy.EVDSlocal.common.url_clean import remove_api_key + +from dataclasses import dataclass + +# ------------------------------------------------------------------------------ + +m_cache = MyCache() + +from evdspy.EVDSlocal.config.config import config + +CANCEL_REQUEST_TEMP = config.cancel_request_temp + + +def mock_request(url, proxies=None) -> requests.models.Response: + """ pytest will get this mock response object""" + assert isinstance(url, str) + file_name = str(Path(__file__).parent / "test_reg_result") + assert Path(file_name + ".pickle").is_file(), f"file does not exist {file_name}" + return load_pickle(file_name) \ No newline at end of file diff --git a/evdspy/EVDSlocal/requests_/my_cache.py b/evdspy/EVDSlocal/requests_/my_cache.py index 2d7260d..e68f78a 100644 --- a/evdspy/EVDSlocal/requests_/my_cache.py +++ b/evdspy/EVDSlocal/requests_/my_cache.py @@ -1,267 +1,250 @@ -# from functools import lru_cache -import shutil - -from ..common.common_imports import * -from evdspy.EVDSlocal.utils.utils_general import * -from ..components.api_params import get_enum_with_value -from ..components.options_class import load_options, SingletonOptions -from ..common.url_clean import remove_api_key -from evdspy.EVDSlocal.series_format.stats.save_stats_of_requests import Report -from evdspy.EVDSlocal.config.apikey_class import ApikeyClass -from typing import Union - -# ----------------------------------------------------------------------------- -test_result_file_name = str(get_current_dir() / ".." / "requests_" / "test_reg_result") -arg_sep = "_argSEP_" -p = Path() -pickle_folder = p.absolute() / 'pickles' - - -# ----------------------------------------------------------------------------- - - -class CacheDecider(Enum): - day = date.today() - hour = datetime.now().strftime("%H") - nocache = datetime.now().strftime("%H:%M:%S") - default = date.today() - - -options_ = load_options() - - -def get_default_cache(): - obj = { - "daily": CacheDecider.day, - "hourly": CacheDecider.hour, - 'nocache': CacheDecider.nocache, - 'default': CacheDecider.day - - } - return obj.get(options_.default_cache, CacheDecider.day) - - -def cache_represent(choice: CacheDecider): - obj = { - CacheDecider.day: "daily", - CacheDecider.hour: "hourly", - CacheDecider.nocache: 'nocache', - CacheDecider.default: 'daily' - } - return obj[choice] - - -@dataclass -class MyCache: - decider: Union[CacheDecider, None] = None # post init - - # get_default_cache() # get_default_cache() # CacheDecider.hour - report_ = Report("stats_requests.txt") - - def __post_init__(self): - default_cache = SingletonOptions().get_valid_value("default_cache") - self.decider = get_enum_with_value(key=default_cache, enum_=CacheDecider, default_value=CacheDecider.day) - - def update_rules_of_cache(self): - if ApikeyClass().now_testing_is_key_is_valid: - msg = "since this looks like a test, Program will be changing cache rulse to nocahce at all..." - print(msg) - deb(msg) - - def report(self, content=None): - if content is None: - content = f""" - - Cache Info : Current request cache method caches {cache_represent(self.decider)} - -""" - self.report_.add(content) - - def prepare_report_for_cache(self, func, args): - self.report("Cache loaded...") - str_args = (x for x in args if isinstance(x, str)) - str_args = tuple(map(remove_api_key, str_args)) - content = f"" ", \n".join(str_args) - self.report(content) - - def cache(self, func): - self.update_rules_of_cache() - - @functools.wraps(func) - def wrapper_decorator(*args, **kwargs): - if self.check_cache(func, *args): - value = self.load_cache(func, *args) - self.prepare_report_for_cache(func, args) - - else: - value = func(*args, **kwargs) - self.save_cache(func, *args, data=value) - return value - - return wrapper_decorator - - def sort_safe(self, items): - items = list(items) - items = sorted(items) - return items - - def safe_serialize(self, *items): - safe_list = [] - for item in items: - if isinstance(item, str): - safe_list.append(item) - - safe_list = self.sort_safe(safe_list) + [str(self.decider)] - parameters = arg_sep.join(safe_list) - return parameters - - def get_hash_alt1(self, st): - import hashlib, base64 - d = hashlib.md5(bytes(st, encoding="utf-8")).digest() - d = base64.urlsafe_b64encode(d).decode('ascii') - return d - - def get_func_hash(self, f, *args): - parameters = self.safe_serialize(*args) - f_hash = f"{f.__name__}__{parameters}" - f_hash = self.get_hash_alt1(f_hash) - return f_hash - - def check_cache(self, f, *args): - """added below to provide an exception when we check for valid key """ - self.update_rules_of_cache() - - f_hash = self.get_func_hash(f, *args) - f_hash_path = rf"{pickle_folder}\\{f_hash}" - return check_pickle(f_hash_path) - - def load_cache(self, f, *args): - f_hash = self.get_func_hash(f, *args) - f_hash_path = rf"{pickle_folder}\\{f_hash}" - return load_pickle(f_hash_path) - - def save_cache(self, f, *args, data=None): - f_hash = self.get_func_hash(f, *args) - f_hash_path = f"{pickle_folder}\\{f_hash}" - save_pickle(f_hash_path, data) - - -def check_pickle(file_name: str) -> bool: - return os.path.isfile(file_name + ".pickle") - - -def load_pickle(file_name: str) -> Union[bool, requests.models.Response]: - file_name = file_name + ".pickle" - file_name_path = Path(file_name) - - if not file_name_path.is_file(): - # print(file_name_path) - return False - with open(file_name_path, "rb") as infile: - test_dict_reconstructed: requests.models.Response = pickle.load(infile) - - # exit() - - # f = bound(print, f"{file_name_path} pickle loaded...") - # functools.partial(print, f"{file_name} pickle loaded...") - # delay(1, f) - - msg = f""" - --------------------------------- - Recent cache was found for this request phrase. It will be loaded instead of making a new redundant request - You may change cache options in options file. - cache loaded...({file_name_path}) - --------------------------------- -""" - - print(msg) - - return test_dict_reconstructed - - -def delete_cache_folder(): - path = Path(pickle_folder) - if not path.is_dir(): - return True - try: - # Path.rmdir(path) - # os.remove(path) - shutil.rmtree(path) - return True - except Exception as exc: - print(exc) - return False - - -def save_pickle(file_name, data): - # print("saving", file_name) - msg = f""" - - --------------------------------- - - - Request was successfull... - --------------------------------- - Cache will be saved for this result. Next time program will be - checking if this cache is new enough to load for the new request - You may change cache options in options file - --------------------------------- - cache saved ...({file_name}) - - """ - - file_name_path = file_name + ".pickle" - try: - save_pickle_helper(file_name_path, data) - except: - - print("Cache folder may be deleted.\n setup() in order to create...") - # if callable("setup_now"): - # setup_now() - # save_pickle_helper(file_name_path, data) - - -def save_pickle_helper(file_name_path, data): - with open(file_name_path, "wb") as outfile: - pickle.dump(data, outfile) - # f = bound(print, f"{file_name_path} pickle saved...") - # delay(1, f) - - -def save_pickle_for_test(data): - save_pickle(test_result_file_name, data) - - -def load_test_pickle(): - return load_pickle(test_result_file_name) - - -def lru_cache_patched(maxsize=128, typed=False): - import weakref - def decorator(func): - @functools.wraps(func) - def wrapped_func(self, *args, **kwargs): - self_weak = weakref.ref(self) - - @functools.wraps(func) - @functools.lru_cache(maxsize=maxsize, typed=typed) - def cached_method(*args, **kwargs): - return func(self_weak(), *args, **kwargs) - - setattr(self, func.__name__, cached_method) - return cached_method(*args, **kwargs) - - return wrapped_func - - if callable(maxsize) and isinstance(typed, bool): - func, maxsize = maxsize, 128 - return decorator(func) - return decorator - - -__all__ = [ - 'lru_cache_patched', - 'MyCache', - 'save_pickle_for_test', - 'load_test_pickle' -] +# from functools import lru_cache +import shutil + +from ..common.common_imports import * +from evdspy.EVDSlocal.utils.utils_general import * +from ..components.api_params import get_enum_with_value +from ..components.options_class import load_options, SingletonOptions +from ..common.url_clean import remove_api_key +from evdspy.EVDSlocal.series_format.stats.save_stats_of_requests import Report +from evdspy.EVDSlocal.config.apikey_class import ApikeyClass +from typing import Union + +# ----------------------------------------------------------------------------- +test_result_file_name = str(get_current_dir() / ".." / "requests_" / "test_reg_result") +arg_sep = "_argSEP_" +p = Path() +pickle_folder = p.absolute() / 'pickles' + + +# ----------------------------------------------------------------------------- + + +class CacheDecider(Enum): + day = date.today() + hour = datetime.now().strftime("%H") + nocache = datetime.now().strftime("%H:%M:%S") + default = date.today() + + +options_ = load_options() + + +def get_default_cache(): + obj = { + "daily": CacheDecider.day, + "hourly": CacheDecider.hour, + 'nocache': CacheDecider.nocache, + 'default': CacheDecider.day + + } + return obj.get(options_.default_cache, CacheDecider.day) + + +def cache_represent(choice: CacheDecider): + obj = { + CacheDecider.day: "daily", + CacheDecider.hour: "hourly", + CacheDecider.nocache: 'nocache', + CacheDecider.default: 'daily' + } + return obj[choice] + + +@dataclass +class MyCache: + decider: Union[CacheDecider, None] = None # post init + + # get_default_cache() # get_default_cache() # CacheDecider.hour + report_ = Report("stats_requests.txt") + msg = "will be running now..." + + def __post_init__(self): + default_cache = SingletonOptions().get_valid_value("default_cache") + self.decider = get_enum_with_value(key=default_cache, enum_=CacheDecider, default_value=CacheDecider.day) + + def update_rules_of_cache(self): + if ApikeyClass().now_testing_is_key_is_valid: + msg = "since this looks like a test, Program will be changing cache rulse to nocahce at all..." + print(msg) + deb(msg) + + def report(self, content=None): + if content is None: + content = f""" + + Cache Info : Current request cache method caches {cache_represent(self.decider)} + +""" + self.report_.add(content) + + def prepare_report_for_cache(self, func, args): + self.report("Cache loaded...") + str_args = (x for x in args if isinstance(x, str)) + str_args = tuple(map(remove_api_key, str_args)) + content = f"" ", \n".join(str_args) + self.report(content) + + def cache(self, func): + self.update_rules_of_cache() + + @functools.wraps(func) + def wrapper_decorator(*args, **kwargs): + if self.check_cache(func, *args): + value = self.load_cache(func, *args) + + self.prepare_report_for_cache(func, args) + + else: + value = func(*args, **kwargs) + print("Requesting...", self.msg) + self.save_cache(func, *args, data=value) + return value + + return wrapper_decorator + + def sort_safe(self, items): + items = list(items) + items = sorted(items) + return items + + def safe_serialize(self, *items): + safe_list = [] + for item in items: + if isinstance(item, str): + safe_list.append(item) + + safe_list = self.sort_safe(safe_list) + [str(self.decider)] + parameters = arg_sep.join(safe_list) + return parameters + + def get_hash_alt1(self, st): + import hashlib, base64 + d = hashlib.md5(bytes(st, encoding="utf-8")).digest() + d = base64.urlsafe_b64encode(d).decode('ascii') + return d + + def get_func_hash(self, f, *args): + parameters = self.safe_serialize(*args) + f_hash = f"{f.__name__}__{parameters}" + f_hash = self.get_hash_alt1(f_hash) + return f_hash + + def check_cache(self, f, *args): + """added below to provide an exception when we check for valid key """ + self.update_rules_of_cache() + f_hash = self.get_func_hash(f, *args) + f_hash_path = Path() / pickle_folder / f_hash + return check_pickle(f_hash_path) + + def load_cache(self, f, *args): + f_hash = self.get_func_hash(f, *args) + + f_hash_path = Path(pickle_folder) / f_hash + return load_pickle(f_hash_path) + + def save_cache(self, f, *args, data=None): + f_hash = self.get_func_hash(f, *args) + f_hash_path = Path(pickle_folder) / f_hash + + try: + save_pickle(f_hash_path, data) + except: + + print("Cache folder may be deleted.\n setup() in order to create...") + + +def name_format_pickle(file_name: str): + return Path(f"{file_name}.pickle") + + +def check_pickle(file_name: str) -> bool: + file_name_full = name_format_pickle(file_name) + return os.path.isfile(file_name_full) + + +def load_pickle(file_name: str, verbose=False) -> Union[bool, requests.models.Response]: + file_name_full = name_format_pickle(file_name) + + if not file_name_full.is_file(): + return False + with open(file_name_full, "rb") as infile: + test_dict_reconstructed: requests.models.Response = pickle.load(infile) + + msg = f""" + --------------------------------- + Recent cache was found for this request phrase. It will be loaded instead of making a new redundant request + You may change cache options in options file. + cache loaded...({file_name_full}) + --------------------------------- +""" + if verbose: + print(msg) + else: + print("") + return test_dict_reconstructed + + +import shutil + + +def delete_cache_folder(): + path = Path(pickle_folder) + if not path.is_dir(): + return True + try: + + shutil.rmtree(path) + return True + except Exception as exc: + print(exc) + return False + + +def save_pickle(file_name, data): + file_name_full = name_format_pickle(file_name) + save_pickle_helper(file_name_full, data) + + +def save_pickle_helper(file_name_path, data): + with open(file_name_path, "wb") as outfile: + pickle.dump(data, outfile) + + +def save_pickle_for_test(data): + return save_pickle(test_result_file_name, data) + + +def load_test_pickle(): + return load_pickle(test_result_file_name) + + +def lru_cache_patched(maxsize=128, typed=False): + import weakref + def decorator(func): + @functools.wraps(func) + def wrapped_func(self, *args, **kwargs): + self_weak = weakref.ref(self) + + @functools.wraps(func) + @functools.lru_cache(maxsize=maxsize, typed=typed) + def cached_method(*args, **kwargs): + return func(self_weak(), *args, **kwargs) + + setattr(self, func.__name__, cached_method) + return cached_method(*args, **kwargs) + + return wrapped_func + + if callable(maxsize) and isinstance(typed, bool): + func, maxsize = maxsize, 128 + return decorator(func) + return decorator + + +__all__ = [ + 'lru_cache_patched', + 'MyCache', + 'save_pickle_for_test', + 'load_test_pickle' +] diff --git a/evdspy/EVDSlocal/requests_/real_requests.py b/evdspy/EVDSlocal/requests_/real_requests.py new file mode 100644 index 0000000..70525d7 --- /dev/null +++ b/evdspy/EVDSlocal/requests_/real_requests.py @@ -0,0 +1,87 @@ +# ------------------------------------------------------------------------------ +import requests as requests + +from evdspy.EVDSlocal.components.url_class import URLClass +from evdspy.EVDSlocal.utils.utils_general import * +from evdspy.EVDSlocal.requests_.my_cache import MyCache, save_pickle_for_test, lru_cache_patched, load_test_pickle +from evdspy.EVDSlocal.components.options_class import Options +from evdspy.EVDSlocal.config.credentials_file import Credentials +from evdspy.EVDSlocal.initial.start_options import current_mode_is_test +from evdspy.EVDSlocal.initial.start_args import Args +from evdspy.EVDSlocal.messages.error_classes import * +from evdspy.EVDSlocal.config.apikey_class import * +from evdspy.EVDSlocal.config.config import config +from evdspy.EVDSlocal.requests_.my_cache import load_pickle +from evdspy.EVDSlocal.stats.save_stats_of_requests import * +from evdspy.EVDSlocal.requests_.request_error_classes import REQUEST_ERROR_CODES +from evdspy.EVDSlocal.common.url_clean import remove_api_key + +from dataclasses import dataclass + +# ------------------------------------------------------------------------------ + +m_cache = MyCache() + +from evdspy.EVDSlocal.config.config import config + +CANCEL_REQUEST_TEMP = config.cancel_request_temp + +from evdspy.EVDSlocal.requests_.mock_req import * + + +class RealRequest(object): + """ pytest will get this mock response object""" + + def __init__(self, url: str, proxies=None, api_key=False): + self.url = url + self.proxies = proxies + if not api_key: + self.api_key = ApikeyClass().key + else: + self.api_key = api_key + + def request_no_proxy(self) -> requests.Response: + return requests.get(self.url) + + def request_proxy(self) -> requests.Response: + return requests.get(self.url, proxies=self.proxies) + + def request(self) -> requests.Response: + if config.current_mode_is_test and not config.temp_cancel_mock_request: + """ pytest will get this mock response object""" + return mock_request(self.url, self.proxies) + + if self.proxies is None: + return self.request_no_proxy() + return self.request_proxy() + + +class RealRequestWithParam(RealRequest): + + def get_header(self) -> dict: + # api_key = ApikeyClass().key + headers = { + "key": self.api_key + } + + return headers + + def request_no_proxy(self) -> requests.Response: + headers = self.get_header() + # print(headers) + # print(self.url) + response = requests.get(self.url, headers=headers) + return response + + def request_proxy(self) -> requests.Response: + headers = self.get_header() + return requests.get(self.url, headers=headers, proxies=self.proxies) + + def request(self) -> requests.Response: + if config.current_mode_is_test and not config.temp_cancel_mock_request: + """ pytest will get this mock response object""" + return mock_request(self.url, self.proxies) + + if self.proxies is None: + return self.request_no_proxy() + return self.request_proxy() diff --git a/evdspy/EVDSlocal/requests_/request_error_classes.py b/evdspy/EVDSlocal/requests_/request_error_classes.py index 2f2df2b..9131e17 100644 --- a/evdspy/EVDSlocal/requests_/request_error_classes.py +++ b/evdspy/EVDSlocal/requests_/request_error_classes.py @@ -1,53 +1,53 @@ -from evdspy.EVDSlocal.messages.error_classes import ApiKeyNotSetError - - -class BaseException_Request(Exception): - """BaseException_Request""" - - -class Req_NotFound(BaseException_Request): - """Req_NotFound""" - - -class Req_Unauthorized(BaseException_Request): - """Req_NotFound""" - - -class Req_Forbidden(BaseException_Request): - """Req_NotFound""" - - -class Req_BadRequest(BaseException_Request): - """Req_NotFound""" - - -class Req_TooMany(BaseException_Request): - """Req_TooMany""" - - -class Internal(BaseException_Request): - """Internal""" - -class Bad_Gateway(BaseException_Request): - """Bad_Gateway""" - - -class ServiceUnavailable(BaseException_Request): - """ServiceUnavailable""" - - -class GatewayNotImplemented(BaseException_Request): - """GatewayNotImplemented""" - - -REQUEST_ERROR_CODES = { - 400: Req_BadRequest, - 401: Req_Unauthorized, - 403: Req_Forbidden, - 404: Req_NotFound, - 429: Req_TooMany, - 500: Internal, - 502: Bad_Gateway, - 503: ServiceUnavailable, - 504: GatewayNotImplemented -} +from evdspy.EVDSlocal.messages.error_classes import ApiKeyNotSetError + + +class BaseException_Request(Exception): + """BaseException_Request""" + + +class Req_NotFound(BaseException_Request): + """Req_NotFound""" + + +class Req_Unauthorized(BaseException_Request): + """Req_NotFound""" + + +class Req_Forbidden(BaseException_Request): + """Req_NotFound""" + + +class Req_BadRequest(BaseException_Request): + """Req_NotFound""" + + +class Req_TooMany(BaseException_Request): + """Req_TooMany""" + + +class Internal(BaseException_Request): + """Internal""" + +class Bad_Gateway(BaseException_Request): + """Bad_Gateway""" + + +class ServiceUnavailable(BaseException_Request): + """ServiceUnavailable""" + + +class GatewayNotImplemented(BaseException_Request): + """GatewayNotImplemented""" + + +REQUEST_ERROR_CODES = { + 400: Req_BadRequest, + 401: Req_Unauthorized, + 403: Req_Forbidden, + 404: Req_NotFound, + 429: Req_TooMany, + 500: Internal, + 502: Bad_Gateway, + 503: ServiceUnavailable, + 504: GatewayNotImplemented +} diff --git a/evdspy/EVDSlocal/requests_/test_reg_result.pickle b/evdspy/EVDSlocal/requests_/test_reg_result.pickle index 41a495b..78cacab 100644 Binary files a/evdspy/EVDSlocal/requests_/test_reg_result.pickle and b/evdspy/EVDSlocal/requests_/test_reg_result.pickle differ diff --git a/evdspy/EVDSlocal/series_format/populate_series.py b/evdspy/EVDSlocal/series_format/populate_series.py index 7f75987..4000f49 100644 --- a/evdspy/EVDSlocal/series_format/populate_series.py +++ b/evdspy/EVDSlocal/series_format/populate_series.py @@ -1,207 +1,213 @@ -from evdspy.EVDSlocal.components.evds_seri_files import EvdsSeri, EvdsSeriesRequest, EvdsSeriesRequestWrapperFromFile, \ - BucketFromSeriesFile -from evdspy.EVDSlocal.messages.error_classes import * -from evdspy.EVDSlocal.common.files import * -from evdspy.EVDSlocal.series_format.populate_series_helper import * - -# from evdspy.EVDSlocal.series_format.series_creator import get_approval - -NEW_LINE =chr(10) - -GSEP = "--++--" -BeginS = "#Begin_series" -series_begins_note = "---Series - --------------------------------" - -from evdspy.EVDSlocal.messages.error_messages import * - -from typing import Callable -from dataclasses import dataclass -from evdspy.EVDSlocal.config.config import config -from evdspy.EVDSlocal.series_format.series_examples import test_series_file_content_for_test -from evdspy.EVDSlocal.initial.start_options import * - -from evdspy.EVDSlocal.series_format.series_examples import example_series - - -def get_input(msg): - if config.current_mode_is_test: - return "test" - ans = input(msg) - return str(ans) - - -def get_approval(file_name): - msg = f"{file_name} already exists. If you would like to replace it with a new example please type `replace`: " - - ans = get_input(msg) - if str(ans).lower().strip() == "replace": - return True - return False - - -def create_series_text_file(file_name: str, content=""): - """General usage""" - if Path(file_name).is_file() and "-locked" not in file_name.lower(): - if not get_approval(file_name): - return False - print(f"creating...{file_name}") - result, msg = Write(file_name, content) - print(msg) - time.sleep(1) - return result - - -import random - - -def create_series_text_example(file_name=default_series_file_name): - """ main series config file """ - return create_series_text_file(file_name, random.choice(example_series)) - - -@dataclass -class PopulateSeries: - name: str = "config_series.cfg" - separator: str = GSEP - EvdsSeriesRequestWrapper_Type: Callable = EvdsSeriesRequestWrapperFromFile - injection: bool = False # for pytest - - def __post_init__(self): - self.input_file_name = Path() / f"{self.name}" - if not self.input_file_name.is_file(): - create_series_text_example() - self.checks() - - def checks(self): - - items_will_be_checked = ( - BeginS in self.series_file_full_content and self.separator in self.series_file_full_content, - self.series_file_full_content.count( - series_begins_note) < self.series_file_full_content.count( - self.separator) - ,) - - if not all(items_will_be_checked): - ... - msg = f"{self.input_file_name} may be corrupted. You may create a new one from the menu. (create series config file)" - print(msg ) - raise SeriesFileDoesNotExists(msg) - - deb(f"reading : {self.input_file_name}", f"content: {self.series_file_content}") - deb(f"content: {self.series_file_content}") - - def extract_group(self, group: str): - return [x for x in group.split(NEW_LINE) if x != ''] - - @property - def series_file_full_content(self): - if config.current_mode_is_test: - return test_series_file_content_for_test - - content = Read(self.input_file_name) - return content - - @property - def series_file_content(self): - if self.injection: - return self.injected_content - self.full_content = content = self.series_file_full_content - if BeginS in self.full_content: - content = self.full_content.split(BeginS)[1] - return content - - def check_file(self): - x = self.input_file_name.is_file() - if not x: - print(SeriesFileDoesNotExists(series_file_not_found_error_msg)) - return x - return x - - def split_series_file(self, content=None): - """ main function to split content from series file""" - if content is None: - """ For pytest or other test processes """ - content = self.series_file_content - else: - self.injection = True - self.injected_content = content - groups = content.split(self.separator) - - conts = [self.extract_group(group) for group in groups] - conts = [cont for cont in conts if len(cont) > 1] - return [self.create_class(cont) for cont in conts] - - def create_class(self, cont): - def check(x): - return all(("#" not in x, "--" not in x, ":" not in x, len(x) > 2)) - - folder_name = self.extract_prop(cont, "foldername") - abs_path = self.extract_prop(cont, "abs_path") - subject = self.extract_prop(cont, "subject") - prefix = self.extract_prop(cont, "prefix") - frequency = self.extract_prop(cont, "frequency") - formulas = self.extract_prop(cont, "formulas") - aggregateType = self.extract_prop(cont, "aggregateType") - - bfs = BucketFromSeriesFile(folder_name=folder_name, - subject=subject, - prefix=prefix, - frequency=frequency, - formulas=formulas, - aggregateType=aggregateType, - abs_path=abs_path) - - series_codes = [x for x in cont if check(x)] - objs = [EvdsSeri(x, bfs=bfs) for x in series_codes] - - - return self.export_series(objs, bfs) - - def export_series(self, objs, bfs: BucketFromSeriesFile): - req = EvdsSeriesRequest(series_list=objs, bfs=bfs) - - assert self.EvdsSeriesRequestWrapper_Type is EvdsSeriesRequestWrapperFromFile, "populate 82" - return self.EvdsSeriesRequestWrapper_Type(bfs=bfs, EvdsSeriesRequest_=req) - - def clean_series_line(self, line): - line = line.strip() - line = line.split("#") - return line[0] - - def extract_prop(self, lines, prop): - def get_prop(prop, item): - value = "" - r = item.split(":") - if len(r) > 2: - # "folder:http:xx" - value = ":".join(r[1:]) - elif len(r) > 1: - # "filename:xx" - value = r[1] - return value.strip() - - lines = [self.clean_series_line(x) for x in lines if ":" in x] - lines = [get_prop(prop, x) for x in lines if prop in x] - lines = [x for x in lines if x is not None] - if len(lines) == 0: - lines = ["prop_not_found"] - return lines[0] - - def process(self): - reqs = self.split_series_file() - return reqs - - -__all__ = [ - 'PopulateSeries', - -] - - - - -def check_pop_read(): - ps = PopulateSeries() - req = ps.split_series_file(content=pop_series_test_content) - deb2(req) - return req +from evdspy.EVDSlocal.components.evds_seri_files import EvdsSeri, EvdsSeriesRequest, EvdsSeriesRequestWrapperFromFile, \ + BucketFromSeriesFile +from evdspy.EVDSlocal.messages.error_classes import * +from evdspy.EVDSlocal.common.files import * +from evdspy.EVDSlocal.series_format.populate_series_helper import * + +# from evdspy.EVDSlocal.series_format.series_creator import get_approval + +NEW_LINE = "\n" +GSEP = "--++--" +BeginS = "#Begin_series" +series_begins_note = "---Series - --------------------------------" + +from evdspy.EVDSlocal.messages.error_messages import * + +from typing import Callable + +from evdspy.EVDSlocal.config.config import config +from evdspy.EVDSlocal.series_format.series_examples import test_series_file_content_for_test +from evdspy.EVDSlocal.initial.start_options import * + +from evdspy.EVDSlocal.series_format.series_examples import example_series + + +def get_input(msg): + if config.current_mode_is_test: + return "test" + ans = input(msg) + return str(ans) + + +def get_approval(file_name): + msg = f"{file_name} already exists. If you would like to replace it with a new example please type `replace`: " + + ans = get_input(msg) + if str(ans).lower().strip() == "replace": + return True + return False + + +def create_series_text_file(file_name: str, content=""): + """General usage""" + if Path(file_name).is_file() and "-locked" not in file_name.lower(): + if not get_approval(file_name): + return False + print(f"creating...{file_name}") + result, msg = Write(file_name, content) + print(msg) + time.sleep(1) + return result + + +import random + + +def create_series_text_example(file_name=default_series_file_name): + """ main series config file """ + return create_series_text_file(file_name, random.choice(example_series)) + + +@dataclass +class PopulateSeries: + name: str = "config_series.cfg" + separator: str = GSEP + EvdsSeriesRequestWrapper_Type: Callable = EvdsSeriesRequestWrapperFromFile + injection: bool = False # for pytest + + def __post_init__(self): + self.input_file_name = Path() / f"{self.name}" + if not self.input_file_name.is_file(): + create_series_text_example() + self.checks() + + def checks(self): + + items_will_be_checked = ( + BeginS in self.series_file_full_content and self.separator in self.series_file_full_content, + self.series_file_full_content.count( + series_begins_note) < self.series_file_full_content.count( + self.separator) + ,) + + if not all(items_will_be_checked): + ... + msg = f"{self.input_file_name} may be corrupted. You may create a new one from the menu. (create series config file)" + print(msg ) + raise SeriesFileDoesNotExists(msg) + + deb(f"reading : {self.input_file_name}", f"content: {self.series_file_content}") + deb(f"content: {self.series_file_content}") + + def extract_group(self, group: str): + return [x for x in group.split(NEW_LINE) if x != ''] + + @property + def series_file_full_content(self): + if config.current_mode_is_test: + return test_series_file_content_for_test + + content = Read(self.input_file_name) + return content + + @property + def series_file_content(self): + if self.injection: + return self.injected_content + self.full_content = content = self.series_file_full_content + if BeginS in self.full_content: + content = self.full_content.split(BeginS)[1] + return content + + def check_file(self): + x = self.input_file_name.is_file() + if not x: + print(SeriesFileDoesNotExists(series_file_not_found_error_msg)) + return x + return x + + def split_series_file(self, content=None): + """ main function to split content from series file""" + if content is None: + """ For pytest or other test processes """ + content = self.series_file_content + else: + self.injection = True + self.injected_content = content + groups = content.split(self.separator) + + conts = [self.extract_group(group) for group in groups] + conts = [cont for cont in conts if len(cont) > 1] + return [self.create_class(cont) for cont in conts] + + def create_class(self, cont): + def check(x): + return all(("#" not in x, "--" not in x, ":" not in x, len(x) > 2)) + + folder_name = self.extract_prop(cont, "foldername") + abs_path = self.extract_prop(cont, "abs_path") + subject = self.extract_prop(cont, "subject") + prefix = self.extract_prop(cont, "prefix") + frequency = self.extract_prop(cont, "frequency") + formulas = self.extract_prop(cont, "formulas") + aggregateType = self.extract_prop(cont, "aggregateType") + + bfs = BucketFromSeriesFile(folder_name=folder_name, + subject=subject, + prefix=prefix, + frequency=frequency, + formulas=formulas, + aggregateType=aggregateType, + abs_path=abs_path) + + series_codes = [x for x in cont if check(x)] + objs = [EvdsSeri(x, bfs=bfs) for x in series_codes] + + # def update(item: EvdsSeri): + # item.bfs = bfs + # + # return item + # + # objs: List[EvdsSeri] = [update(x) for x in objs] + + return self.export_series(objs, bfs) + + def export_series(self, objs, bfs: BucketFromSeriesFile): + req = EvdsSeriesRequest(series_list=objs, bfs=bfs) + + assert self.EvdsSeriesRequestWrapper_Type is EvdsSeriesRequestWrapperFromFile, "populate 82" + return self.EvdsSeriesRequestWrapper_Type(bfs=bfs, EvdsSeriesRequest_=req) + + def clean_series_line(self, line): + line = line.strip() + line = line.split("#") + return line[0] + + def extract_prop(self, lines, prop): + def get_prop(prop, item): + value = "" + r = item.split(":") + if len(r) > 2: + # "folder:http:xx" + value = ":".join(r[1:]) + elif len(r) > 1: + # "filename:xx" + value = r[1] + return value.strip() + + lines = [self.clean_series_line(x) for x in lines if ":" in x] + lines = [get_prop(prop, x) for x in lines if prop in x] + lines = [x for x in lines if x is not None] + if len(lines) == 0: + lines = ["prop_not_found"] + return lines[0] + + def process(self): + reqs = self.split_series_file() + return reqs + + +__all__ = [ + 'PopulateSeries', + +] + + +# req = PopulateSeries().split_series_file() +# print(req ) + +def check_pop_read(): + ps = PopulateSeries() + req = ps.split_series_file(content=pop_series_test_content) + deb2(req) + return req diff --git a/evdspy/EVDSlocal/series_format/populate_series_helper.py b/evdspy/EVDSlocal/series_format/populate_series_helper.py index 4217549..ae02662 100644 --- a/evdspy/EVDSlocal/series_format/populate_series_helper.py +++ b/evdspy/EVDSlocal/series_format/populate_series_helper.py @@ -1,29 +1,29 @@ -pop_series_test_content = rf""" - -#Series_config_file - E V D S P Y _ C O N F I G _ F I L E --------------------------------------------- -# -# This file will be used by evdspy package (python) in order to help updating -# your series. -# Script will be adding this file when you setup a new project. -# Deleting or modifying its content may require to setup configuration from the beginning -# ---------------------------------------------------------------------------------------- -#Begin_series ----Series--------------------------------- -filename : t1\series.txt -subject : visitors -prefix : EV_ -------------SERIES CODES------------------ -TP.ODEMGZS.BDTTOPLAM -TP.ODEMGZS.ABD -TP.ODEMGZS.ARJANTIN -TP.ODEMGZS.BREZILYA -TP.ODEMGZS.KANADA -TP.ODEMGZS.KOLOMBIYA -TP.ODEMGZS.MEKSIKA -TP.ODEMGZS.SILI -------------/SERIES CODES------------------ ----/Series--------------------------------- ---++-- - -""" +pop_series_test_content = rf""" + +#Series_config_file + E V D S P Y _ C O N F I G _ F I L E --------------------------------------------- +# +# This file will be used by evdspy package (python) in order to help updating +# your series. +# Script will be adding this file when you setup a new project. +# Deleting or modifying its content may require to setup configuration from the beginning +# ---------------------------------------------------------------------------------------- +#Begin_series +---Series--------------------------------- +filename : t1\series.txt +subject : visitors +prefix : EV_ +------------SERIES CODES------------------ +TP.ODEMGZS.BDTTOPLAM +TP.ODEMGZS.ABD +TP.ODEMGZS.ARJANTIN +TP.ODEMGZS.BREZILYA +TP.ODEMGZS.KANADA +TP.ODEMGZS.KOLOMBIYA +TP.ODEMGZS.MEKSIKA +TP.ODEMGZS.SILI +------------/SERIES CODES------------------ +---/Series--------------------------------- +--++-- + +""" diff --git a/evdspy/EVDSlocal/series_format/read_config_series.py b/evdspy/EVDSlocal/series_format/read_config_series.py index 9474d9e..5c3f720 100644 --- a/evdspy/EVDSlocal/series_format/read_config_series.py +++ b/evdspy/EVDSlocal/series_format/read_config_series.py @@ -1,8 +1,8 @@ -from evdspy.EVDSlocal.series_format.populate_series import * -from evdspy.EVDSlocal.log_classes.log_template import * - - -def read_series_config(): - req = PopulateSeries("config_series.cfg").split_series_file() - print(req) - deb(req) +from evdspy.EVDSlocal.series_format.populate_series import * +from evdspy.EVDSlocal.log_classes.log_template import * + + +def read_series_config(): + req = PopulateSeries("config_series.cfg").split_series_file() + print(req) + deb(req) diff --git a/evdspy/EVDSlocal/series_format/sample_series_content.py b/evdspy/EVDSlocal/series_format/sample_series_content.py index f50f9c6..3f63570 100644 --- a/evdspy/EVDSlocal/series_format/sample_series_content.py +++ b/evdspy/EVDSlocal/series_format/sample_series_content.py @@ -1,109 +1,109 @@ -sample_series = f""" -file:visitors -subject:visitors -TP.ODEMGZS.BDTTOPLAM -TP.ODEMGZS.ABD -TP.ODEMGZS.ARJANTIN -TP.ODEMGZS.BREZILYA -TP.ODEMGZS.KANADA -TP.ODEMGZS.KOLOMBIYA -TP.ODEMGZS.MEKSIKA -TP.ODEMGZS.SILI -TP.ODEMGZS.VENEZUELLA -TP.ODEMGZS.DAMERIKA -TP.ODEMGZS.AMERIKATOP -TP.ODEMGZS.CEZAYIR -TP.ODEMGZS.FAS -TP.ODEMGZS.GAFRIKA -TP.ODEMGZS.LIBYA -TP.ODEMGZS.MISIR -TP.ODEMGZS.SUDAN -TP.ODEMGZS.TUNUS -TP.ODEMGZS.DAFRIKA -TP.ODEMGZS.AFRIKATOP -TP.ODEMGZS.BAE -TP.ODEMGZS.BAHREYN -TP.ODEMGZS.BANGLADES -TP.ODEMGZS.CIN -TP.ODEMGZS.ENDONEZYA -TP.ODEMGZS.FILIPINLER -TP.ODEMGZS.GKORE -TP.ODEMGZS.HINDISTAN -TP.ODEMGZS.IRAK -TP.ODEMGZS.IRAN -TP.ODEMGZS.ISRAIL -TP.ODEMGZS.JAPONYA -TP.ODEMGZS.KKTC -TP.ODEMGZS.KATAR -TP.ODEMGZS.KUVEYT -TP.ODEMGZS.LUBNAN -TP.ODEMGZS.MALEZYA -TP.ODEMGZS.PAKISTAN -TP.ODEMGZS.SINGAPUR -TP.ODEMGZS.SURIYE -TP.ODEMGZS.SUUDARABISTAN -TP.ODEMGZS.TAYLAND -TP.ODEMGZS.URDUN -TP.ODEMGZS.YEMEN -TP.ODEMGZS.DASYA -TP.ODEMGZS.ASYATOP -TP.ODEMGZS.AVUSTRALYA -TP.ODEMGZS.YENIZELLANDA -TP.ODEMGZS.OKYANUSYA -TP.ODEMGZS.MILLIYESIZ -TP.ODEMGZS.GTOPLAM --- -file:visitors2 -subject:visitors2 -TP.ODEMGZS.BDTTOPLAM -TP.ODEMGZS.ABD -TP.ODEMGZS.ARJANTIN -TP.ODEMGZS.BREZILYA -TP.ODEMGZS.KANADA -TP.ODEMGZS.KOLOMBIYA -TP.ODEMGZS.MEKSIKA -TP.ODEMGZS.SILI -TP.ODEMGZS.VENEZUELLA -TP.ODEMGZS.DAMERIKA -TP.ODEMGZS.AMERIKATOP -TP.ODEMGZS.CEZAYIR -TP.ODEMGZS.FAS -TP.ODEMGZS.GAFRIKA -TP.ODEMGZS.LIBYA -TP.ODEMGZS.MISIR -TP.ODEMGZS.SUDAN -TP.ODEMGZS.TUNUS -TP.ODEMGZS.DAFRIKA -TP.ODEMGZS.AFRIKATOP -TP.ODEMGZS.BAE -TP.ODEMGZS.BAHREYN -TP.ODEMGZS.BANGLADES -TP.ODEMGZS.CIN -TP.ODEMGZS.ENDONEZYA -TP.ODEMGZS.FILIPINLER -TP.ODEMGZS.GKORE -TP.ODEMGZS.HINDISTAN -TP.ODEMGZS.IRAK -TP.ODEMGZS.IRAN -TP.ODEMGZS.ISRAIL -TP.ODEMGZS.JAPONYA -TP.ODEMGZS.KKTC -TP.ODEMGZS.KATAR -TP.ODEMGZS.KUVEYT -TP.ODEMGZS.LUBNAN -TP.ODEMGZS.MALEZYA -TP.ODEMGZS.PAKISTAN -TP.ODEMGZS.SINGAPUR -TP.ODEMGZS.SURIYE -TP.ODEMGZS.SUUDARABISTAN -TP.ODEMGZS.TAYLAND -TP.ODEMGZS.URDUN -TP.ODEMGZS.YEMEN -TP.ODEMGZS.DASYA -TP.ODEMGZS.ASYATOP -TP.ODEMGZS.AVUSTRALYA -TP.ODEMGZS.YENIZELLANDA -TP.ODEMGZS.OKYANUSYA -TP.ODEMGZS.MILLIYESIZ -TP.ODEMGZS.GTOPLAM -""" +sample_series = f""" +file:visitors +subject:visitors +TP.ODEMGZS.BDTTOPLAM +TP.ODEMGZS.ABD +TP.ODEMGZS.ARJANTIN +TP.ODEMGZS.BREZILYA +TP.ODEMGZS.KANADA +TP.ODEMGZS.KOLOMBIYA +TP.ODEMGZS.MEKSIKA +TP.ODEMGZS.SILI +TP.ODEMGZS.VENEZUELLA +TP.ODEMGZS.DAMERIKA +TP.ODEMGZS.AMERIKATOP +TP.ODEMGZS.CEZAYIR +TP.ODEMGZS.FAS +TP.ODEMGZS.GAFRIKA +TP.ODEMGZS.LIBYA +TP.ODEMGZS.MISIR +TP.ODEMGZS.SUDAN +TP.ODEMGZS.TUNUS +TP.ODEMGZS.DAFRIKA +TP.ODEMGZS.AFRIKATOP +TP.ODEMGZS.BAE +TP.ODEMGZS.BAHREYN +TP.ODEMGZS.BANGLADES +TP.ODEMGZS.CIN +TP.ODEMGZS.ENDONEZYA +TP.ODEMGZS.FILIPINLER +TP.ODEMGZS.GKORE +TP.ODEMGZS.HINDISTAN +TP.ODEMGZS.IRAK +TP.ODEMGZS.IRAN +TP.ODEMGZS.ISRAIL +TP.ODEMGZS.JAPONYA +TP.ODEMGZS.KKTC +TP.ODEMGZS.KATAR +TP.ODEMGZS.KUVEYT +TP.ODEMGZS.LUBNAN +TP.ODEMGZS.MALEZYA +TP.ODEMGZS.PAKISTAN +TP.ODEMGZS.SINGAPUR +TP.ODEMGZS.SURIYE +TP.ODEMGZS.SUUDARABISTAN +TP.ODEMGZS.TAYLAND +TP.ODEMGZS.URDUN +TP.ODEMGZS.YEMEN +TP.ODEMGZS.DASYA +TP.ODEMGZS.ASYATOP +TP.ODEMGZS.AVUSTRALYA +TP.ODEMGZS.YENIZELLANDA +TP.ODEMGZS.OKYANUSYA +TP.ODEMGZS.MILLIYESIZ +TP.ODEMGZS.GTOPLAM +-- +file:visitors2 +subject:visitors2 +TP.ODEMGZS.BDTTOPLAM +TP.ODEMGZS.ABD +TP.ODEMGZS.ARJANTIN +TP.ODEMGZS.BREZILYA +TP.ODEMGZS.KANADA +TP.ODEMGZS.KOLOMBIYA +TP.ODEMGZS.MEKSIKA +TP.ODEMGZS.SILI +TP.ODEMGZS.VENEZUELLA +TP.ODEMGZS.DAMERIKA +TP.ODEMGZS.AMERIKATOP +TP.ODEMGZS.CEZAYIR +TP.ODEMGZS.FAS +TP.ODEMGZS.GAFRIKA +TP.ODEMGZS.LIBYA +TP.ODEMGZS.MISIR +TP.ODEMGZS.SUDAN +TP.ODEMGZS.TUNUS +TP.ODEMGZS.DAFRIKA +TP.ODEMGZS.AFRIKATOP +TP.ODEMGZS.BAE +TP.ODEMGZS.BAHREYN +TP.ODEMGZS.BANGLADES +TP.ODEMGZS.CIN +TP.ODEMGZS.ENDONEZYA +TP.ODEMGZS.FILIPINLER +TP.ODEMGZS.GKORE +TP.ODEMGZS.HINDISTAN +TP.ODEMGZS.IRAK +TP.ODEMGZS.IRAN +TP.ODEMGZS.ISRAIL +TP.ODEMGZS.JAPONYA +TP.ODEMGZS.KKTC +TP.ODEMGZS.KATAR +TP.ODEMGZS.KUVEYT +TP.ODEMGZS.LUBNAN +TP.ODEMGZS.MALEZYA +TP.ODEMGZS.PAKISTAN +TP.ODEMGZS.SINGAPUR +TP.ODEMGZS.SURIYE +TP.ODEMGZS.SUUDARABISTAN +TP.ODEMGZS.TAYLAND +TP.ODEMGZS.URDUN +TP.ODEMGZS.YEMEN +TP.ODEMGZS.DASYA +TP.ODEMGZS.ASYATOP +TP.ODEMGZS.AVUSTRALYA +TP.ODEMGZS.YENIZELLANDA +TP.ODEMGZS.OKYANUSYA +TP.ODEMGZS.MILLIYESIZ +TP.ODEMGZS.GTOPLAM +""" diff --git a/evdspy/EVDSlocal/series_format/series_creator.py b/evdspy/EVDSlocal/series_format/series_creator.py index 22f40fb..06a0720 100644 --- a/evdspy/EVDSlocal/series_format/series_creator.py +++ b/evdspy/EVDSlocal/series_format/series_creator.py @@ -1,190 +1,190 @@ -# ------------------------------------------------------------------------------ -from ..common.files import * -from dataclasses import dataclass -from .series_examples import * -from ..components.evds_seri_files import EvdsSeriesRequestWrapper, EvdsSeriesRequest, EvdsSeri -from evdspy.EVDSlocal.series_format.populate_series import * -from evdspy.EVDSlocal.config.config import default_series_file_name - -import random -from ..common.colors import * - -GSEP = "--" - -# ------------------------------------------v1.0 refactored------------------------------------------------------ -from pathlib import Path - - -def get_approval(file_name): - msg = f"{file_name} already exists. \n If you would like to replace it with a new example please type `replace`: " - print_get_input_style(msg ) - ans = input() - if str(ans).lower().strip() == "replace": - return True - return False - - -def create_series_text_file(file_name: str, content=""): - """General usage""" - if Path(file_name).is_file() and "-locked" not in file_name.lower(): - if not get_approval(file_name): - return False - print_with_creating_style(f"creating...{file_name}") - result, msg = Write(file_name, content) - print_with_success_style(msg) - time.sleep(1) - return result - - -def create_series_text_example(file_name: str = default_series_file_name, onsetup: bool = False): - if onsetup: - if file_exists_show_and_return(file_name): - return - """ main series config file """ - return create_series_text_file(file_name, random.choice(example_series)) - - -# ------------------------------------------ / v1.0 refactored------------------------------------------------------ - - -def series_file_info(file_name): - print_with_info_style(f"In order to use your own choice of data series in " - f"`{file_name}` you may change this file accordingly") - - -from evdspy.EVDSlocal.components.bucket_from_series import BucketFromSeriesFile - - -def get_locked_file_title(): - title = f""" -#package : evdspy -#author : sermet.pekin -#Series_config_file_LOCKED :Please do not modify. -# -# E V D S P Y _ C O N F I G _ F I L E (LOCKED) --------------------------------------------- -# -# ----------------------------------------------------------------------------------------- -# NOTE : PLEASE DO NOT MODIFY *LOCKED* VERSION OF THE CONFIG FILE (THIS FILE). -# BECAUSE IT WILL NOT HAVE EFFECT ON RUN. -# INSTEAD IF YOU WOULD LIKE TO MODIFY ANY PROPERTIES OF SERIES OR OTHER OPTIONS -# YOU MAY MODIFY UNLOCKED VERSION OF THIS FILE. (`config_series.cfg`) -# -# THIS FILE(LOCKED) IS HELP USERS TO SEE HOW MACHINE MODIFIED DEFAULT OPTIONS -# DURING RUN AFTER CHECKING PROCESS. -# -# ------------------------------------------------------------------------------------------- - - -""" - return title - - -from evdspy.EVDSlocal.setup_project.user_series_config import frequency_dict, formulas_dict -from evdspy.EVDSlocal.state.current_state import CurrentState -from typing import Dict -from evdspy.EVDSlocal.components.request_or_cache import RequestOrCacheResultInfo - - -def get_request_results(): - result_data_dict: Dict[str, RequestOrCacheResultInfo] = CurrentState().get_result_dict() - items = result_data_dict.items() - items_str_list = (tuple_request_or_cache_info[1].get_data() for tuple_request_or_cache_info in items) - - result_content = "\n".join(items_str_list) - result = f""" -------------REQUEST or CACHE RESULTS------------------ -{result_content} -------------/REQUEST or CACHE RESULTS------------------ -""" - return result - - -def create_content(bfs: BucketFromSeriesFile, evds_series_request_: EvdsSeriesRequest, subject, - series_list: List[EvdsSeri]): - list_ = [x.ID for x in series_list] - series_list_str = "\n".join(list_) - r = f""" ----Series--------------------------------- -foldername : {bfs.folder_name} -abs_path : {bfs.abs_path} -subject : {subject} -prefix : {bfs.prefix} -frequency : {bfs.frequency} # {frequency_dict.get(int(bfs.frequency), 'Not Found (request will be made with default option for this property)')} -formulas : {bfs.formulas} # {formulas_dict.get(int(bfs.formulas), 'Not Found (request will be made with default option for this property)')} -aggregateType : {bfs.aggregateType} - -------------SERIES CODES------------------ -{series_list_str} -------------/SERIES CODES------------------ - - - ----/Series--------------------------------- ---++-- -""" - return r - - -def create_series_file_from_Wrapper(wrapperList: List[EvdsSeriesRequestWrapper]): - contents = [] - for EvdsSeriesRequestWrapper_ in wrapperList: - name = EvdsSeriesRequestWrapper_.name - subject = EvdsSeriesRequestWrapper_.subject - series_list = EvdsSeriesRequestWrapper_.EvdsSeriesRequest_.series_list - contents.append( - create_content(EvdsSeriesRequestWrapper_.bfs, EvdsSeriesRequestWrapper_.EvdsSeriesRequest_, subject, - series_list)) - cont = get_locked_file_title() \ - + f"\n{GSEP}".join(contents) \ - + get_request_results() - - return cont - - -from ..components.evds_seri_files import * - - -# ------------------------------------------------------------------------------ -# /* -# SeriesFileFormat -# -# ------------------------------------------------------------------------------ -# */ - -@dataclass -class SeriesFileFormat: - series_filename: str - EvdsSeriesRequestWrapperList: any = None - - def __post_init__(self): - self.get_series_from_file() - - def read(self): - return Read(self.series_filename, f"{self.series_filename} problem") - - def get_series_from_file(self): - self.EvdsSeriesRequestWrapperList: \ - List[EvdsSeriesRequestWrapper] = \ - PopulateSeries( - self.series_filename - ).split_series_file() - return self.EvdsSeriesRequestWrapperList - - - -def test_SeriesFileFormat2(): - sff = SeriesFileFormat("series.txt") - return sff.EvdsSeriesRequestWrapperList # s.read() - - -# ------------------------------------------------------------------------------ -# /* -# SeriesCreator -# -# ------------------------------------------------------------------------------ -# */ -@dataclass -class SeriesCreator: - - def create(self): - ... +# ------------------------------------------------------------------------------ +from ..common.files import * +from dataclasses import dataclass +from .series_examples import * +from ..components.evds_seri_files import EvdsSeriesRequestWrapper, EvdsSeriesRequest, EvdsSeri +from evdspy.EVDSlocal.series_format.populate_series import * +from evdspy.EVDSlocal.config.config import default_series_file_name + +import random +from ..common.colors import * + +GSEP = "--" + +# ------------------------------------------v1.0 refactored------------------------------------------------------ +from pathlib import Path + + +def get_approval(file_name): + msg = f"{file_name} already exists. \n If you would like to replace it with a new example please type `replace`: " + print_get_input_style(msg ) + ans = input() + if str(ans).lower().strip() == "replace": + return True + return False + + +def create_series_text_file(file_name: str, content=""): + """General usage""" + if Path(file_name).is_file() and "-locked" not in file_name.lower(): + if not get_approval(file_name): + return False + print_with_creating_style(f"creating...{file_name}") + result, msg = Write(file_name, content) + print_with_success_style(msg) + time.sleep(1) + return result + + +def create_series_text_example(file_name: str = default_series_file_name, onsetup: bool = False): + if onsetup: + if file_exists_show_and_return(file_name): + return + """ main series config file """ + return create_series_text_file(file_name, random.choice(example_series)) + + +# ------------------------------------------ / v1.0 refactored------------------------------------------------------ + + +def series_file_info(file_name): + print_with_info_style(f"In order to use your own choice of data series in " + f"`{file_name}` you may change this file accordingly") + + +from evdspy.EVDSlocal.components.bucket_from_series import BucketFromSeriesFile + + +def get_locked_file_title(): + title = f""" +#package : evdspy +#author : sermet.pekin +#Series_config_file_LOCKED :Please do not modify. +# +# E V D S P Y _ C O N F I G _ F I L E (LOCKED) --------------------------------------------- +# +# ----------------------------------------------------------------------------------------- +# NOTE : PLEASE DO NOT MODIFY *LOCKED* VERSION OF THE CONFIG FILE (THIS FILE). +# BECAUSE IT WILL NOT HAVE EFFECT ON RUN. +# INSTEAD IF YOU WOULD LIKE TO MODIFY ANY PROPERTIES OF SERIES OR OTHER OPTIONS +# YOU MAY MODIFY UNLOCKED VERSION OF THIS FILE. (`config_series.cfg`) +# +# THIS FILE(LOCKED) IS HELP USERS TO SEE HOW MACHINE MODIFIED DEFAULT OPTIONS +# DURING RUN AFTER CHECKING PROCESS. +# +# ------------------------------------------------------------------------------------------- + + +""" + return title + + +from evdspy.EVDSlocal.setup_project.user_series_config import frequency_dict, formulas_dict +from evdspy.EVDSlocal.state.current_state import CurrentState +from typing import Dict +from evdspy.EVDSlocal.components.request_or_cache import RequestOrCacheResultInfo + + +def get_request_results(): + result_data_dict: Dict[str, RequestOrCacheResultInfo] = CurrentState().get_result_dict() + items = result_data_dict.items() + items_str_list = (tuple_request_or_cache_info[1].get_data() for tuple_request_or_cache_info in items) + + result_content = "\n".join(items_str_list) + result = f""" +------------REQUEST or CACHE RESULTS------------------ +{result_content} +------------/REQUEST or CACHE RESULTS------------------ +""" + return result + + +def create_content(bfs: BucketFromSeriesFile, evds_series_request_: EvdsSeriesRequest, subject, + series_list: List[EvdsSeri]): + list_ = [x.ID for x in series_list] + series_list_str = "\n".join(list_) + r = f""" +---Series--------------------------------- +foldername : {bfs.folder_name} +abs_path : {bfs.abs_path} +subject : {subject} +prefix : {bfs.prefix} +frequency : {bfs.frequency} # {frequency_dict.get(int(bfs.frequency), 'Not Found (request will be made with default option for this property)')} +formulas : {bfs.formulas} # {formulas_dict.get(int(bfs.formulas), 'Not Found (request will be made with default option for this property)')} +aggregateType : {bfs.aggregateType} + +------------SERIES CODES------------------ +{series_list_str} +------------/SERIES CODES------------------ + + + +---/Series--------------------------------- +--++-- +""" + return r + + +def create_series_file_from_Wrapper(wrapperList: List[EvdsSeriesRequestWrapper]): + contents = [] + for EvdsSeriesRequestWrapper_ in wrapperList: + name = EvdsSeriesRequestWrapper_.name + subject = EvdsSeriesRequestWrapper_.subject + series_list = EvdsSeriesRequestWrapper_.EvdsSeriesRequest_.series_list + contents.append( + create_content(EvdsSeriesRequestWrapper_.bfs, EvdsSeriesRequestWrapper_.EvdsSeriesRequest_, subject, + series_list)) + cont = get_locked_file_title() \ + + f"\n{GSEP}".join(contents) \ + + get_request_results() + + return cont + + +from ..components.evds_seri_files import * + + +# ------------------------------------------------------------------------------ +# /* +# SeriesFileFormat +# +# ------------------------------------------------------------------------------ +# */ + +@dataclass +class SeriesFileFormat: + series_filename: str + EvdsSeriesRequestWrapperList: any = None + + def __post_init__(self): + self.get_series_from_file() + + def read(self): + return Read(self.series_filename, f"{self.series_filename} problem") + + def get_series_from_file(self): + self.EvdsSeriesRequestWrapperList: \ + List[EvdsSeriesRequestWrapper] = \ + PopulateSeries( + self.series_filename + ).split_series_file() + return self.EvdsSeriesRequestWrapperList + + + +def test_SeriesFileFormat2(): + sff = SeriesFileFormat("series.txt") + return sff.EvdsSeriesRequestWrapperList # s.read() + + +# ------------------------------------------------------------------------------ +# /* +# SeriesCreator +# +# ------------------------------------------------------------------------------ +# */ +@dataclass +class SeriesCreator: + + def create(self): + ... diff --git a/evdspy/EVDSlocal/series_format/series_creator_on_setup.py b/evdspy/EVDSlocal/series_format/series_creator_on_setup.py index b9d9616..836ada9 100644 --- a/evdspy/EVDSlocal/series_format/series_creator_on_setup.py +++ b/evdspy/EVDSlocal/series_format/series_creator_on_setup.py @@ -1,29 +1,30 @@ -from evdspy.EVDSlocal.common.common_imports import * - -from .sample_series_content import sample_series - -""" - This file runs only on startup to create some samples to check setup. - you may change [default_series_file_name] `config_series.cfg` content according to format provided both on - readme file and in the text file. -""" -from evdspy.EVDSlocal.utils.utils_general import * -from evdspy.EVDSlocal.initial.start_options import * - - -def create_sample_series_text_file(): - with open(default_series_file_name, "w", encoding=ENCODING) as file_: - file_.write(sample_series) - - -def on_start_create(): - from pathlib import Path - f = Path(default_series_file_name) - if not f.is_file(): - create_sample_series_text_file() - print(f"{indent} sample file {default_series_file_name} was created...") - - -__all__ = [ - 'on_start_create' -] +from evdspy.EVDSlocal.common.common_imports import * + +from .sample_series_content import sample_series + +""" + This file runs only on startup to create some samples to check setup. + you may change `series.txt` content according to format provided both on + readme file and in the text file. +""" +from evdspy.EVDSlocal.utils.utils_general import * + +from evdspy.EVDSlocal.initial.start_options import * + + +def create_sample_series_text_file(): + with open(default_series_file_name, "w", encoding=ENCODING) as file_: + file_.write(sample_series) + + +def on_start_create(): + from pathlib import Path + f = Path(default_series_file_name) + if not f.is_file(): + create_sample_series_text_file() + print(f"{indent} sample file {default_series_file_name} was created...") + + +__all__ = [ + 'on_start_create' +] diff --git a/evdspy/EVDSlocal/series_format/series_examples.py b/evdspy/EVDSlocal/series_format/series_examples.py index bd96629..b59f4bf 100644 --- a/evdspy/EVDSlocal/series_format/series_examples.py +++ b/evdspy/EVDSlocal/series_format/series_examples.py @@ -1,107 +1,107 @@ -site_visitors = rf""" - -#Series_config_file -E V D S P Y _ C O N F I G _ F I L E --------------------------------------------- -# -# This file will be used by evdspy package (python) in order to help updating -# your series. -# Script will be adding this file when you setup a new project. -# Deleting or modifying its content may require to setup configuration from the beginning -# ---------------------------------------------------------------------------------------- -# -#About alternative params -# ---------------------------------------------------------------------------------------- - - - Frequencies - ----------------- - - Daily: 1 - Business: 2 - Weekly(Friday): 3 - Twicemonthly: 4 - Monthly: 5 - Quarterly: 6 - Semiannual: 7 - Annual: 8 - - - `Formulas`s - ----------------- - - Level: 0 - Percentage change: 1 - Difference: 2 - Year-to-year Percent Change: 3 - Year-to-year Differences: 4 - Percentage Change Compared to End-of-Previous Year: 5 - Difference Compared to End-of-Previous Year : 6 - Moving Average: 7 - Moving Sum: 8 - - Aggregate types - ----------------- - - Average: avg, - Minimum: min, - Maximum: max - Beginning: first, - End: last, - Cumulative: sum - - -#Begin_series - ----Series--------------------------------- -foldername : visitors\annual -abs_path : visitors\annual # will check again before saving requests from the server it might be replaced by ...WD.../DataSeries/visitors\monthly -subject : visitors -prefix : EVPY_ -frequency : 8 # annually -formulas : 0 # Level -aggregateType : avg -------------SERIES CODES------------------ -TP.ODEMGZS.BDTTOPLAM -TP.ODEMGZS.ABD -TP.ODEMGZS.ARJANTIN -TP.ODEMGZS.BREZILYA -TP.ODEMGZS.KANADA -TP.ODEMGZS.KOLOMBIYA -TP.ODEMGZS.MEKSIKA -TP.ODEMGZS.SILI -------------/SERIES CODES------------------ ----/Series--------------------------------- ---++-- - ----Series--------------------------------- -foldername : visitors\monthly -abs_path : C:\Users\User\SeriesData\visitors\monthly # will check again before saving requests from the server it might be replaced by ...WD.../DataSeries/visitors\monthly -subject : visitors -prefix : EVPY_ -frequency : 5 # Monthly -formulas : 0 # Level -aggregateType : avg -------------SERIES CODES------------------ -TP.ODEMGZS.BDTTOPLAM -TP.ODEMGZS.ABD -TP.ODEMGZS.ARJANTIN -TP.ODEMGZS.BREZILYA -TP.ODEMGZS.KANADA -TP.ODEMGZS.KOLOMBIYA -TP.ODEMGZS.MEKSIKA -TP.ODEMGZS.SILI -------------/SERIES CODES------------------ ----/Series--------------------------------- ---++-- - - - - -""" - -test_series_file_content_for_test = site_visitors - -example_series = [site_visitors] -__all__ = [ - 'example_series', -] +site_visitors = rf""" + +#Series_config_file +E V D S P Y _ C O N F I G _ F I L E --------------------------------------------- +# +# This file will be used by evdspy package (python) in order to help updating +# your series. +# Script will be adding this file when you setup a new project. +# Deleting or modifying its content may require to setup configuration from the beginning +# ---------------------------------------------------------------------------------------- +# +#About alternative params +# ---------------------------------------------------------------------------------------- + + + Frequencies + ----------------- + + Daily: 1 + Business: 2 + Weekly(Friday): 3 + Twicemonthly: 4 + Monthly: 5 + Quarterly: 6 + Semiannual: 7 + Annual: 8 + + + `Formulas`s + ----------------- + + Level: 0 + Percentage change: 1 + Difference: 2 + Year-to-year Percent Change: 3 + Year-to-year Differences: 4 + Percentage Change Compared to End-of-Previous Year: 5 + Difference Compared to End-of-Previous Year : 6 + Moving Average: 7 + Moving Sum: 8 + + Aggregate types + ----------------- + + Average: avg, + Minimum: min, + Maximum: max + Beginning: first, + End: last, + Cumulative: sum + + +#Begin_series + +---Series--------------------------------- +foldername : visitors/annual +abs_path : visitors/annual # will check again before saving requests from the server it might be replaced by ...WD.../DataSeries/visitors\monthly +subject : visitors +prefix : EVPY_ +frequency : 8 # annually +formulas : 0 # Level +aggregateType : avg +------------SERIES CODES------------------ +TP.ODEMGZS.BDTTOPLAM +TP.ODEMGZS.ABD +TP.ODEMGZS.ARJANTIN +TP.ODEMGZS.BREZILYA +TP.ODEMGZS.KANADA +TP.ODEMGZS.KOLOMBIYA +TP.ODEMGZS.MEKSIKA +TP.ODEMGZS.SILI +------------/SERIES CODES------------------ +---/Series--------------------------------- +--++-- + +---Series--------------------------------- +foldername : visitors/monthly +abs_path : visitors/monthly # will check again before saving requests from the server it might be replaced by ...WD.../DataSeries/visitors\monthly +subject : visitors +prefix : EVPY_ +frequency : 5 # Monthly +formulas : 0 # Level +aggregateType : avg +------------SERIES CODES------------------ +TP.ODEMGZS.BDTTOPLAM +TP.ODEMGZS.ABD +TP.ODEMGZS.ARJANTIN +TP.ODEMGZS.BREZILYA +TP.ODEMGZS.KANADA +TP.ODEMGZS.KOLOMBIYA +TP.ODEMGZS.MEKSIKA +TP.ODEMGZS.SILI +------------/SERIES CODES------------------ +---/Series--------------------------------- +--++-- + + + + +""" + +test_series_file_content_for_test = site_visitors + +example_series = [site_visitors] +__all__ = [ + 'example_series', +] diff --git a/evdspy/EVDSlocal/series_format/series_format_config_funcs.py b/evdspy/EVDSlocal/series_format/series_format_config_funcs.py index a5cf907..21549d8 100644 --- a/evdspy/EVDSlocal/series_format/series_format_config_funcs.py +++ b/evdspy/EVDSlocal/series_format/series_format_config_funcs.py @@ -1,66 +1,66 @@ -from ..common.common_imports import * - -TrueFunc = (lambda x: True) - - -def folder_creatable(folder): - try: - d = Path(folder) - if d.is_dir(): - return True - except: - return False - return False - - -def folder_creatable_by_adding(folder): - try: - d = Path(folder) - e = str(d).replace(d.stem, "") - if not len(e) > 0: - return False - f = Path(e) - except: - return False - return folder_creatable(f) - - -from evdspy.EVDSlocal.common.folder_name_checks import is_relative - -from rich import print -from rich.console import Console -from rich.theme import Theme - -custom_theme = Theme({ - "info": "dim cyan", - "warning": "magenta", - "danger": "bold red" -}) -console = Console(theme=custom_theme) - - -# console.print("test info", style="info") -# console.print("[warning]test warning[/warning]") -# console.print("Test", style="danger") - - -def folder_format_check(folder: str): - if not folder.strip(): - return True - # print(f"checking ... {folder}") - console.print(f"checked foldername : {folder}", style="warning") - import string - if isinstance(folder, str) and is_relative(folder): - return True - print("[danger]folder name does not fit to format[/danger]") - return False - - -def notest(): - t = is_relative(r"/asfasdf/asdfasdf") - is_relative(r"C:/asfasdf/asdfasdf??") - is_relative(r"C:/asfasdf/asdfasdf??") - is_relative(r"asfasdf/asdfasdf") - - -notest() +from ..common.common_imports import * + +TrueFunc = (lambda x: True) + + +def folder_creatable(folder): + try: + d = Path(folder) + if d.is_dir(): + return True + except: + return False + return False + + +def folder_creatable_by_adding(folder): + try: + d = Path(folder) + e = str(d).replace(d.stem, "") + if not len(e) > 0: + return False + f = Path(e) + except: + return False + return folder_creatable(f) + + +from evdspy.EVDSlocal.common.folder_name_checks import is_relative + +from rich import print +from rich.console import Console +from rich.theme import Theme + +custom_theme = Theme({ + "info": "dim cyan", + "warning": "magenta", + "danger": "bold red" +}) +console = Console(theme=custom_theme) + + +# console.print("test info", style="info") +# console.print("[warning]test warning[/warning]") +# console.print("Test", style="danger") + + +def folder_format_check(folder: str): + if not folder.strip(): + return True + # print(f"checking ... {folder}") + console.print(f"checked foldername : {folder}", style="warning") + import string + if isinstance(folder, str) and is_relative(folder): + return True + print("[danger]folder name does not fit to format[/danger]") + return False + + +def notest(): + t = is_relative(r"/asfasdf/asdfasdf") + is_relative(r"C:/asfasdf/asdfasdf??") + is_relative(r"C:/asfasdf/asdfasdf??") + is_relative(r"asfasdf/asdfasdf") + + +notest() diff --git a/evdspy/EVDSlocal/series_format/stats/save_stats_of_requests.py b/evdspy/EVDSlocal/series_format/stats/save_stats_of_requests.py index 98c340a..b746a76 100644 --- a/evdspy/EVDSlocal/series_format/stats/save_stats_of_requests.py +++ b/evdspy/EVDSlocal/series_format/stats/save_stats_of_requests.py @@ -1,25 +1,25 @@ -from evdspy.EVDSlocal.common.files import * -from dataclasses import dataclass, field - -from datetime import datetime - - -@dataclass -class Report: - file_name: str = "stats_report.txt" - - @property - def date_content(self): - now = datetime.now() - - current_time = now.strftime("%Y-%m-%d %H:%M:%S") - return current_time - - def add(self, content): - content = f"{self.date_content} => {content}" - WriteAdd(self.file_name, content) - - -def report_test(): - r = Report(file_name="test_stats_report.txt") - r.add("content") +from evdspy.EVDSlocal.common.files import * +from dataclasses import dataclass, field + +from datetime import datetime + + +@dataclass +class Report: + file_name: str = "stats_report.txt" + + @property + def date_content(self): + now = datetime.now() + + current_time = now.strftime("%Y-%m-%d %H:%M:%S") + return current_time + + def add(self, content): + content = f"{self.date_content} => {content}" + WriteAdd(self.file_name, content) + + +def report_test(): + r = Report(file_name="test_stats_report.txt") + r.add("content") diff --git a/evdspy/EVDSlocal/session/session_.py b/evdspy/EVDSlocal/session/session_.py index 9b24e6e..fe28070 100644 --- a/evdspy/EVDSlocal/session/session_.py +++ b/evdspy/EVDSlocal/session/session_.py @@ -1,32 +1,32 @@ -from evdspy.EVDSlocal.utils.utils_general import * - - -class Session: - - def __new__(cls, *args, **kwargs): - if not hasattr(cls, 'instance'): - cls.instance = super(Session, cls).__new__(cls) - cls.start(cls) - - return cls.instance - - def start(cls): - cls.hash = get_random_hash(5) - - def attach_logger(cls, logger_): - cls.logger = logger_ - - def __repr__(self): - return f"session:{self.hash}" - - # def __new__(cls, sObj = None , DB = None , *args, **kwargs): - # if not hasattr(cls, 'instance'): - # cls.db = DB(cls) - # cls.annoying = False - # if sObj is not None : - # cls.start(cls, sObj) - # cls.instance = super(Session, cls).__new__(cls) - - -def get_session(): +from evdspy.EVDSlocal.utils.utils_general import * + + +class Session: + + def __new__(cls, *args, **kwargs): + if not hasattr(cls, 'instance'): + cls.instance = super(Session, cls).__new__(cls) + cls.start(cls) + + return cls.instance + + def start(cls): + cls.hash = get_random_hash(5) + + def attach_logger(cls, logger_): + cls.logger = logger_ + + def __repr__(self): + return f"session:{self.hash}" + + # def __new__(cls, sObj = None , DB = None , *args, **kwargs): + # if not hasattr(cls, 'instance'): + # cls.db = DB(cls) + # cls.annoying = False + # if sObj is not None : + # cls.start(cls, sObj) + # cls.instance = super(Session, cls).__new__(cls) + + +def get_session(): return Session() \ No newline at end of file diff --git a/evdspy/EVDSlocal/setup_project/read_config_series.py b/evdspy/EVDSlocal/setup_project/read_config_series.py new file mode 100644 index 0000000..9dead06 --- /dev/null +++ b/evdspy/EVDSlocal/setup_project/read_config_series.py @@ -0,0 +1,10 @@ +from evdspy.EVDSlocal.setup_project.user_setup_helper import * + +from evdspy.EVDSlocal.components.populate_series import * +from evdspy.EVDSlocal.logs.log_template import * + + +def read_series_config(): + req = PopulateSeries("config_series.cfg").split_series_file() + print(req) + deb(req) diff --git a/evdspy/EVDSlocal/setup_project/user_options_config.py b/evdspy/EVDSlocal/setup_project/user_options_config.py index 622e55a..0c8d9ef 100644 --- a/evdspy/EVDSlocal/setup_project/user_options_config.py +++ b/evdspy/EVDSlocal/setup_project/user_options_config.py @@ -1,33 +1,33 @@ -from evdspy.EVDSlocal.utils.utils_general import * -from evdspy.EVDSlocal.series_format.series_format_config_funcs import * - -mainSepBegin = "---Series---------------------------------" -mainSepEnd = "---/Series---------------------------------" -GSEP = "--++--" -NEW_LINE = "\n" - -# "cache_freq gl_date_start gl_date_end" - -# ----------------------------- C O N F I G --------------------------------------------------- -items_from_user_config = [ - "Cache frequency", - "global date start for series", - "global date end for the series", - "avoid absolute paths protection" , -] - -explanations_config = [ - f"Cache frequency will be used to decide to make a new request. {NEW_LINE} " - f"If recent cache is found in local cache folder program will use it instead of making a request. {NEW_LINE}" - f" {indent} Options : monthly / daily / nocache. Default : daily {NEW_LINE}", - f"if not special start date for the series was given in `config_series.cfg` file " - f"this date will be used as start date of series {NEW_LINE} Example 19-01-2015", - f"if not special end date for the series was given in `config_series.cfg` file " - f"this date will be used as end date of series {NEW_LINE} Example : 19-01-2030", - rf"if set False it will accept absolute paths such as C:\Users\Userx . default is True to protect users other folders from polluting" -] -check_funcs_options = [TrueFunc, TrueFunc, TrueFunc, TrueFunc] -default_answers_config = ['', '', '', 'True'] -same = lambda x: x - -transform_answers_options = (same for _ in items_from_user_config) +from evdspy.EVDSlocal.utils.utils_general import * +from evdspy.EVDSlocal.series_format.series_format_config_funcs import * + +mainSepBegin = "---Series---------------------------------" +mainSepEnd = "---/Series---------------------------------" +GSEP = "--++--" +NEW_LINE = "\n" + +# "cache_freq gl_date_start gl_date_end" + +# ----------------------------- C O N F I G --------------------------------------------------- +items_from_user_config = [ + "Cache frequency", + "global date start for series", + "global date end for the series", + "avoid absolute paths protection" , +] + +explanations_config = [ + f"Cache frequency will be used to decide to make a new request. {NEW_LINE} " + f"If recent cache is found in local cache folder program will use it instead of making a request. {NEW_LINE}" + f" {indent} Options : monthly / daily / nocache. Default : daily {NEW_LINE}", + f"if not special start date for the series was given in `config_series.cfg` file " + f"this date will be used as start date of series {NEW_LINE} Example 19-01-2015", + f"if not special end date for the series was given in `config_series.cfg` file " + f"this date will be used as end date of series {NEW_LINE} Example : 19-01-2030", + rf"if set False it will accept absolute paths such as C:\Users\Userx . default is True to protect users other folders from polluting" +] +check_funcs_options = [TrueFunc, TrueFunc, TrueFunc, TrueFunc] +default_answers_config = ['', '', '', 'True'] +same = lambda x: x + +transform_answers_options = (same for _ in items_from_user_config) diff --git a/evdspy/EVDSlocal/setup_project/user_series_config.py b/evdspy/EVDSlocal/setup_project/user_series_config.py index 0e26d14..11c80ac 100644 --- a/evdspy/EVDSlocal/setup_project/user_series_config.py +++ b/evdspy/EVDSlocal/setup_project/user_series_config.py @@ -1,172 +1,172 @@ -from evdspy.EVDSlocal.utils.utils_general import * -from evdspy.EVDSlocal.series_format.series_format_config_funcs import * - -mainSepBegin = "---Series---------------------------------" -mainSepEnd = "---/Series---------------------------------" -GSEP = "--++--" -NEW_LINE = "\n" -example_codes = ['TP.EVDSSTATS.KAYITLI', 'TP.EVDSSTATS.ZIYARET'] -example_codes_str = ",".join(example_codes) - -# ----------------------------- S E R I E S --------------------------------------------------- -items_from_user_series = [ - "Data folder", - "Subject", - "Name prefix(Optional) Default : `EVPY_` ", - "EVDS data series codes", - "Frequency", - "Formulas", - "AggregateType", -] - -default_prefix = "EVPY_" -freq = f""" -Daily: 1 -Business: 2 -Weekly(Friday): 3 -Semimonthly: 4 -Monthly: 5 -Quarterly: 6 -Semiannual: 7 -Annual: 8 -""" -frequency_dict = { - 1: 'Daily', - 2: 'Business day', - 3: 'Weekly(Friday)', - 4: 'Semimonthly', - 5: 'Monthly', - 6: 'Quarterly', - 7: 'Semiannual', - 8: 'Annual', -} -default_freq = "5" -formulas_ = f""" -Level: 0 -Percentage change: 1 -Difference: 2 -Year-to-year Percent Change: 3 -Year-to-year Differences: 4 -Percentage Change Compared to End-of-Previous Year: 5 -Difference Compared to End-of-Previous Year : 6 -Moving Average: 7 -Moving Sum: 8 -""" -formulas_dict = { - 0: "Level", - 1: "Percentage change", - 2: "Difference", - 3: "Year-to-year Percent Change", - 4: "Year-to-year Differences", - 5: "Percentage Change Compared to End-of-Previous Year", - 6: "Difference Compared to End-of-Previous Year", - 7: "Moving Average", - 8: "Moving Sum", -} -default_formulas_ = "0" -AggregateType_ = f""" -Average: avg, -Minimum: min, -Maximum: max -Beginning: first, -End: last, -Cumulative: sum -""" -quickNoteForParams = f""" -Frequencies ------------------ -{freq} -`Formulas`s ------------------ -{formulas_} -Aggregate types ------------------ -{AggregateType_} -""" -AggregateType__valid_answers = ["avg", "min", "max", "first", "last", "sum"] -default_AggregateType_ = "avg" -explanations_series = [ - rf"Path for your project {NEW_LINE}{indent}(Example: output or C:\Users\Userx\MyTempData ) default: {default_prefix}Data " - rf"{NEW_LINE} This should be an empty folder. If folder does not exist" - "program will create a new folder with this name", - rf"Subject will be used to name excel files. {NEW_LINE}{indent}(Example: Visitors, Tourism, Balance of Payments, Exchange Rates etc.", - "If there is already excel files in the folder this will prevent replacing existing files. ", - rf"evdspy will create your series.txt file {NEW_LINE} it will add data series codes if you provide. " - rf"{NEW_LINE} {indent} example : {example_codes_str} {NEW_LINE}" - f"You may also continue with default values and modify the config_series.cfg file later if you prefer", - f"{freq}\nFrequency (Number between 1, 8 e.g.(monthly) : 5) default: 1", - f"{formulas_}\n e.g. (Number between 0, 8 e.g.(Level) : 0) default: 0 ", - f"{AggregateType_}\n e.g. ( avg / min / max / first / last / sum ) default: avg", -] - - -def check_valid_answer(items, answer: str): - return answer in items - - -def check_valid_answer_freq(answer: str): - return check_valid_answer(tuple(map(str, range(1, 8))), answer) or answer.strip() == "" - - -def check_valid_answer_formulas_(answer: str): - return check_valid_answer(tuple(map(str, range(0, 9))), answer) or answer.strip() == "" - - -def check_valid_answer_aggr(answer: str): - return check_valid_answer(AggregateType__valid_answers, answer) or answer.strip() == "" - - -default_answer_subject = 'SubjectNotGiven' -default_answers_series = [f"{default_prefix}Data", - default_answer_subject, - default_prefix, - example_codes, - default_freq, - default_formulas_, - default_AggregateType_] -check_funcs_series = [folder_format_check, - TrueFunc, - TrueFunc, - TrueFunc, - check_valid_answer_freq, - check_valid_answer_formulas_, - check_valid_answer_aggr] -# import string -# x = "aa,ab-ac" -# s = x.split() -# -""" Transform Functions """ -same = lambda x: x -trim_string = lambda x: x.strip() -from typing import Tuple - -# import re -# split_items = lambda x: re.split("[,-/\n;]+", x) -split_items = lambda text: tuple(text.translate(text.maketrans({x: "-" for x in "[,-/\n;]~"})).split("-")) -""" Default answers if the user goes with an Empty answer """ - - -def get_default_for_question(answer, question): - obj = { - "folder": f"{default_prefix}Data", - "prefix": default_prefix, - "freq": default_freq, - "formulas": default_formulas_, - "aggr": default_AggregateType_, - "series": example_codes, - "subject": default_answer_subject - } - if not answer.strip(): - """ default returns here """ - return obj.get(question, answer) - - if question == "series": - """item1,item2\nitem3""" - return split_items(answer) - return answer.strip() - - -# instead of functools partial lambda this time -bound_question = lambda question: lambda answer: get_default_for_question(answer, question) -funcs_names = ("folder", "subject", "prefix", "series", "freq", "formulas", "aggr",) -transform_answers_series: Tuple = tuple(map(lambda x: bound_question(x), funcs_names)) +from evdspy.EVDSlocal.utils.utils_general import * +from evdspy.EVDSlocal.series_format.series_format_config_funcs import * + +mainSepBegin = "---Series---------------------------------" +mainSepEnd = "---/Series---------------------------------" +GSEP = "--++--" +NEW_LINE = "\n" +example_codes = ['TP.EVDSSTATS.KAYITLI', 'TP.EVDSSTATS.ZIYARET'] +example_codes_str = ",".join(example_codes) + +# ----------------------------- S E R I E S --------------------------------------------------- +items_from_user_series = [ + "Data folder", + "Subject", + "Name prefix(Optional) Default : `EVPY_` ", + "EVDS data series codes", + "Frequency", + "Formulas", + "AggregateType", +] + +default_prefix = "EVPY_" +freq = f""" +Daily: 1 +Business: 2 +Weekly(Friday): 3 +Semimonthly: 4 +Monthly: 5 +Quarterly: 6 +Semiannual: 7 +Annual: 8 +""" +frequency_dict = { + 1: 'Daily', + 2: 'Business day', + 3: 'Weekly(Friday)', + 4: 'Semimonthly', + 5: 'Monthly', + 6: 'Quarterly', + 7: 'Semiannual', + 8: 'Annual', +} +default_freq = "5" +formulas_ = f""" +Level: 0 +Percentage change: 1 +Difference: 2 +Year-to-year Percent Change: 3 +Year-to-year Differences: 4 +Percentage Change Compared to End-of-Previous Year: 5 +Difference Compared to End-of-Previous Year : 6 +Moving Average: 7 +Moving Sum: 8 +""" +formulas_dict = { + 0: "Level", + 1: "Percentage change", + 2: "Difference", + 3: "Year-to-year Percent Change", + 4: "Year-to-year Differences", + 5: "Percentage Change Compared to End-of-Previous Year", + 6: "Difference Compared to End-of-Previous Year", + 7: "Moving Average", + 8: "Moving Sum", +} +default_formulas_ = "0" +AggregateType_ = f""" +Average: avg, +Minimum: min, +Maximum: max +Beginning: first, +End: last, +Cumulative: sum +""" +quickNoteForParams = f""" +Frequencies +----------------- +{freq} +`Formulas`s +----------------- +{formulas_} +Aggregate types +----------------- +{AggregateType_} +""" +AggregateType__valid_answers = ["avg", "min", "max", "first", "last", "sum"] +default_AggregateType_ = "avg" +explanations_series = [ + rf"Path for your project {NEW_LINE}{indent}(Example: output or C:\Users\Userx\MyTempData ) default: {default_prefix}Data " + rf"{NEW_LINE} This should be an empty folder. If folder does not exist" + "program will create a new folder with this name", + rf"Subject will be used to name excel files. {NEW_LINE}{indent}(Example: Visitors, Tourism, Balance of Payments, Exchange Rates etc.", + "If there is already excel files in the folder this will prevent replacing existing files. ", + rf"evdspy will create your series.txt file {NEW_LINE} it will add data series codes if you provide. " + rf"{NEW_LINE} {indent} example : {example_codes_str} {NEW_LINE}" + f"You may also continue with default values and modify the config_series.cfg file later if you prefer", + f"{freq}\nFrequency (Number between 1, 8 e.g.(monthly) : 5) default: 1", + f"{formulas_}\n e.g. (Number between 0, 8 e.g.(Level) : 0) default: 0 ", + f"{AggregateType_}\n e.g. ( avg / min / max / first / last / sum ) default: avg", +] + + +def check_valid_answer(items, answer: str): + return answer in items + + +def check_valid_answer_freq(answer: str): + return check_valid_answer(tuple(map(str, range(1, 8))), answer) or answer.strip() == "" + + +def check_valid_answer_formulas_(answer: str): + return check_valid_answer(tuple(map(str, range(0, 9))), answer) or answer.strip() == "" + + +def check_valid_answer_aggr(answer: str): + return check_valid_answer(AggregateType__valid_answers, answer) or answer.strip() == "" + + +default_answer_subject = 'SubjectNotGiven' +default_answers_series = [f"{default_prefix}Data", + default_answer_subject, + default_prefix, + example_codes, + default_freq, + default_formulas_, + default_AggregateType_] +check_funcs_series = [folder_format_check, + TrueFunc, + TrueFunc, + TrueFunc, + check_valid_answer_freq, + check_valid_answer_formulas_, + check_valid_answer_aggr] +# import string +# x = "aa,ab-ac" +# s = x.split() +# +""" Transform Functions """ +same = lambda x: x +trim_string = lambda x: x.strip() +from typing import Tuple + +# import re +# split_items = lambda x: re.split("[,-/\n;]+", x) +split_items = lambda text: tuple(text.translate(text.maketrans({x: "-" for x in "[,-/\n;]~"})).split("-")) +""" Default answers if the user goes with an Empty answer """ + + +def get_default_for_question(answer, question): + obj = { + "folder": f"{default_prefix}Data", + "prefix": default_prefix, + "freq": default_freq, + "formulas": default_formulas_, + "aggr": default_AggregateType_, + "series": example_codes, + "subject": default_answer_subject + } + if not answer.strip(): + """ default returns here """ + return obj.get(question, answer) + + if question == "series": + """item1,item2\nitem3""" + return split_items(answer) + return answer.strip() + + +# instead of functools partial lambda this time +bound_question = lambda question: lambda answer: get_default_for_question(answer, question) +funcs_names = ("folder", "subject", "prefix", "series", "freq", "formulas", "aggr",) +transform_answers_series: Tuple = tuple(map(lambda x: bound_question(x), funcs_names)) diff --git a/evdspy/EVDSlocal/setup_project/user_setup.py b/evdspy/EVDSlocal/setup_project/user_setup.py index 3aea447..605cc15 100644 --- a/evdspy/EVDSlocal/setup_project/user_setup.py +++ b/evdspy/EVDSlocal/setup_project/user_setup.py @@ -1,480 +1,480 @@ -# from ..common.common_imports import * -import time -from dataclasses import dataclass -from collections import namedtuple -from typing import Callable, List, Tuple, Union -from ..common.colors import * - -from evdspy.EVDSlocal.components.options_class import SingletonOptions -from evdspy.EVDSlocal.config.config import * -from evdspy.EVDSlocal.common.files import * -from evdspy.EVDSlocal.setup_project.user_series_config import * -from evdspy.EVDSlocal.setup_project.user_series_config import formulas_dict, frequency_dict -from evdspy.EVDSlocal.setup_project.user_setup_helper import series_title -from evdspy.EVDSlocal.setup_project.user_options_config import items_from_user_config, \ - explanations_config, default_answers_config, check_funcs_options, transform_answers_options - -from evdspy.EVDSlocal.config.config import config -from evdspy.EVDSlocal.initial.start_options import default_cache, default_end_date, default_start_date - -# ----------------------------------------------------SetupInputs--------------------------- - -# ----------------------------------------------------------------------------------------- -# SetupInputsConfig = namedtuple('SetupInputsConfig', 'cache_freq gl_date_start gl_date_end') -# SetupInputsSeries = namedtuple('SetupInputsSeries', -# 'data_folder subject prefix ecodes frequency formulas aggregateType') - -cache_freq = SingletonOptions().options_.default_cache -gl_date_start = SingletonOptions().options_.default_start_date -gl_date_end = SingletonOptions().options_.default_end_date -avoid_absolute_paths = SingletonOptions().options_.avoid_absolute_paths - - -@dataclass -class SetupInputsConfig: - cache_freq: str = SingletonOptions().options_.default_cache - gl_date_start: str = SingletonOptions().options_.default_start_date - gl_date_end: str = SingletonOptions().options_.default_end_date - avoid_absolute_paths: str = SingletonOptions().options_.avoid_absolute_paths - - -@dataclass -class SetupInputsSeries: - data_folder: str - subject: str - prefix: str - ecodes: tuple - frequency: str - formulas: str - aggregateType: str - - -# ----------------------------------------------------------------------------------------- - - -from enum import Enum - - -# ----------------------------------------------------configType--------------------------- -class configType(Enum): - Series = 1 - Config = 2 - - -# ----------------------------------------------------InputItem---------------------- - -@dataclass -class InputItem: - msg: str - long_msg: str = "" - check_func: Callable = TrueFunc - transform_func: Callable = same - optional: bool = True - - # ----------------------------------------------------------------------------------------- - - -""" - GetInputFromUser -""" - -# ----------------------------------------------------------------------------------------- -from abc import ABC, abstractmethod - - -# ----------------------------------------------------GetInputFromUser---------------------- -@dataclass -class GetInputFromUser(ABC): - items: List[InputItem] - config_type: configType - - @abstractmethod - def ask_user(self, msg, check_func): - pass - - @abstractmethod - def get_from_user(self, item, explanation, check_func): - pass - - @abstractmethod - def process(self): - pass - - -@dataclass -class GetInputFromUserBase(): - items: List[InputItem] - config_type: configType - - def ask_user(self, msg, check_func): - ans = input(msg) - if not check_func(ans): - return self.ask_user(msg, check_func) - return ans - - def get_from_user(self, item, explanation, check_func): - window = f"*" * 50 + "\n" - msg = f"{window}**{item} \n {explanation} :" - if config.current_mode_is_test: - return 'pytest running' - # ans = input(msg) - ans = self.ask_user(msg, check_func) - if not ans.strip(): - msg = "==> Continued with default value ..." - print_with_updating_style(msg) - print_with_creating_style(f"{window}") - return str(ans) - - def process(self): - assert config.current_mode_is_test is False, "config.current_mode_is_test is False" - if config.current_mode_is_test: - return get_default_setup_answers(self.config_type) - user_typed: List = [] - for item in self.items: - ans = self.get_from_user(item.msg, item.long_msg, item.check_func) - """ We will transform users answer same / split for now """ - ans = item.transform_func(ans) - - user_typed.append(ans) - - # user_typed = list(map(lambda x: x , user_typed)) - self.user_typed = user_typed - return tuple(user_typed) - - -# ----------------------------------------------------GetInputFromUserConfig---------------------- -@dataclass -class GetInputFromUserConfig(GetInputFromUserBase): - """ GetInputFromUserConfig """ - items: List[InputItem] - config_type: configType = configType.Config - - -# ----------------------------------------------------GetInputFromUserSeries---------------------- -@dataclass -class GetInputFromUserSeries(GetInputFromUserBase): - """ GetInputFromUserSeries """ - items: List[InputItem] - config_type: configType = configType.Series - - -# ----------------------------------------------------create_Input_Items---------------------- -def create_Input_Items( - config_type: configType, - items_from_user: List, explanations: List, - check_funcs: List[Callable], - transform_answers: List[Callable], - -): - items: List[InputItem] = [] - for msg, explanation, check_func, transform_func in zip(items_from_user, explanations, check_funcs, - transform_answers): - items.append( - InputItem( - msg=msg, - long_msg=explanation, - check_func=check_func, - transform_func=transform_func - ) - ) - - GetInputFromUserClassType = { - configType.Series: GetInputFromUserSeries, - configType.Config: GetInputFromUserConfig - }[config_type] - - GIF = GetInputFromUserClassType( - items=items, config_type=config_type - ) - return GIF.process() - - -from evdspy.EVDSlocal.components.evds_seri_files import EvdsSeri - -from typing import List - -from evdspy.EVDSlocal.common.folder_name_checks import check_remove_back_slash - - -# -------------- GOES to Utils ------------------------ -# split_items: any = lambda text : list( -# text.translate(text.maketrans({x: "-" for x in "[,-/\n;]~"})).split("-")) -def split_items_multi(series_list: Union[str, List, Tuple]) -> str: - """ 1.1 """ - - def split_items(series_list) -> tuple: - if isinstance(series_list, tuple([list, tuple])): - return series_list - return tuple(series_list.translate(series_list.maketrans({x: "-" for x in "[,-/\n;]~"})).split("-")) - - """ 1 """ - if isinstance(series_list, str): - if not series_list.strip(): - series_list: list = default_answers_series - else: - series_list: list = list(split_items(series_list)) - if isinstance(series_list, tuple([list, tuple])): - series_list_str: str = "\n".join(series_list) - else: - series_list_str: str = "\n".join(list(split_items(series_list))) - - return series_list_str - - -# -------------- GOES to Utils ------------------------ - -def content_from_SetupInputsSeries(SI: SetupInputsSeries): - """ S E R I E S """ - """ - namedtuple('SetupInputsSeries', 'data_folder subject prefix ecodes frequency formulas aggregateType') - - """ - - def create_content(folder, subject, prefix, series_list: Union[Tuple, List, str]): - folder_path = check_remove_back_slash(folder) - # folder_path_series = str(Path().absolute() / folder / 'series.txt') - abs_path = str(Path().absolute() / folder_path) - - series_list_str: str = split_items_multi(series_list) - - r = f"""{mainSepBegin} -foldername : {folder_path} -abs_path : {abs_path} # will check again before saving requests from the server it may be replaced by ...WD.../DataSeries/{folder_path} -subject : {subject} -prefix : {prefix} -frequency : {SI.frequency} # {frequency_dict[int(SI.frequency)]} -formulas : {SI.formulas} # {formulas_dict[int(SI.formulas)]} -aggregateType : {SI.aggregateType} -------------SERIES CODES------------------ -{series_list_str} -------------/SERIES CODES------------------ -{mainSepEnd} -{GSEP}""" - return r - - return create_content(SI.data_folder, SI.subject, SI.prefix, tuple(SI.ecodes)) - - -def content_from_SetupInputsOptions(SI: SetupInputsConfig): - """ O P T I O N S """ - """ - SetupInputsConfig = namedtuple('SetupInputsConfig', 'cache_freq gl_date_start gl_date_end') - """ - - def get_default(item): - # SingletonOptions().get_valid_value("default_cache") - # SingletonOptions().get_valid_value("default_start_date") - # SingletonOptions().get_valid_value("default_end_date") - - cache_freq = SingletonOptions().options_.default_cache - gl_date_start = SingletonOptions().options_.default_start_date - gl_date_end = SingletonOptions().options_.default_end_date - avoid_absolute_paths = SingletonOptions().options_.avoid_absolute_paths - - # result = SI.__getattribute__(item) - # result = SI.__dict__.get(item, None) - result = getattr(SI, item, None) - if not result: - result = locals()[item] - return result - - def create_content(): - cache_freq = get_default("cache_freq") - gl_date_start = get_default("gl_date_start") - gl_date_end = get_default("gl_date_end") - avoid_absolute_paths = get_default("avoid_absolute_paths") - - """ Options """ - r = f"""#Global Options File -# G L O B A L O P T I O N S F I L E ------------------------------------------------------- -cache_freq : {cache_freq} -gl_date_start : {gl_date_start} -gl_date_end : {gl_date_end} -avoid_absolute_paths : {avoid_absolute_paths} -{GSEP}""" - print(r) - return r - - return create_content() - - -def content_from_SetupInputsSeries_MainFile(SI: SetupInputsSeries): - cont = content_from_SetupInputsSeries(SI) - content = f"{cont}" - return content - - -def content_from_SetupInputsOptions_MainFile(SI: SetupInputsConfig): - cont = content_from_SetupInputsOptions(SI) - content = f"{cont}" - return content - - -# ----------------------------------------------------create_config_series---------------------- -def create_config_series(SI: SetupInputsSeries): - """ Main Aggregated Configuration file for all series """ - config_series_main_file = 'config_series.cfg' - SetupInputsSeriesRepr = content_from_SetupInputsSeries_MainFile(SI) - if not is_file(config_series_main_file): - SetupInputsSeriesRepr = series_title + "\n" + SetupInputsSeriesRepr - WriteAdd(config_series_main_file, SetupInputsSeriesRepr) - - """ Individual Series ( Each call create only one set of series) """ - create_folder(SI.data_folder) - series_file_content = content_from_SetupInputsSeries(SI) - Write(str(Path() / SI.data_folder / 'series.txt'), series_file_content) - return True - - -# ----------------------------------------------------create_config_config---------------------- -def create_config_config(SI: SetupInputsConfig): - """ Main Aggregated Configuration file for all USER OPTIONS """ - config_options_main_file = 'options.cfg' - SetupInputsSeriesRepr = content_from_SetupInputsOptions_MainFile(SI) - Write(config_options_main_file, SetupInputsSeriesRepr) - print_with_creating_style("writing") - print_with_creating_style(SetupInputsSeriesRepr) - return True - - -# ---------------------------------------------------- ---------------------- - -def get_item_for_config_type(obj, config_type): - return obj[config_type] - - -# ---------------------------------------------------- InputType ---------------------- - -@dataclass -class InputType: - items_from_user: list - explanations: list - check_funcs: list - transform_answers: Union[List[callable], Tuple[callable]] - applyFunc: Callable # not from config - SetupInputs: any # ... - - -# ----------------------------------------------------start_setup---------------------- - - -def start_setup( - config_type: configType = configType.Series, - onsetup: bool = False, -): - # assert config_type == configType.Series, "config_type not configType.Series " - """ S E R I E S """ - Series_obj = InputType( - items_from_user_series, - explanations_series, - check_funcs_series, - transform_answers_series, - create_config_series, - SetupInputsSeries - ) - - """ O P T I O N S """ - Config_obj = InputType( - items_from_user_config, - explanations_config, - check_funcs_options, - transform_answers_options, - create_config_config, - SetupInputsConfig - ) - - instance = {configType.Config: Config_obj, configType.Series: Series_obj}[config_type] - if not onsetup: - CIS = create_Input_Items(config_type, instance.items_from_user, instance.explanations, instance.check_funcs, - instance.transform_answers) - print_with_creating_style(CIS) - else: - - CIS = tuple("" for _ in items_from_user_config) - - instance.applyFunc(instance.SetupInputs(*CIS)) - - -# ----------------------------------------------------start_setup_series---------------------- - -def start_setup_series(): - msg = f""" - - This process is going to add new series to your configuration file (config_series.cfg).... - - Program will ask couple of questions to complete your series block on your file. - - Pressing `Enter` will accept for default values for the questions. - You may update all information later by opening file with your favorite file editor. - -------------------------------------- - - -""" - - print_with_creating_style(msg) - time.sleep(1) - start_setup(configType.Series) - return True - - -# ----------------------------------------------------start_setup_config---------------------- - - -def start_setup_config(onsetup=False): - file_name_options = "options.cfg" - msg = f""" - This process is going to create user options file (options.cfg).... - You may also update all info by opening file with your favorite file editor. - -------------------------------------- - Program will ask couple of questions to complete your options on your file. - - """ - if onsetup: - msg = f""" - creating `{file_name_options}` -""" - - if file_exists_show_and_return(file_name_options): - return - print_with_creating_style(msg) - time.sleep(1) - start_setup(configType.Config, onsetup) - return True - - -# ----------------------------------------------------------------------------------------- -""" - default_setup -""" - - -# ----------------------------------------------------------------------------------------- - - -def get_default_setup_answers(config_type: configType = configType.Config): - default_answers = { - configType.Series: default_answers_series, - configType.Config: default_answers_config - }[config_type] - return default_answers - - -def default_setup(config_type: configType = configType.Config): - print_with_updating_style("Default setup starting....") - - CIS = get_default_setup_answers(config_type) - create_config_series(SetupInputsSeries(*CIS)) - return True - - -__all__ = [ - 'default_setup', - 'create_config_series', - 'start_setup_series', - 'default_setup', - 'folder_creatable_by_adding', - 'folder_format_check', - 'folder_creatable', - 'get_default_setup_answers' - -] +# from ..common.common_imports import * +import time +from dataclasses import dataclass +from collections import namedtuple +from typing import Callable, List, Tuple, Union +from ..common.colors import * + +from evdspy.EVDSlocal.components.options_class import SingletonOptions +from evdspy.EVDSlocal.config.config import * +from evdspy.EVDSlocal.common.files import * +from evdspy.EVDSlocal.setup_project.user_series_config import * +from evdspy.EVDSlocal.setup_project.user_series_config import formulas_dict, frequency_dict +from evdspy.EVDSlocal.setup_project.user_setup_helper import series_title +from evdspy.EVDSlocal.setup_project.user_options_config import items_from_user_config, \ + explanations_config, default_answers_config, check_funcs_options, transform_answers_options + +from evdspy.EVDSlocal.config.config import config +from evdspy.EVDSlocal.initial.start_options import default_cache, default_end_date, default_start_date + +# ----------------------------------------------------SetupInputs--------------------------- + +# ----------------------------------------------------------------------------------------- +# SetupInputsConfig = namedtuple('SetupInputsConfig', 'cache_freq gl_date_start gl_date_end') +# SetupInputsSeries = namedtuple('SetupInputsSeries', +# 'data_folder subject prefix ecodes frequency formulas aggregateType') + +cache_freq = SingletonOptions().options_.default_cache +gl_date_start = SingletonOptions().options_.default_start_date +gl_date_end = SingletonOptions().options_.default_end_date +avoid_absolute_paths = SingletonOptions().options_.avoid_absolute_paths + + +@dataclass +class SetupInputsConfig: + cache_freq: str = SingletonOptions().options_.default_cache + gl_date_start: str = SingletonOptions().options_.default_start_date + gl_date_end: str = SingletonOptions().options_.default_end_date + avoid_absolute_paths: str = SingletonOptions().options_.avoid_absolute_paths + + +@dataclass +class SetupInputsSeries: + data_folder: str + subject: str + prefix: str + ecodes: tuple + frequency: str + formulas: str + aggregateType: str + + +# ----------------------------------------------------------------------------------------- + + +from enum import Enum + + +# ----------------------------------------------------configType--------------------------- +class configType(Enum): + Series = 1 + Config = 2 + + +# ----------------------------------------------------InputItem---------------------- + +@dataclass +class InputItem: + msg: str + long_msg: str = "" + check_func: Callable = TrueFunc + transform_func: Callable = same + optional: bool = True + + # ----------------------------------------------------------------------------------------- + + +""" + GetInputFromUser +""" + +# ----------------------------------------------------------------------------------------- +from abc import ABC, abstractmethod + + +# ----------------------------------------------------GetInputFromUser---------------------- +@dataclass +class GetInputFromUser(ABC): + items: List[InputItem] + config_type: configType + + @abstractmethod + def ask_user(self, msg, check_func): + pass + + @abstractmethod + def get_from_user(self, item, explanation, check_func): + pass + + @abstractmethod + def process(self): + pass + + +@dataclass +class GetInputFromUserBase(): + items: List[InputItem] + config_type: configType + + def ask_user(self, msg, check_func): + ans = input(msg) + if not check_func(ans): + return self.ask_user(msg, check_func) + return ans + + def get_from_user(self, item, explanation, check_func): + window = f"*" * 50 + "\n" + msg = f"{window}**{item} \n {explanation} :" + if config.current_mode_is_test: + return 'pytest running' + # ans = input(msg) + ans = self.ask_user(msg, check_func) + if not ans.strip(): + msg = "==> Continued with default value ..." + print_with_updating_style(msg) + print_with_creating_style(f"{window}") + return str(ans) + + def process(self): + assert config.current_mode_is_test is False, "config.current_mode_is_test is False" + if config.current_mode_is_test: + return get_default_setup_answers(self.config_type) + user_typed: List = [] + for item in self.items: + ans = self.get_from_user(item.msg, item.long_msg, item.check_func) + """ We will transform users answer same / split for now """ + ans = item.transform_func(ans) + + user_typed.append(ans) + + # user_typed = list(map(lambda x: x , user_typed)) + self.user_typed = user_typed + return tuple(user_typed) + + +# ----------------------------------------------------GetInputFromUserConfig---------------------- +@dataclass +class GetInputFromUserConfig(GetInputFromUserBase): + """ GetInputFromUserConfig """ + items: List[InputItem] + config_type: configType = configType.Config + + +# ----------------------------------------------------GetInputFromUserSeries---------------------- +@dataclass +class GetInputFromUserSeries(GetInputFromUserBase): + """ GetInputFromUserSeries """ + items: List[InputItem] + config_type: configType = configType.Series + + +# ----------------------------------------------------create_Input_Items---------------------- +def create_Input_Items( + config_type: configType, + items_from_user: List, explanations: List, + check_funcs: List[Callable], + transform_answers: List[Callable], + +): + items: List[InputItem] = [] + for msg, explanation, check_func, transform_func in zip(items_from_user, explanations, check_funcs, + transform_answers): + items.append( + InputItem( + msg=msg, + long_msg=explanation, + check_func=check_func, + transform_func=transform_func + ) + ) + + GetInputFromUserClassType = { + configType.Series: GetInputFromUserSeries, + configType.Config: GetInputFromUserConfig + }[config_type] + + GIF = GetInputFromUserClassType( + items=items, config_type=config_type + ) + return GIF.process() + + +from evdspy.EVDSlocal.components.evds_seri_files import EvdsSeri + +from typing import List + +from evdspy.EVDSlocal.common.folder_name_checks import check_remove_back_slash + + +# -------------- GOES to Utils ------------------------ +# split_items: any = lambda text : list( +# text.translate(text.maketrans({x: "-" for x in "[,-/\n;]~"})).split("-")) +def split_items_multi(series_list: Union[str, List, Tuple]) -> str: + """ 1.1 """ + + def split_items(series_list) -> tuple: + if isinstance(series_list, tuple([list, tuple])): + return series_list + return tuple(series_list.translate(series_list.maketrans({x: "-" for x in "[,-/\n;]~"})).split("-")) + + """ 1 """ + if isinstance(series_list, str): + if not series_list.strip(): + series_list: list = default_answers_series + else: + series_list: list = list(split_items(series_list)) + if isinstance(series_list, tuple([list, tuple])): + series_list_str: str = "\n".join(series_list) + else: + series_list_str: str = "\n".join(list(split_items(series_list))) + + return series_list_str + + +# -------------- GOES to Utils ------------------------ + +def content_from_SetupInputsSeries(SI: SetupInputsSeries): + """ S E R I E S """ + """ + namedtuple('SetupInputsSeries', 'data_folder subject prefix ecodes frequency formulas aggregateType') + + """ + + def create_content(folder, subject, prefix, series_list: Union[Tuple, List, str]): + folder_path = check_remove_back_slash(folder) + # folder_path_series = str(Path().absolute() / folder / 'series.txt') + abs_path = str(Path().absolute() / folder_path) + + series_list_str: str = split_items_multi(series_list) + + r = f"""{mainSepBegin} +foldername : {folder_path} +abs_path : {abs_path} # will check again before saving requests from the server it may be replaced by ...WD.../DataSeries/{folder_path} +subject : {subject} +prefix : {prefix} +frequency : {SI.frequency} # {frequency_dict[int(SI.frequency)]} +formulas : {SI.formulas} # {formulas_dict[int(SI.formulas)]} +aggregateType : {SI.aggregateType} +------------SERIES CODES------------------ +{series_list_str} +------------/SERIES CODES------------------ +{mainSepEnd} +{GSEP}""" + return r + + return create_content(SI.data_folder, SI.subject, SI.prefix, tuple(SI.ecodes)) + + +def content_from_SetupInputsOptions(SI: SetupInputsConfig): + """ O P T I O N S """ + """ + SetupInputsConfig = namedtuple('SetupInputsConfig', 'cache_freq gl_date_start gl_date_end') + """ + + def get_default(item): + # SingletonOptions().get_valid_value("default_cache") + # SingletonOptions().get_valid_value("default_start_date") + # SingletonOptions().get_valid_value("default_end_date") + + cache_freq = SingletonOptions().options_.default_cache + gl_date_start = SingletonOptions().options_.default_start_date + gl_date_end = SingletonOptions().options_.default_end_date + avoid_absolute_paths = SingletonOptions().options_.avoid_absolute_paths + + # result = SI.__getattribute__(item) + # result = SI.__dict__.get(item, None) + result = getattr(SI, item, None) + if not result: + result = locals()[item] + return result + + def create_content(): + cache_freq = get_default("cache_freq") + gl_date_start = get_default("gl_date_start") + gl_date_end = get_default("gl_date_end") + avoid_absolute_paths = get_default("avoid_absolute_paths") + + """ Options """ + r = f"""#Global Options File +# G L O B A L O P T I O N S F I L E ------------------------------------------------------- +cache_freq : {cache_freq} +gl_date_start : {gl_date_start} +gl_date_end : {gl_date_end} +avoid_absolute_paths : {avoid_absolute_paths} +{GSEP}""" + print(r) + return r + + return create_content() + + +def content_from_SetupInputsSeries_MainFile(SI: SetupInputsSeries): + cont = content_from_SetupInputsSeries(SI) + content = f"{cont}" + return content + + +def content_from_SetupInputsOptions_MainFile(SI: SetupInputsConfig): + cont = content_from_SetupInputsOptions(SI) + content = f"{cont}" + return content + + +# ----------------------------------------------------create_config_series---------------------- +def create_config_series(SI: SetupInputsSeries): + """ Main Aggregated Configuration file for all series """ + config_series_main_file = 'config_series.cfg' + SetupInputsSeriesRepr = content_from_SetupInputsSeries_MainFile(SI) + if not is_file(config_series_main_file): + SetupInputsSeriesRepr = series_title + "\n" + SetupInputsSeriesRepr + WriteAdd(config_series_main_file, SetupInputsSeriesRepr) + + """ Individual Series ( Each call create only one set of series) """ + create_folder(SI.data_folder) + series_file_content = content_from_SetupInputsSeries(SI) + Write(str(Path() / SI.data_folder / 'series.txt'), series_file_content) + return True + + +# ----------------------------------------------------create_config_config---------------------- +def create_config_config(SI: SetupInputsConfig): + """ Main Aggregated Configuration file for all USER OPTIONS """ + config_options_main_file = 'options.cfg' + SetupInputsSeriesRepr = content_from_SetupInputsOptions_MainFile(SI) + Write(config_options_main_file, SetupInputsSeriesRepr) + print_with_creating_style("writing") + print_with_creating_style(SetupInputsSeriesRepr) + return True + + +# ---------------------------------------------------- ---------------------- + +def get_item_for_config_type(obj, config_type): + return obj[config_type] + + +# ---------------------------------------------------- InputType ---------------------- + +@dataclass +class InputType: + items_from_user: list + explanations: list + check_funcs: list + transform_answers: Union[List[callable], Tuple[callable]] + applyFunc: Callable # not from config + SetupInputs: any # ... + + +# ----------------------------------------------------start_setup---------------------- + + +def start_setup( + config_type: configType = configType.Series, + onsetup: bool = False, +): + # assert config_type == configType.Series, "config_type not configType.Series " + """ S E R I E S """ + Series_obj = InputType( + items_from_user_series, + explanations_series, + check_funcs_series, + transform_answers_series, + create_config_series, + SetupInputsSeries + ) + + """ O P T I O N S """ + Config_obj = InputType( + items_from_user_config, + explanations_config, + check_funcs_options, + transform_answers_options, + create_config_config, + SetupInputsConfig + ) + + instance = {configType.Config: Config_obj, configType.Series: Series_obj}[config_type] + if not onsetup: + CIS = create_Input_Items(config_type, instance.items_from_user, instance.explanations, instance.check_funcs, + instance.transform_answers) + print_with_creating_style(CIS) + else: + + CIS = tuple("" for _ in items_from_user_config) + + instance.applyFunc(instance.SetupInputs(*CIS)) + + +# ----------------------------------------------------start_setup_series---------------------- + +def start_setup_series(): + msg = f""" + + This process is going to add new series to your configuration file (config_series.cfg).... + + Program will ask couple of questions to complete your series block on your file. + + Pressing `Enter` will accept for default values for the questions. + You may update all information later by opening file with your favorite file editor. + -------------------------------------- + + +""" + + print_with_creating_style(msg) + time.sleep(1) + start_setup(configType.Series) + return True + + +# ----------------------------------------------------start_setup_config---------------------- + + +def start_setup_config(onsetup=False): + file_name_options = "options.cfg" + msg = f""" + This process is going to create user options file (options.cfg).... + You may also update all info by opening file with your favorite file editor. + -------------------------------------- + Program will ask couple of questions to complete your options on your file. + + """ + if onsetup: + msg = f""" + creating `{file_name_options}` +""" + + if file_exists_show_and_return(file_name_options): + return + print_with_creating_style(msg) + time.sleep(1) + start_setup(configType.Config, onsetup) + return True + + +# ----------------------------------------------------------------------------------------- +""" + default_setup +""" + + +# ----------------------------------------------------------------------------------------- + + +def get_default_setup_answers(config_type: configType = configType.Config): + default_answers = { + configType.Series: default_answers_series, + configType.Config: default_answers_config + }[config_type] + return default_answers + + +def default_setup(config_type: configType = configType.Config): + print_with_updating_style("Default setup starting....") + + CIS = get_default_setup_answers(config_type) + create_config_series(SetupInputsSeries(*CIS)) + return True + + +__all__ = [ + 'default_setup', + 'create_config_series', + 'start_setup_series', + 'default_setup', + 'folder_creatable_by_adding', + 'folder_format_check', + 'folder_creatable', + 'get_default_setup_answers' + +] diff --git a/evdspy/EVDSlocal/setup_project/user_setup_helper.py b/evdspy/EVDSlocal/setup_project/user_setup_helper.py index ddbff31..b6260d3 100644 --- a/evdspy/EVDSlocal/setup_project/user_setup_helper.py +++ b/evdspy/EVDSlocal/setup_project/user_setup_helper.py @@ -1,27 +1,27 @@ -from evdspy.EVDSlocal.setup_project.user_series_config import quickNoteForParams - - -def add_indent(content): - quickNoteForParamsLines = content.split("\n") - quickNoteForParamsLines = (" " * 10 + x for x in quickNoteForParamsLines) - content = "\n".join(quickNoteForParamsLines) - return content - - -quickNoteForParams = add_indent(quickNoteForParams) -series_title = f"""#Series_config_file -E V D S P Y _ C O N F I G _ F I L E --------------------------------------------- -# -# This file will be used by evdspy package (python) in order to help updating -# your series. -# Script will be adding to it content when you setup a new project. -# Deleting this file current file may require to setup a new configuration from the beginning -# please see `README.md` file -# ---------------------------------------------------------------------------------------- -# -#About alternative params -# ---------------------------------------------------------------------------------------- - -{quickNoteForParams} -#Begin_series -""" +from evdspy.EVDSlocal.setup_project.user_series_config import quickNoteForParams + + +def add_indent(content): + quickNoteForParamsLines = content.split("\n") + quickNoteForParamsLines = (" " * 10 + x for x in quickNoteForParamsLines) + content = "\n".join(quickNoteForParamsLines) + return content + + +quickNoteForParams = add_indent(quickNoteForParams) +series_title = f"""#Series_config_file +E V D S P Y _ C O N F I G _ F I L E --------------------------------------------- +# +# This file will be used by evdspy package (python) in order to help updating +# your series. +# Script will be adding to it content when you setup a new project. +# Deleting this file current file may require to setup a new configuration from the beginning +# please see `README.md` file +# ---------------------------------------------------------------------------------------- +# +#About alternative params +# ---------------------------------------------------------------------------------------- + +{quickNoteForParams} +#Begin_series +""" diff --git a/evdspy/EVDSlocal/state/current_state.py b/evdspy/EVDSlocal/state/current_state.py index b8a81c0..3a48f35 100644 --- a/evdspy/EVDSlocal/state/current_state.py +++ b/evdspy/EVDSlocal/state/current_state.py @@ -1,45 +1,45 @@ -from dataclasses import dataclass -from rich import pretty - - -@dataclass -class CurrentState: - """ Global State to check loaded funcstions - and other global variables """ - - def __new__(cls, *args, **kwargs): - if not hasattr(cls, 'instance'): - cls.instance = super(CurrentState, cls).__new__(cls) - cls.set_state_on_load(cls) - cls.set_result_dict(cls) - cls.initial_sets(cls) - return cls.instance - - def initial_sets(cls): - cls.menu_will_open = False - - def set_state_on_load(cls, attr="loaded_menu_on_load", value=True): - cls.loaded_menu_on_load = False - - - def set_state(cls, attr="loaded_menu_on_load", value=True): - cls.__setattr__(attr, value) - # self.loaded_menu_on_load = False - - def set_result_dict(cls, attr=None, value=None): - if attr is None: - result = {} - cls.result = result - else: - cls.result.update({attr: value}) - - def get_result_dict(cls, id=None) -> [dict, any]: - if id is None: - result = cls.result - else: - result = cls.result.get(id, None) - return result - - def __repr__(cls): - return pretty.Pretty(cls.result) - # return f"CurrentState:{cls.result}" +from dataclasses import dataclass +from rich import pretty + + +@dataclass +class CurrentState: + """ Global State to check loaded functions + and other global variables """ + + def __new__(cls, *args, **kwargs): + if not hasattr(cls, 'instance'): + cls.instance = super(CurrentState, cls).__new__(cls) + cls.set_state_on_load(cls) + cls.set_result_dict(cls) + cls.initial_sets(cls) + return cls.instance + + def initial_sets(cls): + cls.menu_will_open = False + + def set_state_on_load(cls, attr="loaded_menu_on_load", value=True): + cls.loaded_menu_on_load = False + + + def set_state(cls, attr="loaded_menu_on_load", value=True): + cls.__setattr__(attr, value) + # self.loaded_menu_on_load = False + + def set_result_dict(cls, attr=None, value=None): + if attr is None: + result = {} + cls.result = result + else: + cls.result.update({attr: value}) + + def get_result_dict(cls, id=None) -> [dict, any]: + if id is None: + result = cls.result + else: + result = cls.result.get(id, None) + return result + + def __repr__(cls): + return pretty.Pretty(cls.result) + # return f"CurrentState:{cls.result}" diff --git a/evdspy/EVDSlocal/state/test_or_real.py b/evdspy/EVDSlocal/state/test_or_real.py index d388156..b9d5fdb 100644 --- a/evdspy/EVDSlocal/state/test_or_real.py +++ b/evdspy/EVDSlocal/state/test_or_real.py @@ -1,14 +1,14 @@ -from ..common.common_imports import * -from pathlib import Path - - -def check_if_this_is_pytest(): - def check(): - path_ = Path(sys.argv[0]) - return "pytest" in str(path_.stem) - - if len(sys.argv) > 0 and check(): - return True - else: - - return False +from ..common.common_imports import * +from pathlib import Path + + +def check_if_this_is_pytest(): + def check(): + path_ = Path(sys.argv[0]) + return "pytest" in str(path_.stem) + + if len(sys.argv) > 0 and check(): + return True + else: + + return False diff --git a/evdspy/EVDSlocal/stats/save_stats_of_requests.py b/evdspy/EVDSlocal/stats/save_stats_of_requests.py index cac98fc..d49939e 100644 --- a/evdspy/EVDSlocal/stats/save_stats_of_requests.py +++ b/evdspy/EVDSlocal/stats/save_stats_of_requests.py @@ -1,25 +1,25 @@ -from evdspy.EVDSlocal.common.files import * -from dataclasses import dataclass, field - -from datetime import datetime - - -@dataclass -class Report: - file_name: str = "stats_report.txt" - - @property - def date_content(self): - now = datetime.now() - - current_time = now.strftime("%Y-%m-%d %H:%M:%S") - return current_time - - def add(self, content): - content = f"{self.date_content} => {content}" - WriteAdd(self.file_name, content) - - -def report_test(): - r = Report(file_name="test_stats_report.txt") +from evdspy.EVDSlocal.common.files import * +from dataclasses import dataclass, field + +from datetime import datetime + + +@dataclass +class Report: + file_name: str = "stats_report.txt" + + @property + def date_content(self): + now = datetime.now() + + current_time = now.strftime("%Y-%m-%d %H:%M:%S") + return current_time + + def add(self, content): + content = f"{self.date_content} => {content}" + WriteAdd(self.file_name, content) + + +def report_test(): + r = Report(file_name="test_stats_report.txt") r.add("content") \ No newline at end of file diff --git a/evdspy/EVDSlocal/tests/core_options_test.py b/evdspy/EVDSlocal/tests/core_options_test.py index 7313ad3..b764373 100644 --- a/evdspy/EVDSlocal/tests/core_options_test.py +++ b/evdspy/EVDSlocal/tests/core_options_test.py @@ -1,2 +1,2 @@ -""" Test Options """ -verbose = False +""" Test Options """ +verbose = False diff --git a/evdspy/EVDSlocal/tests/test_apikey_checks.py b/evdspy/EVDSlocal/tests/test_apikey_checks.py index df07096..acdae7b 100644 --- a/evdspy/EVDSlocal/tests/test_apikey_checks.py +++ b/evdspy/EVDSlocal/tests/test_apikey_checks.py @@ -1,6 +1,6 @@ -from evdspy.EVDSlocal.requests_.lower_energy import apikey_works - - -def test_apikey_worksM(): - assert apikey_works("s1") is True, "s1 is not True" - assert apikey_works("f1") is False, "s1 is not True" +from evdspy.EVDSlocal.requests_.lower_energy import apikey_works + + +def test_apikey_worksM(): + assert apikey_works("s1") is True, "s1 is not True" + assert apikey_works("f1") is False, "s1 is not True" diff --git a/evdspy/EVDSlocal/tests/test_categories.py b/evdspy/EVDSlocal/tests/test_categories.py index a877659..fc4ddc8 100644 --- a/evdspy/EVDSlocal/tests/test_categories.py +++ b/evdspy/EVDSlocal/tests/test_categories.py @@ -1,23 +1,23 @@ -from ..index_requests.categories import get_categories -from ..index_requests.datagroups import get_datagroups -from ..tests.core_options_test import verbose - - -# def test_get_categories(capsys): -# with capsys.disabled(): -# a = get_categories() -# if verbose : -# print(a) -# -# -# def test_get_datagroups(capsys): -# with capsys.disabled(): -# a = get_datagroups() -# if verbose : -# print(a) -def test_get_categories(capsys): - get_categories() - - -def test_get_datagroups(capsys): - get_datagroups() +from ..index_requests.categories import get_categories +from ..index_requests.datagroups import get_datagroups +from ..tests.core_options_test import verbose + + +# def test_get_categories(capsys): +# with capsys.disabled(): +# a = get_categories() +# if verbose : +# print(a) +# +# +# def test_get_datagroups(capsys): +# with capsys.disabled(): +# a = get_datagroups() +# if verbose : +# print(a) +def test_get_categories(capsys): + get_categories() + + +def test_get_datagroups(capsys): + get_datagroups() diff --git a/evdspy/EVDSlocal/tests/test_datagroups.py b/evdspy/EVDSlocal/tests/test_datagroups.py index 749d646..2fc21b5 100644 --- a/evdspy/EVDSlocal/tests/test_datagroups.py +++ b/evdspy/EVDSlocal/tests/test_datagroups.py @@ -1,7 +1,7 @@ -from evdspy.EVDSlocal.index_requests.datagroups import get_keys - - -def test_get_keys(capsys): - with capsys.disabled(): - coming = get_keys() - print(coming) +from evdspy.EVDSlocal.index_requests.datagroups import get_keys + + +def test_get_keys(capsys): + with capsys.disabled(): + coming = get_keys() + print(coming) diff --git a/evdspy/EVDSlocal/tests/test_evds_classes.py b/evdspy/EVDSlocal/tests/test_evds_classes.py index 6609f2a..c5ba6ff 100644 --- a/evdspy/EVDSlocal/tests/test_evds_classes.py +++ b/evdspy/EVDSlocal/tests/test_evds_classes.py @@ -1,61 +1,61 @@ -import sys - -from ..components.evds_files import * -from ..components.evds_seri_files import test_series_ -from ..utils.utils_general import * -from ..initial.start_args import Args -from ..components.options_class import Options, load_options -from ..config.apikey_class import * - -#from ...main import * - -options_ = load_options() -args = Args(sys.argv) -test_evds = EvdsSorgu( - options_=options_, - session=None, - series_=test_series_, - file_name='pytest_req', - args=args -) -test_evds_series = EvdsSorguSeries( - options_, - session=None, - series_=test_series_, - file_name='pytest_req', - args=args -) - - - - -def test_create_class(): - assert test_evds is not None, "test_evds not created" - - -# def test_evds_save_excel(): -# assert test_evds.kaydet_excel() is True, "test_evds not created" -# -# -# def test_test_evds_series_save_excel(): -# assert test_evds_series.kaydet_excel() is True, "test_evds not created" -# -# -# def test_test_evds_series_save_excel_returns_smt(): -# assert test_evds_series.kaydet_excel() in [True, False], "test_evds not created" -# -folder = get_current_dir() - - - -def test_get_proxy_from_file(): - assert get_proxy_from_file( - folder / ".." / "tests" / r"test.proxy.txt") == "http://proxy.example.com", "Proxy test failed" - - -def test_get_api_key(): - assert get_api_key_from_file(folder / ".." / "tests" / r"test.api.txt") == "testApiKey", "Api key test failed" - - -def test_global_var_api_key(): - assert isinstance(global_var_api_key(), str) +import sys + +from ..components.evds_files import * +from ..components.evds_seri_files import test_series_ +from ..utils.utils_general import * +from ..initial.start_args import Args +from ..components.options_class import Options, load_options +from ..config.apikey_class import * + +#from ...main import * + +options_ = load_options() +args = Args(sys.argv) +test_evds = EvdsSorgu( + options_=options_, + session=None, + series_=test_series_, + file_name='pytest_req', + args=args +) +test_evds_series = EvdsSorguSeries( + options_, + session=None, + series_=test_series_, + file_name='pytest_req', + args=args +) + + + + +def test_create_class(): + assert test_evds is not None, "test_evds not created" + + +# def test_evds_save_excel(): +# assert test_evds.kaydet_excel() is True, "test_evds not created" +# +# +# def test_test_evds_series_save_excel(): +# assert test_evds_series.kaydet_excel() is True, "test_evds not created" +# +# +# def test_test_evds_series_save_excel_returns_smt(): +# assert test_evds_series.kaydet_excel() in [True, False], "test_evds not created" +# +folder = get_current_dir() + + + +def test_get_proxy_from_file(): + assert get_proxy_from_file( + folder / ".." / "tests" / r"test.proxy.txt") == "http://proxy.example.com", "Proxy test failed" + + +def test_get_api_key(): + assert get_api_key_from_file(folder / ".." / "tests" / r"test.api.txt") == "testApiKey", "Api key test failed" + + +def test_global_var_api_key(): + assert isinstance(global_var_api_key(), str) diff --git a/evdspy/EVDSlocal/tests/test_log_session.py b/evdspy/EVDSlocal/tests/test_log_session.py index 4a1d2b4..81fd108 100644 --- a/evdspy/EVDSlocal/tests/test_log_session.py +++ b/evdspy/EVDSlocal/tests/test_log_session.py @@ -1,15 +1,15 @@ -import evdspy -from evdspy.EVDSlocal.session.session_ import * -from evdspy.EVDSlocal.log_classes.log_template import * - -session = get_session() - - -def test_get_session(capsys): - s = get_session() - # with capsys.disabled(): - # print(f"\nSession : {s.hash}") - - -def test_log(): - deb, deb2, debug = get_debugger() +import evdspy +from evdspy.EVDSlocal.session.session_ import * +from evdspy.EVDSlocal.log_classes.log_template import * + +session = get_session() + + +def test_get_session(capsys): + s = get_session() + # with capsys.disabled(): + # print(f"\nSession : {s.hash}") + + +def test_log(): + deb, deb2, debug = get_debugger() diff --git a/evdspy/EVDSlocal/tests/test_main_cmd.py b/evdspy/EVDSlocal/tests/test_main_cmd.py index f0cb679..def7b5a 100644 --- a/evdspy/EVDSlocal/tests/test_main_cmd.py +++ b/evdspy/EVDSlocal/tests/test_main_cmd.py @@ -1,19 +1,19 @@ -import evdspy -from evdspy.EVDSlocal.main_ import * - -def test_check(): - assert callable(check) - check() - -def test_get(): - assert callable(get) - get() - -def test_help_(): - assert callable(help_) - help_() - -def test_menu(): - assert callable(menu) - menu() - +import evdspy +from evdspy.EVDSlocal.main_ import * + +def test_check(): + assert callable(check) + check() + +def test_get(): + assert callable(get) + get() + +def test_help_(): + assert callable(help_) + help_() + +def test_menu(): + assert callable(menu) + menu() + diff --git a/evdspy/EVDSlocal/tests/test_main_load.py b/evdspy/EVDSlocal/tests/test_main_load.py index c449f42..9ae8845 100644 --- a/evdspy/EVDSlocal/tests/test_main_load.py +++ b/evdspy/EVDSlocal/tests/test_main_load.py @@ -1,35 +1,35 @@ -import evdspy -from evdspy.EVDSlocal.main_ import * - -def test_load_general(): - assert callable(setup_series), "setup_series is not callable" - assert callable(help_), "help_ is not callable" - - -def test_setup_now(): - # evdspy.setup_now() - # evdspy.help_() - # evdspy.check() - easy_setup() - get() - - -from evdspy.EVDSlocal.config.apikey_class import ApikeyClass - - -def test_set_apikey(): - assert ApikeyClass().set_api_key_filetype(value="test") == "test", "set api key did not work" - assert ApikeyClass().set_api_key_runtime(value="testruntime") == "testruntime", "set api key did not work" - - -def test_get_apikey(): - assert ApikeyClass().set_api_key_filetype(value="test") == "test", "get api key did not work" - assert ApikeyClass().get_api_key_fromfile() == "test", "get api key did not work" - assert ApikeyClass().set_api_key_filetype("test3") == "test3", "set api key did not work" - assert ApikeyClass().get_api_key_fromfile() == "test3", "get api3 key did not work" - assert ApikeyClass().get_api_key_runtime() == "testruntime", "get testruntime key did not work" - -def test_valid_key(): - assert ApikeyClass().set_api_key_filetype(value="thatisfromFile") == "thatisfromFile", "get api key did not work" - ApikeyClass().now_testing_is_key_is_valid = "thisisValid" - # assert ApikeyClass().get_valid_api_key() == "thisisValid", "get thisisValid key did not work" +import evdspy +from evdspy.EVDSlocal.main_ import * + +def test_load_general(): + assert callable(setup_series), "setup_series is not callable" + assert callable(help_), "help_ is not callable" + + +def test_setup_now(): + # evdspy.setup_now() + # evdspy.help_() + # evdspy.check() + easy_setup() + get() + + +from evdspy.EVDSlocal.config.apikey_class import ApikeyClass + + +def test_set_apikey(): + assert ApikeyClass().set_api_key_filetype(value="test") == "test", "set api key did not work" + assert ApikeyClass().set_api_key_runtime(value="testruntime") == "testruntime", "set api key did not work" + + +def test_get_apikey(): + assert ApikeyClass().set_api_key_filetype(value="test") == "test", "get api key did not work" + assert ApikeyClass().get_api_key_fromfile() == "test", "get api key did not work" + assert ApikeyClass().set_api_key_filetype("test3") == "test3", "set api key did not work" + assert ApikeyClass().get_api_key_fromfile() == "test3", "get api3 key did not work" + assert ApikeyClass().get_api_key_runtime() == "testruntime", "get testruntime key did not work" + +def test_valid_key(): + assert ApikeyClass().set_api_key_filetype(value="thatisfromFile") == "thatisfromFile", "get api key did not work" + ApikeyClass().now_testing_is_key_is_valid = "thisisValid" + # assert ApikeyClass().get_valid_api_key() == "thisisValid", "get thisisValid key did not work" diff --git a/evdspy/EVDSlocal/tests/test_manual_series.py b/evdspy/EVDSlocal/tests/test_manual_series.py index 619a48f..cbd571a 100644 --- a/evdspy/EVDSlocal/tests/test_manual_series.py +++ b/evdspy/EVDSlocal/tests/test_manual_series.py @@ -1,13 +1,13 @@ - -from evdspy.EVDSlocal.requests_.ev_request import * - -from ..tests.core_options_test import * - - -from evdspy.EVDSlocal.manual_requests.prepare import PrepareUrl - -def test_prep(capsys): - p = PrepareUrl(series=('TP_ODEMGZS_NORVEC-8',), api_key='api_key') - # with capsys.disabled(): - # p = PrepareUrl(series=('TP_ODEMGZS_NORVEC-8',), api_key='api_key') - # #print(p.get_data()) + +from evdspy.EVDSlocal.requests_.ev_request import * + +from ..tests.core_options_test import * + + +from evdspy.EVDSlocal.manual_requests.prepare import PrepareUrl + +def test_prep(capsys): + p = PrepareUrl(series=('TP_ODEMGZS_NORVEC-8',), api_key='api_key') + # with capsys.disabled(): + # p = PrepareUrl(series=('TP_ODEMGZS_NORVEC-8',), api_key='api_key') + # #print(p.get_data()) diff --git a/evdspy/EVDSlocal/tests/test_project_setup.py b/evdspy/EVDSlocal/tests/test_project_setup.py index 4168206..2103aaa 100644 --- a/evdspy/EVDSlocal/tests/test_project_setup.py +++ b/evdspy/EVDSlocal/tests/test_project_setup.py @@ -1,49 +1,49 @@ -import evdspy -from evdspy.EVDSlocal.series_format.series_creator import * -from evdspy.EVDSlocal.components.evds_seri_files import * -from evdspy.EVDSlocal.setup_project.user_setup import start_setup_series, create_config_series, SetupInputsSeries, \ - start_setup_config, folder_format_check, folder_creatable, folder_creatable_by_adding, default_setup, \ - get_default_setup_answers, configType - -from ..tests.core_options_test import * - - -# from evdspy.EVDSlocal.setup_project.user_setup import * - - -def test_start_setup(capsys): - - CIS = get_default_setup_answers(configType.Series) - with capsys.disabled(): - if verbose: - print(SetupInputsSeries(*CIS).__class__.__name__) - # print(type(SetupInputsSeries(*CIS))) - ... - assert "SetupInputsSeries" == SetupInputsSeries(*CIS).__class__.__name__, "SetupInputs(*CIS).__class__.__name__" - assert issubclass(SetupInputsSeries, SetupInputsSeries), "SetupInputs is not subclass of SetupInputs" - - -def test_create_config_series(capsys): - - return # this one is ok. Avoided adding new content to real file - CIS = get_default_setup_answers(configType.Series) - ret = create_config_series(SetupInputsSeries(*CIS)) - assert ret is True, "test_create_config_series failed" - - -def test_folder_creatable_by_adding(): - assert folder_creatable_by_adding("=&)%=") is False - assert folder_creatable_by_adding(r"C:\Users\UserX\PycharmProjects\evdspy\evdspy44\output44") is False - - -def test_folder_format_check(): - assert folder_format_check("=&)%=") is False - assert folder_format_check("xxyy") is True - assert folder_format_check(r"C:\Users\UserX\PycharmProjects\evdspy\evdspy44\output") is False - - -# def test_start_setup_series(): -# start_setup_series() is True - -def test_get_default_setup_answers(): - isinstance(get_default_setup_answers(), list), "get_default_setup_answers" +import evdspy +from evdspy.EVDSlocal.series_format.series_creator import * +from evdspy.EVDSlocal.components.evds_seri_files import * +from evdspy.EVDSlocal.setup_project.user_setup import start_setup_series, create_config_series, SetupInputsSeries, \ + start_setup_config, folder_format_check, folder_creatable, folder_creatable_by_adding, default_setup, \ + get_default_setup_answers, configType + +from ..tests.core_options_test import * + + +# from evdspy.EVDSlocal.setup_project.user_setup import * + + +def test_start_setup(capsys): + + CIS = get_default_setup_answers(configType.Series) + with capsys.disabled(): + if verbose: + print(SetupInputsSeries(*CIS).__class__.__name__) + # print(type(SetupInputsSeries(*CIS))) + ... + assert "SetupInputsSeries" == SetupInputsSeries(*CIS).__class__.__name__, "SetupInputs(*CIS).__class__.__name__" + assert issubclass(SetupInputsSeries, SetupInputsSeries), "SetupInputs is not subclass of SetupInputs" + + +def test_create_config_series(capsys): + + return # this one is ok. Avoided adding new content to real file + CIS = get_default_setup_answers(configType.Series) + ret = create_config_series(SetupInputsSeries(*CIS)) + assert ret is True, "test_create_config_series failed" + + +def test_folder_creatable_by_adding(): + assert folder_creatable_by_adding("=&)%=") is False + assert folder_creatable_by_adding(r"C:\Users\UserX\PycharmProjects\evdspy\evdspy44\output44") is False + + +def test_folder_format_check(): + assert folder_format_check("=&)%=") is False + assert folder_format_check("xxyy") is True + assert folder_format_check(r"C:\Users\UserX\PycharmProjects\evdspy\evdspy44\output") is False + + +# def test_start_setup_series(): +# start_setup_series() is True + +def test_get_default_setup_answers(): + isinstance(get_default_setup_answers(), list), "get_default_setup_answers" diff --git a/evdspy/EVDSlocal/tests/test_requests.py b/evdspy/EVDSlocal/tests/test_requests.py index ec83655..e9ad077 100644 --- a/evdspy/EVDSlocal/tests/test_requests.py +++ b/evdspy/EVDSlocal/tests/test_requests.py @@ -1,19 +1,19 @@ -from evdspy.EVDSlocal.requests_.ev_request import * - -from ..tests.core_options_test import * - - -def test_mock_request2(capsys): - response = mock_request("test_url") - - - with capsys.disabled(): - if verbose: - #print(response , type(response)) - print(type(response )) - assert isinstance(response, requests.models.Response) - -def test_report2(): - report_test() - - +from evdspy.EVDSlocal.requests_.ev_request import * + +from ..tests.core_options_test import * + + +def test_mock_request2(capsys): + response = mock_request("test_url") + + + with capsys.disabled(): + if verbose: + #print(response , type(response)) + print(type(response )) + assert isinstance(response, requests.models.Response) + +def test_report2(): + report_test() + + diff --git a/evdspy/EVDSlocal/tests/test_series_files.py b/evdspy/EVDSlocal/tests/test_series_files.py index 37bf00b..a976b4e 100644 --- a/evdspy/EVDSlocal/tests/test_series_files.py +++ b/evdspy/EVDSlocal/tests/test_series_files.py @@ -1,51 +1,51 @@ -from evdspy.EVDSlocal.series_format.series_creator import * - -from ..tests.core_options_test import * - - -# def test_SeriesFileFormat(capsys): -# with capsys.disabled(): -# # print(test_SeriesFileFormat2()) -# ... -# # SeriesFileFormat -# -# assert isinstance(test_SeriesFileFormat2()[0], -# EvdsSeriesRequestWrapper), "SeriesFileFormat did not get EvdsSeriesRequest Item " -# -# with capsys.disabled(): -# if verbose: -# create_series_file_from_Wrapper(test_SeriesFileFormat2(), 'test3.txt') -# ... - - -from evdspy.EVDSlocal.series_format.read_config_series import * -from evdspy.EVDSlocal.series_format.populate_series import check_pop_read - - -# def test_read_series_config2(capsys): -# read_series_config() -# with capsys.disabled(): -# if verbose: -# print(check_pop_read()) -# -# -# def test_clean_series_line(capsys): -# with capsys.disabled(): -# print("*************test_clean_series_line TEST*************") -# print(PopulateSeries().split_series_file()) - - # req = PopulateSeries().split_series_file() - - # print(req ) - # def check_pop_read(): - # ps = PopulateSeries() - # req = ps.split_series_file(content=pop_series_test_content) - # deb2(req) - # return req - -# -# def test_create_locked_series_file(capsys): -# from evdspy.EVDSlocal.initial.load_modules import LoadModulesClass -# with capsys.disabled(): -# print("*************test_clean_series_line TEST*************") -# print(LoadModulesClass().create_locked_series_file()) +from evdspy.EVDSlocal.series_format.series_creator import * + +from ..tests.core_options_test import * + + +# def test_SeriesFileFormat(capsys): +# with capsys.disabled(): +# # print(test_SeriesFileFormat2()) +# ... +# # SeriesFileFormat +# +# assert isinstance(test_SeriesFileFormat2()[0], +# EvdsSeriesRequestWrapper), "SeriesFileFormat did not get EvdsSeriesRequest Item " +# +# with capsys.disabled(): +# if verbose: +# create_series_file_from_Wrapper(test_SeriesFileFormat2(), 'test3.txt') +# ... + + +from evdspy.EVDSlocal.series_format.read_config_series import * +from evdspy.EVDSlocal.series_format.populate_series import check_pop_read + + +# def test_read_series_config2(capsys): +# read_series_config() +# with capsys.disabled(): +# if verbose: +# print(check_pop_read()) +# +# +# def test_clean_series_line(capsys): +# with capsys.disabled(): +# print("*************test_clean_series_line TEST*************") +# print(PopulateSeries().split_series_file()) + + # req = PopulateSeries().split_series_file() + + # print(req ) + # def check_pop_read(): + # ps = PopulateSeries() + # req = ps.split_series_file(content=pop_series_test_content) + # deb2(req) + # return req + +# +# def test_create_locked_series_file(capsys): +# from evdspy.EVDSlocal.initial.load_modules import LoadModulesClass +# with capsys.disabled(): +# print("*************test_clean_series_line TEST*************") +# print(LoadModulesClass().create_locked_series_file()) diff --git a/evdspy/EVDSlocal/tests/testing_mock_credentials.py b/evdspy/EVDSlocal/tests/testing_mock_credentials.py index 14b61ed..5527936 100644 --- a/evdspy/EVDSlocal/tests/testing_mock_credentials.py +++ b/evdspy/EVDSlocal/tests/testing_mock_credentials.py @@ -1,3 +1,3 @@ - -test_api_key = "test_api_key_mock" + +test_api_key = "test_api_key_mock" test_api_key_set = True \ No newline at end of file diff --git a/evdspy/EVDSlocal/tests_main.py b/evdspy/EVDSlocal/tests_main.py index 62028c8..5aed786 100644 --- a/evdspy/EVDSlocal/tests_main.py +++ b/evdspy/EVDSlocal/tests_main.py @@ -1,20 +1,20 @@ -from evdspy.EVDSlocal.tests.test_evds_classes import * - -from evdspy.EVDSlocal.tests.test_evds_classes import * -from evdspy.EVDSlocal.tests.test_main_load import * - -from evdspy.EVDSlocal.tests.test_project_setup import * -from evdspy.EVDSlocal.tests.test_log_session import * -from evdspy.EVDSlocal.tests.test_requests import * - -from evdspy.EVDSlocal.tests.test_apikey_checks import * -from evdspy.EVDSlocal.tests.test_categories import * -from evdspy.EVDSlocal.tests.test_main_cmd import * -from evdspy.EVDSlocal.tests.test_datagroups import * - - - -#-------------- not necessary for now -# -# from .tests.test_series_files import * -# from .tests.test_manual_series import * +from evdspy.EVDSlocal.tests.test_evds_classes import * + +from evdspy.EVDSlocal.tests.test_evds_classes import * +from evdspy.EVDSlocal.tests.test_main_load import * + +from evdspy.EVDSlocal.tests.test_project_setup import * +from evdspy.EVDSlocal.tests.test_log_session import * +from evdspy.EVDSlocal.tests.test_requests import * + +from evdspy.EVDSlocal.tests.test_apikey_checks import * +from evdspy.EVDSlocal.tests.test_categories import * +from evdspy.EVDSlocal.tests.test_main_cmd import * +from evdspy.EVDSlocal.tests.test_datagroups import * + + + +#-------------- not necessary for now +# +# from .tests.test_series_files import * +# from .tests.test_manual_series import * diff --git a/evdspy/EVDSlocal/utils/github_actions.py b/evdspy/EVDSlocal/utils/github_actions.py new file mode 100644 index 0000000..2de28aa --- /dev/null +++ b/evdspy/EVDSlocal/utils/github_actions.py @@ -0,0 +1,21 @@ +from pathlib import Path +# from .menu import yedekle_this, yedekle_this_onayisteme +from datetime import datetime +from dataclasses import dataclass +import sys +import os +# @dataclass +class GithubActions: + def is_testing(self): + return "hostedtoolcache" in sys.argv[0] +class PytestTesting: + def is_testing(self): + # print(" sys.argv[0]" , sys.argv[0]) + return "pytest" in sys.argv[0] +def get_input(msg, default=None): + if GithubActions().is_testing() or PytestTesting().is_testing(): + if not default: + print("currently testing with no default ") + return False + return default + return input(msg) \ No newline at end of file diff --git a/evdspy/EVDSlocal/utils/utils_general.py b/evdspy/EVDSlocal/utils/utils_general.py index 4bfa0e3..f9010fc 100644 --- a/evdspy/EVDSlocal/utils/utils_general.py +++ b/evdspy/EVDSlocal/utils/utils_general.py @@ -1,141 +1,141 @@ -#### 1 ############### -import base64 -import functools -import locale -# from babel.numbers import format_decimal -import pickle -import functools -import weakref -import functools -import os.path -from pathlib import Path -import sys -indent = " " * 15 -ENCODING = "utf-8" -#### 2 ############### -import os - -#### GLOBALS ############### - -#### -- ############### -from datetime import date - -today = date.today() -stoday = str(today) - -import time - - -def do_if_callable(f): - if callable(f): - f() - - -from pathlib import Path - -def URL_temizle(url: str): - import string - return url.translate({ord(c): None for c in string.whitespace}) - -def arg_acc(argv=None): - if argv is None: - argv = sys.argv - obj = {} - for index, key in enumerate(argv): - key = str(key) - if key.startswith("--"): - value = None - if len(argv) > index + 1: - value = argv[index + 1] - key = key[2:] - obj.update({key: value}) - return obj - -def get_current_dir(): - return Path(__file__).parent - - -def get_current_dir2(pat): - d = pat.absolute() - - return d - - -def delay(s: int, f1=None, f2=None): - do_if_callable(f1) - time.sleep(s) - do_if_callable(f2) - - -def ro(amount: float): - return round(amount) - - -def bound(f, *args): - return functools.partial(f, *args) - - -def create_directory(adres: str) -> None: - import os - if not os.path.isdir(adres): - os.makedirs(adres) - - -def get_api_key_from_file(file_name): - lines = False - file_name_path = Path(file_name) - if not file_name_path.is_file(): - return False - - with open(file_name, encoding=ENCODING) as file: - lines = file.readlines() - if lines is False: - return False - return str(lines[0]).strip() # .split(":")[1] - - -def global_var_api_key(): - import os - return "This version does not read global EVDS" - API_KEY_NAME = "EVDS_API_KEY" - return os.getenv(API_KEY_NAME) - - -def get_proxy_from_file(file_name): - lines = False - if not file_name: - return False - file_name_path = Path(file_name) - if not file_name_path.is_file(): - return False - with open(file_name_path, encoding=ENCODING) as file: - lines = file.readlines() - if lines is False: - return False - return lines[0] # ":".join(lines[0].split(":")[1:]) - - -def reducer(liste): - functools.reduce(lambda a, b: a + b, liste) - - -def reducer_prop(liste, prop="guncel_tutar"): - # print(liste ,prop , "---" ) - return functools.reduce(lambda a, b: a + b, - [getattr(item, prop) for item in liste]) - - -def f2(amount): - return '{:7,.2f}'.format(amount) - - -def f0(amount): - return '{:7,.0f}'.format(amount) - - -def get_random_hash(num=5): - import random - import string - letters = string.ascii_letters - randomF = ''.join(random.choice(letters) for i in range(num)) - return randomF +#### 1 ############### +import base64 +import functools +import locale +# from babel.numbers import format_decimal +import pickle +import functools +import weakref +import functools +import os.path +from pathlib import Path +import sys +indent = " " * 15 +ENCODING = "utf-8" +#### 2 ############### +import os + +#### GLOBALS ############### + +#### -- ############### +from datetime import date + +today = date.today() +stoday = str(today) + +import time + + +def do_if_callable(f): + if callable(f): + f() + + +from pathlib import Path + +def URL_temizle(url: str): + import string + return url.translate({ord(c): None for c in string.whitespace}) + +def arg_acc(argv=None): + if argv is None: + argv = sys.argv + obj = {} + for index, key in enumerate(argv): + key = str(key) + if key.startswith("--"): + value = None + if len(argv) > index + 1: + value = argv[index + 1] + key = key[2:] + obj.update({key: value}) + return obj + +def get_current_dir(): + return Path(__file__).parent + + +def get_current_dir2(pat): + d = pat.absolute() + + return d + + +def delay(s: int, f1=None, f2=None): + do_if_callable(f1) + time.sleep(s) + do_if_callable(f2) + + +def ro(amount: float): + return round(amount) + + +def bound(f, *args): + return functools.partial(f, *args) + + +def create_directory(adres: str) -> None: + import os + if not os.path.isdir(adres): + os.makedirs(adres) + + +def get_api_key_from_file(file_name): + lines = False + file_name_path = Path(file_name) + if not file_name_path.is_file(): + return False + + with open(file_name, encoding=ENCODING) as file: + lines = file.readlines() + if lines is False: + return False + return str(lines[0]).strip() # .split(":")[1] + + +def global_var_api_key(): + import os + return "This version does not read global EVDS" + API_KEY_NAME = "EVDS_API_KEY" + return os.getenv(API_KEY_NAME) + + +def get_proxy_from_file(file_name): + lines = False + if not file_name: + return False + file_name_path = Path(file_name) + if not file_name_path.is_file(): + return False + with open(file_name_path, encoding=ENCODING) as file: + lines = file.readlines() + if lines is False: + return False + return lines[0] # ":".join(lines[0].split(":")[1:]) + + +def reducer(liste): + functools.reduce(lambda a, b: a + b, liste) + + +def reducer_prop(liste, prop="guncel_tutar"): + # print(liste ,prop , "---" ) + return functools.reduce(lambda a, b: a + b, + [getattr(item, prop) for item in liste]) + + +def f2(amount): + return '{:7,.2f}'.format(amount) + + +def f0(amount): + return '{:7,.0f}'.format(amount) + + +def get_random_hash(num=5): + import random + import string + letters = string.ascii_letters + randomF = ''.join(random.choice(letters) for i in range(num)) + return randomF diff --git a/evdspy/EVDSlocal/utils/utils_test.py b/evdspy/EVDSlocal/utils/utils_test.py new file mode 100644 index 0000000..1755d22 --- /dev/null +++ b/evdspy/EVDSlocal/utils/utils_test.py @@ -0,0 +1,30 @@ +from pathlib import Path + +import pandas as pd + +from evdspy.EVDSlocal.index_requests.datagroups_initial import data_models_dict, data_strategy +from evdspy.EVDSlocal.index_requests.index_classes import GeneralIndexesDatagroups, GeneralIndexesDatagroupIndividual, \ + GeneralIndexesDatagroupSeriesList +from evdspy.EVDSlocal.index_requests.error_classes_index import ContentFunctionError +from evdspy.EVDSlocal.index_requests.df_operations import DFOperations +from evdspy.EVDSlocal.index_requests.index_util_funcs import json_to_excel, json_to_df, make_df_float +from ..common.files import Read +from ..common.table import Table2_ +from ..components.api_params import DateStart, DateEnd +from ..components.options_class import SingletonOptions +from ..config.apikey_class import ApikeyClass +from ..config.config import ConfigBase +from ..initial.start_options import default_data_folder_name, Default_Prefix_ +from ..requests_.ev_request import EVRequest +# import pytest + + +def get_api_key_while_testing(): + file_name = Path("..") / ".." / "api_key.txt" + if not file_name.is_file(): + file_name = Path("..") / "api_key.txt" + content = Read(file_name) + lines = content.splitlines() + line = tuple(line for line in lines if "evds" in line) + api_key = line[0].split("=")[1] + return str(api_key).strip() diff --git a/evdspy/__init__.py b/evdspy/__init__.py index aaeecfd..12ede58 100644 --- a/evdspy/__init__.py +++ b/evdspy/__init__.py @@ -1,7 +1,9 @@ -# ------------------------------------------------------ -# -# __init__ -# package: evdspy @2022 -# ------------------------------------------------------ - -from .EVDSlocal.main_ import * +# ------------------------------------------------------ +# +# __init__ +# package: evdspy @2022 +# ------------------------------------------------------ + +from evdspy.EVDSlocal.main_ import * +from evdspy.EVDSlocal.index_requests.get_series_indexes import UserRequest, default_start_date_fnc, \ + default_end_date_fnc, get_series diff --git a/evdspy/__version__.py b/evdspy/__version__.py index d2694d7..8b1003b 100644 --- a/evdspy/__version__.py +++ b/evdspy/__version__.py @@ -1 +1 @@ -#1.1.16 \ No newline at end of file +#1.0.17 \ No newline at end of file diff --git a/evdspy/main.py b/evdspy/main.py index f3af3dc..f7fecc8 100644 --- a/evdspy/main.py +++ b/evdspy/main.py @@ -1,9 +1,9 @@ -# ------------------------------------------------------ -# -# M a i n F i l e -# package: evdspy @2022 -# ------------------------------------------------------ - - - -from evdspy.EVDSlocal.main_ import * +# ------------------------------------------------------ +# +# M a i n F i l e +# package: evdspy @2022 +# ------------------------------------------------------ + + + +from evdspy.EVDSlocal.main_ import * diff --git a/evdspy/main_t.py b/evdspy/main_t.py index cebfbe9..3edff18 100644 --- a/evdspy/main_t.py +++ b/evdspy/main_t.py @@ -1,6 +1,6 @@ -from .evdspy import * -menu() - -# import site -# a =site.getsitepackages() +from .evdspy import * +menu() + +# import site +# a =site.getsitepackages() # print(a) \ No newline at end of file diff --git a/evdspy/test.py b/evdspy/test.py index b0407c9..55f3854 100644 --- a/evdspy/test.py +++ b/evdspy/test.py @@ -1,4 +1,4 @@ - - - -from evdspy.EVDSlocal.tests_main import * + + + +from evdspy.EVDSlocal.tests_main import * diff --git a/main_menu.py b/main_menu.py new file mode 100644 index 0000000..0bf0cd3 --- /dev/null +++ b/main_menu.py @@ -0,0 +1,5 @@ + + +from evdspy import menu + +menu() diff --git a/pyproject.toml b/pyproject.toml index b5fc747..349c349 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,12 +1,12 @@ [tool.poetry] name = "evdspy" -homepage = "https://github.com/SermetPekin/evdspy-repo" -documentation = "https://github.com/SermetPekin/evdspy-repo" -version = "1.0.17.6rc2" -description = "Get data from EVDS API and organize your local work environment with systematical approach. Using caching facility, this package makes less request from the server." +version = "1.1.17" +description = "A versatile interface for the 'EDDS' (EVDS) API of the Central Bank of the Republic of Türkiye (https://evds2.tcmb.gov.tr/index.php?/evds/userDocs). This package allows users to easily access and manage economic data through a user-friendly menu function. It features a robust caching mechanism to enhance the efficiency of data requests by storing frequently accessed data for selected periods. Required API keys can be obtained by registering on the EVDS website." authors = ["Sermet Pekin "] license = "MIT" readme = "README.md" +homepage = "https://github.com/SermetPekin/evdspy-repo" +documentation = "https://github.com/SermetPekin/evdspy-repo" classifiers = [ "Development Status :: 5 - Production/Stable", @@ -23,8 +23,6 @@ classifiers = [ "Typing :: Typed", ] - - [tool.poetry.dependencies] python = "^3.8" pandas = "^1.5.0" @@ -32,13 +30,6 @@ openpyxl = "^3.0.10" rich = "^12.5.1" requests = "^2.28.1" - - - - -[tool.poetry.extras] -jupyter = ["ipywidgets"] - [tool.poetry.dev-dependencies] pygments = "^2.6.0" commonmark = "^0.9.0" @@ -52,12 +43,13 @@ types-dataclasses = "^0.6.4" pre-commit = "^2.17.0" asv = "^0.5.1" - - - - - +[tool.poetry.extras] +jupyter = ["ipywidgets"] [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" + +[tool.poetry.scripts] +evdspy = 'evdspy:console_main' + diff --git a/setup_config_pub.py b/setup_config_pub.py deleted file mode 100644 index 9e53946..0000000 --- a/setup_config_pub.py +++ /dev/null @@ -1,8 +0,0 @@ -# -------------------------------------------------------------------------------------- -root_version = "1.0.15" -# python setup.py bdist_wheel --universal -test_environment = r"" -cmd_file = "Run_Produced" -package_name = "evdspy" - -# -------------------------------------------------------------------------------------- diff --git a/setup_helper.py b/setup_helper.py deleted file mode 100644 index d162a65..0000000 --- a/setup_helper.py +++ /dev/null @@ -1,83 +0,0 @@ -import sys -from pathlib import Path - - -class NOArgsEror(BaseException): - """NOArgsEror""" - - -def arg_acc(argv=tuple(sys.argv)): - if argv is None: - raise NOArgsEror - obj = {} - for index, key in enumerate(argv): - key = str(key) - if key.startswith("--"): - value = None - if len(argv) > index + 1: - value = argv[index + 1] - key = key[2:] - obj.update({key: value}) - return obj - - -# -------------------------------------------------------------------------------------- -# T E S T E N V I R O N M E N T -# -------------------------------------------------------------------------------------- -rf""" - Usage - echo on - cd C:\Users\Username\PycharmProjects\evdspy - python setup.py bdist_wheel --universal --folder C:\Username\SomeFolder\Env - @params - --folder : Test Env folder \ - --stable : status (dev : False / prod : True ) -""" - - -def check_stable(STABLE_FORCE_, get_args_dict_runtime): - """Stable Version or Development with time and date""" - args_dict = get_args_dict_runtime() - stable_param = args_dict.get("stable", None) - stable = True if stable_param == "True" or STABLE_FORCE_ else False - return stable - - -def create_env_folder(test_environment_): - path = Path(test_environment_) - if not path.is_dir(): - import os - os.makedirs(path) - - -def get_cmd_file(get_args_dict_runtime): - cmd_file = False - test_env = get_test_env(get_args_dict_runtime) - if test_env: - cmd_file = 'Run_produced' - create_env_folder(test_env) - """ nick name for the env for simplicity""" - if isinstance(test_env, str): - nick_name_for_env = Path(test_env).parts[-1] - """ command file to install development/pord version in local area""" - cmd_file = f"{cmd_file}-{nick_name_for_env}.cmd" - return cmd_file - - -def get_test_env(get_args_dict_runtime): - args_dict = get_args_dict_runtime() - test_environment__ = False - """ Test Env folder """ - folder = args_dict.get("folder", None) - if folder is None: - folder = args_dict.get("--folder", None) - if folder: - test_environment__ = folder - # normalize parameters for standard build - sys.argv = sys.argv[0: 3] - return test_environment__ - - -def get_args_dict(args): - args_dict = arg_acc(args) - return args_dict diff --git a/setup_options_class.py b/setup_options_class.py deleted file mode 100644 index 8cb8cf0..0000000 --- a/setup_options_class.py +++ /dev/null @@ -1,88 +0,0 @@ -from setup_helper import * -from datetime import datetime -from setup_config_pub import root_version, package_name -import typing as t -from dataclasses import dataclass - - -@dataclass -class SetupOptions: - stable_version: str - stable_force: bool - test_environment: t.Union[bool, str, Path] - get_args_dict_runtime: t.Callable - version: str = '' - long_des: str = '' - test_folder: Path = None - - def __post_init__(self): - self.main() - if get_test_env(self.get_args_dict_runtime): - self.create_run_command() - - def get_stable_version(self): - return self.stable_version - - def get_develop_version(self): - stable = check_stable(self.stable_force, self.get_args_dict_runtime) - if stable: - self.version = self.get_stable_version() - return self.version - ## rest will be develop version - version = datetime.now().strftime("%d.%b_%H.%M") - version = f"{root_version}.bd.{version}" - self.version = version - return version - - def get_commands_content(self): - self.root_folder = Path(__file__).parent - - build_content = f"""REM Build file for {package_name} -echo on -cd {self.root_folder} -python setup.py bdist_wheel --universal - -""" - content = \ - rf"""REM Run file for {package_name} -rem -echo on -rem cd {self.test_environment} - -poetry shell -echo {self.test_cmd_file} - -pip uninstall {package_name} - -rem pip install {self.root_folder}\dist\{package_name}-{self.version}-py2.py3-none-any.whl --force-reinstall --no-deps -pip install {self.root_folder}\dist\{package_name}-{self.version}-py2.py3-none-any.whl -rem python -rem from {package_name} import * - -""" - - return content - - def create_run_command(self): - self.test_folder = Path(self.test_environment) - cmd_file_local = get_cmd_file(self.get_args_dict_runtime) - self.test_cmd_file = self.test_folder / cmd_file_local - self.write(self.test_cmd_file, self.get_commands_content()) - - def main(self): - print(f"building ... version:{self.get_develop_version()}") - parent = Path(__file__).parent - self.read_me_file() - file_name = Path() / parent / package_name / "__version__.py" - - self.write(file_name, f"#{self.get_develop_version()}") - - def write(self, file_name, content): - with open(file_name, 'w') as f: - f.write(content) - - def read_me_file(self): - with open("README.md", "r") as file_: - long_des = file_.read() - self.long_des = long_des - return long_des