Python asynchronous YCLIENTS REST API wrapper on ujson and httpx
Project description
Asynchronous YCLIENTS API
Python Async YCLIENTS API WRAPPER with ujson and httpx packages:
-
PyPI page of project: https://pypi.org/project/asyyclients/
-
The code changed
httpx ⟵ requests
andujson ⟵ json
packages.ujson
andhttpx
faster thanjson
andrequests
-
An example of using library also implemented in the example.py.
-
This is an async implementation of this project. Original author is Nikita Shalashkov
Please note that sending requests to get customer data can take time, especially if your database is quite large, since YCLIENTS API can return only 200 results at once. Also if sending one request takes more than a few seconds, you may need to connect to another Internet network.
Installation:
pip install asyyclients
Usage:
Create API object
from asyyclients import AsyncYClientsAPI
TOKEN = "your token"
СID = 'your company id'
FID = 'form id'
async def main():
api = AsyncYClientsAPI(token=TOKEN, company_id=СID, form_id=FID)
Show debugging process
api.show_debugging()
Booking commands:
-
Get staff info
Returns list of staff for specific service and date
all_staff = await api.get_staff()
print(all_staff)
staff_id = all_staff['data'].get('id')
Response ...
{
"success": true,
"data": [
{
"id": "16",
"name": "Вася",
"bookable": true,
"specialization": "Фельдшер",
"position": {
"id": 1,
"title": "Администратор"
},
"show_rating": "1",
"rating": "3",
"votes_count": "1",
"avatar": "https://yclients.com/images/no-master.png",
"comments_count": "0",
"weight": "11",
"information": "<span></span>",
"seance_date": 1443139200,
"seances": []
},
{
"id": "32",
"name": "Петя",
"bookable": false,
"specialization": "Терапевт",
"position": [],
"show_rating": "1",
"rating": "4",
"votes_count": "1",
"avatar": "https://yclients.com/images/no-master.png",
"comments_count": "0",
"weight": "8",
"information": "<span></span>"
}
],
"meta": []
}
-
Get services info
Returns list of services for specific staff and date
services = await api.get_services(staff_id=staff_id)
print(services)
service_id = services['data']['services'].get('id')
Response ...
{
"success": true,
"data": {
"events": [],
"services": [
{
"id": 1896208,
"title": "Мытье волос",
"category_id": 1895571,
"price_min": 0,
"price_max": 0,
"discount": 0,
"comment": "",
"weight": 0,
"active": 0,
"sex": 0,
"image": "",
"prepaid": "forbidden",
"seance_length": 3600
},
{
"id": 1896303,
"title": "Окрашивание",
"category_id": 1895574,
"price_min": 0,
"price_max": 0,
"discount": 0,
"comment": "",
"weight": 0,
"active": 0,
"sex": 0,
"image": "",
"prepaid": "forbidden",
"seance_length": 3600
}
],
"category": [
{
"id": 1895571,
"title": "Уходы для волос",
"sex": 0,
"api_id": 0,
"weight": 60
},
{
"id": 1895574,
"title": "Окрашивание волос",
"sex": 0,
"api_id": 0,
"weight": 7
}
]
},
"meta": []
}
-
Get booking dates
Returns all available days for specific staff and service
booking_days = await api.get_available_days(staff_id=staff_id, service_id=service_id)
print(booking_days)
day = booking_days['data'].get('booking_dates') # or .get('booking_days')
Response ...
{
"success": true,
"data": {
"booking_days": {
"9": [
"4",
"5",
"8",
"9",
"12",
"13",
"16",
"17",
"20",
"21",
"24",
"25",
"28",
"29",
"30"
],
"10": [
"1",
"4",
"5",
"8",
"9",
"12",
"13",
"16",
"17",
"20",
"21",
"24",
"25"
]
},
"booking_dates": [
1441324800,
1441411200,
1441670400,
1441756800,
1442016000,
1442102400,
1442361600,
1442448000,
1442707200,
1442793600,
1443052800,
1443139200,
1443398400,
1443484800,
1443571200,
1443657600,
1443916800,
1444003200,
1444262400,
1444348800,
1444608000,
1444694400,
1444953600,
1445040000,
1445299200,
1445385600,
1445644800,
1445731200
],
"working_days": {
"9": [
"4",
"5",
"8",
"9",
"12",
"13",
"16",
"17",
"20",
"21",
"24",
"25",
"28",
"29",
"30"
],
"10": [
"1",
"4",
"5",
"8",
"9",
"12",
"13",
"16",
"17",
"20",
"21",
"24",
"25"
]
},
"working_dates": [
1441324800,
1441411200,
1441670400,
1441756800,
1442016000,
1442102400,
1442361600,
1442448000,
1442707200,
1442793600,
1443052800,
1443139200,
1443398400,
1443484800,
1443571200,
1443657600,
1443916800,
1444003200,
1444262400,
1444348800,
1444608000,
1444694400,
1444953600,
1445040000,
1445299200,
1445385600,
1445644800,
1445731200
]
},
"meta": []
}
-
Get booking times
Returns all available times slots on specific day staff and service
time_slots = await api.get_available_times(staff_id=staff_id, service_id=service_id, day=day)
print(time_slots)
date_time = time_slots['data'].get('time') # or .get('datetime')
Response ...
{
"success": true,
"data": [
{
"time": "12:00",
"seance_length": 3600,
"datetime": 1443513600
},
{
"time": "13:00",
"seance_length": 3600,
"datetime": 1443517200
},
{
"time": "14:00",
"seance_length": 3600,
"datetime": 1443520800
},
{
"time": "15:00",
"seance_length": 3600,
"datetime": 1443524400
},
{
"time": "16:00",
"seance_length": 3600,
"datetime": 1443528000
}
],
"meta": []
}
-
Book
booked, message = await api.book(booking_id=0,
fullname='my name',
phone='53425345',
email='myemail@email.com,
service_id=service_id,
date_time=date_time,
staff_id=staff_id,
comment='some comment')
Response ...
{
"success": true,
"data": [
{
"id": 1,
"record_id": 2820023,
"record_hash": "567df655304da9b98487769426d4e76e"
},
{
"id": 2,
"record_id": 2820024,
"record_hash": "34a45ddabdd446d5d33bdd27fbf855b2"
}
],
"meta": []
}
Payload(JSON) example ...
{
"phone": "79000000000",
"fullname": "ДИМА",
"email": "d@asyyclients.com",
"code": "38829",
"comment": "тестовая запись!",
"type": "mobile",
"notify_by_sms": 6,
"notify_by_email": 24,
"api_id": "777",
"appointments": [
{
"id": 1,
"services": [
331
],
"staff_id": 6544,
"datetime": 1443517200,
"custom_fields": {
"my_custom_field": 123,
"some_another_field": [
"first value",
"next value"
]
}
},
{
"id": 2,
"services": [
99055
],
"staff_id": 6544,
"datetime": 1443614400,
"custom_fields": {
"my_custom_field": 456,
"some_another_field": [
"next value",
"last value"
]
}
}
]
}
User commands:
-
Get USER TOKEN from the system
You can save this TOKEN (like BEARER TOKEN) and there is no need to update it every time
login = "example@gmail.com"
password = "password"
user_token = await api.get_user_token(login, password)
Response ...
{
"id": 123456,
"user_token": "wec23fh8cDfFV4432fc352456",
"name": "Иван Попов",
"phone": "79161001010",
"login": "79161001010",
"email": "test@test.com",
"avatar": "https://assets.yclients.com/general/0/01/123456789098765_12345678909876.png"
}
-
Update autorisation parameters of the API class with USER TOKEN
After USER TOKEN was obtained you need to include it in header of requests that you are sending
await api.update_user_token(user_token)
Response ...
{
"success": true,
"data": {
"user_token": "4de9d8cc108c0"
},
"meta": []
}
-
Shows USER permissions
await api.show_user_permissions()
Response ...
{
"success": true,
"data": {
"timetable": {
"timetable_access": true,
"master_id": 1000238,
"position_id": 0,
"last_days_count": 1000,
"schedule_edit_access": true,
"timetable_phones_access": true,
"timetable_transferring_record_access": true,
"timetable_statistics_access": true
},
"record_form": {
"record_form_access": true,
"record_form_client_access": true,
"records_autocomplete_access": true,
"create_records_access": true,
"edit_records_access": true,
"edit_records_attendance_access": true,
"records_services_cost_access": true,
"records_services_discount_access": true,
"record_edit_full_paid_access": true,
"delete_records_access": true,
"delete_customer_came_records_access": true,
"delete_paid_records_access": true,
"records_goods_access": true,
"records_goods_create_transaction_access": true,
"records_goods_create_last_days_count": -1,
"records_goods_edit_transaction_access": true,
"records_goods_edit_last_days_count": -1,
"records_goods_cost_access": true,
"records_goods_discount_access": true,
"records_finances_access": true,
"records_finances_last_days_count": -1,
"records_finances_pay_from_deposits_access": true,
"records_group_id_access": true,
"records_group_id": 134178
},
"finances": {
"finances_access": true,
"finances_accounts_ids": [],
"finances_transactions_access": true,
"finances_last_days_count": -1,
"finances_create_transactions_access": true,
"finances_create_last_days_count": -1,
"finances_edit_transactions_access": true,
"finances_edit_last_days_count": -1,
"finances_delete_transactions_access": true,
"finances_transactions_excel_access": true,
"finances_expenses_ids": [],
"finances_accounts_access": true,
"finances_accounts_banalce_access": true,
"finances_suppliers_read_access": true,
"finances_suppliers_create_access": true,
"finances_suppliers_update_access": true,
"finances_suppliers_delete_access": true,
"finances_suppliers_excel_access": true,
"finances_expenses_read_access": true,
"expenses_read_access": true,
"finances_expenses_create_access": true,
"expenses_create_access": true,
"finances_expenses_update_access": true,
"expenses_update_access": true,
"finances_expenses_delete_access": true,
"expenses_delete_access": true,
"finances_kkm_transactions_access": true,
"kkm_transactions_accounts_access": true,
"finances_kkm_settings_read_access": true,
"kkm_settings_reed_access": true,
"finances_kkm_settings_update_access": true,
"kkm_settings_update_access": true,
"finances_settings_invoicing_read_access": true,
"settings_invoicing_read_access": true,
"finances_settings_invoicing_update_access": true,
"settings_invoicing_update_access": true,
"finances_options_read_access": true,
"options_read_access": true,
"finances_options_update_access": true,
"options_update_access": true,
"finances_salary_schemes_access": true,
"finances_salary_calc_access": true,
"finances_salary_not_limitation_today_access": true,
"finances_payroll_calculation_create_access": true,
"finances_payroll_calculation_create_not_limitation_today_access": true,
"finances_salary_access_master_checkbox": true,
"finances_salary_access_master_id": 1000237,
"get_salary_access_master_id": 1000237,
"finances_salary_master_not_limitation_today_access": true,
"finances_payroll_calculation_create_by_master_access": true,
"calculation_create_by_master_not_limitation_today_access": true,
"finances_period_report_access": true,
"finances_period_report_excel_access": true,
"finances_year_report_access": true,
"finances_year_report_excel_access": true,
"finances_print_check_access": true,
"finances_z_report_access": true,
"finances_z_report_no_limit_today_access": true,
"finances_z_report_excel_access": true
},
"clients": {
"clients_access": true,
"client_phones_access": true,
"clients_phones_email_access": true,
"clients_card_phone_access": true,
"clients_delete_access": true,
"clients_excel_access": true,
"excel_access": true,
"client_comments_list_access": true,
"client_comments_add_access": true,
"client_comments_own_edit_access": true,
"client_comments_other_edit_access": true,
"client_files_list_access": true,
"client_files_upload_access": true,
"client_files_delete_access": true,
"clients_visit_master_id": 0,
"get_visit_master_id": 0
},
"dashboard": {
"dashboard_access": true,
"dash_access": true,
"dash_phones_access": true,
"dash_records_access": true,
"dash_records_last_days_count": -1,
"dash_records_excel_access": true,
"dash_records_phones_access": true,
"dash_message_access": true,
"dash_message_excel_access": true,
"dash_message_phones_access": true,
"dash_reviews_access": true,
"dash_reviews_delete_access": true,
"dashboard_calls_access": true,
"dashboard_calls_excel_access": true,
"dashboard_calls_phones_access": true
},
"notification": {
"notification": true,
"web_push": true,
"web_phone_push": true,
"notification_sms_ending_license": true,
"notification_sms_low_balance": true,
"notification_email_ending_license": true
},
"loyalty": {
"loyalty_access": true,
"has_loyalty_access": true,
"loyalty_cards_manual_transactions_access": true,
"has_loyalty_cards_manual_transactions_access": true,
"loyalty_certificate_and_abonement_manual_transactions_access": true
},
"storages": {
"storages_access": true,
"storages_ids": [],
"storages_transactions_access": true,
"storages_last_days_count": -1,
"storages_move_goods_access": true,
"storages_create_transactions_access": true,
"storages_create_last_days_count": -1,
"storages_create_transactions_buy_access": true,
"storages_create_transactions_sale_access": true,
"storages_edit_transactions_access": true,
"storages_edit_last_days_count": -1,
"storages_edit_transactions_buy_access": true,
"storages_edit_transactions_sale_access": true,
"storages_delete_transactions_access": true,
"storages_transactions_excel_access": true,
"storages_transactions_types": [],
"storages_inventory_access": true,
"storages_inventory_create_edit_access": true,
"storages_inventory_delete_access": true,
"storages_inventory_excel_access": true,
"storages_remnants_report_access": true,
"storages_remnants_report_excel_access": true,
"storages_sales_report_access": true,
"storages_sales_report_excel_access": true,
"storages_consumable_report_access": true,
"storages_consumable_report_excel_access": true,
"storages_write_off_report_access": true,
"storages_write_off_report_excel_access": true,
"storages_turnover_report_access": true,
"storages_turnover_report_excel_access": true,
"storages_goods_crud_access": true,
"storages_goods_create_access": true,
"storages_goods_update_access": true,
"storages_goods_title_edit_access": true,
"storages_goods_category_edit_access": true,
"storages_goods_selling_price_edit_access": true,
"storages_goods_cost_price_edit_access": true,
"storages_goods_units_edit_access": true,
"storages_goods_critical_balance_edit_access": true,
"storages_goods_masses_edit_access": true,
"storages_goods_comment_edit_access": true,
"storages_goods_archive_access": true,
"storages_goods_delete_access": true
},
"settings": {
"settings_access": true,
"settings_basis_access": true,
"settings_information_access": true,
"users_access": true,
"delete_users_access": true,
"create_users_access": true,
"edit_users_access": true,
"limited_users_access": false,
"settings_services_access": true,
"settings_services_create_access": true,
"services_edit": true,
"settings_services_edit_title_access": true,
"settings_services_relation_category_access": true,
"settings_services_edit_price_access": true,
"settings_services_edit_image_access": true,
"settings_services_edit_online_seance_date_time_access": true,
"settings_services_edit_online_pay_access": true,
"settings_services_edit_services_related_resource_access": true,
"settings_positions_read": true,
"settings_positions_create": true,
"settings_positions_delete": true,
"edit_master_service_and_duration": true,
"tech_card_edit": true,
"services_delete": true,
"settings_master_access": true,
"master_create": true,
"master_edit": true,
"master_delete": true,
"settings_master_dismiss_access": true,
"schedule_edit": true,
"settings_notifications_access": true,
"settings_email_notifications_access": true,
"settings_template_notifications_access": true,
"webhook_read_access": true
},
"other": {
"stat_access": true,
"billing_access": true,
"send_sms": true,
"auth_enable_check_ip": false,
"auth_list_allowed_ip": []
}
},
"meta": []
}
Client commands:
-
Get clients list
YCLIENTS API can't return all clients at once and returns in groups of maximum size of 200. Those groups are called pages and you can choose how many clients it will return
clients_data_list = await api.get_clients_data()
Response ...
{
"success": true,
"data": [
{
"name": "Петров",
"id": 2
},
{
"name": "Сидоров",
"id": 3
},
{
"name": "Иванов",
"id": 1
}
],
"meta": {
"total_count": 908
}
}
-
Parse clients data
df = api.parse_clients_data(clients_data_list)
-
Show ID, name and number of visits for all clients
print(df[['id', 'name', 'visits']])
-
Clients IDs list
all_clients_ids = list(df['id'])
Visits commands:
-
Show all visits for client with Client_ID
YCLIENTS API can't return all visits at once and returns in groups of maximum size of 200. Those groups are called pages and you can choose how many visits it will return
cid = 20419758
client_visits = await api.get_visits_for_client(cid)
print(f'Client {cid} visits')
print(f'{pd.DataFrame(client_visits)}')
Response ...
{
"success": true,
"data": [
{
"id": 2,
"company_id": 4564,
"staff_id": 9,
"services": [
{
"id": 1,
"title": "Наращивание волос",
"cost": 100,
"manual_cost": 100,
"cost_per_unit": 100,
"discount": 0,
"first_cost": 100,
"amount": 1
}
],
"goods_transactions": [],
"staff": {
"id": 9,
"name": "Оксана",
"specialization": "наращивание волос",
"position": {
"id": 1,
"title": "Администратор"
},
"avatar": "http://yclients.com/images/no-master-sm.png",
"avatar_big": "http://yclients.com/images/no-master.png",
"rating": 0,
"votes_count": 0
},
"date": 1547654400,
"datetime": 1547622000,
"create_date": "2019-01-16T20:35:11+0900",
"comment": "не записывать",
"online": false,
"visit_attendance": 0,
"attendance": 0,
"confirmed": 1,
"seance_length": 3600,
"length": 3600,
"sms_before": 0,
"sms_now": 0,
"sms_now_text": "",
"email_now": 0,
"notified": 0,
"master_request": 0,
"api_id": "",
"from_url": "",
"review_requested": 0,
"visit_id": "8262996",
"created_user_id": 1073232,
"deleted": false,
"paid_full": 0,
"prepaid": false,
"prepaid_confirmed": false,
"last_change_date": "2019-01-16T20:35:15+0900",
"custom_color": "",
"custom_font_color": "",
"record_labels": [],
"activity_id": 0,
"custom_fields": [],
"documents": [
{
"id": 8172893,
"type_id": 7,
"storage_id": 0,
"user_id": 746310,
"company_id": 4564,
"number": 4163,
"comment": "",
"date_created": 1530615600,
"category_id": 0,
"visit_id": 3,
"record_id": 2,
"type_title": "Визит"
}
],
"sms_remain_hours": 5,
"email_remain_hours": 1,
"bookform_id": 0,
"record_from": "",
"is_mobile": 0,
"is_sale_bill_printed": false,
"consumables": [],
"finance_transactions": []
},
{
"id": 9,
"company_id": 4564,
"staff_id": 49,
"services": [],
"goods_transactions": [],
"staff": {
"id": 49,
"name": "Сергей",
"specialization": "стилист",
"position": {
"id": 1,
"title": "Администратор"
},
"avatar": "http://yclients.com/images/no-master-sm.png",
"avatar_big": "http://yclients.com/images/no-master.png",
"rating": 0,
"votes_count": 0
},
"date": 1547654400,
"datetime": 1547622000,
"create_date": "2019-01-16T20:35:11+0900",
"comment": "",
"online": true,
"visit_attendance": 1,
"attendance": 1,
"confirmed": 1,
"seance_length": 10800,
"length": 10800,
"sms_before": 0,
"sms_now": 0,
"sms_now_text": "",
"email_now": 0,
"notified": 0,
"master_request": 1,
"api_id": "",
"from_url": "",
"review_requested": 0,
"visit_id": "8262996",
"created_user_id": 1073232,
"deleted": false,
"paid_full": 0,
"prepaid": false,
"prepaid_confirmed": false,
"last_change_date": "2017-01-09T20:45:30+0900",
"custom_color": "f44336",
"custom_font_color": "#ffffff",
"record_labels": [
{
"id": "67345",
"title": "Сотрудник не важен",
"color": "#009800",
"icon": "unlock",
"font_color": "#ffffff"
},
{
"id": "104474",
"title": "важная категория",
"color": "#3b2c54",
"icon": "odnoklassniki",
"font_color": "#ffffff"
}
],
"activity_id": 0,
"custom_fields": [],
"documents": [
{
"id": 8172893,
"type_id": 7,
"storage_id": 0,
"user_id": 746310,
"company_id": 4564,
"number": 4163,
"comment": "",
"date_created": 1530615600,
"category_id": 0,
"visit_id": 3,
"record_id": 2,
"type_title": "Визит"
}
],
"sms_remain_hours": 5,
"email_remain_hours": 1,
"bookform_id": 0,
"record_from": "",
"is_mobile": 0,
"is_sale_bill_printed": false,
"consumables": [],
"finance_transactions": []
}
],
"meta": {
"page": 1,
"total_count": 10
}
}
-
Show all visits for all clients
all_clients_visits = await api.get_visits_data_for_clients_list(all_clients_ids)
for cid in all_clients_visits.keys():
print(f'Client {cid} visits')
print(f'{pd.DataFrame(all_clients_visits[cid])}')
-
Show all attended visits for client with Client_ID
Attendance explanation from Yclient API:
2 - The user has confirmed the entry,
1 - The user has arrived, the services are provided,
0 - the user is waiting,
-1 - the user did not come for a visit
cid = 20419758
client_visits = await api.get_attended_visits_for_client(cid)
print(f'Client {cid} attended visits')
print(f'{pd.DataFrame(client_visits)}')
-
Show attended visits information for clients:
df = await api.get_attended_visits_dates_information(all_clients_ids)
print(f'Attended visits dataframe: {df}')
-
Show attended visits information for clients with at least one visit:
print(f"Attended visits ndataframe with no gaps {df[df['visits_number']>0]}")
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file asyyclients-0.0.1.1.tar.gz
.
File metadata
- Download URL: asyyclients-0.0.1.1.tar.gz
- Upload date:
- Size: 18.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 255db0ec16729ab8ea2f87806444faa1e2cc9745ece0587d6ed22e298174a33e |
|
MD5 | 107e0c242af02f1f90a41de7c6130cdc |
|
BLAKE2b-256 | 52018ae30e3f0edd74297c9513c9b45ba645ff3e2787c2187569d608e4402120 |
File details
Details for the file asyyclients-0.0.1.1-py3-none-any.whl
.
File metadata
- Download URL: asyyclients-0.0.1.1-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.2 CPython/3.11.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 06714cd8c3d48fcf89d1f7608ad8988f817ada93fa855dbb4fbaa7cd321c1155 |
|
MD5 | 969a69f97a439426229ff8901482e7d4 |
|
BLAKE2b-256 | 03c21b9e52bf51bc878f988e5fad4662bd8215d59565c62507426124e774a263 |