Hurtownia danych o publicznych przetargach IT z miejscem realizacji w Polsce. ProcureScope pobiera ogłoszenia z TED, archiwizuje niezmienioną odpowiedź API, zapisuje uporządkowane rekordy w PostgreSQL i buduje modele analityczne przez dbt. Airflow uruchamia codzienny przyrost, a Metabase udostępnia gotowe zapytania do raportów.
To projekt portfolio do monitorowania i analizy danych. Nie składa ofert, nie jest poradą prawną i nie gwarantuje kompletności rynku. Każdy rekord prowadzi z powrotem do widoku źródłowego TED, jeśli rekord ma numer publikacji.
- klient TED Search API v3 z iteracyjnym pobieraniem, retry i zachowaniem stron;
- niezmienne pliki Bronze JSON oraz manifest z zapytaniem, czasem i SHA-256;
- tabela wersji ogłoszeń, historia przebiegów i kwarantanna błędnych rekordów;
- deterministyczne klucze i UPSERT, żeby ponowne uruchomienie nie tworzyło kopii;
- modele dbt dla szans IT, terminów, zamawiających, zmian źródłowych i pokrycia danych;
- harmonogram Airflow, lokalne środowisko Docker Compose i konfiguracja Metabase;
- dokumentacja architektury, modelu danych, obsługi, źródeł i przygotowania do rozmowy.
TED Search API v3 -> Python: pobieranie i walidacja -> MinIO: niezmienne odpowiedzi JSON
-> PostgreSQL: ogłoszenia i kwarantanna
Airflow: harmonogram -> Python -> dbt: modele analityczne -> Metabase: raporty
Przebieg zapisuje każdą odebraną stronę przed parsowaniem. Błąd parsera trafia do rejected_records, a źródłowy JSON pozostaje w Bronze. Archiwum umożliwia przyszłe ponowne parsowanie, ale wersja 0.1 nie udostępnia jeszcze polecenia reprocess. W razie przerwania pobrania przebieg otrzymuje status failed; rozpoczęte strony pozostają dostępne do audytu.
Wymagane są Docker Desktop z Compose v2 oraz dostęp do Internetu. W PowerShell, uruchomionym w katalogu repozytorium:
Copy-Item .env.example .env
Zmień hasła w .env przed startem. Po zmianie hasła PostgreSQL zaktualizuj POSTGRES_PASSWORD, DATABASE_URL i AIRFLOW__DATABASE__SQL_ALCHEMY_CONN w .env. Compose przekazuje hasło do Metabase i dbt. Po zmianie hasła MinIO zaktualizuj S3_SECRET_KEY.
Uruchom podstawowe usługi:
docker compose up --build -d
docker compose ps
Interfejsy lokalne:
| Usługa | Adres | Dane demo |
|---|---|---|
| Airflow | http://localhost:8080 | użytkownik i hasło z .env |
| Metabase | http://localhost:3000 | pierwsza konfiguracja w przeglądarce |
| MinIO Console | http://localhost:9001 | wartości MINIO_ROOT_USER i MINIO_ROOT_PASSWORD |
| PostgreSQL | localhost:5432 | baza procurescope |
W Airflow włącz DAG procurescope_daily, aby uruchomić harmonogram. Krótki import demonstracyjny można wykonać bez czekania na scheduler:
docker compose --profile manual run --rm ingest python -m procurescope.cli ingest --days 7
Pełny backfill około 18 miesięcy uruchom z --days 548.
Po pobraniu i zapisaniu danych zbuduj modele:
docker compose --profile manual run --rm dbt
Polecenie może pobrać duży zakres z TED. Krótszy, jawny zakres do pierwszego przebiegu:
docker compose --profile manual run --rm ingest python -m procurescope.cli ingest --days 14
Daty są włączne. API TED udostępnia publiczne wyszukiwanie bez klucza API. Repozytorium nie zawiera tokenów ani skopiowanych zbiorów TED.
Podczas konfiguracji Metabase dodaj bazę PostgreSQL:
- host: postgres
- port: 5432
- baza: procurescope
- użytkownik i hasło: z .env
- schemat: analytics (modele dbt) lub public (tabele źródłowe)
Gotowe zapytania znajdują się w metabase/questions.sql. Zapisz je w Metabase jako pytania SQL i dodaj do dashboardu: „Terminy”, „Aktywność zamawiających”, „Zmiany w TED”, „Pokrycie danych” i „Dostępne wyniki”. Repozytorium udostępnia zapytania i modele, ale nie automatycznie utworzony dashboard Metabase.
Do lokalnego uruchamiania poza Dockerem zainstaluj projekt i ustaw własne adresy PostgreSQL/MinIO w środowisku:
py -3.11 -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e .
$env:DATABASE_URL = "postgresql://procurescope:haslo@localhost:5432/procurescope"
$env:STORAGE_BACKEND = "local"
procurescope init-db
procurescope ingest --days 14
Quality gate w GitHub Actions uruchamia Ruff i sprawdza kompilację modułów Pythona. Kontrole danych dbt są opisane przy modelach; uruchamia je dbt build.
- Zakres domyślny to daty publikacji, rodzina CPV 72* i miejsce realizacji POL. Kraj zamawiającego pozostaje osobnym polem.
- publication-number, notice-identifier i wersja są przechowywane oddzielnie. Klucz rekordu budowany jest z identyfikatora źródła i wersji; bezpieczne połączenie ogłoszeń w jedno postępowanie korzysta wyłącznie z procedure_identifier.
- Rozstrzygnięcia są zachowane jako pola źródłowe, jeśli API je zwróci. Wartości szacunkowe i wartości udzielonych zamówień nie są sumowane. award_fields jest surowym podsumowaniem dostępnych pól wynikowych, a nie znormalizowanym faktem na poziomie części.
- Różne waluty nie są przeliczane. Puste pola mogą być zgodne z typem ogłoszenia i nie są automatycznie usuwane.
- Pola wielojęzyczne są wybierane w kolejności polski, angielski, a potem pozostałe
języki. Jeśli TED zwróci wiele różnych terminów dla części, kolumna
deadlineprzechowuje najwcześniejszy dostępny dzień; pełne dane pozostają wsource_payload. last_seen_atoznacza ponowne pobranie rekordu, asource_changed_atzmianę treści zwróconej przez TED. Samo odświeżenie identycznego ogłoszenia nie zmieniasource_changed_at.- TED zawiera formularze eForms i starsze formularze. Parser przyjmuje niejednorodne wartości, a Silver zachowuje pełny rekord źródłowy. Wersja 0.1 nie ma jeszcze polecenia do ponownego parsowania istniejącego Bronze bez pobrania z API.
- Okno przyrostu można zmienić przez przekazanie zakresu dat; dzienny DAG pobiera bieżący dzień i 14 poprzednich dni.
- Połączenie zamawiających po nazwie nie jest tożsamością prawną. Raporty grupują po nazwie i kraju wyłącznie dla wygody.
Szczegóły: docs/ARCHITECTURE.md, docs/DATA_DICTIONARY.md i docs/OPERATIONS.md.
ProcureScope korzysta z publicznego TED Search API. Zachowaj atrybucję do TED przy ponownym wykorzystaniu jego danych i sprawdź aktualne warunki TED przed komercyjnym wdrożeniem.
- TED Search API v3
- Pobieranie danych i tryby stronicowania
- Lista pól wyszukiwarki TED
- Pomoc TED: składnia wyszukiwania eksperckiego
- Klasyfikacja CPV
- Ponowne wykorzystanie danych TED
Kod projektu jest udostępniony na licencji MIT. Licencja kodu nie zmienia warunków, na których udostępniane są dane zewnętrzne. Zobacz NOTICE.
Zgłoszenia i poprawki są mile widziane. Przed pull requestem przeczytaj CONTRIBUTING.md. Zasady zgłaszania problemów bezpieczeństwa opisuje SECURITY.md.