# القوائم

> صفحات من الجهات بفلاتر، وبطاقة لكل جهة.

المصدر: https://new.wasmenia.com/developers/products/list

صفحات من الجهات بفلاتر تجتمع: الدولة، والقطاع، والصناعة، ونوع الجهة، وحكومية أو خاصة، والموثّقة، وما يتوفر لها من ملفات، وسنة الهوية، ومجموعة عامة، بالترتيب الذي تختاره. لكل جهة بطاقة جاهزة للعرض، والقائمة كلها لا تُحسب سحبًا.

- `GET https://new.wasmenia.com/api/v1/brands`

- **يُحسب سحبًا**: لا
- **الصفحة**: حتى 50 جهة، و500 صفحة
- **الحد**: 60 في الدقيقة بلا مفتاح
- **قيمة غير صالحة**: تُتجاهل كأنها لم تُرسل

## ما يعطيك

### فلاتر تجتمع

الدولة والقطاع ونوع الجهة والتوثيق والملفات معًا، وأكثر من دولة بفاصلة.

### ترتيب تختاره

الأحدث، أو المحدَّثة مؤخرًا، أو الأكثر تحميلًا، أو أبجديًا.

### بطاقة جاهزة

المعرّف والاسم والدولة والقطاع والتوثيق وعدد النسخ والصورة المصغّرة.

### صفحات معروفة

`total` و`pageCount` لترقيم الصفحات من أول طلب.

### نسخة عندك

امشِ على الصفحات كلها لتبني قائمة وبحثًا عندك، بلا سحوبات.

### التحديث اليومي

`sort=updated` يعطيك ما تغيّر أولًا، فتتوقف حين تصل إلى ما قرأته.

## الفلاتر

| المعامل | مثال |
| --- | --- |
| `country` | `SA`، أو `SA,AE` |
| `category` | معرّف القطاع، ويشمل المتفرع منه |
| `entityType` | `government`، `private_company`… |
| `sector` | `government` أو `private` |
| `verified` | `1` للموثّقة |
| `has` | `svg` أو `png` أو `pdf` أو `guidelines` |
| `collection` | معرّف مجموعة عامة |
| `sort` | `newest`، `updated`، `downloads`، `alpha_ar`… |

القيمة غير الصالحة تُتجاهل كأنها لم تُرسل. كل المعاملات في [مرجع القائمة](https://new.wasmenia.com/developers/docs/reference/brands-list.md#brands-list).

## كيف تستخدمه

### خذ مفتاحًا

افتح حساب مطور من لوحة المطورين وأنشئ مفتاحًا. الباقة المجانية تكفي للبداية، والمفتاح يبقى على خادمك في متغير بيئة.

### ابنِ العنوان من الفلاتر

كل فلتر معامل في العنوان، وما لا تحتاجه لا ترسله.

### اعرض البطاقات

كل عنصر في `items` يكفي لبطاقة: لا تقرأ السجل لكل بطاقة.

### رقّم الصفحات

`page` و`pageCount`، و`total` لعدد النتائج.

### اقرأ السجل حين تُفتح البطاقة

للألوان والموقع والنسخ، سحب واحد حين يفتحها المستخدم.

## صفحة من الدليل

`directory.js`

```javascript
const base = 'https://new.wasmenia.com';

/** One page of a directory: Saudi brands with an SVG logo, newest first. */
export async function directoryPage(page = 1) {
  const url = new URL('/api/v1/brands', base);
  url.searchParams.set('country', 'SA');
  url.searchParams.set('has', 'svg');
  url.searchParams.set('limit', '24'); // up to 50
  url.searchParams.set('page', String(page));

  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.WASMENIA_API_KEY}` },
  });
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const { total, pageCount, items } = await res.json();
  // pageCount is 0 when nothing matches.
  return { total, pageCount, items };
}
```

```python
import os

import requests

def directory_page(page=1):
    res = requests.get(
        'https://new.wasmenia.com/api/v1/brands',
        params={'country': 'SA', 'has': 'svg', 'limit': 24, 'page': page},
        headers={'Authorization': f"Bearer {os.environ['WASMENIA_API_KEY']}"},
        timeout=10,
    )
    res.raise_for_status()
    data = res.json()
    return data['total'], data['pageCount'], data['items']
```

## المرور على القائمة كلها

`walk.js`

```javascript
// Every card of the archive, page by page. Lists are not pulls.
const base = 'https://new.wasmenia.com';
const headers = { Authorization: `Bearer ${process.env.WASMENIA_API_KEY}` };
const sleep = (s) => new Promise((r) => setTimeout(r, s * 1000));

export async function* allBrands(filters = {}) {
  for (let page = 1; ; page++) {
    const url = new URL('/api/v1/brands', base);
    for (const [k, v] of Object.entries({ ...filters, limit: 50, page }))
      url.searchParams.set(k, String(v));
    const res = await fetch(url, { headers });
    if (res.status === 429) {
      await sleep(Number(res.headers.get('Retry-After') ?? 60));
      page--; // the same page again
      continue;
    }
    if (!res.ok) throw new Error(`HTTP ${res.status}`);
    const { items, pageCount } = await res.json();
    yield* items; // { slug, name, country, category, verified, versions, thumbnailUrl, url }
    if (page >= pageCount || page >= 500) return;
  }
}

for await (const brand of allBrands({ country: 'SA' })) {
  await db.cards.upsert(brand.slug, brand);
}
```

`walk.py`

```python
import os
import time

import requests

BASE = 'https://new.wasmenia.com'
HEADERS = {'Authorization': f"Bearer {os.environ['WASMENIA_API_KEY']}"}

def all_brands(**filters):
    page = 1
    while True:
        res = requests.get(
            f'{BASE}/api/v1/brands',
            params={**filters, 'limit': 50, 'page': page},
            headers=HEADERS,
            timeout=10,
        )
        if res.status_code == 429:
            time.sleep(int(res.headers.get('Retry-After', 60)))
            continue
        res.raise_for_status()
        data = res.json()
        yield from data['items']
        if page >= data['pageCount'] or page >= 500:
            return
        page += 1
```

## أسئلة

### القائمة أطول من حد الصفحات

أقصى ما تمر عليه القائمة بفلاتر واحدة 25,000 جهة. قسّم المرور بفلتر: دولة بعد دولة، أو قطاعًا بعد قطاع.

### هل في البطاقة ألوان الجهة؟

لا. البطاقة للقائمة، والألوان والموقع والنسخ في السجل.

### ماذا في `category` في البطاقة؟

اسم القطاع للعرض. للفلترة استخدم معرّف القطاع في المعامل `category`.

**نسخة من الأرشيف عندك**

القائمة كاملة بلا سحوبات، والسجل حين تحتاجه، وتحديث يومي.

[اقرأ الدليل](https://new.wasmenia.com/developers/docs/guides/sync.md)
