beanqueue 1.0.0__tar.gz → 1.1.1__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.
- {beanqueue-1.0.0 → beanqueue-1.1.1}/PKG-INFO +6 -5
- {beanqueue-1.0.0 → beanqueue-1.1.1}/README.md +4 -4
- beanqueue-1.1.1/bq/cmds/cli.py +44 -0
- beanqueue-1.1.1/bq/cmds/create_tables.py +12 -0
- beanqueue-1.1.1/bq/cmds/environment.py +36 -0
- beanqueue-1.1.1/bq/cmds/main.py +9 -0
- beanqueue-1.1.1/bq/cmds/process.py +15 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/cmds/submit.py +14 -20
- {beanqueue-1.0.0 → beanqueue-1.1.1}/pyproject.toml +5 -1
- beanqueue-1.0.0/bq/cmds/create_tables.py +0 -26
- beanqueue-1.0.0/bq/cmds/process.py +0 -23
- {beanqueue-1.0.0 → beanqueue-1.1.1}/LICENSE +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/__init__.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/app.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/cmds/__init__.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/cmds/utils.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/config.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/constants.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/db/__init__.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/db/base.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/db/session.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/events.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/models/__init__.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/models/event.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/models/helpers.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/models/task.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/models/worker.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/processors/__init__.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/processors/processor.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/processors/registry.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/processors/retry_policies.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/services/__init__.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/services/dispatch.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/services/worker.py +0 -0
- {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: beanqueue
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.1.1
|
|
4
4
|
Summary: BeanQueue or BQ for short, PostgreSQL SKIP LOCK and SQLAlchemy based worker queue library
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Fang-Pen Lin
|
|
@@ -14,6 +14,7 @@ Requires-Dist: blinker (>=1.8.2,<2.0.0)
|
|
|
14
14
|
Requires-Dist: click (>=8.1.7,<9.0.0)
|
|
15
15
|
Requires-Dist: pg-activity (>=3.5.1,<4.0.0)
|
|
16
16
|
Requires-Dist: pydantic-settings (>=2.2.1,<3.0.0)
|
|
17
|
+
Requires-Dist: rich (>=13.7.1,<14.0.0)
|
|
17
18
|
Requires-Dist: sqlalchemy (>=2.0.30,<3.0.0)
|
|
18
19
|
Requires-Dist: venusian (>=3.1.0,<4.0.0)
|
|
19
20
|
Description-Content-Type: text/markdown
|
|
@@ -113,20 +114,20 @@ db.commit()
|
|
|
113
114
|
To run the worker, you can do this:
|
|
114
115
|
|
|
115
116
|
```bash
|
|
116
|
-
BQ_PROCESSOR_PACKAGES='["my_pkgs.processors"]'
|
|
117
|
+
BQ_PROCESSOR_PACKAGES='["my_pkgs.processors"]' bq process images
|
|
117
118
|
```
|
|
118
119
|
|
|
119
120
|
The `BQ_PROCESSOR_PACKAGES` is a JSON list contains the Python packages where you define your processors (the functions you decorated with `bq.processors.registry.processor`).
|
|
120
121
|
To submit a task for testing purpose, you can do
|
|
121
122
|
|
|
122
123
|
```bash
|
|
123
|
-
|
|
124
|
+
bq submit images my_pkgs.processors resize_image -k '{"width": 200, "height": 300}'
|
|
124
125
|
```
|
|
125
126
|
|
|
126
127
|
To create tables for BeanQueue, you can run
|
|
127
128
|
|
|
128
129
|
```bash
|
|
129
|
-
|
|
130
|
+
bq create_tables
|
|
130
131
|
```
|
|
131
132
|
|
|
132
133
|
### Schedule
|
|
@@ -228,7 +229,7 @@ app = bq.BeanQueue(config=config)
|
|
|
228
229
|
Then you can pass `--app` argument (or `-a` for short) pointing to the app object to the process command like this:
|
|
229
230
|
|
|
230
231
|
```bash
|
|
231
|
-
|
|
232
|
+
bq -a my_pkgs.bq.app process images
|
|
232
233
|
```
|
|
233
234
|
|
|
234
235
|
Or if you prefer to define your own process command, you can also call `process_tasks` of the `BeanQueue` object directly like this:
|
|
@@ -93,20 +93,20 @@ db.commit()
|
|
|
93
93
|
To run the worker, you can do this:
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
BQ_PROCESSOR_PACKAGES='["my_pkgs.processors"]'
|
|
96
|
+
BQ_PROCESSOR_PACKAGES='["my_pkgs.processors"]' bq process images
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
The `BQ_PROCESSOR_PACKAGES` is a JSON list contains the Python packages where you define your processors (the functions you decorated with `bq.processors.registry.processor`).
|
|
100
100
|
To submit a task for testing purpose, you can do
|
|
101
101
|
|
|
102
102
|
```bash
|
|
103
|
-
|
|
103
|
+
bq submit images my_pkgs.processors resize_image -k '{"width": 200, "height": 300}'
|
|
104
104
|
```
|
|
105
105
|
|
|
106
106
|
To create tables for BeanQueue, you can run
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
|
-
|
|
109
|
+
bq create_tables
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
### Schedule
|
|
@@ -208,7 +208,7 @@ app = bq.BeanQueue(config=config)
|
|
|
208
208
|
Then you can pass `--app` argument (or `-a` for short) pointing to the app object to the process command like this:
|
|
209
209
|
|
|
210
210
|
```bash
|
|
211
|
-
|
|
211
|
+
bq -a my_pkgs.bq.app process images
|
|
212
212
|
```
|
|
213
213
|
|
|
214
214
|
Or if you prefer to define your own process command, you can also call `process_tasks` of the `BeanQueue` object directly like this:
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
from rich.logging import RichHandler
|
|
6
|
+
|
|
7
|
+
from .environment import Environment
|
|
8
|
+
from .environment import LOG_LEVEL_MAP
|
|
9
|
+
from .environment import LogLevel
|
|
10
|
+
from .environment import pass_env
|
|
11
|
+
from .utils import load_app
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@click.group(help="Command line tools for BeanQueue")
|
|
15
|
+
@click.option(
|
|
16
|
+
"-l",
|
|
17
|
+
"--log-level",
|
|
18
|
+
type=click.Choice(
|
|
19
|
+
list(map(lambda key: key.value, LOG_LEVEL_MAP.keys())), case_sensitive=False
|
|
20
|
+
),
|
|
21
|
+
default=lambda: os.environ.get("LOG_LEVEL", "INFO"),
|
|
22
|
+
)
|
|
23
|
+
@click.option(
|
|
24
|
+
"--disable-rich-log",
|
|
25
|
+
is_flag=True,
|
|
26
|
+
help="disable rich log handler",
|
|
27
|
+
)
|
|
28
|
+
@click.option(
|
|
29
|
+
"-a", "--app", type=str, help='BeanQueue app object to use, e.g. "my_pkgs.bq.app"'
|
|
30
|
+
)
|
|
31
|
+
@click.version_option(prog_name="bq", package_name="bq")
|
|
32
|
+
@pass_env
|
|
33
|
+
def cli(env: Environment, log_level: str, disable_rich_log: bool, app: str):
|
|
34
|
+
env.log_level = LogLevel(log_level)
|
|
35
|
+
env.app = load_app(app)
|
|
36
|
+
|
|
37
|
+
FORMAT = "%(message)s"
|
|
38
|
+
logging.basicConfig(
|
|
39
|
+
level=LOG_LEVEL_MAP[env.log_level],
|
|
40
|
+
format=FORMAT,
|
|
41
|
+
datefmt="[%X]",
|
|
42
|
+
force=True,
|
|
43
|
+
**(dict(handlers=[RichHandler()]) if not disable_rich_log else {})
|
|
44
|
+
)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from .. import models # noqa
|
|
2
|
+
from ..db.base import Base
|
|
3
|
+
from .cli import cli
|
|
4
|
+
from .environment import Environment
|
|
5
|
+
from .environment import pass_env
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@cli.command(name="create_tables", help="Create BeanQueue tables")
|
|
9
|
+
@pass_env
|
|
10
|
+
def create_tables(env: Environment):
|
|
11
|
+
Base.metadata.create_all(bind=env.app.engine)
|
|
12
|
+
env.logger.info("Done, tables created")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import enum
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
|
|
7
|
+
from ..app import BeanQueue
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@enum.unique
|
|
11
|
+
class LogLevel(enum.Enum):
|
|
12
|
+
VERBOSE = "verbose"
|
|
13
|
+
DEBUG = "debug"
|
|
14
|
+
INFO = "info"
|
|
15
|
+
WARNING = "warning"
|
|
16
|
+
ERROR = "error"
|
|
17
|
+
FATAL = "fatal"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
LOG_LEVEL_MAP = {
|
|
21
|
+
LogLevel.DEBUG: logging.DEBUG,
|
|
22
|
+
LogLevel.INFO: logging.INFO,
|
|
23
|
+
LogLevel.WARNING: logging.WARNING,
|
|
24
|
+
LogLevel.ERROR: logging.ERROR,
|
|
25
|
+
LogLevel.FATAL: logging.FATAL,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclasses.dataclass
|
|
30
|
+
class Environment:
|
|
31
|
+
log_level: LogLevel = LogLevel.INFO
|
|
32
|
+
logger: logging.Logger = logging.getLogger("bq")
|
|
33
|
+
app: BeanQueue = BeanQueue()
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
pass_env = click.make_pass_decorator(Environment, ensure=True)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from .cli import cli
|
|
4
|
+
from .environment import Environment
|
|
5
|
+
from .environment import pass_env
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@cli.command(name="process", help="Process BeanQueue tasks")
|
|
9
|
+
@click.argument("channels", nargs=-1)
|
|
10
|
+
@pass_env
|
|
11
|
+
def process(
|
|
12
|
+
env: Environment,
|
|
13
|
+
channels: tuple[str, ...],
|
|
14
|
+
):
|
|
15
|
+
env.app.process_tasks(channels)
|
|
@@ -1,48 +1,42 @@
|
|
|
1
1
|
import json
|
|
2
|
-
import logging
|
|
3
2
|
|
|
4
3
|
import click
|
|
5
4
|
|
|
6
5
|
from .. import models
|
|
7
|
-
from .
|
|
6
|
+
from .cli import cli
|
|
7
|
+
from .environment import Environment
|
|
8
|
+
from .environment import pass_env
|
|
8
9
|
|
|
9
|
-
logger = logging.getLogger(__name__)
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
@click.command()
|
|
11
|
+
@cli.command(name="submit", help="Submit a new task, mostly for debugging purpose")
|
|
13
12
|
@click.argument("channel", nargs=1)
|
|
14
13
|
@click.argument("module", nargs=1)
|
|
15
14
|
@click.argument("func", nargs=1)
|
|
16
15
|
@click.option(
|
|
17
16
|
"-k", "--kwargs", type=str, help="Keyword arguments as JSON", default=None
|
|
18
17
|
)
|
|
19
|
-
@
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
def main(
|
|
18
|
+
@pass_env
|
|
19
|
+
def submit(
|
|
20
|
+
env: Environment,
|
|
23
21
|
channel: str,
|
|
24
22
|
module: str,
|
|
25
23
|
func: str,
|
|
26
24
|
kwargs: str | None,
|
|
27
|
-
app: str | None = None,
|
|
28
25
|
):
|
|
29
|
-
|
|
30
|
-
db = app.session_cls(bind=app.create_default_engine())
|
|
26
|
+
db = env.app.session_cls(bind=env.app.create_default_engine())
|
|
31
27
|
|
|
32
|
-
logger.info(
|
|
28
|
+
env.logger.info(
|
|
33
29
|
"Submit task with channel=%s, module=%s, func=%s", channel, module, func
|
|
34
30
|
)
|
|
35
31
|
kwargs_value = {}
|
|
36
32
|
if kwargs:
|
|
37
33
|
kwargs_value = json.loads(kwargs)
|
|
38
34
|
task = models.Task(
|
|
39
|
-
channel=channel,
|
|
35
|
+
channel=channel,
|
|
36
|
+
module=module,
|
|
37
|
+
func_name=func,
|
|
38
|
+
kwargs=kwargs_value,
|
|
40
39
|
)
|
|
41
40
|
db.add(task)
|
|
42
41
|
db.commit()
|
|
43
|
-
logger.info("Done, submit task %s", task.id)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if __name__ == "__main__":
|
|
47
|
-
logging.basicConfig(level=logging.INFO)
|
|
48
|
-
main()
|
|
42
|
+
env.logger.info("Done, submit task %s", task.id)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "beanqueue"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.1.1"
|
|
4
4
|
description = "BeanQueue or BQ for short, PostgreSQL SKIP LOCK and SQLAlchemy based worker queue library"
|
|
5
5
|
authors = ["Fang-Pen Lin <fangpen@launchplatform.com>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -9,6 +9,9 @@ packages = [
|
|
|
9
9
|
{ include = "bq" },
|
|
10
10
|
]
|
|
11
11
|
|
|
12
|
+
[tool.poetry.scripts]
|
|
13
|
+
bq = "bq.cmds.main:cli"
|
|
14
|
+
|
|
12
15
|
[tool.poetry.dependencies]
|
|
13
16
|
python = "^3.11"
|
|
14
17
|
sqlalchemy = "^2.0.30"
|
|
@@ -17,6 +20,7 @@ click = "^8.1.7"
|
|
|
17
20
|
pydantic-settings = "^2.2.1"
|
|
18
21
|
pg-activity = "^3.5.1"
|
|
19
22
|
blinker = "^1.8.2"
|
|
23
|
+
rich = "^13.7.1"
|
|
20
24
|
|
|
21
25
|
|
|
22
26
|
[tool.poetry.group.dev.dependencies]
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
import click
|
|
4
|
-
|
|
5
|
-
from .. import models # noqa
|
|
6
|
-
from ..db.base import Base
|
|
7
|
-
from .utils import load_app
|
|
8
|
-
|
|
9
|
-
logger = logging.getLogger(__name__)
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@click.command()
|
|
13
|
-
@click.option(
|
|
14
|
-
"-a", "--app", type=str, help='BeanQueue app object to use, e.g. "my_pkgs.bq.app"'
|
|
15
|
-
)
|
|
16
|
-
def main(
|
|
17
|
-
app: str | None = None,
|
|
18
|
-
):
|
|
19
|
-
app = load_app(app)
|
|
20
|
-
Base.metadata.create_all(bind=app.engine)
|
|
21
|
-
logger.info("Done, tables created")
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if __name__ == "__main__":
|
|
25
|
-
logging.basicConfig(level=logging.INFO)
|
|
26
|
-
main()
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
|
|
3
|
-
import click
|
|
4
|
-
|
|
5
|
-
from .utils import load_app
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@click.command()
|
|
9
|
-
@click.argument("channels", nargs=-1)
|
|
10
|
-
@click.option(
|
|
11
|
-
"-a", "--app", type=str, help='BeanQueue app object to use, e.g. "my_pkgs.bq.app"'
|
|
12
|
-
)
|
|
13
|
-
def main(
|
|
14
|
-
channels: tuple[str, ...],
|
|
15
|
-
app: str | None = None,
|
|
16
|
-
):
|
|
17
|
-
app = load_app(app)
|
|
18
|
-
app.process_tasks(channels)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if __name__ == "__main__":
|
|
22
|
-
logging.basicConfig(level=logging.INFO)
|
|
23
|
-
main()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|