datalegion-cli 1.7.0__tar.gz → 1.8.0__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 (31) hide show
  1. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/PKG-INFO +25 -18
  2. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/README.md +24 -17
  3. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/pyproject.toml +1 -1
  4. datalegion_cli-1.8.0/src/datalegion_cli/commands/__init__.py +26 -0
  5. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/commands/company.py +13 -3
  6. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/commands/person.py +13 -3
  7. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/test_commands.py +30 -0
  8. datalegion_cli-1.7.0/src/datalegion_cli/commands/__init__.py +0 -1
  9. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/.gitignore +0 -0
  10. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/LICENSE +0 -0
  11. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/__init__.py +0 -0
  12. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/async_typer.py +0 -0
  13. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/client.py +0 -0
  14. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/commands/credits.py +0 -0
  15. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/commands/utility.py +0 -0
  16. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/config.py +0 -0
  17. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/logging.py +0 -0
  18. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/login.py +0 -0
  19. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/main.py +0 -0
  20. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/output.py +0 -0
  21. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/src/datalegion_cli/update.py +0 -0
  22. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/__init__.py +0 -0
  23. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/conftest.py +0 -0
  24. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/test_client.py +0 -0
  25. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/test_config.py +0 -0
  26. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/test_live.py +0 -0
  27. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/test_logging.py +0 -0
  28. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/test_login.py +0 -0
  29. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/test_output.py +0 -0
  30. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/test_package_contents.py +0 -0
  31. {datalegion_cli-1.7.0 → datalegion_cli-1.8.0}/tests/test_update.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: datalegion-cli
3
- Version: 1.7.0
3
+ Version: 1.8.0
4
4
  Summary: CLI for the Data Legion API — agent-friendly, fully async
5
5
  Project-URL: Homepage, https://www.datalegion.ai
6
6
  Project-URL: Documentation, https://www.datalegion.ai/docs
@@ -62,7 +62,7 @@ datalegion-cli person enrich --email john@example.com
62
62
  brew install datalegion-ai/tap/datalegion-cli
63
63
  ```
64
64
 
65
- ### From PyPI (or private index)
65
+ ### From PyPI (or Private Index)
66
66
 
67
67
  ```bash
68
68
  uv pip install datalegion-cli
@@ -80,7 +80,7 @@ To install from a private index:
80
80
  uv pip install datalegion-cli --extra-index-url https://your-private-index.com/simple
81
81
  ```
82
82
 
83
- ### From GitHub release
83
+ ### From GitHub Release
84
84
 
85
85
  Download the `.whl` from the [latest release](https://github.com/datalegion-ai/datalegion-cli/releases/latest) and install:
86
86
 
@@ -88,7 +88,7 @@ Download the `.whl` from the [latest release](https://github.com/datalegion-ai/d
88
88
  uv pip install datalegion_cli-*.whl
89
89
  ```
90
90
 
91
- ### From source
91
+ ### From Source
92
92
 
93
93
  ```bash
94
94
  git clone https://github.com/datalegion-ai/datalegion-cli.git
@@ -120,7 +120,7 @@ Or via environment variable (takes precedence over file config):
120
120
  export LEGION_API_KEY=legion_your_key_here
121
121
  ```
122
122
 
123
- ### Other config options
123
+ ### Other Config Options
124
124
 
125
125
  ```bash
126
126
  # Set the API base URL
@@ -138,7 +138,7 @@ datalegion-cli config path
138
138
 
139
139
  Config is stored at `~/.datalegion/config.toml`. Override the location with `LEGION_CONFIG_DIR`.
140
140
 
141
- ### Install method detection
141
+ ### Install Method Detection
142
142
 
143
143
  The `update` command auto-detects how the CLI was installed:
144
144
 
@@ -153,7 +153,7 @@ You can override detection by setting `install_method` in config. For pip instal
153
153
 
154
154
  ## Usage
155
155
 
156
- ### Person enrichment
156
+ ### Person Enrichment
157
157
 
158
158
  ```bash
159
159
  # By email
@@ -165,28 +165,35 @@ datalegion-cli person enrich --name "Jane Smith" --company "Acme Corp" --city "N
165
165
  # By LinkedIn
166
166
  datalegion-cli person enrich --social-url "https://linkedin.com/in/johndoe"
167
167
 
168
- # Multiple results with minimum confidence
168
+ # Minimum confidence
169
169
  datalegion-cli person enrich --email john@example.com --min-confidence high
170
170
 
171
171
  # Select specific fields
172
172
  datalegion-cli person enrich --email john@example.com --fields "full_name,emails,phones"
