anzu 0.1.3__tar.gz → 0.1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
anzu-0.1.5/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ *.pyc
2
+ __pycache__/
3
+ *.pkl
4
+ dist/
5
+ build/
6
+ .venv
@@ -1,35 +1,19 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: anzu
3
- Version: 0.1.3
4
- Summary: A package for updating queue items in a Django service
5
- Home-page: https://github.com/yourusername/queue_updater
6
- Author: Your Name
3
+ Version: 0.1.5
4
+ Summary: Anzu package for workers
7
5
  Author-email: Your Name <your.email@example.com>
8
6
  License: MIT
9
- Project-URL: Homepage, https://github.com/yourusername/queue_updater
10
- Project-URL: Bug Tracker, https://github.com/yourusername/queue_updater/issues
7
+ License-File: LICENSE
11
8
  Keywords: django,queue,update
12
- Classifier: Programming Language :: Python :: 3
13
9
  Classifier: License :: OSI Approved :: MIT License
14
10
  Classifier: Operating System :: OS Independent
15
- Requires-Python: >=3.6
16
- Description-Content-Type: text/markdown
17
- License-File: LICENSE
18
- Requires-Dist: requests>=2.25.0
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Python: >=3.8
19
13
  Requires-Dist: aiohttp>=3.7.3
20
14
  Requires-Dist: python-socketio>=5.12.1
21
- Provides-Extra: langfuse
22
- Requires-Dist: langfuse>=2.0.0; extra == "langfuse"
23
- Provides-Extra: dev
24
- Requires-Dist: pytest>=6.0.0; extra == "dev"
25
- Requires-Dist: black>=22.0.0; extra == "dev"
26
- Requires-Dist: isort>=5.0.0; extra == "dev"
27
- Requires-Dist: mypy>=0.900; extra == "dev"
28
- Requires-Dist: flake8>=4.0.0; extra == "dev"
29
- Dynamic: author
30
- Dynamic: home-page
31
- Dynamic: license-file
32
- Dynamic: requires-python
15
+ Requires-Dist: requests>=2.25.0
16
+ Description-Content-Type: text/markdown
33
17
 
34
18
  # Queue Updater
35
19
 
