namecheap-python 1.0.0__tar.gz → 1.0.1__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 (38) hide show
  1. namecheap_python-1.0.1/.github/workflows/release.yml +73 -0
  2. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/PKG-INFO +73 -62
  3. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/README.md +70 -61
  4. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/pyproject.toml +3 -1
  5. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_cli/__main__.py +57 -28
  6. namecheap_python-1.0.0/.github/workflows/publish.yml +0 -45
  7. namecheap_python-1.0.0/.github/workflows/release.yml +0 -113
  8. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/.env.example +0 -0
  9. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/.github/workflows/lint.yml +0 -0
  10. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/.gitignore +0 -0
  11. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/.pre-commit-config.yaml +0 -0
  12. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/CLI.md +0 -0
  13. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/LICENSE +0 -0
  14. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/MANIFEST.in +0 -0
  15. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/docs/dev/README.md +0 -0
  16. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/examples/README.md +0 -0
  17. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/examples/quickstart.py +0 -0
  18. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/pending.md +0 -0
  19. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap/__init__.py +0 -0
  20. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap/_api/__init__.py +0 -0
  21. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap/_api/base.py +0 -0
  22. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap/_api/dns.py +0 -0
  23. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap/_api/domains.py +0 -0
  24. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap/client.py +0 -0
  25. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap/errors.py +0 -0
  26. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap/logging.py +0 -0
  27. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap/models.py +0 -0
  28. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_cli/README.md +0 -0
  29. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_cli/__init__.py +0 -0
  30. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_cli/completion.py +0 -0
  31. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_dns_tui/README.md +0 -0
  32. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_dns_tui/__init__.py +0 -0
  33. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_dns_tui/__main__.py +0 -0
  34. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_dns_tui/assets/screenshot1.png +0 -0
  35. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_dns_tui/assets/screenshot2.png +0 -0
  36. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_dns_tui/assets/screenshot3.png +0 -0
  37. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/src/namecheap_dns_tui/assets/screenshot4.png +0 -0
  38. {namecheap_python-1.0.0 → namecheap_python-1.0.1}/uv.lock +0 -0
