├── 01.png ├── 02.png ├── setup.py ├── LICENCE ├── README_EN.md ├── .gitignore ├── README.md └── evds └── __init__.py /01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fatihmete/evds/HEAD/01.png -------------------------------------------------------------------------------- /02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fatihmete/evds/HEAD/02.png -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open("README.md", "r", encoding="utf8") as fh: 4 | long_description = fh.read() 5 | 6 | setuptools.setup( 7 | name="evds", 8 | version="0.3.2", 9 | author="Fatih Mete", 10 | author_email="fatihmete@live.com", 11 | description="EVDS python wrapper", 12 | long_description=long_description, 13 | long_description_content_type="text/markdown", 14 | url="https://github.com/fatihmete/evds", 15 | packages=setuptools.find_packages(), 16 | classifiers=[ 17 | "Programming Language :: Python :: 3", 18 | "License :: OSI Approved :: MIT License", 19 | "Operating System :: OS Independent", 20 | ], 21 | install_requires=[ 22 | 'pandas', 'requests', 'urllib3' 23 | ], 24 | python_requires='>=3.6', 25 | ) 26 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Fatih Mete 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README_EN.md: -------------------------------------------------------------------------------- 1 | # EVDS 2 | EVDS package allows you to access statistical data released by Central Bank of the Republic of Turkey (CBRT) (Electronic Data Delivery System (EDDS)) with Python. 3 | 4 | With the EVDS package, you can access all the following data: 5 | - MARKET STATISTICS 6 | - EXCHANGE RATES 7 | - INTEREST RATES 8 | - MONEY AND BANKING STATISTICS 9 | - WEEKLY SECURITIES STATISTICS 10 | - FINANCIAL STATISTICS 11 | - CBRT BALANCE SHEET DATA 12 | - PRICE INDICES 13 | - SURVEYS 14 | - BALANCE OF PAYMENTS INTERNATIONAL INVESTMENT P... 15 | - FOREIGN TRADE STATISTICS 16 | - PUBLIC FINANCE 17 | - PRODUCTION STATISTICS 18 | - PAYMENT SYSTEMS AND EMISSION 19 | - EMPLOYMENT STATISTICS 20 | - EXTERNAL DEBT 21 | - GOLD STATISTICS 22 | - HOUSING AND CONSTRUCTION STATISTICS 23 | - TOURISM STATISTICS 24 | 25 | ## Installation 26 | ``` 27 | pip install evds --upgrade 28 | ``` 29 | ## Usage 30 | ```python 31 | from evds import evdsAPI 32 | evds = evdsAPI('EVDS_API_KEY', lang="ENG") 33 | evds.get_data(['TP.DK.USD.A.YTL','TP.DK.EUR.A.YTL'], startdate="01-01-2019", enddate="01-01-2020") 34 | ``` 35 | ### Get API Key 36 | To use the evds package, you must first get the API Key on the EVDS system. To get the API Key, follow the steps below: 37 | 1. Open [EVDS](https://evds2.tcmb.gov.tr/) page and create an EVDS Account. 38 | 2. Then click on the profile link under your username. 39 | 40 | ![01](01.png) 41 | 42 | 3. Click the "API Key" button at the bottom of your profile page and copy the value in the box that opens. 43 | 44 | ![02](02.png) 45 | 46 | ## Proxies 47 | You can set proxies with `proxies` parameter as following. Also you can disable https verify with `httpsVerify` parameter. 48 | ``` 49 | proxies = { "https" : "HTTPS_PROXY_URL"} 50 | evds = evdsAPI('EVDS_API_KEY', proxies=proxies, httpsVerify=False) 51 | ``` 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # poetry 98 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 99 | # This is especially recommended for binary packages to ensure reproducibility, and is more 100 | # commonly ignored for libraries. 101 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 102 | #poetry.lock 103 | 104 | # pdm 105 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 106 | #pdm.lock 107 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 108 | # in version control. 109 | # https://pdm.fming.dev/#use-with-ide 110 | .pdm.toml 111 | 112 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 113 | __pypackages__/ 114 | 115 | # Celery stuff 116 | celerybeat-schedule 117 | celerybeat.pid 118 | 119 | # SageMath parsed files 120 | *.sage.py 121 | 122 | # Environments 123 | .env 124 | .venv 125 | env/ 126 | venv/ 127 | ENV/ 128 | env.bak/ 129 | venv.bak/ 130 | 131 | # Spyder project settings 132 | .spyderproject 133 | .spyproject 134 | 135 | # Rope project settings 136 | .ropeproject 137 | 138 | # mkdocs documentation 139 | /site 140 | 141 | # mypy 142 | .mypy_cache/ 143 | .dmypy.json 144 | dmypy.json 145 | 146 | # Pyre type checker 147 | .pyre/ 148 | 149 | # pytype static type analyzer 150 | .pytype/ 151 | 152 | # Cython debug symbols 153 | cython_debug/ 154 | 155 | # PyCharm 156 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 157 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 158 | # and can be added to the global gitignore or merged into this file. For a more nuclear 159 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 160 | #.idea/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EVDS 2 | 3 | [English](https://github.com/fatihmete/evds/blob/master/README_EN.md) 4 | 5 | EVDS paketi EVDS-API üzerinden Türkiye Cumhuriyet Merkez Bankası (TCMB) tarafından Elektronik Veri Dağıtım Sistemi (EVDS) aracılığıyla yayımlanan tüm istatistiki verilere python aracılığıyla erişmenize imkan sağlar. 6 | 7 | EVDS paketi resmi bir paket olmayıp açık kaynak kodlu olarak geliştirilmektedir. 8 | 9 | ## Kurulum 10 | 11 | evds paketini pip paket yöneticisi aracılığıyla kurabilirsiniz: 12 | 13 | ``` 14 | pip install evds --upgrade 15 | ``` 16 | 17 | ## Yenilikler 18 | 19 | 0.3 sürümü ile aşağıdaki değişiklikler yapıldı: 20 | 21 | 1. SSL hatalarının giderilmesi için legacySSL parametresi eklendi. [PR #8](https://github.com/fatihmete/evds/pull/8) 22 | 2. Kod içerisinde düzeltmeler yapıldı. [PR #6](https://github.com/fatihmete/evds/pull/6) [PR #4](https://github.com/fatihmete/evds/pull/4) 23 | 3. request session'un açık kalması nedeniyle ortaya çıkan ResourceWarning uyarısı giderildi. [PR #4](https://github.com/fatihmete/evds/pull/4) 24 | 4. Pandas DataFrame numeric tiplere cast ederken ortaya çıkan FutureWarning uyarıları çıkıyordu. Bu sorun giderildi. [PR #9](https://github.com/fatihmete/evds/pull/9) 25 | 26 | 0.2 sürümü ile birlikte aşağıdaki özellikler eklenmiştir: 27 | 28 | 1. `get_data`, `get_sub_categories` ve `get_series` fonksiyonlarına, `raw` parametresi eklendi. Bu parametre `True` olarak tanımlandığında ilgili verilere dictionary formatında erişebilirsiniz. 29 | 2. Çeşitli hatalar giderildi. 30 | 31 | 0.1.1 sürümü ile birlikte aşağıdaki özellikler eklenmiştir: 32 | 33 | 1. formulas parametresindeki hata giderildi. 34 | 35 | 0.1.0 sürümü ile birlikte aşağıdaki özellikler eklenmiştir: 36 | 37 | 1. API üzerinden erişilemeyen serilere ilişkin EVDS'de yapılan güncellemeye paralel olarak tüm serilere erişim olanağı sağlanmıştır. 38 | 2. Proxy desteği eklenmiştir. 39 | 3. Küçük hatalar giderildi 40 | 41 | ## Kullanım 42 | 43 | Örnek kullanım, 01-01-2019 - 01-01-2020 arası USD ve EUR alış kurlarına aşağıdaki şekilde erişilebilir. 44 | 45 | ```python 46 | from evds import evdsAPI 47 | evds = evdsAPI('EVDS_API_ANAHTARI') 48 | evds.get_data(['TP.DK.USD.A.YTL','TP.DK.EUR.A.YTL'], startdate="01-01-2019", enddate="01-01-2020") 49 | ``` 50 | 51 | get_data fonksiyonu DataFrame return edecektir. İstenmesi halinde `raw=True` parametresi ile dictionary formatında ham veriye ulaşılabilir. 52 | 53 | ### API Anahtarı Alma 54 | 55 | evds paketini kullanmak için öncelikle EVDS sistemi üzerinden API Anahtarı almanız gerekmektedir. API Anahtarı almak için aşağıdaki adımları izleyiniz: 56 | 57 | 1. [EVDS](https://evds2.tcmb.gov.tr/) sayfasına giriş yaptıktan sonra Giriş Yap ve Kayıt Ol bağlantılarını izleyerek bir EVDS hesabı oluşturun. 58 | 2. Ardından kullanıcı adınızın altında yer alan profil bağlantısına tıklayınız. 59 | 60 | ![01](01.png) 61 | 62 | 3. Profil sayfanızın alt kısmında yer alan "API Anahtarı" butonuna tıklayınız ve açılan kutucukta yer alan değeri kopyalayınız. 63 | 64 | ![02](02.png) 65 | 66 | ### Detaylı Sorgulama 67 | 68 | `get_data` fonksiyonu aşağıdaki parametreleri alır: 69 | 70 | #### series 71 | 72 | Bu parametre liste olarak tanımlanmalıdır. Ayrıca birden fazla seri bu liste içerisinde tanımlanabilir. Tanımlanması zorunludur. 73 | 74 | #### startdate 75 | 76 | Seride yer alan verilerin hangi tarihten itibaren seçileceği bu parametre ile belirlenir. Tanımlanması zorunludur. 77 | 78 | #### enddate 79 | 80 | Eğer seri üzerinde bir aralık seçimi yapılmak isteniyorsa aralığın bitiş tarihi bu parametre ile belirtilir. Tanımlanması ihtiyaridir. Tanımlanmadığı durumda `startdate` değerine eşit olarak tanımlanır. 81 | 82 | #### raw 83 | 84 | `True` olması halinde fonksiyon talep edilen veriyi DataFrame yerine dictionary return eder. 85 | Örnek kullanım: 86 | 87 | ```python 88 | ... 89 | evds.get_data(['TP.DK.USD.A.YTL','TP.DK.EUR.A.YTL'], startdate="01-01-2019", enddate="01-01-2020", raw=True) 90 | ``` 91 | 92 | #### aggregation_types 93 | 94 | Seri içindeki verilerin getirilmesi esnasında kullanılacak olan toplululaştırma yöntemini ifade eder. Tanımlanması ihtiyaridir. Eğer tanımlanmamışsa seri için tanımlanan öntanımlı yöntem kullanılır. Ayrıca değer olarak string veya liste alabilir. String alması durumunda tüm seriler için aynı yöntem uygulanır. Liste olarak tanımlanırsa `series` parametresinde tanımlanan serilere sırasıyla belirtilen yöntemler uygulanır. 95 | Kullanılabilecek yöntemler aşağıdaki gibidir: 96 | 97 | | Yöntem | Parametre Değeri | 98 | | --------- | ---------------- | 99 | | Ortalama | avg | 100 | | En düşük | min | 101 | | En yüksek | max | 102 | | Başlangıç | first | 103 | | Bitiş | last | 104 | | Kümülatif | sum | 105 | 106 | #### formulas 107 | 108 | Seri içindeki verilerin getirilmesi esnasında uygulanacak formülü ifade eder. Tanımlanması ihtiyaridir. Eğer tanımlanmamışsa seri için tanımlanan öntanımlı formül kullanılır. Ayrıca değer olarak string veya liste alabilir. String alması durumunda tüm seriler için aynı formül uygulanır. Liste olarak tanımlanırsa `series` parametresinde tanımlanan serilere sırasıyla belirtilen formüller uygulanır. 109 | Kullanılabilecek yöntemler aşağıdaki gibidir: 110 | 111 | | Formül | Değer | 112 | | ------------------------------------------ | ----- | 113 | | Düzey (Öntanımlı) | 0 | 114 | | Yüzde Değişim | 1 | 115 | | Fark | 2 | 116 | | Yıllık Yüzde Değişim | 3 | 117 | | Yıllık Fark | 4 | 118 | | Bir Önceki Yılın Sonuna Göre Yüzde Değişim | 5 | 119 | | Bir Önceki Yılın Sonuna Göre Fark | 6 | 120 | | Hareketli Ortalama | 7 | 121 | | Hareketli Toplam | 8 | 122 | 123 | API formula parametresi uygulandığında orijinal değerleri `None` olarak yanıtladığı için, formula parametresi tanımladığınız serinin orijinal değerlere ulaşmak için aynı seriyi tekrar ekleyiniz ve formula parametresini 0 olarak tanımlayınız. Örneğin 124 | 125 | ```python 126 | evds.get_data(['TP.DK.USD.A.YTL','TP.DK.USD.A.YTL'], 127 | startdate="01-01-2019", 128 | enddate="01-01-2020", 129 | formulas=[1,0], 130 | ) 131 | ``` 132 | 133 | USD için yüzde değişim ve orijinal değerlere aynı anda yukarıdaki gibi ulaşabilirsiniz. 134 | 135 | #### frequency 136 | 137 | Seri içerisinde yer alan verilerin hangi sıklıkla getireceğini ifade eder. Tanımlanması ihtiyaridir. Eğer tanımlanmamışsa seri için tanımlanan öntanımlı yayımlanma sıklığı kullanılır.Aşağıdaki değerleri alabilir. 138 | 139 | | Sıklık | Değer | 140 | | ---------- | ----- | 141 | | Günlük | 1 | 142 | | İşgünü | 2 | 143 | | Haftalık | 3 | 144 | | Ayda 2 Kez | 4 | 145 | | Aylık | 5 | 146 | | 3 Aylık | 6 | 147 | | 6 Aylık | 7 | 148 | | Yıllık | 8 | 149 | 150 | ## Mevcut Serileri Listeleme 151 | 152 | EVDS üzerinde veri serileri sırasıyla Ana Kategori, Alt Kategori ve Seri hiyerarşisinde sunulmaktadır. 153 | 154 | > `get_data` fonksiyonun kullanılması için aşağıda yer alan işlemlerin gerçekleştirilmesine gerek yoktur. Veri serisine ait kodun bilinmesi durumunda doğrudan `get_data` fonksiyonu kullanılabilir. 155 | 156 | ### Ana kategorileri listeleme 157 | 158 | `main_categories` değişkeni ile ana kategorileri listeleyebilirsiniz. 159 | 160 | ```python 161 | ... 162 | evds.main_categories 163 | ``` 164 | 165 | komut ile ana kategorileri listeleyebilirsiniz. 166 | 167 | | CATEGORY_ID | TOPIC_TITLE_TR | 168 | | ----------- | ---------------------------- | 169 | | 1 | PİYASA VERİLERİ | 170 | | 2 | KURLAR | 171 | | 3 | FAİZ İSTATİSTİKLERİ | 172 | | 4 | PARA VE BANKA İSTATİSTİKLERİ | 173 | | ... | ... | 174 | 175 | ### Alt kategorileri listeleme 176 | 177 | Ana kategori altında yer alan alt kategorilere aşağıdaki şekilde ulaşabilirsiniz. Ayrıca `raw=True` parametresi ile DataFrame yerine dictionary formatında alt kategorileri ulaşılabilir. 178 | 179 | ```python 180 | evds.get_sub_categories('Ana kategori ID'si veya Adı') 181 | ``` 182 | 183 | Örnek kulllanım; 184 | 185 | ```python 186 | ... 187 | evds.get_sub_categories(6) 188 | ``` 189 | 190 | | CATEGORY_ID | DATAGROUP_CODE | DATAGROUP_NAME | 191 | | ----------- | -------------- | ------------------------------------------------- | 192 | | 6 | bie_dbafod | Dış Borç Anapara ve Faiz Ödemeleri ile Diğer T... | 193 | | 6 | bie_dbdborc | Dış Borçlar-Brüt (Hazine ve Maliye Bakanlığı) | 194 | | 6 | bie_kvdbs | Kısa Vadeli Dış Borç Stoku (milyon ABD doları) | 195 | | 6 | bie_yssk | Özel Sektörün Yurt Dışından Sağladığı Uzun Vad... | 196 | 197 | Yukarıda yer alan örnekte 6'nolu kategori altında yer alan alt kategoriler listelenmiştir. Ayrıca `get_sub_categories` fonksiyonunda CATEGORY_ID yerine doğrudan ana kategori adı ile kullanabilirsiniz. Örneğin 198 | 199 | ```python 200 | ... 201 | evds.get_sub_categories("KURLAR") 202 | ``` 203 | 204 | ### Serileri listeleme 205 | 206 | Alt kategori altında yer alan veri serilerine aşağıdaki şekilde ulaşabilirsiniz. Ayrıca `raw=True` parametresi ile DataFrame yerine dictionary formatında serilere ulaşılabilir. 207 | 208 | ```python 209 | evds.get_series('Alt kategori adı') 210 | ``` 211 | 212 | Örnek kulllanım; 213 | 214 | ``` 215 | ... 216 | evds.get_series('bie_dbdborc') 217 | ``` 218 | 219 | | SERIE_CODE | SERIE_NAME | START_DATE | 220 | | ---------- | ------------------------------------- | ---------- | 221 | | TP.DB.B01 | 1:TÜRKİYE BRÜT DIŞ BORÇ STOKU | 01-10-1989 | 222 | | TP.DB.B02 | 2:KISA VADELİ BORÇLAR (Borçluya Göre) | 01-10-1989 | 223 | | TP.DB.B03 | 2A:KAMU (Borçluya Göre) | 01-10-1989 | 224 | | TP.DB.B04 | 2A1:GENEL YÖNETİM (Borçluya Göre) | 01-10-1989 | 225 | | TP.DB.B05 | 2A1a:Merkezi Yönetim | 01-10-1989 | 226 | 227 | `get_data()` fonksiyonu aracılığıyla SERIE_CODE'u kullanarak serilere ait verilere ulaşabilirsiniz. 228 | 229 | ## Proxy Tanımlama 230 | 231 | Proxy adresinizi aşağıdaki gibi `proxies` parametresi ile tanımlayabilirsiniz. Ayrıca `httpsVerify` parametresi ile https kontrolünü devre dışı bırakabilirsiniz. 232 | 233 | ``` 234 | proxies = { "https" : "HTTPS_PROXY_URL"} 235 | evds = evdsAPI('EVDS_API_ANAHTARI', proxies=proxies, httpsVerify=False) 236 | ``` 237 | 238 | ## SSLError Hatası çözümü 239 | 240 | Sunucu sertifikası ve kullanılan python paketlerinden kaynaklı olarak SSL hatası alınabilmektedir. Bu hata durumunda legacySSL parametresi kullanılabilir: 241 | 242 | ``` 243 | evds = evdsAPI('EVDS_API_ANAHTARI', legacySSL=True) 244 | 245 | ``` 246 | -------------------------------------------------------------------------------- /evds/__init__.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import requests 3 | import json 4 | import ssl 5 | import urllib3 6 | 7 | class CustomHttpAdapter (requests.adapters.HTTPAdapter): 8 | # "Transport adapter" that allows us to use custom ssl_context. 9 | def __init__(self, ssl_context=None, **kwargs): 10 | self.ssl_context = ssl_context 11 | super().__init__(**kwargs) 12 | 13 | def init_poolmanager(self, connections, maxsize, block=False): 14 | self.poolmanager = urllib3.poolmanager.PoolManager( 15 | num_pools=connections, maxsize=maxsize, 16 | block=block, ssl_context=self.ssl_context) 17 | 18 | 19 | class evdsAPI: 20 | """ 21 | for more detail https://github.com/fatihmete/evds 22 | Example usage: 23 | from evds import evdsAPI 24 | evds = evdsAPI('EVDS_API_KEY') 25 | evds.get_data(['TP.DK.USD.A.YTL','TP.DK.EUR.A.YTL'], startdate="01-01-2019", enddate="01-01-2020") 26 | """ 27 | 28 | def __init__(self, key, lang="TR", DEBUG=False, proxies="", httpsVerify=True, legacySSL=True): 29 | self.key = key 30 | self.DEBUG = DEBUG 31 | self.proxies = proxies 32 | self.httpsVerify = httpsVerify 33 | self.legacySSL = legacySSL 34 | 35 | self.__create_session() 36 | 37 | if lang in ["TR", "ENG"]: 38 | self.lang = lang 39 | else: 40 | self.lang = "TR" 41 | # API returns this main categories but they are not available 42 | self.not_available_categories = [17] 43 | 44 | self.main_categories = self.__get_main_categories() 45 | 46 | def __create_session(self): 47 | self.session = requests.Session() 48 | if self.legacySSL: 49 | ctx = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) 50 | ctx.options |= 0x4 # OP_LEGACY_SERVER_CONNECT 51 | self.session.mount('https://', CustomHttpAdapter(ctx)) 52 | 53 | if self.proxies != "": 54 | self.session.proxies = self.proxies 55 | self.session.verify = self.httpsVerify 56 | 57 | def __get_main_categories(self): 58 | """ 59 | Function returns main categories dataframe. 60 | """ 61 | main_categories = self.__make_request('https://evds2.tcmb.gov.tr/service/evds/categories/', 62 | params={'type': 'json'}) 63 | try: 64 | main_categories_raw = json.loads(main_categories) 65 | main_categories_df = pd.DataFrame(main_categories_raw)[ 66 | ["CATEGORY_ID", "TOPIC_TITLE_" + self.lang]] 67 | main_categories_df["CATEGORY_ID"] = main_categories_df["CATEGORY_ID"].astype( 68 | "int") 69 | return main_categories_df[~main_categories_df.CATEGORY_ID.isin(self.not_available_categories)] 70 | 71 | except: 72 | raise EVDSConnectionError( 73 | f"Main categories couldn't load. Please check your API Key.") 74 | 75 | def get_sub_categories(self, main_category="", detail=False, raw=False): 76 | """ 77 | The function returns sub-categories as dataframe object. 78 | If main_category, 79 | - Not defined, returns all subcategories, 80 | - Defined as an integer, returns subcategories which main category id match this value, 81 | - Defined as a string, depending on self.lang value, search in main category name and 82 | returns matched the main category' subcategories 83 | """ 84 | if main_category == "": 85 | params = {'mode': 0, 'code': '', 'type': 'json'} 86 | 87 | elif isinstance(main_category, (int, float)): 88 | if main_category in self.main_categories["CATEGORY_ID"].to_list(): 89 | params = {'mode': 2, 'code': main_category, 'type': 'json'} 90 | else: 91 | raise CategoryNotFoundError("Category not found.") 92 | else: 93 | try: 94 | code = self.main_categories[self.main_categories["TOPIC_TITLE_" + 95 | self.lang].str.contains(main_category)]["CATEGORY_ID"].values[0] 96 | params = {'mode': 2, 'code': code, 'type': 'json'} 97 | except: 98 | raise CategoryNotFoundError("Category not found.") 99 | 100 | sub_categories = self.__make_request('https://evds2.tcmb.gov.tr/service/evds/datagroups/', 101 | params=params) 102 | sub_categories = json.loads(sub_categories) 103 | if raw: 104 | return sub_categories 105 | df = pd.DataFrame(sub_categories) 106 | if detail == False: 107 | return df[["CATEGORY_ID", 108 | "DATAGROUP_CODE", 109 | "DATAGROUP_NAME" + ("_ENG" if self.lang == "ENG" else "")]] 110 | 111 | return df 112 | 113 | def get_series(self, datagroup_code, detail=False, raw=False): 114 | """ 115 | The function returns dataframe of series which belongs to given data group. 116 | Because of default detail parameter is False, only return "SERIE_CODE", "SERIE_NAME" and "START_DATE" value. 117 | """ 118 | series = self.__make_request('https://evds2.tcmb.gov.tr/service/evds/serieList/', 119 | params={'type': 'json', 'code': datagroup_code}) 120 | series = json.loads(series) 121 | if raw: 122 | return series 123 | df = pd.DataFrame(series) 124 | if detail == False: 125 | return df[["SERIE_CODE", 126 | "SERIE_NAME" + ("_ENG" if self.lang == "ENG" else ""), 127 | "START_DATE"]] 128 | 129 | return df 130 | 131 | def get_data(self, series, startdate, enddate="", aggregation_types="", formulas="", frequency="", raw=False): 132 | """ 133 | The function returns data of the given series data. Series must be typed as list. 134 | Also, set parameter raw=False to return dictionary format. 135 | If end date not defined, end date set as equal to start date 136 | If aggregation_types and formulas, 137 | - not defined, API returns value aggregated and calculated default aggregations type and formula for the series. 138 | - defined as a string, given aggregation type and formula applied for all given series 139 | - defined as a list, given aggregation types and formulas applied for given series respectively. 140 | Available aggregation types are avg, min, max, first, last, sum. 141 | Available formulas are the following: 142 | Percentage change: 1 143 | Difference: 2 144 | Yearly percentage change: 3 145 | Yearly difference: 4 146 | Percentage change in comparison with end of previous year: 5 147 | Difference in comparison with end of previous year: 6 148 | Moving average: 7 149 | Moving total: 8 150 | It is possible to set frequency of data. Possible frequencies are the following: 151 | Daily: 1 152 | Workday: 2 153 | Weekly: 3 154 | Two times in a month: 4 155 | Monthly: 5 156 | Quarterly: 6 157 | Six month: 7 158 | Yearly: 8 159 | """ 160 | if isinstance(series, list) == False: 161 | return print("Series type must be list.") 162 | 163 | # For daily data set enddate to startdate, if blank 164 | if enddate == "": 165 | enddate = startdate 166 | 167 | series_count = len(series) 168 | 169 | # Set aggregation type 170 | if aggregation_types == "": 171 | # Default aggregation method 172 | aggregation_type_param = '' 173 | elif isinstance(aggregation_types, list): 174 | # User defined aggregation per series 175 | aggregation_type_param = "-".join([str(i) 176 | for i in aggregation_types]) 177 | else: 178 | # User defined aggregation same for all series 179 | aggregation_type_param = "-".join([str(aggregation_types) 180 | for i in range(series_count)]) 181 | 182 | # Set formulas 183 | if formulas == "": 184 | # Default formula 185 | formula_param = '' 186 | elif isinstance(formulas, list): 187 | # User defined formula per series 188 | formula_param = "-".join([str(i) for i in formulas]) 189 | else: 190 | # User defined formula same for all series 191 | formula_param = "-".join([str(formulas) 192 | for i in range(series_count)]) 193 | 194 | data = self.__make_request('https://evds2.tcmb.gov.tr/service/evds/', 195 | params={ 196 | 'series': "-".join(series), 197 | 'startDate': startdate, 198 | 'endDate': enddate, 199 | 'type': 'json', 200 | 'formulas': formula_param, 201 | 'frequency': str(frequency), 202 | 'aggregationTypes': aggregation_type_param, 203 | }) 204 | data = json.loads(data)["items"] 205 | # If raw is true return only json results. 206 | if raw: 207 | return data 208 | 209 | df = pd.DataFrame(data) 210 | 211 | # Numeric values in json data is defined as string. To fix this problem, we cast values to float. 212 | for serie_col in [s.replace(".", "_") for s in series]: 213 | if serie_col in df.columns: 214 | df[serie_col] = df[serie_col].astype("float") 215 | 216 | if "UNIXTIME" in df.columns: 217 | df.drop(columns=["UNIXTIME"], inplace=True) 218 | return df 219 | 220 | def __make_request(self, url, params={}): 221 | params = self.__param_generator(params) 222 | request = self.session.get(url + params, headers={'key': self.key}) 223 | self.session.close() 224 | print(request.url) if self.DEBUG == True else None 225 | if request.status_code == 200: 226 | return request.content 227 | else: 228 | raise EVDSConnectionError( 229 | "Connection error, please check your API Key or request. Url:{}".format(request.url)) 230 | 231 | def __param_generator(self, param): 232 | param_text = '' 233 | for key, value in param.items(): 234 | param_text += str(key) + "=" + str(value) 235 | param_text += '&' 236 | return param_text[:-1] 237 | 238 | 239 | class CategoryNotFoundError(Exception): 240 | pass 241 | 242 | 243 | class EVDSConnectionError(Exception): 244 | pass 245 | --------------------------------------------------------------------------------