Skip to content

Commit d45ea55

Browse files
author
Ilya Nevolin
committed
initial code
0 parents  commit d45ea55

File tree

8 files changed

+189
-0
lines changed

8 files changed

+189
-0
lines changed

.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# user config
2+
config.py
3+
4+
# Byte-compiled / optimized / DLL files
5+
__pycache__/
6+
*.py[cod]
7+
*$py.class
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
share/python-wheels/
24+
*.egg-info/
25+
.installed.cfg
26+
*.egg
27+
MANIFEST

LICENSE.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
MIT

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Spurwing API Python Library

setup.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from setuptools import setup
2+
3+
with open("README.md", "r", encoding="utf-8") as fh:
4+
long_description = fh.read()
5+
6+
setup(
7+
name='Spurwing',
8+
version='1.0.0',
9+
author='Ilya Nevolin',
10+
author_email='ilya@spurwing.io',
11+
packages=['spurwing', 'spurwing.tests'],
12+
url='',
13+
license='MIT License (MIT)',
14+
description='Python Library for Spurwing API',
15+
long_description=long_description,
16+
long_description_content_type="text/markdown",
17+
install_requires=[
18+
"requests",
19+
],
20+
)

spurwing/Client.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import requests
2+
3+
API_URL = 'https://api.spurwing.io/api/v2/'
4+
5+
def get_appointment_types(provider_id, clients_can_book):
6+
return HTTP('GET', 'appointment_types.json',
7+
params = {
8+
'provider_id':provider_id,
9+
'clients_can_book': clients_can_book })
10+
11+
def get_days_available(provider_id, appointment_type_id, date_from_month, timezone, org_level):
12+
return HTTP('GET', 'bookings/days_available.json',
13+
params={
14+
'provider_id':provider_id,
15+
'appointment_type_id': appointment_type_id,
16+
'date_from_month': date_from_month,
17+
'timezone': timezone,
18+
'org_level': org_level })
19+
20+
def get_slots_available(provider_id, appointment_type_id, start_date, end_date, org_level):
21+
return HTTP('GET', 'bookings/slots_available.json',
22+
params = {
23+
'provider_id':provider_id,
24+
'appointment_type_id': appointment_type_id,
25+
'start_date': start_date,
26+
'end_date': end_date,
27+
'org_level': org_level })
28+
29+
def complete_booking(provider_id, appointment_type_id, date, timezone, first_name, last_name, email, phone_number, contact_type):
30+
return HTTP('POST', 'bookings/complete_booking.json',
31+
data={
32+
'provider_id':provider_id,
33+
'appointment_type_id': appointment_type_id,
34+
'date': date,
35+
'timezone': timezone,
36+
'first_name': first_name,
37+
'last_name': last_name,
38+
'email': email,
39+
'phone_number': phone_number,
40+
'contact_type': contact_type })
41+
42+
def list_appointments(authorization, page_size, offset, provider_id):
43+
return HTTP('GET', 'appointments',
44+
params={
45+
'page_size':page_size,
46+
'offset': offset,
47+
'provider_id': provider_id },
48+
headers={ 'authorization': 'Bearer ' + authorization })
49+
50+
def delete_appointment(appointment_id, authorization):
51+
return HTTP('DELETE', 'appointments/' + appointment_id, headers={ 'authorization': 'Bearer ' + authorization })
52+
53+
54+
def HTTP(method, endpoint, params=None, data=None, headers=None):
55+
url = API_URL + endpoint
56+
57+
if (method == 'GET'): resp = requests.get(url, params=params, headers=headers)
58+
elif method == 'POST': resp = requests.post(url, params=params, headers=headers, data=data,)
59+
elif method == 'PUT': resp = requests.put(url, params=params, headers=headers, data=data,)
60+
elif method == 'DELETE': resp = requests.delete(url, params=params, headers=headers)
61+
62+
if resp.status_code == 200: return resp.json()
63+
else: raise Exception({'status':resp.status, 'text':resp.statusText, 'url':url})

spurwing/__init__.py

Whitespace-only changes.

spurwing/config.sample.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pid = 'your_provider_id'
2+
key = 'your_api_key'

spurwing/test_api.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
from config import KEY, PID
2+
import Client as sp
3+
4+
def runner(func):
5+
def wrapper():
6+
try:
7+
print(func.__name__, 'STARTED')
8+
func()
9+
print('\n' + func.__name__, 'PASSED')
10+
except Exception as ex:
11+
print('\n' + func.__name__, 'FAILED')
12+
raise ex
13+
return wrapper
14+
15+
@runner
16+
def test_1():
17+
tz = "Europe/Brussels";
18+
19+
A = sp.get_appointment_types(PID, True)
20+
log(A)
21+
assert len(A) == 3
22+
23+
B = sp.get_days_available(PID, A[0]['id'], dateNow(), tz, False)
24+
log(B)
25+
assert len(B['days_available']) >= 1
26+
27+
C = sp.get_slots_available(PID, A[0]['id'], dateNow(), dateTomorrow(), False)
28+
log(C)
29+
assert len(C['slots_available']) >= 10
30+
slot = C['slots_available'][5]['date']
31+
32+
D = sp.complete_booking(PID, A[0]['id'], slot, tz, 'Ilya', 'Nevo', 'ilya2@nevolin.be', '111-111-7777', 'My Contact Type')
33+
log(D)
34+
assert 'appointment' in D
35+
36+
E = sp.list_appointments(KEY, 1000, 0, PID)
37+
log(E)
38+
assert 'data' in E
39+
assert 'appointments' in E['data']
40+
assert E['data']['appointmentsCount'] >= 1
41+
42+
apid = D['appointment']['id']
43+
F = sp.delete_appointment(apid, KEY)
44+
log(F)
45+
assert 'data' in F
46+
assert 'appointment' in F['data']
47+
assert F['data']['appointment']['id'] == apid
48+
assert len(F['errors']) == 0
49+
50+
51+
@runner
52+
def test_2():
53+
A = sp.list_appointments(KEY, 1000, 0, PID)
54+
log(A)
55+
assert len(A) == 3
56+
assert 'data' in A
57+
assert 'appointments' in A['data']
58+
59+
60+
from datetime import date, timedelta
61+
def dateNow():
62+
return date.today().strftime("%Y/%m/%d")
63+
def dateTomorrow():
64+
dt = date.today() + timedelta(days=1)
65+
return dt.strftime("%Y/%m/%d")
66+
67+
def log(obj):
68+
# print(obj)
69+
print('.', end='')
70+
71+
if __name__ == "__main__":
72+
lc = dict.fromkeys(vars())
73+
for item in lc:
74+
if 'test_' in item:
75+
vars()[item]()

0 commit comments

Comments
 (0)