5 Commits
Author SHA1 Message Date
C b4b0ccdac6 added rotating logs! epicsauce 2025-10-09 13:33:59 -07:00
C 32664c3a10 added optional logging to brickset 2025-10-09 13:33:51 -07:00
C 41ce94c85c Auto stash before rebase of "uv" 2025-10-09 12:55:38 -07:00
ph0sgene 397eddf299 rm 314t 2025-10-09 12:54:32 -07:00
C 8affb90308 refactor: Migrate build system to Hatch and integrate UV 2025-10-09 12:49:37 -07:00
5 changed files with 48 additions and 20 deletions

No files matched your search

+1
View File
@@ -9,6 +9,7 @@ __pycache__/
*.sqlite3 *.sqlite3
*.log *.log
poetry.lock poetry.lock
uv.lock
bin/build/ bin/build/
.zip .zip
snippet.py snippet.py
+1
View File
@@ -1,6 +1,7 @@
# Edderkop # Edderkop
environment: poetry environment: poetry
code style: black code style: black
built with built with
+7 -10
View File
@@ -2,12 +2,10 @@
name = "edderkop" name = "edderkop"
version = "0.1.0" version = "0.1.0"
description = "" description = ""
authors = [ authors = [{ name = "CF", email = "ph0sgene@pm.me" }]
{name = "CF", email = "chris-forst@pm.me"}
]
license = {text = "MIT"}
readme = "README.md"
requires-python = ">=3.13,<3.14" requires-python = ">=3.13,<3.14"
readme = "README.md"
license = { text = "MIT" }
dependencies = [ dependencies = [
"aiohttp (>=3.12.13,<4.0.0)", "aiohttp (>=3.12.13,<4.0.0)",
"dotenv (>=0.9.9,<0.10.0)", "dotenv (>=0.9.9,<0.10.0)",
@@ -20,13 +18,12 @@ dependencies = [
"aiosqlite (>=0.21.0,<0.22.0)", "aiosqlite (>=0.21.0,<0.22.0)",
] ]
[build-system] [build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"] requires = ["hatchling"]
build-backend = "poetry.core.masonry.api" build-backend = "hatchling.build"
[tool.poetry] [tool.uv]
package-mode = false package = false
[tool.bricksetapi] [tool.bricksetapi]
version = "0.1.0" version = "0.1.0"
+26 -4
View File
@@ -17,7 +17,7 @@ dotenv.load_dotenv()
class AsyncBricksetAPI: class AsyncBricksetAPI:
"""Asynchronous client for the Brickset API""" """Asynchronous client for the Brickset API"""
def __init__(self, debug: bool = False): def __init__(self, debug: bool = False, logger=None):
self.username = os.getenv("BRICKSET_USERNAME") self.username = os.getenv("BRICKSET_USERNAME")
self.password = os.getenv("BRICKSET_PASS") self.password = os.getenv("BRICKSET_PASS")
self.api_key = os.getenv("BRICKSET_API_KEY") self.api_key = os.getenv("BRICKSET_API_KEY")
@@ -25,6 +25,7 @@ class AsyncBricksetAPI:
self.headers = {"UserAgent": "Edderkop/0.1"} self.headers = {"UserAgent": "Edderkop/0.1"}
self.throttler = Throttler(rate_limit=500, period=60) self.throttler = Throttler(rate_limit=500, period=60)
self.user_hash = None self.user_hash = None
self.logger = logger
async def login(self) -> Dict[str, Any]: async def login(self) -> Dict[str, Any]:
"""Asynchronously authenticate with Brickset API""" """Asynchronously authenticate with Brickset API"""
@@ -41,10 +42,15 @@ class AsyncBricksetAPI:
) as response: ) as response:
if self.debug: if self.debug:
print(f"[@DEBUG] Login response status: {response.status}") print(f"[@DEBUG] Login response status: {response.status}")
if self.logger:
self.logger.debug(f"Login response status: {response.status}")
data = await response.read() data = await response.read()
result = json.loads(data.decode("utf-8")) result = json.loads(data.decode("utf-8"))
self.user_hash = result.get("hash") self.user_hash = result.get("hash")
if self.logger:
self.logger.info("Successfully authenticated with Brickset API")
return result return result
async def get_set(self, set_number: str) -> Dict[str, Any]: async def get_set(self, set_number: str) -> Dict[str, Any]:
@@ -73,13 +79,23 @@ class AsyncBricksetAPI:
) as response: ) as response:
if self.debug: if self.debug:
print(f"[@DEBUG] Get set response status: {response.status}") print(f"[@DEBUG] Get set response status: {response.status}")
if self.logger:
self.logger.debug(f"Get set response status: {response.status}")
if response.status == 200: if response.status == 200:
data = await response.read() data = await response.read()
result = json.loads(data.decode("utf-8")) result = json.loads(data.decode("utf-8"))
if not result.get("sets"): if not result.get("sets"):
raise ValueError(f"No data found for set {set_number}") error_msg = f"No data found for set {set_number}"
if self.logger:
self.logger.error(error_msg)
raise ValueError(error_msg)
if self.logger:
self.logger.info(
f"Successfully retrieved data for set {set_number}"
)
set_data = result["sets"][0] set_data = result["sets"][0]
our_set = { our_set = {
@@ -111,11 +127,17 @@ class AsyncBricksetAPI:
return our_set return our_set
elif response.status == 500: elif response.status == 500:
raise Exception( error_msg = (
"Internal Server Error: Please check API key and parameters." "Internal Server Error: Please check API key and parameters."
) )
if self.logger:
self.logger.error(error_msg)
raise Exception(error_msg)
else: else:
raise Exception(f"Unexpected response: {response.status}") error_msg = f"Unexpected response: {response.status}"
if self.logger:
self.logger.error(error_msg)
raise Exception(error_msg)
async def throttled_get_set(self, set_number: str) -> Dict[str, Any]: async def throttled_get_set(self, set_number: str) -> Dict[str, Any]:
"""Get set information with rate limiting""" """Get set information with rate limiting"""
+13 -6
View File
@@ -9,6 +9,7 @@ import dotenv
import os import os
import re import re
import logging import logging
from logging.handlers import RotatingFileHandler
from pathlib import Path from pathlib import Path
Path("./logs/").mkdir(parents=True, exist_ok=True) Path("./logs/").mkdir(parents=True, exist_ok=True)
@@ -18,7 +19,6 @@ import get_sq_env
import asquare as sq import asquare as sq
from abricksetapi import AsyncBricksetAPI from abricksetapi import AsyncBricksetAPI
lego = AsyncBricksetAPI(debug=True)
dotenv.load_dotenv() dotenv.load_dotenv()
SQUARE_LEGO_CAT_ID = os.environ.get("SQUARE_LEGO_CAT_ID") SQUARE_LEGO_CAT_ID = os.environ.get("SQUARE_LEGO_CAT_ID")
@@ -26,16 +26,23 @@ SQUARE_LEGO_CAT_ID = os.environ.get("SQUARE_LEGO_CAT_ID")
from asyncio_throttle.throttler import Throttler from asyncio_throttle.throttler import Throttler
logger = logging.getLogger("aiohttp.access") # set up logger
logging.basicConfig( logger = logging.getLogger("edderkop")
filename="./logs/edderkop.log", encoding="utf-8", level=logging.DEBUG logger.setLevel(logging.DEBUG)
) handler = RotatingFileHandler("./logs/", maxBytes=1024, backupCount=5)
logger.addHandler(handler)
lego = AsyncBricksetAPI(debug=True, logger=logger)
# logging.basicConfig(
# filename="./logs/edderkop.log", encoding="utf-8", level=logging.DEBUG
# )
UA = re.compile(r"^kopling\/?", re.IGNORECASE) UA = re.compile(r"^kopling\/?", re.IGNORECASE)
async def run_update(): async def run_update():
set_list = await sq.acat2id(SQUARE_LEGO_CAT_ID) set_list = await sq.acat2id(SQUARE_LEGO_CAT_ID) # type: ignore
for l_set in set_list: for l_set in set_list:
print(f"[@DEBUG]{l_set}") print(f"[@DEBUG]{l_set}")
l_setinfo = await lego.throttled_get_set(l_set["number"]) l_setinfo = await lego.throttled_get_set(l_set["number"])