codefetch-cli 1.2.2__tar.gz → 1.2.4__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codefetch-cli
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: Quickly fetch code files from GitHub repositories with simple commands
5
5
  Home-page: https://github.com/InzamamulQureshi/Codefetch
6
6
  Author: Inzamamul Qureshi
@@ -24,7 +24,7 @@ Dynamic: requires-python
24
24
 
25
25
  Quickly fetch code files from GitHub repositories with simple commands.
26
26
 
27
- CodeFetch is a lightweight command-line utility designed to quickly inspect, preview, and download individual source code files directly from any GitHub repository without needing to clone full repositories.
27
+ CodeFetch is a lightweight command-line utility and Python library designed to quickly inspect, preview, and download individual source code files directly from any GitHub repository without needing to clone full repositories.
28
28
 
29
29
  ---
30
30
 
@@ -35,6 +35,7 @@ CodeFetch is a lightweight command-line utility designed to quickly inspect, pre
35
35
  - **Automatic Path & Case Resolution**: Automatically resolves case mismatches and finds files nested inside subdirectories.
36
36
  - **Repository Discovery**: List all public repositories for any GitHub user with `--repos`.
37
37
  - **Tree Exploration**: List all supported code files within a repository with `--list`.
38
+ - **Python Library Support**: Import and use programmatically with `import codefetch as cf`.
38
39
  - **Optional Persistent Defaults**: Save a default repository or user with `--set-default` if you frequently work with the same repository.
39
40
  - **Zero Runtime Dependencies**: Built using only the Python standard library with zero third-party dependencies.
40
41
 
@@ -130,6 +131,28 @@ codefetch --reset-config
130
131
 
131
132
  ---
132
133
 
134
+ ## Python API Usage
135
+
136
+ You can also use CodeFetch programmatically within your Python scripts:
137
+
138
+ ```python
139
+ import codefetch as cf
140
+
141
+ # 1. Fetch file content as a string directly in memory
142
+ makefile_text = cf.get("torvalds/linux", "Makefile")
143
+ # Or shorthand single argument syntax:
144
+ readme_text = cf.get("psf/requests/README.md")
145
+
146
+ # 2. Download a file to disk
147
+ cf.download("torvalds/linux", "Makefile", output="linux_Makefile")
148
+
149
+ # 3. List all code files in a repository
150
+ files = cf.list("torvalds/linux")
151
+ print(f"Found {len(files)} files")
152
+ ```
153
+
154
+ ---
155
+
133
156
  ## Command Reference
134
157
 
135
158
  | Flag | Description | Example |
@@ -2,7 +2,7 @@
2
2
 
3
3
  Quickly fetch code files from GitHub repositories with simple commands.
4
4
 
5
- CodeFetch is a lightweight command-line utility designed to quickly inspect, preview, and download individual source code files directly from any GitHub repository without needing to clone full repositories.
5
+ CodeFetch is a lightweight command-line utility and Python library designed to quickly inspect, preview, and download individual source code files directly from any GitHub repository without needing to clone full repositories.
6
6
 
7
7
  ---
8
8
 
@@ -13,6 +13,7 @@ CodeFetch is a lightweight command-line utility designed to quickly inspect, pre
13
13
  - **Automatic Path & Case Resolution**: Automatically resolves case mismatches and finds files nested inside subdirectories.
14
14
  - **Repository Discovery**: List all public repositories for any GitHub user with `--repos`.
15
15
  - **Tree Exploration**: List all supported code files within a repository with `--list`.
16
+ - **Python Library Support**: Import and use programmatically with `import codefetch as cf`.
16
17
  - **Optional Persistent Defaults**: Save a default repository or user with `--set-default` if you frequently work with the same repository.
17
18
  - **Zero Runtime Dependencies**: Built using only the Python standard library with zero third-party dependencies.
18
19
 
@@ -108,6 +109,28 @@ codefetch --reset-config
108
109
 
109
110
  ---
110
111
 
112
+ ## Python API Usage
113
+
114
+ You can also use CodeFetch programmatically within your Python scripts:
115
+
116
+ ```python
117
+ import codefetch as cf
118
+
119
+ # 1. Fetch file content as a string directly in memory
120
+ makefile_text = cf.get("torvalds/linux", "Makefile")
121
+ # Or shorthand single argument syntax:
122
+ readme_text = cf.get("psf/requests/README.md")
123
+
124
+ # 2. Download a file to disk
125
+ cf.download("torvalds/linux", "Makefile", output="linux_Makefile")
126
+
127
+ # 3. List all code files in a repository
128
+ files = cf.list("torvalds/linux")
129
+ print(f"Found {len(files)} files")
130
+ ```
131
+
132
+ ---
133
+
111
134
  ## Command Reference
112
135
 
113
136
  | Flag | Description | Example |
