{"id":16359799,"url":"https://github.com/alxwrd/specsavers","last_synced_at":"2025-07-19T03:03:44.019Z","repository":{"id":43363698,"uuid":"129158555","full_name":"alxwrd/specsavers","owner":"alxwrd","description":":eyeglasses: A Python wrapper around the Specsavers appointment booking API","archived":false,"fork":false,"pushed_at":"2022-12-08T01:09:57.000Z","size":139,"stargazers_count":3,"open_issues_count":2,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-18T00:47:30.991Z","etag":null,"topics":["api-client","client","python","reverse-engineering","specsavers","testing"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alxwrd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-11T21:53:06.000Z","updated_at":"2021-12-13T19:53:48.000Z","dependencies_parsed_at":"2023-01-24T05:46:15.714Z","dependency_job_id":null,"html_url":"https://github.com/alxwrd/specsavers","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alxwrd/specsavers","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alxwrd%2Fspecsavers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alxwrd%2Fspecsavers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alxwrd%2Fspecsavers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alxwrd%2Fspecsavers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alxwrd","download_url":"https://codeload.github.com/alxwrd/specsavers/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alxwrd%2Fspecsavers/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265878859,"owners_count":23843026,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","client","python","reverse-engineering","specsavers","testing"],"created_at":"2024-10-11T02:09:39.960Z","updated_at":"2025-07-19T03:03:43.726Z","avatar_url":"https://github.com/alxwrd.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Specsavers :eyeglasses:\n_A Python wrapper around the Specsavers appointment booking API_\n\n[![Build Status](https://travis-ci.org/alxwrd/specsavers.svg?branch=master)](https://travis-ci.org/alxwrd/specsavers)\n[![Downloads](https://img.shields.io/badge/dynamic/json.svg?url=https://pypistats.org/api/packages/specsavers/recent?mirrors=false\u0026label=downloads\u0026query=$.data.last_month\u0026suffix=/month)](https://pypistats.org/packages/specsavers)\n\n\u003e **IMPORTANT**: This project is NOT affiliated with Specsavers. Specsavers, nor this\nlibrary, should not be held responsible for any misinformation gained regarding\nappointment information during the use of this library. \n\n\u003e **NOTE**: Whilst this is a toy project, the endpoints it connects to are very real.\nPlease be responsible if you use this library: don't spam requests, and don't spam bookings.\n\n## Example\n\n```python\n\u003e\u003e\u003e import specsavers\n\n# Find local stores\n\u003e\u003e\u003e stores = specsavers.locate(latitude=51.507879, longitude=0.087732)\n\n# Closest / first store\n\u003e\u003e\u003e stores[0]\n\u003cStore name='londonwall'\u003e\n\n# Store by name\n\u003e\u003e\u003e stores[\"strand\"]\n\u003cStore name='strand'\u003e\n\n# Lookup directly by name\n\u003e\u003e\u003eother_store = specsavers.find(\"nottingham\")\n\n\u003e\u003e\u003e other_store.appointments() # Implies today\n[\u003cAppointment date='Jan 9', time='11:45'\u003e, \u003cAppointment date='Jan 9', time='15:00'\u003e]\n\n\u003e\u003e\u003e other_store.appointments(\"tomorrow\")[0]\n\u003cAppointment date='Jan 10', time='09:20'\u003e\n```\n\n## What?\n\nThe Specsavers booking site is powered by a RESTful API. This library\naims to provide a simple, easy, and Pythonic interface to that service.\n\n\n## Why?\n\nI recently needed an eye test, and Specsavers has the ability to book online.\nI needed an appointment fairly last minute (two days before), but fortunately,\nthere was _one_ slot left. I proceeded to make the appointment, but in the\ntime it had taken to fill in my details: it had already been taken.\n\nI wanted to watch for new appointments to pop up, but frustratingly, every\ntime I refreshed the page, I was taken back to the first step of the process.\n\nSo I did some digging in the browsers dev tools. To my delight, I realised\nthat the Specsavers booking site is powered by a RESTful API. I wrote some\ncode to fetch appointments for the desired date; so I could watch to see if\nanother appointment became available.\n\nIn the end, I got an appointment for the day I wanted. I didn't want to let\nmy learnings about the API go to waste though, so I created this package!\n\n\n## Using\n\n### Installing\n\n_Python 3.6+ only_\n\n```shell\npip3 install specsavers\n```\n\n\n## Contributing\n\nIf you find any problems, you should open an\n[issue](https://github.com/alxwrd/specsavers/issues).\n\nIf you can fix an issue you've found, or another issue, you should open\na [pull request](https://github.com/alxwrd/specsavers/pulls).\n\n1. Fork this repository on GitHub to start making your changes to the master\nbranch (or branch off of it).\n2. Write a test which shows that the bug was fixed or that the feature works as expected.\n3. Send a pull request!\n\n### Development setup\n\nThis project uses [poetry](https://python-poetry.org/docs/) to manage\ndependencies, pytest [pytest](https://docs.pytest.org/en/latest/)\nfor tests, and [pycodestyle](https://github.com/PyCQA/pycodestyle) (formerly pep8)\nfor style checks.\n\n```bash\n# https://python-poetry.org/docs/#installation\n# (If you haven't already)\ncurl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python\n\ngit clone https://github.com/\u003cyourname\u003e/specsavers.git  # Clone the repo from your fork\ncd specsavers\npoetry install # Install all dependencies\npoetry shell  # Start the new virtual enviroment\n\n# Make changes\n\npytest tests  # Run tests\npycodestyle specsavers/ tests/  # Check style\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falxwrd%2Fspecsavers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falxwrd%2Fspecsavers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falxwrd%2Fspecsavers/lists"}