{"id":42037,"date":"2026-05-24T21:01:15","date_gmt":"2026-05-24T18:01:15","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/"},"modified":"2026-05-24T21:01:56","modified_gmt":"2026-05-24T18:01:56","slug":"pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/","title":{"rendered":"Python&#8217;dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz"},"content":{"rendered":"<h2>Python&#8217;dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz<\/h2>\n<p>G\u00fcn\u00fcm\u00fcz veri odakl\u0131 d\u00fcnyas\u0131nda, \u015firketler her ge\u00e7en g\u00fcn daha fazla veri \u00fcretmekte ve bu veriyi anlaml\u0131 i\u00e7g\u00f6r\u00fclere d\u00f6n\u00fc\u015ft\u00fcrmek i\u00e7in karma\u015f\u0131k s\u00fcre\u00e7lere ihtiya\u00e7 duymaktad\u0131r. Manuel olarak y\u00f6netilen veri i\u015fleme ad\u0131mlar\u0131, zamanla bir kabusa d\u00f6n\u00fc\u015febilir: hatalara a\u00e7\u0131k, \u00f6l\u00e7eklenemez ve izlenmesi zor hale gelirler. Peki, y\u00fczlerce farkl\u0131 kaynaktan gelen veriyi d\u00fczenli, hatas\u0131z ve otomatik bir \u015fekilde i\u015fleyip, do\u011fru zamanda do\u011fru yere ula\u015ft\u0131racak sa\u011flam bir \u00fcretim hatt\u0131n\u0131 (production pipeline) nas\u0131l kurabiliriz? \u0130\u015fte tam bu noktada, Python&#8217;\u0131n g\u00fcc\u00fcyle entegre \u00e7al\u0131\u015fan Apache Airflow, veri m\u00fchendislerinin ve geli\u015ftiricilerin en b\u00fcy\u00fck yard\u0131mc\u0131s\u0131 olarak sahneye \u00e7\u0131k\u0131yor. Bu kapsaml\u0131 rehberde, Python projelerinizi \u00fcretim ortam\u0131na ta\u015f\u0131mak i\u00e7in Apache Airflow&#8217;u nas\u0131l kullanaca\u011f\u0131n\u0131z\u0131 ad\u0131m ad\u0131m ke\u015ffedece\u011fiz.<\/p>\n<h3>Apache Airflow Nedir ve Veri Ak\u0131\u015f Y\u00f6netiminde Neden Bu Kadar \u00d6nemlidir?<\/h3>\n<p>Apache Airflow, programatik olarak i\u015f ak\u0131\u015flar\u0131n\u0131 (workflows) yazman\u0131za, planlaman\u0131za ve izlemenize olanak tan\u0131yan a\u00e7\u0131k kaynakl\u0131 bir platformdur. \u00d6zellikle veri m\u00fchendisli\u011fi, makine \u00f6\u011frenimi ve i\u015f zekas\u0131 alanlar\u0131nda, birbirine ba\u011f\u0131ml\u0131 g\u00f6revlerin (tasks) karma\u015f\u0131k zincirlerini otomatikle\u015ftirmek i\u00e7in vazge\u00e7ilmez bir ara\u00e7 haline gelmi\u015ftir. Python ile yaz\u0131lm\u0131\u015f olmas\u0131, platformu Python ekosistemine a\u015fina olan geli\u015ftiriciler i\u00e7in son derece eri\u015filebilir k\u0131lar.<\/p>\n<p>Peki, Airflow&#8217;u bu kadar \u00f6nemli yapan nedir?<\/p>\n<ul>\n<li>\n        <strong>Programatik \u0130\u015f Ak\u0131\u015f\u0131 Tan\u0131mlama (Programmatic Workflow Definition):<\/strong> Airflow&#8217;da i\u015f ak\u0131\u015flar\u0131, yani DAG&#8217;ler (Directed Acyclic Graphs &#8211; Y\u00f6nlendirilmi\u015f D\u00f6ng\u00fcsel Olmayan Grafikler), saf Python kodu ile tan\u0131mlan\u0131r. Bu, s\u00fcr\u00fcm kontrol sistemleriyle (\u00f6rne\u011fin Git) kolayca entegre olabilmesini, test edilebilirli\u011fini ve esnekli\u011fini art\u0131r\u0131r. Bir veri hatt\u0131n\u0131 (data pipeline) kod olarak d\u00fc\u015f\u00fcnmek, &#8220;altyap\u0131 kod olarak&#8221; (infrastructure as code) prensibinin i\u015f ak\u0131\u015flar\u0131na uygulanmas\u0131 anlam\u0131na gelir.\n    <\/li>\n<li>\n        <strong>\u00d6l\u00e7eklenebilirlik (Scalability):<\/strong> Airflow, da\u011f\u0131t\u0131k bir mimariye sahiptir. G\u00f6revleri birden fazla worker (i\u015f\u00e7i) \u00fczerinde paralel olarak \u00e7al\u0131\u015ft\u0131rabilir, bu da b\u00fcy\u00fck veri k\u00fcmeleriyle \u00e7al\u0131\u015f\u0131rken veya \u00e7ok say\u0131da i\u015f ak\u0131\u015f\u0131 y\u00f6netirken performans\u0131 art\u0131r\u0131r. Kubernetes veya Celery gibi teknolojilerle entegrasyonu sayesinde yatay \u00f6l\u00e7eklenebilirlik sunar.\n    <\/li>\n<li>\n        <strong>Zengin Kullan\u0131c\u0131 Aray\u00fcz\u00fc (Rich User Interface):<\/strong> Airflow&#8217;un web tabanl\u0131 kullan\u0131c\u0131 aray\u00fcz\u00fc, DAG&#8217;lerinizi g\u00f6rselle\u015ftirmek, g\u00f6revlerin durumunu izlemek, hata g\u00fcnl\u00fcklerini (logs) incelemek ve i\u015f ak\u0131\u015flar\u0131n\u0131 manuel olarak tetiklemek veya durdurmak i\u00e7in merkezi bir kontrol paneli sa\u011flar. Bu, operasyonel g\u00f6r\u00fcn\u00fcrl\u00fc\u011f\u00fc (operational visibility) \u00f6nemli \u00f6l\u00e7\u00fcde art\u0131r\u0131r.\n    <\/li>\n<li>\n        <strong>Esneklik ve Geni\u015fletilebilirlik (Flexibility and Extensibility):<\/strong> Airflow, \u00e7e\u015fitli veri kaynaklar\u0131 ve platformlarla entegrasyonu kolayla\u015ft\u0131ran y\u00fczlerce operat\u00f6r (operators), sens\u00f6r (sensors) ve hook (kancalar) ile birlikte gelir. \u00d6rne\u011fin, bir veritaban\u0131ndan veri \u00e7ekmek, bir API&#8217;ye istek g\u00f6ndermek, Spark i\u015fleri \u00e7al\u0131\u015ft\u0131rmak veya bir bulut depolama hizmetine dosya y\u00fcklemek gibi g\u00f6revler i\u00e7in \u00f6nceden tan\u0131mlanm\u0131\u015f operat\u00f6rler mevcuttur. Kendi \u00f6zel operat\u00f6rlerinizi ve hook&#8217;lar\u0131n\u0131z\u0131 yazarak Airflow&#8217;u kendi \u00f6zel ihtiya\u00e7lar\u0131n\u0131za g\u00f6re geni\u015fletebilirsiniz.\n    <\/li>\n<li>\n        <strong>Hata Y\u00f6netimi ve Yeniden Deneme Mekanizmalar\u0131 (Error Handling and Retries):<\/strong> Bir \u00fcretim ortam\u0131nda hatalar ka\u00e7\u0131n\u0131lmazd\u0131r. Airflow, g\u00f6revlerin ba\u015far\u0131s\u0131z olmas\u0131 durumunda otomatik yeniden deneme (retries) mekanizmalar\u0131, hata bildirimleri (e-posta, Slack vb.) ve esnek hata i\u015fleme stratejileri sunar. Bu \u00f6zellikler, veri hatlar\u0131n\u0131z\u0131n sa\u011flaml\u0131\u011f\u0131n\u0131 ve g\u00fcvenilirli\u011fini art\u0131r\u0131r.\n    <\/li>\n<\/ul>\n<p>\u00d6zetle, Airflow, karma\u015f\u0131k veri i\u015fleme s\u00fcre\u00e7lerini otomatikle\u015ftirmek, y\u00f6netmek ve izlemek i\u00e7in g\u00fc\u00e7l\u00fc, esnek ve \u00f6l\u00e7eklenebilir bir \u00e7\u00f6z\u00fcm sunar. Bir veri m\u00fchendisi veya geli\u015ftirici olarak, zaman\u0131n\u0131z\u0131 tekrarlayan manuel g\u00f6revler yerine daha de\u011ferli i\u015flere ay\u0131rman\u0131za olanak tan\u0131r.<\/p>\n<h3>Airflow&#8217;un Temel Bile\u015fenleri Nelerdir ve Mimari Nas\u0131l \u00c7al\u0131\u015f\u0131r?<\/h3>\n<p>Apache Airflow, bir dizi temel bile\u015fenin uyumlu bir \u015fekilde \u00e7al\u0131\u015fmas\u0131yla tam i\u015flevselli\u011fini sunar. Bu bile\u015fenlerin her biri, veri i\u015f ak\u0131\u015flar\u0131n\u0131z\u0131n sorunsuz bir \u015fekilde y\u00fcr\u00fct\u00fclmesini sa\u011flamak i\u00e7in belirli bir role sahiptir. Airflow&#8217;un mimarisini anlamak, sorun giderme ve optimizasyon i\u00e7in kritik \u00f6neme sahiptir.<\/p>\n<p>Airflow&#8217;un ba\u015fl\u0131ca bile\u015fenleri \u015funlard\u0131r:<\/p>\n<ol>\n<li>\n        <strong>Web Sunucusu (Webserver):<\/strong> Airflow&#8217;un kullan\u0131c\u0131 aray\u00fcz\u00fcn\u00fc (UI) bar\u0131nd\u0131ran bile\u015fendir. Geli\u015ftiricilerin ve operasyon ekiplerinin DAG&#8217;leri g\u00f6rselle\u015ftirmesine, g\u00f6revlerin durumunu izlemesine, g\u00fcnl\u00fckleri g\u00f6r\u00fcnt\u00fclemesine, ba\u011flant\u0131lar\u0131 ve de\u011fi\u015fkenleri y\u00f6netmesine olanak tan\u0131r. Python&#8217;da Flask framework&#8217;\u00fc ile olu\u015fturulmu\u015ftur ve genellikle bir HTTP sunucusu (\u00f6rne\u011fin Gunicorn) arac\u0131l\u0131\u011f\u0131yla \u00e7al\u0131\u015f\u0131r.\n    <\/li>\n<li>\n        <strong>Planlay\u0131c\u0131 (Scheduler):<\/strong> Airflow&#8217;un kalbi diyebiliriz. Bu bile\u015fen, DAG klas\u00f6r\u00fcn\u00fcz\u00fc s\u00fcrekli olarak izler, yeni DAG&#8217;leri veya g\u00fcncellemeleri alg\u0131lar ve g\u00f6revlerin zamanlanm\u0131\u015f tetikleyicilerine g\u00f6re \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131 gereken g\u00f6revleri belirler. Planlay\u0131c\u0131, g\u00f6rev ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 (dependencies) \u00e7\u00f6zer, g\u00f6revlerin \u00e7al\u0131\u015fmaya haz\u0131r olup olmad\u0131\u011f\u0131n\u0131 kontrol eder ve uygun g\u00f6revleri y\u00fcr\u00fctmek \u00fczere bir y\u00fcr\u00fct\u00fcc\u00fcye (Executor) g\u00f6nderir. Airflow&#8217;un zamanlama mant\u0131\u011f\u0131, cron benzeri ifadelerden veya \u00f6zel zamanlama ayarlar\u0131ndan beslenir.\n    <\/li>\n<li>\n        <strong>Y\u00fcr\u00fct\u00fcc\u00fc (Executor):<\/strong> G\u00f6revlerin (tasks) ger\u00e7ekten nerede ve nas\u0131l \u00e7al\u0131\u015ft\u0131r\u0131laca\u011f\u0131n\u0131 belirleyen bile\u015fendir. Airflow&#8217;un esnekli\u011fi burada da kendini g\u00f6sterir, \u00e7\u00fcnk\u00fc farkl\u0131 y\u00fcr\u00fct\u00fcc\u00fc t\u00fcrleri mevcuttur:<\/p>\n<ul>\n<li>\n                <strong>SequentialExecutor:<\/strong> Geli\u015ftirme ortamlar\u0131 i\u00e7in idealdir. T\u00fcm g\u00f6revleri tek bir i\u015flemde, s\u0131rayla \u00e7al\u0131\u015ft\u0131r\u0131r. \u00dcretim i\u00e7in uygun de\u011fildir.\n            <\/li>\n<li>\n                <strong>LocalExecutor:<\/strong> G\u00f6revleri ayn\u0131 makinedeki paralel s\u00fcre\u00e7lerde \u00e7al\u0131\u015ft\u0131r\u0131r. Daha b\u00fcy\u00fck geli\u015ftirme veya k\u00fc\u00e7\u00fck \u00fcretim ortamlar\u0131 i\u00e7in kullan\u0131labilir, ancak tek bir makinenin kaynaklar\u0131yla s\u0131n\u0131rl\u0131d\u0131r.\n            <\/li>\n<li>\n                <strong>CeleryExecutor:<\/strong> G\u00f6revleri Celery kuyru\u011fu arac\u0131l\u0131\u011f\u0131yla birden fazla worker (i\u015f\u00e7i) aras\u0131nda da\u011f\u0131t\u0131r. Bu, Airflow kurulumunuzu yatay olarak \u00f6l\u00e7eklendirmenizi sa\u011flar ve \u00fcretim ortamlar\u0131 i\u00e7in pop\u00fcler bir se\u00e7enektir.\n            <\/li>\n<li>\n                <strong>KubernetesExecutor:<\/strong> Her bir Airflow g\u00f6revini ayr\u0131 bir Kubernetes Pod&#8217;u olarak \u00e7al\u0131\u015ft\u0131r\u0131r. Bu, g\u00f6revlerin birbirinden izole olmas\u0131n\u0131, kaynak izolasyonu sa\u011flamas\u0131n\u0131 ve Kubernetes&#8217;in g\u00fc\u00e7l\u00fc orkestrasyon yeteneklerinden faydalanmas\u0131n\u0131 sa\u011flar. Bulut tabanl\u0131 \u00fcretim ortamlar\u0131 i\u00e7in en modern ve \u00f6l\u00e7eklenebilir \u00e7\u00f6z\u00fcmlerden biridir.\n            <\/li>\n<\/ul>\n<p>        Y\u00fcr\u00fct\u00fcc\u00fc se\u00e7imi, Airflow kurulumunuzun \u00f6l\u00e7eklenebilirlik ve esneklik ihtiya\u00e7lar\u0131na g\u00f6re yap\u0131l\u0131r.\n    <\/li>\n<li>\n        <strong>Veritaban\u0131 (Metadata Database):<\/strong> Airflow&#8217;un t\u00fcm meta verilerini (meta-data) depolad\u0131\u011f\u0131 yerdir. Bu veritaban\u0131, DAG&#8217;lerin durumunu, g\u00f6rev \u00f6rneklerinin (task instances) ge\u00e7mi\u015fini, ba\u011flant\u0131 bilgilerini, de\u011fi\u015fkenleri, kullan\u0131c\u0131lar\u0131 ve di\u011fer yap\u0131land\u0131rma verilerini i\u00e7erir. Genellikle PostgreSQL veya MySQL gibi bir ili\u015fkisel veritaban\u0131 kullan\u0131l\u0131r. Web sunucusu, planlay\u0131c\u0131 ve y\u00fcr\u00fct\u00fcc\u00fcler, bu veritaban\u0131 arac\u0131l\u0131\u011f\u0131yla birbirleriyle ileti\u015fim kurar.\n    <\/li>\n<li>\n        <strong>DAG Klas\u00f6r\u00fc (DAGs Folder):<\/strong> Airflow&#8217;un DAG tan\u0131mlamalar\u0131n\u0131 i\u00e7eren Python scriptlerini buldu\u011fu dosya sistemindeki bir dizindir. Planlay\u0131c\u0131, bu klas\u00f6r\u00fc belirli aral\u0131klarla tarayarak yeni veya g\u00fcncellenmi\u015f DAG&#8217;leri tespit eder ve veritaban\u0131na kaydeder.\n    <\/li>\n<\/ol>\n<p>Bu bile\u015fenler, bir araya gelerek Airflow&#8217;un g\u00fc\u00e7l\u00fc ve esnek bir i\u015f ak\u0131\u015f\u0131 y\u00f6netim platformu olmas\u0131n\u0131 sa\u011flar. Planlay\u0131c\u0131, veritaban\u0131na bakarak hangi g\u00f6revlerin \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131 gerekti\u011fini belirler, y\u00fcr\u00fct\u00fcc\u00fc bu g\u00f6revleri uygun worker&#8217;lara da\u011f\u0131t\u0131r ve web sunucusu da t\u00fcm bu s\u00fcrecin g\u00f6rsel bir temsilini sunar. Veritaban\u0131 ise t\u00fcm bu i\u015flemlerin kayd\u0131n\u0131 tutar ve bile\u015fenler aras\u0131 ileti\u015fimi m\u00fcmk\u00fcn k\u0131lar.<\/p>\n<h3>Airflow Ortam\u0131 Nas\u0131l Kurulur ve Yap\u0131land\u0131r\u0131l\u0131r?<\/h3>\n<p>Apache Airflow&#8217;u kurman\u0131n ve yap\u0131land\u0131rman\u0131n birka\u00e7 yolu vard\u0131r, ancak geli\u015ftirme ve test ortamlar\u0131 i\u00e7in en yayg\u0131n ve \u00f6nerilen y\u00f6ntemlerden biri Docker Compose kullanmakt\u0131r. Docker Compose, Airflow&#8217;un t\u00fcm bile\u015fenlerini (web sunucusu, planlay\u0131c\u0131, veritaban\u0131 vb.) tek bir komutla aya\u011fa kald\u0131rman\u0131za olanak tan\u0131r. \u00dcretim ortamlar\u0131 i\u00e7in ise genellikle Kubernetes veya daha karma\u015f\u0131k Docker Swarm kurulumlar\u0131 tercih edilir.<\/p>\n<p>Bu b\u00f6l\u00fcmde, Docker Compose kullanarak yerel bir Airflow ortam\u0131n\u0131 nas\u0131l kuraca\u011f\u0131n\u0131z\u0131 ad\u0131m ad\u0131m inceleyece\u011fiz.<\/p>\n<h4>Ad\u0131m 1: \u00d6n Ko\u015fullar<\/h4>\n<p>\u00d6ncelikle sisteminizde Docker ve Docker Compose&#8217;un kurulu oldu\u011fundan emin olun. E\u011fer kurulu de\u011filse, i\u015fletim sisteminize uygun kurulum ad\u0131mlar\u0131n\u0131 Docker&#8217;\u0131n resmi web sitesinden takip edebilirsiniz.<\/p>\n<h4>Ad\u0131m 2: Airflow Docker Compose Dosyas\u0131n\u0131 \u0130ndirme<\/h4>\n<p>Airflow&#8217;un resmi GitHub deposunda, haz\u0131r bir Docker Compose dosyas\u0131 bulunur. Bu dosyay\u0131 indirmek i\u00e7in a\u015fa\u011f\u0131daki komutlar\u0131 kullanabilirsiniz:<\/p>\n<div class=\"code-container\">\n<pre><code>\nmkdir airflow_project\ncd airflow_project\ncurl -LfO \"https:\/\/airflow.apache.org\/docs\/apache-airflow\/2.7.3\/docker-compose.yaml\"\n  <\/code><\/pre>\n<\/div>\n<p>Bu komutlar, <code>airflow_project<\/code> ad\u0131nda yeni bir dizin olu\u015fturur ve Airflow&#8217;un Docker Compose dosyas\u0131n\u0131 bu dizine indirir. \u0130ndirdi\u011finiz dosyan\u0131n ad\u0131 <code>docker-compose.yaml<\/code> olacakt\u0131r. Airflow&#8217;un s\u00fcr\u00fcm\u00fcne g\u00f6re URL&#8217;yi g\u00fcncellemeyi unutmay\u0131n, yukar\u0131daki \u00f6rnek 2.7.3 s\u00fcr\u00fcm\u00fc i\u00e7indir.<\/p>\n<h4>Ad\u0131m 3: Ortam De\u011fi\u015fkenlerini Ayarlama<\/h4>\n<p>Docker Compose dosyas\u0131n\u0131 \u00e7al\u0131\u015ft\u0131rmadan \u00f6nce, Airflow&#8217;un kullan\u0131c\u0131 kimli\u011fi ve parolas\u0131n\u0131 ayarlamak i\u00e7in bir <code>.env<\/code> dosyas\u0131 olu\u015fturman\u0131z \u00f6nerilir. Ayn\u0131 dizinde <code>.env<\/code> ad\u0131nda bir dosya olu\u015fturun ve i\u00e7ine a\u015fa\u011f\u0131daki sat\u0131rlar\u0131 ekleyin:<\/p>\n<div class=\"code-container\">\n<pre><code>\n_AIRFLOW_WWW_USER_USERNAME=airflow\n_AIRFLOW_WWW_USER_PASSWORD=airflow\n  <\/code><\/pre>\n<\/div>\n<p>Bu, varsay\u0131lan kullan\u0131c\u0131 ad\u0131n\u0131 ve parolas\u0131n\u0131 <code>airflow<\/code> olarak ayarlar. \u00dcretim ortam\u0131nda kesinlikle daha g\u00fcvenli parolalar kullanmal\u0131s\u0131n\u0131z.<\/p>\n<h4>Ad\u0131m 4: Airflow Ortam\u0131n\u0131 Ba\u015flatma<\/h4>\n<p>Art\u0131k Airflow bile\u015fenlerini ba\u015flatmaya haz\u0131rs\u0131n\u0131z. \u0130lk \u00e7al\u0131\u015ft\u0131rmada, Airflow&#8217;un gerekli dizinlerini olu\u015fturmas\u0131 ve veritaban\u0131n\u0131 ba\u015flatmas\u0131 i\u00e7in bir ba\u015flang\u0131\u00e7 komutu \u00e7al\u0131\u015ft\u0131rman\u0131z gerekir:<\/p>\n<div class=\"code-container\">\n<pre><code>\ndocker compose up airflow-init\n  <\/code><\/pre>\n<\/div>\n<p>Bu komut tamamland\u0131ktan sonra, t\u00fcm Airflow hizmetlerini ba\u015flatabilirsiniz:<\/p>\n<div class=\"code-container\">\n<pre><code>\ndocker compose up -d\n  <\/code><\/pre>\n<\/div>\n<p><code>-d<\/code> bayra\u011f\u0131, hizmetleri arka planda (detached mode) \u00e7al\u0131\u015ft\u0131rman\u0131z\u0131 sa\u011flar.<\/p>\n<h4>Ad\u0131m 5: Airflow UI&#8217;ya Eri\u015fme<\/h4>\n<p>Hizmetler ba\u015flad\u0131ktan sonra, web taray\u0131c\u0131n\u0131z\u0131 a\u00e7\u0131n ve <code>http:\/\/localhost:8080<\/code> adresine gidin. Kar\u015f\u0131n\u0131za Airflow&#8217;un giri\u015f ekran\u0131 \u00e7\u0131kacakt\u0131r. Ad\u0131m 3&#8217;te ayarlad\u0131\u011f\u0131n\u0131z kullan\u0131c\u0131 ad\u0131 (<code>airflow<\/code>) ve parola (<code>airflow<\/code>) ile giri\u015f yapabilirsiniz.<\/p>\n<h4>Ad\u0131m 6: DAG Klas\u00f6r\u00fcn\u00fc Yap\u0131land\u0131rma<\/h4>\n<p>Airflow&#8217;un DAG&#8217;lerinizi bulabilmesi i\u00e7in, Python scriptlerinizi i\u00e7eren bir klas\u00f6r olu\u015fturman\u0131z ve bu klas\u00f6r\u00fc Docker Compose dosyas\u0131nda Airflow konteynerine ba\u011flaman\u0131z (mount) gerekir.<br \/>\n<code>airflow_project<\/code> dizininin i\u00e7inde <code>dags<\/code> ad\u0131nda bir klas\u00f6r olu\u015fturun:<\/p>\n<div class=\"code-container\">\n<pre><code>\nmkdir dags\n  <\/code><\/pre>\n<\/div>\n<p>\u015eimdi <code>docker-compose.yaml<\/code> dosyas\u0131n\u0131 a\u00e7\u0131n ve <code>airflow-worker<\/code>, <code>airflow-scheduler<\/code> ve <code>airflow-webserver<\/code> servislerinin <code>volumes<\/code> b\u00f6l\u00fcm\u00fcne a\u015fa\u011f\u0131daki sat\u0131r\u0131 ekleyin:<\/p>\n<div class=\"code-container\">\n<pre><code>\n    volumes:\n      - .\/dags:\/opt\/airflow\/dags\n  <\/code><\/pre>\n<\/div>\n<p>Bu de\u011fi\u015fiklikten sonra Docker Compose hizmetlerini yeniden ba\u015flatman\u0131z gerekebilir:<\/p>\n<div class=\"code-container\">\n<pre><code>\ndocker compose down\ndocker compose up -d\n  <\/code><\/pre>\n<\/div>\n<p>Art\u0131k <code>dags<\/code> klas\u00f6r\u00fcn\u00fcze koydu\u011funuz Python dosyalar\u0131, Airflow UI&#8217;da DAG olarak g\u00f6r\u00fcnecektir. Bu kurulum, yerel geli\u015ftirme ve test i\u00e7in sa\u011flam bir temel sa\u011flar. \u00dcretim ortamlar\u0131 i\u00e7in ise, g\u00fcvenlik, yedeklilik ve izleme gibi ek yap\u0131land\u0131rmalar gerekecektir.<\/p>\n<h3>\u0130lk DAG&#8217;\u0131m\u0131z\u0131 Nas\u0131l Olu\u015ftururuz? (Uygulamal\u0131 \u00d6rnek)<\/h3>\n<p>Airflow&#8217;un kalbi olan DAG&#8217;ler (Directed Acyclic Graphs &#8211; Y\u00f6nlendirilmi\u015f D\u00f6ng\u00fcsel Olmayan Grafikler), i\u015f ak\u0131\u015flar\u0131n\u0131z\u0131 tan\u0131mlad\u0131\u011f\u0131n\u0131z Python dosyalar\u0131d\u0131r. Bir DAG, bir dizi g\u00f6revin (tasks) ve bu g\u00f6revler aras\u0131ndaki ba\u011f\u0131ml\u0131l\u0131klar\u0131n (dependencies) mant\u0131ksal bir koleksiyonudur. Her g\u00f6rev, bir operat\u00f6r (operator) taraf\u0131ndan tan\u0131mlan\u0131r ve belirli bir i\u015fi yapar. \u015eimdi, ilk basit DAG&#8217;\u0131m\u0131z\u0131 olu\u015ftural\u0131m ve temel bile\u015fenlerini inceleyelim.<\/p>\n<p>Yukar\u0131daki b\u00f6l\u00fcmde olu\u015fturdu\u011fumuz <code>airflow_project\/dags<\/code> klas\u00f6r\u00fcn\u00fcn i\u00e7ine <code>ilk_dag.py<\/code> ad\u0131nda bir dosya olu\u015ftural\u0131m ve a\u015fa\u011f\u0131daki kodu yap\u0131\u015ft\u0131ral\u0131m:<\/p>\n<div class=\"code-container\">\n<pre><code>\nfrom airflow import DAG\nfrom airflow.operators.bash import BashOperator\nfrom airflow.operators.python import PythonOperator\nfrom datetime import datetime\n\n# Python fonksiyonu tan\u0131mlayal\u0131m\ndef merhaba_dunya_fonksiyonu():\n    print(\"Merhaba Airflow d\u00fcnyas\u0131!\")\n    return \"Fonksiyon ba\u015far\u0131yla \u00e7al\u0131\u015ft\u0131.\"\n\ndef veri_cek_fonksiyonu(kaynak, **kwargs):\n    print(f\"{kaynak} kayna\u011f\u0131ndan veri \u00e7ekiliyor...\")\n    # Burada ger\u00e7ek bir API \u00e7a\u011fr\u0131s\u0131 veya veritaban\u0131 sorgusu olabilir\n    cekilen_veri = f\"'{kaynak}' kayna\u011f\u0131ndan \u00e7ekilen \u00f6rnek veri.\"\n    print(f\"\u00c7ekilen veri: {cekilen_veri}\")\n    # XCom kullanarak veriyi di\u011fer g\u00f6revlere aktarabiliriz\n    kwargs['ti'].xcom_push(key='cekilen_veri', value=cekilen_veri)\n\ndef veriyi_isle_fonksiyonu(**kwargs):\n    ti = kwargs['ti']\n    cekilen_veri = ti.xcom_pull(key='cekilen_veri', task_ids='veri_cek_gorevi')\n    print(f\"\u0130\u015flenecek veri: {cekilen_veri}\")\n    islenmis_veri = f\"'{cekilen_veri}' i\u015flendi ve d\u00f6n\u00fc\u015ft\u00fcr\u00fcld\u00fc.\"\n    print(f\"\u0130\u015flenmi\u015f veri: {islenmis_veri}\")\n    kwargs['ti'].xcom_push(key='islenmis_veri', value=islenmis_veri)\n\ndef veriyi_yukle_fonksiyonu(**kwargs):\n    ti = kwargs['ti']\n    islenmis_veri = ti.xcom_pull(key='islenmis_veri', task_ids='veriyi_isle_gorevi')\n    print(f\"Y\u00fcklenecek veri: {islenmis_veri}\")\n    print(f\"'{islenmis_veri}' veritaban\u0131na veya depolama alan\u0131na y\u00fcklendi.\")\n\n\nwith DAG(\n    dag_id='ilk_airflow_dag',\n    start_date=datetime(2023, 1, 1),\n    schedule_interval='@daily', # Her g\u00fcn \u00e7al\u0131\u015facak\n    catchup=False, # Ge\u00e7mi\u015fteki ka\u00e7\u0131r\u0131lan \u00e7al\u0131\u015ft\u0131rmalar\u0131 yapma\n    tags=['ornek', 'python', 'egitim'],\n    description='Basit bir Airflow DAG \u00f6rne\u011fi',\n) as dag:\n    # G\u00f6rev 1: Bash komutu \u00e7al\u0131\u015ft\u0131rma\n    bash_selamlama = BashOperator(\n        task_id='bash_selamlama_gorevi',\n        bash_command='echo \"Merhaba, Airflow Bash Operat\u00f6r\u00fc!\"',\n    )\n\n    # G\u00f6rev 2: Python fonksiyonu \u00e7al\u0131\u015ft\u0131rma\n    python_selamlama = PythonOperator(\n        task_id='python_selamlama_gorevi',\n        python_callable=merhaba_dunya_fonksiyonu,\n    )\n\n    # G\u00f6rev 3: Veri \u00e7ekme sim\u00fclasyonu\n    veri_cek_gorevi = PythonOperator(\n        task_id='veri_cek_gorevi',\n        python_callable=veri_cek_fonksiyonu,\n        op_kwargs={'kaynak': 'API_Servisi'},\n    )\n\n    # G\u00f6rev 4: Veriyi i\u015fleme sim\u00fclasyonu\n    veriyi_isle_gorevi = PythonOperator(\n        task_id='veriyi_isle_gorevi',\n        python_callable=veriyi_isle_fonksiyonu,\n    )\n\n    # G\u00f6rev 5: Veriyi y\u00fckleme sim\u00fclasyonu\n    veriyi_yukle_gorevi = PythonOperator(\n        task_id='veriyi_yukle_gorevi',\n        python_callable=veriyi_yukle_fonksiyonu,\n    )\n\n    # G\u00f6revler aras\u0131 ba\u011f\u0131ml\u0131l\u0131klar\u0131 tan\u0131mlama\n    # bash_selamlama -> python_selamlama\n    # python_selamlama -> veri_cek_gorevi\n    # veri_cek_gorevi -> veriyi_isle_gorevi -> veriyi_yukle_gorevi\n\n    bash_selamlama >> python_selamlama >> veri_cek_gorevi >> veriyi_isle_gorevi >> veriyi_yukle_gorevi\n  <\/code><\/pre>\n<\/div>\n<h4>Kod A\u00e7\u0131klamas\u0131:<\/h4>\n<ol>\n<li>\n        <strong>\u0130\u00e7e Aktarmalar (Imports):<\/strong><\/p>\n<ul>\n<li><code>DAG<\/code>: Airflow&#8217;da bir i\u015f ak\u0131\u015f\u0131n\u0131 tan\u0131mlamak i\u00e7in ana s\u0131n\u0131ft\u0131r.<\/li>\n<li><code>BashOperator<\/code>: Bash komutlar\u0131n\u0131 \u00e7al\u0131\u015ft\u0131rmak i\u00e7in kullan\u0131l\u0131r.<\/li>\n<li><code>PythonOperator<\/code>: Python fonksiyonlar\u0131n\u0131 \u00e7al\u0131\u015ft\u0131rmak i\u00e7in kullan\u0131l\u0131r.<\/li>\n<li><code>datetime<\/code>: Zamanlama i\u00e7in kullan\u0131l\u0131r.<\/li>\n<\/ul>\n<\/li>\n<li>\n        <strong>Python Fonksiyonlar\u0131:<\/strong><\/p>\n<ul>\n<li><code>merhaba_dunya_fonksiyonu()<\/code>: Basit bir mesaj yazd\u0131ran fonksiyon.<\/li>\n<li><code>veri_cek_fonksiyonu()<\/code>: Belirli bir kaynaktan veri \u00e7ekme i\u015flemini sim\u00fcle eder ve \u00e7ekilen veriyi XCom (Cross-Communication) kullanarak di\u011fer g\u00f6revlere aktar\u0131r. <code>op_kwargs<\/code> ile operat\u00f6re arg\u00fcman ge\u00e7irebiliriz.<\/li>\n<li><code>veriyi_isle_fonksiyonu()<\/code>: <code>veri_cek_gorevi<\/code>&#8216;nden \u00e7ekilen veriyi al\u0131r, i\u015fler ve i\u015flenmi\u015f veriyi yine XCom ile aktar\u0131r.<\/li>\n<li><code>veriyi_yukle_fonksiyonu()<\/code>: <code>veriyi_isle_gorevi<\/code>&#8216;nden i\u015flenmi\u015f veriyi al\u0131r ve y\u00fckleme i\u015flemini sim\u00fcle eder.<\/li>\n<\/ul>\n<\/li>\n<li>\n        <strong>DAG Tan\u0131mlamas\u0131:<\/strong><\/p>\n<ul>\n<li><code>dag_id<\/code>: DAG&#8217;in benzersiz tan\u0131mlay\u0131c\u0131s\u0131d\u0131r. Airflow UI&#8217;da bu isimle g\u00f6r\u00fcn\u00fcr.<\/li>\n<li><code>start_date<\/code>: DAG&#8217;in ne zaman \u00e7al\u0131\u015fmaya ba\u015flayaca\u011f\u0131n\u0131 belirtir. Airflow, bu tarihten itibaren <code>schedule_interval<\/code>&#8216;e g\u00f6re ge\u00e7mi\u015f \u00e7al\u0131\u015ft\u0131rmalar\u0131 planlar.<\/li>\n<li><code>schedule_interval<\/code>: DAG&#8217;in ne s\u0131kl\u0131kta \u00e7al\u0131\u015faca\u011f\u0131n\u0131 belirler. Cron ifadeleri (\u00f6rne\u011fin <code>'0 0 * * *'<\/code> veya <code>'@daily'<\/code>) veya zaman aral\u0131klar\u0131 (\u00f6rne\u011fin <code>timedelta(days=1)<\/code>) kullan\u0131labilir. <code>None<\/code> olarak ayarlan\u0131rsa sadece manuel olarak tetiklenebilir.<\/li>\n<li><code>catchup=False<\/code>: <code>start_date<\/code> ile mevcut tarih aras\u0131ndaki ka\u00e7\u0131r\u0131lan \u00e7al\u0131\u015ft\u0131rmalar\u0131n yap\u0131lmamas\u0131n\u0131 sa\u011flar. Genellikle geli\u015ftirme ortamlar\u0131nda <code>False<\/code> olarak ayarlan\u0131r.<\/li>\n<li><code>tags<\/code>: DAG&#8217;leri grupland\u0131rmak ve filtrelemek i\u00e7in etiketler.<\/li>\n<li><code>description<\/code>: DAG hakk\u0131nda k\u0131sa bir a\u00e7\u0131klama.<\/li>\n<\/ul>\n<\/li>\n<li>\n        <strong>G\u00f6rev Tan\u0131mlamalar\u0131 (Task Definitions):<\/strong><\/p>\n<ul>\n<li><code>BashOperator<\/code>: <code>task_id<\/code> ile benzersiz bir kimlik ve <code>bash_command<\/code> ile \u00e7al\u0131\u015ft\u0131r\u0131lacak Bash komutunu al\u0131r.<\/li>\n<li><code>PythonOperator<\/code>: <code>task_id<\/code> ve \u00e7al\u0131\u015ft\u0131r\u0131lacak Python fonksiyonunu (<code>python_callable<\/code>) al\u0131r. Fonksiyona arg\u00fcman ge\u00e7irmek i\u00e7in <code>op_kwargs<\/code> kullan\u0131labilir. XCom&#8217;a eri\u015fim i\u00e7in fonksiyonun <code>**kwargs<\/code> almas\u0131 ve <code>ti = kwargs['ti']<\/code> ile <code>TaskInstance<\/code> objesine ula\u015fmas\u0131 gerekir.<\/li>\n<\/ul>\n<\/li>\n<li>\n        <strong>Ba\u011f\u0131ml\u0131l\u0131klar (Dependencies):<\/strong><\/p>\n<ul>\n<li>G\u00f6revler aras\u0131ndaki y\u00fcr\u00fctme s\u0131ras\u0131n\u0131 belirler. <code>>><\/code> operat\u00f6r\u00fc &#8220;\u015fundan sonra \u00e7al\u0131\u015f&#8221; anlam\u0131na gelir. \u00d6rne\u011fin, <code>task_a >> task_b<\/code>, <code>task_a<\/code> ba\u015far\u0131yla tamamland\u0131ktan sonra <code>task_b<\/code>&#8216;nin \u00e7al\u0131\u015faca\u011f\u0131 anlam\u0131na gelir. Birden fazla ba\u011f\u0131ml\u0131l\u0131k zincirleme yap\u0131labilir.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>Bu dosyay\u0131 <code>airflow_project\/dags<\/code> klas\u00f6r\u00fcne kaydettikten sonra, Airflow web aray\u00fcz\u00fcn\u00fc yeniledi\u011finizde &#8220;ilk_airflow_dag&#8221; ad\u0131nda yeni bir DAG g\u00f6receksiniz. DAG&#8217;i etkinle\u015ftirmek i\u00e7in anahtar d\u00fc\u011fmesini &#8220;On&#8221; konumuna getirin. Daha sonra, DAG&#8217;i manuel olarak tetikleyebilir veya zamanlanm\u0131\u015f \u00e7al\u0131\u015ft\u0131rmas\u0131n\u0131 bekleyebilirsiniz. \u00c7al\u0131\u015ft\u0131rma s\u0131ras\u0131nda g\u00f6revlerin durumunu (running, success, failed) ve g\u00fcnl\u00fcklerini (logs) web aray\u00fcz\u00fcnden izleyebilirsiniz. Bu basit \u00f6rnek, Airflow&#8217;un temel g\u00fcc\u00fcn\u00fc ve esnekli\u011fini g\u00f6stermektedir.<\/p>\n<h3>Ger\u00e7ek D\u00fcnya Senaryolar\u0131nda Airflow Kullan\u0131m\u0131: Bir Vaka Analizi<\/h3>\n<p>Bir\u00e7ok \u015firket, m\u00fc\u015fteri davran\u0131\u015flar\u0131n\u0131 anlamak, pazarlama kampanyalar\u0131n\u0131 optimize etmek veya \u00fcr\u00fcn \u00f6nerilerini ki\u015fiselle\u015ftirmek i\u00e7in farkl\u0131 kaynaklardan (web sitesi, mobil uygulama, CRM, sosyal medya vb.) gelen verileri toplar, i\u015fler ve analiz eder. Bu s\u00fcre\u00e7 genellikle bir ETL (Extract, Transform, Load) veya ELT (Extract, Load, Transform) boru hatt\u0131 gerektirir. Airflow, bu t\u00fcr karma\u015f\u0131k boru hatlar\u0131n\u0131 y\u00f6netmek i\u00e7in m\u00fckemmel bir ara\u00e7t\u0131r.<\/p>\n<p>\u015eimdi, e-ticaret verilerini i\u015fleyen basit bir ETL boru hatt\u0131 senaryosunu Airflow ile nas\u0131l otomatikle\u015ftirece\u011fimizi inceleyelim.<\/p>\n<h4>Vaka Analizi: E-ticaret M\u00fc\u015fteri Davran\u0131\u015flar\u0131 Analizi<\/h4>\n<p>Bir e-ticaret \u015firketi, g\u00fcnl\u00fck olarak farkl\u0131 sistemlerden (web sitesi analizleri, sipari\u015f veritaban\u0131, pazarlama platformu) gelen verileri toplay\u0131p, bunlar\u0131 birle\u015ftirerek m\u00fc\u015fteri segmentasyonu ve kampanya performans analizi yapmak istiyor. Hedef, bu verileri d\u00fczenli olarak bir veri ambar\u0131na (data warehouse) y\u00fcklemek ve BI (Business Intelligence) ara\u00e7lar\u0131 arac\u0131l\u0131\u011f\u0131yla raporlanabilir hale getirmektir.<\/p>\n<p><strong>Boru Hatt\u0131n\u0131n Ad\u0131mlar\u0131:<\/strong><\/p>\n<ol>\n<li><strong>Veri \u00c7ekme (Extract):<\/strong>\n<ul>\n<li>G\u00fcn\u00fcn web sitesi trafik verilerini bir harici API&#8217;den \u00e7ekme.<\/li>\n<li>Yeni sipari\u015f verilerini \u015firket i\u00e7i PostgreSQL veritaban\u0131ndan \u00e7ekme.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Veri D\u00f6n\u00fc\u015ft\u00fcrme (Transform):<\/strong>\n<ul>\n<li>\u00c7ekilen trafik ve sipari\u015f verilerini birle\u015ftirme.<\/li>\n<li>M\u00fc\u015fteri ID&#8217;lerini anonimle\u015ftirme (hashleme).<\/li>\n<li>Eksik de\u011ferleri doldurma veya ayk\u0131r\u0131 de\u011ferleri temizleme.<\/li>\n<li>Zaman damgalar\u0131n\u0131 (timestamps) standart bir formata d\u00f6n\u00fc\u015ft\u00fcrme.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Veri Y\u00fckleme (Load):<\/strong>\n<ul>\n<li>\u0130\u015flenmi\u015f ve temizlenmi\u015f veriyi \u015firketin veri ambar\u0131na (\u00f6rne\u011fin, Google BigQuery, Snowflake veya \u015firket i\u00e7i bir PostgreSQL\/Redshift) y\u00fckleme.<\/li>\n<\/ul>\n<\/li>\n<li><strong>Raporlama Tetikleme (Optional):<\/strong>\n<ul>\n<li>Veri ambar\u0131na y\u00fckleme tamamland\u0131ktan sonra, BI raporlama arac\u0131nda (\u00f6rne\u011fin Tableau, Power BI) yeni raporlar\u0131n olu\u015fturulmas\u0131n\u0131 veya mevcut raporlar\u0131n yenilenmesini tetikleme.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<h4>Airflow ile Uygulama \u00d6rne\u011fi (K\u0131smi Kod):<\/h4>\n<p>Bu senaryo i\u00e7in <code>e_ticaret_etl_dag.py<\/code> ad\u0131nda bir DAG olu\u015ftural\u0131m:<\/p>\n<div class=\"code-container\">\n<pre><code>\nfrom airflow import DAG\nfrom airflow.operators.python import PythonOperator\nfrom airflow.providers.http.operators.http import SimpleHttpOperator\nfrom airflow.providers.postgres.hooks.postgres import PostgresHook\nfrom airflow.models import Variable\nfrom datetime import datetime, timedelta\nimport json\nimport pandas as pd # Veri i\u015fleme i\u00e7in\n\n# --- Python Fonksiyonlar\u0131 ---\n\ndef web_traffic_api_cek(ti, **kwargs):\n    # SimpleHttpOperator'dan gelen yan\u0131t\u0131 \u00e7ekiyoruz\n    response_json = ti.xcom_pull(task_ids='web_traffic_cek', key='return_value')\n    if not response_json:\n        raise ValueError(\"Web trafik verisi API'den \u00e7ekilemedi.\")\n    \n    traffic_data = json.loads(response_json)\n    print(f\"Web trafik verisi \u00e7ekildi: {len(traffic_data)} kay\u0131t.\")\n    # Burada daha fazla i\u015fleme yap\u0131labilir, \u015fimdilik sadece yazd\u0131r\u0131yoruz\n    ti.xcom_push(key='web_traffic_data', value=traffic_data)\n\ndef siparis_verisi_cek(ti, **kwargs):\n    pg_hook = PostgresHook(postgres_conn_id='postgres_default')\n    sql_query = \"SELECT order_id, customer_id, product_id, amount, order_date FROM orders WHERE order_date = CURRENT_DATE;\"\n    records = pg_hook.get_pandas_df(sql_query)\n    print(f\"PostgreSQL'den sipari\u015f verisi \u00e7ekildi: {len(records)} kay\u0131t.\")\n    ti.xcom_push(key='order_data', value=records.to_json())\n\ndef verileri_donustur(ti, **kwargs):\n    web_traffic_data = ti.xcom_pull(task_ids='web_traffic_api_isleme', key='web_traffic_data')\n    order_data_json = ti.xcom_pull(task_ids='siparis_verisi_cek', key='order_data')\n    \n    if not web_traffic_data or not order_data_json:\n        raise ValueError(\"D\u00f6n\u00fc\u015ft\u00fcrme i\u00e7in gerekli veriler eksik.\")\n\n    order_df = pd.read_json(order_data_json)\n    traffic_df = pd.DataFrame(web_traffic_data)\n\n    # \u00d6rnek d\u00f6n\u00fc\u015f\u00fcm: M\u00fc\u015fteri ID'lerini hashleme ve verileri birle\u015ftirme\n    order_df['customer_id_hashed'] = order_df['customer_id'].apply(lambda x: hash(str(x)))\n    # traffic_df ile order_df'yi birle\u015ftirmek i\u00e7in ortak bir anahtar olmal\u0131\n    # Burada basit\u00e7e \u00f6rnek verilerle devam edelim\n    \n    merged_df = pd.merge(order_df, traffic_df, left_on='customer_id', right_on='user_id', how='left', suffixes=('_order', '_traffic'))\n    merged_df = merged_df.fillna(0) # Eksik de\u011ferleri doldurma\n\n    print(f\"Veriler ba\u015far\u0131yla d\u00f6n\u00fc\u015ft\u00fcr\u00fcld\u00fc. Birle\u015ftirilmi\u015f kay\u0131t say\u0131s\u0131: {len(merged_df)}\")\n    ti.xcom_push(key='transformed_data', value=merged_df.to_json())\n\ndef veriyi_veri_ambarina_yukle(ti, **kwargs):\n    transformed_data_json = ti.xcom_pull(task_ids='verileri_donustur', key='transformed_data')\n    if not transformed_data_json:\n        raise ValueError(\"Y\u00fcklenecek d\u00f6n\u00fc\u015ft\u00fcr\u00fclm\u00fc\u015f veri eksik.\")\n\n    final_df = pd.read_json(transformed_data_json)\n    \n    # Burada veri ambar\u0131na y\u00fckleme i\u015flemleri yap\u0131l\u0131r.\n    # \u00d6rne\u011fin, BigQueryHook, SnowflakeHook veya ba\u015fka bir veritaban\u0131 hook'u kullan\u0131labilir.\n    # \u00d6rnek olarak PostgreSQL'e y\u00fckleme yapal\u0131m:\n    pg_hook = PostgresHook(postgres_conn_id='postgres_default')\n    table_name = \"customer_analytics_daily\"\n    final_df.to_sql(table_name, con=pg_hook.get_sqlalchemy_engine(), if_exists='append', index=False)\n    \n    print(f\"{len(final_df)} kay\u0131t '{table_name}' tablosuna ba\u015far\u0131yla y\u00fcklendi.\")\n\n# --- DAG Tan\u0131mlamas\u0131 ---\n\nwith DAG(\n    dag_id='e_ticaret_etl_pipeline',\n    start_date=datetime(2023, 1, 1),\n    schedule_interval=timedelta(days=1), # Her g\u00fcn \u00e7al\u0131\u015f\u0131r\n    catchup=False,\n    tags=['etl', 'e-ticaret', 'veri-ambar'],\n    default_args={\n        'owner': 'airflow',\n        'depends_on_past': False,\n        'email_on_failure': False,\n        'email_on_retry': False,\n        'retries': 1,\n        'retry_delay': timedelta(minutes=5),\n    }\n) as dag:\n    # G\u00f6rev 1: Web trafik verilerini API'den \u00e7ekme\n    web_traffic_cek = SimpleHttpOperator(\n        task_id='web_traffic_cek',\n        http_conn_id='http_default', # Airflow'da tan\u0131ml\u0131 HTTP ba\u011flant\u0131s\u0131\n        endpoint='\/api\/v1\/traffic', # \u00d6rnek API endpoint'i\n        method='GET',\n        headers={\"Content-Type\": \"application\/json\"},\n        response_filter=lambda response: response.text, # Yan\u0131t\u0131 string olarak d\u00f6nd\u00fcr\n        log_response=True,\n    )\n\n    # G\u00f6rev 1.1: \u00c7ekilen web trafik verisini i\u015fleme (XCom ile alma)\n    web_traffic_api_isleme = PythonOperator(\n        task_id='web_traffic_api_isleme',\n        python_callable=web_traffic_api_cek,\n    )\n\n    # G\u00f6rev 2: Sipari\u015f verilerini PostgreSQL'den \u00e7ekme\n    siparis_verisi_cek = PythonOperator(\n        task_id='siparis_verisi_cek',\n        python_callable=siparis_verisi_cek,\n    )\n\n    # G\u00f6rev 3: \u00c7ekilen verileri d\u00f6n\u00fc\u015ft\u00fcrme ve birle\u015ftirme\n    verileri_donustur = PythonOperator(\n        task_id='verileri_donustur',\n        python_callable=verileri_donustur,\n    )\n\n    # G\u00f6rev 4: D\u00f6n\u00fc\u015ft\u00fcr\u00fclm\u00fc\u015f veriyi veri ambar\u0131na y\u00fckleme\n    veriyi_veri_ambarina_yukle = PythonOperator(\n        task_id='veriyi_veri_ambarina_yukle',\n        python_callable=veriyi_veri_ambarina_yukle,\n    )\n\n    # G\u00f6revler aras\u0131 ba\u011f\u0131ml\u0131l\u0131klar\n    [web_traffic_cek, siparis_verisi_cek] >> verileri_donustur >> veriyi_veri_ambarina_yukle\n  <\/code><\/pre>\n<\/div>\n<h4>A\u00e7\u0131klamalar ve \u0130pu\u00e7lar\u0131:<\/h4>\n<ol>\n<li>\n        <strong>Ba\u011flant\u0131lar (Connections):<\/strong> Airflow, harici sistemlere (veritabanlar\u0131, API&#8217;ler, bulut hizmetleri) ba\u011flant\u0131 bilgilerini g\u00fcvenli bir \u015fekilde depolaman\u0131za olanak tan\u0131r. <code>http_default<\/code> ve <code>postgres_default<\/code> gibi ba\u011flant\u0131lar, Airflow UI&#8217;da &#8220;Admin -> Connections&#8221; alt\u0131ndan tan\u0131mlanmal\u0131d\u0131r. Bu, hassas bilgilerin (API anahtarlar\u0131, veritaban\u0131 parolalar\u0131) kod i\u00e7inde saklanmas\u0131n\u0131 engeller.\n    <\/li>\n<li>\n        <strong>XCom (Cross-Communication):<\/strong> G\u00f6revler aras\u0131nda k\u00fc\u00e7\u00fck miktarlarda veri (\u00f6rne\u011fin, dosya yollar\u0131, ID&#8217;ler, JSON yan\u0131tlar\u0131) aktarmak i\u00e7in kullan\u0131l\u0131r. <code>xcom_push<\/code> ile veri g\u00f6nderilir, <code>xcom_pull<\/code> ile al\u0131n\u0131r. Yukar\u0131daki \u00f6rnekte, API&#8217;den ve veritaban\u0131ndan \u00e7ekilen veriler, i\u015fleme g\u00f6revine XCom arac\u0131l\u0131\u011f\u0131yla aktar\u0131l\u0131r.\n    <\/li>\n<li>\n        <strong>Operat\u00f6rler (Operators):<\/strong><\/p>\n<ul>\n<li><code>SimpleHttpOperator<\/code>: HTTP\/HTTPS endpoint&#8217;lerine istek g\u00f6ndermek i\u00e7in kullan\u0131l\u0131r. API&#8217;den veri \u00e7ekmek i\u00e7in idealdir.<\/li>\n<li><code>PythonOperator<\/code>: \u00d6zel Python fonksiyonlar\u0131n\u0131z\u0131 \u00e7al\u0131\u015ft\u0131rmak i\u00e7in kullan\u0131l\u0131r. Veri d\u00f6n\u00fc\u015f\u00fcm\u00fc ve veritaban\u0131 etkile\u015fimleri i\u00e7in olduk\u00e7a esnektir.<\/li>\n<li>Di\u011fer operat\u00f6rler: Airflow, bir\u00e7ok farkl\u0131 platform i\u00e7in haz\u0131r operat\u00f6rler sunar (<code>S3Hook<\/code>, <code>BigQueryOperator<\/code>, <code>SparkSubmitOperator<\/code> vb.). Kendi ihtiya\u00e7lar\u0131n\u0131za g\u00f6re bunlar\u0131 kullanabilir veya \u00f6zel operat\u00f6rler yazabilirsiniz.<\/li>\n<\/ul>\n<\/li>\n<li>\n        <strong>Pandas Kullan\u0131m\u0131:<\/strong> Python tabanl\u0131 veri i\u015fleme i\u00e7in Pandas k\u00fct\u00fcphanesi olduk\u00e7a g\u00fc\u00e7l\u00fcd\u00fcr ve Airflow&#8217;daki PythonOperator i\u00e7inde rahatl\u0131kla kullan\u0131labilir. Veri \u00e7er\u00e7evelerini (DataFrames) JSON&#8217;a d\u00f6n\u00fc\u015ft\u00fcrerek XCom \u00fczerinden aktarmak yayg\u0131n bir y\u00f6ntemdir.\n    <\/li>\n<li>\n        <strong>Hata Y\u00f6netimi:<\/strong> <code>default_args<\/code> i\u00e7inde <code>retries<\/code> ve <code>retry_delay<\/code> gibi parametreler tan\u0131mlayarak, g\u00f6revlerin ba\u015far\u0131s\u0131z olmas\u0131 durumunda otomatik olarak yeniden denenmesini sa\u011flayabilirsiniz. Ayr\u0131ca <code>email_on_failure<\/code> gibi se\u00e7eneklerle hata durumunda bildirim alabilirsiniz.\n    <\/li>\n<\/ol>\n<p>Bu vaka analizi, Airflow&#8217;un ger\u00e7ek bir ETL senaryosunda nas\u0131l kullan\u0131labilece\u011fine dair pratik bir bak\u0131\u015f sunmaktad\u0131r. Karma\u015f\u0131k veri boru hatlar\u0131n\u0131 y\u00f6netmek i\u00e7in Airflow&#8217;un mod\u00fcler yap\u0131s\u0131, esnek operat\u00f6rleri ve g\u00fc\u00e7l\u00fc izleme yetenekleri paha bi\u00e7ilmezdir.<\/p>\n<h3>Airflow&#8217;da \u0130leri D\u00fczey Konular ve En \u0130yi Uygulamalar<\/h3>\n<p>Airflow&#8217;u temel seviyede kurup ilk DAG&#8217;lerinizi olu\u015fturduktan sonra, \u00fcretim ortamlar\u0131nda daha sa\u011flam, verimli ve y\u00f6netilebilir i\u015f ak\u0131\u015flar\u0131 olu\u015fturmak i\u00e7in baz\u0131 ileri d\u00fczey konulara ve en iyi uygulamalara hakim olmak \u00f6nemlidir.<\/p>\n<h4>1. XCom (Cross-Communication) Kullan\u0131m\u0131 ve S\u0131n\u0131rlamalar\u0131<\/h4>\n<p>XCom&#8217;lar, g\u00f6revler aras\u0131nda k\u00fc\u00e7\u00fck miktarlarda veri payla\u015fmak i\u00e7in harika bir yoldur. Ancak, b\u00fcy\u00fck veri k\u00fcmelerini (\u00f6rne\u011fin, birka\u00e7 MB&#8217;tan fazla) XCom arac\u0131l\u0131\u011f\u0131yla aktarmaktan ka\u00e7\u0131n\u0131lmal\u0131s\u0131n\u0131z. Bunun yerine, b\u00fcy\u00fck verileri payla\u015f\u0131lan bir depolama alan\u0131na (S3, GCS, HDFS) yaz\u0131p, XCom ile sadece verinin konumunu (dosya yolu, ID) aktarmak daha verimlidir.<\/p>\n<h4>2. Sens\u00f6rler (Sensors)<\/h4>\n<p>Sens\u00f6rler, belirli bir ko\u015fulun ger\u00e7ekle\u015fmesini bekleyen \u00f6zel operat\u00f6rlerdir. \u00d6rne\u011fin, bir dosyan\u0131n S3&#8217;e y\u00fcklenmesini, bir veritaban\u0131 kayd\u0131n\u0131n olu\u015fmas\u0131n\u0131 veya belirli bir API&#8217;nin yan\u0131t vermesini bekleyebilirler. Bu, i\u015f ak\u0131\u015flar\u0131n\u0131z\u0131n harici olaylara tepki vermesini sa\u011flar.<\/p>\n<div class=\"code-container\">\n<pre><code>\nfrom airflow.providers.s3.sensors.s3 import S3KeySensor\n\ns3_dosya_bekle = S3KeySensor(\n    task_id='s3_dosya_geldi_mi',\n    bucket_name='veri-kovasi',\n    bucket_key='input\/yeni_veri.csv',\n    aws_conn_id='aws_default',\n    poke_interval=60, # Her 60 saniyede bir kontrol et\n    timeout=60 * 60, # 1 saat sonra zaman a\u015f\u0131m\u0131na u\u011fra\n)\n  <\/code><\/pre>\n<\/div>\n<h4>3. Ba\u011flant\u0131lar (Connections) ve De\u011fi\u015fkenler (Variables)<\/h4>\n<ul>\n<li>\n        <strong>Ba\u011flant\u0131lar:<\/strong> Veritaban\u0131 kimlik bilgileri, API anahtarlar\u0131 gibi hassas bilgileri Airflow UI&#8217;dan veya CLI arac\u0131l\u0131\u011f\u0131yla g\u00fcvenli bir \u015fekilde y\u00f6netin. Kodunuzda asla sabit kodlanm\u0131\u015f kimlik bilgileri kullanmay\u0131n.\n    <\/li>\n<li>\n        <strong>De\u011fi\u015fkenler:<\/strong> Ortam yap\u0131land\u0131rmalar\u0131, e\u015fikler veya s\u0131k kullan\u0131lan de\u011ferler gibi statik veya yar\u0131 statik verileri Airflow UI&#8217;dan veya CLI arac\u0131l\u0131\u011f\u0131yla depolay\u0131n. Bu, DAG&#8217;lerinizi daha dinamik hale getirir ve kodda de\u011fi\u015fiklik yapmadan yap\u0131land\u0131rmalar\u0131 g\u00fcncellemenizi sa\u011flar.<\/p>\n<div class=\"code-container\">\n<pre><code>\nfrom airflow.models import Variable\n\n# Airflow UI'da tan\u0131mlanm\u0131\u015f bir de\u011fi\u015fkene eri\u015fim\napi_url = Variable.get(\"my_api_base_url\", default_var=\"http:\/\/default-api.com\")\n          <\/code><\/pre>\n<\/p><\/div>\n<\/li>\n<\/ul>\n<h4>4. Hata Y\u00f6netimi ve Bildirimler<\/h4>\n<ul>\n<li>\n        <strong>Yeniden Denemeler (Retries):<\/strong> Ge\u00e7ici hatalar i\u00e7in g\u00f6revlere yeniden deneme say\u0131lar\u0131 (<code>retries<\/code>) ve gecikmeleri (<code>retry_delay<\/code>) ekleyin.\n    <\/li>\n<li>\n        <strong>E-posta\/Slack Bildirimleri:<\/strong> <code>default_args<\/code> i\u00e7inde <code>email_on_failure=True<\/code> veya Slack operat\u00f6rleri gibi bildirim mekanizmalar\u0131n\u0131 kullanarak g\u00f6rev ba\u015far\u0131s\u0131zl\u0131klar\u0131nda veya yeniden denemelerde ilgili ekipleri bilgilendirin.\n    <\/li>\n<li>\n        <strong>On-failure Callback&#8217;ler:<\/strong> Daha karma\u015f\u0131k hata i\u015fleme senaryolar\u0131 i\u00e7in, bir g\u00f6revin ba\u015far\u0131s\u0131z olmas\u0131 durumunda \u00e7al\u0131\u015ft\u0131r\u0131lacak \u00f6zel Python fonksiyonlar\u0131 tan\u0131mlayabilirsiniz (<code>on_failure_callback<\/code>).\n    <\/li>\n<\/ul>\n<h4>5. Idempotency (Tekrarlanabilirlik)<\/h4>\n<p>\u00dcretim ortam\u0131ndaki veri boru hatlar\u0131n\u0131n en \u00f6nemli \u00f6zelliklerinden biri tekrarlanabilirliktir. Bir g\u00f6revin birden fazla kez \u00e7al\u0131\u015ft\u0131r\u0131lmas\u0131 durumunda ayn\u0131 sonucu \u00fcretmesi veya sistemin durumunu de\u011fi\u015ftirmemesi anlam\u0131na gelir. \u00d6rne\u011fin, bir dosya y\u00fckleme g\u00f6revi, dosya zaten varsa hata vermemeli veya ayn\u0131 veriyi tekrar y\u00fcklememeli, bunun yerine var olan\u0131 g\u00fcncellemelidir. Bu, hata durumunda g\u00f6revleri g\u00fcvenle yeniden \u00e7al\u0131\u015ft\u0131rman\u0131za olanak tan\u0131r.<\/p>\n<h4>6. CI\/CD Entegrasyonu<\/h4>\n<p>DAG&#8217;lerinizi s\u00fcr\u00fcm kontrol sistemlerinde (Git) tutmak ve s\u00fcrekli entegrasyon\/s\u00fcrekli da\u011f\u0131t\u0131m (CI\/CD) s\u00fcre\u00e7lerine dahil etmek, DAG geli\u015ftirme ve da\u011f\u0131t\u0131m\u0131n\u0131 otomatikle\u015ftirmenin anahtar\u0131d\u0131r. Yeni bir DAG veya DAG de\u011fi\u015fikli\u011fi Git&#8217;e g\u00f6nderildi\u011finde, CI\/CD boru hatt\u0131 otomatik olarak DAG&#8217;i test edebilir ve Airflow&#8217;un DAG klas\u00f6r\u00fcne da\u011f\u0131tabilir. Bu, hatalar\u0131 erken yakalar ve da\u011f\u0131t\u0131m s\u00fcrecini h\u0131zland\u0131r\u0131r.<\/p>\n<h4>7. Airflow Best Practices (En \u0130yi Uygulamalar)<\/h4>\n<ul>\n<li>\n        <strong>K\u00fc\u00e7\u00fck ve Odaklanm\u0131\u015f G\u00f6revler:<\/strong> Her g\u00f6revin tek bir sorumlulu\u011fu olmal\u0131d\u0131r (Single Responsibility Principle). Bu, hatalar\u0131 ay\u0131klamay\u0131 ve yeniden denemeleri kolayla\u015ft\u0131r\u0131r.\n    <\/li>\n<li>\n        <strong>Parametrik DAG&#8217;ler:<\/strong> <code>Variable<\/code> veya <code>op_kwargs<\/code> kullanarak DAG&#8217;lerinizi parametrik hale getirin. Bu, ayn\u0131 DAG&#8217;i farkl\u0131 girdilerle yeniden kullanman\u0131z\u0131 sa\u011flar.\n    <\/li>\n<li>\n        <strong>Test Edilebilirlik:<\/strong> DAG&#8217;lerinizi ve \u00f6zel operat\u00f6rlerinizi\/hook&#8217;lar\u0131n\u0131z\u0131 birim testleri (unit tests) ve entegrasyon testleri ile test edin.\n    <\/li>\n<li>\n        <strong>G\u00fcnl\u00fck Kay\u0131tlar\u0131 (Logging):<\/strong> G\u00f6revlerinizde yeterli ve anlaml\u0131 g\u00fcnl\u00fck kay\u0131tlar\u0131 tutun. Airflow UI&#8217;dan bu g\u00fcnl\u00fckleri inceleyerek sorunlar\u0131 h\u0131zl\u0131ca te\u015fhis edebilirsiniz.\n    <\/li>\n<li>\n        <strong>Resource Management:<\/strong> \u00d6zellikle KubernetesExecutor kullan\u0131rken, g\u00f6revleriniz i\u00e7in CPU ve bellek s\u0131n\u0131rlar\u0131 belirleyerek kaynak t\u00fcketimini kontrol alt\u0131nda tutun ve sistem kararl\u0131l\u0131\u011f\u0131n\u0131 sa\u011flay\u0131n.\n    <\/li>\n<\/ul>\n<p>Bu ileri d\u00fczey konular ve en iyi uygulamalar, Airflow ile daha g\u00fc\u00e7l\u00fc, esnek ve g\u00fcvenilir veri boru hatlar\u0131 olu\u015fturman\u0131za yard\u0131mc\u0131 olacakt\u0131r. Airflow ekosistemi s\u00fcrekli geli\u015fti\u011fi i\u00e7in, toplulu\u011fu takip etmek ve yeni \u00f6zellikleri \u00f6\u011frenmek de \u00f6nemlidir.<\/p>\n<h3>Sonu\u00e7 ve Gelecek Perspektifi<\/h3>\n<p>Bu makalede, Python&#8217;dan \u00fcretim hatt\u0131na ge\u00e7i\u015fte Apache Airflow&#8217;un neden bu kadar kritik bir rol oynad\u0131\u011f\u0131n\u0131, temel bile\u015fenlerini, yerel bir ortamda nas\u0131l kurulaca\u011f\u0131n\u0131 ve basit bir DAG&#8217;in nas\u0131l olu\u015fturulaca\u011f\u0131n\u0131 ad\u0131m ad\u0131m inceledik. Ayr\u0131ca, ger\u00e7ek d\u00fcnya senaryolar\u0131ndan bir vaka analizi ile Airflow&#8217;un pratik kullan\u0131m\u0131n\u0131 g\u00f6sterdik ve ileri d\u00fczey konular ile en iyi uygulamalara de\u011findik.<\/p>\n<p>Airflow, veri odakl\u0131 \u015firketlerin karma\u015f\u0131k veri i\u015f ak\u0131\u015flar\u0131n\u0131 otomatikle\u015ftirme, izleme ve y\u00f6netme bi\u00e7imini devrim niteli\u011finde de\u011fi\u015ftirdi. Python&#8217;\u0131n esnekli\u011fi ile birle\u015fen g\u00fc\u00e7l\u00fc orkestrasyon yetenekleri sayesinde, geli\u015ftiriciler ve veri m\u00fchendisleri, manuel hatalar\u0131 azalt\u0131rken veri boru hatlar\u0131n\u0131n g\u00fcvenilirli\u011fini ve \u00f6l\u00e7eklenebilirli\u011fini art\u0131rabilirler. \u0130ster k\u00fc\u00e7\u00fck bir startup olun ister b\u00fcy\u00fck bir kurumsal \u015firket, Airflow veri altyap\u0131n\u0131z\u0131n temel bir par\u00e7as\u0131 haline gelerek operasyonel verimlili\u011finizi art\u0131rabilir ve de\u011ferli i\u00e7g\u00f6r\u00fclere daha h\u0131zl\u0131 ula\u015fman\u0131z\u0131 sa\u011flayabilir.<\/p>\n<p>Gelecekte, Airflow&#8217;un bulut entegrasyonlar\u0131n\u0131n daha da derinle\u015fti\u011fini, makine \u00f6\u011frenimi i\u015f ak\u0131\u015flar\u0131 (MLOps) i\u00e7in daha fazla \u00f6zel operat\u00f6r ve \u00f6zellik sundu\u011funu ve genel olarak veri orkestrasyonu alan\u0131nda standart olmaya devam etti\u011fini g\u00f6rece\u011fiz. Airflow toplulu\u011fu aktif ve b\u00fcy\u00fcmeye devam ediyor, bu da platformun s\u00fcrekli geli\u015fimi i\u00e7in sa\u011flam bir zemin olu\u015fturuyor. Python bilginizi kullanarak Airflow ile veri d\u00fcnyas\u0131nda harikalar yaratmaya ba\u015flamak i\u00e7in \u015fimdi tam zaman\u0131!<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<p><strong>1. Apache Airflow&#8217;u kullanmak i\u00e7in Python bilmek \u015fart m\u0131?<\/strong><\/p>\n<p>Evet, Apache Airflow&#8217;un i\u015f ak\u0131\u015flar\u0131 (DAG&#8217;ler) Python ile tan\u0131mland\u0131\u011f\u0131 i\u00e7in Python programlama diline hakim olmak kesinlikle gereklidir. Temel Python bilgisi, Airflow&#8217;u etkili bir \u015fekilde kullanmak i\u00e7in yeterlidir, ancak daha karma\u015f\u0131k g\u00f6revler ve \u00f6zel operat\u00f6rler geli\u015ftirmek i\u00e7in ileri d\u00fczey Python bilgisi faydal\u0131 olacakt\u0131r.<\/p>\n<p><strong>2. Airflow, ETL\/ELT s\u00fcre\u00e7leri i\u00e7in tek \u00e7\u00f6z\u00fcm m\u00fcd\u00fcr?<\/strong><\/p>\n<p>Hay\u0131r, Airflow ETL\/ELT s\u00fcre\u00e7leri i\u00e7in pop\u00fcler ve g\u00fc\u00e7l\u00fc bir ara\u00e7 olsa da tek \u00e7\u00f6z\u00fcm de\u011fildir. Apache Nifi, Luigi, Prefect, Dagster gibi ba\u015fka i\u015f ak\u0131\u015f\u0131 y\u00f6netim ara\u00e7lar\u0131 da mevcuttur. Airflow&#8217;un avantajlar\u0131 aras\u0131nda geni\u015f topluluk deste\u011fi, zengin operat\u00f6r k\u00fct\u00fcphanesi ve Python tabanl\u0131 olmas\u0131 say\u0131labilir.<\/p>\n<p><strong>3. Airflow&#8217;u \u00fcretim ortam\u0131nda kullanmak i\u00e7in nelere dikkat etmeliyim?<\/strong><\/p>\n<p>\u00dcretim ortam\u0131nda Airflow kullan\u0131rken \u00f6l\u00e7eklenebilirlik (CeleryExecutor veya KubernetesExecutor), y\u00fcksek eri\u015filebilirlik, g\u00fcvenlik (ba\u011flant\u0131lar\u0131n ve de\u011fi\u015fkenlerin \u015fifrelenmesi), izleme ve uyar\u0131 sistemleri, CI\/CD entegrasyonu ve d\u00fczenli yedeklemeler gibi konulara dikkat etmelisiniz. Ayr\u0131ca, g\u00f6revlerinizin tekrarlanabilir (idempotent) oldu\u011fundan emin olun.<\/p>\n<p><strong>4. Airflow&#8217;daki &#8216;operat\u00f6r&#8217; ve &#8216;sens\u00f6r&#8217; aras\u0131ndaki fark nedir?<\/strong><\/p>\n<p>Operat\u00f6rler, bir g\u00f6revin temel eylemini tan\u0131mlar; \u00f6rne\u011fin bir Bash komutu \u00e7al\u0131\u015ft\u0131rmak (<code>BashOperator<\/code>), bir Python fonksiyonu \u00e7a\u011f\u0131rmak (<code>PythonOperator<\/code>) veya bir SQL sorgusu y\u00fcr\u00fctmek (<code>PostgresOperator<\/code>). Sens\u00f6rler ise, belirli bir ko\u015fulun ger\u00e7ekle\u015fmesini bekleyen \u00f6zel operat\u00f6rlerdir; \u00f6rne\u011fin bir dosyan\u0131n varl\u0131\u011f\u0131n\u0131 kontrol etmek (<code>S3KeySensor<\/code>) veya bir API&#8217;nin yan\u0131t vermesini beklemek. Sens\u00f6rler, ko\u015ful ger\u00e7ekle\u015fene kadar s\u00fcrekli olarak &#8220;yoklama&#8221; (poke) yapar.<\/p>\n<p><strong>5. Airflow ile hangi bulut platformlar\u0131nda \u00e7al\u0131\u015fabilirim?<\/strong><\/p>\n<p>Apache Airflow, bulut platformlar\u0131ndan ba\u011f\u0131ms\u0131z olarak \u00e7al\u0131\u015fabilir. AWS (Amazon Web Services), GCP (Google Cloud Platform) ve Azure gibi b\u00fcy\u00fck bulut sa\u011flay\u0131c\u0131lar\u0131, Airflow i\u00e7in \u00f6zel y\u00f6netilen hizmetler (\u00f6rne\u011fin Amazon MWAA, Google Cloud Composer) sunar. Bu hizmetler, Airflow kurulumu ve y\u00f6netimi y\u00fck\u00fcn\u00fc azaltarak altyap\u0131 yerine DAG geli\u015ftirmeye odaklanman\u0131z\u0131 sa\u011flar. Kendi bulut sanal sunucular\u0131n\u0131zda veya Kubernetes k\u00fcmelerinizde de Airflow&#8217;u manuel olarak kurup \u00e7al\u0131\u015ft\u0131rabilirsiniz.<\/p>\n<p>#ApacheAirflow #Python #VeriM\u00fchendisli\u011fi #ETL #Otomasyon #VeriBoruHatt\u0131<\/p>\n<div class=\"github-example-link\"><strong>\u00d6rnek kod:<\/strong> <a href=\"https:\/\/github.com\/fatihsoysalcom\/airflow-simple-data-pipeline-dag\" target=\"_blank\" rel=\"noopener noreferrer\">github.com\/fatihsoysalcom\/airflow-simple-data-pipeline-dag<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"mkdir airflow_project cd airflow_project curl -LfO &#8220;https:\/\/airflow. apache.","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[874],"tags":[],"class_list":{"0":"post-42037","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-server","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Python&#039;dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Python&#039;dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz\" \/>\n<meta property=\"og:description\" content=\"mkdir airflow_project cd airflow_project curl -LfO &quot;https:\/\/airflow. apache.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-05-24T18:01:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-05-24T18:01:56+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"29 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Python&#8217;dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz\",\"datePublished\":\"2026-05-24T18:01:15+00:00\",\"dateModified\":\"2026-05-24T18:01:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/\"},\"wordCount\":4362,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Server\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/\",\"name\":\"Python'dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2026-05-24T18:01:15+00:00\",\"dateModified\":\"2026-05-24T18:01:56+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Python&#8217;dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Python'dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/","og_locale":"tr_TR","og_type":"article","og_title":"Python'dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz","og_description":"mkdir airflow_project cd airflow_project curl -LfO \"https:\/\/airflow. apache.","og_url":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2026-05-24T18:01:15+00:00","article_modified_time":"2026-05-24T18:01:56+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"29 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Python&#8217;dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz","datePublished":"2026-05-24T18:01:15+00:00","dateModified":"2026-05-24T18:01:56+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/"},"wordCount":4362,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Server"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/","url":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/","name":"Python'dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2026-05-24T18:01:15+00:00","dateModified":"2026-05-24T18:01:56+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/pythondan-uretim-hattina-apache-airflow-ile-pratik-bir-kilavuz\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Python&#8217;dan \u00dcretim Hatt\u0131na: Apache Airflow ile Pratik Bir K\u0131lavuz"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/42037","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=42037"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/42037\/revisions"}],"predecessor-version":[{"id":42038,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/42037\/revisions\/42038"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=42037"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=42037"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=42037"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}