sista-tacrpy 1.0.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ Metadata-Version: 2.1
2
+ Name: sista-tacrpy
3
+ Version: 1.0.12
4
+ Summary: stahovani dat ze sista
5
+ Home-page: UNKNOWN
6
+ Author: velci panove tacru
7
+ Author-email: rozalie.bilkova@tacr.cz
8
+ License: UNKNOWN
9
+ Project-URL: Documentation, https://youtu.be/1RulQYSl1aw?feature=shared
10
+ Platform: UNKNOWN
11
+ Requires-Dist: pandas
12
+ Requires-Dist: gspread
13
+ Requires-Dist: numpy
14
+ Requires-Dist: requests
15
+ Requires-Dist: unidecode
16
+
17
+ odebiram summary
18
+
@@ -0,0 +1,17 @@
1
+ tacrpy/__init__.py,sha256=5EqHQTmrErChJWgYELv5IVBCiCS_LdHM873KIaDBHd8,69
2
+ tacrpy/data_operations.py,sha256=hofQLx2q-XV_MILHEntUwnoG-6wlz-uQ2IR35KPwKqs,2751
3
+ tacrpy/analytics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ tacrpy/data_fetcher/__init__.py,sha256=leOLhwRHvGW4tN79HNOEjSKLfQW7mKEPhhn8lwIidw0,68
5
+ tacrpy/data_fetcher/googlesheets.py,sha256=yqHOVAwyCA_xajDtsJAFfwi0PJH3Ireoowu50hnQAdY,9674
6
+ tacrpy/data_fetcher/isvavai.py,sha256=xPhGbKF_GV1QEG5R-u6Dv83deymnJtlvZ-GsfzBNbLA,5441
7
+ tacrpy/data_fetcher/ssot.py,sha256=UP7nXbqeOExKaA9g2vuIFDJ12rElIfRJM3HhS8w92q4,52143
8
+ tacrpy/datahub/__init__.py,sha256=0zK9D2SShhdxCfHDh0sPiQxn__YxVjB7d6cEIS2U4g4,122
9
+ tacrpy/datahub/data_lineage.py,sha256=-QqvyihMHUZ5hiSghye2BjObs_A5JuJbjlFiyA4FrG8,3425
10
+ tacrpy/datahub/datasets.py,sha256=Qs71cziF2igP1XWVmMOUufE8whiRJ-dPWG1YJOZf9YE,16806
11
+ tacrpy/datahub/glossary.py,sha256=mD3u2A8ve5T26hebF6oRqF67GhgHfHw_ct3YKFMnj94,18424
12
+ tacrpy/datahub/import_checks.py,sha256=A10G9Cb8RoDskLzXM4R6Ek_x2uCJu7LtLfphjoN34Pc,6031
13
+ tacrpy/datahub/openapi.py,sha256=M8ewVDiywa2UT5G4Wz0Q6YUxl4oxrbf9fFv2QeDYgQ4,2147
14
+ sista_tacrpy-1.0.12.dist-info/METADATA,sha256=0Sx1HcECha_eIR0983Kms9IMgiTOtH8uQDLQd2LCSPE,414
15
+ sista_tacrpy-1.0.12.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
16
+ sista_tacrpy-1.0.12.dist-info/top_level.txt,sha256=BqpXuN5c5p-Kf_Qv8U1hT8dbV6NhdnLZ7QQa4wAvBH4,7
17
+ sista_tacrpy-1.0.12.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.41.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ tacrpy
tacrpy/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ # from . import nlp
2
+ from . import datahub
3
+ from . import data_fetcher
File without changes
@@ -0,0 +1,3 @@
1
+ from . import googlesheets
2
+ from . import ssot
3
+ from . import isvavai
@@ -0,0 +1,237 @@
1
+ """Modul na načítání dat, které jsou uložené v BigQuery jakožto 'zdroj pravdy'."""
2
+
3
+ import pandas as pd
4
+ import gspread
5
+
6
+ #from google.colab import auth
7
+ #auth.authenticate_user()
8
+
9
+
10
+ #from google.auth import default
11
+ #creds, _ = default()
12
+
13
+
14
+ def _load_df_from_google_sheet(creds, file_id, worksheet_idx):
15
+ gc = gspread.authorize(creds)
16
+ sht = gc.open_by_key(file_id)
17
+ worksheet = sht.get_worksheet(worksheet_idx)
18
+ rows = worksheet.get_all_values()
19
+ df = pd.DataFrame.from_records(rows[1:], columns=rows[0])
20
+ return df
21
+
22
+
23
+ class Projects:
24
+ """ Třída, která načítá a reprezentuje tabulku projektů.
25
+
26
+ Funguje pouze v rámci Google Colab prostředí.
27
+
28
+ :param projects: DataFrame načtených dat ze zdroje nebo z nově vytvořené (vyfiltrované) instance
29
+ :type projects: DataFrame
30
+ :param summary: DataFrame s agregovanými údaji na úrovni veřejných soutěží
31
+ :type summary: DataFrame
32
+ """
33
+
34
+ def __init__(self, creds_or_df: object):
35
+ """ Kontstruktor, který načte data do DataFrame, očistí finanční hodnoty a vytvoří agregovanou tabulku.
36
+
37
+ :param creds_or_df: údaje, které slouží k authenizaci v rámci Google Colab nebo přímo DataFrame projektu
38
+ """
39
+
40
+ self.projects = None
41
+ if isinstance(creds_or_df, pd.DataFrame):
42
+ self.projects = creds_or_df
43
+ else:
44
+ self.projects = self._get_projects(creds_or_df)
45
+ self._finance_cleaning('Náklady celkem')
46
+ self._finance_cleaning('Podpora celkem')
47
+ self._finance_cleaning('Ostatní celkem')
48
+ self.summary = self.create_summary()
49
+
50
+
51
+ def _get_projects(self, creds_or_df: object) -> pd.DataFrame:
52
+ """ Načte data o projektech ze "zdroje pravdy" z googlesheets uloženého na Google disku.
53
+
54
+ Lze použít pouze v rámci Google Colab prostředí.
55
+
56
+ :param creds_or_df: údaje, které slouží k authenizaci v rámci Google Colab nebo přímo DataFrame projektu
57
+ :return: DataFrame načtených dat ze zdroje
58
+ """
59
+
60
+ file_id = "1Ax1OYkdg3IA1YZki0fePizgQR6zOuzq7VGhFgeMorDQ"
61
+ return _load_df_from_google_sheet(creds_or_df, file_id, 0)
62
+
63
+
64
+ def _finance_cleaning(self, column_name: str):
65
+ """ Interní funkce, která očistí finanční data.
66
+
67
+ :param column_name: název sloupce, ve kterém se mají finanční data očistit
68
+ """
69
+
70
+ self.projects[column_name].fillna(0, inplace=True)
71
+ self.projects[column_name] = self.projects[column_name].str.replace(',', '.')
72
+ self.projects[column_name] = self.projects[column_name].replace('', '0')
73
+ self.projects[column_name] = self.projects[column_name].astype(float)
74
+
75
+
76
+ def _check_missing_items(self, provided_items: tuple, existing_items: list, item_name: str):
77
+ """Ověří, zda se všechny zadané položky nacházejí v existujícím seznamu.
78
+
79
+ Pokud jsou nalezeny chybějící položky, vyvolá ValueError s chybovou zprávou.
80
+
81
+ :param provided_items: Tuple položek zadaných pro filtrování.
82
+ :param existing_items: Seznam všech unikátních položek nacházejících se v datové sadě.
83
+ :param item_name: Popisný název položky, který se použije v chabové hlášce.
84
+
85
+ :raises ValueError: Pokud alespoň jedna zadaná položka neexistuje v datové sadě.
86
+ """
87
+
88
+ missing_items = [item for item in provided_items if item not in existing_items]
89
+ if missing_items:
90
+ raise ValueError(f'{item_name} {missing_items} neexistuje/neexistují.')
91
+
92
+
93
+
94
+ def create_summary(self, level: str = 'cfp') -> pd.DataFrame:
95
+ """ Vytvoří agregovaný souhrn buď na úrovni veřejných soutěží (defaultní) nebo na úrovni programů.
96
+
97
+ :param level: určuje, na jaké úrovni se provede agregace
98
+
99
+ * 'cfp' (defaultní) - na úrovni veřejných soutěží
100
+ * 'prog' - na úrovni programů
101
+ :return: agregovaný DataFrame, který obsahuje:
102
+
103
+ * Počet podaných projektů
104
+ * Počet podpořených projektů
105
+ * Náklady podpořených projektů
106
+ * Podpora podpořených projektů
107
+ """
108
+
109
+ if level not in ['cfp', 'prog']:
110
+ raise ValueError('Neexistující forma agregace.')
111
+
112
+ temp_df = self.projects.copy()
113
+ temp_df['Podpořené'] = temp_df.apply(
114
+ lambda x: 'Ano' if x['Fáze projektu'] in ['Realizace', 'Implementace', 'Ukončené'] else 'Ne', axis=1)
115
+ submitted = temp_df.groupby(['Kód programu', 'Kód VS']).agg(
116
+ {'Kód projektu': 'count', 'Náklady celkem': 'sum', 'Podpora celkem': 'sum'}).reset_index()
117
+ funded = temp_df[temp_df['Podpořené'] == 'Ano'].groupby(['Kód programu', 'Kód VS']).agg(
118
+ {'Kód projektu': 'count', 'Náklady celkem': 'sum', 'Podpora celkem': 'sum'}).reset_index()
119
+
120
+ summary_df = pd.merge(submitted[['Kód programu', 'Kód VS', 'Kód projektu']], funded, how='inner',
121
+ on=['Kód programu', 'Kód VS'])
122
+ summary_df.columns = ['Kód programu', 'Kód VS', 'Podané', 'Podpořené', 'Náklady', 'Podpora']
123
+
124
+ if level == 'cfp':
125
+ pass
126
+ elif level == 'prog':
127
+ summary_df = summary_df.groupby('Kód programu').agg('sum', numeric_only=True).reset_index()
128
+
129
+ return summary_df
130
+
131
+
132
+ def select_programme(self, *args: str) -> 'Projects':
133
+ """ Vyfiltruje tabulku tak, aby obsahovala pouze projekty vybraných programů.
134
+
135
+ :param args: kódy programů, které se mají vyfiltrovat
136
+ :return: nová instance třídy Projects s vyfiltrovanými údaji
137
+ :raise: ValueError
138
+ """
139
+
140
+ existing_programmes = self.projects['Kód programu'].unique()
141
+ self._check_missing_items(args, existing_programmes, 'Programy')
142
+
143
+ select_df = self.projects[self.projects['Kód programu'].isin(args)].reset_index(drop=True)
144
+ return Projects(select_df) # todo maybe another class Programms?
145
+
146
+
147
+ def select_cfp(self, *args: str) -> 'Projects':
148
+ """ Vyfiltruje tabulku tak, aby obsahovala pouze projekty vybraných veřejných soutěží.
149
+
150
+ :param args: kódy veřejných soutěží, které se mají vyfiltrovat
151
+ :return: nová instance třídy Projects s vyfiltrovanými údaji
152
+ :raise: ValueError
153
+ """
154
+
155
+ existing_cfp = self.projects['Kód VS'].unique()
156
+ self._check_missing_items(args, existing_cfp, 'Veřejné soutěže')
157
+
158
+ select_df = self.projects[self.projects['Kód VS'].isin(args)].reset_index(drop=True)
159
+ return Projects(select_df)
160
+
161
+
162
+ def select_funded(self) -> 'Projects':
163
+ """ Vyfiltruje tabulku tak, aby obsahovala pouze podpořené projekty.
164
+
165
+ :return: nová instance třídy Projects s vyfiltrovanými údaji
166
+ """
167
+
168
+ funded_states = ['Realizace', 'Implementace', 'Ukončené']
169
+ select_df = self.projects[self.projects['Fáze projektu'].isin(funded_states)].reset_index(drop=True)
170
+ return Projects(select_df)
171
+
172
+
173
+ def projects_finance(creds_or_df: object) -> pd.DataFrame:
174
+ """ Načte data o financích projektů ze "zdroje pravdy" z googlesheets uloženého na Google disku.
175
+
176
+ Finance jsou v rozdělení po jednotlivých letech.
177
+ Lze použít pouze v rámci Google Colab prostředí.
178
+
179
+ :param creds_or_df: údaje, které slouží k authenizaci v rámci Google Colab
180
+ :return: DataFrame načtených dat ze zdroje
181
+ """
182
+
183
+ file_id = "1Ax1OYkdg3IA1YZki0fePizgQR6zOuzq7VGhFgeMorDQ"
184
+ return _load_df_from_google_sheet(creds_or_df, file_id, 1)
185
+
186
+
187
+ def organizations(creds_or_df: object) -> pd.DataFrame:
188
+ """ Načte data o uchazečích/příjemcích ze "zdroje pravdy" z googlesheets uloženého na Google disku.
189
+
190
+ Lze použít pouze v rámci Google Colab prostředí.
191
+
192
+ :param creds_or_df: údaje, které slouží k authenizaci v rámci Google Colab
193
+ :return: DataFrame načtených dat ze zdroje
194
+ """
195
+
196
+ file_id = "1h7HpPn-G0_XY2gb_sExAQDkzR1TswGUH_2FuHCWhbRg"
197
+ return _load_df_from_google_sheet(creds_or_df, file_id, 0)
198
+
199
+
200
+ def organizations_finance(creds_or_df: object) -> pd.DataFrame:
201
+ """ Načte data o financích uchazečů/příjemců ze "zdroje pravdy" z googlesheets uloženého na Google disku.
202
+
203
+ Finance jsou v rozdělení po jednotlivých letech.
204
+ Lze použít pouze v rámci Google Colab prostředí.
205
+
206
+ :param creds_or_df: údaje, které slouží k authenizaci v rámci Google Colab
207
+ :return: DataFrame načtených dat ze zdroje
208
+ """
209
+
210
+ file_id = "1h7HpPn-G0_XY2gb_sExAQDkzR1TswGUH_2FuHCWhbRg"
211
+ return _load_df_from_google_sheet(creds_or_df, file_id, 1)
212
+
213
+
214
+ def results(creds_or_df: object) -> pd.DataFrame:
215
+ """ Načte data o výsledcích ze "zdroje pravdy" z googlesheets uloženého na Google disku.
216
+
217
+ Lze použít pouze v rámci Google Colab prostředí.
218
+
219
+ :param creds_or_df: údaje, které slouží k authenizaci v rámci Google Colab
220
+ :return: DataFrame načtených dat ze zdroje
221
+ """
222
+
223
+ file_id = "1eSE6gB8bwuP6OVwVVhQojQLS6aPi_q8t7gK6VhPyiRw"
224
+ return _load_df_from_google_sheet(creds_or_df, file_id, 0)
225
+
226
+
227
+ def cfp(creds_or_df: object) -> pd.DataFrame:
228
+ """ Načte data o veřejných soutěží z googlesheets uloženého na Google disku.
229
+
230
+ Lze použít pouze v rámci Google Colab prostředí.
231
+
232
+ :param creds_or_df: údaje, které slouží k authenizaci v rámci Google Colab
233
+ :return: DataFrame načtených dat ze zdroje
234
+ """
235
+
236
+ file_id = "1FaVienG6ceJGdqSTyD5tpsUsRGxgPii6BWOL73Vk2_s"
237
+ return _load_df_from_google_sheet(creds_or_df, file_id, 1).iloc[:, 0:15]
@@ -0,0 +1,162 @@
1
+ """Modul na načítání dat z IS VaVaI a STARFOSu."""
2
+
3
+ import pandas as pd
4
+ import requests
5
+ import string
6
+ from tqdm import tqdm
7
+ from typing import Union
8
+ from bs4 import BeautifulSoup
9
+
10
+
11
+ def isvav_projects() -> pd.DataFrame:
12
+ """ Načte data o příjemcích z otevřených dat IS VaVaI.
13
+ Data jsou aktualizovaná cca jednou za čtvrt roku.
14
+
15
+ :return: DataFrame načtených dat ze zdroje
16
+ """
17
+
18
+ df = pd.read_csv("https://www.isvavai.cz/dokumenty/opendata/CEP-projekty.csv")
19
+ return df
20
+
21
+
22
+ def isvav_organizations() -> pd.DataFrame:
23
+ """ Načte data o projektech z otevřených dat IS VaVaI.
24
+ Data jsou aktualizovaná cca jednou za čtvrt roku.
25
+
26
+ :return: DataFrame načtených dat ze zdroje
27
+ """
28
+
29
+ df = pd.read_csv("https://www.isvavai.cz/dokumenty/opendata/CEP-ucastnici.csv")
30
+ return df
31
+
32
+
33
+ def get_providers() -> list:
34
+ """ Stáhne seznam kódu všech poskytovatelů v IS VaVaI.
35
+ Data jsou získána pomocí web scrapingu z webu IS VaVaI.
36
+
37
+ :return: seznam kódu poskytovatelů
38
+ """
39
+
40
+ base_url = 'https://www.isvavai.cz/cea?s=poskytovatele&n='
41
+
42
+ provider_list = []
43
+ for page in range(0, 2):
44
+ url = base_url + str(page)
45
+ html = requests.get(url).content
46
+ parsed_html = BeautifulSoup(html, 'html.parser')
47
+
48
+ for i in parsed_html.findAll('b', attrs={'class': 'abbr'}):
49
+ provider_list.append(i.find('a').text)
50
+
51
+ # nejsou v seznamu aktivních poskytovatelů, jedná se o historická ministerstva
52
+ # ministerstvo hospodářství a ministesrtvo informatiky
53
+ provider_list.extend(['MH0', 'MI0'])
54
+ return provider_list
55
+
56
+
57
+ def starfos_projects(prog_select: Union[str, list] = None,
58
+ prov_select: Union[str, list] = None) -> Union[pd.DataFrame, dict[str]]:
59
+ """ Stáhne ze STARFOS projekty buď podle kódů programů nebo kódů poskytovatelů
60
+
61
+ Volá API endpoint, který slouží pro vytváření exportů. Výstup exportu převede na DataFrame.
62
+
63
+ :param prog_select: seznam programů
64
+ :param prov_select: seznam poskytovatelů
65
+ :return: projekty ze STARFOS
66
+ """
67
+
68
+ url = 'https://old.starfos.tacr.cz/api/starfos/export'
69
+ headers = {'content-type': 'application/json'}
70
+
71
+ common_query_template = {
72
+ "collection": "isvav_project",
73
+ "language_ui": "cs",
74
+ "format": "xlsx",
75
+ "limit": 0,
76
+ "columns": ["code", "name", "anot", "name_en", "anot_en", "x_solve_begin_year", "x_solve_end_year"],
77
+ "filters": {}
78
+ }
79
+
80
+ if prog_select:
81
+ programme_filter = {
82
+ "programme__code": {
83
+ "option_codes": prog_select
84
+ }
85
+ }
86
+ common_query_template['filters'].update(programme_filter)
87
+
88
+ if prov_select:
89
+ provider_filter = {
90
+ "programme__funder__code": {
91
+ "option_codes": prov_select
92
+ }
93
+ }
94
+ common_query_template['filters'].update(provider_filter)
95
+
96
+ try:
97
+ r = requests.post(url, headers=headers, json=common_query_template, stream=True)
98
+ r.raise_for_status()
99
+ df = pd.read_excel(r.content)
100
+ return df
101
+ except requests.exceptions.RequestException as e:
102
+ if not prog_select or prov_select:
103
+ return {'error': str(e),
104
+ 'additional_info': 'You need to enter at least one programme (prog_select) or provider (prov_select).'}
105
+ else:
106
+ return {'error': str(e), 'additional_info': 'Unknown error.'}
107
+
108
+
109
+ def starfos_projects_all() -> pd.DataFrame:
110
+ """ Stáhne ze STARFOS všechny projekty.
111
+
112
+ Postupně volá API endpoint, který slouží pro vytváření exportu, za jednotlivé poskytovatele. Výjimku tvoří GA ČR,
113
+ který přesahuje maximální limit 20 000 záznamů, proto se volá po jednotlivých programech (resp. zkouší různé
114
+ kombinace s G na začátku). Výstupy se skládají do jednoho DataFrame.
115
+
116
+ :return: projekty ze STARFOS
117
+ """
118
+
119
+ url = 'https://old.starfos.tacr.cz/api/starfos/export'
120
+ headers = {'content-type': 'application/json'}
121
+
122
+ df_list = []
123
+
124
+ provider_list = get_providers()
125
+
126
+ common_query_template = {
127
+ "collection": "isvav_project",
128
+ "language_ui": "cs",
129
+ "format": "xlsx",
130
+ "limit": 0,
131
+ "columns": ["code", "name", "anot", "name_en", "anot_en", "x_solve_begin_year", "x_solve_end_year"],
132
+ "filters": {}
133
+ }
134
+
135
+ for prov in tqdm(provider_list):
136
+ query_template = common_query_template.copy()
137
+
138
+ if prov == 'GA0':
139
+ programme_list = ['G' + i for i in string.ascii_uppercase]
140
+ for prog in programme_list:
141
+ query_template['filters'] = {
142
+ "programme__code": {
143
+ "option_codes": [prog]
144
+ }
145
+ }
146
+ r = requests.post(url, headers=headers, json=query_template, stream=True)
147
+ df = pd.read_excel(r.content)
148
+ df['provider'] = prov
149
+ df_list.append(df)
150
+ else:
151
+ query_template['filters'] = {
152
+ "programme__funder__code": {
153
+ "option_codes": [prov]
154
+ }
155
+ }
156
+
157
+ r = requests.post(url, headers=headers, json=query_template, stream=True)
158
+ df = pd.read_excel(r.content)
159
+ df['provider'] = prov
160
+ df_list.append(df)
161
+ df_concat = pd.concat(df_list).reset_index(drop=True)
162
+ return df_concat