rohlik-api 0.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.
- rohlik_api-0.1.0/LICENSE +21 -0
- rohlik_api-0.1.0/MANIFEST.in +4 -0
- rohlik_api-0.1.0/PKG-INFO +381 -0
- rohlik_api-0.1.0/README.md +349 -0
- rohlik_api-0.1.0/pyproject.toml +98 -0
- rohlik_api-0.1.0/requirements.txt +8 -0
- rohlik_api-0.1.0/rohlik_api/__init__.py +74 -0
- rohlik_api-0.1.0/rohlik_api/auth.py +173 -0
- rohlik_api-0.1.0/rohlik_api/client.py +250 -0
- rohlik_api-0.1.0/rohlik_api/endpoints.py +104 -0
- rohlik_api-0.1.0/rohlik_api/errors.py +13 -0
- rohlik_api-0.1.0/rohlik_api/helpers.py +57 -0
- rohlik_api-0.1.0/rohlik_api/http_client.py +273 -0
- rohlik_api-0.1.0/rohlik_api/models.py +650 -0
- rohlik_api-0.1.0/rohlik_api/py.typed +1 -0
- rohlik_api-0.1.0/rohlik_api/services/__init__.py +19 -0
- rohlik_api-0.1.0/rohlik_api/services/account.py +70 -0
- rohlik_api-0.1.0/rohlik_api/services/base.py +63 -0
- rohlik_api-0.1.0/rohlik_api/services/cart.py +90 -0
- rohlik_api-0.1.0/rohlik_api/services/delivery.py +67 -0
- rohlik_api-0.1.0/rohlik_api/services/orders.py +111 -0
- rohlik_api-0.1.0/rohlik_api/services/products.py +176 -0
- rohlik_api-0.1.0/rohlik_api/services/recipes.py +87 -0
- rohlik_api-0.1.0/rohlik_api.egg-info/PKG-INFO +381 -0
- rohlik_api-0.1.0/rohlik_api.egg-info/SOURCES.txt +34 -0
- rohlik_api-0.1.0/rohlik_api.egg-info/dependency_links.txt +1 -0
- rohlik_api-0.1.0/rohlik_api.egg-info/requires.txt +9 -0
- rohlik_api-0.1.0/rohlik_api.egg-info/top_level.txt +1 -0
- rohlik_api-0.1.0/setup.cfg +4 -0
- rohlik_api-0.1.0/tests/test_auth.py +149 -0
- rohlik_api-0.1.0/tests/test_client.py +231 -0
- rohlik_api-0.1.0/tests/test_endpoints.py +178 -0
- rohlik_api-0.1.0/tests/test_helpers.py +37 -0
- rohlik_api-0.1.0/tests/test_http_client.py +286 -0
- rohlik_api-0.1.0/tests/test_recipes.py +256 -0
- rohlik_api-0.1.0/tests/test_services.py +495 -0
rohlik_api-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Daniel Vejsada
|
|
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,381 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rohlik-api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Async Python client for the Rohlik.cz API
|
|
5
|
+
Author-email: Daniel Vejsada <dan.vejsada@gmail.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dvejsada/rohlik_api_python
|
|
8
|
+
Project-URL: Repository, https://github.com/dvejsada/rohlik_api_python
|
|
9
|
+
Project-URL: Issues, https://github.com/dvejsada/rohlik_api_python/issues
|
|
10
|
+
Keywords: rohlik,api,client,grocery,async
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Framework :: AsyncIO
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.13
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: aiohttp>=3.10
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
26
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
|
|
27
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == "dev"
|
|
28
|
+
Requires-Dist: black>=24.0.0; extra == "dev"
|
|
29
|
+
Requires-Dist: ruff>=0.6.0; extra == "dev"
|
|
30
|
+
Requires-Dist: mypy>=1.11.0; extra == "dev"
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
# 🛒 Rohlik API Python Client
|
|
34
|
+
|
|
35
|
+
An async, fully typed Python client for the [Rohlik.cz](https://www.rohlik.cz)
|
|
36
|
+
online grocery service — search products, manage your cart, browse recipes
|
|
37
|
+
(Rohlík Chef), and read your orders and deliveries, all from Python.
|
|
38
|
+
|
|
39
|
+
> ## ⚠️ Unofficial — personal use only
|
|
40
|
+
>
|
|
41
|
+
> This is an **unofficial** client for Rohlik.cz's **non-public** API. It is
|
|
42
|
+
> **not affiliated with, authorized by, or endorsed by Rohlik.cz / Rohlik Group**.
|
|
43
|
+
>
|
|
44
|
+
> - Intended for **personal, non-commercial use with your own account** only.
|
|
45
|
+
> - The private API can change or break **at any time, without notice**.
|
|
46
|
+
> - Your use may be subject to **Rohlik.cz's Terms of Service** — review them and
|
|
47
|
+
> behave responsibly (don't hammer the API or use it commercially).
|
|
48
|
+
> - Provided "as is", with **no warranty**. **Use at your own risk.**
|
|
49
|
+
|
|
50
|
+
## Table of contents
|
|
51
|
+
|
|
52
|
+
- [Features](#features)
|
|
53
|
+
- [Requirements](#requirements)
|
|
54
|
+
- [Installation](#installation)
|
|
55
|
+
- [Quick start](#quick-start)
|
|
56
|
+
- [Credentials & security](#credentials--security)
|
|
57
|
+
- [Typed models](#typed-models)
|
|
58
|
+
- [Services](#services)
|
|
59
|
+
- [API reference](#api-reference)
|
|
60
|
+
- [Error handling](#error-handling)
|
|
61
|
+
- [Advanced usage](#advanced-usage)
|
|
62
|
+
- [Development](#development)
|
|
63
|
+
- [Disclaimer](#disclaimer)
|
|
64
|
+
- [License](#license)
|
|
65
|
+
|
|
66
|
+
## Features
|
|
67
|
+
|
|
68
|
+
- 🚀 Built on aiohttp; bring your own session (e.g. Home Assistant's shared session)
|
|
69
|
+
- 🔐 Automatic login/logout, plus transparent re-authentication when a session expires (HTTP 401)
|
|
70
|
+
- 🎯 Clean, service-based API (`client.cart`, `client.products`, …)
|
|
71
|
+
- 🧩 Fully typed dataclass models for parsed responses (`py.typed`)
|
|
72
|
+
- 🔄 Works as an async context manager
|
|
73
|
+
- 🍳 Recipe search and ingredient shopping (Rohlík Chef)
|
|
74
|
+
- 📦 Product details, composition/nutrition, prices, and AI summaries
|
|
75
|
+
|
|
76
|
+
## Requirements
|
|
77
|
+
|
|
78
|
+
- Python 3.13+
|
|
79
|
+
- [aiohttp](https://docs.aiohttp.org/) (installed automatically)
|
|
80
|
+
|
|
81
|
+
## Installation
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install rohlik-api
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Quick start
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
import asyncio
|
|
91
|
+
from rohlik_api import RohlikAPI
|
|
92
|
+
|
|
93
|
+
async def main():
|
|
94
|
+
async with RohlikAPI(username="your_email@example.com", password="your_password") as client:
|
|
95
|
+
# Search for products (returns a SearchResults model)
|
|
96
|
+
results = await client.products.search("mleko", limit=5)
|
|
97
|
+
for product in results.results:
|
|
98
|
+
print(f"{product.name} - {product.price}")
|
|
99
|
+
|
|
100
|
+
# Get cart contents (returns a Cart model)
|
|
101
|
+
cart = await client.cart.get_content()
|
|
102
|
+
print(f"Cart total: {cart.total_price} ({cart.total_items} items)")
|
|
103
|
+
|
|
104
|
+
# Search recipes (returns a RecipeSearchResults model)
|
|
105
|
+
recipes = await client.recipes.search("rajská", limit=5)
|
|
106
|
+
print(f"Found {recipes.total_hits} recipes")
|
|
107
|
+
|
|
108
|
+
asyncio.run(main())
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The async context manager logs you in on entry and logs out + closes the
|
|
112
|
+
connection on exit.
|
|
113
|
+
|
|
114
|
+
## Credentials & security
|
|
115
|
+
|
|
116
|
+
The client authenticates with your normal Rohlik.cz **email and password**.
|
|
117
|
+
|
|
118
|
+
- **Never hard-code credentials** in source you commit. Prefer environment
|
|
119
|
+
variables or a secrets manager:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
import os
|
|
123
|
+
from rohlik_api import RohlikAPI
|
|
124
|
+
|
|
125
|
+
client = RohlikAPI(
|
|
126
|
+
username=os.environ["ROHLIK_USERNAME"],
|
|
127
|
+
password=os.environ["ROHLIK_PASSWORD"],
|
|
128
|
+
)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
- Credentials are only ever sent to Rohlik.cz over HTTPS. This library does not
|
|
132
|
+
store or transmit them anywhere else.
|
|
133
|
+
- Use a dedicated account if you're uncomfortable automating your primary one.
|
|
134
|
+
|
|
135
|
+
## Typed models
|
|
136
|
+
|
|
137
|
+
Service methods that parse responses return typed dataclasses (importable from
|
|
138
|
+
`rohlik_api`) rather than raw dictionaries, so your editor and type checker know
|
|
139
|
+
the shape of the data:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
from dataclasses import asdict
|
|
143
|
+
from rohlik_api import Cart, SearchResults
|
|
144
|
+
|
|
145
|
+
cart = await client.cart.get_content() # -> Cart
|
|
146
|
+
cart.total_price # float
|
|
147
|
+
cart.products[0].name # str
|
|
148
|
+
|
|
149
|
+
# Convert any model to a plain dict (e.g. for JSON / Home Assistant / MCP):
|
|
150
|
+
asdict(cart)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Raw passthrough endpoints (`orders.*`, `delivery.*`, `account.get_premium_profile`,
|
|
154
|
+
`account.get_bags_info`, `account.get_announcements`, and `get_data`) return the
|
|
155
|
+
decoded JSON as `dict` / `list`, since they are not reshaped by the client.
|
|
156
|
+
|
|
157
|
+
## Services
|
|
158
|
+
|
|
159
|
+
Functionality is grouped into services, accessed as properties on the client:
|
|
160
|
+
|
|
161
|
+
| Service | Property | Description |
|
|
162
|
+
| -------- | ------------------ | --------------------------------------------- |
|
|
163
|
+
| Cart | `client.cart` | Shopping cart operations |
|
|
164
|
+
| Products | `client.products` | Product search and details |
|
|
165
|
+
| Orders | `client.orders` | Order history |
|
|
166
|
+
| Delivery | `client.delivery` | Delivery info and timeslots |
|
|
167
|
+
| Account | `client.account` | Account data and shopping lists |
|
|
168
|
+
| Recipes | `client.recipes` | Recipe search and ingredients (Rohlík Chef) |
|
|
169
|
+
|
|
170
|
+
## API reference
|
|
171
|
+
|
|
172
|
+
### Cart service (`client.cart`)
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
# Get cart contents
|
|
176
|
+
cart = await client.cart.get_content()
|
|
177
|
+
# -> Cart(total_price=199.90, total_items=3, can_make_order=True, products=[CartItem, ...])
|
|
178
|
+
|
|
179
|
+
# Add items to cart
|
|
180
|
+
added = await client.cart.add_items([
|
|
181
|
+
{"product_id": 123456, "quantity": 2},
|
|
182
|
+
{"product_id": 789012, "quantity": 1},
|
|
183
|
+
])
|
|
184
|
+
# -> [123456, 789012] (list of product IDs successfully added)
|
|
185
|
+
|
|
186
|
+
# Delete item from cart (raises APIRequestFailedError on failure)
|
|
187
|
+
await client.cart.delete_item(order_field_id="abc123")
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Products service (`client.products`)
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
# Search for products -> SearchResults | None (None only on request failure)
|
|
194
|
+
results = await client.products.search("mléko", limit=10, favourite=False)
|
|
195
|
+
for product in results.results: # ProductSearchResult: id, name, price, brand, amount
|
|
196
|
+
print(product.name, product.price)
|
|
197
|
+
|
|
198
|
+
# AI-generated product summary -> AISummary | None
|
|
199
|
+
summary = await client.products.get_ai_summary(product_id=1384964)
|
|
200
|
+
|
|
201
|
+
# Composition / nutrition / allergens -> ProductComposition | None
|
|
202
|
+
composition = await client.products.get_composition(product_id=1425155)
|
|
203
|
+
|
|
204
|
+
# Current price -> ProductPrice | None
|
|
205
|
+
price = await client.products.get_price(product_id=1425155)
|
|
206
|
+
|
|
207
|
+
# Raw product detail (brand, attributes, …) -> dict | None (None on 404)
|
|
208
|
+
detail = await client.products.get_detail(product_id=1425155)
|
|
209
|
+
|
|
210
|
+
# Category hierarchy -> list[dict] | None (None if discontinued / 404)
|
|
211
|
+
categories = await client.products.get_categories(product_id=1425155)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Orders service (`client.orders`)
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
next_order = await client.orders.get_next() # upcoming order
|
|
218
|
+
last_order = await client.orders.get_last() # last delivered order
|
|
219
|
+
orders = await client.orders.get_delivered(limit=50, offset=0) # one history page
|
|
220
|
+
all_orders = await client.orders.get_all_delivered() # every page, paginated
|
|
221
|
+
detail = await client.orders.get_detail(order_id=12345678) # full order incl. items
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### Delivery service (`client.delivery`)
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
delivery = await client.delivery.get_info()
|
|
228
|
+
timeslot = await client.delivery.get_timeslot_reservation()
|
|
229
|
+
slots = await client.delivery.get_next_slots()
|
|
230
|
+
announcements = await client.delivery.get_announcements()
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Account service (`client.account`)
|
|
234
|
+
|
|
235
|
+
```python
|
|
236
|
+
premium = await client.account.get_premium_profile()
|
|
237
|
+
bags = await client.account.get_bags_info()
|
|
238
|
+
announcements = await client.account.get_announcements()
|
|
239
|
+
|
|
240
|
+
# Shopping list by ID -> ShoppingList
|
|
241
|
+
shopping_list = await client.account.get_shopping_list("list_id_here")
|
|
242
|
+
# ShoppingList(name="My List", products_in_list=[...])
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### Recipes service (`client.recipes`) — Rohlík Chef
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
# Search recipes -> RecipeSearchResults(recipes=[RecipeSummary, ...], total_hits=4)
|
|
249
|
+
recipes = await client.recipes.search("rajská", limit=10, offset=0)
|
|
250
|
+
|
|
251
|
+
# Recipe details -> RecipeDetail | None
|
|
252
|
+
recipe = await client.recipes.get_detail(recipe_id=59)
|
|
253
|
+
|
|
254
|
+
# Products for ingredients -> IngredientProducts | None
|
|
255
|
+
products = await client.recipes.get_ingredient_products(ingredient_ids=[102, 56], limit=5)
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Aggregated data
|
|
259
|
+
|
|
260
|
+
```python
|
|
261
|
+
# Fetch delivery, orders, cart, premium profile, announcements, etc. in one call
|
|
262
|
+
all_data = await client.get_data()
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## Error handling
|
|
266
|
+
|
|
267
|
+
All errors derive from `RohlikAPIError`:
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
from rohlik_api import RohlikAPI, InvalidCredentialsError, APIRequestFailedError
|
|
271
|
+
|
|
272
|
+
try:
|
|
273
|
+
async with RohlikAPI(username="email@example.com", password="password") as client:
|
|
274
|
+
cart = await client.cart.get_content()
|
|
275
|
+
except InvalidCredentialsError:
|
|
276
|
+
print("Wrong username or password")
|
|
277
|
+
except APIRequestFailedError as err:
|
|
278
|
+
print(f"Request failed: {err}")
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
**Error contract:**
|
|
282
|
+
|
|
283
|
+
- **Critical / mutating operations** (login, `cart.get_content`, `cart.delete_item`,
|
|
284
|
+
`account.get_shopping_list`) **raise** `APIRequestFailedError` on failure.
|
|
285
|
+
- **Read / optional fetches** (most `orders`, `delivery`, `account`, `products`,
|
|
286
|
+
and `recipes` getters) **return `None`** on failure, so an aggregate fetch can
|
|
287
|
+
continue gracefully.
|
|
288
|
+
|
|
289
|
+
## Advanced usage
|
|
290
|
+
|
|
291
|
+
### Configuration
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
client = RohlikAPI(
|
|
295
|
+
username="your_email@example.com",
|
|
296
|
+
password="your_password",
|
|
297
|
+
base_url="https://www.rohlik.cz", # optional
|
|
298
|
+
timeout=30.0, # optional
|
|
299
|
+
headers={"Custom-Header": "Value"}, # optional
|
|
300
|
+
auto_login=True, # optional, default True
|
|
301
|
+
)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### Manual session management
|
|
305
|
+
|
|
306
|
+
```python
|
|
307
|
+
from rohlik_api import RohlikAPI
|
|
308
|
+
|
|
309
|
+
async def main():
|
|
310
|
+
client = RohlikAPI(
|
|
311
|
+
username="email@example.com",
|
|
312
|
+
password="password",
|
|
313
|
+
auto_login=False, # disable auto-login
|
|
314
|
+
)
|
|
315
|
+
try:
|
|
316
|
+
await client.login()
|
|
317
|
+
cart = await client.cart.get_content()
|
|
318
|
+
await client.logout()
|
|
319
|
+
finally:
|
|
320
|
+
await client.close()
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Reusing an existing aiohttp session
|
|
324
|
+
|
|
325
|
+
The client is built on [aiohttp](https://docs.aiohttp.org/). By default it
|
|
326
|
+
creates and owns its own `ClientSession`, but you can inject an externally
|
|
327
|
+
managed session instead — useful inside a Home Assistant integration, where
|
|
328
|
+
the recommended pattern is to share a single session per instance. An injected
|
|
329
|
+
session is **never** closed by the client; its lifecycle stays with the owner.
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
import aiohttp
|
|
333
|
+
from rohlik_api import RohlikAPI
|
|
334
|
+
|
|
335
|
+
async def main(session: aiohttp.ClientSession):
|
|
336
|
+
client = RohlikAPI(
|
|
337
|
+
username="email@example.com",
|
|
338
|
+
password="password",
|
|
339
|
+
session=session, # reuse the caller's session
|
|
340
|
+
)
|
|
341
|
+
async with client:
|
|
342
|
+
cart = await client.cart.get_content()
|
|
343
|
+
# `session` is left open for the caller to close.
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Inside a Home Assistant integration you would pass the shared session, for
|
|
347
|
+
example `RohlikAPI(..., session=async_get_clientsession(hass))`.
|
|
348
|
+
|
|
349
|
+
## Development
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# Install with development dependencies
|
|
353
|
+
pip install -e ".[dev]"
|
|
354
|
+
|
|
355
|
+
# Run the test suite
|
|
356
|
+
pytest
|
|
357
|
+
|
|
358
|
+
# Lint, format check and type check
|
|
359
|
+
ruff check .
|
|
360
|
+
black --check .
|
|
361
|
+
mypy rohlik_api
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Please make sure `pytest`, `ruff`, `black` and `mypy` all pass before opening a
|
|
365
|
+
pull request.
|
|
366
|
+
|
|
367
|
+
## Disclaimer
|
|
368
|
+
|
|
369
|
+
This project is an **independent, unofficial** client. It is **not affiliated
|
|
370
|
+
with, authorized by, or endorsed by Rohlik.cz, Rohlik Group, or any of its
|
|
371
|
+
subsidiaries**. "Rohlik", "Rohlik.cz" and "Rohlík Chef" are trademarks of their
|
|
372
|
+
respective owners.
|
|
373
|
+
|
|
374
|
+
It talks to a **private, undocumented API** that may change or stop working at
|
|
375
|
+
any time. It is provided for **personal, non-commercial use** only, and comes
|
|
376
|
+
with **no warranty of any kind**. You are responsible for complying with
|
|
377
|
+
Rohlik.cz's Terms of Service and applicable law. **Use at your own risk.**
|
|
378
|
+
|
|
379
|
+
## License
|
|
380
|
+
|
|
381
|
+
[MIT](LICENSE) © Daniel Vejsada
|