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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ lightman run --dry-run --agent openai --score 9
| `--prompt-file` | File containing prompt templates | `lightman.toml` |
| `--start-date` | Start date to retrieve articles | None |
| `--today` | Retrieve articles from today | None |
| `--yesterday` | Retrieve articles from yesterday | None |

### Example Workflows

Expand Down
12 changes: 9 additions & 3 deletions src/lightman_ai/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
from datetime import date, datetime, time
from datetime import date, datetime, time, timedelta
from importlib import metadata
from zoneinfo import ZoneInfo

Expand Down Expand Up @@ -70,6 +70,7 @@ def entry_point() -> None:
)
@click.option("--start-date", type=click.DateTime(formats=["%Y-%m-%d"]), help="Start date to retrieve articles")
@click.option("--today", is_flag=True, help="Retrieve articles from today.")
@click.option("--yesterday", is_flag=True, help="Retrieve articles from yesterday.")
def run(
agent: str,
prompt: str,
Expand All @@ -82,6 +83,7 @@ def run(
dry_run: bool,
start_date: date | None,
today: bool,
yesterday: bool,
) -> int:
"""
Entrypoint of the application.
Expand All @@ -91,11 +93,15 @@ def run(
load_dotenv(env_file)
configure_sentry()

if start_date and today:
raise click.UsageError("--today and --start-date cannot be set at the same time.")
mutually_exclusive_fields_set = [x for x in [start_date, today, yesterday] if x]
if len(mutually_exclusive_fields_set) > 1:
raise click.UsageError("--today, --yesterday and --start-date are mutually exclusive. Set one at a time.")
elif today:
now = datetime.now(ZoneInfo(settings.TIME_ZONE))
start_datetime = datetime.combine(now, time(0, 0), tzinfo=ZoneInfo(settings.TIME_ZONE))
elif yesterday:
yesterday_date = datetime.now(ZoneInfo(settings.TIME_ZONE)) - timedelta(days=1)
start_datetime = datetime.combine(yesterday_date, time(0, 0), tzinfo=ZoneInfo(settings.TIME_ZONE))
elif isinstance(start_date, date):
start_datetime = datetime.combine(start_date, time(0, 0), tzinfo=ZoneInfo(settings.TIME_ZONE))
else:
Expand Down
60 changes: 48 additions & 12 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ def test_arguments(self, m_prompt: Mock, m_config: Mock, m_lightman: Mock, m_loa
@patch("lightman_ai.cli.PromptConfig.get_config_from_file")
def test_start_date(self, m_prompt: Mock, m_config: Mock, m_lightman: Mock, m_load_dotenv: Mock) -> None:
runner = CliRunner()
m_prompt.return_value = PromptConfig({"eval": "eval prompt"})
m_config.return_value = FileConfig()

with patch_config_file():
Expand All @@ -89,19 +88,56 @@ def test_start_date(self, m_prompt: Mock, m_config: Mock, m_lightman: Mock, m_lo
assert result.exit_code == 0
assert m_lightman.call_count == 1
assert m_lightman.call_args == call(
agent="gemini",
prompt="eval prompt",
score_threshold=1,
dry_run=False,
project_key=None,
request_id_type=None,
model=None,
agent=ANY,
prompt=ANY,
score_threshold=ANY,
dry_run=ANY,
project_key=ANY,
request_id_type=ANY,
model=ANY,
start_date=datetime(2025, 7, 29, 0, 0, tzinfo=ZoneInfo(key="UTC")),
)
assert m_config.call_count == 1
assert m_config.call_args == call(config_section="my-config", path="config-path")
assert m_prompt.call_args == call(path="prompt file")
assert m_load_dotenv.call_args == call(".env") # Default env file

@patch("lightman_ai.cli.load_dotenv")
@patch("lightman_ai.cli.lightman")
@patch("lightman_ai.cli.FileConfig.get_config_from_file")
@patch("lightman_ai.cli.PromptConfig.get_config_from_file")
@freeze_time("2025-07-29 19:00:00")
def test_yesterday(self, m_prompt: Mock, m_config: Mock, m_lightman: Mock, m_load_dotenv: Mock) -> None:
runner = CliRunner()
m_config.return_value = FileConfig()

with patch_config_file():
result = runner.invoke(
cli.run,
[
"--agent",
"gemini",
"--prompt",
"eval",
"--prompt-file",
"prompt file",
"--score",
"1",
"--config-file",
"config-path",
"--config",
"my-config",
"--yesterday",
],
)
assert result.exit_code == 0
assert m_lightman.call_count == 1
assert m_lightman.call_args == call(
agent=ANY,
prompt=ANY,
score_threshold=ANY,
dry_run=ANY,
project_key=ANY,
request_id_type=ANY,
model=ANY,
start_date=datetime(2025, 7, 28, 0, 0, tzinfo=ZoneInfo(key="UTC")),
)

@patch("lightman_ai.cli.load_dotenv")
@patch("lightman_ai.cli.lightman")
Expand Down