EGYADMIN commited on
Commit
1cb1f72
·
verified ·
1 Parent(s): c976442

Create utils/api_integrations.py

Browse files
Files changed (1) hide show
  1. utils/api_integrations.py +615 -0
utils/api_integrations.py ADDED
@@ -0,0 +1,615 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import requests
4
+ from typing import Dict, List, Any, Union, Tuple, Optional
5
+ from datetime import datetime
6
+
7
+ class MunafasatAPI:
8
+ """
9
+ فئة للاتصال بمنصة المنافسات والمشتريات الحكومية
10
+ """
11
+
12
+ def __init__(self, api_key: str = None):
13
+ """
14
+ تهيئة الاتصال بمنصة المنافسات
15
+
16
+ المعاملات:
17
+ ----------
18
+ api_key : str, optional
19
+ مفتاح API (يمكن تعيينه لاحقاً أو استخدام المفتاح من متغيرات البيئة)
20
+ """
21
+ self.api_key = api_key or os.getenv("MUNAFASAT_API_KEY")
22
+ self.base_url = "https://api.etimad.sa/munafasat/v1" # عنوان API افتراضي
23
+
24
+ # التحقق من توفر مفتاح API
25
+ if not self.api_key:
26
+ print("Warning: MUNAFASAT_API_KEY not provided. Some functions might not work.")
27
+
28
+ def get_tenders(self, params: Dict[str, Any] = None) -> Dict[str, Any]:
29
+ """
30
+ الحصول على قائمة المناقصات
31
+
32
+ المعاملات:
33
+ ----------
34
+ params : Dict[str, Any], optional
35
+ معاملات البحث والتصفية
36
+
37
+ المخرجات:
38
+ --------
39
+ Dict[str, Any]
40
+ نتائج البحث
41
+ """
42
+ # في التطبيق الفعلي، سيتم استدعاء API
43
+ # هنا نستخدم بيانات افتراضية للتوضيح
44
+
45
+ # إعداد رأس الطلب
46
+ headers = {
47
+ "Authorization": f"Bearer {self.api_key}",
48
+ "Content-Type": "application/json"
49
+ }
50
+
51
+ try:
52
+ # إرسال طلب GET للحصول على المناقصات
53
+ # response = requests.get(f"{self.base_url}/tenders", headers=headers, params=params)
54
+ # return response.json()
55
+
56
+ # استخدام بيانات افتراضية للتوضيح
57
+ return {
58
+ "success": True,
59
+ "data": [
60
+ {
61
+ "id": "T001",
62
+ "title": "إنشاء مبنى إداري لوزارة الصحة",
63
+ "tender_type": "مناقصة عامة",
64
+ "sector": "الإنشاءات",
65
+ "agency": "وزارة الصحة",
66
+ "publication_date": "2023-09-01",
67
+ "submission_deadline": "2023-10-01",
68
+ "estimated_value": 15000000,
69
+ "status": "نشطة"
70
+ },
71
+ {
72
+ "id": "T002",
73
+ "title": "تطوير نظام إدارة المستشفيات المركزي",
74
+ "tender_type": "مناقصة عامة",
75
+ "sector": "تقنية المعلومات",
76
+ "agency": "وزارة الصحة",
77
+ "publication_date": "2023-08-15",
78
+ "submission_deadline": "2023-09-15",
79
+ "estimated_value": 8000000,
80
+ "status": "مغلقة"
81
+ },
82
+ {
83
+ "id": "T003",
84
+ "title": "توريد وتركيب أجهزة طبية لمستشفيات المنطقة الشرقية",
85
+ "tender_type": "مناقصة محدودة",
86
+ "sector": "الصحة",
87
+ "agency": "وزارة الصحة",
88
+ "publication_date": "2023-09-10",
89
+ "submission_deadline": "2023-10-10",
90
+ "estimated_value": 12000000,
91
+ "status": "نشطة"
92
+ }
93
+ ],
94
+ "meta": {
95
+ "total": 3,
96
+ "page": 1,
97
+ "per_page": 10
98
+ }
99
+ }
100
+ except Exception as e:
101
+ print(f"Error fetching tenders: {str(e)}")
102
+ return {
103
+ "success": False,
104
+ "error": str(e)
105
+ }
106
+
107
+ def get_tender_details(self, tender_id: str) -> Dict[str, Any]:
108
+ """
109
+ الحصول على تفاصيل مناقصة محددة
110
+
111
+ المعاملات:
112
+ ----------
113
+ tender_id : str
114
+ معرف المناقصة
115
+
116
+ المخرجات:
117
+ --------
118
+ Dict[str, Any]
119
+ تفاصيل المناقصة
120
+ """
121
+ # في التطبيق الفعلي، سيتم استدعاء API
122
+ # هنا نستخدم بيانات افتراضية للتوضيح
123
+
124
+ # إعداد رأس الطلب
125
+ headers = {
126
+ "Authorization": f"Bearer {self.api_key}",
127
+ "Content-Type": "application/json"
128
+ }
129
+
130
+ try:
131
+ # إرسال طلب GET للحصول على تفاصيل المناقصة
132
+ # response = requests.get(f"{self.base_url}/tenders/{tender_id}", headers=headers)
133
+ # return response.json()
134
+
135
+ # استخدام بيانات افتراضية للتوضيح
136
+ if tender_id == "T001":
137
+ return {
138
+ "success": True,
139
+ "data": {
140
+ "id": "T001",
141
+ "title": "إنشاء مبنى إداري لوزارة الصحة",
142
+ "description": "إنشاء مبنى إداري من 5 طوابق بمساحة إجمالية 10000 متر مربع في مدينة الرياض",
143
+ "tender_type": "مناقصة عامة",
144
+ "sector": "الإنشاءات",
145
+ "agency": "وزارة الصحة",
146
+ "publication_date": "2023-09-01",
147
+ "submission_deadline": "2023-10-01",
148
+ "implementation_duration": "24 شهر",
149
+ "estimated_value": 15000000,
150
+ "required_classification": "مباني - الدرجة الثانية",
151
+ "local_content_requirements": "40% كحد أدنى",
152
+ "status": "نشطة",
153
+ "documents": [
154
+ {"name": "كراسة الشروط والمواصفات", "type": "pdf"},
155
+ {"name": "المخططات", "type": "dwg"},
156
+ {"name": "جدول الكميات", "type": "xlsx"}
157
+ ],
158
+ "milestones": [
159
+ {"name": "الاجتماع التمهيدي", "date": "2023-09-15"},
160
+ {"name": "آخر موعد للاستفسارات", "date": "2023-09-20"},
161
+ {"name": "فتح المظاريف", "date": "2023-10-05"}
162
+ ]
163
+ }
164
+ }
165
+ else:
166
+ return {
167
+ "success": False,
168
+ "error": "Tender not found"
169
+ }
170
+ except Exception as e:
171
+ print(f"Error fetching tender details: {str(e)}")
172
+ return {
173
+ "success": False,
174
+ "error": str(e)
175
+ }
176
+
177
+ def submit_bid(self, tender_id: str, bid_data: Dict[str, Any]) -> Dict[str, Any]:
178
+ """
179
+ تقديم عرض لمناقصة
180
+
181
+ المعاملات:
182
+ ----------
183
+ tender_id : str
184
+ معرف المناقصة
185
+ bid_data : Dict[str, Any]
186
+ بيانات العرض
187
+
188
+ المخرجات:
189
+ --------
190
+ Dict[str, Any]
191
+ نتيجة تقديم العرض
192
+ """
193
+ # في التطبيق الفعلي، سيتم استدعاء API
194
+ # هنا نستخدم بيانات افتراضية للتوضيح
195
+
196
+ # إعداد رأس الطلب
197
+ headers = {
198
+ "Authorization": f"Bearer {self.api_key}",
199
+ "Content-Type": "application/json"
200
+ }
201
+
202
+ try:
203
+ # إرسال طلب POST لتقديم العرض
204
+ # response = requests.post(f"{self.base_url}/tenders/{tender_id}/bids", headers=headers, json=bid_data)
205
+ # return response.json()
206
+
207
+ # استخدام بيانات افتراضية للتوضيح
208
+ return {
209
+ "success": True,
210
+ "data": {
211
+ "bid_id": "B001",
212
+ "tender_id": tender_id,
213
+ "submission_date": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
214
+ "status": "تم التقديم بنجاح"
215
+ }
216
+ }
217
+ except Exception as e:
218
+ print(f"Error submitting bid: {str(e)}")
219
+ return {
220
+ "success": False,
221
+ "error": str(e)
222
+ }
223
+
224
+
225
+ class EtimadAPI:
226
+ """
227
+ فئة للاتصال بمنصة اعتماد
228
+ """
229
+
230
+ def __init__(self, api_key: str = None):
231
+ """
232
+ تهيئة الاتصال بمنصة اعتماد
233
+
234
+ المعاملات:
235
+ ----------
236
+ api_key : str, optional
237
+ مفتاح API (يمكن تعيينه لاحقاً أو استخدام المفتاح من متغيرات البيئة)
238
+ """
239
+ self.api_key = api_key or os.getenv("ETIMAD_API_KEY")
240
+ self.base_url = "https://api.etimad.sa/v1" # عنوان API افتراضي
241
+
242
+ # التحقق من توفر مفتاح API
243
+ if not self.api_key:
244
+ print("Warning: ETIMAD_API_KEY not provided. Some functions might not work.")
245
+
246
+ def verify_supplier(self, cr_number: str) -> Dict[str, Any]:
247
+ """
248
+ التحقق من بيانات مورد
249
+
250
+ ال��عاملات:
251
+ ----------
252
+ cr_number : str
253
+ رقم السجل التجاري
254
+
255
+ المخرجات:
256
+ --------
257
+ Dict[str, Any]
258
+ بيانات المورد
259
+ """
260
+ # في التطبيق الفعلي، سيتم استدعاء API
261
+ # هنا نستخدم بيانات افتراضية للتوضيح
262
+
263
+ # إعداد رأس الطلب
264
+ headers = {
265
+ "Authorization": f"Bearer {self.api_key}",
266
+ "Content-Type": "application/json"
267
+ }
268
+
269
+ try:
270
+ # إرسال طلب GET للتحقق من بيانات المورد
271
+ # response = requests.get(f"{self.base_url}/suppliers/{cr_number}", headers=headers)
272
+ # return response.json()
273
+
274
+ # استخدام بيانات افتراضية للتوضيح
275
+ if cr_number == "1010000000":
276
+ return {
277
+ "success": True,
278
+ "data": {
279
+ "cr_number": "1010000000",
280
+ "company_name": "شركة الإنشاءات السعودية",
281
+ "establishment_date": "2010-01-01",
282
+ "company_type": "ذات مسؤولية محدودة",
283
+ "owner_name": "محمد عبدالله",
284
+ "sector": "الإنشاءات",
285
+ "status": "نشط",
286
+ "classification": {
287
+ "category": "مباني",
288
+ "level": "الدرجة الأولى"
289
+ },
290
+ "local_content_certificate": {
291
+ "status": "معتمد",
292
+ "percentage": 65,
293
+ "expiry_date": "2024-12-31"
294
+ },
295
+ "financial_status": {
296
+ "credit_rating": "A",
297
+ "liquid_assets": 5000000
298
+ }
299
+ }
300
+ }
301
+ else:
302
+ return {
303
+ "success": False,
304
+ "error": "Supplier not found"
305
+ }
306
+ except Exception as e:
307
+ print(f"Error verifying supplier: {str(e)}")
308
+ return {
309
+ "success": False,
310
+ "error": str(e)
311
+ }
312
+
313
+ def get_local_content_certificate(self, cr_number: str) -> Dict[str, Any]:
314
+ """
315
+ الحصول على شهادة المحتوى المحلي
316
+
317
+ المعاملات:
318
+ ----------
319
+ cr_number : str
320
+ رقم السجل التجاري
321
+
322
+ المخرجات:
323
+ --------
324
+ Dict[str, Any]
325
+ بيانات شهادة المحتوى المحلي
326
+ """
327
+ # في التطبيق الفعلي، سيتم استدعاء API
328
+ # هنا نستخدم بيانات افتراضية للتوضيح
329
+
330
+ # إعداد رأس الطلب
331
+ headers = {
332
+ "Authorization": f"Bearer {self.api_key}",
333
+ "Content-Type": "application/json"
334
+ }
335
+
336
+ try:
337
+ # إرسال طلب GET للحصول على شهادة المحتوى المحلي
338
+ # response = requests.get(f"{self.base_url}/local-content/{cr_number}", headers=headers)
339
+ # return response.json()
340
+
341
+ # استخدام بيانات افتراضية للتوضيح
342
+ if cr_number == "1010000000":
343
+ return {
344
+ "success": True,
345
+ "data": {
346
+ "cr_number": "1010000000",
347
+ "company_name": "شركة الإنشاءات السعودية",
348
+ "certificate_number": "LC-2023-1234",
349
+ "issue_date": "2023-01-01",
350
+ "expiry_date": "2024-12-31",
351
+ "percentage": 65,
352
+ "status": "معتمد",
353
+ "details": {
354
+ "manpower": {
355
+ "saudi_percentage": 55,
356
+ "score": 16.5
357
+ },
358
+ "local_materials": {
359
+ "percentage": 70,
360
+ "score": 35.0
361
+ },
362
+ "local_services": {
363
+ "percentage": 45,
364
+ "score": 13.5
365
+ }
366
+ }
367
+ }
368
+ }
369
+ else:
370
+ return {
371
+ "success": False,
372
+ "error": "Local content certificate not found"
373
+ }
374
+ except Exception as e:
375
+ print(f"Error fetching local content certificate: {str(e)}")
376
+ return {
377
+ "success": False,
378
+ "error": str(e)
379
+ }
380
+
381
+
382
+ class BaladyAPI:
383
+ """
384
+ فئة للاتصال بمنصة بلدي
385
+ """
386
+
387
+ def __init__(self, api_key: str = None):
388
+ """
389
+ تهيئة الاتصال بمنصة بلدي
390
+
391
+ المعاملات:
392
+ ----------
393
+ api_key : str, optional
394
+ مفتاح API (يمكن تعيينه لاحقاً أو استخدام المفتاح من متغيرات البيئة)
395
+ """
396
+ self.api_key = api_key or os.getenv("BALADY_API_KEY")
397
+ self.base_url = "https://api.balady.gov.sa/v1" # عنوان API افتراضي
398
+
399
+ # التحقق من توفر مفتاح API
400
+ if not self.api_key:
401
+ print("Warning: BALADY_API_KEY not provided. Some functions might not work.")
402
+
403
+ def get_location_info(self, location_id: str) -> Dict[str, Any]:
404
+ """
405
+ الحصول على معلومات موقع
406
+
407
+ المعاملات:
408
+ ----------
409
+ location_id : str
410
+ معرف الموقع
411
+
412
+ المخرجات:
413
+ --------
414
+ Dict[str, Any]
415
+ معلومات الموقع
416
+ """
417
+ # في التطبيق الفعلي، سيتم استدعاء API
418
+ # هنا نستخدم بيانات افتراضية للتوضيح
419
+
420
+ # إعداد رأس الطلب
421
+ headers = {
422
+ "Authorization": f"Bearer {self.api_key}",
423
+ "Content-Type": "application/json"
424
+ }
425
+
426
+ try:
427
+ # إرسال طلب GET للحصول على معلومات الموقع
428
+ # response = requests.get(f"{self.base_url}/locations/{location_id}", headers=headers)
429
+ # return response.json()
430
+
431
+ # استخدام بيانات افتراضية للتوضيح
432
+ if location_id == "L001":
433
+ return {
434
+ "success": True,
435
+ "data": {
436
+ "location_id": "L001",
437
+ "name": "حي الملك فهد",
438
+ "municipality": "أمانة الرياض",
439
+ "city": "الرياض",
440
+ "coordinates": {
441
+ "latitude": 24.7136,
442
+ "longitude": 46.6753
443
+ },
444
+ "land_use": "تجاري وسكني",
445
+ "zoning": {
446
+ "type": "تجاري",
447
+ "max_height": "15 طابق",
448
+ "max_build_ratio": 60
449
+ },
450
+ "services": {
451
+ "water": True,
452
+ "electricity": True,
453
+ "sewage": True,
454
+ "internet": True
455
+ }
456
+ }
457
+ }
458
+ else:
459
+ return {
460
+ "success": False,
461
+ "error": "Location not found"
462
+ }
463
+ except Exception as e:
464
+ print(f"Error fetching location info: {str(e)}")
465
+ return {
466
+ "success": False,
467
+ "error": str(e)
468
+ }
469
+
470
+ def get_permit_requirements(self, project_type: str, location_id: str) -> Dict[str, Any]:
471
+ """
472
+ الحصول على متطلبات التصاريح
473
+
474
+ المعاملات:
475
+ ----------
476
+ project_type : str
477
+ نوع المشروع
478
+ location_id : str
479
+ معرف الموقع
480
+
481
+ المخرجات:
482
+ --------
483
+ Dict[str, Any]
484
+ متطلبات التصاريح
485
+ """
486
+ # في التطبيق الفعلي، سيتم استدعاء API
487
+ # هنا نستخدم بيانات افتراضية للتوضيح
488
+
489
+ # إعداد رأس الطلب
490
+ headers = {
491
+ "Authorization": f"Bearer {self.api_key}",
492
+ "Content-Type": "application/json"
493
+ }
494
+
495
+ # إعداد معاملات الطلب
496
+ params = {
497
+ "project_type": project_type,
498
+ "location_id": location_id
499
+ }
500
+
501
+ try:
502
+ # إرسال طلب GET للحصول على متطلبات التصاريح
503
+ # response = requests.get(f"{self.base_url}/permits/requirements", headers=headers, params=params)
504
+ # return response.json()
505
+
506
+ # استخدام بيانات افتراضية للتوضيح
507
+ if project_type == "مبنى تجاري" and location_id == "L001":
508
+ return {
509
+ "success": True,
510
+ "data": {
511
+ "project_type": "مبنى تجاري",
512
+ "location_id": "L001",
513
+ "required_documents": [
514
+ {"name": "صك الأرض", "mandatory": True},
515
+ {"name": "رخصة البناء", "mandatory": True},
516
+ {"name": "المخططات المعتمدة", "mandatory": True},
517
+ {"name": "تقرير التربة", "mandatory": True},
518
+ {"name": "موافقة الدفاع المدني", "mandatory": True},
519
+ {"name": "موافقة شركة الكهرباء", "mandatory": True},
520
+ {"name": "موافقة شركة المياه", "mandatory": True}
521
+ ],
522
+ "regulations": [
523
+ "الارتداد الأمامي لا يقل عن 5 متر",
524
+ "الارتداد الجانبي لا يقل عن 2 متر",
525
+ "الارتداد الخلفي لا يقل عن 3 متر",
526
+ "نسبة البناء لا تتجاوز 60% من مساحة الأرض",
527
+ "ارتفاع المبنى لا يتجاوز 15 طابق"
528
+ ],
529
+ "fees": [
530
+ {"name": "رسوم إصدار رخصة البناء", "amount": 5000},
531
+ {"name": "تأمين نظافة الموقع", "amount": 10000, "refundable": True}
532
+ ],
533
+ "processing_time": "30 يوم عمل"
534
+ }
535
+ }
536
+ else:
537
+ return {
538
+ "success": False,
539
+ "error": "Requirements not found for the specified project type and location"
540
+ }
541
+ except Exception as e:
542
+ print(f"Error fetching permit requirements: {str(e)}")
543
+ return {
544
+ "success": False,
545
+ "error": str(e)
546
+ }
547
+
548
+ def check_permit_status(self, permit_id: str) -> Dict[str, Any]:
549
+ """
550
+ التحقق من حالة تصريح
551
+
552
+ المعاملات:
553
+ ----------
554
+ permit_id : str
555
+ معرف التصريح
556
+
557
+ المخرجات:
558
+ --------
559
+ Dict[str, Any]
560
+ حالة التصريح
561
+ """
562
+ # في التطبيق الفعلي، سيتم استدعاء API
563
+ # هنا نستخدم بيانات افتراضية للتوضيح
564
+
565
+ # إعداد رأس الطلب
566
+ headers = {
567
+ "Authorization": f"Bearer {self.api_key}",
568
+ "Content-Type": "application/json"
569
+ }
570
+
571
+ try:
572
+ # إرسال طلب GET للتحقق من حالة التصريح
573
+ # response = requests.get(f"{self.base_url}/permits/{permit_id}/status", headers=headers)
574
+ # return response.json()
575
+
576
+ # استخدام بيانات افتراضية للتوضيح
577
+ if permit_id == "P001":
578
+ return {
579
+ "success": True,
580
+ "data": {
581
+ "permit_id": "P001",
582
+ "type": "رخصة بناء",
583
+ "status": "موافقة",
584
+ "issue_date": "2023-05-15",
585
+ "expiry_date": "2024-05-15",
586
+ "notes": "تم إصدار الرخصة بنجاح"
587
+ }
588
+ }
589
+ elif permit_id == "P002":
590
+ return {
591
+ "success": True,
592
+ "data": {
593
+ "permit_id": "P002",
594
+ "type": "رخصة بناء",
595
+ "status": "قيد المراجعة",
596
+ "submission_date": "2023-09-10",
597
+ "expected_completion_date": "2023-10-10",
598
+ "progress": 60,
599
+ "pending_approvals": [
600
+ "موافقة الدفاع المدني",
601
+ "موافقة شركة الكهرباء"
602
+ ]
603
+ }
604
+ }
605
+ else:
606
+ return {
607
+ "success": False,
608
+ "error": "Permit not found"
609
+ }
610
+ except Exception as e:
611
+ print(f"Error checking permit status: {str(e)}")
612
+ return {
613
+ "success": False,
614
+ "error": str(e)
615
+ }