Skip to content

Commit c592c5b

Browse files
authored
0.5 Update (#33)
* Drop dependency (whats-that-code) * Following the latest API update , /code path will return a `language` field in response. See [here](boyter/searchcode#54) * Return results as SimpleNamespace object(s) * Updated tests
2 parents a1ff845 + 28d71d1 commit c592c5b

7 files changed

Lines changed: 86 additions & 111 deletions

File tree

README.md

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,14 @@ searchcode "import module" --languages java,javascript
9191
#### In Code
9292

9393
```python
94+
from pprint import pprint
9495
from searchcode import Searchcode
9596

9697
sc = Searchcode(user_agent="My-Searchcode-script")
9798
search = sc.search(query="import module", languages=["Java", "JavaScript"])
9899

99-
for result in search.get("results"):
100-
print(result.language)
100+
for result in search.results:
101+
pprint(result.language)
101102
```
102103

103104
___
@@ -113,13 +114,14 @@ searchcode "import module" --sources bitbucket,codeplex
113114
#### In Code
114115

115116
```python
117+
from pprint import pprint
116118
from searchcode import Searchcode
117119

118120
sc = Searchcode(user_agent="My-Searchcode-script")
119121
search = sc.search(query="import module", sources=["BitBucket", "CodePlex"])
120122

121-
for result in search.get("results"):
122-
print(result.filename)
123+
for result in search.results:
124+
pprint(result.filename)
123125
```
124126

125127
___
@@ -135,14 +137,14 @@ searchcode "import module" --lines-of-code-gt 500 --lines-of-code-lt 1000
135137
#### In Code
136138

137139
```python
138-
140+
from pprint import pprint
139141
from searchcode import Searchcode
140142

141143
sc = Searchcode(user_agent="My-Searchcode-script")
142144
search = sc.search(query="import module", lines_of_code_gt=500, lines_of_code_lt=1000)
143145

144-
for result in search.get("results"):
145-
print(result)
146+
for result in search.results:
147+
pprint(result)
146148
```
147149

148150
___
@@ -158,11 +160,13 @@ searchcode "import module" --callback myCallback
158160
#### In Code
159161

160162
```python
163+
from pprint import pprint
161164
from searchcode import Searchcode
162165

163166
sc = Searchcode(user_agent="My-Searchcode-script")
164167
search = sc.search(query="import module", callback="myCallback")
165-
print(search)
168+
169+
pprint(search)
166170
```
167171

168172
`
@@ -221,8 +225,10 @@ searchode code 4061576
221225
from searchcode import Searchcode
222226

223227
sc = Searchcode(user_agent="My-Searchcode-script")
224-
code = sc.code(4061576)
225-
print(code)
228+
data = sc.code(4061576)
229+
230+
print(data.language)
231+
print(data.code)
226232
```
227233

228234
---

poetry.lock

Lines changed: 1 addition & 60 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "searchcode"
3-
version = "0.4.4"
3+
version = "0.5.0"
44
description = "Simple, comprehensive code search."
55
authors = ["Ritchie Mwewa <rly0nheart@duck.com>"]
66
license = "GPLv3+"
@@ -20,7 +20,6 @@ classifiers = [
2020
python = "^3.10"
2121
requests = "^2.32.2"
2222
rich-click = "^1.8.8"
23-
whats-that-code = "^0.2.0"
2423

2524
[tool.poetry.group.dev.dependencies]
2625
flake8 = "^7.1.2"

searchcode/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from .api import Searchcode
2121

2222
__pkg__ = "searchcode"
23-
__version__ = "0.4.4"
23+
__version__ = "0.5.0"
2424
__author__ = "Ritchie Mwewa"
2525

2626

searchcode/api.py

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@
1717

1818
import typing as t
1919
from platform import python_version, platform
20+
from types import SimpleNamespace
2021

2122
import requests
2223

2324
from .filters import CODE_LANGUAGES, CODE_SOURCES, get_language_ids, get_source_ids
2425

25-
BASE_API_ENDPOINT = "https://searchcode.com/api"
26-
2726
__all__ = ["Searchcode"]
2827

2928

3029
class Searchcode:
3130
def __init__(self, user_agent: str):
3231
self.user_agent = user_agent
32+
self.__base_api_endpoint: str = "https://searchcode.com/api"
3333

3434
def search(
3535
self,
@@ -41,7 +41,7 @@ def search(
4141
lines_of_code_gt: t.Optional[int] = None,
4242
lines_of_code_lt: t.Optional[int] = None,
4343
callback: t.Optional[str] = None,
44-
) -> t.Union[t.Dict, str]:
44+
) -> t.Union[SimpleNamespace, str]:
4545
"""
4646
Searches and returns code snippets matching the query.
4747
@@ -80,7 +80,7 @@ def search(
8080
source_ids = [] if not sources else get_source_ids(source_names=sources)
8181

8282
response = self.__send_request(
83-
endpoint=f"{BASE_API_ENDPOINT}/{'jsonp_codesearch_I' if callback else 'codesearch_I'}/",
83+
endpoint=f"{self.__base_api_endpoint}/{'jsonp_codesearch_I' if callback else 'codesearch_I'}/",
8484
params=[
8585
("q", query),
8686
("p", page),
@@ -95,22 +95,25 @@ def search(
9595
)
9696

9797
if not callback:
98-
response["results"] = response.get("results", [])[:per_page]
98+
response = self.__to_namespace_obj(response=response)
99+
response.results = response.results[:per_page]
99100

100101
return response
101102

102-
def code(self, __id: int) -> str:
103+
def code(self, __id: int) -> SimpleNamespace:
103104
"""
104105
Returns the raw data from a code file given the code ID which can be found as the `id` in a code search result.
105106
106107
:param __id: The unique identifier of the code result.
107108
:type __id: int
108-
:return: Raw code result data.
109-
:rtype: str
109+
:return: SimpleNamespace object containing code file data.
110+
:rtype: SimpleNamespace
110111
"""
111112

112-
response = self.__send_request(endpoint=f"{BASE_API_ENDPOINT}/result/{__id}")
113-
return response.get("code")
113+
response = self.__send_request(
114+
endpoint=f"{self.__base_api_endpoint}/result/{__id}"
115+
)
116+
return self.__to_namespace_obj(response=response)
114117

115118
# This is deprecated (for now).
116119
# def related(_id: int) -> Dict:
@@ -156,3 +159,28 @@ def __send_request(
156159
)
157160
response.raise_for_status()
158161
return response.text if callback else response.json()
162+
163+
def __to_namespace_obj(
164+
self,
165+
response: t.Union[t.List[t.Dict], t.Dict],
166+
) -> t.Union[t.List[SimpleNamespace], SimpleNamespace, t.List[t.Dict], t.Dict]:
167+
"""
168+
Recursively converts the API response into a SimpleNamespace object(s).
169+
170+
:param response: The object to convert, either a dictionary or a list of dictionaries.
171+
:type response: Union[List[Dict], Dict]
172+
:return: A SimpleNamespace object or list of SimpleNamespace objects.
173+
:rtype: Union[List[SimpleNamespace], SimpleNamespace, None]
174+
"""
175+
176+
if isinstance(response, t.Dict):
177+
return SimpleNamespace(
178+
**{
179+
key: self.__to_namespace_obj(response=value)
180+
for key, value in response.items()
181+
}
182+
)
183+
elif isinstance(response, t.List):
184+
return [self.__to_namespace_obj(response=item) for item in response]
185+
else:
186+
return response

searchcode/cli.py

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
import os
1919
import subprocess
2020
import typing as t
21+
from types import SimpleNamespace
2122

2223
import rich_click as click
2324
from rich import box
2425
from rich.console import Console
2526
from rich.panel import Panel
2627
from rich.pretty import pprint
2728
from rich.syntax import Syntax
28-
from whats_that_code.election import guess_language_all_methods
2929

3030
from . import License, __pkg__, __version__
3131
from .api import Searchcode
@@ -136,11 +136,13 @@ def search(
136136
__clear_screen()
137137
__update_window_title(text=query)
138138

139-
with console.status(f"Querying code index with [green]{query}[/]"):
139+
with console.status(
140+
f"Querying code index with search string: [green]{query}[/]..."
141+
):
140142
languages = languages.split(",") if languages else None
141143
sources = sources.split(",") if sources else None
142144

143-
results = sc.search(
145+
response = sc.search(
144146
query=query,
145147
page=page,
146148
per_page=per_page,
@@ -152,13 +154,9 @@ def search(
152154
)
153155

154156
(
155-
__print_jsonp(jsonp=results)
157+
__print_jsonp(jsonp=response)
156158
if callback
157-
else (
158-
pprint(results)
159-
if pretty
160-
else __print_panels(data=results.get("results"))
161-
)
159+
else (pprint(response) if pretty else __print_panels(data=response.results))
162160
)
163161

164162

@@ -172,13 +170,13 @@ def code(id: int):
172170
"""
173171
__clear_screen()
174172
__update_window_title(text=str(id))
175-
with console.status(f"Retrieving code data for [cyan]{id}[/]") as status:
176-
code_data = sc.code(id)
177-
if code_data:
178-
status.update("Determining code language")
179-
language = guess_language_all_methods(code=code_data)
173+
with console.status(f"Fetching data for code file with ID: [cyan]{id}[/]..."):
174+
data = sc.code(id)
175+
lines = data.code
176+
language = data.language
177+
if lines:
180178
syntax = Syntax(
181-
code=code_data, lexer=language, line_numbers=True, theme="dracula"
179+
code=lines, lexer=language, line_numbers=True, theme="dracula"
182180
)
183181
console.print(syntax)
184182

@@ -193,7 +191,7 @@ def __print_jsonp(jsonp: str) -> None:
193191
console.print(syntax)
194192

195193

196-
def __print_panels(data: t.List[t.Dict]):
194+
def __print_panels(data: t.List[SimpleNamespace]):
197195
"""
198196
Render a list of code records as rich panels with syntax highlighting.
199197
Line numbers are preserved and displayed alongside code content.
@@ -218,14 +216,13 @@ def extract_code_string_with_linenumbers(lines_dict: t.Dict[str, str]) -> str:
218216
return "\n".join(numbered_lines)
219217

220218
for item in data:
221-
filename = item.get("filename", "Unknown")
222-
repo = item.get("repo", "Unknown")
223-
language = item.get("language", "text")
224-
lines_count = item.get("linescount", "??")
219+
filename = item.filename
220+
repo = item.repo
221+
language = item.language
222+
lines_count = item.linescount
223+
lines = item.lines
225224

226-
code_string = extract_code_string_with_linenumbers(
227-
lines_dict=item.get("lines", {})
228-
)
225+
code_string = extract_code_string_with_linenumbers(lines_dict=lines.__dict__)
229226

230227
syntax = Syntax(
231228
code=code_string,

0 commit comments

Comments
 (0)