commit
a31624bbce
7 changed files with 294 additions and 0 deletions
-
162.gitignore
-
8.streamlit/secrets.toml.template
-
3README.md
-
107home.py
-
3pages/1_Reports.py
-
BINrequierements.txt
-
11test.py
@ -0,0 +1,162 @@ |
|||||
|
# Byte-compiled / optimized / DLL files |
||||
|
__pycache__/ |
||||
|
*.py[cod] |
||||
|
*$py.class |
||||
|
|
||||
|
# C extensions |
||||
|
*.so |
||||
|
|
||||
|
# Distribution / packaging |
||||
|
.Python |
||||
|
build/ |
||||
|
develop-eggs/ |
||||
|
dist/ |
||||
|
downloads/ |
||||
|
eggs/ |
||||
|
.eggs/ |
||||
|
lib/ |
||||
|
lib64/ |
||||
|
parts/ |
||||
|
sdist/ |
||||
|
var/ |
||||
|
wheels/ |
||||
|
share/python-wheels/ |
||||
|
*.egg-info/ |
||||
|
.installed.cfg |
||||
|
*.egg |
||||
|
MANIFEST |
||||
|
|
||||
|
# 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/latest/usage/project/#working-with-version-control |
||||
|
.pdm.toml |
||||
|
.pdm-python |
||||
|
.pdm-build/ |
||||
|
|
||||
|
# 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/ |
@ -0,0 +1,8 @@ |
|||||
|
[db_info] |
||||
|
host = 'host_ip' |
||||
|
username = 'user' |
||||
|
password = 'password' |
||||
|
db_name = 'databse name' |
||||
|
[auth] |
||||
|
check_url = 'https://api.jkhsakha.ru/auth/get_current_user/' |
||||
|
auth_url = 'https://api.jkhsakha.ru/auth/login/' |
@ -0,0 +1,3 @@ |
|||||
|
1. поменять значения в файле .streamlit/secrets.toml.template, сохранить под названием secrets.toml |
||||
|
2. pip install -r requierements.txt |
||||
|
3. streamlit run .\home.py |
@ -0,0 +1,107 @@ |
|||||
|
import streamlit as st |
||||
|
import pandas as pd |
||||
|
import requests |
||||
|
from streamlit_cookies_manager import CookieManager |
||||
|
from sqlalchemy import create_engine, text |
||||
|
db = st.secrets.db_info |
||||
|
auth = st.secrets.auth |
||||
|
|
||||
|
cookies = CookieManager() |
||||
|
if not cookies.ready(): |
||||
|
# Wait for the component to load and send us current cookies. |
||||
|
st.stop() |
||||
|
|
||||
|
|
||||
|
if token:=cookies.get("token"): |
||||
|
st.session_state["token"] = token |
||||
|
|
||||
|
|
||||
|
def check_token(): |
||||
|
if 'token' in st.session_state: |
||||
|
r = requests.get(auth.check_url+st.session_state["token"]) |
||||
|
if r.status_code==200: |
||||
|
st.session_state["auth"]=r.json() |
||||
|
return True |
||||
|
return False |
||||
|
|
||||
|
|
||||
|
def logout(): |
||||
|
del st.session_state["token"] |
||||
|
del cookies["token"] |
||||
|
|
||||
|
def get_token(username:str,password:str ): |
||||
|
r = requests.post(auth.auth_url,data={'username':username, 'password':password}) |
||||
|
if r.status_code==200: |
||||
|
data = r.json() |
||||
|
st.session_state["token"] = data["access_token"] |
||||
|
cookies["token"] = data["access_token"] |
||||
|
return True |
||||
|
return False |
||||
|
|
||||
|
def login_form(): |
||||
|
with st.form("Авторизация"): |
||||
|
username = st.text_input(label="Имя пользователя") |
||||
|
password = st.text_input(label="Пароль", type="password") |
||||
|
submitted = st.form_submit_button("Войти") |
||||
|
if all((submitted , username, password)): |
||||
|
if get_token(username,password): |
||||
|
st.rerun() |
||||
|
else: |
||||
|
st.error("Имя или пароль указаны неправильно!") |
||||
|
else: |
||||
|
st.warning("Нужно заполнить имя и пароль!") |
||||
|
def side_bar(): |
||||
|
with st.sidebar: |
||||
|
st.markdown(f"""Вы вошли как <span style='color: red;'>{st.session_state.auth.get('login')}</span>""", unsafe_allow_html=True) |
||||
|
logoutted = st.button("Выход") |
||||
|
if logoutted: |
||||
|
logout() |
||||
|
st.rerun() |
||||
|
with st.popover("Open popover"): |
||||
|
st.markdown("Hello World 👋") |
||||
|
name = st.text_input("What's your name?") |
||||
|
st.write(name) |
||||
|
|
||||
|
|
||||
|
|
||||
|
def home_page(): |
||||
|
option = st.selectbox( |
||||
|
"Выберете далее", |
||||
|
("SQL", "EXCEL"), |
||||
|
) |
||||
|
if option =="SQL": |
||||
|
engine= create_engine(f"mssql+pyodbc://{db.username}:{db.password}@{db.host}/{db.db_name}?driver=ODBC+Driver+17+for+SQL+Server") |
||||
|
|
||||
|
df = pd.read_sql_query(sql =text("SELECT * FROM tParameters"), con=engine, index_col="id") |
||||
|
search_str = st.text_input("Строка поиска") |
||||
|
df_top5 = df[df["name"].str.lower().str.contains(search_str.lower())].groupby().aggregate("value":"avg") |
||||
|
table = st.dataframe(df_top5, selection_mode='single-row', on_select='rerun') |
||||
|
if row_id :=table.get("selection").get("rows"): |
||||
|
vote(row_id[0],df.iloc[row_id[0]].to_dict()) |
||||
|
elif option == 'EXCEL': |
||||
|
uploaded_file = st.file_uploader("Загрузить файл EXCEL") |
||||
|
if uploaded_file is not None: |
||||
|
dataframe = pd.read_excel(uploaded_file) |
||||
|
st.write(dataframe) |
||||
|
st.link_button("Переход на страницу Reports","/Reports") |
||||
|
|
||||
|
@st.dialog("Модальное окно") |
||||
|
def vote(id: int,item_dict:dict): |
||||
|
id = st.text_input(label="ID", value=str(id), disabled=True) |
||||
|
id_group = st.text_input(label="id_group", value=str(item_dict.get('id_group')),) |
||||
|
name = st.text_input(label="name", value=str(item_dict.get('name')),) |
||||
|
format = st.text_input(label="format", value=str(item_dict.get('format')),) |
||||
|
vtable = st.text_input(label="vtable", value=str(item_dict.get('vtable')),) |
||||
|
unit = st.text_input(label="unit", value=str(item_dict.get('unit')),) |
||||
|
exact_format = st.text_input(label="exact_format", value=str(item_dict.get('exact_format')),) |
||||
|
inHistory = st.text_input(label="inHistory", value=str(item_dict.get('inHistory')),) |
||||
|
if st.button("Submit"): |
||||
|
#какая то функция обновления данных |
||||
|
st.rerun() |
||||
|
|
||||
|
if __name__ == "__main__": |
||||
|
if check_token(): |
||||
|
side_bar() |
||||
|
home_page() |
||||
|
else: |
||||
|
login_form() |
@ -0,0 +1,3 @@ |
|||||
|
import streamlit as st |
||||
|
|
||||
|
st.write("Страница Report") |
@ -0,0 +1,11 @@ |
|||||
|
import pandas as pd |
||||
|
from sqlalchemy import create_engine, text |
||||
|
|
||||
|
engine = create_engine('URL DB') |
||||
|
|
||||
|
df = pd.read_sql_query(text("SELECT DISTINCT id, name FROM Table"), con = engine.connect(), index_col="id") |
||||
|
|
||||
|
|
||||
|
for i in list(df.values()): |
||||
|
stmt = text("UPDATE table SET name = :new_name WHERE id =:id").bind_params(new_name = "dasdasdas", id=i.index) |
||||
|
engine.execute(stmt) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue