qanuni-sdk 0.2.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.
- qanuni_sdk-0.2.0/.env.example +10 -0
- qanuni_sdk-0.2.0/.gitignore +12 -0
- qanuni_sdk-0.2.0/CHANGELOG.md +27 -0
- qanuni_sdk-0.2.0/FullReadme.md +427 -0
- qanuni_sdk-0.2.0/LICENSE +21 -0
- qanuni_sdk-0.2.0/PKG-INFO +115 -0
- qanuni_sdk-0.2.0/README.md +112 -0
- qanuni_sdk-0.2.0/README_PYPI.md +75 -0
- qanuni_sdk-0.2.0/docs/08_PROMPT_AUTHORING.md +126 -0
- qanuni_sdk-0.2.0/docs/guides/README_PUBLISHING.md +102 -0
- qanuni_sdk-0.2.0/docs/guides/README_USERS.md +170 -0
- qanuni_sdk-0.2.0/examples.py +1063 -0
- qanuni_sdk-0.2.0/pyproject.toml +103 -0
- qanuni_sdk-0.2.0/qanuni/__init__.py +7 -0
- qanuni_sdk-0.2.0/qanuni/_version.py +3 -0
- qanuni_sdk-0.2.0/qanuni/catalog.py +193 -0
- qanuni_sdk-0.2.0/qanuni/client.py +287 -0
- qanuni_sdk-0.2.0/qanuni/core/__init__.py +1 -0
- qanuni_sdk-0.2.0/qanuni/core/base_tool.py +559 -0
- qanuni_sdk-0.2.0/qanuni/core/config.py +75 -0
- qanuni_sdk-0.2.0/qanuni/core/exceptions.py +446 -0
- qanuni_sdk-0.2.0/qanuni/core/output_parser.py +59 -0
- qanuni_sdk-0.2.0/qanuni/core/prompt_loader.py +385 -0
- qanuni_sdk-0.2.0/qanuni/jurisdictions/__init__.py +1 -0
- qanuni_sdk-0.2.0/qanuni/jurisdictions/sa_labor.py +75 -0
- qanuni_sdk-0.2.0/qanuni/jurisdictions/sa_pdpl.py +13 -0
- qanuni_sdk-0.2.0/qanuni/legal_references/__init__.py +21 -0
- qanuni_sdk-0.2.0/qanuni/legal_references/loader.py +123 -0
- qanuni_sdk-0.2.0/qanuni/legal_references/models.py +257 -0
- qanuni_sdk-0.2.0/qanuni/legal_references_data/sa/compliance/legal_notice_baseline.yaml +36 -0
- qanuni_sdk-0.2.0/qanuni/legal_references_data/sa/compliance/pdpl_baseline.yaml +37 -0
- qanuni_sdk-0.2.0/qanuni/legal_references_data/sa/contracts/generation_baseline.yaml +39 -0
- qanuni_sdk-0.2.0/qanuni/legal_references_data/sa/contracts/review_baseline.yaml +38 -0
- qanuni_sdk-0.2.0/qanuni/legal_references_data/sa/drafting/legal_language_baseline.yaml +40 -0
- qanuni_sdk-0.2.0/qanuni/legal_references_data/sa/labor/employment_baseline.yaml +39 -0
- qanuni_sdk-0.2.0/qanuni/legal_references_data/sa/policies/hr_baseline.yaml +40 -0
- qanuni_sdk-0.2.0/qanuni/models/__init__.py +1 -0
- qanuni_sdk-0.2.0/qanuni/models/common.py +85 -0
- qanuni_sdk-0.2.0/qanuni/models/compliance.py +48 -0
- qanuni_sdk-0.2.0/qanuni/models/contracts.py +85 -0
- qanuni_sdk-0.2.0/qanuni/models/drafting.py +78 -0
- qanuni_sdk-0.2.0/qanuni/models/labor.py +59 -0
- qanuni_sdk-0.2.0/qanuni/models/policies.py +48 -0
- qanuni_sdk-0.2.0/qanuni/prompts/compliance/demand_letter.yaml +45 -0
- qanuni_sdk-0.2.0/qanuni/prompts/compliance/privacy_policy.yaml +42 -0
- qanuni_sdk-0.2.0/qanuni/prompts/contracts/gap_analysis.yaml +41 -0
- qanuni_sdk-0.2.0/qanuni/prompts/contracts/generate_mou.yaml +45 -0
- qanuni_sdk-0.2.0/qanuni/prompts/contracts/generate_nda.yaml +47 -0
- qanuni_sdk-0.2.0/qanuni/prompts/drafting/improve.yaml +36 -0
- qanuni_sdk-0.2.0/qanuni/prompts/drafting/simplify.yaml +36 -0
- qanuni_sdk-0.2.0/qanuni/prompts/drafting/summarize.yaml +37 -0
- qanuni_sdk-0.2.0/qanuni/prompts/policies/hr_policy.yaml +39 -0
- qanuni_sdk-0.2.0/qanuni/prompts/policies/job_description.yaml +42 -0
- qanuni_sdk-0.2.0/qanuni/providers/__init__.py +13 -0
- qanuni_sdk-0.2.0/qanuni/providers/base_provider.py +121 -0
- qanuni_sdk-0.2.0/qanuni/providers/openai_provider.py +335 -0
- qanuni_sdk-0.2.0/qanuni/providers/static_provider.py +195 -0
- qanuni_sdk-0.2.0/qanuni/py.typed +1 -0
- qanuni_sdk-0.2.0/qanuni/tools/__init__.py +1 -0
- qanuni_sdk-0.2.0/qanuni/tools/compliance/__init__.py +5 -0
- qanuni_sdk-0.2.0/qanuni/tools/compliance/demand_letter.py +39 -0
- qanuni_sdk-0.2.0/qanuni/tools/compliance/namespace.py +140 -0
- qanuni_sdk-0.2.0/qanuni/tools/compliance/privacy_policy.py +39 -0
- qanuni_sdk-0.2.0/qanuni/tools/contracts/__init__.py +5 -0
- qanuni_sdk-0.2.0/qanuni/tools/contracts/gap_analysis.py +62 -0
- qanuni_sdk-0.2.0/qanuni/tools/contracts/mou_generator.py +35 -0
- qanuni_sdk-0.2.0/qanuni/tools/contracts/namespace.py +188 -0
- qanuni_sdk-0.2.0/qanuni/tools/contracts/nda_generator.py +35 -0
- qanuni_sdk-0.2.0/qanuni/tools/drafting/__init__.py +5 -0
- qanuni_sdk-0.2.0/qanuni/tools/drafting/improve.py +39 -0
- qanuni_sdk-0.2.0/qanuni/tools/drafting/namespace.py +188 -0
- qanuni_sdk-0.2.0/qanuni/tools/drafting/simplify.py +35 -0
- qanuni_sdk-0.2.0/qanuni/tools/drafting/summarize.py +52 -0
- qanuni_sdk-0.2.0/qanuni/tools/labor/__init__.py +5 -0
- qanuni_sdk-0.2.0/qanuni/tools/labor/end_of_service.py +66 -0
- qanuni_sdk-0.2.0/qanuni/tools/labor/namespace.py +143 -0
- qanuni_sdk-0.2.0/qanuni/tools/labor/probation_check.py +63 -0
- qanuni_sdk-0.2.0/qanuni/tools/policies/__init__.py +5 -0
- qanuni_sdk-0.2.0/qanuni/tools/policies/hr_policy.py +35 -0
- qanuni_sdk-0.2.0/qanuni/tools/policies/job_description.py +39 -0
- qanuni_sdk-0.2.0/qanuni/tools/policies/namespace.py +140 -0
- qanuni_sdk-0.2.0/qanuni/utils/__init__.py +1 -0
- qanuni_sdk-0.2.0/qanuni/utils/documents.py +42 -0
- qanuni_sdk-0.2.0/qanuni/utils/pdf_parser.py +35 -0
- qanuni_sdk-0.2.0/release_preflight.py +594 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
OPENAI_API_KEY=sk-your-openai-key
|
|
2
|
+
QANUNI_MODEL=gpt-5.5
|
|
3
|
+
QANUNI_LANGUAGE=ar
|
|
4
|
+
QANUNI_JURISDICTION=SA
|
|
5
|
+
QANUNI_TIMEOUT=90
|
|
6
|
+
QANUNI_MAX_RETRIES=2
|
|
7
|
+
QANUNI_MAX_OUTPUT_TOKENS=2500
|
|
8
|
+
QANUNI_REASONING_EFFORT=medium
|
|
9
|
+
QANUNI_VERBOSITY=medium
|
|
10
|
+
QANUNI_LOG_LEVEL=WARNING
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `qanuni-sdk` should be documented in this file.
|
|
4
|
+
|
|
5
|
+
## 0.2.0 - 2026-05-24
|
|
6
|
+
|
|
7
|
+
Free-edition release.
|
|
8
|
+
|
|
9
|
+
Highlights:
|
|
10
|
+
|
|
11
|
+
- Removed activation and licensing flows from the published distribution
|
|
12
|
+
- Made the shipped toolset and async execution fully free
|
|
13
|
+
- Rebuilt examples and user docs around a zero-license journey
|
|
14
|
+
- Split this distribution into its own publishable `free_edition` folder
|
|
15
|
+
- Simplified package metadata and dependencies for the free build
|
|
16
|
+
|
|
17
|
+
## 0.1.0 - 2026-05-24
|
|
18
|
+
|
|
19
|
+
Initial public alpha release.
|
|
20
|
+
|
|
21
|
+
Highlights:
|
|
22
|
+
|
|
23
|
+
- Arabic-first Saudi legal SDK foundation
|
|
24
|
+
- Implemented labor, contracts, compliance, drafting, and policy namespaces
|
|
25
|
+
- Signed-license validation and entitlement enforcement
|
|
26
|
+
- Bundled runnable examples and local owner verification command
|
|
27
|
+
- Trusted-publishing-ready GitHub workflow for TestPyPI and PyPI
|
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
# Full Qanuni Free Edition Walkthrough
|
|
2
|
+
|
|
3
|
+
This file is the complete journey for a first-time user of the **free Qanuni SDK distribution**.
|
|
4
|
+
|
|
5
|
+
In this edition:
|
|
6
|
+
|
|
7
|
+
- all shipped tools are free
|
|
8
|
+
- there is no activation flow
|
|
9
|
+
- there is no `license_token`
|
|
10
|
+
- there is no `client.license`
|
|
11
|
+
- async methods are also available
|
|
12
|
+
|
|
13
|
+
The only external credential you may need is your own `OPENAI_API_KEY` for prompt-backed tools.
|
|
14
|
+
Do not place the API key directly inside notebook cells. Prefer `.env` or environment variables.
|
|
15
|
+
|
|
16
|
+
## 1. Install the Package
|
|
17
|
+
|
|
18
|
+
If you are using the already published package:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install qanuni-sdk
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
If you are validating this repository locally before publishing, move into
|
|
25
|
+
`free_edition` and install the local source instead of pulling the older PyPI release:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd free_edition
|
|
29
|
+
python -m pip install -e .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Inside Jupyter, prefer:
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
%pip install -e .
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Import name:
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from qanuni import LegalClient
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Package name and import name are different on purpose:
|
|
45
|
+
|
|
46
|
+
- package on PyPI: `qanuni-sdk`
|
|
47
|
+
- import in Python: `qanuni`
|
|
48
|
+
|
|
49
|
+
## 2. Optional `.env` Setup
|
|
50
|
+
|
|
51
|
+
Create a local `.env`:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
OPENAI_API_KEY=sk-...
|
|
55
|
+
QANUNI_MODEL=gpt-5.5
|
|
56
|
+
QANUNI_LANGUAGE=ar
|
|
57
|
+
QANUNI_JURISDICTION=SA
|
|
58
|
+
QANUNI_TIMEOUT=90
|
|
59
|
+
QANUNI_MAX_RETRIES=2
|
|
60
|
+
QANUNI_MAX_OUTPUT_TOKENS=2500
|
|
61
|
+
QANUNI_REASONING_EFFORT=medium
|
|
62
|
+
QANUNI_VERBOSITY=medium
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
You can also pass everything directly in code.
|
|
66
|
+
|
|
67
|
+
## 3. Create Your First Client
|
|
68
|
+
|
|
69
|
+
If you only want deterministic labor tools:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from qanuni import LegalClient
|
|
73
|
+
|
|
74
|
+
client = LegalClient()
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
If you want prompt-backed tools:
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from qanuni import LegalClient
|
|
81
|
+
|
|
82
|
+
client = LegalClient(api_key="sk-...")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## 4. Inspect the Tool Catalog
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from qanuni import LegalClient
|
|
89
|
+
|
|
90
|
+
client = LegalClient()
|
|
91
|
+
|
|
92
|
+
for tool in client.list_tools():
|
|
93
|
+
print(tool.tool_id, tool.tier, tool.implementation)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
You can also inspect availability:
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
for tool in client.list_tool_access():
|
|
100
|
+
print(tool.tool_id, tool.available, tool.reason)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
In this free edition, all shipped tools should be available.
|
|
104
|
+
|
|
105
|
+
## 5. Use Deterministic Tools Without OpenAI
|
|
106
|
+
|
|
107
|
+
### End of service
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from qanuni import LegalClient
|
|
111
|
+
|
|
112
|
+
client = LegalClient()
|
|
113
|
+
|
|
114
|
+
result = client.labor.end_of_service(
|
|
115
|
+
monthly_salary=12000,
|
|
116
|
+
years_of_service=7.5,
|
|
117
|
+
termination_reason="resignation",
|
|
118
|
+
contract_type="indefinite",
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
print(result.total_amount)
|
|
122
|
+
print(result.calculation_breakdown)
|
|
123
|
+
print(result.legal_explanation)
|
|
124
|
+
print(result.additional_entitlements)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Probation check
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
result = client.labor.probation_check(
|
|
131
|
+
probation_days=120,
|
|
132
|
+
extension_in_writing=True,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
print(result.is_legal)
|
|
136
|
+
print(result.max_allowed_days)
|
|
137
|
+
print(result.violations)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## 6. Use Prompt-Backed Tools With OpenAI
|
|
141
|
+
|
|
142
|
+
### Improve drafting
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from qanuni import LegalClient
|
|
146
|
+
|
|
147
|
+
client = LegalClient(api_key="sk-...")
|
|
148
|
+
|
|
149
|
+
result = client.drafting.improve(
|
|
150
|
+
original_text="يدفع الطرف الأول عند الإنجاز.",
|
|
151
|
+
improvement_goals=["precision", "clarity", "formality"],
|
|
152
|
+
context="service agreement",
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
print(result.improved_text)
|
|
156
|
+
print(result.changes)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Summarize a legal document
|
|
160
|
+
|
|
161
|
+
```python
|
|
162
|
+
result = client.drafting.summarize(
|
|
163
|
+
document_text="""
|
|
164
|
+
يتعهد الطرف الأول بتقديم الخدمات التقنية،
|
|
165
|
+
ويلتزم الطرف الثاني بسداد المقابل وفق الفواتير الصادرة،
|
|
166
|
+
ويجوز إنهاء الاتفاق عند الإخلال الجسيم.
|
|
167
|
+
""",
|
|
168
|
+
summary_length="executive",
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
print(result.summary)
|
|
172
|
+
print(result.key_obligations)
|
|
173
|
+
print(result.risk_highlights)
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Simplify legal Arabic
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
result = client.drafting.simplify(
|
|
180
|
+
legal_text="يلتزم الموظف بعدم منافسة صاحب العمل خلال المدة المنصوص عليها تعاقديًا."
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
print(result.simplified_text)
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 7. Contract and Commercial Tools
|
|
187
|
+
|
|
188
|
+
### Contract gap analysis
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
result = client.contracts.gap_analysis(
|
|
192
|
+
contract_text="""
|
|
193
|
+
يلتزم الطرف الثاني بتنفيذ الأعمال،
|
|
194
|
+
ويتم السداد لاحقًا وفق ما يراه الطرف الأول مناسبًا،
|
|
195
|
+
ويجوز إنهاء العقد عند الحاجة.
|
|
196
|
+
""",
|
|
197
|
+
contract_type="service_agreement",
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
print(result.summary)
|
|
201
|
+
print(result.gaps)
|
|
202
|
+
print(result.missing_mandatory_clauses)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Generate NDA
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
result = client.contracts.generate_nda(
|
|
209
|
+
nda_type="mutual",
|
|
210
|
+
disclosing_party="شركة ألف",
|
|
211
|
+
receiving_party="شركة باء",
|
|
212
|
+
purpose="دراسة شراكة تشغيلية",
|
|
213
|
+
confidentiality_period_years=3,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
print(result.nda_text)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Generate MOU
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
result = client.contracts.generate_mou(
|
|
223
|
+
party_a="شركة ألف",
|
|
224
|
+
party_b="شركة باء",
|
|
225
|
+
objectives=["تطوير منصة قانونية مشتركة"],
|
|
226
|
+
responsibilities=["تبادل المتطلبات", "تجهيز خطة تنفيذ أولية"],
|
|
227
|
+
duration_months=6,
|
|
228
|
+
binding_sections=["السرية", "القانون الحاكم"],
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
print(result.mou_text)
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## 8. Compliance and Policy Tools
|
|
235
|
+
|
|
236
|
+
### Privacy policy
|
|
237
|
+
|
|
238
|
+
```python
|
|
239
|
+
result = client.compliance.generate_privacy_policy(
|
|
240
|
+
company_name="شركة تقنية سعودية",
|
|
241
|
+
service_type="منصة SaaS",
|
|
242
|
+
data_collected=["الاسم", "الهاتف", "البريد الإلكتروني", "بيانات الاستخدام"],
|
|
243
|
+
data_purposes=["تشغيل الخدمة", "التحقق", "الدعم", "الأمن"],
|
|
244
|
+
third_party_sharing=False,
|
|
245
|
+
international_transfers=False,
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
print(result.policy_text)
|
|
249
|
+
print(result.pdpl_compliance_score)
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### Demand letter
|
|
253
|
+
|
|
254
|
+
```python
|
|
255
|
+
result = client.compliance.demand_letter(
|
|
256
|
+
sender_name="شركة ألف",
|
|
257
|
+
recipient_name="شركة باء",
|
|
258
|
+
claim_type="مستحقات تعاقدية",
|
|
259
|
+
claim_amount=85000,
|
|
260
|
+
incident_description="تأخر في سداد مستحقات عقد خدمات تقنية.",
|
|
261
|
+
deadline_days=7,
|
|
262
|
+
threat_of_action="سيتم اتخاذ الإجراءات القانونية المناسبة عند عدم السداد.",
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
print(result.letter_text)
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### HR policy
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
result = client.policies.generate_hr_policy(
|
|
272
|
+
policy_type="الغياب والانضباط",
|
|
273
|
+
company_name="شركة تجريبية",
|
|
274
|
+
industry="خدمات تقنية",
|
|
275
|
+
employee_count=45,
|
|
276
|
+
custom_requirements=["اعتماد التدرج التأديبي", "تحديد آلية التوثيق"],
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
print(result.policy_text)
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Job description
|
|
283
|
+
|
|
284
|
+
```python
|
|
285
|
+
result = client.policies.job_description(
|
|
286
|
+
job_title="أخصائي التزام",
|
|
287
|
+
department="الشؤون القانونية",
|
|
288
|
+
required_experience_years=2,
|
|
289
|
+
required_education="بكالوريوس قانون",
|
|
290
|
+
key_responsibilities=["إعداد التقارير", "متابعة السياسات", "مراجعة المخاطر"],
|
|
291
|
+
required_skills=["التحليل", "صياغة السياسات", "المراجعة القانونية"],
|
|
292
|
+
saudization_preferred=True,
|
|
293
|
+
)
|
|
294
|
+
|
|
295
|
+
print(result.job_description_text)
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## 9. Async Is Free in This Edition
|
|
299
|
+
|
|
300
|
+
```python
|
|
301
|
+
import asyncio
|
|
302
|
+
|
|
303
|
+
from qanuni import LegalClient
|
|
304
|
+
|
|
305
|
+
client = LegalClient(api_key="sk-...")
|
|
306
|
+
|
|
307
|
+
|
|
308
|
+
async def main() -> None:
|
|
309
|
+
result = await client.drafting.aimprove(
|
|
310
|
+
original_text="يدفع الطرف الأول عند الإنجاز.",
|
|
311
|
+
improvement_goals=["precision", "clarity"],
|
|
312
|
+
context="service agreement",
|
|
313
|
+
)
|
|
314
|
+
print(result.improved_text)
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
asyncio.run(main())
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
## 10. Local Mocked Exploration Without OpenAI
|
|
321
|
+
|
|
322
|
+
The package ships `examples.py` as a mini lab:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
qanuni-examples --list
|
|
326
|
+
qanuni-examples --category mocked_local
|
|
327
|
+
qanuni-examples labor_end_of_service
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
This is useful when you want to:
|
|
331
|
+
|
|
332
|
+
- explore outputs
|
|
333
|
+
- verify installation
|
|
334
|
+
- write docs
|
|
335
|
+
- test the package without API cost
|
|
336
|
+
|
|
337
|
+
## 11. Common Faulty Scenarios
|
|
338
|
+
|
|
339
|
+
### Missing OpenAI key
|
|
340
|
+
|
|
341
|
+
```python
|
|
342
|
+
from qanuni import LegalClient
|
|
343
|
+
|
|
344
|
+
client = LegalClient()
|
|
345
|
+
|
|
346
|
+
client.drafting.improve(
|
|
347
|
+
original_text="هذا نص يحتاج تحسينًا.",
|
|
348
|
+
improvement_goals=["clarity"],
|
|
349
|
+
context="contract",
|
|
350
|
+
)
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Expected result:
|
|
354
|
+
|
|
355
|
+
- provider configuration error because no `OPENAI_API_KEY` was configured
|
|
356
|
+
|
|
357
|
+
### Mixed input styles
|
|
358
|
+
|
|
359
|
+
```python
|
|
360
|
+
client.drafting.improve(
|
|
361
|
+
{"original_text": "نص أولي"},
|
|
362
|
+
original_text="نص آخر",
|
|
363
|
+
improvement_goals=["clarity"],
|
|
364
|
+
context="memo",
|
|
365
|
+
)
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Expected result:
|
|
369
|
+
|
|
370
|
+
- `QANUNI_VALIDATION_INPUT_CONFLICT`
|
|
371
|
+
|
|
372
|
+
### Missing contract source
|
|
373
|
+
|
|
374
|
+
```python
|
|
375
|
+
client.contracts.gap_analysis(contract_type="service_agreement")
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Expected result:
|
|
379
|
+
|
|
380
|
+
- `QANUNI_VALIDATION_DOCUMENT_SOURCE_MISSING`
|
|
381
|
+
|
|
382
|
+
## 12. YAML Configuration
|
|
383
|
+
|
|
384
|
+
You can load the client from `.qanuni.yaml`:
|
|
385
|
+
|
|
386
|
+
```yaml
|
|
387
|
+
openai:
|
|
388
|
+
api_key: "sk-..."
|
|
389
|
+
model: "gpt-5.5"
|
|
390
|
+
|
|
391
|
+
locale:
|
|
392
|
+
language: "ar"
|
|
393
|
+
jurisdiction: "SA"
|
|
394
|
+
|
|
395
|
+
performance:
|
|
396
|
+
timeout: 90
|
|
397
|
+
max_retries: 2
|
|
398
|
+
|
|
399
|
+
tools:
|
|
400
|
+
drafting.improve:
|
|
401
|
+
max_output_tokens: 1800
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Then:
|
|
405
|
+
|
|
406
|
+
```python
|
|
407
|
+
from qanuni import LegalClient
|
|
408
|
+
|
|
409
|
+
client = LegalClient.from_config(".qanuni.yaml")
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## 13. Full First Session Suggestion
|
|
413
|
+
|
|
414
|
+
If you are new to the SDK, use this order:
|
|
415
|
+
|
|
416
|
+
1. Install `qanuni-sdk` if you are testing the published package.
|
|
417
|
+
2. If you are still inside the repository before release, run `%pip install -e .` from `free_edition`.
|
|
418
|
+
3. Run `qanuni-examples --list`.
|
|
419
|
+
4. Run `qanuni-examples --category mocked_local`.
|
|
420
|
+
5. Add your `OPENAI_API_KEY` through `.env`.
|
|
421
|
+
6. Try `drafting.improve`.
|
|
422
|
+
7. Try `contracts.gap_analysis`.
|
|
423
|
+
8. Integrate the returned structured outputs into your app.
|
|
424
|
+
|
|
425
|
+
## 14. Maintainer Note
|
|
426
|
+
|
|
427
|
+
This free distribution is designed to keep the same PyPI project name `qanuni-sdk`, but it must be published as a **new version**, not by re-uploading the old one. See [docs/guides/README_PUBLISHING.md](docs/guides/README_PUBLISHING.md).
|
qanuni_sdk-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 BandAI
|
|
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,115 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qanuni-sdk
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Arabic-first free legal intelligence SDK for Saudi-focused legal workflows.
|
|
5
|
+
Author: BandAI
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Keywords: arabic,compliance,legal,openai,saudi,sdk
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Classifier: Typing :: Typed
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Requires-Dist: jinja2>=3.1.4
|
|
20
|
+
Requires-Dist: openai<3.0.0,>=2.0.0
|
|
21
|
+
Requires-Dist: pydantic-settings>=2.3.4
|
|
22
|
+
Requires-Dist: pydantic>=2.8.2
|
|
23
|
+
Requires-Dist: pyyaml>=6.0.2
|
|
24
|
+
Provides-Extra: cli
|
|
25
|
+
Requires-Dist: rich>=13.7.1; extra == 'cli'
|
|
26
|
+
Requires-Dist: typer>=0.12.3; extra == 'cli'
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: build>=1.2.2.post1; extra == 'dev'
|
|
29
|
+
Requires-Dist: mypy>=1.11.1; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: pytest>=8.3.2; extra == 'dev'
|
|
32
|
+
Requires-Dist: ruff>=0.6.1; extra == 'dev'
|
|
33
|
+
Requires-Dist: twine>=6.1.0; extra == 'dev'
|
|
34
|
+
Provides-Extra: pdf
|
|
35
|
+
Requires-Dist: pdfplumber>=0.11.4; extra == 'pdf'
|
|
36
|
+
Provides-Extra: release
|
|
37
|
+
Requires-Dist: build>=1.2.2.post1; extra == 'release'
|
|
38
|
+
Requires-Dist: twine>=6.1.0; extra == 'release'
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
# Qanuni SDK
|
|
42
|
+
|
|
43
|
+
Qanuni is an Arabic-first Python SDK for Saudi legal workflows.
|
|
44
|
+
|
|
45
|
+
This build is the **fully free distribution**:
|
|
46
|
+
|
|
47
|
+
- no activation
|
|
48
|
+
- no license token
|
|
49
|
+
- no premium gate
|
|
50
|
+
- all shipped tools are available immediately
|
|
51
|
+
|
|
52
|
+
Users bring their own OpenAI API key for prompt-backed tools. Deterministic tools such as Saudi labor calculations work without OpenAI.
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install qanuni-sdk
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Quickstart
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from qanuni import LegalClient
|
|
64
|
+
|
|
65
|
+
client = LegalClient(api_key="sk-...")
|
|
66
|
+
|
|
67
|
+
benefit = client.labor.end_of_service(
|
|
68
|
+
monthly_salary=12000,
|
|
69
|
+
years_of_service=7.5,
|
|
70
|
+
termination_reason="resignation",
|
|
71
|
+
contract_type="indefinite",
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
print(benefit.total_amount)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from qanuni import LegalClient
|
|
79
|
+
|
|
80
|
+
client = LegalClient(api_key="sk-...")
|
|
81
|
+
|
|
82
|
+
result = client.contracts.gap_analysis(
|
|
83
|
+
contract_text="يلتزم الطرف الثاني بتنفيذ الأعمال، ويتم السداد لاحقًا."
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
print(result.summary)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Included Tools
|
|
90
|
+
|
|
91
|
+
- `labor.end_of_service`
|
|
92
|
+
- `labor.probation_check`
|
|
93
|
+
- `contracts.gap_analysis`
|
|
94
|
+
- `contracts.generate_nda`
|
|
95
|
+
- `contracts.generate_mou`
|
|
96
|
+
- `drafting.improve`
|
|
97
|
+
- `drafting.summarize`
|
|
98
|
+
- `drafting.simplify`
|
|
99
|
+
- `compliance.generate_privacy_policy`
|
|
100
|
+
- `compliance.demand_letter`
|
|
101
|
+
- `policies.generate_hr_policy`
|
|
102
|
+
- `policies.job_description`
|
|
103
|
+
|
|
104
|
+
## Examples Command
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
qanuni-examples --list
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Default Behavior
|
|
111
|
+
|
|
112
|
+
- Arabic-first prompts and outputs
|
|
113
|
+
- Saudi-oriented legal framing
|
|
114
|
+
- structured Pydantic outputs
|
|
115
|
+
- async methods available in this free build
|