@@ -0,0 +1,73 @@
1
+ name: Release to PyPI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ environment:
11
+ name: pypi
12
+ url: https://pypi.org/p/namecheap-python
13
+ permissions:
14
+ id-token: write
15
+ contents: write
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+
19
+ - name: Set up Python
20
+ uses: actions/setup-python@v5
21
+ with:
22
+ python-version: "3.12"
23
+
24
+ - name: Install uv
25
+ uses: astral-sh/setup-uv@v3
26
+
27
+ - name: Build package
28
+ run: uv build
29
+
30
+ - name: Check if version exists on PyPI
31
+ id: check
32
+ run: |
33
+ WHEEL=$(ls dist/*.whl | head -1)
34
+ PACKAGE_NAME=$(echo $WHEEL | cut -d'/' -f2 | cut -d'-' -f1)
35
+ VERSION=$(echo $WHEEL | cut -d'/' -f2 | cut -d'-' -f2)
36
+
37
+ if [ -z "$VERSION" ] || [ -z "$PACKAGE_NAME" ]; then
38
+ echo "Failed to extract package name or version from wheel"
39
+ exit 1
40
+ fi
41
+
42
+ echo "package=$PACKAGE_NAME" >> $GITHUB_OUTPUT
43
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
44
+ echo "Checking PyPI for $PACKAGE_NAME version $VERSION"
45
+
46
+ if curl -sf https://pypi.org/pypi/$PACKAGE_NAME/$VERSION/json > /dev/null 2>&1; then
47
+ echo "exists=true" >> $GITHUB_OUTPUT
48
+ echo "Version $VERSION already exists on PyPI"
49
+ else
50
+ echo "exists=false" >> $GITHUB_OUTPUT
51
+ echo "Version $VERSION not on PyPI, will publish"
52
+ fi
53
+
54
+ - name: Publish to PyPI
55
+ if: steps.check.outputs.exists == 'false'
56
+ uses: pypa/gh-action-pypi-publish@release/v1
57
+
58
+ - name: Create git tag
59
+ if: steps.check.outputs.exists == 'false'
60
+ run: |
61
+ VERSION=${{ steps.check.outputs.version }}
62
+ git config user.name github-actions
63
+ git config user.email github-actions@github.com
64
+ git tag -a "v$VERSION" -m "Release v$VERSION"
65
+ git push origin "v$VERSION"
66
+
67
+ - name: Create GitHub Release
68
+ if: steps.check.outputs.exists == 'false'
69
+ uses: softprops/action-gh-release@v2
70
+ with:
71
+ tag_name: v${{ steps.check.outputs.version }}
72
+ name: v${{ steps.check.outputs.version }}
73
+ generate_release_notes: true
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: namecheap-python
3
- Version: 1.0.0
3
+ Version: 1.0.1
4
4
  Summary: A friendly Python SDK for Namecheap API
5
5
  Project-URL: Homepage, https://github.com/adriangalilea/namecheap-python
6
6
  Project-URL: Repository, https://github.com/adriangalilea/namecheap-python
@@ -26,11 +26,13 @@ Requires-Dist: tldextract>=5.0.0
26
26
  Requires-Dist: xmltodict>=0.13.0
27
27
  Provides-Extra: all
28
28
  Requires-Dist: click>=8.1.0; extra == 'all'
29
+ Requires-Dist: platformdirs>=4.0.0; extra == 'all'
29
30
  Requires-Dist: pyyaml>=6.0.0; extra == 'all'
30
31
  Requires-Dist: rich>=13.0.0; extra == 'all'
31
32
  Requires-Dist: textual>=0.47.0; extra == 'all'
32
33
  Provides-Extra: cli
33
34
  Requires-Dist: click>=8.1.0; extra == 'cli'
35
+ Requires-Dist: platformdirs>=4.0.0; extra == 'cli'
34
36
  Requires-Dist: pyyaml>=6.0.0; extra == 'cli'
35
37
  Requires-Dist: rich>=13.0.0; extra == 'cli'
36
38
  Provides-Extra: dev
@@ -60,26 +62,17 @@ A modern, friendly Python SDK for the Namecheap API with comprehensive CLI and T
60
62
  - **Comprehensive logging** with beautiful colored output
61
63
  - **Sandbox support** for safe testing
62
64
 
63
- ## 📦 Installation
64
-
65
- ```bash
66
- # Core SDK only
67
- pip install namecheap-python
65
+ ## 🎯 Quick Start
68
66
 
69
- # With CLI tool
70
- pip install namecheap-python[cli]
67
+ **Requires Python 3.12 or higher**
71
68
 
72
- # With TUI tool
73
- pip install namecheap-python[tui]
69
+ ### `namecheap-python`: Core Python SDK Library
74
70
 
75
- # Everything
76
- pip install namecheap-python[all]
71
+ ```bash
72
+ # Add as a dependency to your project
73
+ uv add namecheap-python
77
74
  ```
78
75
 
79
- ## 🎯 Quick Start
80
-
81
- ### SDK Usage
82
-
83
76
  ```python
84
77
  from namecheap import Namecheap
85
78
 
@@ -107,18 +100,22 @@ nc.dns.set("example.com",
107
100
  )
108
101
  ```
109
102
 
110
- ### CLI Usage
103
+ ### `namecheap-cli`: CLI tool
111
104
 
112
- ```bash
113
- # Configure CLI
114
- uv run namecheap-cli config init
105
+ It was meant as a proof of concept to showcase `namecheap-python`, but it is a tool that I use
115
106
 
107
+ ```bash
116
108
  # List domains with beautiful table output
117
- uv run namecheap-cli domain list
118
- ```
119
109
 
120
- Output:
121
- ```
110
+ # Run it without install with:
111
+ uvx --from 'namecheap-python[cli]' namecheap-cli domain list
112
+
113
+ # Or install it permanently with:
114
+ uv tool install --python 3.12 'namecheap-python[cli]'
115
+
116
+ # Then run
117
+ namecheap-cli domain list
118
+
122
119
  Domains (4 total)
123
120
  ┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━┓
124
121
  ┃ Domain ┃ Status ┃ Expires ┃ Auto-Renew ┃ Locked ┃
@@ -130,22 +127,42 @@ Output:
130
127
  └───────────────────┴────────┴────────────┴────────────┴────────┘
131
128
  ```
132
129
 
130
+ Configure it before first use:
131
+
132
+ ```bash
133
+ # Interactive setup
134
+ namecheap-cli config init
135
+
136
+ # Creates config file at:
137
+ # - Linux/macOS: $XDG_CONFIG_HOME/namecheap/config.yaml (or ~/.config/namecheap/config.yaml)
138
+ # - Windows: %APPDATA%\namecheap\config.yaml
139
+ ```
140
+ Check domain availability and pricing:
141
+
133
142
  ```bash
134
143
  # Check domain availability
135
- uv run namecheap-cli domain check myawesome.com coolstartup.io
144
+ namecheap-cli domain check myawesome.com coolstartup.io
145
+ Domain Availability
146
+ ┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓
147
+ ┃ Domain ┃ Available ┃ Price (USD/year) ┃
148
+ ┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩
149
+ │ myawesome.com │ ❌ Taken │ - │
150
+ │ coolstartup.io │ ✅ Available │ $34.98 │
151
+ └────────────────┴──────────────┴──────────────────┘
152
+
153
+ 💡 Suggestions for taken domains:
154
+ • myawesome.com → myawesome.net, myawesome.io, getmyawesome.com
155
+ ```
156
+
157
+ Manage DNS records:
136
158
 
137
- # Manage DNS records
138
- uv run namecheap-cli dns list example.com
139
- uv run namecheap-cli dns add example.com A www 192.0.2.1
140
- uv run namecheap-cli dns export example.com --format yaml
159
+ In this example I'll set up GitHub Pages for my domain `tdo.garden`
141
160
 
142
- # Setup GitHub Pages (example: tdo.garden)
161
+ ```bash
143
162
  # First, check current DNS records (before setup)
144
- uv run namecheap-cli dns list tdo.garden
145
- ```
163
+ namecheap-cli dns list tdo.garden
146
164
 
147
- Initial state (Namecheap default parking page):
148
- ```
165
+ # Initial state (Namecheap default parking page):
149
166
  DNS Records for tdo.garden (2 total)
150
167
  ┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┓
151
168
  ┃ Type ┃ Name ┃ Value ┃ TTL ┃ Priority ┃
@@ -153,40 +170,34 @@ Initial state (Namecheap default parking page):
153
170
  │ CNAME │ www │ parkingpage.namecheap.com. │ 1800 │ 10 │
154
171
  │ URL │ @ │ http://www.tdo.garden/ │ 1800 │ 10 │
155
172
  └──────────┴──────────────────────┴────────────────────────────┴──────────┴──────────┘
156
- ```
157
173
 
158
- ```bash
159
174
  # Add GitHub Pages A records for apex domain
160
- uv run namecheap-cli dns add tdo.garden A @ 185.199.108.153
161
- Built namecheap-python @ file:///Users/adrian/Developer/namecheap-python
162
- Uninstalled 1 package in 0.77ms
163
- Installed 1 package in 1ms
175
+ ❯ namecheap-cli dns add tdo.garden A @ 185.199.108.153
164
176
  Adding A record to tdo.garden...
165
177
  ✅ Added A record successfully!
166
178
 
167
- uv run namecheap-cli dns add tdo.garden A @ 185.199.109.153
179
+ ❯ namecheap-cli dns add tdo.garden A @ 185.199.109.153
168
180
  Adding A record to tdo.garden...
169
181
  ✅ Added A record successfully!
170
182
 
171
- uv run namecheap-cli dns add tdo.garden A @ 185.199.110.153
183
+ ❯ namecheap-cli dns add tdo.garden A @ 185.199.110.153
172
184
  Adding A record to tdo.garden...
173
185
  ✅ Added A record successfully!
174
186
 
175
- uv run namecheap-cli dns add tdo.garden A @ 185.199.111.153
187
+ ❯ namecheap-cli dns add tdo.garden A @ 185.199.111.153
176
188
  Adding A record to tdo.garden...
177
189
  ✅ Added A record successfully!
178
190
 
179
191
  # Add CNAME for www subdomain
180
- uv run namecheap-cli dns add tdo.garden CNAME www adriangalilea.github.io
192
+ ❯ namecheap-cli dns add tdo.garden CNAME www adriangalilea.github.io
181
193
  Adding CNAME record to tdo.garden...
182
194
  ✅ Added CNAME record successfully!
183
195
 
184
196
  # Verify the setup
185
- uv run namecheap-cli dns list tdo.garden
186
- ```
197
+ ❯ namecheap-cli dns list tdo.garden
187
198
 
188
- Final state (with GitHub Pages + old records still present):
189
- ```
199
+ # Final state with GitHub Pages + old records still present that you may want to remove:
200
+ ```bash
190
201
  DNS Records for tdo.garden (7 total)
191
202
  ┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┓
192
203
  ┃ Type ┃ Name ┃ Value ┃ TTL ┃ Priority ┃
@@ -201,18 +212,27 @@ Final state (with GitHub Pages + old records still present):
201
212
  └──────────┴──────────────────────┴────────────────────────────┴──────────┴──────────┘
202
213
  ```
203
214
 
204
- Note: You may want to remove the old parking page records after confirming GitHub Pages works.
205
- ```
206
215
 
207
- ### TUI Usage
216
+ You can also export DNS records:
217
+
218
+ ```bash
219
+ namecheap-cli dns export example.com --format yaml
220
+ ```
221
+ ### `namecheap-dns-tui`: TUI for DNS management
208
222
 
209
223
  ```bash
210
224
  # Launch interactive DNS manager
211
- uv run namecheap-dns-tui
225
+ namecheap-dns-tui
212
226
  ```
213
227
 
214
228
  ![DNS Manager TUI](src/namecheap_dns_tui/assets/screenshot2.png)
215
229
 
230
+ ## Install both the CLI and TUI
231
+
232
+ ```bash
233
+ uv tool install --python 3.12 'namecheap-python[all]'
234
+ ```
235
+
216
236
  ## 📖 Documentation
217
237
 
218
238
  - **[Examples Overview](examples/README.md)** - Quick examples for all tools
@@ -251,15 +271,6 @@ nc = Namecheap(
251
271
  )
252
272
  ```
253
273
 
254
- ### CLI Configuration
255
-
256
- ```bash
257
- # Interactive setup
258
- uv run namecheap-cli config init
259
-
260
- # Creates ~/.namecheap/config.yaml with profiles
261
- ```
262
-
263
274
  ## 🔧 Advanced SDK Usage
264
275
 
265
276
  ### DNS Builder Pattern
@@ -376,4 +387,4 @@ MIT License - see [LICENSE](LICENSE) file for details.
376
387
 
377
388
  ## 🤝 Contributing
378
389
 
379
- Contributions are welcome! Please feel free to submit a Pull Request. See the [Development Guide](docs/dev/README.md) for setup instructions and guidelines.
390
+ Contributions are welcome! Please feel free to submit a Pull Request. See the [Development Guide](docs/dev/README.md) for setup instructions and guidelines.
@@ -13,26 +13,17 @@ A modern, friendly Python SDK for the Namecheap API with comprehensive CLI and T
13
13
  - **Comprehensive logging** with beautiful colored output
14
14
  - **Sandbox support** for safe testing
15
15
 
16
- ## 📦 Installation
17
-
18
- ```bash
19
- # Core SDK only
20
- pip install namecheap-python
16
+ ## 🎯 Quick Start
21
17
 
22
- # With CLI tool
23
- pip install namecheap-python[cli]
18
+ **Requires Python 3.12 or higher**
24
19
 
25
- # With TUI tool
26
- pip install namecheap-python[tui]
20
+ ### `namecheap-python`: Core Python SDK Library
27
21
 
28
- # Everything
29
- pip install namecheap-python[all]
22
+ ```bash
23
+ # Add as a dependency to your project
24
+ uv add namecheap-python
30
25
  ```
31
26
 
32
- ## 🎯 Quick Start
33
-
34
- ### SDK Usage
35
-
36
27
  ```python
37
28
  from namecheap import Namecheap
38
29
 
@@ -60,18 +51,22 @@ nc.dns.set("example.com",
60
51
  )
61
52
  ```
62
53
 
63
- ### CLI Usage
54
+ ### `namecheap-cli`: CLI tool
64
55
 
65
- ```bash
66
- # Configure CLI
67
- uv run namecheap-cli config init
56
+ It was meant as a proof of concept to showcase `namecheap-python`, but it is a tool that I use
68
57
 
58
+ ```bash
69
59
  # List domains with beautiful table output
70
- uv run namecheap-cli domain list
71
- ```
72
60
 
73
- Output:
74
- ```
61
+ # Run it without install with:
62
+ uvx --from 'namecheap-python[cli]' namecheap-cli domain list
63
+
64
+ # Or install it permanently with:
65
+ uv tool install --python 3.12 'namecheap-python[cli]'
66
+
67
+ # Then run
68
+ namecheap-cli domain list
69
+
75
70
  Domains (4 total)
76
71
  ┏━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━┓
77
72
  ┃ Domain ┃ Status ┃ Expires ┃ Auto-Renew ┃ Locked ┃
@@ -83,22 +78,42 @@ Output:
83
78
  └───────────────────┴────────┴────────────┴────────────┴────────┘
84
79
  ```
85
80
 
81
+ Configure it before first use:
82
+
83
+ ```bash
84
+ # Interactive setup
85
+ namecheap-cli config init
86
+
87
+ # Creates config file at:
88
+ # - Linux/macOS: $XDG_CONFIG_HOME/namecheap/config.yaml (or ~/.config/namecheap/config.yaml)
89
+ # - Windows: %APPDATA%\namecheap\config.yaml
90
+ ```
91
+ Check domain availability and pricing:
92
+
86
93
  ```bash
87
94
  # Check domain availability
88
- uv run namecheap-cli domain check myawesome.com coolstartup.io
95
+ namecheap-cli domain check myawesome.com coolstartup.io
96
+ Domain Availability
97
+ ┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━┓
98
+ ┃ Domain ┃ Available ┃ Price (USD/year) ┃
99
+ ┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━┩
100
+ │ myawesome.com │ ❌ Taken │ - │
101
+ │ coolstartup.io │ ✅ Available │ $34.98 │
102
+ └────────────────┴──────────────┴──────────────────┘
103
+
104
+ 💡 Suggestions for taken domains:
105
+ • myawesome.com → myawesome.net, myawesome.io, getmyawesome.com
106
+ ```
107
+
108
+ Manage DNS records:
89
109
 
90
- # Manage DNS records
91
- uv run namecheap-cli dns list example.com
92
- uv run namecheap-cli dns add example.com A www 192.0.2.1
93
- uv run namecheap-cli dns export example.com --format yaml
110
+ In this example I'll set up GitHub Pages for my domain `tdo.garden`
94
111
 
95
- # Setup GitHub Pages (example: tdo.garden)
112
+ ```bash
96
113
  # First, check current DNS records (before setup)
97
- uv run namecheap-cli dns list tdo.garden
98
- ```
114
+ namecheap-cli dns list tdo.garden
99
115
 
100
- Initial state (Namecheap default parking page):
101
- ```
116
+ # Initial state (Namecheap default parking page):
102
117
  DNS Records for tdo.garden (2 total)
103
118
  ┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┓
104
119
  ┃ Type ┃ Name ┃ Value ┃ TTL ┃ Priority ┃
@@ -106,40 +121,34 @@ Initial state (Namecheap default parking page):
106
121
  │ CNAME │ www │ parkingpage.namecheap.com. │ 1800 │ 10 │
107
122
  │ URL │ @ │ http://www.tdo.garden/ │ 1800 │ 10 │
108
123
  └──────────┴──────────────────────┴────────────────────────────┴──────────┴──────────┘
109
- ```
110
124
 
111
- ```bash
112
125
  # Add GitHub Pages A records for apex domain
113
- uv run namecheap-cli dns add tdo.garden A @ 185.199.108.153
114
- Built namecheap-python @ file:///Users/adrian/Developer/namecheap-python
115
- Uninstalled 1 package in 0.77ms
116
- Installed 1 package in 1ms
126
+ ❯ namecheap-cli dns add tdo.garden A @ 185.199.108.153
117
127
  Adding A record to tdo.garden...
118
128
  ✅ Added A record successfully!
119
129
 
120
- uv run namecheap-cli dns add tdo.garden A @ 185.199.109.153
130
+ ❯ namecheap-cli dns add tdo.garden A @ 185.199.109.153
121
131
  Adding A record to tdo.garden...
122
132
  ✅ Added A record successfully!
123
133
 
124
- uv run namecheap-cli dns add tdo.garden A @ 185.199.110.153
134
+ ❯ namecheap-cli dns add tdo.garden A @ 185.199.110.153
125
135
  Adding A record to tdo.garden...
126
136
  ✅ Added A record successfully!
127
137
 
128
- uv run namecheap-cli dns add tdo.garden A @ 185.199.111.153
138
+ ❯ namecheap-cli dns add tdo.garden A @ 185.199.111.153
129
139
  Adding A record to tdo.garden...
130
140
  ✅ Added A record successfully!
131
141
 
132
142
  # Add CNAME for www subdomain
133
- uv run namecheap-cli dns add tdo.garden CNAME www adriangalilea.github.io
143
+ ❯ namecheap-cli dns add tdo.garden CNAME www adriangalilea.github.io
134
144
  Adding CNAME record to tdo.garden...
135
145
  ✅ Added CNAME record successfully!
136
146
 
137
147
  # Verify the setup
138
- uv run namecheap-cli dns list tdo.garden
139
- ```
148
+ ❯ namecheap-cli dns list tdo.garden
140
149
 
141
- Final state (with GitHub Pages + old records still present):
142
- ```
150
+ # Final state with GitHub Pages + old records still present that you may want to remove:
151
+ ```bash
143
152
  DNS Records for tdo.garden (7 total)
144
153
  ┏━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━┓
145
154
  ┃ Type ┃ Name ┃ Value ┃ TTL ┃ Priority ┃
@@ -154,18 +163,27 @@ Final state (with GitHub Pages + old records still present):
154
163
  └──────────┴──────────────────────┴────────────────────────────┴──────────┴──────────┘
155
164
  ```
156
165
 
157
- Note: You may want to remove the old parking page records after confirming GitHub Pages works.
158
- ```
159
166
 
160
- ### TUI Usage
167
+ You can also export DNS records:
168
+
169
+ ```bash
170
+ namecheap-cli dns export example.com --format yaml
171
+ ```
172
+ ### `namecheap-dns-tui`: TUI for DNS management
161
173
 
162
174
  ```bash
163
175
  # Launch interactive DNS manager
164
- uv run namecheap-dns-tui
176
+ namecheap-dns-tui
165
177
  ```
166
178
 
167
179
  ![DNS Manager TUI](src/namecheap_dns_tui/assets/screenshot2.png)
168
180
 
181
+ ## Install both the CLI and TUI
182
+
183
+ ```bash
184
+ uv tool install --python 3.12 'namecheap-python[all]'
185
+ ```
186
+
169
187
  ## 📖 Documentation
170
188
 
171
189
  - **[Examples Overview](examples/README.md)** - Quick examples for all tools
@@ -204,15 +222,6 @@ nc = Namecheap(
204
222
  )
205
223
  ```
206
224
 
207
- ### CLI Configuration
208
-
209
- ```bash
210
- # Interactive setup
211
- uv run namecheap-cli config init
212
-
213
- # Creates ~/.namecheap/config.yaml with profiles
214
- ```
215
-
216
225
  ## 🔧 Advanced SDK Usage
217
226
 
218
227
  ### DNS Builder Pattern
@@ -329,4 +338,4 @@ MIT License - see [LICENSE](LICENSE) file for details.
329
338
 
330
339
  ## 🤝 Contributing
331
340
 
332
- Contributions are welcome! Please feel free to submit a Pull Request. See the [Development Guide](docs/dev/README.md) for setup instructions and guidelines.
341
+ Contributions are welcome! Please feel free to submit a Pull Request. See the [Development Guide](docs/dev/README.md) for setup instructions and guidelines.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "namecheap-python"
3
- version = "1.0.0"
3
+ version = "1.0.1"
4
4
  description = "A friendly Python SDK for Namecheap API"
5
5
  authors = [{name = "Adrian Galilea Delgado", email = "adriangalilea@gmail.com"}]
6
6
  readme = "README.md"
@@ -37,6 +37,7 @@ cli = [
37
37
  "click>=8.1.0",
38
38
  "rich>=13.0.0",
39
39
  "PyYAML>=6.0.0",
40
+ "platformdirs>=4.0.0",
40
41
  ]
41
42
  tui = [
42
43
  "textual>=0.47.0",
@@ -45,6 +46,7 @@ all = [
45
46
  "click>=8.1.0",
46
47
  "rich>=13.0.0",
47
48
  "PyYAML>=6.0.0",
49
+ "platformdirs>=4.0.0",
48
50
  "textual>=0.47.0",
49
51
  ]
50
52
  dev = [
@@ -24,7 +24,24 @@ from .completion import get_completion_script
24
24
  console = Console()
25
25
 
26
26
  # Configuration
27
- CONFIG_DIR = Path.home() / ".namecheap"
27
+ def get_config_dir() -> Path:
28
+ """Get config directory, using XDG on Unix-like systems."""
29
+ import sys
30
+ import os
31
+
32
+ if sys.platform == "win32":
33
+ # Windows: use platformdirs for proper Windows paths
34
+ from platformdirs import user_config_dir
35
+ return Path(user_config_dir("namecheap"))
36
+ else:
37
+ # Linux/macOS: use XDG
38
+ xdg_config = os.environ.get("XDG_CONFIG_HOME")
39
+ if xdg_config:
40
+ return Path(xdg_config) / "namecheap"
41
+ else:
42
+ return Path.home() / ".config" / "namecheap"
43
+
44
+ CONFIG_DIR = get_config_dir()
28
45
  CONFIG_FILE = CONFIG_DIR / "config.yaml"
29
46
 
30
47
 
@@ -54,9 +71,23 @@ class Config:
54
71
  if self.client:
55
72
  return self.client
56
73
 
74
+ # Check if config file exists
75
+ if not CONFIG_FILE.exists():
76
+ console.print("[red]❌ Configuration not found![/red]")
77
+ console.print(f"\nPlease run [bold cyan]namecheap-cli config init[/bold cyan] to set up your configuration.")
78
+ console.print(f"\nThis will create a config file at: [dim]{CONFIG_FILE}[/dim]")
79
+ sys.exit(1)
80
+
57
81
  config = self.load_config()
58
82
  profile_config = config.get("profiles", {}).get(self.profile, {})
59
83
 
84
+ # Check if profile exists
85
+ if not profile_config:
86
+ console.print(f"[red]❌ Profile '{self.profile}' not found in configuration![/red]")
87
+ console.print(f"\nAvailable profiles: {', '.join(config.get('profiles', {}).keys()) or 'none'}")
88
+ console.print(f"\nRun [bold cyan]namecheap-cli config init[/bold cyan] to create a new profile.")
89
+ sys.exit(1)
90
+
60
91
  # Override sandbox if specified
61
92
  if self.sandbox is not None:
62
93
  profile_config["sandbox"] = self.sandbox
@@ -65,7 +96,14 @@ class Config:
65
96
  self.client = Namecheap(**profile_config)
66
97
  return self.client
67
98
  except Exception as e:
68
- console.print(f"[red]❌ Error initializing client: {e}[/red]")
99
+ # Check for common configuration errors
100
+ error_msg = str(e)
101
+ if "Parameter APIUser is missing" in error_msg or "Parameter APIKey is missing" in error_msg:
102
+ console.print("[red]❌ Invalid or incomplete configuration![/red]")
103
+ console.print(f"\nYour configuration appears to be missing required fields.")
104
+ console.print(f"Please run [bold cyan]namecheap-cli config init[/bold cyan] to reconfigure.")
105
+ else:
106
+ console.print(f"[red]❌ Error initializing client: {e}[/red]")
69
107
  sys.exit(1)
70
108
 
71
109
 
@@ -213,9 +251,8 @@ def domain_list(config: Config, status: str | None, sort: str, expiring_in: int
213
251
  @domain_group.command("check")
214
252
  @click.argument("domains", nargs=-1, required=False)
215
253
  @click.option("--file", "-f", type=click.File("r"), help="File with domains to check")
216
- @click.option("--pricing", "-p", is_flag=True, help="Include pricing information")
217
254
  @pass_config
218
- def domain_check(config: Config, domains: tuple[str, ...], file, pricing: bool) -> None:
255
+ def domain_check(config: Config, domains: tuple[str, ...], file) -> None:
219
256
  """Check domain availability."""
220
257
  nc = config.init_client()
221
258
 
@@ -235,39 +272,30 @@ def domain_check(config: Config, domains: tuple[str, ...], file, pricing: bool)
235
272
  transient=True,
236
273
  ) as progress:
237
274
  progress.add_task(f"Checking {len(domain_list)} domains...", total=None)
238
- results = nc.domains.check(*domain_list, include_pricing=pricing)
275
+ results = nc.domains.check(*domain_list, include_pricing=True)
239
276
 
240
277
  # Output
241
278
  if config.output_format == "table":
242
279
  table = Table(title="Domain Availability")
243
280
  table.add_column("Domain", style="cyan")
244
281
  table.add_column("Available", style="green")
245
- if pricing:
246
- table.add_column("Price", style="yellow")
247
- table.add_column("Total", style="yellow")
282
+ table.add_column("Price (USD/year)", style="yellow")
248
283
 
249
284
  for result in results:
250
285
  available_text = "✅ Available" if result.available else "❌ Taken"
251
286
  available_style = "green" if result.available else "red"
252
287
 
288
+ if result.available and result.price:
289
+ price_text = f"${result.price:.2f}"
290
+ else:
291
+ price_text = "-"
292
+
253
293
  row = [
254
294
  result.domain,
255
295
  f"[{available_style}]{available_text}[/{available_style}]",
296
+ price_text
256
297
  ]
257
298
 
258
- if pricing and result.available:
259
- if result.price:
260
- price_text = f"${result.price:.2f}"
261
- total_text = (
262
- f"${result.total_price:.2f}" if result.total_price else price_text
263
- )
264
- else:
265
- price_text = "N/A"
266
- total_text = "N/A"
267
- row.extend([price_text, total_text])
268
- elif pricing:
269
- row.extend(["-", "-"])
270
-
271
299
  table.add_row(*row)
272
300
 
273
301
  console.print(table)
@@ -293,16 +321,11 @@ def domain_check(config: Config, domains: tuple[str, ...], file, pricing: bool)
293
321
  "domain": result.domain,
294
322
  "available": result.available,
295
323
  }
296
- if pricing and result.available and result.price:
324
+ if result.available and result.price:
297
325
  item["price"] = float(result.price)
298
- item["total_price"] = (
299
- float(result.total_price) if result.total_price else float(result.price)
300
- )
301
326
  data.append(item)
302
327
 
303
- headers = ["domain", "available"]
304
- if pricing:
305
- headers.extend(["price", "total_price"])
328
+ headers = ["domain", "available", "price"]
306
329
  output_formatter(data, config.output_format, headers)
307
330
 
308
331
  except NamecheapError as e:
@@ -747,6 +770,12 @@ def config_init() -> None:
747
770
  return
748
771
 
749
772
  console.print("\n[bold cyan]Namecheap CLI Configuration Wizard[/bold cyan]\n")
773
+
774
+ console.print("[dim]To get your API key:[/dim]")
775
+ console.print("1. Go to [link=https://ap.www.namecheap.com/settings/tools/apiaccess/]https://ap.www.namecheap.com/settings/tools/apiaccess/[/link]")
776
+ console.print("2. Enable API access")
777
+ console.print("3. Whitelist your IP address")
778
+ console.print("4. Generate your API key\n")
750
779
 
751
780
  # Get configuration values
752
781
  api_key = Prompt.ask("API Key", password=True)
@@ -1,45 +0,0 @@
1
- name: Publish Python Package
2
-
3
- # This workflow is triggered by the release.yml workflow
4
- # No need for manual triggers, as release.yml handles everything
5
- on:
6
- push:
7
- tags:
8
- - 'v*.*.*' # Run when tag matches v*, e.g., v1.0.0, v2.3.4
9
-
10
- jobs:
11
- deploy:
12
- runs-on: ubuntu-latest
13
- environment:
14
- name: pypi
15
- url: https://pypi.org/p/namecheap-python
16
- permissions:
17
- id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
18
-
19
- steps:
20
- - uses: actions/checkout@v4
21
-
22
- - name: Install uv
23
- uses: astral-sh/setup-uv@v5
24
- with:
25
- enable-cache: true
26
-
27
- - name: Set up Python
28
- run: uv python install 3.12
29
-
30
- - name: Set version from tag (if triggered by tag)
31
- if: startsWith(github.ref, 'refs/tags/')
32
- run: |
33
- # Extract version from the tag
34
- TAG_NAME=${GITHUB_REF#refs/tags/}
35
- VERSION=${TAG_NAME#v}
36
- echo "Using version from tag: ${VERSION}"
37
-
38
- # Update version in pyproject.toml
39
- sed -i "s/^version = .*/version = \"${VERSION}\"/" pyproject.toml
40
-
41
- - name: Build package
42
- run: uv build
43
-
44
- - name: Publish package
45
- uses: pypa/gh-action-pypi-publish@release/v1
@@ -1,113 +0,0 @@
1
- name: Bump Version and Release
2
-
3
- on:
4
- workflow_dispatch:
5
- inputs:
6
- version_part:
7
- description: 'Part of the version to bump (major, minor, patch)'
8
- required: true
9
- default: 'patch'
10
- type: choice
11
- options:
12
- - major
13
- - minor
14
- - patch
15
-
16
- jobs:
17
- release:
18
- runs-on: ubuntu-latest
19
- environment:
20
- name: pypi
21
- url: https://pypi.org/p/namecheap-python
22
- permissions:
23
- contents: write # Needed for creating tags and releases
24
- id-token: write # Needed for PyPI trusted publishing
25
-
26
- steps:
27
- - uses: actions/checkout@v4
28
- with:
29
- fetch-depth: 0
30
-
31
- - name: Install uv
32
- uses: astral-sh/setup-uv@v5
33
- with:
34
- enable-cache: true
35
-
36
- - name: Set up Python
37
- run: uv python install 3.12
38
-
39
- - name: Configure Git
40
- run: |
41
- git config user.name github-actions
42
- git config user.email github-actions@github.com
43
-
44
- - name: Bump version
45
- id: bump_version
46
- run: |
47
- # Get current version
48
- CURRENT_VERSION=$(grep '^version = ' pyproject.toml | cut -d'"' -f2)
49
-
50
- # Calculate new version
51
- IFS='.' read -ra VERSION_PARTS <<< "$CURRENT_VERSION"
52
- MAJOR=${VERSION_PARTS[0]}
53
- MINOR=${VERSION_PARTS[1]}
54
- PATCH=${VERSION_PARTS[2]}
55
-
56
- case "${{ github.event.inputs.version_part }}" in
57
- major)
58
- MAJOR=$((MAJOR + 1))
59
- MINOR=0
60
- PATCH=0
61
- ;;
62
- minor)
63
- MINOR=$((MINOR + 1))
64
- PATCH=0
65
- ;;
66
- patch)
67
- PATCH=$((PATCH + 1))
68
- ;;
69
- esac
70
-
71
- NEW_VERSION="${MAJOR}.${MINOR}.${PATCH}"
72
-
73
- # Update version in pyproject.toml
74
- sed -i "s/^version = .*/version = \"${NEW_VERSION}\"/" pyproject.toml
75
-
76
- echo "NEW_VERSION=${NEW_VERSION}" >> $GITHUB_ENV
77
- echo "Bumped version from ${CURRENT_VERSION} to ${NEW_VERSION}"
78
-
79
- - name: Commit version changes
80
- run: |
81
- git add pyproject.toml
82
- git commit -m "Bump version to ${NEW_VERSION}"
83
- git push
84
-
85
- - name: Create and push tag
86
- run: |
87
- git tag -a "v${NEW_VERSION}" -m "Release version ${NEW_VERSION}"
88
- git push origin "v${NEW_VERSION}"
89
-
90
- - name: Build package
91
- run: uv build
92
-
93
- - name: Create GitHub Release
94
- uses: actions/create-release@v1
95
- env:
96
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
97
- with:
98
- tag_name: v${{ env.NEW_VERSION }}
99
- release_name: Release v${{ env.NEW_VERSION }}
100
- draft: false
101
- prerelease: false
102
- body: |
103
- Release version ${{ env.NEW_VERSION }}
104
-
105
- ## How to install
106
- ```
107
- pip install namecheap-python==${{ env.NEW_VERSION }}
108
- ```
109
-
110
- - name: Publish package to PyPI
111
- uses: pypa/gh-action-pypi-publish@release/v1
112
- with:
113
- skip-existing: true