173
173
  ```
174
174
 
175
- ### Person search (Beta)
175
+ ### Person Search
176
176
 
177
177
  ```bash
178
178
  # SQL-based search
179
179
  datalegion-cli person search "SELECT * FROM people WHERE company_name ILIKE '%google%' AND state = 'CA'" --limit 5
180
180
  ```
181
181
 
182
- ### Person discovery (Beta)
182
+ `query` can also be an Elasticsearch-style query object as JSON (`bool`, `term`, `terms`, `match`, `match_phrase`, `range`, `exists`, `prefix`, `wildcard`, `nested`), on the response's own field names. For deep paging, pass each page's `next_cursor` back with `--cursor`; the last page has none. Company search takes both too.
183
+
184
+ ```bash
185
+ datalegion-cli person search '{"bool": {"filter": [{"term": {"company_name": "google"}}, {"match": {"job_title": "engineer"}}]}}' --limit 100
186
+ datalegion-cli person search "SELECT * FROM people WHERE state = 'ohio'" --limit 100 --cursor "<next_cursor from the last page>"
187
+ ```
188
+
189
+ ### Person Discovery (Beta)
183
190
 
184
191
  ```bash
185
192
  # Natural-language search
186
193
  datalegion-cli person discover "software engineers in San Francisco who know Rust" --limit 10
187
194
  ```
188
195
 
189
- ### Company enrichment
196
+ ### Company Enrichment
190
197
 
191
198
  ```bash
192
199
  # By domain
@@ -199,21 +206,21 @@ datalegion-cli company enrich --ticker AAPL
199
206
  datalegion-cli company enrich --name "Stripe" --industry "Financial Services"
200
207
  ```
201
208
 
202
- ### Company search (Beta)
209
+ ### Company Search
203
210
 
204
211
  ```bash
205
212
  # SQL-based search
206
213
  datalegion-cli company search "SELECT * FROM companies WHERE industry ILIKE '%software%' AND legion_employee_count > 100"
207
214
  ```
208
215
 
209
- ### Company discovery (Beta)
216
+ ### Company Discovery (Beta)
210
217
 
211
218
  ```bash
212
219
  # Natural-language search
213
220
  datalegion-cli company discover "fintech startups in New York with under 50 employees"
214
221
  ```
215
222
 
216
- ### Utility commands
223
+ ### Utility Commands
217
224
 
218
225
  ```bash
219
226
  # Clean and normalize fields
@@ -240,7 +247,7 @@ datalegion-cli credits balance
240
247
  datalegion-cli credits usage --from 2026-01-01 --to 2026-03-01
241
248
  ```
242
249
 
243
- ### Other commands
250
+ ### Other Commands
244
251
 
245
252
  ```bash
246
253
  # Check for updates
@@ -253,7 +260,7 @@ datalegion-cli update
253
260
  datalegion-cli version
254
261
  ```
255
262
 
256
- ## Agent / automation usage
263
+ ## Agent / Automation Usage
257
264
 
258
265
  The CLI is designed to be called by AI agents and scripts. Key patterns:
259
266
 
@@ -274,13 +281,13 @@ datalegion-cli person enrich --email bad 2>/dev/null
274
281
 
275
282
  ## Sandbox
276
283
 
277
- Try commands without spending credits: `--sandbox` (or `LEGION_SANDBOX=1`, or `datalegion-cli config set sandbox true`) makes enrich, bulk enrich, search and discover return sample records with every field a real record has. Utilities, which are free, still call the real API. Sandbox discover answers only a few fixed example queries.
284
+ Try commands without spending credits: `--sandbox` (or `LEGION_SANDBOX=1`, or `datalegion-cli config set sandbox true`) makes Enrich, Bulk Enrich, Search and Discover return sample records with every field a real record has. Utilities, which are free, still call the real API. Sandbox discover answers only a few fixed example queries.
278
285
 
279
286
  ```bash
280
287
  datalegion-cli --sandbox person enrich --email anyone@example.com
281
288
  ```
282
289
 
283
- ## Global flags
290
+ ## Global Flags
284
291
 
285
292
  | Flag | Description |
286
293
  |------|-------------|
@@ -27,7 +27,7 @@ datalegion-cli person enrich --email john@example.com
27
27
  brew install datalegion-ai/tap/datalegion-cli
28
28
  ```
29
29
 
30
- ### From PyPI (or private index)
30
+ ### From PyPI (or Private Index)
31
31
 
32
32
  ```bash
33
33
  uv pip install datalegion-cli
@@ -45,7 +45,7 @@ To install from a private index:
45
45
  uv pip install datalegion-cli --extra-index-url https://your-private-index.com/simple
46
46
  ```
