codex-services 0.1.0__py3-none-any.whl
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.
- codex_services/__init__.py +1 -0
- codex_services/booking/__init__.py +37 -0
- codex_services/booking/_shared/__init__.py +1 -0
- codex_services/booking/_shared/calculator.py +330 -0
- codex_services/booking/_shared/dto.py +82 -0
- codex_services/booking/_shared/exceptions.py +318 -0
- codex_services/booking/_shared/interfaces.py +66 -0
- codex_services/booking/_shared/validators.py +132 -0
- codex_services/booking/room/__init__.py +7 -0
- codex_services/booking/slot_master/__init__.py +58 -0
- codex_services/booking/slot_master/api.py +171 -0
- codex_services/booking/slot_master/chain_finder.py +450 -0
- codex_services/booking/slot_master/dto.py +446 -0
- codex_services/booking/slot_master/modes.py +44 -0
- codex_services/booking/slot_master/scorer.py +168 -0
- codex_services/calendar/__init__.py +5 -0
- codex_services/calendar/engine.py +101 -0
- codex_services/py.typed +0 -0
- codex_services-0.1.0.dist-info/METADATA +113 -0
- codex_services-0.1.0.dist-info/RECORD +21 -0
- codex_services-0.1.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""
|
|
2
|
+
codex_services.calendar.engine
|
|
3
|
+
==============================
|
|
4
|
+
Universal calendar generator.
|
|
5
|
+
Framework-agnostic (does not depend on Django).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import calendar
|
|
9
|
+
from datetime import date
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
import holidays
|
|
14
|
+
except ImportError as exc:
|
|
15
|
+
raise ImportError("CalendarEngine requires the 'calendar' extra: pip install codex-services[calendar]") from exc
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class CalendarEngine:
|
|
19
|
+
"""
|
|
20
|
+
Day matrix generator for a calendar.
|
|
21
|
+
|
|
22
|
+
Used for rendering UI (website, bot).
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
@staticmethod
|
|
26
|
+
def get_month_matrix(
|
|
27
|
+
year: int,
|
|
28
|
+
month: int,
|
|
29
|
+
today: date,
|
|
30
|
+
selected_date: date | None = None,
|
|
31
|
+
holidays_subdiv: str = "ST", # Default: Saxony-Anhalt
|
|
32
|
+
) -> list[dict[str, Any]]:
|
|
33
|
+
"""
|
|
34
|
+
Generates a list of days for the calendar grid.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
year: Year.
|
|
38
|
+
month: Month.
|
|
39
|
+
today: Current date (to determine past days).
|
|
40
|
+
selected_date: Selected date (for 'active' status).
|
|
41
|
+
holidays_subdiv: German region for holidays.
|
|
42
|
+
|
|
43
|
+
Returns:
|
|
44
|
+
List of dictionaries with day data.
|
|
45
|
+
"""
|
|
46
|
+
de_holidays = holidays.country_holidays("DE", subdiv=holidays_subdiv, years=year)
|
|
47
|
+
|
|
48
|
+
cal = calendar.Calendar(firstweekday=0) # Mon - first day
|
|
49
|
+
month_days = cal.itermonthdays(year, month)
|
|
50
|
+
|
|
51
|
+
result: list[dict[str, Any]] = []
|
|
52
|
+
for day_num in month_days:
|
|
53
|
+
if day_num == 0:
|
|
54
|
+
result.append({"num": "", "status": "empty"})
|
|
55
|
+
continue
|
|
56
|
+
|
|
57
|
+
calc_date = date(year, month, day_num)
|
|
58
|
+
weekday = calc_date.weekday()
|
|
59
|
+
|
|
60
|
+
# Base status
|
|
61
|
+
status = "available"
|
|
62
|
+
|
|
63
|
+
if calc_date < today or weekday == 6:
|
|
64
|
+
status = "disabled"
|
|
65
|
+
elif calc_date in de_holidays:
|
|
66
|
+
status = "holiday"
|
|
67
|
+
|
|
68
|
+
if selected_date and calc_date == selected_date:
|
|
69
|
+
status = "active"
|
|
70
|
+
|
|
71
|
+
day_data: dict[str, Any] = {
|
|
72
|
+
"num": str(day_num),
|
|
73
|
+
"date": calc_date.isoformat(),
|
|
74
|
+
"status": status,
|
|
75
|
+
"is_holiday": calc_date in de_holidays,
|
|
76
|
+
"weekday": weekday,
|
|
77
|
+
}
|
|
78
|
+
result.append(day_data)
|
|
79
|
+
|
|
80
|
+
return result
|
|
81
|
+
|
|
82
|
+
@staticmethod
|
|
83
|
+
def get_month_label(year: int, month: int, locale: str = "ru") -> str:
|
|
84
|
+
"""Returns the month name and year."""
|
|
85
|
+
month_names_ru = {
|
|
86
|
+
1: "Январь",
|
|
87
|
+
2: "Февраль",
|
|
88
|
+
3: "Март",
|
|
89
|
+
4: "Апрель",
|
|
90
|
+
5: "Май",
|
|
91
|
+
6: "Июнь",
|
|
92
|
+
7: "Июль",
|
|
93
|
+
8: "Август",
|
|
94
|
+
9: "Сентябрь",
|
|
95
|
+
10: "Октябрь",
|
|
96
|
+
11: "Ноябрь",
|
|
97
|
+
12: "Декабрь",
|
|
98
|
+
}
|
|
99
|
+
# Other languages (de, en) can be added if necessary
|
|
100
|
+
name = month_names_ru.get(month, "")
|
|
101
|
+
return f"{name} {year}"
|
codex_services/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codex-services
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Reusable business logic engines for Codex platform (CRM, finance, HR, inventory)
|
|
5
|
+
Project-URL: Homepage, https://github.com/codexdlc/codex-services
|
|
6
|
+
Project-URL: Documentation, https://codexdlc.github.io/codex-services/
|
|
7
|
+
Project-URL: Repository, https://github.com/codexdlc/codex-services
|
|
8
|
+
Project-URL: Issues, https://github.com/codexdlc/codex-services/issues
|
|
9
|
+
Author: CodexDLC
|
|
10
|
+
License: Apache-2.0
|
|
11
|
+
Keywords: booking,business,calculator,crm,scheduling,waas
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Requires-Dist: codex-core
|
|
21
|
+
Requires-Dist: pydantic<3.0,>=2.0
|
|
22
|
+
Provides-Extra: all
|
|
23
|
+
Requires-Dist: holidays>=0.40; extra == 'all'
|
|
24
|
+
Provides-Extra: calendar
|
|
25
|
+
Requires-Dist: holidays>=0.40; extra == 'calendar'
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: bandit>=1.7; extra == 'dev'
|
|
28
|
+
Requires-Dist: detect-secrets>=1.5; extra == 'dev'
|
|
29
|
+
Requires-Dist: holidays>=0.40; extra == 'dev'
|
|
30
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
31
|
+
Requires-Dist: pip-audit>=2.7; extra == 'dev'
|
|
32
|
+
Requires-Dist: pre-commit>=3.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
36
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
37
|
+
Provides-Extra: docs
|
|
38
|
+
Requires-Dist: mike>=2.0; extra == 'docs'
|
|
39
|
+
Requires-Dist: mkdocs-include-markdown-plugin; extra == 'docs'
|
|
40
|
+
Requires-Dist: mkdocs-material>=9.0; extra == 'docs'
|
|
41
|
+
Requires-Dist: mkdocs-static-i18n[material]>=1.2.0; extra == 'docs'
|
|
42
|
+
Requires-Dist: mkdocs>=1.5; extra == 'docs'
|
|
43
|
+
Requires-Dist: mkdocstrings[python]>=0.24; extra == 'docs'
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
|
|
46
|
+
# codex-services
|
|
47
|
+
<!-- Type: LANDING -->
|
|
48
|
+
|
|
49
|
+
[](https://pypi.org/project/codex-services/)
|
|
50
|
+
[](https://pypi.org/project/codex-services/)
|
|
51
|
+
[](https://github.com/codexdlc/codex-services/actions/workflows/ci.yml)
|
|
52
|
+
[](LICENSE)
|
|
53
|
+
|
|
54
|
+
Pure-Python business logic engines for booking, scheduling, and CRM workflows.
|
|
55
|
+
No ORM, no framework dependencies — drop into any Python project or use as a building block inside the Codex ecosystem.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Install
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install codex-services
|
|
63
|
+
|
|
64
|
+
# With holiday calendar support
|
|
65
|
+
pip install "codex-services[calendar]"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Quick Start
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from codex_services.booking.slot_master import find_slots, BookingEngineRequest, ServiceRequest, BookingMode
|
|
72
|
+
from datetime import date
|
|
73
|
+
|
|
74
|
+
request = BookingEngineRequest(
|
|
75
|
+
service_requests=[
|
|
76
|
+
ServiceRequest(service_id="haircut", duration_minutes=60, possible_master_ids=["m1", "m2"]),
|
|
77
|
+
],
|
|
78
|
+
booking_date=date.today(),
|
|
79
|
+
mode=BookingMode.SINGLE_DAY,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
result = find_slots(request, masters_availability=[...])
|
|
83
|
+
if result.has_solutions:
|
|
84
|
+
print(result.best.starts_at)
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Modules
|
|
88
|
+
|
|
89
|
+
| Module | Extra | Description |
|
|
90
|
+
| :--- | :--- | :--- |
|
|
91
|
+
| `codex_services.booking.slot_master` | — | Recursive chain-finder for multi-service bookings with scoring and waitlist |
|
|
92
|
+
| `codex_services.booking._shared` | — | Low-level slot arithmetic — windows, gaps, busy interval merging |
|
|
93
|
+
| `codex_services.calendar` | `[calendar]` | Calendar grid generator for UI rendering with holiday awareness |
|
|
94
|
+
|
|
95
|
+
## Documentation
|
|
96
|
+
|
|
97
|
+
Full docs with architecture, API reference, and data flow diagrams:
|
|
98
|
+
|
|
99
|
+
**[https://codexdlc.github.io/codex-services/](https://codexdlc.github.io/codex-services/)**
|
|
100
|
+
|
|
101
|
+
## Part of the Codex ecosystem
|
|
102
|
+
|
|
103
|
+
| Package | Role |
|
|
104
|
+
| :--- | :--- |
|
|
105
|
+
| [codex-core](https://github.com/codexdlc/codex-core) | Foundation — immutable DTOs, PII masking, env settings |
|
|
106
|
+
| [codex-platform](https://github.com/codexdlc/codex-platform) | Infrastructure — Redis, Streams, ARQ workers, Notifications |
|
|
107
|
+
| [codex-ai](https://github.com/codexdlc/codex-ai) | LLM layer — unified async interface for OpenAI, Gemini, Anthropic |
|
|
108
|
+
| **codex-services** | Business logic — Booking engine, CRM, Calendar |
|
|
109
|
+
|
|
110
|
+
Each library is **fully standalone** — install only what your project needs.
|
|
111
|
+
Together they form the backbone of **[codex-bot](https://github.com/codexdlc/codex-bot)**
|
|
112
|
+
(Telegram AI-agent infrastructure built on aiogram) and
|
|
113
|
+
**[codex-django](https://github.com/codexdlc/codex-django)** (Django integration layer).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
codex_services/__init__.py,sha256=sE9LPad-7lXzTlX3d_AAr-1CiyQsiNFt4Hmpkr8euTE,74
|
|
2
|
+
codex_services/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
codex_services/booking/__init__.py,sha256=HZBIRoDN3MRRpozurSmuz4OHwAU3Aqyf9pd1DBolXHA,980
|
|
4
|
+
codex_services/booking/_shared/__init__.py,sha256=2YmPQzheF_iBJbYzQubhXM1WhvkXcFBFlU00jvia0T8,60
|
|
5
|
+
codex_services/booking/_shared/calculator.py,sha256=VE0KSPmKfS7288RnWznY8zfPH-g5utxUCfbSCsK4KZw,12286
|
|
6
|
+
codex_services/booking/_shared/dto.py,sha256=aCBXb--NcdIGMTPVrbPFcUF5Hn78nSINTiwYdm35fEg,2321
|
|
7
|
+
codex_services/booking/_shared/exceptions.py,sha256=JDsN9_vO6CDPpMOrpdt2BycZ8Gai73-7BbPIqc_xFuI,9949
|
|
8
|
+
codex_services/booking/_shared/interfaces.py,sha256=mz0uW2_MFBBJpfYNStUSGDZxjaq-JCwWfjk75YgH6TE,2145
|
|
9
|
+
codex_services/booking/_shared/validators.py,sha256=1qHqvdFZsWKOfwt_VJkdehhXk1dcZY2nno0TrXcvKMw,4732
|
|
10
|
+
codex_services/booking/room/__init__.py,sha256=PKk1dMmL8XuOOhx6GbxWXRyrwTqZCLxQizHcAhxZUwE,266
|
|
11
|
+
codex_services/booking/slot_master/__init__.py,sha256=mBOhfg7H-6ceO2QKe8I-hqTVJL_Sub9VseaRhBcSNug,1516
|
|
12
|
+
codex_services/booking/slot_master/api.py,sha256=wykjGF8tPqGO0r2whcO02zBXB9P-xjZzqm-KNEwO850,6535
|
|
13
|
+
codex_services/booking/slot_master/chain_finder.py,sha256=quOwH_3ueTaCkN1dPwWq7SLUqCr8VH3WSMLfTcFooLw,18663
|
|
14
|
+
codex_services/booking/slot_master/dto.py,sha256=XJ7SFg8Rj9G19d_Z5U9Ri-jQJAnMDe9Z-N1Gm_ufmB0,16176
|
|
15
|
+
codex_services/booking/slot_master/modes.py,sha256=GCDRjJYhv6ixJs4Ra0FaPEjVXB_ih2OaokyAXezlr8c,1060
|
|
16
|
+
codex_services/booking/slot_master/scorer.py,sha256=Baj8_5se7yuLMdMArmtrdilMP1madaSyYpLaplzpawQ,6573
|
|
17
|
+
codex_services/calendar/__init__.py,sha256=xLFeotqbhF24u8Ow60CclaBmgJJ5d-wJLr3_BIvoEHA,117
|
|
18
|
+
codex_services/calendar/engine.py,sha256=z-ernrCOUCp3scxjOs0k5uo9gnaAVInq7XKdGkwlypM,2967
|
|
19
|
+
codex_services-0.1.0.dist-info/METADATA,sha256=dYPDIYtLFi-CpNUeG7-zZyuGxFSKz9xeYv4hNu-NszY,4732
|
|
20
|
+
codex_services-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
21
|
+
codex_services-0.1.0.dist-info/RECORD,,
|