Skip to content

Commit 6a06578

Browse files
committed
Merge branch 'development' into github-actions-and-readme
2 parents 0c01777 + ff833dd commit 6a06578

File tree

6 files changed

+184
-10
lines changed

6 files changed

+184
-10
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ coverage.xml
4949

5050
# Jupyter Notebook
5151
.ipynb_checkpoints
52-
*.ipynb
52+
5353

5454
# Distribution / packaging
5555
.Python

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ Thank you for your interest in contributing to the Extend API Client! This docum
77
1. Fork the repository
88
2. Clone your fork:
99
```bash
10-
git clone https://github.com/your-username/extend-api-client.git
11-
cd extend-api-client
10+
git clone https://github.com/your-username/extend-python.git
11+
cd extend-python
1212
```
1313
3. Create a virtual environment and activate it:
1414
```bash

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ and more.
2323
### From PyPI
2424

2525
```bash
26-
pip install extend
26+
pip install extend-python
2727
```
2828

2929
### From Source

extend/client.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import httpx
55

6-
from .config import config
6+
from .config import API_HOST, API_VERSION
77

88

99
class APIClient:
@@ -19,7 +19,6 @@ class APIClient:
1919
cards = await client.get_virtual_cards()
2020
```
2121
"""
22-
BASE_URL = "https://apiv2-stage.paywithextend.com"
2322

2423
_shared_instance: Optional["APIClient"] = None
2524

@@ -34,7 +33,7 @@ def __init__(self, api_key: str, api_secret: str):
3433
self.headers = {
3534
"x-extend-api-key": api_key,
3635
"Authorization": f"Basic {auth_value}",
37-
"Accept": config.API_VERSION
36+
"Accept": API_VERSION
3837
}
3938

4039
@classmethod
@@ -126,4 +125,4 @@ async def put(self, url: str, data: Dict) -> Any:
126125
return response.json()
127126

128127
def build_full_url(self, url: Optional[str]):
129-
return f"{self.BASE_URL}{url or ''}"
128+
return f"https://{API_HOST}{url or ''}"

extend/config/config.py

Lines changed: 0 additions & 2 deletions
This file was deleted.

notebooks/api_testing.ipynb

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Extend API Testing\n",
8+
"## This notebook is for testing the ExtendAPI client manually."
9+
]
10+
},
11+
{
12+
"cell_type": "code",
13+
"execution_count": 1,
14+
"metadata": {},
15+
"outputs": [],
16+
"source": [
17+
"import asyncio\n",
18+
"import os\n",
19+
"from datetime import datetime, timedelta\n",
20+
"from extend import ExtendClient"
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": 2,
26+
"metadata": {},
27+
"outputs": [],
28+
"source": [
29+
"# Initialize the client\n",
30+
"api_key = os.getenv(\"EXTEND_API_KEY\")\n",
31+
"api_secret = os.getenv(\"EXTEND_API_SECRET\")\n",
32+
"client = ExtendClient(api_key, api_secret)"
33+
]
34+
},
35+
{
36+
"cell_type": "code",
37+
"execution_count": null,
38+
"metadata": {},
39+
"outputs": [],
40+
"source": [
41+
"print(api_key)\n",
42+
"print(api_secret)\n"
43+
]
44+
},
45+
{
46+
"cell_type": "code",
47+
"execution_count": null,
48+
"metadata": {},
49+
"outputs": [],
50+
"source": [
51+
"async def test_virtual_cards():\n",
52+
" cards = await client.virtual_cards.get_virtual_cards()\n",
53+
" print(\"Virtual Cards:\")\n",
54+
" print(cards)\n",
55+
" return cards\n",
56+
"\n",
57+
"await test_virtual_cards()"
58+
]
59+
},
60+
{
61+
"cell_type": "code",
62+
"execution_count": null,
63+
"metadata": {},
64+
"outputs": [],
65+
"source": [
66+
"### Test Transactions API\n",
67+
"\n",
68+
"async def test_transactions():\n",
69+
" txns = await client.transactions.get_transactions()\n",
70+
" print(\"Transactions:\")\n",
71+
" print(txns)\n",
72+
" return txns\n",
73+
"\n",
74+
"await test_transactions()"
75+
]
76+
},
77+
{
78+
"cell_type": "code",
79+
"execution_count": null,
80+
"metadata": {},
81+
"outputs": [],
82+
"source": [
83+
"async def test_virtual_card_lifecycle():\n",
84+
" \"\"\"Test the full lifecycle of a virtual card\"\"\"\n",
85+
" # Get the first available credit card\n",
86+
" credit_cards = await client.credit_cards.get_credit_cards()\n",
87+
" if not credit_cards.get(\"creditCards\"):\n",
88+
" print(\"No credit cards available for testing\")\n",
89+
" return\n",
90+
" \n",
91+
" credit_card = credit_cards[\"creditCards\"][0]\n",
92+
" print(f\"Using credit card: {credit_card['id']}\")\n",
93+
" \n",
94+
" # Get test recipient and cardholder from environment\n",
95+
" recipient = os.getenv(\"EXTEND_TEST_RECIPIENT\")\n",
96+
" cardholder = os.getenv(\"EXTEND_TEST_CARDHOLDER\")\n",
97+
" \n",
98+
" # Calculate valid_to date (3 months from today)\n",
99+
" valid_to = (datetime.now() + timedelta(days=90)).strftime(\"%Y-%m-%dT23:59:59.999Z\")\n",
100+
" \n",
101+
" # Create a virtual card\n",
102+
" print(\"\\nCreating virtual card...\")\n",
103+
" response = await client.virtual_cards.create_virtual_card(\n",
104+
" credit_card_id=credit_card[\"id\"],\n",
105+
" display_name=\"Notebook Test Card\",\n",
106+
" balance_cents=5000,\n",
107+
" notes=\"Created by notebook test\",\n",
108+
" recurs=False,\n",
109+
" recipient=recipient,\n",
110+
" cardholder=cardholder,\n",
111+
" valid_to=valid_to\n",
112+
" )\n",
113+
" \n",
114+
" card = response[\"virtualCard\"]\n",
115+
" print(f\"Created card: {card['id']}\")\n",
116+
" print(f\"Status: {card['status']}\")\n",
117+
" print(f\"Balance: ${card['balanceCents']/100:.2f}\")\n",
118+
" \n",
119+
" # Get the card details\n",
120+
" print(\"\\nRetrieving card details...\")\n",
121+
" get_response = await client.virtual_cards.get_virtual_card_detail(card[\"id\"])\n",
122+
" print(f\"Retrieved card: {get_response['virtualCard']['id']}\")\n",
123+
" \n",
124+
" # Update the card\n",
125+
" print(\"\\nUpdating card...\")\n",
126+
" update_response = await client.virtual_cards.update_virtual_card(\n",
127+
" card_id=card[\"id\"],\n",
128+
" display_name=\"Updated Notebook Card\",\n",
129+
" notes=\"Updated by notebook test\",\n",
130+
" balance_cents=6000\n",
131+
" )\n",
132+
" print(f\"Updated card: {update_response['virtualCard']['id']}\")\n",
133+
" print(f\"New balance: ${update_response['virtualCard']['balanceCents']/100:.2f}\")\n",
134+
" \n",
135+
" # Cancel the card\n",
136+
" print(\"\\nCanceling card...\")\n",
137+
" cancel_response = await client.virtual_cards.cancel_virtual_card(card[\"id\"])\n",
138+
" print(f\"Card status after cancel: {cancel_response['virtualCard']['status']}\")\n",
139+
" \n",
140+
" # Close the card (cleanup)\n",
141+
" print(\"\\nClosing card...\")\n",
142+
" close_response = await client.virtual_cards.close_virtual_card(card[\"id\"])\n",
143+
" print(f\"Final card status: {close_response['virtualCard']['status']}\")\n",
144+
"\n",
145+
"await test_virtual_card_lifecycle()"
146+
]
147+
},
148+
{
149+
"cell_type": "code",
150+
"execution_count": null,
151+
"metadata": {},
152+
"outputs": [],
153+
"source": []
154+
}
155+
],
156+
"metadata": {
157+
"kernelspec": {
158+
"display_name": "venv",
159+
"language": "python",
160+
"name": "python3"
161+
},
162+
"language_info": {
163+
"codemirror_mode": {
164+
"name": "ipython",
165+
"version": 3
166+
},
167+
"file_extension": ".py",
168+
"mimetype": "text/x-python",
169+
"name": "python",
170+
"nbconvert_exporter": "python",
171+
"pygments_lexer": "ipython3",
172+
"version": "3.13.1"
173+
}
174+
},
175+
"nbformat": 4,
176+
"nbformat_minor": 2
177+
}

0 commit comments

Comments
 (0)