{"id":33839,"date":"2025-11-07T20:31:28","date_gmt":"2025-11-07T17:31:28","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/"},"modified":"2025-11-07T20:31:28","modified_gmt":"2025-11-07T17:31:28","slug":"fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/","title":{"rendered":"FastAPI ve AWS S3 Presigned URL&#8217;ler ile G\u00fcvenli Dosya Y\u00fckleme API&#8217;si Nas\u0131l Olu\u015fturulur?"},"content":{"rendered":"<p><body><\/p>\n<p>G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131nda dosya y\u00fckleme, en temel ve ayn\u0131 zamanda en kritik i\u015flevlerden biridir. Peki, bu s\u00fcreci hem g\u00fcvenli hem de \u00f6l\u00e7eklenebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Kullan\u0131c\u0131 deneyimini kesintiye u\u011fratmadan, sunucu y\u00fck\u00fcn\u00fc minimumda tutarak b\u00fcy\u00fck dosyalar\u0131n bile sorunsuz bir \u015fekilde y\u00fcklenebilmesini sa\u011flamak m\u00fcmk\u00fcn m\u00fcd\u00fcr? Bu makalede, modern bir yakla\u015f\u0131mla, <a href=\"https:\/\/fastapi.tiangolo.com\/\">FastAPI<\/a> ve <a href=\"https:\/\/aws.amazon.com\/s3\/\">AWS S3 Presigned URL<\/a>&#8216;lerini kullanarak u\u00e7tan uca g\u00fcvenli ve \u00f6l\u00e7eklenebilir bir dosya y\u00fckleme API&#8217;si olu\u015fturma s\u00fcrecini ad\u0131m ad\u0131m ele alaca\u011f\u0131z.<\/p>\n<p>Web uygulamalar\u0131n\u0131n \u00e7o\u011funda, kullan\u0131c\u0131lar\u0131n profil resimleri, belgeler, videolar veya di\u011fer medya dosyalar\u0131 gibi i\u00e7erikleri y\u00fcklemesi gerekmektedir. Ancak bu basit g\u00f6r\u00fcnen i\u015flem, arka planda bir\u00e7ok zorlu\u011fu bar\u0131nd\u0131r\u0131r. Geleneksel dosya y\u00fckleme y\u00f6ntemlerinde, kullan\u0131c\u0131 dosyalar\u0131 \u00f6nce sunucu taraf\u0131ndaki API&#8217;nize gelir, sunucu bu dosyay\u0131 i\u015fler ve ard\u0131ndan kal\u0131c\u0131 bir depolama alan\u0131na (genellikle sunucu diskine veya bir bulut depolama servisine) kaydeder. Bu s\u00fcre\u00e7, \u00f6zellikle y\u00fcksek trafikli veya b\u00fcy\u00fck dosya boyutlar\u0131na sahip uygulamalarda ciddi performans darbo\u011fazlar\u0131na ve g\u00fcvenlik risklerine yol a\u00e7abilir.<\/p>\n<p>\u00d6ncelikle, sunucuya do\u011frudan y\u00fcklenen dosyalar, sunucunun i\u015flem g\u00fcc\u00fcn\u00fc ve bant geni\u015fli\u011fini t\u00fcketir. Her dosya y\u00fcklemesi bir HTTP iste\u011fi olarak sunucuya gelir, sunucu bu iste\u011fi al\u0131r, dosyay\u0131 belle\u011fe veya ge\u00e7ici bir konuma yazar ve ard\u0131ndan bulut depolama gibi nihai hedefine aktar\u0131r. Bu zincirleme i\u015flem, \u00f6zellikle ayn\u0131 anda y\u00fczlerce veya binlerce kullan\u0131c\u0131n\u0131n dosya y\u00fcklemeye \u00e7al\u0131\u015ft\u0131\u011f\u0131 senaryolarda sunucunun a\u015f\u0131r\u0131 y\u00fcklenmesine neden olabilir. Sunucu kaynaklar\u0131 s\u0131n\u0131rl\u0131 oldu\u011fundan, bu durum uygulaman\u0131n genel yan\u0131t s\u00fcresini yava\u015flat\u0131r, kullan\u0131c\u0131 deneyimini olumsuz etkiler ve hatta sunucunun \u00e7\u00f6kmesine neden olabilir. Diyelim ki bir foto\u011fraf payla\u015f\u0131m platformu geli\u015ftiriyorsunuz. Kullan\u0131c\u0131lar an\u0131nda onlarca y\u00fcksek \u00e7\u00f6z\u00fcn\u00fcrl\u00fckl\u00fc foto\u011fraf y\u00fcklemek isteyeceklerdir. Geleneksel y\u00f6ntemle her bir foto\u011fraf\u0131n \u00f6nce API sunucunuza gelmesi ve oradan S3&#8217;e aktar\u0131lmas\u0131, sunucunuzun performans\u0131n\u0131 ciddi anlamda d\u00fc\u015f\u00fcrecektir. \u0130\u015fte tam bu noktada, \u00f6l\u00e7eklenebilir bir \u00e7\u00f6z\u00fcm aray\u0131\u015f\u0131na girilir.<\/p>\n<p>\u0130kincil olarak, g\u00fcvenlik b\u00fcy\u00fck bir endi\u015fe kayna\u011f\u0131d\u0131r. Sunucuya do\u011frudan dosya y\u00fcklemeye izin vermek, k\u00f6t\u00fc niyetli kullan\u0131c\u0131lar\u0131n zararl\u0131 i\u00e7erikleri (vir\u00fcsler, k\u00f6t\u00fc ama\u00e7l\u0131 yaz\u0131l\u0131mlar) sunucuya y\u00fcklemesine veya g\u00fcvenlik a\u00e7\u0131klar\u0131n\u0131 kullanarak sisteminize s\u0131zmas\u0131na davetiye \u00e7\u0131karabilir. Dosya t\u00fcr\u00fc do\u011frulamas\u0131, boyut limitleri ve k\u00f6t\u00fc ama\u00e7l\u0131 yaz\u0131l\u0131m taramas\u0131 gibi g\u00fcvenlik \u00f6nlemleri her ne kadar al\u0131nsa da, bu i\u015flemlerin her biri sunucuya ek y\u00fck bindirir ve tam koruma sa\u011flamak zordur. Ayr\u0131ca, y\u00fcklenen dosyalar\u0131n ge\u00e7ici olarak sunucuda depolanmas\u0131, veri ihlali riskini art\u0131r\u0131r. Hassas verilerin sunucu diskinde, hatta k\u0131sa bir s\u00fcreli\u011fine bile olsa, tutulmas\u0131 g\u00fcvenlik ekibinin korkulu r\u00fcyas\u0131 olabilir. Bu nedenle, dosyalar\u0131n API sunucusuyla do\u011frudan etkile\u015fime girmeden g\u00fcvenli bir \u015fekilde depolanmas\u0131n\u0131 sa\u011flayacak bir mekanizma kritik \u00f6neme sahiptir.<\/p>\n<p>\u00dc\u00e7\u00fcnc\u00fcl olarak, g\u00fcncel teknoloji standartlar\u0131 ve mimarileri, mikroservisler ve sunucusuz mimariler gibi da\u011f\u0131t\u0131k sistemlere y\u00f6nelmektedir. Bu t\u00fcr mimarilerde, dosya y\u00fckleme gibi I\/O yo\u011fun i\u015flemlerin ana uygulama mant\u0131\u011f\u0131ndan ayr\u0131lmas\u0131 ve \u00f6zel, \u00f6l\u00e7eklenebilir bir hizmet taraf\u0131ndan ele al\u0131nmas\u0131 istenir. Bu sayede ana API servisleri daha hafif kal\u0131r, daha h\u0131zl\u0131 yan\u0131t verir ve bak\u0131m ile geli\u015ftirme s\u00fcre\u00e7leri kolayla\u015f\u0131r. Bu makalede ele alaca\u011f\u0131m\u0131z y\u00f6ntem, tam da bu ihtiya\u00e7lar\u0131 kar\u015f\u0131layarak, dosya y\u00fckleme s\u00fcrecini hem g\u00fcvenli hem de son derece \u00f6l\u00e7eklenebilir hale getirmemizi sa\u011flayacak.<\/p>\n<h2>FastAPI, AWS S3 ve Presigned URL&#8217;ler: Bu Teknolojiler Ne \u0130\u015fe Yarar?<\/h2>\n<p>G\u00fcvenli ve \u00f6l\u00e7eklenebilir dosya y\u00fckleme API&#8217;mizin temelini olu\u015fturan \u00fc\u00e7 ana teknolojiye yak\u0131ndan bakal\u0131m: FastAPI, AWS S3 ve S3 Presigned URL&#8217;leri. Bu \u00fc\u00e7l\u00fcn\u00fcn birle\u015fimi, dosya y\u00fckleme mimarisini k\u00f6kten de\u011fi\u015ftiren g\u00fc\u00e7l\u00fc bir sinerji yarat\u0131r.<\/p>\n<p><strong>FastAPI: H\u0131zl\u0131 ve Modern API Geli\u015ftirmenin Yeni Y\u00fcz\u00fc<\/strong><\/p>\n<p>FastAPI, Python i\u00e7in modern, h\u0131zl\u0131 (y\u00fcksek performansl\u0131) bir web \u00e7er\u00e7evesidir ve Python 3.6+ standard tip ipu\u00e7lar\u0131na dayanarak API&#8217;leri olu\u015fturmak i\u00e7in tasarlanm\u0131\u015ft\u0131r. Starlette (hafif ASGI \u00e7er\u00e7evesi) ve Pydantic (veri do\u011frulama ve ayar y\u00f6netimi) \u00fczerine in\u015fa edilmi\u015ftir. Temel \u00f6zellikleri aras\u0131nda otomatik interaktif API dok\u00fcmantasyonu (Swagger UI ve ReDoc), veri do\u011frulama, serile\u015ftirme, asenkron programlama deste\u011fi (<code>async\/await<\/code>) ve performans yer al\u0131r. FastAPI ile API endpoint&#8217;leri yazmak hem \u00e7ok h\u0131zl\u0131d\u0131r hem de kod okunakl\u0131\u011f\u0131 y\u00fcksektir. Geli\u015ftirici verimlili\u011fini art\u0131r\u0131rken, d\u00fc\u015f\u00fck gecikme s\u00fcresi ve y\u00fcksek verim sunar. Bir e-ticaret uygulamas\u0131nda \u00fcr\u00fcn g\u00f6rsellerini y\u00fcklemek i\u00e7in bir API&#8217;ye ihtiyac\u0131n\u0131z oldu\u011funu d\u00fc\u015f\u00fcn\u00fcn. FastAPI, bu API&#8217;yi dakikalar i\u00e7inde, veri modelleriyle birlikte tan\u0131mlaman\u0131za olanak tan\u0131r, bu da geli\u015ftirme s\u00fcrecini inan\u0131lmaz h\u0131zland\u0131r\u0131r.<\/p>\n<p><strong>AWS S3 (Simple Storage Service): Bulut Depolaman\u0131n Lideri<\/strong><\/p>\n<p>Amazon S3, \u00f6l\u00e7eklenebilirli\u011fi, veri kullan\u0131labilirli\u011fi, g\u00fcvenli\u011fi ve performans\u0131yla sekt\u00f6r standard\u0131 haline gelmi\u015f bir nesne depolama hizmetidir. S\u0131n\u0131rs\u0131z veri depolama kapasitesi sunar ve milyarlarca nesneyi saklayabilir. Verileriniz, d\u00fcnya \u00e7ap\u0131nda birden fazla b\u00f6lgede ve birden fazla cihazda otomatik olarak yedeklenir, bu da %99.999999999 (11 dokuz) dayan\u0131kl\u0131l\u0131k anlam\u0131na gelir. S3, foto\u011fraflardan videolara, yedeklemelerden uygulama paketlerine kadar her t\u00fcrl\u00fc veriyi depolamak i\u00e7in idealdir. Web sitelerinin statik i\u00e7eriklerini bar\u0131nd\u0131rmak, b\u00fcy\u00fck veri analizi i\u00e7in veri g\u00f6lleri olu\u015fturmak veya felaket kurtarma \u00e7\u00f6z\u00fcmleri sunmak gibi say\u0131s\u0131z kullan\u0131m senaryosuna sahiptir. \u00d6rne\u011fin, bir medya \u015firketiyseniz, t\u00fcm video ar\u015fivinizi S3&#8217;te depolayabilir ve d\u00fcnya genelindeki izleyicilere d\u00fc\u015f\u00fck gecikmeyle ula\u015ft\u0131rabilirsiniz.<\/p>\n<p><strong>S3 Presigned URL&#8217;ler: G\u00fcvenli ve Do\u011frudan Y\u00fcklemenin Anahtar\u0131<\/strong><\/p>\n<p>\u0130\u015fte projemizin en kritik bile\u015feni: S3 Presigned URL&#8217;ler. Bu URL&#8217;ler, AWS kimlik bilgilerinizi if\u015fa etmeden, belirli bir S3 nesnesine (dosyaya) s\u0131n\u0131rl\u0131 bir s\u00fcre i\u00e7in ge\u00e7ici eri\u015fim izni veren \u00f6zel olarak olu\u015fturulmu\u015f URL&#8217;lerdir. Basit\u00e7e ifade etmek gerekirse, API sunucunuz S3&#8217;e &#8220;\u015eu dosyay\u0131, \u015fu ki\u015fi, \u015fu s\u00fcre boyunca, \u015fu izinlerle (\u00f6rne\u011fin sadece y\u00fckleme veya sadece indirme) kullanabilir&#8221; diyen bir imza (URL) olu\u015fturur. Bu imza daha sonra istemciye verilir ve istemci, bu URL&#8217;yi kullanarak do\u011frudan S3 ile etkile\u015fime girer. Bu sayede:<\/p>\n<ul>\n<li><strong>Sunucu Y\u00fck\u00fc Azal\u0131r:<\/strong> Dosyalar API sunucusuna u\u011framadan do\u011frudan S3&#8217;e gider. Bu, API sunucunuzun yaln\u0131zca Presigned URL&#8217;yi olu\u015fturma gibi hafif bir i\u015flem yapmas\u0131n\u0131 sa\u011flar, as\u0131l y\u00fckleme i\u015fini S3 ve istemci \u00fcstlenir.<\/li>\n<li><strong>Geli\u015ftirilmi\u015f G\u00fcvenlik:<\/strong> AWS kimlik bilgileriniz istemcide asla a\u00e7\u0131\u011fa \u00e7\u0131kmaz. Presigned URL&#8217;ler s\u0131n\u0131rl\u0131 bir s\u00fcre i\u00e7in ge\u00e7erlidir ve belirli izinlerle ili\u015fkilendirilir. Bu, k\u00f6t\u00fc niyetli kullan\u0131c\u0131lar\u0131n s\u00fcrekli eri\u015fim sa\u011flamas\u0131n\u0131 engeller.<\/li>\n<li><strong>\u00d6l\u00e7eklenebilirlik:<\/strong> S3&#8217;\u00fcn do\u011fal \u00f6l\u00e7eklenebilirli\u011finden tam olarak yararlan\u0131l\u0131r. Ayn\u0131 anda binlerce kullan\u0131c\u0131n\u0131n dosya y\u00fcklemesi bile S3 taraf\u0131ndan kolayca y\u00f6netilir.<\/li>\n<li><strong>Daha \u0130yi Kullan\u0131c\u0131 Deneyimi:<\/strong> Dosyalar do\u011frudan S3&#8217;e y\u00fcklendi\u011fi i\u00e7in y\u00fckleme s\u00fcreleri k\u0131sal\u0131r ve genel kullan\u0131c\u0131 deneyimi iyile\u015fir.<\/li>\n<\/ul>\n<p>Bir e-\u00f6\u011frenme platformunda \u00f6\u011frencilerin \u00f6devlerini PDF olarak y\u00fcklemesi gerekti\u011fini varsayal\u0131m. Presigned URL&#8217;ler sayesinde, API&#8217;niz sadece \u00f6\u011frencilerin dosyay\u0131 S3&#8217;e y\u00fckleyebilece\u011fi ge\u00e7ici bir link verir. \u00d6\u011frenci dosyay\u0131 bu link \u00fczerinden y\u00fcklerken, API sunucunuz ba\u015fka isteklere hizmet vermeye devam edebilir, b\u00f6ylece platformun genel performans\u0131 etkilenmez.<\/p>\n<h2>Proje Kurulumu ve Gerekli Ayarlar: G\u00fcvenli Dosya Y\u00fckleme API&#8217;si \u0130\u00e7in Ortam\u0131 Nas\u0131l Haz\u0131rlar\u0131z?<\/h2>\n<p>\u015eimdi, bu g\u00fc\u00e7l\u00fc teknolojileri bir araya getirmek i\u00e7in projemizin temelini olu\u015ftural\u0131m. Temiz bir ba\u015flang\u0131\u00e7 i\u00e7in gerekli t\u00fcm ad\u0131mlar\u0131 detayl\u0131 bir \u015fekilde inceleyece\u011fiz. Bu b\u00f6l\u00fcmde, Python sanal ortam\u0131 olu\u015fturmaktan AWS kimlik bilgilerini yap\u0131land\u0131rmaya kadar her detay\u0131 ele alaca\u011f\u0131z.<\/p>\n<p><strong>1. Proje Dizinini Olu\u015fturma ve Sanal Ortam Kurulumu<\/strong><\/p>\n<p>\u0130lk ad\u0131m olarak, projemiz i\u00e7in bir dizin olu\u015fturup i\u00e7ine girelim ve ard\u0131ndan ba\u011f\u0131ml\u0131l\u0131klar\u0131 izole etmek i\u00e7in bir Python sanal ortam\u0131 olu\u015ftural\u0131m. Bu, projemizin sistemimizdeki di\u011fer Python projeleriyle \u00e7ak\u0131\u015fmas\u0131n\u0131 engeller ve ba\u011f\u0131ml\u0131l\u0131k y\u00f6netimini kolayla\u015ft\u0131r\u0131r.<\/p>\n<pre><code class=\"language-bash\">\nmkdir fastapi-s3-upload\ncd fastapi-s3-upload\npython3 -m venv venv\nsource venv\/bin\/activate # Linux\/macOS\n# .\\venv\\Scripts\\activate # Windows\n    <\/pre>\n<p><\/code><\/p>\n<p>Sanal ortam\u0131 etkinle\u015ftirdikten sonra, t\u00fcm ba\u011f\u0131ml\u0131l\u0131klar\u0131 bu ortamda kuraca\u011f\u0131z.<\/p>\n<p><strong>2. Gerekli Python K\u00fct\u00fcphanelerini Kurulumu<\/strong><\/p>\n<p>API'mizi olu\u015fturmak i\u00e7in FastAPI'ye, HTTP isteklerini y\u00f6netmek i\u00e7in Uvicorn'a ve AWS hizmetleriyle etkile\u015fim kurmak i\u00e7in <code>boto3<\/code>'e ihtiyac\u0131m\u0131z olacak. Ayr\u0131ca, hassas bilgileri (AWS kimlik bilgileri gibi) g\u00fcvenli bir \u015fekilde y\u00f6netmek i\u00e7in <code>python-dotenv<\/code> kullanaca\u011f\u0131z.<\/p>\n<pre><code class=\"language-bash\">\npip install fastapi uvicorn python-dotenv boto3\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu komut, t\u00fcm gerekli k\u00fct\u00fcphaneleri sanal ortam\u0131m\u0131za kuracakt\u0131r.<\/p>\n<p><strong>3. AWS Kimlik Bilgileri ve S3 Bucket Konfig\u00fcrasyonu<\/strong><\/p>\n<p>FastAPI uygulamam\u0131z\u0131n S3 ile etkile\u015fime ge\u00e7ebilmesi i\u00e7in AWS kimlik bilgilerine ihtiyac\u0131m\u0131z var. Bu bilgileri do\u011frudan kod i\u00e7ine yazmak yerine, <code>.env<\/code> dosyas\u0131 kullanarak g\u00fcvenli bir \u015fekilde y\u00f6netmek en iyi uygulamad\u0131r. Ayr\u0131ca, dosyalar\u0131 y\u00fckleyece\u011fimiz bir S3 bucket'\u0131 (kovas\u0131) da \u00f6nceden olu\u015fturmu\u015f olmal\u0131y\u0131z.<\/p>\n<p><strong>Ad\u0131m 3.1: AWS Kullan\u0131c\u0131s\u0131 ve \u0130zinleri Olu\u015fturma<\/strong><\/p>\n<p>AWS konsoluna giri\u015f yap\u0131n ve IAM (Identity and Access Management) servisine gidin. Yeni bir kullan\u0131c\u0131 olu\u015fturun (Programmatic access se\u00e7ene\u011fini i\u015faretleyin) ve bu kullan\u0131c\u0131ya yaln\u0131zca S3 ile ilgili belirli izinler veren bir politika ekleyin. En az\u0131ndan, belirli bir S3 bucket'\u0131na <code>s3:PutObject<\/code>, <code>s3:GetObject<\/code> ve <code>s3:ListBucket<\/code> izinleri vermeniz gerekecektir. Bir \u00f6rnek politika \u015f\u00f6yle g\u00f6r\u00fcnebilir:<\/p>\n<pre><code class=\"language-json\">\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"s3:PutObject\",\n                \"s3:GetObject\",\n                \"s3:DeleteObject\",\n                \"s3:ListBucket\"\n            ],\n            \"Resource\": [\n                \"arn:aws:s3:::your-bucket-name\/*\",\n                \"arn:aws:s3:::your-bucket-name\"\n            ]\n        }\n    ]\n}\n    <\/pre>\n<p><\/code><\/p>\n<p><code>your-bucket-name<\/code> yerine kendi S3 kovan\u0131z\u0131n ad\u0131n\u0131 yazmay\u0131 unutmay\u0131n. Bu ad\u0131mlar\u0131 tamamlad\u0131ktan sonra, AWS eri\u015fim anahtar\u0131 kimli\u011fini (Access Key ID) ve gizli eri\u015fim anahtar\u0131n\u0131 (Secret Access Key) alacaks\u0131n\u0131z. Bu bilgileri kimseyle payla\u015fmay\u0131n!<\/p>\n<p><strong>Ad\u0131m 3.2: S3 Bucket Olu\u015fturma<\/strong><\/p>\n<p>AWS S3 servisine gidin ve yeni bir kova (bucket) olu\u015fturun. Kovan\u0131z\u0131n ad\u0131n\u0131 not al\u0131n ve eri\u015fim kontrol\u00fc i\u00e7in \"Block all public access\" se\u00e7ene\u011finin i\u015faretli oldu\u011fundan emin olun. Dosyalar\u0131n herkese a\u00e7\u0131k olmas\u0131n\u0131 isterseniz (\u00f6rne\u011fin statik bir web sitesi i\u00e7in), bu ayar\u0131 de\u011fi\u015ftirebilirsiniz; ancak g\u00fcvenli dosya y\u00fckleme senaryomuzda genellikle \u00f6zel eri\u015fim tercih edilir.<\/p>\n<p><strong>Ad\u0131m 3.3: <code>.env<\/code> Dosyas\u0131n\u0131 Olu\u015fturma<\/strong><\/p>\n<p>Proje k\u00f6k dizininizde <code>.env<\/code> ad\u0131nda bir dosya olu\u015fturun ve i\u00e7ine a\u015fa\u011f\u0131daki bilgileri ekleyin:<\/p>\n<pre><code class=\"language-ini\">\nAWS_ACCESS_KEY_ID=\"YOUR_AWS_ACCESS_KEY_ID\"\nAWS_SECRET_ACCESS_KEY=\"YOUR_AWS_SECRET_ACCESS_KEY\"\nAWS_REGION=\"your-aws-region\" # \u00d6rne\u011fin: eu-central-1\nS3_BUCKET_NAME=\"your-bucket-name\"\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu bilgileri kendi AWS kimlik bilgileriniz ve S3 kovan\u0131z\u0131n ad\u0131 ile g\u00fcncelleyin. <code>.env<\/code> dosyas\u0131n\u0131n versiyon kontrol sistemlerine (Git gibi) y\u00fcklenmemesi gerekti\u011fini unutmay\u0131n. Bu nedenle, <code>.gitignore<\/code> dosyan\u0131za <code>.env<\/code> eklemelisiniz.<\/p>\n<p><strong>4. FastAPI Uygulamas\u0131n\u0131n Temel Yap\u0131s\u0131<\/strong><\/p>\n<p>\u015eimdi <code>main.py<\/code> ad\u0131nda bir dosya olu\u015ftural\u0131m ve temel FastAPI uygulamas\u0131n\u0131 yap\u0131land\u0131ral\u0131m. Bu dosya, Presigned URL'leri olu\u015fturacak mant\u0131\u011f\u0131 i\u00e7erecektir.<\/p>\n<pre><code class=\"language-python\">\n# main.py\nimport os\nfrom fastapi import FastAPI, HTTPException\nfrom pydantic import BaseModel\nfrom dotenv import load_dotenv\nimport boto3\n\n# .env dosyas\u0131n\u0131 y\u00fckle\nload_dotenv()\n\napp = FastAPI(\n    title=\"G\u00fcvenli Dosya Y\u00fckleme API'si\",\n    description=\"AWS S3 Presigned URL'ler ile g\u00fcvenli ve \u00f6l\u00e7eklenebilir dosya y\u00fckleme API'si.\",\n    version=\"1.0.0\"\n)\n\n# Ortam de\u011fi\u015fkenlerini al\nAWS_ACCESS_KEY_ID = os.getenv(\"AWS_ACCESS_KEY_ID\")\nAWS_SECRET_ACCESS_KEY = os.getenv(\"AWS_SECRET_ACCESS_KEY\")\nAWS_REGION = os.getenv(\"AWS_REGION\")\nS3_BUCKET_NAME = os.getenv(\"S3_BUCKET_NAME\")\n\n# Ortam de\u011fi\u015fkenlerinin varl\u0131\u011f\u0131n\u0131 kontrol et\nif not all([AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, S3_BUCKET_NAME]):\n    raise EnvironmentError(\"T\u00fcm AWS ortam de\u011fi\u015fkenleri ayarlanmal\u0131d\u0131r.\")\n\n# S3 istemcisini ba\u015flat\ns3_client = boto3.client(\n    \"s3\",\n    aws_access_key_id=AWS_ACCESS_KEY_ID,\n    aws_secret_access_key=AWS_SECRET_ACCESS_KEY,\n    region_name=AWS_REGION\n)\n\n@app.get(\"\/\")\nasync def read_root():\n    return {\"message\": \"FastAPI ve AWS S3 ile Dosya Y\u00fckleme API'sine Ho\u015f Geldiniz!\"}\n\n# --- Sonraki b\u00f6l\u00fcmde Presigned URL endpoint'i buraya gelecek ---\n    <\/pre>\n<p><\/code><\/p>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: Ortam de\u011fi\u015fkenlerini y\u00fcklemek i\u00e7in <code>python-dotenv<\/code> kullanmak, hassas bilgileri kod taban\u0131ndan ay\u0131rarak g\u00fcvenlik risklerini minimize eder ve farkl\u0131 ortamlarda (geli\u015ftirme, test, \u00fcretim) kolayca y\u00f6netilmesini sa\u011flar. Bu y\u00f6ntem, uygulaman\u0131z\u0131n da\u011f\u0131t\u0131m\u0131n\u0131 da olduk\u00e7a basitle\u015ftirir.\n    <\/div>\n<p>Bu temel yap\u0131land\u0131rma ile art\u0131k FastAPI uygulamam\u0131z\u0131n AWS S3 ile konu\u015fmaya haz\u0131r oldu\u011funu s\u00f6yleyebiliriz. Ortam de\u011fi\u015fkenlerinin do\u011fru bir \u015fekilde y\u00fcklendi\u011finden ve S3 istemcisinin ba\u015far\u0131yla ba\u015flat\u0131ld\u0131\u011f\u0131ndan emin olduk. Bir sonraki b\u00f6l\u00fcmde, as\u0131l i\u015flevi olan Presigned URL olu\u015fturma mekanizmas\u0131n\u0131 geli\u015ftirece\u011fiz.<\/p>\n<h2>Presigned URL Olu\u015fturma Mekanizmas\u0131: Kullan\u0131c\u0131 Dosyalar\u0131n\u0131 Do\u011frudan S3'e Y\u00fcklemek \u0130\u00e7in Presigned URL'leri Nas\u0131l \u00dcretiriz?<\/h2>\n<p>API'mizin kalbi olan Presigned URL olu\u015fturma i\u015flevine odaklanal\u0131m. Bu mekanizma, istemcilere dosyalar\u0131n\u0131 do\u011frudan S3'e y\u00fckleyebilmeleri i\u00e7in g\u00fcvenli, ge\u00e7ici bir anahtar sa\u011flayacak. <code>boto3<\/code> k\u00fct\u00fcphanesini kullanarak bu URL'leri nas\u0131l olu\u015fturaca\u011f\u0131m\u0131z\u0131 ve FastAPI \u00fczerinden nas\u0131l sunaca\u011f\u0131m\u0131z\u0131 ad\u0131m ad\u0131m inceleyece\u011fiz.<\/p>\n<p>AWS S3, iki ana t\u00fcrde Presigned URL olu\u015fturma y\u00f6ntemine sahiptir: <code>generate_presigned_url<\/code> ve <code>generate_presigned_post<\/code>. Bunlar\u0131n her ikisinin de farkl\u0131 kullan\u0131m senaryolar\u0131 ve avantajlar\u0131 vard\u0131r:<\/p>\n<ul>\n<li><strong><code>generate_presigned_url<\/code> (Tek Part Y\u00fckleme veya \u0130ndirme \u0130\u00e7in):<\/strong> Bu y\u00f6ntem, belirli bir S3 nesnesine (dosyas\u0131na) tek bir HTTP <code>PUT<\/code> iste\u011fi ile dosya y\u00fcklemek veya tek bir HTTP <code>GET<\/code> iste\u011fi ile dosya indirmek i\u00e7in kullan\u0131l\u0131r. Genellikle daha k\u00fc\u00e7\u00fck dosyalar i\u00e7in veya basit indirme ba\u011flant\u0131lar\u0131 olu\u015fturmak i\u00e7in tercih edilir. \u0130stemcinin dosyay\u0131 do\u011frudan bu URL'ye <code>PUT<\/code> etmesi yeterlidir.<\/li>\n<li><strong><code>generate_presigned_post<\/code> (Form Tabanl\u0131 Y\u00fckleme \u0130\u00e7in):<\/strong> Bu y\u00f6ntem, \u00f6zellikle HTML formlar\u0131 arac\u0131l\u0131\u011f\u0131yla dosya y\u00fcklemek i\u00e7in tasarlanm\u0131\u015ft\u0131r. Sadece bir URL de\u011fil, ayn\u0131 zamanda y\u00fckleme iste\u011finde bulunmas\u0131 gereken bir dizi \"alan\" (fields) d\u00f6nd\u00fcr\u00fcr. Bu alanlar, S3'e yap\u0131lan <code>POST<\/code> iste\u011finin bir par\u00e7as\u0131 olarak g\u00f6nderilmelidir. Genellikle taray\u0131c\u0131 tabanl\u0131 y\u00fcklemelerde veya daha karma\u015f\u0131k g\u00fcvenlik politikalar\u0131 uygulamak istedi\u011finizde kullan\u0131l\u0131r. B\u00fcy\u00fck dosyalar i\u00e7in daha uygun olabilir ve istemciye \u00e7ok par\u00e7al\u0131 y\u00fcklemeyi (multipart upload) daha kolay yapma imkan\u0131 sunar.<\/li>\n<\/ul>\n<p>Bizim senaryomuzda, hem esneklik hem de geni\u015f taray\u0131c\u0131 deste\u011fi sa\u011flamak ad\u0131na <code>generate_presigned_post<\/code> metodunu kullanaca\u011f\u0131z. Bu metodun sundu\u011fu \"alanlar\" sayesinde, S3'e yap\u0131lan iste\u011fi daha detayl\u0131 bir \u015fekilde kontrol edebiliriz.<\/p>\n<h3>Presigned POST URL Olu\u015fturma Endpoint'i Nas\u0131l Tasarlan\u0131r?<\/h3>\n<p>FastAPI uygulamam\u0131zda, istemcinin bir Presigned URL talep edece\u011fi bir endpoint tan\u0131mlayaca\u011f\u0131z. Bu endpoint, istemciden y\u00fcklemek istedi\u011fi dosyan\u0131n ad\u0131n\u0131 ve iste\u011fe ba\u011fl\u0131 olarak dosya t\u00fcr\u00fcn\u00fc (MIME type) alacakt\u0131r. Ard\u0131ndan, S3 i\u00e7in Presigned POST URL'sini olu\u015fturup istemciye geri d\u00f6nd\u00fcrecektir.<\/p>\n<p>\u00d6ncelikle, istemciden gelecek iste\u011fin yap\u0131s\u0131n\u0131 tan\u0131mlayal\u0131m. Bir Pydantic modeli kullanarak dosya ad\u0131 ve (iste\u011fe ba\u011fl\u0131) i\u00e7erik t\u00fcr\u00fc bilgilerini alabiliriz.<\/p>\n<pre><code class=\"language-python\">\n# main.py i\u00e7indeki di\u011fer kodlar\u0131n alt\u0131na ekleyin\n\nclass FileUploadRequest(BaseModel):\n    file_name: str\n    content_type: str = \"application\/octet-stream\" # Varsay\u0131lan olarak ikili veri\n\nclass PresignedPostResponse(BaseModel):\n    url: str\n    fields: dict\n\n@app.post(\"\/get-presigned-url\", response_model=PresignedPostResponse)\nasync def get_presigned_url(request: FileUploadRequest):\n    \"\"\"\n    Kullan\u0131c\u0131n\u0131n S3'e dosya y\u00fcklemesi i\u00e7in bir Presigned POST URL'si d\u00f6nd\u00fcr\u00fcr.\n    \"\"\"\n    object_name = request.file_name # S3'te depolanacak dosya ad\u0131\n\n    try:\n        # Presigned POST URL'sini olu\u015ftur\n        # expiration: URL'nin ge\u00e7erlilik s\u00fcresi (saniye cinsinden)\n        # Conditions: Y\u00fckleme iste\u011finde kar\u015f\u0131lanmas\u0131 gereken ko\u015fullar.\n        #             Bu \u00f6rnekte: 'Content-Type' ve 'Content-Length' kontrol\u00fc.\n        response = s3_client.generate_presigned_post(\n            Bucket=S3_BUCKET_NAME,\n            Key=object_name,\n            Fields={\"Content-Type\": request.content_type},\n            Conditions=[\n                {\"Content-Type\": request.content_type},\n                [\"content-length-range\", 0, 104857600] # 0 byte'tan 100 MB'a kadar\n            ],\n            ExpiresIn=300 # 5 dakika (300 saniye) ge\u00e7erlilik s\u00fcresi\n        )\n        return PresignedPostResponse(url=response[\"url\"], fields=response[\"fields\"])\n    except Exception as e:\n        raise HTTPException(status_code=500, detail=f\"Presigned URL olu\u015fturulurken hata olu\u015ftu: {str(e)}\")\n    <\/pre>\n<p><\/code><\/p>\n<p>Yukar\u0131daki kod blo\u011funda, <code>get_presigned_url<\/code> adl\u0131 bir POST endpoint'i tan\u0131mlad\u0131k. Bu endpoint, <code>FileUploadRequest<\/code> modeliyle uyumlu bir JSON g\u00f6vdesi bekler. \u0130\u00e7eride:<\/p>\n<ul>\n<li><code>object_name<\/code>: S3'e y\u00fcklenecek dosyan\u0131n ad\u0131n\u0131 belirtir. Genellikle bu, kullan\u0131c\u0131 taraf\u0131ndan sa\u011flanan dosya ad\u0131yla ayn\u0131d\u0131r veya daha iyi bir g\u00fcvenlik i\u00e7in sunucu taraf\u0131nda olu\u015fturulan benzersiz bir ID (UUID) ile \u00f6n eklenir.<\/li>\n<li><code>generate_presigned_post<\/code>: Bu <code>boto3<\/code> metodu ile as\u0131l Presigned URL ve gerekli alanlar olu\u015fturulur.\n<ul>\n<li><code>Bucket<\/code>: Dosyan\u0131n y\u00fcklenece\u011fi S3 kovan\u0131n\u0131n ad\u0131.<\/li>\n<li><code>Key<\/code>: S3'teki dosyan\u0131n tam yolu ve ad\u0131.<\/li>\n<li><code>Fields<\/code>: S3'e yap\u0131lacak POST iste\u011finde bulunmas\u0131 gereken ekstra form alanlar\u0131. Burada <code>Content-Type<\/code>'\u0131 belirtiyoruz.<\/li>\n<li><code>Conditions<\/code>: S3'\u00fcn y\u00fcklemeyi kabul etmesi i\u00e7in kar\u015f\u0131lanmas\u0131 gereken ko\u015fullar. Bu, g\u00fcvenlik i\u00e7in kritik \u00f6neme sahiptir.\n<ul>\n<li><code>{\"Content-Type\": request.content_type}<\/code>: Y\u00fcklenen dosyan\u0131n t\u00fcr\u00fcn\u00fcn API'mize bildirilenle e\u015fle\u015fmesini sa\u011flar. Bu, k\u00f6t\u00fc ama\u00e7l\u0131 dosya y\u00fcklemelerini engellemek i\u00e7in ilk g\u00fcvenlik katman\u0131d\u0131r.<\/li>\n<li><code>[\"content-length-range\", 0, 104857600]<\/code>: Y\u00fcklenen dosyan\u0131n boyutunun 0 ile 100 MB (100 * 1024 * 1024 byte) aras\u0131nda olmas\u0131n\u0131 sa\u011flar. Bu da sunucuyu a\u015f\u0131r\u0131 y\u00fcklenmeden korur.<\/li>\n<\/ul>\n<\/li>\n<li><code>ExpiresIn<\/code>: Olu\u015fturulan URL'nin saniye cinsinden ge\u00e7erlilik s\u00fcresi. Burada 5 dakika olarak ayarlanm\u0131\u015ft\u0131r.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: <code>object_name<\/code> i\u00e7in kullan\u0131c\u0131dan gelen dosya ad\u0131n\u0131 do\u011frudan kullanmak yerine, sunucu taraf\u0131nda benzersiz bir dosya ad\u0131 olu\u015fturmak (\u00f6rne\u011fin bir UUID veya zaman damgas\u0131 kullanarak) \u00e7ak\u0131\u015fmalar\u0131 ve potansiyel g\u00fcvenlik sorunlar\u0131n\u0131 (dizin ge\u00e7i\u015fi sald\u0131r\u0131lar\u0131 gibi) \u00f6nlemek a\u00e7\u0131s\u0131ndan \u00e7ok daha g\u00fcvenlidir. \u00d6rne\u011fin: <code>object_name = f\"uploads\/{uuid.uuid4()}-{request.file_name}\"<\/code>\n    <\/div>\n<h3>Vaka Analizi: B\u00fcy\u00fck Dosya Y\u00fcklemelerinde Performans Kazanc\u0131<\/h3>\n<p>Bir video d\u00fczenleme yaz\u0131l\u0131m\u0131n\u0131n bulut tabanl\u0131 bir versiyonunu geli\u015ftirdi\u011finizi d\u00fc\u015f\u00fcn\u00fcn. Kullan\u0131c\u0131lar, y\u00fczlerce megabayt hatta gigabaytlarca boyutunda video dosyalar\u0131n\u0131 y\u00fcklemek durumunda kal\u0131yor. Geleneksel yakla\u015f\u0131mla, her bir video dosyas\u0131n\u0131n \u00f6nce API sunucunuz \u00fczerinden ge\u00e7mesi, sunucunuzun i\u015flemci, bellek ve a\u011f kaynaklar\u0131n\u0131 ciddi \u015fekilde zorlayacakt\u0131r. Bu, sunucunuzun yava\u015flamas\u0131na, di\u011fer kullan\u0131c\u0131 isteklerine yan\u0131t verememesine ve hatta \u00e7\u00f6kmesine neden olabilir.<\/p>\n<p>Presigned URL yakla\u015f\u0131m\u0131yla ise, kullan\u0131c\u0131 video dosyas\u0131n\u0131 y\u00fcklemeye ba\u015flad\u0131\u011f\u0131nda:<\/p>\n<ol>\n<li>\u0130stemci (taray\u0131c\u0131 veya uygulama), FastAPI API'nize sadece dosya ad\u0131 ve t\u00fcr\u00fcyle bir Presigned URL talep eder.<\/li>\n<li>API, bu hafif iste\u011fi al\u0131r, S3'ten bir Presigned POST URL'si olu\u015fturur (yakla\u015f\u0131k milisaniyeler s\u00fcrer) ve istemciye geri d\u00f6ner.<\/li>\n<li>\u0130stemci, as\u0131l video dosyas\u0131n\u0131 bu Presigned URL'yi kullanarak <strong>do\u011frudan AWS S3'e<\/strong> y\u00fckler. API sunucunuz bu i\u015flemden tamamen muaf kal\u0131r.<\/li>\n<\/ol>\n<p>Bu y\u00f6ntem sayesinde, API sunucunuzun y\u00fck\u00fc \u00f6nemli \u00f6l\u00e7\u00fcde azal\u0131r. Sunucunuz sadece koordinat\u00f6r g\u00f6revi g\u00f6r\u00fcrken, a\u011f\u0131r y\u00fckleme i\u015flemi S3'\u00fcn devasa \u00f6l\u00e7eklenebilirli\u011fi taraf\u0131ndan kar\u015f\u0131lan\u0131r. Bu, \u00f6zellikle b\u00fcy\u00fck dosyalar\u0131n s\u0131k\u00e7a y\u00fcklendi\u011fi senaryolarda performans\u0131 %40 veya daha fazla art\u0131rabilir. Kullan\u0131c\u0131lar daha h\u0131zl\u0131 y\u00fckleme deneyimi ya\u015far, API sunucunuz daha kararl\u0131 \u00e7al\u0131\u015f\u0131r ve operasyonel maliyetler d\u00fc\u015fer.<\/p>\n<h2>\u0130stemci Taraf\u0131ndan Dosya Y\u00fckleme: Web Taray\u0131c\u0131s\u0131ndan S3'e G\u00fcvenli Y\u00fckleme Nas\u0131l Ger\u00e7ekle\u015ftirilir?<\/h2>\n<p>API'miz Presigned URL'yi olu\u015fturduktan sonra, s\u0131ra istemci taraf\u0131nda bu URL'yi kullanarak dosyay\u0131 S3'e y\u00fcklemeye gelir. Bu b\u00f6l\u00fcmde, bir web taray\u0131c\u0131s\u0131ndan (HTML ve JavaScript kullanarak) S3'e dosya y\u00fckleme s\u00fcrecini ad\u0131m ad\u0131m g\u00f6sterece\u011fiz. Bu, genellikle bir React, Vue veya Angular uygulamas\u0131 i\u00e7inde, veya basit bir HTML\/JS formunda ger\u00e7ekle\u015ftirilebilir.<\/p>\n<h3>HTML Formu ve JavaScript Mant\u0131\u011f\u0131<\/h3>\n<p>\u0130lk olarak, kullan\u0131c\u0131dan dosya se\u00e7mesini sa\u011flayacak basit bir HTML formu olu\u015ftural\u0131m. Ard\u0131ndan, JavaScript kullanarak bu formu nas\u0131l i\u015fleyece\u011fimizi ve Presigned URL ile S3'e nas\u0131l y\u00fckleme yapaca\u011f\u0131m\u0131z\u0131 g\u00f6relim.<\/p>\n<p><strong>HTML (<code>index.html<\/code>)<\/strong><\/p>\n<pre><code class=\"language-html\">\n<!DOCTYPE html>\n<html lang=\"tr\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>S3 Dosya Y\u00fckleyici<\/title>\n    <style>\n        body {\n            font-family: Arial, sans-serif;\n            margin: 20px;\n            background-color: #f4f4f4;\n            color: #333;\n        }\n        .container {\n            max-width: 600px;\n            margin: 50px auto;\n            background: #fff;\n            padding: 30px;\n            border-radius: 8px;\n            box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n        }\n        h2 {\n            color: #0056b3;\n            text-align: center;\n            margin-bottom: 30px;\n        }\n        label {\n            display: block;\n            margin-bottom: 8px;\n            font-weight: bold;\n        }\n        input[type=\"file\"] {\n            display: block;\n            width: 100%;\n            padding: 10px;\n            margin-bottom: 20px;\n            border: 1px solid #ddd;\n            border-radius: 4px;\n            box-sizing: border-box;\n            background-color: #fcfcfc;\n        }\n        button {\n            background-color: #007bff;\n            color: white;\n            padding: 12px 20px;\n            border: none;\n            border-radius: 5px;\n            cursor: pointer;\n            font-size: 16px;\n            width: 100%;\n            transition: background-color 0.3s ease;\n        }\n        button:hover {\n            background-color: #0056b3;\n        }\n        #status {\n            margin-top: 20px;\n            padding: 10px;\n            border-radius: 5px;\n            background-color: #e9ecef;\n            color: #333;\n            text-align: center;\n        }\n        #status.success {\n            background-color: #d4edda;\n            color: #155724;\n        }\n        #status.error {\n            background-color: #f8d7da;\n            color: #721c24;\n        }\n\n        \/* Mobil Uyumlu Tasar\u0131m \u0130\u00e7in Media Query \u00d6rne\u011fi *\/\n        @media (max-width: 768px) {\n            .container {\n                margin: 20px;\n                padding: 20px;\n            }\n            h2 {\n                font-size: 20px;\n            }\n            button {\n                font-size: 14px;\n                padding: 10px 15px;\n            }\n        }\n    <\/style>\n<\/head>\n<body>\n    <div class=\"container\">\n        <h2>Dosyay\u0131 S3'e Y\u00fckle<\/h2>\n        <form id=\"uploadForm\">\n            <label for=\"fileInput\">Y\u00fcklenecek Dosya:<\/label>\n            <input type=\"file\" id=\"fileInput\" name=\"file\" required>\n            <button type=\"submit\">Dosyay\u0131 Y\u00fckle<\/button>\n        <\/form>\n        <div id=\"status\">Y\u00fcklemeye haz\u0131r.<\/div>\n    <\/div>\n\n    <script>\n        document.getElementById('uploadForm').addEventListener('submit', async function(event) {\n            event.preventDefault(); \/\/ Formun varsay\u0131lan submit davran\u0131\u015f\u0131n\u0131 engelle\n\n            const fileInput = document.getElementById('fileInput');\n            const file = fileInput.files[0];\n            const statusDiv = document.getElementById('status');\n\n            if (!file) {\n                statusDiv.className = 'error';\n                statusDiv.textContent = 'L\u00fctfen bir dosya se\u00e7in.';\n                return;\n            }\n\n            statusDiv.className = '';\n            statusDiv.textContent = 'Presigned URL al\u0131n\u0131yor...';\n\n            try {\n                \/\/ 1. FastAPI API'den Presigned URL talep et\n                const apiResponse = await fetch('http:\/\/127.0.0.1:8000\/get-presigned-url', { \/\/ FastAPI sunucunuzun adresi\n                    method: 'POST',\n                    headers: {\n                        'Content-Type': 'application\/json',\n                    },\n                    body: JSON.stringify({\n                        file_name: file.name,\n                        content_type: file.type || 'application\/octet-stream'\n                    }),\n                });\n\n                if (!apiResponse.ok) {\n                    throw new Error(<code>API hatas\u0131: ${apiResponse.statusText}<\/code>);\n                }\n\n                const { url, fields } = await apiResponse.json();\n                statusDiv.textContent = 'Presigned URL al\u0131nd\u0131, S3\\'e y\u00fckleniyor...';\n\n                \/\/ 2. Presigned URL ve alanlar\u0131 kullanarak dosyay\u0131 do\u011frudan S3'e y\u00fckle\n                const formData = new FormData();\n                for (const key in fields) {\n                    formData.append(key, fields[key]);\n                }\n                formData.append('file', file); \/\/ Dosyay\u0131 en sona eklemek en iyi y\u00f6ntemdir\n\n                const s3Response = await fetch(url, {\n                    method: 'POST',\n                    body: formData,\n                });\n\n                if (s3Response.ok) {\n                    statusDiv.className = 'success';\n                    statusDiv.textContent = <code>Dosya \"${file.name}\" S3&#039;e ba\u015far\u0131yla y\u00fcklendi!<\/code>;\n                    fileInput.value = ''; \/\/ Y\u00fckleme sonras\u0131 inputu temizle\n                } else {\n                    const errorText = await s3Response.text();\n                    throw new Error(<code>S3 y\u00fckleme hatas\u0131: ${s3Response.statusText} - ${errorText}<\/code>);\n                }\n\n            } catch (error) {\n                statusDiv.className = 'error';\n                statusDiv.textContent = <code>Y\u00fckleme ba\u015far\u0131s\u0131z oldu: ${error.message}<\/code>;\n                console.error('Y\u00fckleme hatas\u0131:', error);\n            }\n        });\n    <\/script>\n<\/body>\n<\/html>\n    <\/pre>\n<p><\/code><\/p>\n<p><strong>JavaScript Mant\u0131\u011f\u0131n\u0131n A\u00e7\u0131klamas\u0131:<\/strong><\/p>\n<ol>\n<li><strong>Form G\u00f6nderimini Engelleme:<\/strong> <code>event.preventDefault()<\/code> ile taray\u0131c\u0131n\u0131n varsay\u0131lan form g\u00f6nderme davran\u0131\u015f\u0131n\u0131 durduruyoruz. Bu sayede AJAX ile y\u00fckleme yapabiliriz.<\/li>\n<li><strong>Dosyay\u0131 Se\u00e7me:<\/strong> <code>fileInput.files[0]<\/code> ile kullan\u0131c\u0131n\u0131n se\u00e7ti\u011fi ilk dosyay\u0131 al\u0131yoruz.<\/li>\n<li><strong>Presigned URL Talebi:<\/strong>\n<ul>\n<li><code>fetch('http:\/\/127.0.0.1:8000\/get-presigned-url', ...)<\/code> ile FastAPI API'mize bir <code>POST<\/code> iste\u011fi g\u00f6nderiyoruz.<\/li>\n<li>\u0130stek g\u00f6vdesinde (<code>body<\/code>), y\u00fcklemek istedi\u011fimiz dosyan\u0131n ad\u0131n\u0131 (<code>file.name<\/code>) ve t\u00fcr\u00fcn\u00fc (<code>file.type<\/code>) JSON format\u0131nda belirtiyoruz. Bu bilgiler, API'mizin S3'ten do\u011fru Presigned URL'yi istemesi i\u00e7in gereklidir.<\/li>\n<li>API'den gelen yan\u0131t, S3'e dosya y\u00fcklemek i\u00e7in kullanaca\u011f\u0131m\u0131z <code>url<\/code> ve <code>fields<\/code> nesnelerini i\u00e7erir.<\/li>\n<\/ul>\n<\/li>\n<li><strong>S3'e Dosya Y\u00fckleme:<\/strong>\n<ul>\n<li><code>FormData<\/code> nesnesi olu\u015fturuyoruz. Bu, dosya ve S3'ten gelen di\u011fer alanlar\u0131 (<code>fields<\/code>) bir HTTP <code>POST<\/code> iste\u011finin g\u00f6vdesine eklemek i\u00e7in kullan\u0131l\u0131r.<\/li>\n<li><code>for (const key in fields) { formData.append(key, fields[key]); }<\/code> d\u00f6ng\u00fcs\u00fcyle, Presigned POST URL'sinden ald\u0131\u011f\u0131m\u0131z t\u00fcm alanlar\u0131 <code>formData<\/code>'ya ekliyoruz. Bu alanlar S3'\u00fcn y\u00fcklemeyi kabul etmesi i\u00e7in kritik \u00f6neme sahiptir.<\/li>\n<li><code>formData.append('file', file);<\/code> ile as\u0131l dosya i\u00e7eri\u011fini <code>formData<\/code>'ya ekliyoruz. Buradaki 'file' anahtar\u0131, S3'\u00fcn bekledi\u011fi varsay\u0131lan dosya alan\u0131d\u0131r.<\/li>\n<li>Son olarak, <code>fetch(url, { method: 'POST', body: formData })<\/code> ile bu <code>formData<\/code>'y\u0131 do\u011frudan S3'\u00fcn bize verdi\u011fi <code>url<\/code>'ye <code>POST<\/code> ediyoruz. \u0130\u015fte bu noktada dosya, API sunucumuza u\u011framadan direkt S3'e gidiyor!<\/li>\n<\/ul>\n<\/li>\n<li><strong>Durum G\u00fcncellemesi:<\/strong> Y\u00fckleme s\u00fcreci boyunca kullan\u0131c\u0131ya geri bildirim sa\u011flamak i\u00e7in <code>statusDiv<\/code> elementini kullan\u0131yoruz.<\/li>\n<\/ol>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: Taray\u0131c\u0131 taraf\u0131nda dosya y\u00fckleme ilerlemesini g\u00f6stermek i\u00e7in Fetch API'nin <code>upload.onprogress<\/code> olay\u0131n\u0131 veya \u00f6zel bir k\u00fct\u00fcphane (\u00f6rne\u011fin Axios) kullanabilirsiniz. Bu, \u00f6zellikle b\u00fcy\u00fck dosyalar i\u00e7in kullan\u0131c\u0131 deneyimini \u00f6nemli \u00f6l\u00e7\u00fcde iyile\u015ftirir.\n    <\/div>\n<p>Bu istemci taraf\u0131 kod, Presigned URL'ler ile g\u00fcvenli ve do\u011frudan S3 y\u00fcklemesini nas\u0131l ger\u00e7ekle\u015ftirece\u011finizi g\u00f6sterir. Bu yakla\u015f\u0131m, hem g\u00fcvenlik hem de performans a\u00e7\u0131s\u0131ndan geleneksel y\u00f6ntemlere g\u00f6re \u00e7ok daha \u00fcst\u00fcnd\u00fcr.<\/p>\n<h2>Y\u00fcklenen Dosyalar\u0131 Y\u00f6netme ve G\u00fcvenlik Best Practices: S3'teki Dosyalar\u0131 G\u00fcvenli Bir \u015eekilde Nas\u0131l Y\u00f6netece\u011fiz?<\/h2>\n<p>Dosyalar\u0131 g\u00fcvenli bir \u015fekilde S3'e y\u00fcklemek sadece ba\u015flang\u0131\u00e7t\u0131r. As\u0131l mesele, bu dosyalar\u0131 uzun vadede nas\u0131l y\u00f6netece\u011fimiz, eri\u015fimi nas\u0131l kontrol edece\u011fimiz ve olas\u0131 g\u00fcvenlik a\u00e7\u0131klar\u0131na kar\u015f\u0131 nas\u0131l koruyaca\u011f\u0131m\u0131zd\u0131r. Bu b\u00f6l\u00fcmde, S3'teki dosyalar\u0131n\u0131z\u0131 daha da g\u00fcvenli hale getirecek en iyi uygulamalar\u0131 ve ek y\u00f6netim stratejilerini ele alaca\u011f\u0131z.<\/p>\n<h3>1. S3 Kova Politikalar\u0131 ve IAM Kullan\u0131m\u0131<\/h3>\n<p>S3'teki en temel g\u00fcvenlik katman\u0131, IAM (Identity and Access Management) kullan\u0131c\u0131lar\u0131 ve S3 kova politikalar\u0131d\u0131r. Daha \u00f6nce API kullan\u0131c\u0131m\u0131z i\u00e7in belirli izinler tan\u0131mlam\u0131\u015ft\u0131k. Ancak, bazen do\u011frudan bir kovaya (bucket) veya i\u00e7indeki belirli bir klas\u00f6re eri\u015fim k\u0131s\u0131tlamalar\u0131 getirmek isteyebilirsiniz. \u00d6rne\u011fin, sadece belirli IP adreslerinden veya belirli bir IAM rol\u00fcne sahip kullan\u0131c\u0131lar\u0131n kovan\u0131za yazma iznine sahip olmas\u0131n\u0131 sa\u011flayabilirsiniz.<\/p>\n<pre><code class=\"language-json\">\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"RestrictAccessToSpecificFolder\",\n            \"Effect\": \"Deny\",\n            \"Principal\": \"*\",\n            \"Action\": \"s3:PutObject\",\n            \"Resource\": \"arn:aws:s3:::your-bucket-name\/sensitive-data\/*\",\n            \"Condition\": {\n                \"NotIpAddress\": {\n                    \"aws:SourceIp\": \"192.0.2.0\/24\"\n                }\n            }\n        },\n        {\n            \"Sid\": \"AllowReadAccessForPublicImages\",\n            \"Effect\": \"Allow\",\n            \"Principal\": \"*\",\n            \"Action\": \"s3:GetObject\",\n            \"Resource\": \"arn:aws:s3:::your-bucket-name\/public-images\/*\"\n        }\n    ]\n}\n    <\/pre>\n<p><\/code><\/p>\n<p>Bu \u00f6rnek politika, <code>sensitive-data<\/code> klas\u00f6r\u00fcne belirli bir IP aral\u0131\u011f\u0131 d\u0131\u015f\u0131ndaki t\u00fcm yazma i\u015flemlerini engellerken, <code>public-images<\/code> klas\u00f6r\u00fcndeki nesnelere herkese a\u00e7\u0131k okuma eri\u015fimi verir. S3 kova politikalar\u0131, \u00e7ok ince taneli eri\u015fim kontrol\u00fc sa\u011flamak i\u00e7in \u00e7ok g\u00fc\u00e7l\u00fcd\u00fcr.<\/p>\n<h3>2. Dosya Adland\u0131rma Stratejileri<\/h3>\n<p>G\u00fcvenli ve y\u00f6netilebilir bir dosya depolama sistemi i\u00e7in dosya adland\u0131rma kritik \u00f6neme sahiptir. A\u015fa\u011f\u0131daki stratejileri g\u00f6z \u00f6n\u00fcnde bulundurun:<\/p>\n<ul>\n<li><strong>Benzersiz Kimlikler (UUID):<\/strong> Her y\u00fcklenen dosyaya benzersiz bir kimlik (UUID - Universally Unique Identifier) atay\u0131n. Bu, dosya adlar\u0131n\u0131n \u00e7ak\u0131\u015fmas\u0131n\u0131 engeller ve ayn\u0131 ada sahip dosyalar\u0131n \u00fczerine yaz\u0131lmas\u0131n\u0131 \u00f6nler. \u00d6rne\u011fin, <code>f\"{uuid.uuid4()}-{original_filename}\"<\/code>.<\/li>\n<li><strong>Klas\u00f6rleme\/Prefixleme:<\/strong> Dosyalar\u0131 mant\u0131ksal olarak klas\u00f6rlere ay\u0131r\u0131n (S3'te klas\u00f6rler asl\u0131nda nesne adlar\u0131ndaki \u00f6neklerdir). \u00d6rne\u011fin, <code>user_uploads\/{user_id}\/{uuid}-{filename}<\/code> veya <code>images\/{year}\/{month}\/{day}\/{uuid}.jpg<\/code>. Bu, dosyalar\u0131n daha kolay bulunmas\u0131n\u0131 ve y\u00f6netilmesini sa\u011flar.<\/li>\n<li><strong>Orijinal Ad\u0131 Saklama:<\/strong> Kullan\u0131c\u0131 deneyimi i\u00e7in orijinal dosya ad\u0131n\u0131 bir meta veri olarak saklamak veya S3 anahtar\u0131nda (key) bir UUID'den sonra kullanmak faydal\u0131 olabilir.<\/li>\n<\/ul>\n<h3>3. Y\u00fckleme Sonras\u0131 \u0130\u015flemler (S3 Olaylar\u0131 ve AWS Lambda)<\/h3>\n<p>S3, bir nesneye (dosyaya) bir olay (y\u00fckleme, silme vb.) ger\u00e7ekle\u015fti\u011finde di\u011fer AWS servislerini tetikleyebilen g\u00fc\u00e7l\u00fc bir olay bildirim sistemine sahiptir. Bu \u00f6zellik, y\u00fckleme sonras\u0131 i\u015flemleri otomatikle\u015ftirmek i\u00e7in harikad\u0131r:<\/p>\n<ul>\n<li><strong>G\u00f6rsel \u0130\u015fleme:<\/strong> Bir resim y\u00fcklendi\u011finde, bir AWS Lambda fonksiyonunu tetikleyebilir ve bu fonksiyon g\u00f6r\u00fcnt\u00fcy\u00fc yeniden boyutland\u0131rabilir, filigran ekleyebilir veya k\u00fc\u00e7\u00fck resimler (thumbnails) olu\u015fturabilir.<\/li>\n<li><strong>Dosya Taramas\u0131:<\/strong> Y\u00fcklenen dosyalar\u0131 k\u00f6t\u00fc ama\u00e7l\u0131 yaz\u0131l\u0131mlara kar\u015f\u0131 taramak i\u00e7in Lambda veya ba\u015fka bir g\u00fcvenlik servisini tetikleyebilir.<\/li>\n<li><strong>Veritaban\u0131 Kayd\u0131:<\/strong> Y\u00fckleme tamamland\u0131ktan sonra dosya bilgilerini (S3 URL'si, dosya ad\u0131, boyutu vb.) veritaban\u0131na kaydedebilir.<\/li>\n<li><strong>Bildirimler:<\/strong> Y\u00fckleme ba\u015far\u0131l\u0131 oldu\u011funda kullan\u0131c\u0131ya veya y\u00f6neticilere bir e-posta veya bildirim g\u00f6nderebilir.<\/li>\n<\/ul>\n<p>Bu senaryolar, sunucu taraf\u0131ndaki API'nizi daha da hafifletirken, i\u015f mant\u0131\u011f\u0131n\u0131 arka planda asenkron olarak y\u00fcr\u00fctmenizi sa\u011flar.<\/p>\n<h3>4. ACL'ler ve Genel Eri\u015fim Kontrol\u00fc<\/h3>\n<p>S3 nesneleri i\u00e7in ACL'ler (Access Control Lists) kullanarak her bir nesneye \u00f6zel eri\u015fim izinleri tan\u0131mlayabilirsiniz. Ancak, AWS genellikle kova politikalar\u0131 ve IAM kullanarak daha merkezi ve y\u00f6netilebilir eri\u015fim kontrol\u00fc sa\u011flamay\u0131 \u00f6nerir. \"Block all public access\" ayar\u0131n\u0131 etkin tutmak ve sadece ihtiyac\u0131n\u0131z oldu\u011funda belirli nesneleri veya prefixleri herkese a\u00e7\u0131k hale getirmek en g\u00fcvenli yakla\u015f\u0131md\u0131r. E\u011fer bir dosyan\u0131n indirilmesi gerekiyorsa, bunun i\u00e7in de bir Presigned URL olu\u015fturmak en g\u00fcvenli y\u00f6ntemdir.<\/p>\n<h3>5. G\u00fcvenlik A\u00e7\u0131klar\u0131 ve \u00d6nlemleri<\/h3>\n<ul>\n<li><strong>MIME Type Do\u011frulama:<\/strong> Presigned URL olu\u015ftururken <code>Conditions<\/code> i\u00e7inde <code>Content-Type<\/code> belirterek istemcinin bildirdi\u011fi t\u00fcr\u00fcn ge\u00e7erli oldu\u011fundan emin olun. Ayr\u0131ca, dosyan\u0131n uzant\u0131s\u0131n\u0131 kontrol eden veya dosyan\u0131n ger\u00e7ek MIME t\u00fcr\u00fcn\u00fc (magic number'lara bakarak) do\u011frulayan bir y\u00fckleme sonras\u0131 Lambda fonksiyonu ekleyebilirsiniz.<\/li>\n<li><strong>Dosya Boyutu Limitleri:<\/strong> Hem Presigned URL olu\u015ftururken <code>content-length-range<\/code> ko\u015fulu ile hem de istemci taraf\u0131nda (JavaScript ile) dosya boyutunu s\u0131n\u0131rlayarak potansiyel DoS sald\u0131r\u0131lar\u0131n\u0131 veya yanl\u0131\u015fl\u0131kla devasa dosyalar\u0131n y\u00fcklenmesini engelleyin.<\/li>\n<li><strong>Vir\u00fcs ve K\u00f6t\u00fc Ama\u00e7l\u0131 Yaz\u0131l\u0131m Taramas\u0131:<\/strong> Y\u00fcklenen dosyalar\u0131 ger\u00e7ek zamanl\u0131 veya periyodik olarak vir\u00fcs taramas\u0131ndan ge\u00e7irmek, k\u00f6t\u00fc ama\u00e7l\u0131 i\u00e7eriklerin sisteminize girmesini engellemek i\u00e7in hayati \u00f6nem ta\u015f\u0131r. Bu genellikle ClamAV gibi ara\u00e7lar\u0131n bir Lambda fonksiyonu i\u00e7inde veya AWS GuardDuty gibi servislerle entegre edilerek yap\u0131l\u0131r.<\/li>\n<li><strong>\u015eifreleme:<\/strong> Hassas verileri S3'e y\u00fcklerken, hem aktar\u0131m s\u0131ras\u0131nda (HTTPS) hem de depoda (server-side encryption veya client-side encryption) \u015fifreledi\u011finizden emin olun. S3, varsay\u0131lan olarak sunucu taraf\u0131 \u015fifrelemeyi (SSE-S3, SSE-KMS, SSE-C) destekler.<\/li>\n<\/ul>\n<p>Bu g\u00fcvenlik pratiklerini uygulamak, dosya y\u00fckleme API'nizin sadece h\u0131zl\u0131 ve \u00f6l\u00e7eklenebilir olmas\u0131n\u0131 sa\u011flamakla kalmayacak, ayn\u0131 zamanda uygulaman\u0131z\u0131n genel g\u00fcvenlik duru\u015funu da \u00f6nemli \u00f6l\u00e7\u00fcde g\u00fc\u00e7lendirecektir. Unutmay\u0131n, g\u00fcvenlik s\u00fcrekli bir s\u00fcre\u00e7tir ve d\u00fczenli olarak g\u00f6zden ge\u00e7irilmelidir.<\/p>\n<h2>\u0130leri D\u00fczey Kullan\u0131m Senaryolar\u0131 ve Optimizasyonlar: Performans\u0131 ve G\u00fcvenli\u011fi Art\u0131rmak \u0130\u00e7in \u0130pu\u00e7lar\u0131 Nelerdir?<\/h2>\n<p>Temel bir Presigned URL tabanl\u0131 dosya y\u00fckleme API'si olu\u015fturduk ve g\u00fcvenlik temellerini att\u0131k. \u015eimdi, uygulaman\u0131z\u0131n performans\u0131n\u0131 ve kullan\u0131c\u0131 deneyimini daha da art\u0131rmak i\u00e7in ileri d\u00fczey ipu\u00e7lar\u0131na ve optimizasyonlara g\u00f6z atal\u0131m. Bu b\u00f6l\u00fcm, \u00f6zellikle b\u00fcy\u00fck \u00f6l\u00e7ekli uygulamalar ve y\u00fcksek trafik senaryolar\u0131 i\u00e7in de\u011fer katacakt\u0131r.<\/p>\n<h3>1. CDN Kullan\u0131m\u0131 (Amazon CloudFront)<\/h3>\n<p>Kullan\u0131c\u0131lar\u0131n\u0131z d\u00fcnyan\u0131n farkl\u0131 yerlerinde mi? O zaman dosyalar\u0131n\u0131z\u0131n indirme h\u0131z\u0131n\u0131 art\u0131rmak ve gecikmeyi azaltmak i\u00e7in bir \u0130\u00e7erik Da\u011f\u0131t\u0131m A\u011f\u0131 (CDN) kullanmak \u015fartt\u0131r. Amazon CloudFront, S3'teki dosyalar\u0131n\u0131z\u0131 (g\u00f6r\u00fcnt\u00fcler, videolar, belgeler) d\u00fcnya genelindeki u\u00e7 konumlar\u0131ndaki \u00f6nbellek sunucular\u0131nda (edge locations) depolar. Bir kullan\u0131c\u0131 bir dosyay\u0131 istedi\u011finde, dosya ona co\u011frafi olarak en yak\u0131n u\u00e7 konumdan sunulur, bu da indirme s\u00fcrelerini \u00f6nemli \u00f6l\u00e7\u00fcde h\u0131zland\u0131r\u0131r.<\/p>\n<pre><code class=\"language-bash\">\n# CloudFront da\u011f\u0131t\u0131m\u0131 olu\u015fturma ad\u0131mlar\u0131 (AWS CLI \u00f6rne\u011fi)\naws cloudfront create-distribution --distribution-config file:\/\/distribution-config.json\n    <\/pre>\n<p><\/code><\/p>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: Presigned URL'leri kullanarak do\u011frudan S3'e y\u00fckleme yaparken bile, S3'ten dosya indirme ba\u011flant\u0131lar\u0131n\u0131 CloudFront \u00fczerinden sunarak son kullan\u0131c\u0131lara daha h\u0131zl\u0131 eri\u015fim sa\u011flayabilirsiniz. CloudFront'u S3'\u00fcn \u00f6n\u00fcnde bir \u00f6nbellek olarak konumland\u0131rmak, okuma i\u015flemleri i\u00e7in performans\u0131 %50'ye kadar art\u0131rabilir.\n    <\/div>\n<h3>2. Sunucu Taraf\u0131 Do\u011frulama ve \u0130\u015flem Kuyruklar\u0131<\/h3>\n<p>\u0130stemci taraf\u0131nda yap\u0131lan t\u00fcm do\u011frulamalar (dosya t\u00fcr\u00fc, boyutu vb.) her zaman g\u00fcvenilir de\u011fildir. K\u00f6t\u00fc niyetli bir kullan\u0131c\u0131 bu kontrolleri atlatabilir. Bu nedenle, y\u00fcklenen dosyalar\u0131 S3'e ula\u015ft\u0131ktan sonra sunucu taraf\u0131nda yeniden do\u011frulamak hayati \u00f6nem ta\u015f\u0131r. Bu i\u015flemi AWS Lambda ve SQS (Simple Queue Service) gibi servislerle entegre edebilirsiniz:<\/p>\n<ol>\n<li>S3'e bir dosya y\u00fcklendi\u011finde, bir S3 olay\u0131 bir Lambda fonksiyonunu tetikler.<\/li>\n<li>Lambda fonksiyonu, dosya ad\u0131n\u0131, t\u00fcr\u00fcn\u00fc ve boyutunu yeniden do\u011frular.<\/li>\n<li>Gerekirse, dosya i\u00e7eri\u011fi \u00fczerinde derinlemesine analiz (vir\u00fcs taramas\u0131, format do\u011frulamas\u0131) yapar.<\/li>\n<li>Ge\u00e7ersiz veya zararl\u0131 dosyalar tespit edilirse silinir veya karantinaya al\u0131n\u0131r.<\/li>\n<li>Ge\u00e7erli dosyalar i\u00e7in, veritaban\u0131na kay\u0131t veya ba\u015fka bir i\u015fleme sokmak \u00fczere bir SQS kuyru\u011funa mesaj g\u00f6nderilebilir. Bu, ana API sunucunuzun y\u00fck\u00fcn\u00fc azalt\u0131r ve asenkron i\u015flem g\u00fcc\u00fc sa\u011flar.<\/li>\n<\/ol>\n<h3>3. Dosya S\u0131k\u0131\u015ft\u0131rma ve \u00d6nizleme Olu\u015fturma<\/h3>\n<p>\u00d6zellikle g\u00f6rseller ve videolar gibi medya dosyalar\u0131 i\u00e7in, y\u00fckleme sonras\u0131 otomatik s\u0131k\u0131\u015ft\u0131rma ve \u00f6nizleme (thumbnail) olu\u015fturma i\u015flemleri kullan\u0131c\u0131 deneyimini b\u00fcy\u00fck \u00f6l\u00e7\u00fcde iyile\u015ftirir ve depolama maliyetlerini d\u00fc\u015f\u00fcr\u00fcr. Yine AWS Lambda bu i\u015f i\u00e7in bi\u00e7ilmi\u015f kaftand\u0131r. Y\u00fcksek \u00e7\u00f6z\u00fcn\u00fcrl\u00fckl\u00fc bir foto\u011fraf y\u00fcklendi\u011finde, Lambda bunu otomatik olarak web i\u00e7in optimize edilmi\u015f boyutlara ve kalitelere d\u00f6n\u00fc\u015ft\u00fcrebilir, farkl\u0131 \u00f6nizleme boyutlar\u0131 olu\u015fturabilir ve t\u00fcm bu s\u00fcr\u00fcmleri S3'e kaydedebilir.<\/p>\n<pre><code class=\"language-python\">\n# Basit bir Lambda fonksiyonu ps\u00f6do-kodu (Python)\nimport boto3\nfrom PIL import Image # Pillow k\u00fct\u00fcphanesi\n\ns3 = boto3.client('s3')\n\ndef lambda_handler(event, context):\n    for record in event['Records']:\n        bucket_name = record['s3']['bucket']['name']\n        object_key = record['s3']['object']['key']\n\n        # Dosyay\u0131 indir\n        s3.download_file(bucket_name, object_key, '\/tmp\/original.jpg')\n\n        # Resmi yeniden boyutland\u0131r (\u00f6rne\u011fin thumbnail)\n        with Image.open('\/tmp\/original.jpg') as img:\n            img.thumbnail((128, 128))\n            img.save('\/tmp\/thumbnail.jpg', 'JPEG')\n\n        # Thumbnail'\u0131 S3'e y\u00fckle\n        s3.upload_file('\/tmp\/thumbnail.jpg', bucket_name, f'thumbnails\/{object_key}')\n        print(f\"Thumbnail olu\u015fturuldu ve y\u00fcklendi: thumbnails\/{object_key}\")\n    <\/pre>\n<p><\/code><\/p>\n<h3>4. \u00c7ok Par\u00e7al\u0131 Y\u00fckleme (Multipart Upload) ve B\u00fcy\u00fck Dosyalar<\/h3>\n<p>AWS S3, 5 GB'tan b\u00fcy\u00fck dosyalar i\u00e7in (veya daha k\u00fc\u00e7\u00fck dosyalar i\u00e7in bile daha verimli olabilen) \u00e7ok par\u00e7al\u0131 y\u00fckleme (Multipart Upload) \u00f6zelli\u011fini destekler. Bu \u00f6zellik, b\u00fcy\u00fck dosyalar\u0131 k\u00fc\u00e7\u00fck par\u00e7alara b\u00f6lerek paralel olarak S3'e y\u00fcklemenize olanak tan\u0131r. Bu, hem y\u00fckleme h\u0131z\u0131n\u0131 art\u0131r\u0131r hem de a\u011f kesintilerine kar\u015f\u0131 daha dayan\u0131kl\u0131 hale gelir. E\u011fer bir par\u00e7a y\u00fcklemesi ba\u015far\u0131s\u0131z olursa, sadece o par\u00e7ay\u0131 yeniden deneyebilirsiniz.<\/p>\n<p><code>boto3<\/code>'\u00fcn <code>create_multipart_upload<\/code>, <code>upload_part<\/code> ve <code>complete_multipart_upload<\/code> gibi metodlar\u0131n\u0131 kullanarak bu i\u015flemi kendi API'nizde y\u00f6netebilirsiniz. \u0130stemci taraf\u0131nda ise, JavaScript'teki Fetch API veya \u00f6zel bir k\u00fct\u00fcphane (\u00f6rne\u011fin <code>uppy<\/code> veya <code>resumable.js<\/code>) ile bu par\u00e7al\u0131 y\u00fcklemeyi kolayca ger\u00e7ekle\u015ftirebilirsiniz. Bu y\u00f6ntem, \u00f6zellikle video, CAD dosyalar\u0131 veya b\u00fcy\u00fck veritaban\u0131 yedekleri gibi \u00e7ok b\u00fcy\u00fck dosyalarla u\u011fra\u015f\u0131rken performans fark\u0131 yarat\u0131r.<\/p>\n<div class=\"expert-tip\">\n        Uzman \u0130pucu: Multipart Upload i\u00e7in Presigned URL'ler olu\u015ftururken her bir par\u00e7a i\u00e7in ayr\u0131 bir Presigned URL olu\u015fturabilir veya tek bir genel Presigned URL ile istemcinin kendisinin par\u00e7alar\u0131 y\u00f6netmesine izin verebilirsiniz. Bu, karma\u015f\u0131k ancak \u00e7ok b\u00fcy\u00fck dosyalar i\u00e7in en optimize edilmi\u015f \u00e7\u00f6z\u00fcmd\u00fcr.\n    <\/div>\n<h3>5. \u0130zleme ve G\u00fcnl\u00fckleme<\/h3>\n<p>Uygulaman\u0131z\u0131n ve S3'teki dosya y\u00fckleme etkinliklerinin sa\u011fl\u0131\u011f\u0131n\u0131 izlemek i\u00e7in CloudWatch metriklerini ve S3 eri\u015fim g\u00fcnl\u00fcklerini kullan\u0131n. Hata oranlar\u0131n\u0131, y\u00fckleme s\u00fcrelerini ve depolama kullan\u0131m\u0131n\u0131 takip etmek, potansiyel sorunlar\u0131 proaktif olarak tespit etmenizi ve uygulaman\u0131z\u0131 s\u00fcrekli olarak optimize etmenizi sa\u011flar.<\/p>\n<p>Bu ileri d\u00fczey optimizasyonlar, dosya y\u00fckleme API'nizi daha sa\u011flam, daha performansl\u0131 ve daha y\u00f6netilebilir hale getirecektir. Her bir ad\u0131m, uygulaman\u0131z\u0131n genel kalitesine ve g\u00fcvenilirli\u011fine katk\u0131da bulunur.<\/p>\n<h2>Sonu\u00e7 ve S\u0131k\u00e7a Sorulan Sorular: FastAPI ve AWS S3 ile G\u00fcvenli Dosya Y\u00fckleme \u00c7\u00f6z\u00fcm\u00fcn\u00fcz<\/h2>\n<p>Bu makalede, FastAPI ve AWS S3 Presigned URL'lerini kullanarak g\u00fcvenli ve \u00f6l\u00e7eklenebilir bir dosya y\u00fckleme API'si olu\u015fturma s\u00fcrecini detayl\u0131 bir \u015fekilde inceledik. Geleneksel dosya y\u00fckleme y\u00f6ntemlerinin getirdi\u011fi zorluklar\u0131 a\u015farak, dosyalar\u0131n do\u011frudan S3'e y\u00fcklenmesinin faydalar\u0131n\u0131, API sunucusu \u00fczerindeki y\u00fck\u00fc azaltma ve g\u00fcvenli\u011fi art\u0131rma potansiyelini g\u00f6rd\u00fck. FastAPI'nin h\u0131z\u0131n\u0131 ve geli\u015ftirici dostu yap\u0131s\u0131n\u0131, S3'\u00fcn s\u0131n\u0131rs\u0131z \u00f6l\u00e7eklenebilirli\u011fini ve Presigned URL'lerin sundu\u011fu g\u00fcvenlik katmanlar\u0131n\u0131 birle\u015ftirerek modern bir \u00e7\u00f6z\u00fcm ortaya koyduk.<\/p>\n<p>Proje kurulumundan ba\u015flayarak, AWS kimlik bilgileri y\u00f6netimi, Presigned URL olu\u015fturma mekanizmas\u0131, istemci taraf\u0131 y\u00fckleme implementasyonu ve y\u00fcklenen dosyalar\u0131n g\u00fcvenli bir \u015fekilde y\u00f6netilmesi i\u00e7in en iyi uygulamalar hakk\u0131nda bilgi edindiniz. Ayr\u0131ca, CDN entegrasyonu, sunucu taraf\u0131 do\u011frulama, otomatik dosya i\u015fleme ve \u00e7ok par\u00e7al\u0131 y\u00fckleme gibi ileri d\u00fczey optimizasyonlar\u0131 ve kullan\u0131m senaryolar\u0131n\u0131 da ke\u015ffettik. Bu bilgilerle donanm\u0131\u015f olarak, kendi uygulamalar\u0131n\u0131zda y\u00fcksek performansl\u0131 ve g\u00fcvenli dosya y\u00fckleme \u00e7\u00f6z\u00fcmleri geli\u015ftirmeye haz\u0131rs\u0131n\u0131z.<\/p>\n<h3>S\u0131k\u00e7a Sorulan Sorular (SSS)<\/h3>\n<ol>\n<li>\n<h4>S: Presigned URL'ler ne kadar g\u00fcvenlidir?<\/h4>\n<p><strong>C:<\/strong> Presigned URL'ler olduk\u00e7a g\u00fcvenlidir \u00e7\u00fcnk\u00fc do\u011frudan AWS kimlik bilgilerinizi if\u015fa etmezler. Belirli bir s\u00fcre (<code>ExpiresIn<\/code> parametresi ile belirlenir) ge\u00e7erli olurlar ve yaln\u0131zca belirli eylemler (y\u00fckleme, indirme) i\u00e7in s\u0131n\u0131rl\u0131 izinler ta\u015f\u0131rlar. Ayr\u0131ca, S3 taraf\u0131nda ko\u015fullar (\u00f6rne\u011fin <code>Content-Type<\/code> veya <code>Content-Length-Range<\/code>) belirleyerek y\u00fckleme s\u0131ras\u0131nda ekstra g\u00fcvenlik katmanlar\u0131 ekleyebilirsiniz. Ancak, URL bir kez olu\u015fturuldu\u011funda, s\u00fcresi dolana kadar o URL'ye sahip herkesin belirlenen eylemi ger\u00e7ekle\u015ftirebilece\u011fini unutmamak \u00f6nemlidir. Bu y\u00fczden k\u0131sa s\u00fcreler belirlemek ve hassas veriler i\u00e7in ek do\u011frulama ad\u0131mlar\u0131 eklemek \u00f6nemlidir.<\/p>\n<\/li>\n<li>\n<h4>S: B\u00fcy\u00fck dosyalar\u0131 y\u00fcklemek i\u00e7in bu y\u00f6ntem uygun mu?<\/h4>\n<p><strong>C:<\/strong> Kesinlikle! Presigned URL'ler, b\u00fcy\u00fck dosyalar\u0131n do\u011frudan S3'e y\u00fcklenmesi i\u00e7in olduk\u00e7a uygundur. \u00d6zellikle <code>generate_presigned_post<\/code> y\u00f6ntemi, taray\u0131c\u0131lar\u0131n \u00e7ok par\u00e7al\u0131 y\u00fcklemeleri (multipart uploads) daha kolay y\u00f6netmesine olanak tan\u0131r. Dosyalar\u0131n API sunucunuz \u00fczerinden ge\u00e7memesi, sunucu y\u00fck\u00fcn\u00fc azalt\u0131r ve S3'\u00fcn do\u011fal \u00f6l\u00e7eklenebilirli\u011finden yararlan\u0131lmas\u0131n\u0131 sa\u011flar, bu da b\u00fcy\u00fck dosyalar\u0131n h\u0131zl\u0131 ve g\u00fcvenilir bir \u015fekilde y\u00fcklenmesi i\u00e7in idealdir.<\/p>\n<\/li>\n<li>\n<h4>S: Y\u00fcklenen dosyalara eri\u015fimi nas\u0131l k\u0131s\u0131tlayabilirim?<\/h4>\n<p><strong>C:<\/strong> Y\u00fcklenen dosyalara eri\u015fimi k\u0131s\u0131tlaman\u0131n birka\u00e7 yolu vard\u0131r. En yayg\u0131n ve \u00f6nerilen y\u00f6ntem, S3 kovalar\u0131n\u0131 varsay\u0131lan olarak \"Block all public access\" ayar\u0131yla \u00f6zel (private) tutmakt\u0131r. Dosyalara eri\u015fim gerekti\u011finde,<\/p>\n<ol type=\"a\">\n<li>\u0130ndirme i\u00e7in ba\u015fka bir Presigned URL olu\u015fturarak yetkili kullan\u0131c\u0131lara ge\u00e7ici eri\u015fim sa\u011flayabilirsiniz.<\/li>\n<li>S3 kova politikalar\u0131 veya IAM rolleri kullanarak belirli IAM kullan\u0131c\u0131lar\u0131na\/rollerine belirli dosyalara veya klas\u00f6rlere eri\u015fim izni verebilirsiniz.<\/li>\n<li>Amazon CloudFront ve Signed URLs\/Cookies kullanarak daha geli\u015fmi\u015f ve zaman bazl\u0131 eri\u015fim kontrol\u00fc uygulayabilirsiniz.<\/li>\n<\/ol>\n<\/li>\n<li>\n<h4>S: Y\u00fckleme tamamland\u0131ktan sonra ba\u015fka bir i\u015flem yapmak istersem ne yapmal\u0131y\u0131m?<\/h4>\n<p><strong>C:<\/strong> Bu t\u00fcr y\u00fckleme sonras\u0131 i\u015flemler i\u00e7in AWS S3 olay bildirimlerini ve AWS Lambda'y\u0131 kullanmak en verimli y\u00f6ntemdir. S3 kovan\u0131zda bir dosya olu\u015fturuldu\u011funda bir Lambda fonksiyonunu tetikleyecek bir olay yap\u0131land\u0131rabilirsiniz. Bu Lambda fonksiyonu, g\u00f6r\u00fcnt\u00fcy\u00fc yeniden boyutland\u0131rmak, dosya i\u00e7eri\u011fini taramak, veritaban\u0131na kay\u0131t eklemek veya ba\u015fka bir AWS servisini (\u00f6rne\u011fin SQS veya Step Functions) tetiklemek gibi g\u00f6revleri yerine getirebilir. Bu yakla\u015f\u0131m, API sunucunuzun daha hafif ve yan\u0131t veren kalmas\u0131n\u0131 sa\u011flar.<\/p>\n<\/li>\n<li>\n<h4>S: Bu \u00e7\u00f6z\u00fcm\u00fcn maliyeti nedir?<\/h4>\n<p><strong>C:<\/strong> Maliyet, kullan\u0131m\u0131n\u0131za ba\u011fl\u0131 olarak de\u011fi\u015fir. AWS S3 depolama alan\u0131, veri aktar\u0131m\u0131 (\u00f6zellikle S3'ten \u00e7\u0131k\u0131\u015f) ve API istekleri (hem S3 hem de FastAPI sunucunuz i\u00e7in) \u00fczerinden \u00fccretlendirilir. FastAPI uygulaman\u0131z\u0131 bar\u0131nd\u0131rd\u0131\u011f\u0131n\u0131z sunucunun maliyeti de eklenir (\u00f6rne\u011fin, EC2, ECS veya AWS Lambda \u00fczerinde). Presigned URL yakla\u015f\u0131m\u0131, dosyalar\u0131n API sunucunuzdan ge\u00e7mesini engelledi\u011fi i\u00e7in sunucu \u00fczerindeki a\u011f trafi\u011fi ve i\u015flem maliyetlerini d\u00fc\u015f\u00fcrerek genel maliyetleri optimize etmenize yard\u0131mc\u0131 olabilir. AWS'nin \u00fccretsiz katman\u0131n\u0131 kullanarak k\u00fc\u00e7\u00fck \u00f6l\u00e7ekli denemeler yapabilirsiniz.<\/p>\n<\/li>\n<\/ol>\n<p><\/body><\/p>\n","protected":false},"excerpt":{"rendered":"G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131nda dosya y\u00fckleme, en temel ve ayn\u0131 zamanda en kritik i\u015flevlerden biridir. Peki, bu s\u00fcreci hem&hellip;","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":[1406],"tags":[],"class_list":{"0":"post-33839","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-aws","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>FastAPI ve AWS S3 Presigned URL&#039;ler ile G\u00fcvenli Dosya Y\u00fckleme API&#039;si Nas\u0131l Olu\u015fturulur?<\/title>\n<meta name=\"description\" content=\"G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131nda dosya y\u00fckleme, en temel ve ayn\u0131 zamanda en kritik i\u015flevlerden biridir. Peki, bu s\u00fcreci hem g\u00fcvenli hem de \u00f6l\u00e7eklenebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Kullan\u0131c\u0131 deneyimini kesintiye u\u011fratmadan, sunucu y\u00fck\u00fcn\u00fc minimumda tutarak b\u00fcy\u00fck dosyalar\u0131n bile sorunsuz bir \u015fekilde y\u00fcklenebilmesini sa\u011flamak m\u00fcmk\u00fcn m\u00fcd\u00fcr? Bu makalede, modern bir yakla\u015f\u0131mla, FastAPI ve AWS S3 Presigned URL&#039;lerini kullanarak u\u00e7tan uca g\u00fcvenli ve \u00f6l\u00e7eklenebilir bir dosya y\u00fckleme API&#039;si olu\u015fturma s\u00fcrecini ad\u0131m ad\u0131m ele alaca\u011f\u0131z.\" \/>\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\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"FastAPI ve AWS S3 Presigned URL&#039;ler ile G\u00fcvenli Dosya Y\u00fckleme API&#039;si Nas\u0131l Olu\u015fturulur?\" \/>\n<meta property=\"og:description\" content=\"G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131nda dosya y\u00fckleme, en temel ve ayn\u0131 zamanda en kritik i\u015flevlerden biridir. Peki, bu s\u00fcreci hem g\u00fcvenli hem de \u00f6l\u00e7eklenebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Kullan\u0131c\u0131 deneyimini kesintiye u\u011fratmadan, sunucu y\u00fck\u00fcn\u00fc minimumda tutarak b\u00fcy\u00fck dosyalar\u0131n bile sorunsuz bir \u015fekilde y\u00fcklenebilmesini sa\u011flamak m\u00fcmk\u00fcn m\u00fcd\u00fcr? Bu makalede, modern bir yakla\u015f\u0131mla, FastAPI ve AWS S3 Presigned URL&#039;lerini kullanarak u\u00e7tan uca g\u00fcvenli ve \u00f6l\u00e7eklenebilir bir dosya y\u00fckleme API&#039;si olu\u015fturma s\u00fcrecini ad\u0131m ad\u0131m ele alaca\u011f\u0131z.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-11-07T17:31:28+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=\"33 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"FastAPI ve AWS S3 Presigned URL&#8217;ler ile G\u00fcvenli Dosya Y\u00fckleme API&#8217;si Nas\u0131l Olu\u015fturulur?\",\"datePublished\":\"2025-11-07T17:31:28+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/\"},\"wordCount\":5888,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"AWS\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/\",\"name\":\"FastAPI ve AWS S3 Presigned URL'ler ile G\u00fcvenli Dosya Y\u00fckleme API'si Nas\u0131l Olu\u015fturulur?\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-11-07T17:31:28+00:00\",\"description\":\"G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131nda dosya y\u00fckleme, en temel ve ayn\u0131 zamanda en kritik i\u015flevlerden biridir. Peki, bu s\u00fcreci hem g\u00fcvenli hem de \u00f6l\u00e7eklenebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Kullan\u0131c\u0131 deneyimini kesintiye u\u011fratmadan, sunucu y\u00fck\u00fcn\u00fc minimumda tutarak b\u00fcy\u00fck dosyalar\u0131n bile sorunsuz bir \u015fekilde y\u00fcklenebilmesini sa\u011flamak m\u00fcmk\u00fcn m\u00fcd\u00fcr? Bu makalede, modern bir yakla\u015f\u0131mla, FastAPI ve AWS S3 Presigned URL'lerini kullanarak u\u00e7tan uca g\u00fcvenli ve \u00f6l\u00e7eklenebilir bir dosya y\u00fckleme API'si olu\u015fturma s\u00fcrecini ad\u0131m ad\u0131m ele alaca\u011f\u0131z.\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"FastAPI ve AWS S3 Presigned URL&#8217;ler ile G\u00fcvenli Dosya Y\u00fckleme API&#8217;si Nas\u0131l Olu\u015fturulur?\"}]},{\"@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":"FastAPI ve AWS S3 Presigned URL'ler ile G\u00fcvenli Dosya Y\u00fckleme API'si Nas\u0131l Olu\u015fturulur?","description":"G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131nda dosya y\u00fckleme, en temel ve ayn\u0131 zamanda en kritik i\u015flevlerden biridir. Peki, bu s\u00fcreci hem g\u00fcvenli hem de \u00f6l\u00e7eklenebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Kullan\u0131c\u0131 deneyimini kesintiye u\u011fratmadan, sunucu y\u00fck\u00fcn\u00fc minimumda tutarak b\u00fcy\u00fck dosyalar\u0131n bile sorunsuz bir \u015fekilde y\u00fcklenebilmesini sa\u011flamak m\u00fcmk\u00fcn m\u00fcd\u00fcr? Bu makalede, modern bir yakla\u015f\u0131mla, FastAPI ve AWS S3 Presigned URL'lerini kullanarak u\u00e7tan uca g\u00fcvenli ve \u00f6l\u00e7eklenebilir bir dosya y\u00fckleme API'si olu\u015fturma s\u00fcrecini ad\u0131m ad\u0131m ele alaca\u011f\u0131z.","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\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/","og_locale":"tr_TR","og_type":"article","og_title":"FastAPI ve AWS S3 Presigned URL'ler ile G\u00fcvenli Dosya Y\u00fckleme API'si Nas\u0131l Olu\u015fturulur?","og_description":"G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131nda dosya y\u00fckleme, en temel ve ayn\u0131 zamanda en kritik i\u015flevlerden biridir. Peki, bu s\u00fcreci hem g\u00fcvenli hem de \u00f6l\u00e7eklenebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Kullan\u0131c\u0131 deneyimini kesintiye u\u011fratmadan, sunucu y\u00fck\u00fcn\u00fc minimumda tutarak b\u00fcy\u00fck dosyalar\u0131n bile sorunsuz bir \u015fekilde y\u00fcklenebilmesini sa\u011flamak m\u00fcmk\u00fcn m\u00fcd\u00fcr? Bu makalede, modern bir yakla\u015f\u0131mla, FastAPI ve AWS S3 Presigned URL'lerini kullanarak u\u00e7tan uca g\u00fcvenli ve \u00f6l\u00e7eklenebilir bir dosya y\u00fckleme API'si olu\u015fturma s\u00fcrecini ad\u0131m ad\u0131m ele alaca\u011f\u0131z.","og_url":"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-11-07T17:31:28+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"33 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"FastAPI ve AWS S3 Presigned URL&#8217;ler ile G\u00fcvenli Dosya Y\u00fckleme API&#8217;si Nas\u0131l Olu\u015fturulur?","datePublished":"2025-11-07T17:31:28+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/"},"wordCount":5888,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["AWS"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/","url":"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/","name":"FastAPI ve AWS S3 Presigned URL'ler ile G\u00fcvenli Dosya Y\u00fckleme API'si Nas\u0131l Olu\u015fturulur?","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-11-07T17:31:28+00:00","description":"G\u00fcn\u00fcm\u00fcz web uygulamalar\u0131nda dosya y\u00fckleme, en temel ve ayn\u0131 zamanda en kritik i\u015flevlerden biridir. Peki, bu s\u00fcreci hem g\u00fcvenli hem de \u00f6l\u00e7eklenebilir bir \u015fekilde nas\u0131l y\u00f6netebiliriz? Kullan\u0131c\u0131 deneyimini kesintiye u\u011fratmadan, sunucu y\u00fck\u00fcn\u00fc minimumda tutarak b\u00fcy\u00fck dosyalar\u0131n bile sorunsuz bir \u015fekilde y\u00fcklenebilmesini sa\u011flamak m\u00fcmk\u00fcn m\u00fcd\u00fcr? Bu makalede, modern bir yakla\u015f\u0131mla, FastAPI ve AWS S3 Presigned URL'lerini kullanarak u\u00e7tan uca g\u00fcvenli ve \u00f6l\u00e7eklenebilir bir dosya y\u00fckleme API'si olu\u015fturma s\u00fcrecini ad\u0131m ad\u0131m ele alaca\u011f\u0131z.","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/fastapi-ve-aws-s3-presigned-urller-ile-guvenli-dosya-yukleme-apisi-nasil-olusturulur\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"FastAPI ve AWS S3 Presigned URL&#8217;ler ile G\u00fcvenli Dosya Y\u00fckleme API&#8217;si Nas\u0131l Olu\u015fturulur?"}]},{"@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\/33839","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=33839"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/33839\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=33839"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=33839"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=33839"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}