Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- Tags are now limited to 255 characters in length, and should match the regex `\A[\w][\w\-]+[\w]\z` (importantly, they can't contain commas). [PR #23](https://github.com/riverqueue/riverqueue-python/pull/23).

## [0.3.0] - 2024-07-04

### Added

- Implement `insert_many` and `insert_many_tx`. [PR #22](https://github.com/riverqueue/river/pull/22).
- Implement `insert_many` and `insert_many_tx`. [PR #22](https://github.com/riverqueue/riverqueue-python/pull/22).

## [0.2.0] - 2024-07-04

### Changed

- Rename `Args` to `JobArgs` and add `JobArgsWithInsertOpts` protocol. [PR #20](https://github.com/riverqueue/river/pull/20).
- Rename `Args` to `JobArgs` and add `JobArgsWithInsertOpts` protocol. [PR #20](https://github.com/riverqueue/riverqueue-python/pull/20).

## [0.1.2] - 2024-07-04

### Changed

- Add usage instructions README, add job state constants, and change return value of `insert_many()` and `insert_many_tx()` to an integer instead of a list of jobs. [PR #19](https://github.com/riverqueue/river/pull/19).
- Add usage instructions README, add job state constants, and change return value of `insert_many()` and `insert_many_tx()` to an integer instead of a list of jobs. [PR #19](https://github.com/riverqueue/riverqueue-python/pull/19).

## [0.1.1] - 2024-07-04

### Fixed

- Fix `pyproject.toml` description and add various URLs like to homepage, docs, and GitHub repositories. [PR #18](https://github.com/riverqueue/river/pull/18).
- Fix `pyproject.toml` description and add various URLs like to homepage, docs, and GitHub repositories. [PR #18](https://github.com/riverqueue/riverqueue-python/pull/18).

## [0.1.0] - 2024-07-04

Expand Down
14 changes: 13 additions & 1 deletion src/riverqueue/client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from dataclasses import dataclass
from datetime import datetime, timezone, timedelta
import re
from typing import (
Any,
Awaitable,
Expand Down Expand Up @@ -320,7 +321,7 @@ def _make_insert_params(
queue=insert_opts.queue or args_insert_opts.queue or QUEUE_DEFAULT,
scheduled_at=scheduled_at and scheduled_at.astimezone(timezone.utc),
state="scheduled" if scheduled_at else "available",
tags=insert_opts.tags or args_insert_opts.tags or [],
tags=_validate_tags(insert_opts.tags or args_insert_opts.tags or []),
)

return insert_params, unique_opts
Expand Down Expand Up @@ -348,3 +349,14 @@ def _truncate_time(time, interval_seconds) -> datetime:
def _uint64_to_int64(uint64):
# Packs a uint64 then unpacks to int64 to fit within Postgres bigint
return (uint64 + (1 << 63)) % (1 << 64) - (1 << 63)


tag_re = re.compile("\A[\w][\w\-]+[\w]\Z")


def _validate_tags(tags: list[str]) -> list[str]:
for tag in tags:
assert (
len(tag) <= 255 and tag_re.match(tag)
), f"tags should be less than 255 characters in length and match regex {tag_re.pattern}"
return tags
20 changes: 20 additions & 0 deletions tests/client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,26 @@ def to_json() -> None:
assert "args should return non-nil from `to_json`" == str(ex.value)


def test_tag_validation(client):
client.insert(
SimpleArgs(), insert_opts=InsertOpts(tags=["foo", "bar", "baz", "foo-bar-baz"])
)

with pytest.raises(AssertionError) as ex:
client.insert(SimpleArgs(), insert_opts=InsertOpts(tags=["commas,bad"]))
assert (
"tags should be less than 255 characters in length and match regex \A[\w][\w\-]+[\w]\Z"
== str(ex.value)
)

with pytest.raises(AssertionError) as ex:
client.insert(SimpleArgs(), insert_opts=InsertOpts(tags=["a" * 256]))
assert (
"tags should be less than 255 characters in length and match regex \A[\w][\w\-]+[\w]\Z"
== str(ex.value)
)


def test_check_advisory_lock_prefix_bounds():
Client(mock_driver, advisory_lock_prefix=123)

Expand Down