@@ -0,0 +1,160 @@
1
+ """
2
+ CodeFetch - Easily preview and download code files from GitHub repositories.
3
+
4
+ Usage in Python:
5
+ import codefetch as cf
6
+
7
+ # 1. Fetch file content as string:
8
+ content = cf.get("torvalds/linux", "Makefile")
9
+ # or shorthand target string:
10
+ content = cf.get("torvalds/linux/Makefile")
11
+
12
+ # 2. Download file to local disk:
13
+ cf.download("torvalds/linux", "Makefile", output="linux_makefile.txt")
14
+
15
+ # 3. List available code files:
16
+ files = cf.list("torvalds/linux")
17
+ """
18
+
19
+ __version__ = "1.2.4"
20
+
21
+
22
+ def get(target, filename=None, branch=None):
23
+ """
24
+ Fetch and return the text content of a file from GitHub.
25
+
26
+ Args:
27
+ target: 'owner/repo' or full path 'owner/repo/path/to/file' or full GitHub URL.
28
+ filename: Optional path to file in repo if target is 'owner/repo'.
29
+ branch: Branch name (default: None, automatically detects repo default branch).
30
+
31
+ Returns:
32
+ str: File content.
33
+
34
+ Raises:
35
+ FileNotFoundError: If the file does not exist in the repository.
36
+ ValueError: If arguments cannot be resolved into a repository and filename.
37
+ """
38
+ import urllib.request
39
+ from .cli import (
40
+ get_default_branch,
41
+ check_branch_exists,
42
+ fetch_raw_single,
43
+ get_repo_tree,
44
+ resolve_file_in_tree,
45
+ parse_repo_identifier,
46
+ resolve_invocation,
47
+ )
48
+
49
+ if filename:
50
+ owner, repo = parse_repo_identifier(target)
51
+ file_path = filename.strip("/\\")
52
+ else:
53
+ owner, repo, resolved_branch, file_path = resolve_invocation(
54
+ [target], None, None, branch, None, None
55
+ )
56
+ if resolved_branch:
57
+ branch = resolved_branch
58
+
59
+ if not owner or not repo or not file_path:
60
+ raise ValueError(f"Could not resolve owner, repo, and filename from target='{target}', filename='{filename}'")
61
+
62
+ target_branch = branch
63
+ if not target_branch:
64
+ target_branch = get_default_branch(owner, repo)
65
+ elif not check_branch_exists(owner, repo, target_branch):
66
+ target_branch = get_default_branch(owner, repo)
67
+
68
+ # 1. Try fast direct raw fetch
69
+ content = fetch_raw_single(owner, repo, target_branch, file_path)
70
+ if content is not None:
71
+ return content
72
+
73
+ # 2. Try repository tree search
74
+ tree_data = get_repo_tree(owner, repo, target_branch)
75
+ matched = resolve_file_in_tree(tree_data, file_path)
76
+ if matched:
77
+ url = f"https://raw.githubusercontent.com/{owner}/{repo}/{target_branch}/{matched}"
78
+ req = urllib.request.Request(url, headers={"User-Agent": "codefetch"})
79
+ with urllib.request.urlopen(req, timeout=15) as resp:
80
+ return resp.read().decode("utf-8")
81
+
82
+ raise FileNotFoundError(f"File '{file_path}' not found in {owner}/{repo} ({target_branch})")
83
+
84
+
85
+ def download(target, filename=None, output=None, branch=None):
86
+ """
87
+ Download a file from GitHub and save it locally.
88
+
89
+ Args:
90
+ target: 'owner/repo' or full path 'owner/repo/path/to/file'.
91
+ filename: Optional path to file in repo if target is 'owner/repo'.
92
+ output: Destination filename/path on local disk (default: original filename).
93
+ branch: Branch name (default: None, automatically detects repo default branch).
94
+
95
+ Returns:
96
+ str: Path to the downloaded file.
97
+ """
98
+ content = get(target, filename=filename, branch=branch)
99
+ dest_name = output
100
+ if not dest_name:
101
+ resolved_file = filename if filename else target.rsplit("/", 1)[-1]
102
+ dest_name = resolved_file.rsplit("/", 1)[-1]
103
+
104
+ with open(dest_name, "w", encoding="utf-8") as f:
105
+ f.write(content)
106
+
107
+ return dest_name
108
+
109
+
110
+ def list(target, branch=None):
111
+ """
112
+ List supported code files in a repository.
113
+
114
+ Args:
115
+ target: 'owner/repo' or repository URL.
116
+ branch: Branch name (default: None, automatically detects repo default branch).
117
+
118
+ Returns:
119
+ list[str]: Relative paths of code files in the repository.
120
+ """
121
+ from .cli import (
122
+ parse_repo_identifier,
123
+ get_default_branch,
124
+ check_branch_exists,
125
+ get_repo_tree,
126
+ CODE_EXTENSIONS,
127
+ NAMED_FILES,
128
+ )
129
+
130
+ owner, repo = parse_repo_identifier(target)
131
+ if not owner or not repo:
132
+ raise ValueError(f"Invalid repository identifier: '{target}'")
133
+
134
+ target_branch = branch
135
+ if not target_branch or not check_branch_exists(owner, repo, target_branch):
136
+ target_branch = get_default_branch(owner, repo)
137
+
138
+ tree_data = get_repo_tree(owner, repo, target_branch)
139
+ files = []
140
+ for item in tree_data.get("tree", []):
141
+ if item.get("type") != "blob":
142
+ continue
143
+ path = item.get("path", "")
144
+ base_name = path.rsplit("/", 1)[-1].lower()
145
+ suffix = ""
146
+ if "." in base_name:
147
+ suffix = "." + base_name.rsplit(".", 1)[-1]
148
+ if suffix in CODE_EXTENSIONS or base_name in NAMED_FILES:
149
+ files.append(path)
150
+
151
+ files.sort(key=str.lower)
152
+ return files
153
+
154
+
155
+ __all__ = [
156
+ "__version__",
157
+ "get",
158
+ "download",
159
+ "list",
160
+ ]