Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
a069db4
refactor project structure
BurningSquid Aug 7, 2022
b037c27
vscode settings
BurningSquid Aug 7, 2022
0f8f346
python version change
BurningSquid Aug 7, 2022
2e5caea
dunder main
BurningSquid Aug 7, 2022
3d2de91
__init__.py
BurningSquid Aug 7, 2022
398fb74
rename
BurningSquid Aug 7, 2022
49ab40f
connection manager name
BurningSquid Aug 7, 2022
0b2213f
more vscode settings
BurningSquid Aug 7, 2022
63bbc56
logging in init
BurningSquid Aug 7, 2022
af9c74a
gitignore
BurningSquid Aug 7, 2022
ac01d97
constants
BurningSquid Aug 7, 2022
0180dec
refactor main WIP
BurningSquid Aug 7, 2022
522b450
refactor connection manager
BurningSquid Aug 7, 2022
54294ab
refactor tests WIP
BurningSquid Aug 7, 2022
e884dc8
refactor computer class
BurningSquid Aug 7, 2022
4795f79
test refactor
BurningSquid Aug 7, 2022
0938511
temp test script
BurningSquid Aug 7, 2022
7ca05ee
windows python path
BurningSquid Aug 7, 2022
be344d5
refactoring
BurningSquid Aug 7, 2022
dc942b0
computer tests
BurningSquid Aug 7, 2022
5739aad
hide pytest cache from explorer
BurningSquid Aug 7, 2022
4ce6d2c
comments
BurningSquid Aug 7, 2022
382a34a
get stats dict method
BurningSquid Aug 7, 2022
ef4da29
remove script
BurningSquid Aug 7, 2022
ffb9cef
debug module
BurningSquid Aug 7, 2022
aa21fce
computer class tests
BurningSquid Aug 7, 2022
9d83413
.env file
BurningSquid Aug 7, 2022
7280356
remove error handling
BurningSquid Aug 7, 2022
8a2763b
javascript fixes and more logging
BurningSquid Aug 7, 2022
e3da1c4
refactor tests
BurningSquid Aug 7, 2022
22b9f9b
helpers
BurningSquid Aug 7, 2022
27e3297
log message change
BurningSquid Aug 7, 2022
e19e1d5
refactoring js
BurningSquid Aug 7, 2022
59f13ac
readme updates
BurningSquid Aug 7, 2022
46d696c
refactor main
BurningSquid Aug 7, 2022
b38a2bc
more constants
BurningSquid Aug 7, 2022
fe86821
more constants
BurningSquid Aug 7, 2022
308612c
comment
BurningSquid Aug 7, 2022
7581d62
lowered number of points
BurningSquid Aug 7, 2022
e0d1299
Update README.md
BurningSquid Aug 7, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
PORT=8000
HOST=127.0.0.1
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
**/__pycache__
/logs/*.log
15 changes: 15 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Module",
"type": "python",
"request": "launch",
"module": "server_stats",
"justMyCode": true
}
]
}
18 changes: 18 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"python.formatting.provider": "black",
"terminal.integrated.env.linux": {
"PYTHONPATH": "${workspaceRoot}/src"
},
"terminal.integrated.env.windows": {
"PYTHONPATH": "${workspaceRoot}/src"
},
"files.exclude": {
"**/__pycache__": true,
"**/.pytest_cache": true
},
"python.testing.pytestArgs": [
"src"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
}
26 changes: 14 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,40 +18,42 @@ Three smaller, more detailed sections to view more in depth statistics on hardwa

## Tech