@@ -65,6 +49,7 @@ client.update_queue_item(
65
49
 
66
50
  # Or initialize using environment variables
67
51
  import os
52
+
68
53
  os.environ["DJANGO_URL"] = "https://your-django-service.com"
69
54
  os.environ["DJANGO_SUPERUSER_USERNAME"] = "admin"
70
55
  os.environ["DJANGO_SUPERUSER_PASSWORD"] = "password"
@@ -103,4 +88,4 @@ update_queue_item(
103
88
 
104
89
  ## License
105
90
 
106
- MIT
91
+ MIT
@@ -32,6 +32,7 @@ client.update_queue_item(
32
32
 
33
33
  # Or initialize using environment variables
34
34
  import os
35
+
35
36
  os.environ["DJANGO_URL"] = "https://your-django-service.com"
36
37
  os.environ["DJANGO_SUPERUSER_USERNAME"] = "admin"
37
38
  os.environ["DJANGO_SUPERUSER_PASSWORD"] = "password"
@@ -0,0 +1,5 @@
1
+ import anzu.logger
2
+ import anzu.websocket
3
+ import anzu.worker
4
+
5
+ __version__ = "2.3.0"
File without changes
@@ -0,0 +1 @@
1
+ from .logger import redis_logger, logger, AnzuLogger
@@ -0,0 +1,45 @@
1
+ import logging
2
+
3
+
4
+ class AnzuLogger:
5
+ _instance = None
6
+
7
+ def __new__(cls, level: str = logging.INFO, name: str = __name__):
8
+ # Ensures that only one instance of the logger is created
9
+ if cls._instance is None:
10
+ cls._instance = super(AnzuLogger, cls).__new__(cls)
11
+ cls._instance._logger = logging.getLogger(name)
12
+ cls._instance._logger.setLevel(logging.INFO) # Default log level
13
+ handler = logging.StreamHandler() # You can also use FileHandler
14
+ formatter = logging.Formatter(
15
+ "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
16
+ )
17
+ handler.setFormatter(formatter)
18
+ cls._instance._logger.addHandler(handler)
19
+
20
+ return cls._instance._logger
21
+
22
+ def get_logger(self):
23
+ """Returns the logger instance."""
24
+ return self._instance._logger
25
+
26
+ def set_name(self, name: str):
27
+ """Sets the name of the logger."""
28
+ self._instance._logger = logging.getLogger(name)
29
+
30
+ def add_file_handler(self, file_name: str):
31
+ """Adds a file handler to the logger."""
32
+ handler = logging.FileHandler(file_name)
33
+ formatter = logging.Formatter(
34
+ "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
35
+ )
36
+ handler.setFormatter(formatter)
37
+ self._instance._logger.addHandler(handler)
38
+
39
+ def remove_handler(self, handler):
40
+ """Removes a handler from the logger."""
41
+ self._instance._logger.removeHandler(handler)
42
+
43
+
44
+ logger = AnzuLogger()
45
+ redis_logger = AnzuLogger(name="redis_logger")
@@ -0,0 +1 @@
1
+ from .sockets import send_socket_response, emit_socket_event
@@ -0,0 +1,14 @@
1
+ import socketio
2
+
3
+ # Create client
4
+ sio = socketio.Client(ssl_verify=False)
5
+ sio_server = 'https://django:9500'
6
+
7
+ def emit_socket_event(event, data):
8
+ if sio.connected is False:
9
+ sio.connect(sio_server)
10
+
11
+ sio.emit(event, data)
12
+
13
+ def send_socket_response(event, data):
14
+ emit_socket_event(event, data)
@@ -0,0 +1,2 @@
1
+ from .client import update_queue_item
2
+ from .constants import WAITING, PROCESSING, FAILURE, SUCCESS
@@ -0,0 +1,112 @@
1
+ import json
2
+ import requests
3
+ from requests.auth import HTTPBasicAuth
4
+ from .exceptions import QueueUpdateError
5
+ from .utils import get_env_var, setup_logger
6
+
7
+ logger = setup_logger()
8
+
9
+
10
+ class QueueClient:
11
+ """Client for updating queue items in a Django service."""
12
+
13
+ def __init__(self, django_url=None, username=None, password=None, service_endpoint=None, verify_ssl=None):
14
+ """
15
+ Initialize the queue client with connection parameters.
16
+
17
+ Args:
18
+ django_url (str, optional): URL of the Django service. Defaults to DJANGO_URL env var.
19
+ username (str, optional): Django superuser username. Defaults to DJANGO_SUPERUSER_USERNAME env var.
20
+ password (str, optional): Django superuser password. Defaults to DJANGO_SUPERUSER_PASSWORD env var.
21
+ service_endpoint (str, optional): Service endpoint. Defaults to SERVICE_ENDPOINT env var or '/'.
22
+ verify_ssl (bool, optional): Whether to verify SSL certificates. Defaults to True unless URL contains 'https'.
23
+ """
24
+ self.django_url = django_url or get_env_var('DJANGO_URL', required=True)
25
+ self.username = username or get_env_var('DJANGO_SUPERUSER_USERNAME', required=True)
26
+ self.password = password or get_env_var('DJANGO_SUPERUSER_PASSWORD', required=True)
27
+ self.service_endpoint = service_endpoint or get_env_var('SERVICE_ENDPOINT', '/')
28
+
29
+ # Handle the verify_ssl parameter
30
+ if verify_ssl is None:
31
+ self.verify_ssl = False if 'https' in self.django_url else True
32
+ else:
33
+ self.verify_ssl = verify_ssl
34
+
35
+ self.headers = {
36
+ 'Content-Type': 'application/json'
37
+ }
38
+
39
+ def update_queue_item(self, qi_hash, status, data=None, error=None, timeout=10):
40
+ """
41
+ Update a queue item with the given status and optional data or error.
42
+
43
+ Args:
44
+ qi_hash (str): Hash of the queue item to update.
45
+ status (str): New status for the queue item.
46
+ data (dict, optional): Additional data to update. Defaults to None.
47
+ error (str, optional): Error message if applicable. Defaults to None.
48
+ timeout (int, optional): Request timeout in seconds. Defaults to 10.
49
+
50
+ Returns:
51
+ dict: Response data from the API
52
+
53
+ Raises:
54
+ TypeError: If data is not a dictionary.
55
+ QueueUpdateError: If the update request fails.
56
+ """
57
+ if not qi_hash:
58
+ logger.warning("No queue item to update")
59
+ return
60
+
61
+ payload = {
62
+ "status": status
63
+ }
64
+
65
+ if data is not None:
66
+ if not isinstance(data, dict):
67
+ raise TypeError(f"Expected dict, got {type(data)} with value: {data}")
68
+ payload.update(data)
69
+
70
+ if error is not None:
71
+ payload['error'] = error
72
+
73
+ url = f'{self.django_url}{self.service_endpoint}{qi_hash}/'
74
+
75
+ response = requests.request(
76
+ "PATCH",
77
+ url,
78
+ headers=self.headers,
79
+ data=json.dumps(payload),
80
+ auth=HTTPBasicAuth(self.username, self.password),
81
+ verify=self.verify_ssl,
82
+ timeout=timeout
83
+ )
84
+
85
+ if response.status_code not in [200, 204]:
86
+ response_text = None
87
+ if 'text/html' in response.headers.get('Content-Type', ''):
88
+ logger.error(f"Failed to update queue item. Status Code: {response.status_code}")
89
+ else:
90
+ response_text = response.text
91
+ logger.error(
92
+ f"Failed to update queue item. Status Code: {response.status_code}, Response: {response_text}")
93
+
94
+ raise QueueUpdateError(response.status_code, response_text)
95
+
96
+ try:
97
+ return response.json()
98
+ except (ValueError, json.JSONDecodeError):
99
+ # Return empty dict if no JSON in response
100
+ return {}
101
+
102
+
103
+ # For backwards compatibility
104
+ def update_queue_item(qi_hash, status, data=None, error=None):
105
+ """
106
+ Legacy function to update a queue item. Uses environment variables for connection details.
107
+
108
+ This function exists for backwards compatibility with the original code.
109
+ New code should use the QueueClient class instead.
110
+ """
111
+ client = QueueClient()
112
+ return client.update_queue_item(qi_hash, status, data, error)
@@ -0,0 +1,4 @@
1
+ WAITING = "0"
2
+ PROCESSING = "1"
3
+ SUCCESS = "2"
4
+ FAILURE = "3"
@@ -0,0 +1,14 @@
1
+ class QueueUpdaterError(Exception):
2
+ """Base exception for queue updater."""
3
+ pass
4
+
5
+
6
+ class QueueUpdateError(QueueUpdaterError):
7
+ """Exception raised when updating a queue item fails."""
8
+ def __init__(self, status_code, response_text=None):
9
+ self.status_code = status_code
10
+ self.response_text = response_text
11
+ message = f"Failed to update queue item. Status Code: {status_code}"
12
+ if response_text:
13
+ message += f", Response: {response_text}"
14
+ super().__init__(message)
@@ -0,0 +1,25 @@
1
+ import logging
2
+ import os
3
+
4
+
5
+ def get_env_var(name, default=None, required=False):
6
+ """Get environment variable with proper error handling."""
7
+ value = os.environ.get(name, default)
8
+ if required and value is None:
9
+ raise ValueError(f"Required environment variable '{name}' is not set")
10
+ return value
11
+
12
+
13
+ def setup_logger(name='queue_updater', level=logging.INFO):
14
+ """Setup and return a logger with the given name and level."""
15
+ logger = logging.getLogger(name)
16
+
17
+ # Only add handler if not already added to avoid duplicate logs
18
+ if not logger.handlers:
19
+ handler = logging.StreamHandler()
20
+ formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
21
+ handler.setFormatter(formatter)
22
+ logger.addHandler(handler)
23
+
24
+ logger.setLevel(level)
25
+ return logger
@@ -0,0 +1,38 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "anzu"
7
+ version = "0.1.5"
8
+ description = "Anzu package for workers"
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ authors = [
12
+ {name = "Your Name", email = "your.email@example.com"}
13
+ ]
14
+ license = {text = "MIT"}
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ ]
20
+ keywords = ["django", "queue", "update"]
21
+ dependencies = [
22
+ "requests>=2.25.0",
23
+ "aiohttp>=3.7.3",
24
+ "python-socketio>=5.12.1"
25
+ ]
26
+
27
+ [project.scripts]
28
+ anzu = "anzu:main"
29
+
30
+ [tool.hatch.version]
31
+ path = "anzu/__init__.py"
32
+
33
+ [tool.hatch.build.targets.sdist]
34
+ include = [
35
+ "/anzu",
36
+ ]
37
+
38
+
@@ -1,7 +0,0 @@
1
- from .worker.client import update_queue_item
2
- from .worker.constants import PROCESSING, WAITING, FAILURE, SUCCESS
3
- from .logger import logger, redis_logger, AnzuLogger
4
- from .websocket import send_socket_response, emit_socket_event
5
-
6
- __version__ = '0.1.2'
7
- __all__ = ['update_queue_item', 'SUCCESS', 'PROCESSING', 'FAILURE', 'WAITING', 'logger', 'redis_logger', 'AnzuLogger', 'emit_socket_event', 'send_socket_response']
@@ -1,106 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: anzu
3
- Version: 0.1.3
4
- Summary: A package for updating queue items in a Django service
5
- Home-page: https://github.com/yourusername/queue_updater
6
- Author: Your Name
7
- Author-email: Your Name <your.email@example.com>
8
- License: MIT
9
- Project-URL: Homepage, https://github.com/yourusername/queue_updater
10
- Project-URL: Bug Tracker, https://github.com/yourusername/queue_updater/issues
11
- Keywords: django,queue,update
12
- Classifier: Programming Language :: Python :: 3
13
- Classifier: License :: OSI Approved :: MIT License
14
- Classifier: Operating System :: OS Independent
15
- Requires-Python: >=3.6
16
- Description-Content-Type: text/markdown
17
- License-File: LICENSE
18
- Requires-Dist: requests>=2.25.0
19
- Requires-Dist: aiohttp>=3.7.3
20
- Requires-Dist: python-socketio>=5.12.1
21
- Provides-Extra: langfuse
22
- Requires-Dist: langfuse>=2.0.0; extra == "langfuse"
23
- Provides-Extra: dev
24
- Requires-Dist: pytest>=6.0.0; extra == "dev"
25
- Requires-Dist: black>=22.0.0; extra == "dev"
26
- Requires-Dist: isort>=5.0.0; extra == "dev"
27
- Requires-Dist: mypy>=0.900; extra == "dev"
28
- Requires-Dist: flake8>=4.0.0; extra == "dev"
29
- Dynamic: author
30
- Dynamic: home-page
31
- Dynamic: license-file
32
- Dynamic: requires-python
33
-
34
- # Queue Updater
35
-
36
- A simple Python package for updating queue items in a Django service.
37
-
38
- ## Installation
39
-
40
- ```bash
41
- pip install anzu
42
- ```
43
-
44
- ## Usage
45
-
46
- ### Using the QueueClient class (recommended)
47
-
48
- ```python
49
- from anzu import QueueClient
50
-
51
- # Initialize with explicit parameters
52
- client = QueueClient(
53
- django_url="https://your-django-service.com",
54
- username="admin",
55
- password="password",
56
- service_endpoint="/api/queue/"
57
- )
58
-
59
- # Update a queue item
60
- client.update_queue_item(
61
- qi_hash="abc123",
62
- status="completed",
63
- data={"result": "success"}
64
- )
65
-
66
- # Or initialize using environment variables
67
- import os
68
- os.environ["DJANGO_URL"] = "https://your-django-service.com"
69
- os.environ["DJANGO_SUPERUSER_USERNAME"] = "admin"
70
- os.environ["DJANGO_SUPERUSER_PASSWORD"] = "password"
71
- os.environ["SERVICE_ENDPOINT"] = "/api/queue/"
72
-
73
- client = QueueClient()
74
- client.update_queue_item("abc123", "completed")
75
- ```
76
-
77
- ### Using the legacy function (for backward compatibility)
78
-
79
- ```python
80
- import os
81
- from anzu import update_queue_item
82
-
83
- # Set required environment variables
84
- os.environ["DJANGO_URL"] = "https://your-django-service.com"
85
- os.environ["DJANGO_SUPERUSER_USERNAME"] = "admin"
86
- os.environ["DJANGO_SUPERUSER_PASSWORD"] = "password"
87
- os.environ["SERVICE_ENDPOINT"] = "/api/queue/"
88
-
89
- # Update a queue item
90
- update_queue_item(
91
- qi_hash="abc123",
92
- status="completed",
93
- data={"result": "success"}
94
- )
95
- ```
96
-
97
- ## Environment Variables
98
-
99
- - `DJANGO_URL`: URL of the Django service
100
- - `DJANGO_SUPERUSER_USERNAME`: Django superuser username
101
- - `DJANGO_SUPERUSER_PASSWORD`: Django superuser password
102
- - `SERVICE_ENDPOINT`: Service endpoint (defaults to '/')
103
-
104
- ## License
105
-
106
- MIT
@@ -1,10 +0,0 @@
1
- LICENSE
2
- README.md
3
- pyproject.toml
4
- setup.py
5
- anzu/__init__.py
6
- anzu.egg-info/PKG-INFO
7
- anzu.egg-info/SOURCES.txt
8
- anzu.egg-info/dependency_links.txt
9
- anzu.egg-info/requires.txt
10
- anzu.egg-info/top_level.txt
@@ -1 +0,0 @@
1
-
@@ -1,13 +0,0 @@
1
- requests>=2.25.0
2
- aiohttp>=3.7.3
3
- python-socketio>=5.12.1
4
-
5
- [dev]
6
- pytest>=6.0.0
7
- black>=22.0.0
8
- isort>=5.0.0
9
- mypy>=0.900
10
- flake8>=4.0.0
11
-
12
- [langfuse]
13
- langfuse>=2.0.0
@@ -1 +0,0 @@
1
- anzu
anzu-0.1.3/pyproject.toml DELETED
@@ -1,61 +0,0 @@
1
- [build-system]
2
- requires = ["setuptools>=42", "wheel"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "anzu"
7
- version = "0.1.3"
8
- description = "A package for updating queue items in a Django service"
9
- readme = "README.md"
10
- authors = [
11
- {name = "Your Name", email = "your.email@example.com"}
12
- ]
13
- license = {text = "MIT"}
14
- classifiers = [
15
- "Programming Language :: Python :: 3",
16
- "License :: OSI Approved :: MIT License",
17
- "Operating System :: OS Independent",
18
- ]
19
- keywords = ["django", "queue", "update"]
20
- dependencies = [
21
- "requests>=2.25.0",
22
- "aiohttp>=3.7.3",
23
- "python-socketio>=5.12.1"
24
- ]
25
- requires-python = ">=3.6"
26
-
27
- [project.optional-dependencies]
28
- langfuse = ["langfuse>=2.0.0"]
29
- dev = [
30
- "pytest>=6.0.0",
31
- "black>=22.0.0",
32
- "isort>=5.0.0",
33
- "mypy>=0.900",
34
- "flake8>=4.0.0",
35
- ]
36
-
37
- [project.urls]
38
- "Homepage" = "https://github.com/yourusername/queue_updater"
39
- "Bug Tracker" = "https://github.com/yourusername/queue_updater/issues"
40
-
41
- [tool.setuptools]
42
- packages = ["anzu"]
43
-
44
- [tool.black]
45
- line-length = 88
46
- target-version = ["py36", "py37", "py38", "py39", "py310"]
47
-
48
- [tool.isort]
49
- profile = "black"
50
- line_length = 88
51
-
52
- [tool.mypy]
53
- python_version = "3.6"
54
- warn_return_any = true
55
- warn_unused_configs = true
56
- disallow_untyped_defs = true
57
- disallow_incomplete_defs = true
58
-
59
- [tool.pytest.ini_options]
60
- testpaths = ["tests"]
61
- python_files = "test_*.py"
anzu-0.1.3/setup.cfg DELETED
@@ -1,4 +0,0 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
anzu-0.1.3/setup.py DELETED
@@ -1,27 +0,0 @@
1
- import setuptools
2
-
3
- with open("README.md", "r", encoding="utf-8") as fh:
4
- long_description = fh.read()
5
-
6
- setuptools.setup(
7
- name="anzu",
8
- version="0.1.3",
9
- author="Your Name",
10
- author_email="your.email@example.com",
11
- description="A package for updating queue items in a Django service",
12
- long_description=long_description,
13
- long_description_content_type="text/markdown",
14
- url="https://github.com/yourusername/queue_updater",
15
- packages=setuptools.find_packages(),
16
- classifiers=[
17
- "Programming Language :: Python :: 3",
18
- "License :: OSI Approved :: MIT License",
19
- "Operating System :: OS Independent",
20
- ],
21
- python_requires=">=3.6",
22
- install_requires=[
23
- "requests>=2.25.0",
24
- "aiohttp>=3.7.3",
25
- "python-socketio>=5.12.1",
26
- ],
27
- )
File without changes