Skip to content

Commit b091895

Browse files
authored
Merge pull request #1 from samdoghor/fix-client-args
fix: late catch of missing client args
2 parents f2f9cf8 + 648b3e4 commit b091895

3 files changed

Lines changed: 276 additions & 0 deletions

File tree

DEVELOPMENT.md

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
# python-termii — Local Setup Guide
2+
3+
A clean and lightweight Python SDK for [Termii](https://termii.com) — send SMS, OTPs, and voice messages effortlessly.
4+
5+
---
6+
7+
## Prerequisites
8+
9+
Before anything else, you'll need:
10+
11+
- A [Termii account](https://accounts.termii.com/#/register) (free to sign up)
12+
- Your **Termii API Key** — found in your dashboard under **Settings → API Keys**
13+
- Git installed on your machine
14+
- Python 3.8 or higher
15+
16+
---
17+
18+
## Step 1 — Install Python
19+
20+
### Windows
21+
22+
1. Go to [https://www.python.org/downloads/](https://www.python.org/downloads/)
23+
2. Download the latest Python 3.x installer
24+
3. Run the installer — **check the box that says "Add Python to PATH"** before clicking Install
25+
4. Verify the installation:
26+
27+
```bash
28+
python --version
29+
```
30+
31+
### macOS
32+
33+
macOS ships with Python 2 (don't touch it). Install Python 3 via Homebrew:
34+
35+
```bash
36+
# Install Homebrew if you don't have it
37+
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
38+
39+
# Install Python
40+
brew install python
41+
42+
# Verify
43+
python3 --version
44+
```
45+
46+
### Linux (Ubuntu/Debian)
47+
48+
```bash
49+
sudo apt update
50+
sudo apt install python3 python3-pip python3-venv -y
51+
52+
# Verify
53+
python3 --version
54+
```
55+
56+
---
57+
58+
## Step 2 — Clone the Repository
59+
60+
```bash
61+
git clone https://github.com/samdoghor/python-termii.git
62+
cd python-termii
63+
```
64+
65+
---
66+
67+
## Step 3 — Create a Virtual Environment
68+
69+
A virtual environment keeps your project dependencies isolated — no global pollution, no version conflicts.
70+
71+
### Windows
72+
73+
```bash
74+
python -m venv venv
75+
source venv/Scripts/activate
76+
```
77+
78+
### macOS / Linux
79+
80+
```bash
81+
python3 -m venv venv
82+
source venv/bin/activate
83+
```
84+
85+
You'll know it's active when your terminal prompt shows `(venv)` at the front. To deactivate later, just run
86+
`deactivate`.
87+
88+
---
89+
90+
## Step 4 — Install Dependencies
91+
92+
With the virtual environment active, install the project and its dependencies:
93+
94+
The project has a `requirements.txt`, run this:
95+
96+
```bash
97+
pip install -r requirements.txt
98+
```
99+
100+
If you want to install the package itself in editable mode (so you can import it in your scripts), run:
101+
102+
```bash
103+
pip install -e .
104+
```
105+
106+
The `-e` flag installs it in **editable mode**, meaning changes you make to the source code are reflected immediately
107+
without reinstalling.
108+
109+
---
110+
111+
## Step 5 — Set Up Your API Key
112+
113+
Never hardcode your API key in source files. Use an environment variable instead.
114+
115+
### Use a `.env` file (recommended)
116+
117+
Create a `.env` file in the project root:
118+
119+
```
120+
TERMII_API_KEY=your_api_key_here
121+
TERMII_BASE_URL=your_base_url_here
122+
```
123+
124+
> ⚠️ The `.gitignore` already excludes `.env` files. Do **not** commit your API key to version control.
125+
126+
---
127+
128+
## Step 6 — Run the (Ignoring tests for now)
129+
130+
Ignore this as test case are not yet pushed to the repo.
131+
132+
The project includes a `test/` directory and a `test_data.py` file. Run the tests to confirm everything is wired up
133+
correctly:
134+
135+
```bash
136+
python -m pytest test/
137+
```
138+
139+
Or run the test data file directly:
140+
141+
```bash
142+
python test_data.py
143+
```
144+
145+
If `pytest` isn't installed:
146+
147+
```bash
148+
pip install pytest
149+
python -m pytest test/
150+
```
151+
152+
---
153+
154+
## Step 7 — Using the SDK
155+
156+
Here's a quick example of what using `python-termii` looks like in practice:
157+
158+
create a file named `example.py` in the project root with the following content:
159+
160+
```python
161+
import os
162+
from termii_py import Termii # adjust import based on actual module structure
163+
164+
# Initialize with your API key
165+
client = Termii(api_key=os.environ.get("TERMII_API_KEY"), base_url=os.environ.get("TERMII_BASE_URL"))
166+
167+
# Send an SMS
168+
response = client.message.send_message(
169+
to="2348012345678", # recipient phone number (international format)
170+
from_="YourSenderID", # approved sender ID from your Termii dashboard
171+
message="Hello from python-termii!",
172+
type="plain",
173+
channel="generic"
174+
)
175+
176+
print(response)
177+
```
178+
179+
```bash
180+
python example.py
181+
```
182+
183+
there is an already a `test_data.py` file in the repo that you can use as a reference for how to call the SDK methods.
184+
185+
```bash
186+
python test_data.py
187+
```
188+
189+
> **Note:** Phone numbers must be in international format **without** the `+` sign (e.g., `2348012345678` for a Nigerian
190+
> number).
191+
192+
---
193+
194+
## Project Structure
195+
196+
```
197+
python-termii/
198+
├── termii_py/ # Core SDK source code
199+
├── test/ # Test files
200+
├── test_data.py # Sample test data / quick test runner
201+
├── pyproject.toml # Project metadata and build config
202+
├── .gitignore
203+
└── LICENSE
204+
```
205+
206+
---
207+
208+
## Common Issues
209+
210+
**`ModuleNotFoundError: No module named 'termii_py'`**
211+
Make sure you ran `pip install -e .` from the project root with your virtual environment active.
212+
213+
**`python: command not found` (macOS/Linux)**
214+
Use `python3` instead of `python`. You can alias it: `alias python=python3`
215+
216+
**API key not being read**
217+
Double-check that you exported the environment variable in the **same terminal session** you're running the script from.
218+
Each new terminal session starts fresh.
219+
220+
**Invalid sender ID**
221+
Sender IDs must be pre-registered and approved in your Termii dashboard before use.
222+
223+
---
224+
225+
## Resources
226+
227+
- [Termii API Documentation](https://developers.termii.com)
228+
- [Termii Dashboard](https://accounts.termii.com)
229+
- [Repository](https://github.com/samdoghor/python-termii)
230+
- [MIT License](./LICENSE)
231+
232+
---
233+
234+
*Built by [Samuel Doghor](https://github.com/samdoghor)*

termii_py/client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ class TermiiClient:
4242
def __init__(self, api_key: str = None, base_url: str = None):
4343
self.api_key = api_key or config.TERMII_API_KEY
4444
self.base_url = base_url or config.TERMII_BASE_URL
45+
46+
if not self.api_key:
47+
raise ValueError("api_key is required. Pass it directly or set TERMII_API_KEY in your environment.")
48+
if not self.base_url:
49+
raise ValueError("base_url is required. Pass it directly or set TERMII_BASE_URL in your environment.")
50+
4551
self.http = RequestHandler(self.api_key, self.base_url)
4652
self.sender_id = SenderIDService(self.http)
4753
self.message = MessageService(self.http)

test_data.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from termii_py import TermiiClient
2+
3+
client = TermiiClient() # when you initialize the client without parameters, it will automatically fetch the API key and base URL from the environment variables if they are set as TERMII_API_KEY and TERMII_BASE_URL respectively.
4+
# client = TermiiClient(api_key="your_api_key", base_url="your_base_url") # you can also initialize the client with your API key and base URL
5+
6+
# message_service = client.phonebook.fetch_phonebooks()
7+
8+
message_service = client.message.send_message(
9+
sent_to="2348031390921",
10+
sent_from="CompanyName",
11+
message="This is a test message",
12+
channel="generic",
13+
type="plain"
14+
15+
)
16+
17+
print(message_service.status_code)
18+
print(message_service.status)
19+
print(message_service.message)
20+
21+
# message_service = client.template.send_message(
22+
# sent_to="2348031390921",
23+
# device_id="f3f4f7b0-52d8-40bc-91fc-120da11ff936",
24+
# template_id="1493-csdn3-ns34w-sd3434-dfdf",
25+
# data={
26+
# "product_name": "Termii",
27+
# "otp": 120435,
28+
# "expiry_time": "10 minutes"
29+
# },
30+
# caption="We are excited to have you on board!",
31+
# url="https://example.com/welcome-image.jpg"
32+
# )
33+
#
34+
# print(message_service.status_code)
35+
# print(message_service.status)
36+
# print(message_service.message)

0 commit comments

Comments
 (0)