47
47
 
48
- ### From GitHub release
48
+ ### From GitHub Release
49
49
 
50
50
  Download the `.whl` from the [latest release](https://github.com/datalegion-ai/datalegion-cli/releases/latest) and install:
51
51
 
@@ -53,7 +53,7 @@ Download the `.whl` from the [latest release](https://github.com/datalegion-ai/d
53
53
  uv pip install datalegion_cli-*.whl
54
54
  ```
55
55
 
56
- ### From source
56
+ ### From Source
57
57
 
58
58
  ```bash
59
59
  git clone https://github.com/datalegion-ai/datalegion-cli.git
@@ -85,7 +85,7 @@ Or via environment variable (takes precedence over file config):
85
85
  export LEGION_API_KEY=legion_your_key_here
86
86
  ```
87
87
 
88
- ### Other config options
88
+ ### Other Config Options
89
89
 
90
90
  ```bash
91
91
  # Set the API base URL
@@ -103,7 +103,7 @@ datalegion-cli config path
103
103
 
104
104
  Config is stored at `~/.datalegion/config.toml`. Override the location with `LEGION_CONFIG_DIR`.
105
105
 
106
- ### Install method detection
106
+ ### Install Method Detection
107
107
 
108
108
  The `update` command auto-detects how the CLI was installed:
109
109
 
@@ -118,7 +118,7 @@ You can override detection by setting `install_method` in config. For pip instal
118
118
 
119
119
  ## Usage
120
120
 
121
- ### Person enrichment
121
+ ### Person Enrichment
122
122
 
123
123
  ```bash
124
124
  # By email
@@ -130,28 +130,35 @@ datalegion-cli person enrich --name "Jane Smith" --company "Acme Corp" --city "N
130
130
  # By LinkedIn
131
131
  datalegion-cli person enrich --social-url "https://linkedin.com/in/johndoe"
132
132
 
133
- # Multiple results with minimum confidence
133
+ # Minimum confidence
134
134
  datalegion-cli person enrich --email john@example.com --min-confidence high
135
135
 
136
136
  # Select specific fields
137
137
  datalegion-cli person enrich --email john@example.com --fields "full_name,emails,phones"
138
138
  ```
139
139
 
140
- ### Person search (Beta)
140
+ ### Person Search
141
141
 
142
142
  ```bash
143
143
  # SQL-based search
144
144
  datalegion-cli person search "SELECT * FROM people WHERE company_name ILIKE '%google%' AND state = 'CA'" --limit 5
145
145
  ```
146
146
 
147
- ### Person discovery (Beta)
147
+ `query` can also be an Elasticsearch-style query object as JSON (`bool`, `term`, `terms`, `match`, `match_phrase`, `range`, `exists`, `prefix`, `wildcard`, `nested`), on the response's own field names. For deep paging, pass each page's `next_cursor` back with `--cursor`; the last page has none. Company search takes both too.
148
+
149
+ ```bash
150
+ datalegion-cli person search '{"bool": {"filter": [{"term": {"company_name": "google"}}, {"match": {"job_title": "engineer"}}]}}' --limit 100
151
+ datalegion-cli person search "SELECT * FROM people WHERE state = 'ohio'" --limit 100 --cursor "<next_cursor from the last page>"
152
+ ```
153
+
154
+ ### Person Discovery (Beta)
148
155
 
149
156
  ```bash
150
157
  # Natural-language search
151
158
  datalegion-cli person discover "software engineers in San Francisco who know Rust" --limit 10
152
159
  ```
153
160
 
154
- ### Company enrichment
161
+ ### Company Enrichment
155
162
 
156
163
  ```bash
157
164
  # By domain
@@ -164,21 +171,21 @@ datalegion-cli company enrich --ticker AAPL
164
171
  datalegion-cli company enrich --name "Stripe" --industry "Financial Services"
165
172
  ```
166
173
 
167
- ### Company search (Beta)
174
+ ### Company Search
168
175
 
169
176
  ```bash
170
177
  # SQL-based search
171
178
  datalegion-cli company search "SELECT * FROM companies WHERE industry ILIKE '%software%' AND legion_employee_count > 100"
172
179
  ```
173
180
 
174
- ### Company discovery (Beta)
181
+ ### Company Discovery (Beta)
175
182
 
176
183
  ```bash
177
184
  # Natural-language search
178
185
  datalegion-cli company discover "fintech startups in New York with under 50 employees"
179
186
  ```
180
187
 
181
- ### Utility commands
188
+ ### Utility Commands
182
189
 
183
190
  ```bash
184
191
  # Clean and normalize fields
@@ -205,7 +212,7 @@ datalegion-cli credits balance
205
212
  datalegion-cli credits usage --from 2026-01-01 --to 2026-03-01
206
213
  ```
207
214
 
208
- ### Other commands
215
+ ### Other Commands
209
216
 
210
217
  ```bash
211
218
  # Check for updates
@@ -218,7 +225,7 @@ datalegion-cli update
218
225
  datalegion-cli version
219
226
  ```
220
227
 
221
- ## Agent / automation usage
228
+ ## Agent / Automation Usage
222
229
 
223
230
  The CLI is designed to be called by AI agents and scripts. Key patterns:
224
231
 
@@ -239,13 +246,13 @@ datalegion-cli person enrich --email bad 2>/dev/null
239
246
 
240
247
  ## Sandbox
241
248
 
242
- Try commands without spending credits: `--sandbox` (or `LEGION_SANDBOX=1`, or `datalegion-cli config set sandbox true`) makes enrich, bulk enrich, search and discover return sample records with every field a real record has. Utilities, which are free, still call the real API. Sandbox discover answers only a few fixed example queries.
249
+ Try commands without spending credits: `--sandbox` (or `LEGION_SANDBOX=1`, or `datalegion-cli config set sandbox true`) makes Enrich, Bulk Enrich, Search and Discover return sample records with every field a real record has. Utilities, which are free, still call the real API. Sandbox discover answers only a few fixed example queries.
243
250
 
244
251
  ```bash
245
252
  datalegion-cli --sandbox person enrich --email anyone@example.com
246
253
  ```
247
254
 
248
- ## Global flags
255
+ ## Global Flags
249
256
 
250
257
  | Flag | Description |
251
258
  |------|-------------|
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "datalegion-cli"
3
- version = "1.7.0"
3
+ version = "1.8.0"
4
4
  description = "CLI for the Data Legion API — agent-friendly, fully async"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -0,0 +1,26 @@
1
+ """CLI command modules."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from typing import Annotated, Any
7
+
8
+ import typer
9
+
10
+ CursorOpt = Annotated[
11
+ str | None,
12
+ typer.Option(
13
+ "--cursor",
14
+ help="The previous page's next_cursor, for deep paging (instead of an offset).",
15
+ ),
16
+ ]
17
+
18
+
19
+ def search_query(text: str) -> str | dict[str, Any]:
20
+ """SQL as given, or a query object when the argument is a JSON object."""
21
+ if not text.lstrip().startswith("{"):
22
+ return text
23
+ try:
24
+ return json.loads(text)
25
+ except json.JSONDecodeError as e:
26
+ raise typer.BadParameter(f"The query looks like JSON but doesn't parse: {e.msg}.") from e
@@ -10,6 +10,7 @@ import typer
10
10
 
11
11
  from datalegion_cli.async_typer import async_command
12
12
  from datalegion_cli.client import APIError, LegionClient
13
+ from datalegion_cli.commands import CursorOpt, search_query
13
14
  from datalegion_cli.output import emit_credits, emit_error, emit_json, emit_search_warning
14
15
 
15
16
  app = typer.Typer(name="company", help="Company enrichment, search, and discovery.")
@@ -102,24 +103,33 @@ async def enrich(
102
103
  @app.command()
103
104
  @async_command
104
105
  async def search(
105
- query: Annotated[str, typer.Argument(help="SQL SELECT query against the companies table.")],
106
+ query: Annotated[
107
+ str,
108
+ typer.Argument(
109
+ help="SQL SELECT query against the companies table, or a query object as JSON."
110
+ ),
111
+ ],
106
112
  limit: LimitOpt = 1,
113
+ cursor: CursorOpt = None,
107
114
  titlecase: TitleOpt = False,
108
115
  include_fields: FieldsInclude = None,
109
116
  exclude_fields: FieldsExclude = None,
110
117
  ) -> None:
111
- """Search for companies with a SQL SELECT over the companies table, no LIMIT (Beta).
118
+ """Search for companies with a SQL SELECT over the companies table, no LIMIT.
112
119
 
113
120
  Examples:
114
121
  datalegion-cli company search "SELECT * FROM companies WHERE industry ILIKE '%software%' AND legion_employee_count > 100"
115
122
  datalegion-cli company search "SELECT * FROM companies WHERE name ILIKE '%tech%'" --limit 20
116
123
  datalegion-cli company search "SELECT * FROM companies WHERE domain = 'stripe.com'" --fields "name,domain,industry"
124
+ datalegion-cli company search '{"term": {"domain": "stripe.com"}}'
125
+ datalegion-cli company search "SELECT * FROM companies WHERE industry = 'banking'" --limit 100 --cursor <next_cursor>
117
126
  """
118
127
  client = LegionClient()
119
128
  try:
120
129
  result = await client.company_search(
121
- query=query,
130
+ query=search_query(query),
122
131
  limit=limit,
132
+ cursor=cursor,
123
133
  titlecase=titlecase,
124
134
  include_fields=include_fields,
125
135
  exclude_fields=exclude_fields,
@@ -10,6 +10,7 @@ import typer
10
10
 
11
11
  from datalegion_cli.async_typer import async_command
12
12
  from datalegion_cli.client import APIError, LegionClient
13
+ from datalegion_cli.commands import CursorOpt, search_query
13
14
  from datalegion_cli.output import emit_credits, emit_error, emit_json, emit_search_warning
14
15
 
15
16
  app = typer.Typer(name="person", help="Person enrichment, search, and discovery.")
@@ -128,23 +129,32 @@ async def enrich(
128
129
  @app.command()
129
130
  @async_command
130
131
  async def search(
131
- query: Annotated[str, typer.Argument(help="SQL SELECT query against the people table.")],
132
+ query: Annotated[
133
+ str,
134
+ typer.Argument(
135
+ help="SQL SELECT query against the people table, or a query object as JSON."
136
+ ),
137
+ ],
132
138
  limit: LimitOpt = 1,
139
+ cursor: CursorOpt = None,
133
140
  titlecase: TitleOpt = False,
134
141
  include_fields: FieldsInclude = None,
135
142
  exclude_fields: FieldsExclude = None,
136
143
  ) -> None:
137
- """Search for people with a SQL SELECT over the people table, no LIMIT (Beta).
144
+ """Search for people with a SQL SELECT over the people table, no LIMIT.
138
145
 
139
146
  Examples:
140
147
  datalegion-cli person search "SELECT * FROM people WHERE job_title = 'ceo' AND company_name ILIKE '%acme%'"
141
148
  datalegion-cli person search "SELECT * FROM people WHERE city = 'san francisco'" --limit 20
149
+ datalegion-cli person search '{"term": {"company_name": "acme"}}' --limit 100
150
+ datalegion-cli person search "SELECT * FROM people WHERE state = 'ohio'" --limit 100 --cursor <next_cursor>
142
151
  """
143
152
  client = LegionClient()
144
153
  try:
145
154
  result = await client.person_search(
146
- query=query,
155
+ query=search_query(query),
147
156
  limit=limit,
157
+ cursor=cursor,
148
158
  titlecase=titlecase,
149
159
  include_fields=include_fields,
150
160
  exclude_fields=exclude_fields,
@@ -168,6 +168,36 @@ class TestPersonSearch:
168
168
  assert result.exit_code == 0
169
169
 
170
170
 
171
+ class TestSearchQueryObjectAndCursor:
172
+ @pytest.mark.parametrize("entity", ["person", "company"])
173
+ def test_a_json_query_goes_as_an_object_with_the_cursor(self, monkeypatch, entity):
174
+ _mock_config(monkeypatch)
175
+ sent = []
176
+
177
+ async def fake_request(self, method, endpoint, *, payload=None, params=None):
178
+ sent.append(payload)
179
+ return {"matches": [], "total": 0, "next_cursor": "abc"}
180
+
181
+ monkeypatch.setattr("datalegion_cli.client.LegionClient.request", fake_request)
182
+ result = runner.invoke(
183
+ app, [entity, "search", '{"exists": {"field": "legion_id"}}', "--cursor", "abc"]
184
+ )
185
+ assert result.exit_code == 0, result.output
186
+ assert sent[0]["query"] == {"exists": {"field": "legion_id"}}
187
+ assert sent[0]["cursor"] == "abc"
188
+ assert json.loads(result.stdout)["next_cursor"] == "abc"
189
+
190
+ def test_a_query_that_looks_like_json_but_does_not_parse_is_refused(self, monkeypatch):
191
+ _mock_config(monkeypatch)
192
+ result = runner.invoke(app, ["person", "search", "{not json"])
193
+ assert result.exit_code == 2
194
+
195
+ def test_sql_stays_a_string(self):
196
+ from datalegion_cli.commands import search_query
197
+
198
+ assert search_query("SELECT * FROM people") == "SELECT * FROM people"
199
+
200
+
171
201
  class TestPersonDiscover:
172
202
  def test_discover(self, monkeypatch):
173
203
  _mock_config(monkeypatch)
@@ -1 +0,0 @@
1
- """CLI command modules."""
File without changes