Scrapes the official exchange rate bulletins from cb.gov.sy, downloads the daily PDF, runs OCR on it, and exposes the structured data through a clean REST API.
GET /rates → scrape listing page → find latest PDF URL
→ check disk/memory cache (avoid re-OCR)
→ download PDF (only if not cached)
→ convert PDF page → image (pdf2image / poppler)
→ OCR (pytesseract / Tesseract with eng+ara)
→ parse structured rates
→ return JSON + cache to disk
- Two-level cache: in-memory dict + JSON files on disk. A PDF is downloaded and OCR'd at most once per day per bulletin.
- Only one HTTP request to the listing page per API call (if data is already cached, the PDF is never re-fetched).
- No headless browser needed – pure
httpx+BeautifulSoup. - Respects standard
User-Agent/Refererheaders.
| Tool | Purpose |
|---|---|
| Tesseract OCR | OCR engine |
| tesseract-lang-ara | Arabic language pack |
| poppler-utils | PDF → image conversion |
sudo apt-get install -y tesseract-ocr tesseract-ocr-ara poppler-utilsbrew install tesseract tesseract-lang poppler- Tesseract: https://github.com/UB-Mannheim/tesseract/wiki
- Poppler: https://github.com/oschwartz10612/poppler-windows/releases
# Clone / copy files
cd syria_exchange_api
# Create a virtual environment (optional but recommended)
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
# Install Python dependencies
pip install -r requirements.txt
# Start the server
uvicorn main:app --host 0.0.0.0 --port 8000 --reloadOpen http://localhost:8000/docs for the interactive Swagger UI.
Returns the latest available exchange rates (parsed from today's or the most recent PDF).
Response example:
{
"bulletin_date": "2026-02-26",
"effective_date": "26/02/2026",
"bulletin_no": "40",
"pdf_url": "https://cb.gov.sy/downloads/files/1772090643.PDF",
"scraped_at": "2026-02-27T10:00:00Z",
"rates": [
{
"currency": "Us Dollar",
"code": "USD",
"old_lira": { "sell": 11100.0, "buy": 11000.0 },
"new_lira": { "sell": 111.0, "buy": 110.0 }
},
...
]
}Alias for /rates.
Fetch rates for a specific bulletin date (format: YYYY-MM-DD).
GET /rates/2026-02-25
Get a single currency's latest rate.
GET /rates/latest/USD
GET /rates/latest/EUR
Returns the list of all available bulletins shown on the website's first page (date, USD sell/buy, PDF URL).
Clears the in-memory cache (disk cache is preserved).
| Layer | TTL | Storage |
|---|---|---|
| In-memory dict | Until process restart | RAM |
| Disk JSON files | Permanent | ./cache/*.json |
On each API call the system checks memory → disk → scrape. This means on a typical server a bulletin is only OCR'd once regardless of how many API consumers hit it.
- The PDF is a static scanned image — standard PDF text extraction won't work. Tesseract OCR with the
eng+aralanguage pack is required. - The site paginates; this API only scrapes the first page (most recent ~30 bulletins). For historical data, extend
fetch_listing_page()to iterate pages. - Rate parsing uses known English currency names from the PDF. If OCR quality is poor, increase
dpiinocr_pdf()(default 200).