Skip to content

Commit fec97ef

Browse files
committed
Merge branch 'develop' into feature/publishing
2 parents f317d24 + a1295a6 commit fec97ef

File tree

14 files changed

+157
-16
lines changed

14 files changed

+157
-16
lines changed

.github/workflows/pipeline.yaml

+6-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ jobs:
5454
run: |
5555
mypy .
5656
57-
- name: Run unit tests
57+
- name: Run common security issue checker
5858
run: |
59-
pytest .
59+
bandit -c pyproject.toml -r .
60+
61+
- name: Run unit tests + code coverage
62+
run: |
63+
coverage run -m pytest .

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
__pycache__
22
*.egg-info
3+
*.log
4+
.coverage
35
.mypy_cache
6+
.pypirc
47
.pytest_cache
58
.ruff_cache
6-
.pypirc
79
.venv
810
dist

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
With pywaveshare, you can easily use the functionality of the [Waveshare GSM/GPRS/GNSS HAT for Raspberry Pi](https://www.waveshare.com/gsm-gprs-gnss-hat.htm). On this module a SIM868 Controller is doing the job to connect your Raspberry Pi with the world just by using a SIM card.
44

55
## Changelog
6-
[See this document.](https://github.com/acmacunlay/pywaveshare/blob/master/CHANGELOG.md)
6+
[See this document.](https://github.com/acmacunlay/pywaveshare/blob/main/CHANGELOG.md)
77

88
## Overview
99
pywaveshare was written for Python 3. It provides the following features
@@ -180,4 +180,4 @@ if gsm.UrlResponse_available() > 0:
180180

181181

182182
## License
183-
[See this document.](https://github.com/acmacunlay/pywaveshare/blob/master/LICENSE)
183+
[See this document.](https://github.com/acmacunlay/pywaveshare/blob/main/LICENSE)

pyproject.toml

+15-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
55
[project]
66
name = "pywaveshare"
77
version = "0.5.0a0"
8-
dependencies = ["RPi.GPIO", "pyserial"]
8+
dependencies = ["pyserial", "RPi.GPIO", "typing-extensions"]
99
requires-python = ">=3.7"
1010
authors = [{ name = "Tarek Tounsi", email = "[email protected]" }]
1111
maintainers = [
@@ -38,13 +38,25 @@ classifiers = [
3838
]
3939

4040
[project.optional-dependencies]
41-
dev = ["build", "mypy", "pytest", "ruff", "setuptools", "twine"]
41+
dev = [
42+
"bandit",
43+
"build",
44+
"coverage",
45+
"mypy",
46+
"pytest",
47+
"ruff",
48+
"setuptools",
49+
"twine",
50+
]
4251

4352
[project.urls]
4453
Homepage = "https://github.com/acmacunlay/pywaveshare"
4554
Repository = "https://github.com/acmacunlay/pywaveshare.git"
46-
# TODO: Changelog = ""
55+
Changelog = "https://github.com/acmacunlay/pywaveshare/blob/main/CHANGELOG.md"
4756

4857
[[tool.mypy.overrides]]
4958
module = ["RPi", "RPi.GPIO", "serial"]
5059
ignore_missing_imports = true
60+
61+
[tool.bandit]
62+
exclude_dirs = ["tests", ".venv"]

src/pywaveshare/boards/sim868/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,7 @@ def __processData(self):
320320
rawData = match[0][1].split(",")
321321
self.__GPRSIPaddress = rawData[2].replace('"', "")
322322

323-
if self.__GPRSIPaddress != "0.0.0.0":
323+
if self.__GPRSIPaddress != "0.0.0.0": # nosec
324324
self.__GPRSready = True
325325
else:
326326
self.__GPRSready = False
+9-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1-
from . import config, worker
1+
from . import config, itc, worker
22

33

44
class Client:
5+
logger = config.get_logger("client")
6+
57
def __init__(self, config: config.Config) -> None:
68
self.config = config
79
self.worker = worker.Worker(self.config)
10+
11+
def start(self) -> None:
12+
itc.IS_WORKER_RUNNING.set()
813
self.worker.start()
14+
15+
def send_at_command(self, command: str):
16+
pass

src/pywaveshare/boards/sim868/config.py

+69
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,72 @@
1+
import json
2+
import logging
3+
import logging.config
4+
import time
5+
6+
LOGGING_CONFIG = {
7+
"version": 1,
8+
"formatters": {
9+
"txt": {
10+
"format": "[%(asctime)s.%(msecs)03d][%(levelname)s]: %(message)s",
11+
"datefmt": "%Y-%m-%dT%H:%M:%S",
12+
},
13+
"jsonl": {
14+
"format": json.dumps(
15+
{
16+
"timestamp": "%(asctime)s.%(msecs)03d",
17+
"process": "%(process)d",
18+
"thread": "%(thread)d",
19+
"logger": "%(name)s",
20+
"level": "%(levelname)s",
21+
"source": "%(pathname)s:%(lineno)d",
22+
"message": "%(message)s",
23+
}
24+
),
25+
"datefmt": "%Y-%m-%dT%H:%M:%S",
26+
},
27+
},
28+
"filters": {},
29+
"handlers": {
30+
"file": {
31+
"class": "logging.FileHandler",
32+
"filename": "event.log",
33+
"formatter": "jsonl",
34+
"level": "DEBUG",
35+
"filters": [],
36+
},
37+
"stream": {
38+
"class": "logging.StreamHandler",
39+
"formatter": "txt",
40+
"level": "DEBUG",
41+
"filters": [],
42+
},
43+
},
44+
"loggers": {
45+
"client": {
46+
"handlers": ["file", "stream"],
47+
"level": "DEBUG",
48+
"propagate": True,
49+
},
50+
"worker": {
51+
"handlers": ["file", "stream"],
52+
"level": "DEBUG",
53+
"propagate": True,
54+
},
55+
"protocol": {
56+
"handlers": ["file", "stream"],
57+
"level": "DEBUG",
58+
"propagate": True,
59+
},
60+
},
61+
}
62+
logging.Formatter.converter = time.gmtime
63+
logging.config.dictConfig(LOGGING_CONFIG)
64+
65+
66+
def get_logger(id: str) -> logging.Logger:
67+
return logging.getLogger(id)
68+
69+
170
class Config:
271
def __init__(self, serial_port: str, baud_rate: int, encoding: str) -> None:
372
self.serial_port = serial_port

src/pywaveshare/boards/sim868/itc.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
from __future__ import annotations
2+
13
import queue
24
import threading
35

46
IS_WORKER_RUNNING = threading.Event()
57

6-
ACQUIRE_SERIAL_OBJECT = threading.Lock()
8+
SERIAL_LOCK = threading.Lock()
9+
C2W_Q_LOCK = threading.Lock()
10+
"""
11+
If acquired, then the acquirer can to safely work on `CLIENT_TO_WORKER_Q` queue.
12+
"""
713

8-
ON_SERIAL_RX: queue.Queue[bytes] = queue.Queue()
9-
ON_SERIAL_TX: queue.Queue[bytes] = queue.Queue()
14+
CLIENT_TO_WORKER_Q: queue.Queue[bytes] = queue.Queue()
15+
WORKER_TO_SERIAL_Q: queue.Queue[bytes] = queue.Queue()
16+
SERIAL_TO_WORKER_Q: queue.Queue[bytes] = queue.Queue()
+27-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,31 @@
11
import abc
2+
import typing
23

34

4-
class SupportedProtocol(abc.ABC):
5+
class SupportedStandard(abc.ABC):
6+
NAME: typing.Optional[str] = None
7+
8+
RESPONSE_PATTERN = r""
9+
10+
11+
class SMS(SupportedStandard):
12+
NAME = "SMS"
13+
14+
RESPONSE_PATTERN = (
15+
r"loremipsumdolorsitamet"
16+
r"loremipsumdolorsitamet"
17+
r"loremipsumdolorsitamet"
18+
r"loremipsumdolorsitamet"
19+
r"loremipsumdolorsitamet"
20+
r"loremipsumdolorsitamet"
21+
r"loremipsumdolorsitamet"
22+
)
23+
24+
25+
class SupportedProtocolFactory:
526
pass
27+
28+
29+
if __name__ == "__main__":
30+
protocol = SMS()
31+
print(protocol.RESPONSE_PATTERN)
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import typing
2+
3+
import typing_extensions
4+
5+
SMSSend = typing_extensions.TypedDict(
6+
"SMSSend",
7+
{
8+
"Recipients": typing.List[str],
9+
"Message": str,
10+
},
11+
)
+4-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import threading
22

3-
from . import config, itc
3+
from . import config, itc, protocols
44

55

66
class Worker(threading.Thread):
7+
logger = config.get_logger("worker")
8+
79
def __init__(self, config: config.Config) -> None:
810
super().__init__()
911

1012
self.config = config
13+
self.protocols = protocols.SupportedProtocolFactory()
1114

1215
def run(self) -> None:
13-
itc.IS_WORKER_RUNNING.set()
1416
while itc.IS_WORKER_RUNNING.is_set():
1517
pass

tests/unit/boards/__init__.py

Whitespace-only changes.

tests/unit/boards/sim868/__init__.py

Whitespace-only changes.

tests/unit/boards/sim868/test_client.py

Whitespace-only changes.

0 commit comments

Comments
 (0)