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.
Files changed (35) hide show
  1. {beanqueue-1.0.0 → beanqueue-1.1.1}/PKG-INFO +6 -5
  2. {beanqueue-1.0.0 → beanqueue-1.1.1}/README.md +4 -4
  3. beanqueue-1.1.1/bq/cmds/cli.py +44 -0
  4. beanqueue-1.1.1/bq/cmds/create_tables.py +12 -0
  5. beanqueue-1.1.1/bq/cmds/environment.py +36 -0
  6. beanqueue-1.1.1/bq/cmds/main.py +9 -0
  7. beanqueue-1.1.1/bq/cmds/process.py +15 -0
  8. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/cmds/submit.py +14 -20
  9. {beanqueue-1.0.0 → beanqueue-1.1.1}/pyproject.toml +5 -1
  10. beanqueue-1.0.0/bq/cmds/create_tables.py +0 -26
  11. beanqueue-1.0.0/bq/cmds/process.py +0 -23
  12. {beanqueue-1.0.0 → beanqueue-1.1.1}/LICENSE +0 -0
  13. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/__init__.py +0 -0
  14. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/app.py +0 -0
  15. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/cmds/__init__.py +0 -0
  16. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/cmds/utils.py +0 -0
  17. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/config.py +0 -0
  18. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/constants.py +0 -0
  19. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/db/__init__.py +0 -0
  20. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/db/base.py +0 -0
  21. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/db/session.py +0 -0
  22. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/events.py +0 -0
  23. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/models/__init__.py +0 -0
  24. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/models/event.py +0 -0
  25. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/models/helpers.py +0 -0
  26. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/models/task.py +0 -0
  27. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/models/worker.py +0 -0
  28. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/processors/__init__.py +0 -0
  29. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/processors/processor.py +0 -0
  30. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/processors/registry.py +0 -0
  31. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/processors/retry_policies.py +0 -0
  32. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/services/__init__.py +0 -0
  33. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/services/dispatch.py +0 -0
  34. {beanqueue-1.0.0 → beanqueue-1.1.1}/bq/services/worker.py +0 -0
  35. {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.0.0
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"]' python -m bq.cmds.process images
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
- python -m bq.cmds.submit images my_pkgs.processors resize_image -k '{"width": 200, "height": 300}'
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
- python -m bq.cmds.create_tables
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
- python -m bq.cmds.process -a my_pkgs.bq.app images
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"]' python -m bq.cmds.process images
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
- python -m bq.cmds.submit images my_pkgs.processors resize_image -k '{"width": 200, "height": 300}'
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
- python -m bq.cmds.create_tables
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
- python -m bq.cmds.process -a my_pkgs.bq.app images
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,9 @@
1
+ from . import create_tables # noqa
2
+ from . import process # noqa
3
+ from . import submit # noqa
4
+ from .cli import cli
5
+
6
+ __ALL__ = [cli]
7
+
8
+ if __name__ == "__main__":
9
+ cli()
@@ -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 .utils import load_app
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
- @click.option(
20
- "-a", "--app", type=str, help='BeanQueue app object to use, e.g. "my_pkgs.bq.app"'
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
- app = load_app(app)
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, module=module, func_name=func, kwargs=kwargs_value
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.0.0"
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