- [FastAPI](https://fastapi.tiangolo.com/) -
- HTML/CSS/JS
- [ChartJS](https://www.chartjs.org/)
- [Poetry](https://python-poetry.org/docs/basic-usage/)
- [Pytest](https://docs.pytest.org/en/7.1.x/)

## Usage
- Run main.py on the computer you wish to monitor, then connect to it via LAN (http://LANIP:8080/stats)



## Installation

[Python 3.7+](https://www.python.org/)

To run:
```
poetry install
poetry run python main.py
poetry run python -m server_stats
```
Connect to your ip, at the endpoint '/stats' on port 8080
Connect to your ip, at the main endpoint on port 8000 (by default)
```
http://YOUR_IP:8080/stats (if accessing from a different client machine than the host)
http://localhost:8080/stats (if youre accessing from the host machine)
http://YOUR_IP:8000/(if accessing from a different client machine than the host)
http://localhost:8080/ (if youre accessing from the host machine)
```
To run tests (development only):
```
poetry run pytest
```
## Development

Want to contribute? Great!
### Contributors

...

### TODO

- [ ] Temperature monitoring for Windows
- [ ] Visual display of temperature
- [ ] Js module for charts
- [ ] App integration tests strategy


## License
Expand Down
File renamed without changes.
88 changes: 0 additions & 88 deletions main.py

This file was deleted.

6 changes: 4 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
[tool.poetry]
name = "pythonproject"
name = "server-stats"
version = "0.1.0"
description = ""
authors = []

[tool.poetry.dependencies]
python = "^3.10"
python = ">=3.8.10,<=3.10"
fastapi = "^0.79.0"
psutil = "^5.9.1"
uvicorn = {extras = ["standard"], version = "^0.18.2"}
Jinja2 = "^3.1.2"
websockets = "^10.3"
python-dotenv = "^0.20.0"

[tool.poetry.dev-dependencies]
black = "^22.6.0"
pytest = "^7.1.2"
pytest-asyncio = "^0.19.0"
httpx = "^0.23.0"
requests = "^2.28.1"
trio = "^0.21.0"
asyncio = "^3.4.3"
pytest-asyncio = "^0.19.0"

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
8 changes: 8 additions & 0 deletions src/server_stats/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# REVIEW: in order to be recognized as a module must have a __init__.py file
# https://docs.python.org/3.8/library/__main__.html. Module can now be run with python -m "module name"

import logging

from .constants import LOGGING_DIR

logging.basicConfig(filename=LOGGING_DIR, filemode="w", level=logging.DEBUG)
95 changes: 95 additions & 0 deletions src/server_stats/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# REVIEW: imports should be sorted in groups: top is python standard library, middle is third party, bottom is local
import logging

import uvicorn
from fastapi import FastAPI, HTTPException, Request, WebSocket
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

# REVIEW: all internal imports should be relative
from .connection_manager import ConnectionManager
from .constants import (
HOST,
PORT,
ROOT,
STATIC_DIR,
STATIC_ROUTE,
TEMPLATES_DIR,
WEBSOCKET_ROUTE,
)
from .computer import Computer
from .helpers import generate_id

# REVIEW: best practice for logger is to initialize logger settings in __ini__.py
# then get the logger when being used in a script. __name__ is going to return main which was
# the name of the logger
logger = logging.getLogger(__name__)

# REVIEW: the __main__.py (called a dunder main) is the top-level script that is executed when the program is run
# https://docs.python.org/3.8/library/__main__.html

# REVIEW: good to have a separate function for main and
# call it in the if statement below
app = FastAPI()
connection_manager = ConnectionManager()
templates = Jinja2Templates(directory=TEMPLATES_DIR)

# REVIEW: Didn't do a ton of research on this but this may not be the recommended mounting pattern for static files
# https://fastapi.tiangolo.com/tutorial/static-files/
app.mount(
STATIC_ROUTE,
# REVIEW: file paths should be constants in most cases
StaticFiles(directory=STATIC_DIR),
name="static",
)


# REVIEW: not really needed to type NoReturn, can just have no type hint
# or type hint None if you really feel like it
@app.get("/favicon.ico")
async def favicon() -> None:
# No current FavIcon - fix later
raise HTTPException(status_code=403, detail="No favicon")


# REVIEW: Since there is only a single endpoint it should be kept as root
@app.get(ROOT, response_class=HTMLResponse)
def root(request: Request):
"""
HTTP endpoint to serve the Server Statistics Dashboard
:param request: HTTP Request from Client
:return: Returns the associated HTML files to the requesting client
"""
client_id = generate_id()
return templates.TemplateResponse(
"index.html", {"request": request, "id": client_id}
)


# REVIEW: Since there is only a single websocket it should be kept as root. As you add
# more websockets you can change this if necessary
@app.websocket(WEBSOCKET_ROUTE)
async def root_websocket(client_websocket: WebSocket):
"""
Web Socket endpoint for communicating the "Server Statistics" in JSON to the client. Communication with the
data visualization client is done here.
:param client_websocket: Incoming Web Socket request.
:return: No explicit return, just continuous requests for information from client
"""
# REVIEW: don't need to resend the connection since the .connect method already does this
await connection_manager.connect(client_websocket)
# Initial connection
while True:
# Client sending data....
data = await client_websocket.receive_json()

# DATAREQUEST is the asking protocol from the client requesting for the Hardware stats
if data["event"] == "DATAREQUEST":
await client_websocket.send_json(
{"event": "DATAREQUEST", "stats": Computer().get_stats_dict()}
)


if __name__ == "__main__":
uvicorn.run(app, port=PORT, host=HOST)
Loading