feat: implement get hardware info api

This commit is contained in:
Stefan Stammberger 2021-06-12 15:07:35 +02:00
parent b62e52aee0
commit 51e369cf14
No known key found for this signature in database
GPG key ID: 645FA807E935D9D5
7 changed files with 200 additions and 6 deletions

0
app/auth/__init__.py Normal file
View file

View file

View file

@ -0,0 +1,83 @@
import json
import time
import psutil
from fastapi import Request
SLEEP_TIME = 1
CPU_USAGE_INTERVAL = 0.5
HW_INFO_YIELD_TIME = SLEEP_TIME+CPU_USAGE_INTERVAL
async def subscribe_hardware_info(request: Request):
while True:
if await request.is_disconnected():
# stop if client disconnects
break
yield get_hardware_info()
time.sleep(SLEEP_TIME)
def get_hardware_info() -> map:
info = {}
info['cpu_overall_percent'] = psutil.cpu_percent(
interval=CPU_USAGE_INTERVAL)
info['cpu_per_cpu_percent'] = psutil.cpu_percent(
interval=CPU_USAGE_INTERVAL, percpu=True)
v = psutil.virtual_memory()
info['vram_total_bytes'] = v.total
info['vram_available_bytes'] = v.available
info['vram_used_bytes'] = v.used
info['vram_usage_percent'] = v.percent
s = psutil.swap_memory()
info['swap_ram_total_bytes'] = s.total
info['swap_used_bytes'] = s.used
info['swap_usage_bytes'] = s.percent
info['temperatures_celsius'] = psutil.sensors_temperatures()
info['boot_time_timestamp'] = psutil.boot_time()
disk_io = psutil.disk_io_counters()
info['disk_io_read_count'] = disk_io.read_count
info['disk_io_write_count'] = disk_io.write_count
info['disk_io_read_bytes'] = disk_io.read_bytes
info['disk_io_write_bytes'] = disk_io.write_bytes
disks = []
partitions = psutil.disk_partitions()
for partition in partitions:
p = {}
p['device'] = partition.device
p['mountpoint'] = partition.mountpoint
p['filesystem_type'] = partition.fstype
try:
usage = psutil.disk_usage(partition.mountpoint)
p['partition_usage_bytes'] = usage.total
p['partition_used_bytes'] = usage.used
p['partition_free_bytes'] = usage.free
p['partition_percent'] = usage.percent
except PermissionError:
continue
disks.append(p)
nets = []
addresses = psutil.net_if_addrs()
for name, address in addresses.items():
net = {}
nets.append(net)
net['interface_name'] = name
for a in address:
if str(a.family) == 'AddressFamily.AF_INET':
net['address'] = a.address
elif str(a.family) == 'AddressFamily.AF_PACKET':
net['mac_address'] = a.address
net_io = psutil.net_io_counters()
info['networks'] = nets
info['networks_bytes_sent'] = net_io.bytes_sent
info['networks_bytes_received'] = net_io.bytes_recv
return json.dumps(info)

14
app/routers/setup.py Normal file
View file

@ -0,0 +1,14 @@
from fastapi import APIRouter, HTTPException, status
from fastapi.params import Depends
from app.auth.auth_bearer import JWTBearer
router = APIRouter(
prefix="/setup",
tags=["Setup"]
)
@router.get("/status", dependencies=[Depends(JWTBearer())])
def get_status():
return HTTPException(status_code=status.HTTP_501_NOT_IMPLEMENTED)

View file

@ -1,8 +1,11 @@
from fastapi import APIRouter, HTTPException, status
from fastapi import APIRouter, HTTPException, status, Request
from fastapi.params import Depends
from sse_starlette.sse import EventSourceResponse
from app.auth.auth_handler import signJWT
from app.auth.auth_bearer import JWTBearer
from app.repositories.hardware_info import HW_INFO_YIELD_TIME, get_hardware_info, subscribe_hardware_info
from app.routers.system_docs import get_hw_info_json
router = APIRouter(
prefix="/system",
@ -11,7 +14,8 @@ router = APIRouter(
@router.post("/login", summary="Logs the user in with password A",
response_description="JWT token for the current session.")
response_description="JWT token for the current session.",
status_code=status.HTTP_200_OK)
def login(password_a: str):
if password_a == "123":
return signJWT()
@ -20,6 +24,37 @@ def login(password_a: str):
detail="Password is wrong")
@router.get("/temperatures", dependencies=[Depends(JWTBearer())])
def get_temperatures():
return "45 °C"
@router.get("/hardware_info",
summary="Get hardware status information.",
response_description="Returns a JSON string with hardware information:\n" +
get_hw_info_json,
dependencies=[Depends(JWTBearer())],
status_code=status.HTTP_200_OK)
def hw_info() -> map:
return get_hardware_info()
@router.get("/hardware_info_sub",
summary="Subscribe to hardware status information.",
response_description=f"Yields a JSON string with hardware information every {HW_INFO_YIELD_TIME} seconds:\n" +
get_hw_info_json,
dependencies=[Depends(JWTBearer())],
status_code=status.HTTP_200_OK)
async def hw_info_sub(request: Request):
return EventSourceResponse(subscribe_hardware_info(request))
@ router.post("/reboot",
summary="Reboots the system",
dependencies=[Depends(JWTBearer())],
status_code=status.HTTP_200_OK)
def reboot_system():
return HTTPException(status.HTTP_501_NOT_IMPLEMENTED)
@ router.post("/shutdown",
summary="Shuts the system down",
dependencies=[Depends(JWTBearer())],
status_code=status.HTTP_200_OK)
def reboot_system():
return HTTPException(status.HTTP_501_NOT_IMPLEMENTED)

View file

@ -0,0 +1,60 @@
get_hw_info_json = """
```JSON
{
"cpu_overall_percent": 15.8,
"cpu_per_cpu_percent": [
11.8,
6.1,
12.5,
],
"vram_total_bytes": 25134919680,
"vram_available_bytes": 17240051712,
"vram_used_bytes": 6044856320,
"vram_usage_percent": 31.4,
"swap_ram_total_bytes": 2147479552,
"swap_used_bytes": 0,
"swap_usage_bytes": 0,
"temperatures_celsius": {
"coretemp": [
[
"Core 1",
51,
84,
100
],
[
"Core 2",
53,
84,
100
],
[
"Core 3",
50,
84,
100
]
]
},
"boot_time_timestamp": 1623486468,
"disk_io_read_count": 254574,
"disk_io_write_count": 133353,
"disk_io_read_bytes": 5306839040,
"disk_io_write_bytes": 5593076736,
"networks": [
{
"interface_name": "lo",
"address": "127.0.0.1",
"mac_address": "00:00:00:00:00:00"
},
{
"interface_name": "enp4s0",
"address": "192.168.1.23",
"mac_address": "35:a3:5c:6a:4a:f0"
},
],
"networks_bytes_sent": 137088249,
"networks_bytes_received": 1603400654
}
```
"""

View file

@ -3,4 +3,6 @@ pydantic==1.8.2
uvicorn==0.14.0
PyJWT==2.1.0
python-decouple==3.4
autopep8
autopep
psutil==5.8.0
sse_starlette==0.7.2