firstcash.py 1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. firstcash_py-1.0/LICENSE +21 -0
  2. firstcash_py-1.0/PKG-INFO +120 -0
  3. firstcash_py-1.0/README.md +91 -0
  4. firstcash_py-1.0/firstcash/__init__.py +37 -0
  5. firstcash_py-1.0/firstcash/_utils.py +123 -0
  6. firstcash_py-1.0/firstcash/api_client.py +841 -0
  7. firstcash_py-1.0/firstcash/exceptions.py +97 -0
  8. firstcash_py-1.0/firstcash/py.typed +0 -0
  9. firstcash_py-1.0/firstcash/types/__init__.py +0 -0
  10. firstcash_py-1.0/firstcash/types/category.py +20 -0
  11. firstcash_py-1.0/firstcash/types/http_content.py +4 -0
  12. firstcash_py-1.0/firstcash/types/http_method.py +4 -0
  13. firstcash_py-1.0/firstcash/types/http_request_message.py +14 -0
  14. firstcash_py-1.0/firstcash/types/http_response_message.py +15 -0
  15. firstcash_py-1.0/firstcash/types/http_status_code.py +48 -0
  16. firstcash_py-1.0/firstcash/types/item_request_by_icn.py +30 -0
  17. firstcash_py-1.0/firstcash/types/item_request_search.py +39 -0
  18. firstcash_py-1.0/firstcash/types/store_address.py +22 -0
  19. firstcash_py-1.0/firstcash/types/store_details.py +32 -0
  20. firstcash_py-1.0/firstcash/types/store_display_info.py +39 -0
  21. firstcash_py-1.0/firstcash/types/store_hours.py +18 -0
  22. firstcash_py-1.0/firstcash/types/store_item.py +42 -0
  23. firstcash_py-1.0/firstcash/types/store_item_response.py +26 -0
  24. firstcash_py-1.0/firstcash/types/store_license.py +4 -0
  25. firstcash_py-1.0/firstcash/types/store_request.py +6 -0
  26. firstcash_py-1.0/firstcash/types/todays_store_hours.py +21 -0
  27. firstcash_py-1.0/firstcash/types/version.py +9 -0
  28. firstcash_py-1.0/firstcash.py.egg-info/PKG-INFO +120 -0
  29. firstcash_py-1.0/firstcash.py.egg-info/SOURCES.txt +33 -0
  30. firstcash_py-1.0/firstcash.py.egg-info/dependency_links.txt +1 -0
  31. firstcash_py-1.0/firstcash.py.egg-info/requires.txt +1 -0
  32. firstcash_py-1.0/firstcash.py.egg-info/top_level.txt +1 -0
  33. firstcash_py-1.0/pyproject.toml +41 -0
  34. firstcash_py-1.0/setup.cfg +4 -0
  35. firstcash_py-1.0/setup.py +21 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AgentLoneStar007
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,120 @@
1
+ Metadata-Version: 2.4
2
+ Name: firstcash.py
3
+ Version: 1.0
4
+ Summary: A basic Python library to communicate with FirstCash' mobile app API.
5
+ Author-email: AgentLoneStar007 <contactagent.3gxdf@simplelogin.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/AgentLoneStar007/FirstCash.Py
8
+ Project-URL: Documentation, https://github.com/AgentLoneStar007/FirstCash.Py/tree/main/docs
9
+ Project-URL: Issues, https://github.com/AgentLoneStar007/FirstCash.Py/issues
10
+ Keywords: api,web,web api,http,https,http api,https api,rest,restful,restful api
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Natural Language :: English
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Database
21
+ Classifier: Topic :: Internet
22
+ Classifier: Topic :: Software Development :: Libraries
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.12
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: httpx
28
+ Dynamic: license-file
29
+
30
+ # FirstCash.py
31
+
32
+ #### *A basic Python library to communicate with the FirstCash mobile app API.*
33
+
34
+ This is a super basic library designed for querying the FirstCash mobile app API, which
35
+ allows the developer to search for stores, items, and more. One major advantage of this
36
+ library is it exposes API methods that aren't in use on the FirstCash [inventory website](https://search.cashamerica.com/),
37
+ such as limiting your search to specific stores or multiple categories.
38
+
39
+ Note: This library does require an API key. While one is very is easy to obtain if you just look
40
+ a little for it, I doubt they're legal to distribute, so you have to attain one on your own.
41
+
42
+ #### Features:
43
+ - Methods/attributes extensively explained within
44
+ - Use of modern Python built-in typing capabilities
45
+ - Asynchronous functionality
46
+
47
+ ## Installation:
48
+ **This library requires at least Python 3.12 or higher.** <br>
49
+
50
+ ### Pip:
51
+
52
+ ---
53
+ Windows:
54
+ ```commandline
55
+ py -3 -m pip install -U firstcash.py
56
+ ```
57
+
58
+ Linux/macOS/Unix:
59
+ ```bash
60
+ python3 -m pip install -U firstcash.py
61
+ ```
62
+
63
+ ### UV:
64
+
65
+ ---
66
+ Windows/macOS/Linux/Unix:
67
+ ```bash
68
+ uv add firstcash.py
69
+ ```
70
+
71
+ ## Usage:
72
+ ```python
73
+ from firstcash import APIClient, StoreItemResponse
74
+ from asyncio import run
75
+
76
+ firstcash_client: APIClient = APIClient(api_key="<api key>")
77
+
78
+ async def main():
79
+ try:
80
+ response: StoreItemResponse = await firstcash_client.searchItemsByGeoLocation(
81
+ category_code=0, # Zero for all categories
82
+ search_latitude=39.105,
83
+ search_longitude=-94.593,
84
+ search_radius=20 # In miles
85
+ )
86
+
87
+ for item in response.results:
88
+ print(item)
89
+ finally:
90
+ await firstcash_client.closeAsyncRequestClient()
91
+
92
+ run(main())
93
+ ```
94
+
95
+ (More examples provided in the [documentation](https://github.com/AgentLoneStar007/FirstCash.Py/tree/main/docs).)
96
+
97
+ ## Contributing:
98
+ To build this library, a normal virtual environment is required (A.K.A. not UV).
99
+ First, install the build requirements:
100
+ ```bash
101
+ python -m pip install -r requirements.txt
102
+ ```
103
+ Then run the build script for either Linux or Windows:
104
+ ```bash
105
+ # Linux
106
+ ./scripts/build_and_install.sh
107
+
108
+ # Windows
109
+ scripts/build_and_install.bat
110
+ ```
111
+ This will uninstall any existing versions of the library, build the newest version, and install it
112
+ into the environment.
113
+
114
+ I'll add more to this in the future!
115
+
116
+ ## TODO:
117
+ - [ ] Add a test suite
118
+ - [ ] Add some documentation and examples
119
+ - [ ] Add more extensive error handling
120
+ - [ ] Add a cache to store recently queried items and store details (possibly)
@@ -0,0 +1,91 @@
1
+ # FirstCash.py
2
+
3
+ #### *A basic Python library to communicate with the FirstCash mobile app API.*
4
+
5
+ This is a super basic library designed for querying the FirstCash mobile app API, which
6
+ allows the developer to search for stores, items, and more. One major advantage of this
7
+ library is it exposes API methods that aren't in use on the FirstCash [inventory website](https://search.cashamerica.com/),
8
+ such as limiting your search to specific stores or multiple categories.
9
+
10
+ Note: This library does require an API key. While one is very is easy to obtain if you just look
11
+ a little for it, I doubt they're legal to distribute, so you have to attain one on your own.
12
+
13
+ #### Features:
14
+ - Methods/attributes extensively explained within
15
+ - Use of modern Python built-in typing capabilities
16
+ - Asynchronous functionality
17
+
18
+ ## Installation:
19
+ **This library requires at least Python 3.12 or higher.** <br>
20
+
21
+ ### Pip:
22
+
23
+ ---
24
+ Windows:
25
+ ```commandline
26
+ py -3 -m pip install -U firstcash.py
27
+ ```
28
+
29
+ Linux/macOS/Unix:
30
+ ```bash
31
+ python3 -m pip install -U firstcash.py
32
+ ```
33
+
34
+ ### UV:
35
+
36
+ ---
37
+ Windows/macOS/Linux/Unix:
38
+ ```bash
39
+ uv add firstcash.py
40
+ ```
41
+
42
+ ## Usage:
43
+ ```python
44
+ from firstcash import APIClient, StoreItemResponse
45
+ from asyncio import run
46
+
47
+ firstcash_client: APIClient = APIClient(api_key="<api key>")
48
+
49
+ async def main():
50
+ try:
51
+ response: StoreItemResponse = await firstcash_client.searchItemsByGeoLocation(
52
+ category_code=0, # Zero for all categories
53
+ search_latitude=39.105,
54
+ search_longitude=-94.593,
55
+ search_radius=20 # In miles
56
+ )
57
+
58
+ for item in response.results:
59
+ print(item)
60
+ finally:
61
+ await firstcash_client.closeAsyncRequestClient()
62
+
63
+ run(main())
64
+ ```
65
+
66
+ (More examples provided in the [documentation](https://github.com/AgentLoneStar007/FirstCash.Py/tree/main/docs).)
67
+
68
+ ## Contributing:
69
+ To build this library, a normal virtual environment is required (A.K.A. not UV).
70
+ First, install the build requirements:
71
+ ```bash
72
+ python -m pip install -r requirements.txt
73
+ ```
74
+ Then run the build script for either Linux or Windows:
75
+ ```bash
76
+ # Linux
77
+ ./scripts/build_and_install.sh
78
+
79
+ # Windows
80
+ scripts/build_and_install.bat
81
+ ```
82
+ This will uninstall any existing versions of the library, build the newest version, and install it
83
+ into the environment.
84
+
85
+ I'll add more to this in the future!
86
+
87
+ ## TODO:
88
+ - [ ] Add a test suite
89
+ - [ ] Add some documentation and examples
90
+ - [ ] Add more extensive error handling
91
+ - [ ] Add a cache to store recently queried items and store details (possibly)
@@ -0,0 +1,37 @@
1
+ """
2
+ FirstCash.Py
3
+ ------------
4
+ A basic API wrapper for the FirstCash
5
+ mobile app API, which exposes the combined
6
+ functionality of the store and inventory
7
+ management APIs, allowing the user to fetch
8
+ store details as well as search for items across
9
+ the massive FirstCash inventory network.
10
+
11
+ :copyright: (c) 2026 AgentLoneStar007
12
+ :license: MIT
13
+ """
14
+
15
+ __title__: str = "firstcash"
16
+ __author__: str = "AgentLoneStar007"
17
+ __license__: str = "MIT"
18
+ __copyright__: str = "Copyright © 2026-present AgentLoneStar007"
19
+ __version__: str = "1.0"
20
+
21
+ # Imports from library files, to make everything accessible under the main import of "firstcash"
22
+
23
+ from .api_client import APIClient
24
+ from .types.category import Category
25
+ from .types.store_address import StoreAddress
26
+ from .types.store_details import StoreDetails
27
+ from .types.store_display_info import StoreDisplayInfo
28
+ from .types.store_hours import StoreHours
29
+ from .types.store_item import StoreItem
30
+ from .types.store_item_response import StoreItemResponse
31
+ from .types.store_license import StoreLicense
32
+ from .types.todays_store_hours import TodaysStoreHours
33
+ from .exceptions import (
34
+ FirstCashException, APIGeneralError, APIServerError, APIUnauthorizedError, APIResponseTimedOut, APIContentNotFound,
35
+ APIRateLimited, SearchCoordinateValueError, SearchRadiusValueError, StoreIDValueError, CategoryCodeValueError,
36
+ PageIndexValueError, PageSizeValueError, PriceValueError
37
+ )
@@ -0,0 +1,123 @@
1
+ from urllib.parse import urljoin, urlencode
2
+ from .exceptions import (SearchCoordinateValueError, SearchRadiusValueError, StoreIDValueError, CategoryCodeValueError,
3
+ PageIndexValueError, PageSizeValueError, PriceValueError)
4
+
5
+
6
+ # Function to build a URL to make a request to
7
+ def buildURL(base_api_url: str, api_key: str, endpoint: str = None, params: dict = None) -> str:
8
+ """
9
+ A function to build a URL that can be used to make an API request.
10
+
11
+ :param base_api_url: The base URL of the API.
12
+ :param api_key: The API key for the used API.
13
+ :param endpoint: The endpoint to use. Optional.
14
+ This will be something like "Categories," or "Items."
15
+ :param params: The parameters to append to the URL, in a dictionary
16
+ "key": "value" format.
17
+
18
+ :returns: ``str`` - The URL to query with all provided parameters.
19
+
20
+ :raises None:
21
+ """
22
+
23
+ # Create the base URL
24
+ url: str = urljoin(base_api_url, endpoint) if endpoint else base_api_url
25
+
26
+ if params:
27
+ # Join the parameters to the base URL, if provided
28
+ query_string: str = urlencode(params)
29
+ if "?" not in url:
30
+ url += "?" + query_string
31
+ else:
32
+ url += "&" + query_string
33
+
34
+ # Append the API key to the end, using a & separator if any parameters were
35
+ # provided, or a ? if none were provided
36
+ url += f"{"&" if params else "?"}key={api_key}"
37
+
38
+ return url
39
+
40
+
41
+ class ValueCheckers:
42
+ @staticmethod
43
+ def checkLatitude(latitude: float) -> None:
44
+ """Checks a latitude coordinate to see if it's within bounds."""
45
+
46
+ if not (-90 <= latitude <= 90):
47
+ raise SearchCoordinateValueError(
48
+ "A latitude value must be greater than or equal to -90, and less than or equal to 90.")
49
+
50
+ return
51
+
52
+ @staticmethod
53
+ def checkLongitude(longitude: float) -> None:
54
+ """Checks a longitude coordinate to see if it's within bounds."""
55
+
56
+ if not (-180 <= longitude <= 180):
57
+ raise SearchCoordinateValueError(
58
+ "A longitude value must be greater than or equal to -180 and less than or equal to 180.")
59
+
60
+ return
61
+
62
+ @staticmethod
63
+ def checkSearchRadius(search_radius: int | float) -> None:
64
+ """Checks a search radius to see if it's within bounds."""
65
+
66
+ if not (0 <= search_radius <= 5000):
67
+ raise SearchRadiusValueError(
68
+ "A search radius cannot be negative and must be less than or equal to 5,000 miles.")
69
+
70
+ return
71
+
72
+ @staticmethod
73
+ def checkPriceFilters(max_price: float | int, min_price: float | int = None) -> None:
74
+ """Checks price filters to see if they're within bounds."""
75
+
76
+ if max_price < 0:
77
+ raise PriceValueError("Price filters cannot be negative.")
78
+
79
+ if min_price:
80
+ if min_price < 0:
81
+ raise PriceValueError("Price filters cannot be negative.")
82
+
83
+ if max_price < min_price:
84
+ raise PriceValueError("The maximum price filter cannot be less than the minimum price filter.")
85
+ return
86
+
87
+ @staticmethod
88
+ def checkStoreID(store_id: int) -> None:
89
+ """Checks a store ID to see if it's within bounds."""
90
+
91
+ if not (0 <= store_id <= 32767):
92
+ raise StoreIDValueError("A store ID cannot be negative and must be less than or equal to 32,767.")
93
+
94
+ return
95
+
96
+ @staticmethod
97
+ def checkCategoryCode(category_code: int) -> None:
98
+ """Checks a category code to see if it's within bounds."""
99
+
100
+ if not (0 <= category_code <= 9999):
101
+ raise CategoryCodeValueError("Category codes must be between zero and 9,999.")
102
+
103
+ return
104
+
105
+ @staticmethod
106
+ def checkPageIndex(index: int, starting_index: int = 0) -> None:
107
+ """Checks a page index to see if it's within bounds."""
108
+
109
+ if index < 0:
110
+ raise PageIndexValueError("Page index cannot be negative.")
111
+
112
+ ## While this is semi-unnecessary, it adds a bit of prettification to the error.
113
+ if index < starting_index:
114
+ raise PageIndexValueError("Page index below starting index.")
115
+
116
+ return
117
+
118
+ @staticmethod
119
+ def checkPageSize(page_size: int) -> None:
120
+ """Checks a page's size to see if it's within bounds."""
121
+
122
+ if page_size <= 0:
123
+ raise PageSizeValueError("The page size must be greater than or equal to one.")