keboola-streamlit 0.0.1__tar.gz
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.
- keboola_streamlit-0.0.1/LICENSE +21 -0
- keboola_streamlit-0.0.1/PKG-INFO +88 -0
- keboola_streamlit-0.0.1/README.md +69 -0
- keboola_streamlit-0.0.1/setup.cfg +4 -0
- keboola_streamlit-0.0.1/setup.py +42 -0
- keboola_streamlit-0.0.1/src/keboola_streamlit/__init__.py +1 -0
- keboola_streamlit-0.0.1/src/keboola_streamlit/keboola_streamlit.py +282 -0
- keboola_streamlit-0.0.1/src/keboola_streamlit.egg-info/PKG-INFO +88 -0
- keboola_streamlit-0.0.1/src/keboola_streamlit.egg-info/SOURCES.txt +11 -0
- keboola_streamlit-0.0.1/src/keboola_streamlit.egg-info/dependency_links.txt +1 -0
- keboola_streamlit-0.0.1/src/keboola_streamlit.egg-info/not-zip-safe +1 -0
- keboola_streamlit-0.0.1/src/keboola_streamlit.egg-info/requires.txt +6 -0
- keboola_streamlit-0.0.1/src/keboola_streamlit.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Vojta Tůma
|
|
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.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: keboola_streamlit
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Keboola Streamlit simplifies the use of Keboola Storage API within Streamlit apps, providing easy-to-use functions for authentication, data retrieval, event logging, and data loading.
|
|
5
|
+
Author: pandyandy
|
|
6
|
+
Author-email: novakovadrea@gmail.com
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Information Technology
|
|
12
|
+
Classifier: Intended Audience :: Education
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
16
|
+
Requires-Python: >=3.7
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
|
|
20
|
+
# KeboolaStreamlit
|
|
21
|
+
|
|
22
|
+
KeboolaStreamlit is a Python package that facilitates the integration of Streamlit applications with the Keboola Storage API. It provides various functionalities for authentication, data retrieval, event creation, and data loading in a Keboola environment.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
To install KeboolaStreamlit, you can use `pip`:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install keboola-streamlit
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
### Initialization
|
|
35
|
+
|
|
36
|
+
Create an instance of the `KeboolaStreamlit` class with the required parameters:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from keboola_streamlit import KeboolaStreamlit
|
|
40
|
+
|
|
41
|
+
keboola = KeboolaStreamlit(root_url='https://connection.keboola.com', token='YOUR_API_TOKEN')
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Authentication Check
|
|
45
|
+
|
|
46
|
+
Ensure that the user is authenticated and authorized to access the Streamlit app:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
keboola.auth_check(required_role_id='YOUR_REQUIRED_ROLE_ID')
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Retrieve Data
|
|
53
|
+
|
|
54
|
+
Fetch data from a Keboola Storage table and return it as a Pandas DataFrame:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
df = keboola.get_data(table_id='YOUR_TABLE_ID')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Load Data
|
|
61
|
+
|
|
62
|
+
Load data from a Pandas DataFrame into a Keboola Storage table:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
keboola.load_data(table_id='YOUR_TABLE_ID', df=your_dataframe, is_incremental=False)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Create Event
|
|
69
|
+
|
|
70
|
+
Create an event in Keboola Storage to log activities:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
keboola.create_event(message='Your event message')
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Add Keboola Table Selection
|
|
77
|
+
|
|
78
|
+
Add a Keboola table selection form to your Streamlit app sidebar:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
selected_table_data = keboola.add_keboola_table_selection()
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
|
|
86
|
+
This project is licensed under the MIT License. See the `LICENSE` file for more details.
|
|
87
|
+
|
|
88
|
+
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# KeboolaStreamlit
|
|
2
|
+
|
|
3
|
+
KeboolaStreamlit is a Python package that facilitates the integration of Streamlit applications with the Keboola Storage API. It provides various functionalities for authentication, data retrieval, event creation, and data loading in a Keboola environment.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
To install KeboolaStreamlit, you can use `pip`:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install keboola-streamlit
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### Initialization
|
|
16
|
+
|
|
17
|
+
Create an instance of the `KeboolaStreamlit` class with the required parameters:
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
from keboola_streamlit import KeboolaStreamlit
|
|
21
|
+
|
|
22
|
+
keboola = KeboolaStreamlit(root_url='https://connection.keboola.com', token='YOUR_API_TOKEN')
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Authentication Check
|
|
26
|
+
|
|
27
|
+
Ensure that the user is authenticated and authorized to access the Streamlit app:
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
keboola.auth_check(required_role_id='YOUR_REQUIRED_ROLE_ID')
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Retrieve Data
|
|
34
|
+
|
|
35
|
+
Fetch data from a Keboola Storage table and return it as a Pandas DataFrame:
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
df = keboola.get_data(table_id='YOUR_TABLE_ID')
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Load Data
|
|
42
|
+
|
|
43
|
+
Load data from a Pandas DataFrame into a Keboola Storage table:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
keboola.load_data(table_id='YOUR_TABLE_ID', df=your_dataframe, is_incremental=False)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Create Event
|
|
50
|
+
|
|
51
|
+
Create an event in Keboola Storage to log activities:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
keboola.create_event(message='Your event message')
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Add Keboola Table Selection
|
|
58
|
+
|
|
59
|
+
Add a Keboola table selection form to your Streamlit app sidebar:
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
selected_table_data = keboola.add_keboola_table_selection()
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
This project is licensed under the MIT License. See the `LICENSE` file for more details.
|
|
68
|
+
|
|
69
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import setuptools
|
|
2
|
+
|
|
3
|
+
with open("README.md", "r") as f:
|
|
4
|
+
long_description = f.read()
|
|
5
|
+
|
|
6
|
+
setuptools.setup(
|
|
7
|
+
name='keboola_streamlit',
|
|
8
|
+
version='0.0.1',
|
|
9
|
+
author="pandyandy",
|
|
10
|
+
#project_urls=project_urls,
|
|
11
|
+
setup_requires=['pytest-runner', 'flake8'],
|
|
12
|
+
tests_require=['pytest'],
|
|
13
|
+
install_requires=[
|
|
14
|
+
'pygelf',
|
|
15
|
+
'pytz',
|
|
16
|
+
'deprecated',
|
|
17
|
+
'streamlit',
|
|
18
|
+
'pandas',
|
|
19
|
+
'kbcstorage'
|
|
20
|
+
],
|
|
21
|
+
author_email='novakovadrea@gmail.com',
|
|
22
|
+
description='Keboola Streamlit simplifies the use of Keboola Storage API within Streamlit apps, providing easy-to-use functions for authentication, data retrieval, event logging, and data loading.',
|
|
23
|
+
long_description=long_description,
|
|
24
|
+
long_description_content_type="text/markdown",
|
|
25
|
+
package_dir={'': 'src'},
|
|
26
|
+
packages=setuptools.find_packages(where='src'),
|
|
27
|
+
include_package_data=True,
|
|
28
|
+
zip_safe=False,
|
|
29
|
+
test_suite='tests',
|
|
30
|
+
classifiers=[
|
|
31
|
+
"Programming Language :: Python :: 3",
|
|
32
|
+
"License :: OSI Approved :: MIT License",
|
|
33
|
+
"Operating System :: OS Independent",
|
|
34
|
+
"Intended Audience :: Developers",
|
|
35
|
+
"Intended Audience :: Information Technology",
|
|
36
|
+
"Intended Audience :: Education",
|
|
37
|
+
"Topic :: Software Development :: Libraries",
|
|
38
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
39
|
+
"Development Status :: 5 - Production/Stable"
|
|
40
|
+
],
|
|
41
|
+
python_requires='>=3.7'
|
|
42
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .keboola_streamlit import KeboolaStreamlit
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import streamlit as st
|
|
2
|
+
import pandas as pd
|
|
3
|
+
import requests
|
|
4
|
+
import datetime
|
|
5
|
+
import os
|
|
6
|
+
|
|
7
|
+
from kbcstorage.client import Client
|
|
8
|
+
from requests.exceptions import HTTPError
|
|
9
|
+
from typing import Dict, List, Tuple, Optional
|
|
10
|
+
from streamlit.web.server.websocket_headers import _get_websocket_headers
|
|
11
|
+
|
|
12
|
+
class KeboolaStreamlit:
|
|
13
|
+
def __init__(self, root_url: str, token: str, tmp_data_folder: str = 'tmp/'):
|
|
14
|
+
"""
|
|
15
|
+
Initializes the KeboolaStreamlit class with the provided parameters.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
root_url (str): The root URL for the Keboola Storage API.
|
|
19
|
+
token (str): The API token for accessing Keboola Storage.
|
|
20
|
+
tmp_data_folder (str): The temporary data folder for storing files locally.
|
|
21
|
+
"""
|
|
22
|
+
self.client = Client(root_url, token)
|
|
23
|
+
self.token = token
|
|
24
|
+
self.root_url = root_url
|
|
25
|
+
self.dev_mockup_headers = None
|
|
26
|
+
self.tmp_data_folder = tmp_data_folder
|
|
27
|
+
|
|
28
|
+
def _get_headers(self) -> dict:
|
|
29
|
+
"""
|
|
30
|
+
Retrieves the headers for the current request, including development mock headers if set.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
dict: The headers for the current request.
|
|
34
|
+
"""
|
|
35
|
+
headers = _get_websocket_headers()
|
|
36
|
+
return headers if 'X-Kbc-User-Email' in headers else (self.dev_mockup_headers or {})
|
|
37
|
+
|
|
38
|
+
def _get_sapi_client(self):
|
|
39
|
+
"""
|
|
40
|
+
Getter for the Keboola Storage API client.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
Client: The Keboola Storage API client.
|
|
44
|
+
"""
|
|
45
|
+
return self.client
|
|
46
|
+
|
|
47
|
+
def set_dev_mockup_headers(self, headers: dict):
|
|
48
|
+
"""
|
|
49
|
+
Sets the development mock headers for local development.
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
headers (dict): The mock headers to set.
|
|
53
|
+
"""
|
|
54
|
+
self.dev_mockup_headers = headers
|
|
55
|
+
|
|
56
|
+
def auth_check(self, required_role_id: str):
|
|
57
|
+
"""
|
|
58
|
+
Checks the user's authentication and authorization based on the headers.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
required_role_id (str): The required role ID for authorization.
|
|
62
|
+
|
|
63
|
+
Stops the Streamlit app if the user is not authorized.
|
|
64
|
+
"""
|
|
65
|
+
headers = self._get_headers()
|
|
66
|
+
|
|
67
|
+
if 'X-Kbc-User-Email' in headers:
|
|
68
|
+
user_email = headers['X-Kbc-User-Email']
|
|
69
|
+
st.sidebar.write(f'Logged in as user: {user_email}')
|
|
70
|
+
st.sidebar.link_button('Logout', '/_proxy/sign_out', use_container_width=True)
|
|
71
|
+
with st.sidebar.expander('Show more'):
|
|
72
|
+
st.write(headers)
|
|
73
|
+
|
|
74
|
+
user_roles = headers.get('X-Kbc-User-Roles', [])
|
|
75
|
+
if required_role_id not in user_roles:
|
|
76
|
+
st.error("You are not authorised to use this app.")
|
|
77
|
+
st.stop()
|
|
78
|
+
else:
|
|
79
|
+
st.write('Not using proxy')
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def create_event(self, message: str = 'Streamlit App Create Event', endpoint: str = '/v2/storage/events/create', data: Optional[str] = None, jobId: Optional[int] = None):
|
|
83
|
+
"""
|
|
84
|
+
Creates an event in Keboola Storage.
|
|
85
|
+
|
|
86
|
+
Args:
|
|
87
|
+
jobId (int): The job ID for the event.
|
|
88
|
+
message (str): The message for the event.
|
|
89
|
+
data (str): The data associated with the event.
|
|
90
|
+
endpoint (str): The endpoint for the event.
|
|
91
|
+
|
|
92
|
+
Displays a success or error message in the Streamlit app.
|
|
93
|
+
"""
|
|
94
|
+
headers = self._get_headers()
|
|
95
|
+
url = f'{self.root_url}/v2/storage/events'
|
|
96
|
+
requestHeaders = {
|
|
97
|
+
'Content-Type': 'application/json',
|
|
98
|
+
'X-StorageApi-Token': self.token
|
|
99
|
+
}
|
|
100
|
+
requestData = {
|
|
101
|
+
'message': message,
|
|
102
|
+
'component': 'keboola.data-apps',
|
|
103
|
+
'params': {
|
|
104
|
+
'user': headers.get('X-Kbc-User-Email', 'Unknown'),
|
|
105
|
+
'time': datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
|
106
|
+
'endpoint': endpoint,
|
|
107
|
+
'event_type': 'keboola_data_app_write',
|
|
108
|
+
'event_application': headers['Origin']
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if data is not None:
|
|
113
|
+
requestData['params']['event_data'] = {'data': f'{data}'}
|
|
114
|
+
|
|
115
|
+
if jobId is not None:
|
|
116
|
+
requestData['params']['event_job_id'] = jobId
|
|
117
|
+
|
|
118
|
+
response = requests.post(url, headers=requestHeaders, json=requestData)
|
|
119
|
+
|
|
120
|
+
if response.status_code == 201:
|
|
121
|
+
st.success('Event sent.')
|
|
122
|
+
else:
|
|
123
|
+
st.error(f'Error: {response.status_code} - {response.text}')
|
|
124
|
+
|
|
125
|
+
def get_event_job_id(self, table_id: str, operation_name: str):
|
|
126
|
+
client = self._get_sapi_client()
|
|
127
|
+
job_list = client.jobs.list()
|
|
128
|
+
job_id = ''
|
|
129
|
+
for job in job_list:
|
|
130
|
+
if job['tableId'] == table_id and job['operationName'] == operation_name:
|
|
131
|
+
job_id = job['id']
|
|
132
|
+
break
|
|
133
|
+
return job_id
|
|
134
|
+
|
|
135
|
+
def get_data(self, table_id: str, endpoint: str = '/v2/storage/tables/export_to_file') -> pd.DataFrame:
|
|
136
|
+
"""
|
|
137
|
+
Retrieves data from a Keboola Storage table and returns it as a Pandas DataFrame.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
table_id (str): The ID of the table to retrieve data from.
|
|
141
|
+
endpoint (str): The endpoint for retrieving table details.
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
pd.DataFrame: The table data as a Pandas DataFrame.
|
|
145
|
+
"""
|
|
146
|
+
client = self._get_sapi_client()
|
|
147
|
+
try:
|
|
148
|
+
table_detail = client.tables.detail(table_id)
|
|
149
|
+
table_name = table_detail['name']
|
|
150
|
+
if not os.path.exists(self.tmp_data_folder):
|
|
151
|
+
os.makedirs(self.tmp_data_folder)
|
|
152
|
+
|
|
153
|
+
client.tables.export_to_file(table_id=table_id, path_name=self.tmp_data_folder)
|
|
154
|
+
|
|
155
|
+
csv_path = os.path.join(self.tmp_data_folder, f'{table_name}.csv')
|
|
156
|
+
if os.path.exists(csv_path):
|
|
157
|
+
os.remove(csv_path)
|
|
158
|
+
|
|
159
|
+
exported_file_path = os.path.join(self.tmp_data_folder, table_name)
|
|
160
|
+
os.rename(exported_file_path, csv_path)
|
|
161
|
+
df = pd.read_csv(csv_path)
|
|
162
|
+
|
|
163
|
+
event_job_id = self.get_event_job_id(table_id=table_id, operation_name='tableExport')
|
|
164
|
+
self.create_event(
|
|
165
|
+
jobId=event_job_id,
|
|
166
|
+
message='Streamlit App Download Data',
|
|
167
|
+
endpoint=endpoint
|
|
168
|
+
)
|
|
169
|
+
return df
|
|
170
|
+
except Exception as e:
|
|
171
|
+
st.error(f'An error occurred while retrieving data: {str(e)}')
|
|
172
|
+
return pd.DataFrame()
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def load_data(self, table_id: str, df: pd.DataFrame, is_incremental: bool = False, endpoint: str = '/v2/storage/tables/load'):
|
|
176
|
+
"""
|
|
177
|
+
Load data into an existing table.
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
table_id (str): The ID of the table to load data into.
|
|
181
|
+
df (pd.DataFrame): The DataFrame containing the data to be loaded.
|
|
182
|
+
is_incremental (bool): Whether to load incrementally (do not truncate the table). Defaults to False.
|
|
183
|
+
endpoint (str): The endpoint for loading data.
|
|
184
|
+
|
|
185
|
+
Displays a success or error message in the Streamlit app.
|
|
186
|
+
"""
|
|
187
|
+
client = self._get_sapi_client()
|
|
188
|
+
csv_path = f'{table_id}.csv'
|
|
189
|
+
try:
|
|
190
|
+
df.to_csv(csv_path, index=False)
|
|
191
|
+
client.tables.load(table_id=table_id, file_path=csv_path, is_incremental=is_incremental)
|
|
192
|
+
event_job_id = self.get_event_job_id(table_id=table_id, operation_name='tableImport')
|
|
193
|
+
self.create_event(
|
|
194
|
+
jobId=event_job_id,
|
|
195
|
+
message='Streamlit App Load Data',
|
|
196
|
+
endpoint=endpoint,
|
|
197
|
+
data=df
|
|
198
|
+
)
|
|
199
|
+
except Exception as e:
|
|
200
|
+
st.error(f'Data upload failed with: {str(e)}')
|
|
201
|
+
finally:
|
|
202
|
+
if os.path.exists(csv_path):
|
|
203
|
+
os.remove(csv_path)
|
|
204
|
+
|
|
205
|
+
def add_keboola_table_selection(self):
|
|
206
|
+
self._add_connection_form()
|
|
207
|
+
if 'kbc_storage_client' in st.session_state:
|
|
208
|
+
self._add_bucket_form()
|
|
209
|
+
if 'selected_bucket' in st.session_state and 'kbc_storage_client' in st.session_state:
|
|
210
|
+
self._add_table_form()
|
|
211
|
+
if 'selected_table_id' in st.session_state and 'kbc_storage_client' in st.session_state:
|
|
212
|
+
selected_table_id = st.session_state['selected_table_id']
|
|
213
|
+
if 'tables_data' not in st.session_state:
|
|
214
|
+
st.session_state['tables_data'] = {}
|
|
215
|
+
if selected_table_id not in st.session_state['tables_data']:
|
|
216
|
+
st.session_state['tables_data'][selected_table_id] = self.get_data(table_id=selected_table_id)
|
|
217
|
+
return st.session_state['tables_data'][selected_table_id]
|
|
218
|
+
return pd.DataFrame()
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
def _add_connection_form(self):
|
|
222
|
+
with st.sidebar.form('Connection Details'):
|
|
223
|
+
if st.form_submit_button('Connect', use_container_width=True):
|
|
224
|
+
try:
|
|
225
|
+
kbc_client = self._get_sapi_client()
|
|
226
|
+
|
|
227
|
+
if 'kbc_storage_client' in st.session_state:
|
|
228
|
+
st.session_state.pop('kbc_storage_client')
|
|
229
|
+
if 'selected_table' in st.session_state:
|
|
230
|
+
st.session_state.pop('selected_table')
|
|
231
|
+
if 'selected_table_id' in st.session_state:
|
|
232
|
+
st.session_state.pop('selected_table_id')
|
|
233
|
+
if 'selected_bucket' in st.session_state:
|
|
234
|
+
st.session_state.pop('selected_bucket')
|
|
235
|
+
if 'uploaded_file' in st.session_state:
|
|
236
|
+
st.session_state.pop('uploaded_file')
|
|
237
|
+
|
|
238
|
+
if self._get_bucket_list(kbc_client):
|
|
239
|
+
st.session_state['kbc_storage_client'] = kbc_client
|
|
240
|
+
st.session_state['bucket_list'] = self._get_bucket_list(kbc_client)
|
|
241
|
+
|
|
242
|
+
except Exception as e:
|
|
243
|
+
st.error(f'Connection failed: {str(e)}')
|
|
244
|
+
|
|
245
|
+
def _add_bucket_form(self):
|
|
246
|
+
with st.sidebar.form('Bucket Details'):
|
|
247
|
+
with st.header('Select a bucket from storage'):
|
|
248
|
+
bucket = st.selectbox('Bucket', self._get_buckets_from_bucket_list())
|
|
249
|
+
if st.form_submit_button('Select Bucket',use_container_width=True):
|
|
250
|
+
st.session_state['selected_bucket'] = bucket
|
|
251
|
+
|
|
252
|
+
def _add_table_form(self):
|
|
253
|
+
with st.sidebar.form('Table Details'):
|
|
254
|
+
table_names, tables = self._get_tables(st.session_state['selected_bucket'])
|
|
255
|
+
st.session_state['selected_table'] = st.selectbox('Table', table_names)
|
|
256
|
+
table_id = tables[st.session_state['selected_table']]['id']
|
|
257
|
+
if st.form_submit_button('Select table', use_container_width=True):
|
|
258
|
+
st.session_state['selected_table_id'] = table_id
|
|
259
|
+
|
|
260
|
+
def _get_bucket_list(self, kbc_storage_client):
|
|
261
|
+
try:
|
|
262
|
+
project_bucket_list = kbc_storage_client.buckets.list()
|
|
263
|
+
return project_bucket_list
|
|
264
|
+
except HTTPError:
|
|
265
|
+
st.error('Invalid Connection settings')
|
|
266
|
+
|
|
267
|
+
def _get_buckets_from_bucket_list(self):
|
|
268
|
+
try:
|
|
269
|
+
return [bucket['id'] for bucket in st.session_state['bucket_list']]
|
|
270
|
+
except Exception:
|
|
271
|
+
st.error('Could not list buckets')
|
|
272
|
+
|
|
273
|
+
def _get_tables(self, bucket_id: str) -> Tuple[List, Dict]:
|
|
274
|
+
try:
|
|
275
|
+
tables = {}
|
|
276
|
+
for table in st.session_state['kbc_storage_client'].buckets.list_tables(bucket_id):
|
|
277
|
+
tables[table['name']] = table
|
|
278
|
+
table_names = list(tables.keys())
|
|
279
|
+
return table_names, tables
|
|
280
|
+
except Exception as e:
|
|
281
|
+
st.error('Could not list tables')
|
|
282
|
+
st.error(e)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: keboola-streamlit
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Keboola Streamlit simplifies the use of Keboola Storage API within Streamlit apps, providing easy-to-use functions for authentication, data retrieval, event logging, and data loading.
|
|
5
|
+
Author: pandyandy
|
|
6
|
+
Author-email: novakovadrea@gmail.com
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
9
|
+
Classifier: Operating System :: OS Independent
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Information Technology
|
|
12
|
+
Classifier: Intended Audience :: Education
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
16
|
+
Requires-Python: >=3.7
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
|
|
20
|
+
# KeboolaStreamlit
|
|
21
|
+
|
|
22
|
+
KeboolaStreamlit is a Python package that facilitates the integration of Streamlit applications with the Keboola Storage API. It provides various functionalities for authentication, data retrieval, event creation, and data loading in a Keboola environment.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
To install KeboolaStreamlit, you can use `pip`:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install keboola-streamlit
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
### Initialization
|
|
35
|
+
|
|
36
|
+
Create an instance of the `KeboolaStreamlit` class with the required parameters:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
from keboola_streamlit import KeboolaStreamlit
|
|
40
|
+
|
|
41
|
+
keboola = KeboolaStreamlit(root_url='https://connection.keboola.com', token='YOUR_API_TOKEN')
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Authentication Check
|
|
45
|
+
|
|
46
|
+
Ensure that the user is authenticated and authorized to access the Streamlit app:
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
keboola.auth_check(required_role_id='YOUR_REQUIRED_ROLE_ID')
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Retrieve Data
|
|
53
|
+
|
|
54
|
+
Fetch data from a Keboola Storage table and return it as a Pandas DataFrame:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
df = keboola.get_data(table_id='YOUR_TABLE_ID')
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Load Data
|
|
61
|
+
|
|
62
|
+
Load data from a Pandas DataFrame into a Keboola Storage table:
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
keboola.load_data(table_id='YOUR_TABLE_ID', df=your_dataframe, is_incremental=False)
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Create Event
|
|
69
|
+
|
|
70
|
+
Create an event in Keboola Storage to log activities:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
keboola.create_event(message='Your event message')
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Add Keboola Table Selection
|
|
77
|
+
|
|
78
|
+
Add a Keboola table selection form to your Streamlit app sidebar:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
selected_table_data = keboola.add_keboola_table_selection()
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
|
|
86
|
+
This project is licensed under the MIT License. See the `LICENSE` file for more details.
|
|
87
|
+
|
|
88
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
setup.py
|
|
4
|
+
src/keboola_streamlit/__init__.py
|
|
5
|
+
src/keboola_streamlit/keboola_streamlit.py
|
|
6
|
+
src/keboola_streamlit.egg-info/PKG-INFO
|
|
7
|
+
src/keboola_streamlit.egg-info/SOURCES.txt
|
|
8
|
+
src/keboola_streamlit.egg-info/dependency_links.txt
|
|
9
|
+
src/keboola_streamlit.egg-info/not-zip-safe
|
|
10
|
+
src/keboola_streamlit.egg-info/requires.txt
|
|
11
|
+
src/keboola_streamlit.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
keboola_streamlit
|