This commit is contained in:
Kseninia Mikhaylova 2024-05-15 12:40:15 +03:00
parent 1c35f21a6b
commit 704da3fc82
9 changed files with 133 additions and 10 deletions

4
.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.env
.vscode/
__pycache__/
poetry.lock

View File

@ -3,10 +3,10 @@ const links = [[
{ {
label: 'Состояние вендотеков', label: 'Состояние вендотеков',
icon: 'i-heroicons-credit-card', icon: 'i-heroicons-credit-card',
to: '/wtk', to: '/vtk',
}, },
{ label: 'Офис', to: '/wtk/office' }, { label: 'Офис', to: '/vtk/office' },
{ label: 'Парк', to: '/wtk/park' }, { label: 'Парк', to: '/vtk/park' },
], ],
[ [
{ {

View File

@ -2,7 +2,13 @@
export default defineNuxtConfig({ export default defineNuxtConfig({
devtools: { enabled: true }, devtools: { enabled: true },
modules: ["@nuxt/ui"], modules: ["@nuxt/ui"],
ssr: false,
devServer: { devServer: {
port: 3010 port: 3010
} },
runtimeConfig: {
public: {
apiBase: '', // can be overridden by NUXT_PUBLIC_API_BASE environment variable
}
},
}) })

View File

@ -0,0 +1,34 @@
<script setup lang="ts">
const config = useRuntimeConfig()
const route = useRoute()
interface APIBody {
data: any[],
status: 'success' | 'error'
}
const { data, pending, error, status } = await useLazyFetch<APIBody>(`${config.public.apiBase}/api/vtk/${route.params.slug}`, { server: false })
</script>
<template>
<UAlert v-if="status == 'error'" :title="`Произошла ошибка ${error?.statusCode}`"
:description="error?.data && error.data.detail ? error.data.detail : error?.statusMessage" />
<UTable v-else :loading="pending" :columns="[
{ key: 'sn', label: 'Serial Number' },
{ key: 'name', label: 'name' },
{ key: 'ip', label: 'IP' },
{ key: 'last_online', label: 'last_online' }
]" :rows="pending ? [] : data?.data">
<template #last_online-data="{ row }">
<UIcon name="i-heroicons-check-circle" class="text-green-500 text-xl" v-if="row.last_online == -1" />
<span class="flex align-baseline gap-1" v-else>
<UIcon name="i-heroicons-x-circle" class="text-red-500 text-xl" />
{{ new Date(row.last_online).toLocaleTimeString('ru-RU') }}
</span>
</template>
<template #name-data="{ row }">
<div class="text-wrap">
{{ row.name }}
</div>
</template>
</UTable>
</template>

View File

@ -1,3 +0,0 @@
<template>
slug
</template>

8
helpers.py Normal file
View File

@ -0,0 +1,8 @@
def flatten_dict(dd, separator='_', prefix=''):
res = {}
for key, value in dd.items():
if isinstance(value, dict):
res.update(flatten_dict(value, separator, prefix + key + separator))
else:
res[prefix + key] = value
return res

77
main.py
View File

@ -1,26 +1,99 @@
import requests import json
import os import os
from fastapi import FastAPI import pprint
import requests
from dotenv import load_dotenv
from fastapi import FastAPI, HTTPException
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
import logging import logging
from helpers import flatten_dict
load_dotenv()
logging.basicConfig( logging.basicConfig(
level=logging.INFO, level=logging.INFO,
format="%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s %(message)s", format="%(asctime)s %(levelname)s %(filename)s:%(lineno)d %(funcName)s %(message)s",
) )
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
origins = [ origins = [
"http://localhost", "http://localhost",
"http://localhost:3010",
"http://localhost:4173", "http://localhost:4173",
"http://localhost:5173", "http://localhost:5173",
"http://localhost:8000", "http://localhost:8000",
] ]
vtk = json.loads(os.getenv("VTK_KEYS"))
vtk_org = {}
api_app = FastAPI(title="api app") api_app = FastAPI(title="api app")
@api_app.get("/")
def test():
return {"app": "service monitoring api"}
@api_app.get("/vtk/{item_id}")
def get_vtk(item_id):
if not item_id in vtk:
raise HTTPException(status_code=404, detail="Item not found")
try:
if not item_id in vtk_org:
res = requests.get(
"https://my.vendotek.com/api/v1/org",
headers={"Authorization": f"Bearer {vtk[item_id]}"},
)
data = res.json()
org_id = data[0]["name"]
vtk_org[item_id] = org_id
res_unit = requests.get(
f"https://my.vendotek.com/api/v1/org/{vtk_org[item_id]}/unit",
headers={"Authorization": f"Bearer {vtk[item_id]}"},
)
data_unit = res_unit.json()
result = [
{
"sn": d["sn"],
"last_online": d["last_seen_at"],
"name": ", ".join(
list(filter(None, [d["location_name"], d["address"], d["city"]]))
),
"ip": list(
filter(
lambda item: item["name"] == "IP address",
list(
filter(
lambda item: item["id"] == "LAN",
list(
filter(
lambda item: item["id"] == "Communications",
d["modules"],
)
)[0]["modules"],
)
)[0]["details"],
)
)[0]["value"],
}
for d in data_unit
]
return {"status": "success", "data": result}
except Exception as e:
logger.error(e)
raise HTTPException(status_code=500, detail=str(e))
app = FastAPI(title="main app") app = FastAPI(title="main app")
app.exception_handler(404)
async def return_error():
return {"error": "custom error"}
app.add_middleware( app.add_middleware(
CORSMiddleware, CORSMiddleware,

View File

@ -10,6 +10,7 @@ python = "^3.10"
fastapi = "^0.111.0" fastapi = "^0.111.0"
uvicorn = "^0.29.0" uvicorn = "^0.29.0"
requests = "^2.31.0" requests = "^2.31.0"
python-dotenv = "^1.0.1"
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
taskipy = "^1.0.0" taskipy = "^1.0.0"
@ -20,4 +21,4 @@ build-backend = "poetry.core.masonry.api"
[tool.taskipy.tasks] [tool.taskipy.tasks]
build = "cd front && npm install && npm run generate" build = "cd front && npm install && npm run generate"
start = "uvicorn main:app --reload --host 0.0.0.0" start = "uvicorn main:app --reload --host 0.0.0.0 --port 8000"