{"id":35955,"date":"2025-12-06T03:40:55","date_gmt":"2025-12-06T00:40:55","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/?p=35955"},"modified":"2025-12-06T03:40:55","modified_gmt":"2025-12-06T00:40:55","slug":"ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/","title":{"rendered":"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber"},"content":{"rendered":"<p><body><\/p>\n<h2>Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber<\/h2>\n<h2>Giri\u015f<\/h2>\n<p>Python ekosistemi, web uygulamalar\u0131 geli\u015ftirmek i\u00e7in zengin bir \u00e7er\u00e7eve se\u00e7ene\u011fi sunar. Django ve Flask gibi pop\u00fcler isimlerin yan\u0131 s\u0131ra, daha az bilinen ancak esnekli\u011fi ve g\u00fcc\u00fcyle \u00f6ne \u00e7\u0131kan bir se\u00e7enek de Pyramid&#8217;dir. Pyramid, &#8220;opinionated&#8221; (belirli bir yol dayatan) olmaktan ziyade, geli\u015ftiriciye tam kontrol sa\u011flayan, &#8220;unopinionated&#8221; (belirli bir yol dayatmayan) bir yap\u0131ya sahiptir. Bu, onu k\u00fc\u00e7\u00fck prototiplerden b\u00fcy\u00fck, karma\u015f\u0131k API&#8217;lere ve web hizmetlerine kadar her t\u00fcrl\u00fc proje i\u00e7in ideal bir se\u00e7im haline getirir.<\/p>\n<p>Bu makalede, Pyramid \u00e7er\u00e7evesini kullanarak Ubuntu i\u015fletim sistemi \u00fczerinde bir Python web uygulamas\u0131 olu\u015fturman\u0131n t\u00fcm ad\u0131mlar\u0131n\u0131 ba\u015ftan sona inceleyece\u011fiz. Temel kurulumdan veritaban\u0131 entegrasyonuna, g\u00f6r\u00fcn\u00fcmlerden \u015fablonlara ve hatta da\u011f\u0131t\u0131m ipu\u00e7lar\u0131na kadar geni\u015f bir yelpazeyi kapsayaca\u011f\u0131z. Amac\u0131m\u0131z, Pyramid&#8217;in g\u00fcc\u00fcn\u00fc ve esnekli\u011fini anlaman\u0131za yard\u0131mc\u0131 olmak ve kendi projelerinizi ba\u015flatmak i\u00e7in sa\u011flam bir temel sunmakt\u0131r. E\u011fer Python biliyorsan\u0131z ve daha az &#8220;sihir&#8221; i\u00e7eren, daha fazla kontrol sa\u011flayan bir web \u00e7er\u00e7evesi ar\u0131yorsan\u0131z, Pyramid tam size g\u00f6re olabilir.<\/p>\n<h2>\u00d6n Ko\u015fullar ve Ortam Kurulumu<\/h2>\n<p>Herhangi bir yaz\u0131l\u0131m geli\u015ftirme projesine ba\u015flamadan \u00f6nce, \u00e7al\u0131\u015fma ortam\u0131m\u0131z\u0131 do\u011fru \u015fekilde haz\u0131rlamak kritik \u00f6neme sahiptir. Bu b\u00f6l\u00fcmde, Ubuntu i\u015fletim sisteminizi Pyramid projeniz i\u00e7in haz\u0131r hale getirecek temel ad\u0131mlar\u0131 ele alaca\u011f\u0131z.<\/p>\n<h3>Ubuntu Haz\u0131rl\u0131\u011f\u0131<\/h3>\n<p>\u00d6ncelikle, sisteminizin g\u00fcncel oldu\u011fundan emin olal\u0131m ve gerekli temel geli\u015ftirme ara\u00e7lar\u0131n\u0131 kural\u0131m:<\/p>\n<pre><code class=\"language-bash\">sudo apt update\nsudo apt upgrade -y\nsudo apt install -y build-essential python3-dev python3-pip<\/code><\/pre>\n<p>*   <code>build-essential<\/code>: Derleme ara\u00e7lar\u0131 (GCC gibi) sa\u011flar, baz\u0131 Python paketleri C uzant\u0131lar\u0131 gerektirebilir.<br \/>\n*   <code>python3-dev<\/code>: Python ba\u015fl\u0131k dosyalar\u0131n\u0131 ve statik k\u00fct\u00fcphaneleri i\u00e7erir, bu da C uzant\u0131lar\u0131na sahip Python paketlerini derlemek i\u00e7in gereklidir.<br \/>\n*   <code>python3-pip<\/code>: Python paket y\u00f6neticisi pip&#8217;i kurar.<\/p>\n<h3>Python ve Sanal Ortam Kurulumu<\/h3>\n<p>Python projeleri geli\u015ftirirken sanal ortam kullanmak iyi bir pratiktir. Sanal ortamlar, her projenin kendi ba\u011f\u0131ml\u0131l\u0131k setine sahip olmas\u0131n\u0131 sa\u011flayarak ba\u011f\u0131ml\u0131l\u0131k \u00e7ak\u0131\u015fmalar\u0131n\u0131 \u00f6nler ve sistem genelindeki Python kurulumunuzu temiz tutar.<\/p>\n<p>Ubuntu&#8217;da Python 3 genellikle \u00f6n y\u00fckl\u00fc gelir. Python 3.8 veya daha yeni bir s\u00fcr\u00fcm\u00fcn\u00fc kulland\u0131\u011f\u0131n\u0131zdan emin olun. Sanal ortam olu\u015fturmak i\u00e7in <code>venv<\/code> mod\u00fcl\u00fcn\u00fc kullanaca\u011f\u0131z:<\/p>\n<pre><code class=\"language-bash\"># Proje dizini olu\u015fturun ve i\u00e7ine girin\nmkdir my_pyramid_app\ncd my_pyramid_app\n\n<h2>Sanal ortam olu\u015fturun (genellikle '.venv' veya 'venv' ad\u0131yla)<\/h2>\npython3 -m venv .venv\n\n<h2>Sanal ortam\u0131 etkinle\u015ftirin<\/h2>\nsource .venv\/bin\/activate<\/code><\/pre>\n<p>Sanal ortam etkinle\u015ftirildi\u011finde, komut sat\u0131r\u0131 isteminizin ba\u015f\u0131nda <code>(.venv)<\/code> gibi bir ifade g\u00f6receksiniz. Art\u0131k y\u00fckleyece\u011finiz t\u00fcm Python paketleri bu sanal ortam\u0131n i\u00e7ine kurulacak ve sistem genelindeki Python kurulumunuzu etkilemeyecektir.<\/p>\n<h3>PostgreSQL Kurulumu ve Yap\u0131land\u0131rmas\u0131<\/h3>\n<p>\u00c7o\u011fu web uygulamas\u0131 bir veritaban\u0131na ihtiya\u00e7 duyar. Bu rehberde, g\u00fc\u00e7l\u00fc ve g\u00fcvenilir bir a\u00e7\u0131k kaynak ili\u015fkisel veritaban\u0131 y\u00f6netim sistemi olan PostgreSQL&#8217;i kullanaca\u011f\u0131z.<\/p>\n<pre><code class=\"language-bash\"># PostgreSQL sunucusunu ve ek ara\u00e7lar\u0131 kurun\nsudo apt install -y postgresql postgresql-contrib<\/code><\/pre>\n<p>Kurulumdan sonra, PostgreSQL varsay\u0131lan olarak <code>postgres<\/code> adl\u0131 bir sistem kullan\u0131c\u0131s\u0131 olu\u015fturur. Bu kullan\u0131c\u0131 ile veritaban\u0131 i\u015flemleri yapabiliriz. \u00d6ncelikle, <code>postgres<\/code> kullan\u0131c\u0131s\u0131na ge\u00e7i\u015f yap\u0131n:<\/p>\n<pre><code class=\"language-bash\">sudo -i -u postgres<\/code><\/pre>\n<p>\u015eimdi, uygulamam\u0131z i\u00e7in bir veritaban\u0131 kullan\u0131c\u0131s\u0131 ve bir veritaban\u0131 olu\u015ftural\u0131m:<\/p>\n<pre><code class=\"language-bash\"># Yeni bir veritaban\u0131 kullan\u0131c\u0131s\u0131 olu\u015fturun\ncreateuser --pwprompt myuser # \u015eifre isteyecektir, g\u00fc\u00e7l\u00fc bir \u015fifre girin\n\n<h2>Uygulaman\u0131z i\u00e7in bir veritaban\u0131 olu\u015fturun ve sahibini belirleyin<\/h2>\ncreatedb -O myuser myapp_db\n\n<h2>postgres kullan\u0131c\u0131s\u0131ndan \u00e7\u0131k\u0131n<\/h2>\nexit<\/code><\/pre>\n<p>Art\u0131k <code>myuser<\/code> adl\u0131 bir veritaban\u0131 kullan\u0131c\u0131n\u0131z ve <code>myapp_db<\/code> adl\u0131 bir veritaban\u0131n\u0131z var. Uygulaman\u0131z bu kimlik bilgileriyle veritaban\u0131na ba\u011flanabilecektir. Pyramid uygulaman\u0131z\u0131n PostgreSQL ile etkile\u015fim kurabilmesi i\u00e7in <code>psycopg2-binary<\/code> paketini kurmam\u0131z gerekecek, ancak bunu Pyramid projesini olu\u015fturduktan sonra yapaca\u011f\u0131z.<\/p>\n<h2>Pyramid Projesi Olu\u015fturma<\/h2>\n<p>Ortam\u0131m\u0131z haz\u0131r oldu\u011funa g\u00f6re, art\u0131k bir Pyramid projesi olu\u015fturmaya ba\u015flayabiliriz. Pyramid, proje iskeleti olu\u015fturmak i\u00e7in kullan\u0131\u015fl\u0131 ara\u00e7lar sunar.<\/p>\n<h3>Pyramid Kurulumu<\/h3>\n<p>Sanal ortam\u0131n\u0131z etkinle\u015ftirilmi\u015fken, Pyramid \u00e7er\u00e7evesini kurun:<\/p>\n<pre><code class=\"language-bash\">pip install pyramid<\/code><\/pre>\n<p>Bu komut, Pyramid&#8217;in kendisini ve temel ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 sanal ortam\u0131n\u0131za y\u00fckleyecektir.<\/p>\n<h3>Proje \u0130skeleti Olu\u015fturma<\/h3>\n<p>Pyramid, <code>pcreate<\/code> ad\u0131nda bir komut sat\u0131r\u0131 arac\u0131yla proje iskeletleri olu\u015fturmay\u0131 kolayla\u015ft\u0131r\u0131r. <code>pcreate<\/code>&#8216;i kullanabilmek i\u00e7in \u00f6ncelikle <code>pyramid_cookiecutter_starter<\/code> paketini kurmam\u0131z gerekiyor:<\/p>\n<pre><code class=\"language-bash\">pip install pyramid_cookiecutter_starter<\/code><\/pre>\n<p>\u015eimdi, <code>pcreate<\/code> komutuyla yeni bir Pyramid projesi olu\u015ftural\u0131m. <code>pyramid_cookiecutter_starter<\/code> \u015fablonu, modern Pyramid uygulamalar\u0131 i\u00e7in iyi bir ba\u015flang\u0131\u00e7 noktas\u0131 sunar:<\/p>\n<pre><code class=\"language-bash\">pcreate -s pyramid_cookiecutter_starter mywebapp<\/code><\/pre>\n<p>Bu komut, <code>mywebapp<\/code> ad\u0131nda yeni bir dizin olu\u015fturacak ve i\u00e7ine temel bir Pyramid uygulamas\u0131 iskeletini yerle\u015ftirecektir. Proje olu\u015fturulurken sizden baz\u0131 bilgiler (proje ad\u0131, a\u00e7\u0131klama vb.) isteyebilir. Varsay\u0131lan de\u011ferleri kabul edebilir veya kendi tercihlerinizi girebilirsiniz.<\/p>\n<p>Proje yap\u0131s\u0131 genellikle \u015funa benzer olacakt\u0131r:<\/p>\n<pre><code class=\"language-\">mywebapp\/\n\u251c\u2500\u2500 .venv\/\n\u251c\u2500\u2500 mywebapp\/\n\u2502   \u251c\u2500\u2500 __init__.py\n\u2502   \u251c\u2500\u2500 models\/\n\u2502   \u2502   \u251c\u2500\u2500 __init__.py\n\u2502   \u2502   \u2514\u2500\u2500 mymodel.py\n\u2502   \u251c\u2500\u2500 views\/\n\u2502   \u2502   \u251c\u2500\u2500 __init__.py\n\u2502   \u2502   \u2514\u2500\u2500 default.py\n\u2502   \u251c\u2500\u2500 static\/\n\u2502   \u2502   \u251c\u2500\u2500 pyramid-logo.png\n\u2502   \u2502   \u2514\u2500\u2500 sample.css\n\u2502   \u251c\u2500\u2500 templates\/\n\u2502   \u2502   \u2514\u2500\u2500 mytemplate.pt\n\u2502   \u2514\u2500\u2500 tests\/\n\u2502       \u2514\u2500\u2500 test_mywebapp.py\n\u251c\u2500\u2500 development.ini\n\u251c\u2500\u2500 production.ini\n\u251c\u2500\u2500 setup.py\n\u251c\u2500\u2500 README.md\n\u2514\u2500\u2500 requirements.txt<\/code><\/pre>\n<p>*   <code>mywebapp\/<\/code>: Uygulaman\u0131z\u0131n Python mod\u00fclleri burada bulunur.<br \/>\n*   <code>development.ini<\/code>, <code>production.ini<\/code>: Uygulaman\u0131n geli\u015ftirme ve \u00fcretim ortamlar\u0131 i\u00e7in yap\u0131land\u0131rma dosyalar\u0131.<br \/>\n*   <code>setup.py<\/code>: Projenizin da\u011f\u0131t\u0131m ve ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 y\u00f6neten standart Python setup dosyas\u0131.<br \/>\n*   <code>requirements.txt<\/code>: Projenizin Python ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 listeler.<\/p>\n<h3>Uygulamay\u0131 \u00c7al\u0131\u015ft\u0131rma<\/h3>\n<p>Proje iskeletini olu\u015fturduktan sonra, uygulamay\u0131 \u00e7al\u0131\u015ft\u0131r\u0131p varsay\u0131lan \u00e7\u0131kt\u0131y\u0131 g\u00f6relim. \u00d6ncelikle, yeni olu\u015fturulan proje dizinine gidin ve projenin ba\u011f\u0131ml\u0131l\u0131klar\u0131n\u0131 kurun:<\/p>\n<pre><code class=\"language-bash\">cd mywebapp\npip install -e .<\/code><\/pre>\n<p><code>pip install -e .<\/code> komutu, projenizi &#8220;d\u00fczenlenebilir&#8221; modda kurar. Bu, <code>setup.py<\/code> dosyas\u0131nda belirtilen t\u00fcm ba\u011f\u0131ml\u0131l\u0131klar\u0131 y\u00fckler ve projenizin Python paketleri olarak eri\u015filebilir olmas\u0131n\u0131 sa\u011flar.<\/p>\n<p>\u015eimdi uygulamay\u0131 \u00e7al\u0131\u015ft\u0131rabiliriz:<\/p>\n<pre><code class=\"language-bash\">pserve development.ini --reload<\/code><\/pre>\n<p>*   <code>pserve<\/code>: Pyramid uygulamalar\u0131n\u0131 \u00e7al\u0131\u015ft\u0131ran bir komut sat\u0131r\u0131 arac\u0131d\u0131r.<br \/>\n*   <code>development.ini<\/code>: Uygulaman\u0131n geli\u015ftirme yap\u0131land\u0131rmas\u0131n\u0131 kullanmas\u0131n\u0131 s\u00f6yleriz.<br \/>\n*   <code>--reload<\/code>: Kodunuzda yapt\u0131\u011f\u0131n\u0131z de\u011fi\u015fikliklerde sunucunun otomatik olarak yeniden y\u00fcklenmesini sa\u011flar, bu da geli\u015ftirme s\u00fcrecini h\u0131zland\u0131r\u0131r.<\/p>\n<p>Uygulama ba\u015far\u0131yla ba\u015flat\u0131ld\u0131\u011f\u0131nda, terminalinizde <code>Serving on http:\/\/0.0.0.0:6543<\/code> (veya benzer bir adres) gibi bir mesaj g\u00f6rmelisiniz. Web taray\u0131c\u0131n\u0131z\u0131 a\u00e7\u0131n ve <code>http:\/\/localhost:6543\/<\/code> adresine gidin. Pyramid&#8217;in varsay\u0131lan kar\u015f\u0131lama sayfas\u0131n\u0131 g\u00f6rmelisiniz. Tebrikler, ilk Pyramid uygulaman\u0131z \u00e7al\u0131\u015f\u0131yor!<\/p>\n<h2>Pyramid Temelleri<\/h2>\n<p>Pyramid&#8217;in temel yap\u0131 ta\u015flar\u0131n\u0131 ve bir web uygulamas\u0131n\u0131n nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 anlamak i\u00e7in g\u00f6r\u00fcn\u00fcmler (views), rotalar (routes) ve \u015fablonlar (templates) gibi kavramlar\u0131 inceleyelim.<\/p>\n<h3>Yap\u0131land\u0131rma ve <code>development.ini<\/code><\/h3>\n<p><code>development.ini<\/code> dosyas\u0131, uygulaman\u0131z\u0131n nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 kontrol eden \u00f6nemli ayarlar\u0131 i\u00e7erir. Bu dosya, uygulaman\u0131n ana yap\u0131land\u0131rma dosyas\u0131d\u0131r ve uygulaman\u0131n hangi Python mod\u00fcl\u00fcn\u00fc ba\u015flataca\u011f\u0131n\u0131, hangi portta dinleyece\u011fini ve \u00e7e\u015fitli Pyramid ayarlar\u0131n\u0131 belirtir.<\/p>\n<p>\u00d6nemli b\u00f6l\u00fcmler \u015funlard\u0131r:<br \/>\n*   <code>[app:main]<\/code>: Uygulaman\u0131z\u0131n ana yap\u0131land\u0131rmas\u0131. Burada Pyramid uygulaman\u0131z\u0131n ba\u015flatma i\u015flevini (genellikle <code>mywebapp.main<\/code> gibi) ve \u00e7e\u015fitli Pyramid ayarlar\u0131n\u0131 tan\u0131mlars\u0131n\u0131z. \u00d6rne\u011fin, <code>pyramid.reload_templates = true<\/code> gibi ayarlar geli\u015ftirme s\u0131ras\u0131nda \u015fablon de\u011fi\u015fikliklerinin an\u0131nda g\u00f6r\u00fcnmesini sa\u011flar.<br \/>\n*   <code>[server:main]<\/code>: Uygulaman\u0131z\u0131n hangi adreste ve portta dinleyece\u011fini belirtir. Varsay\u0131lan olarak <code>host = 0.0.0.0<\/code> ve <code>port = 6543<\/code> olabilir.<br \/>\n*   Di\u011fer b\u00f6l\u00fcmler veritaban\u0131 ba\u011flant\u0131 dizeleri, hata ay\u0131klama ayarlar\u0131 ve di\u011fer eklentilerin yap\u0131land\u0131rmalar\u0131 i\u00e7in kullan\u0131labilir.<\/p>\n<h3>G\u00f6r\u00fcn\u00fcmler (Views) ve Rotalar (Routes)<\/h3>\n<p>Pyramid&#8217;de bir web uygulamas\u0131n\u0131n kalbi g\u00f6r\u00fcn\u00fcmler ve rotalard\u0131r.<br \/>\n*   <strong>Rotasyon (Routing)<\/strong>: Gelen bir HTTP iste\u011finin URL&#8217;sini bir g\u00f6r\u00fcn\u00fcmle e\u015fle\u015ftirme s\u00fcrecidir.<br \/>\n*   <strong>G\u00f6r\u00fcn\u00fcm (View)<\/strong>: E\u015fle\u015fen URL&#8217;ye yan\u0131t veren Python fonksiyonu veya s\u0131n\u0131f\u0131d\u0131r.<\/p>\n<p><code>mywebapp\/views\/default.py<\/code> dosyas\u0131na bakarsan\u0131z, a\u015fa\u011f\u0131daki gibi bir yap\u0131 g\u00f6receksiniz:<\/p>\n<pre><code class=\"language-python\">from pyramid.view import view_config\nfrom pyramid.response import Response\n\n@view_config(route_name='home', renderer='..\/templates\/mytemplate.pt')\ndef my_view(request):\n    return {'project': 'mywebapp'}\n\n@view_config(route_name='hello', renderer='json')\ndef hello_world(request):\n    name = request.matchdict.get('name', 'World')\n    return {'message': f'Hello, {name}!'}<\/code><\/pre>\n<p>*   <code>@view_config<\/code>: Bu dekorat\u00f6r, bir fonksiyonu veya s\u0131n\u0131f\u0131 bir g\u00f6r\u00fcn\u00fcm olarak kaydeder.<br \/>\n    *   <code>route_name='home'<\/code>: Bu g\u00f6r\u00fcn\u00fcm\u00fcn <code>home<\/code> adl\u0131 rota ile e\u015fle\u015fece\u011fini belirtir. Rotalar genellikle <code>mywebapp\/__init__.py<\/code> i\u00e7inde tan\u0131mlan\u0131r.<br \/>\n    *   <code>renderer='..\/templates\/mytemplate.pt'<\/code>: G\u00f6r\u00fcn\u00fcm\u00fcn d\u00f6nd\u00fcrd\u00fc\u011f\u00fc s\u00f6zl\u00fc\u011f\u00fcn bu \u015fablon kullan\u0131larak HTML&#8217;e d\u00f6n\u00fc\u015ft\u00fcr\u00fclece\u011fini belirtir.<br \/>\n    *   <code>renderer='json'<\/code>: G\u00f6r\u00fcn\u00fcm\u00fcn d\u00f6nd\u00fcrd\u00fc\u011f\u00fc s\u00f6zl\u00fc\u011f\u00fcn otomatik olarak JSON yan\u0131t\u0131na d\u00f6n\u00fc\u015ft\u00fcr\u00fclece\u011fini belirtir.<br \/>\n*   <code>request<\/code>: Her g\u00f6r\u00fcn\u00fcm fonksiyonu, gelen HTTP iste\u011fi hakk\u0131nda bilgi i\u00e7eren bir <code>request<\/code> nesnesi al\u0131r. Bu nesne, URL parametrelerine (<code>request.matchdict<\/code>), sorgu parametrelerine (<code>request.GET<\/code>), form verilerine (<code>request.POST<\/code>), oturum bilgilerine (<code>request.session<\/code>) ve daha fazlas\u0131na eri\u015fim sa\u011flar.<\/p>\n<p>Rotalar ise <code>mywebapp\/__init__.py<\/code> dosyas\u0131nda <code>Configurator<\/code> nesnesi kullan\u0131larak tan\u0131mlan\u0131r:<\/p>\n<pre><code class=\"language-python\">from pyramid.config import Configurator\n\ndef main(global_config, <em><\/em>settings):\n    with Configurator(settings=settings) as config:\n        config.include('pyramid_chameleon') # E\u011fer Chameleon \u015fablon motoru kullan\u0131yorsan\u0131z\n        config.add_static_view('static', 'static', cache_max_age=3600)\n        config.add_route('home', '\/')\n        config.add_route('hello', '\/hello\/{name}') # URL parametresi ile\n        config.scan('.') # mywebapp mod\u00fcl\u00fcndeki t\u00fcm @view_config'lar\u0131 tarar\n    return config.make_wsgi_app()<\/code><\/pre>\n<p>*   <code>config.add_route('home', '\/')<\/code>: <code>\/<\/code> URL&#8217;sine <code>home<\/code> ad\u0131n\u0131 veren bir rota tan\u0131mlar.<br \/>\n*   <code>config.add_route('hello', '\/hello\/{name}')<\/code>: <code>\/hello\/<\/code> ile ba\u015flayan ve sonras\u0131nda bir parametre (<code>name<\/code>) alan bir rota tan\u0131mlar. Bu parametreye g\u00f6r\u00fcn\u00fcm i\u00e7inde <code>request.matchdict['name']<\/code> ile eri\u015filebilir.<br \/>\n*   <code>config.scan('.')<\/code>: Pyramid&#8217;e, uygulaman\u0131n ge\u00e7erli dizinindeki (ve alt dizinlerindeki) t\u00fcm Python dosyalar\u0131n\u0131 taramas\u0131n\u0131 ve <code>@view_config<\/code> dekorat\u00f6rleri ile i\u015faretlenmi\u015f g\u00f6r\u00fcn\u00fcmleri kaydetmesini s\u00f6yler.<\/p>\n<h3>\u015eablonlar (Templates)<\/h3>\n<p>Pyramid, HTML olu\u015fturmak i\u00e7in \u00e7e\u015fitli \u015fablon motorlar\u0131n\u0131 destekler. Varsay\u0131lan olarak <code>pyramid_chameleon<\/code> veya <code>pyramid_jinja2<\/code> gibi eklentilerle gelir. Starter \u015fablon genellikle Chameleon kullan\u0131r.<\/p>\n<p><code>mywebapp\/templates\/mytemplate.pt<\/code> dosyas\u0131 \u015f\u00f6yle g\u00f6r\u00fcnebilir:<\/p>\n<pre><code class=\"language-html\"><!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Pyramid App<\/title>\n    <link rel=\"stylesheet\" href=\"${request.static_url('mywebapp:static\/sample.css')}\">\n<\/head>\n<body>\n    \n    <p>This is a basic Pyramid application.<\/p>\n    <p><a href=\"${request.route_url('hello', name='PyramidUser')}\">Say Hello to PyramidUser<\/a><\/p>\n<\/body>\n<\/html><\/code><\/pre>\n<p>*   <code>${project}<\/code>: G\u00f6r\u00fcn\u00fcmden gelen <code>project<\/code> anahtar\u0131n\u0131n de\u011ferini buraya yerle\u015ftirir.<br \/>\n*   <code>${request.static_url(...)<\/code>}: Statik bir dosyan\u0131n (CSS, JS, resim) URL&#8217;sini olu\u015fturur.<br \/>\n*   <code>${request.route_url(...)<\/code>}: Bir rotan\u0131n URL&#8217;sini olu\u015fturur. Bu, URL&#8217;lerin dinamik olarak olu\u015fturulmas\u0131n\u0131 sa\u011flar ve rota tan\u0131mlar\u0131 de\u011fi\u015fti\u011finde kodunuzu g\u00fcncellemenizi gerektirmez.<\/p>\n<h3>Varl\u0131klar (Assets) ve Statik Dosyalar<\/h3>\n<p>CSS, JavaScript dosyalar\u0131 ve resimler gibi statik varl\u0131klar, <code>mywebapp\/static\/<\/code> dizininde bulunur. Bu dosyalar\u0131n taray\u0131c\u0131 taraf\u0131ndan eri\u015filebilir olmas\u0131 i\u00e7in <code>mywebapp\/__init__.py<\/code> i\u00e7inde bir statik g\u00f6r\u00fcn\u00fcm tan\u0131mlan\u0131r:<\/p>\n<pre><code class=\"language-python\">config.add_static_view('static', 'static', cache_max_age=3600)<\/code><\/pre>\n<p>*   <code>'static'<\/code>: Bu, URL&#8217;de <code>\/static\/<\/code> \u00f6n eki ile eri\u015filebilecek bir adland\u0131rmad\u0131r.<br \/>\n*   <code>'static'<\/code>: Bu, uygulaman\u0131n <code>static<\/code> dizinindeki dosyalar\u0131 sunar.<br \/>\n*   <code>cache_max_age=3600<\/code>: Taray\u0131c\u0131lar\u0131n bu dosyalar\u0131 ne kadar s\u00fcreyle \u00f6nbelle\u011fe alabilece\u011fini belirtir (saniye cinsinden).<\/p>\n<p>Bu yap\u0131land\u0131rma sayesinde, \u015fablonlar\u0131n\u0131zda <code>request.static_url('mywebapp:static\/sample.css')<\/code> gibi ifadelerle statik dosyalara g\u00fcvenli bir \u015fekilde referans verebilirsiniz.<\/p>\n<h2>Veritaban\u0131 Entegrasyonu<\/h2>\n<p>Modern web uygulamalar\u0131n\u0131n \u00e7o\u011fu veritaban\u0131 etkile\u015fimine ihtiya\u00e7 duyar. Pyramid, belirli bir ORM (Object-Relational Mapper) dayatmaz, ancak SQLAlchemy Python d\u00fcnyas\u0131nda en pop\u00fcler ve g\u00fc\u00e7l\u00fc ORM&#8217;lerden biridir ve Pyramid ile harika bir uyum i\u00e7indedir. Bu b\u00f6l\u00fcmde, PostgreSQL veritaban\u0131m\u0131z\u0131 SQLAlchemy ve Alembic ile entegre edece\u011fiz.<\/p>\n<h3>SQLAlchemy ve Alembic<\/h3>\n<p>*   <strong>SQLAlchemy<\/strong>: Python nesnelerini veritaban\u0131 tablolar\u0131na e\u015fleyen ve veritaban\u0131 i\u015flemlerini Python koduyla yapmam\u0131z\u0131 sa\u011flayan bir ORM&#8217;dir. Ham SQL sorgular\u0131 yazmak yerine Python s\u0131n\u0131flar\u0131 ve nesneleriyle \u00e7al\u0131\u015f\u0131r\u0131z.<br \/>\n*   <strong>Alembic<\/strong>: SQLAlchemy i\u00e7in bir veritaban\u0131 ge\u00e7i\u015f (migration) arac\u0131d\u0131r. Veritaban\u0131 \u015feman\u0131zdaki de\u011fi\u015fiklikleri (yeni tablolar, s\u00fctun ekleme\/\u00e7\u0131karma) y\u00f6netmenizi sa\u011flar.<\/p>\n<p>\u00d6ncelikle, gerekli paketleri sanal ortam\u0131m\u0131za kural\u0131m:<\/p>\n<pre><code class=\"language-bash\">pip install sqlalchemy alembic psycopg2-binary<\/code><\/pre>\n<p>*   <code>psycopg2-binary<\/code>: PostgreSQL veritaban\u0131 s\u00fcr\u00fcc\u00fcs\u00fcd\u00fcr.<\/p>\n<p>\u015eimdi Alembic&#8217;i projemize entegre edelim. Proje k\u00f6k dizinindeyken (yani <code>mywebapp<\/code> dizininin i\u00e7inde), Alembic yap\u0131land\u0131rmas\u0131n\u0131 ba\u015flat\u0131n:<\/p>\n<pre><code class=\"language-bash\">alembic init alembic<\/code><\/pre>\n<p>Bu komut, <code>alembic<\/code> ad\u0131nda yeni bir dizin olu\u015fturacak ve i\u00e7ine Alembic&#8217;in yap\u0131land\u0131rma dosyalar\u0131n\u0131 (\u00f6zellikle <code>alembic.ini<\/code> ve <code>env.py<\/code>) yerle\u015ftirecektir.<\/p>\n<p><code>alembic.ini<\/code> dosyas\u0131nda veritaban\u0131 ba\u011flant\u0131 dizenizi ayarlaman\u0131z gerekir. Dosyay\u0131 a\u00e7\u0131n ve <code>sqlalchemy.url<\/code> sat\u0131r\u0131n\u0131 bulun. Kendi PostgreSQL ba\u011flant\u0131 dizenizle g\u00fcncelleyin:<\/p>\n<pre><code class=\"language-ini\"># alembic.ini\n<h2>...<\/h2>\nsqlalchemy.url = postgresql:\/\/myuser:your_password@localhost:5432\/myapp_db\n<h2>...<\/code><\/pre>\n<\/h2>\n<p><code>your_password<\/code> k\u0131sm\u0131n\u0131 PostgreSQL kullan\u0131c\u0131n\u0131z\u0131 olu\u015ftururken belirledi\u011finiz \u015fifre ile de\u011fi\u015ftirin.<\/p>\n<p>Ard\u0131ndan, <code>alembic\/env.py<\/code> dosyas\u0131n\u0131 d\u00fczenlememiz gerekecek. Alembic&#8217;in SQLAlchemy modellerinizi otomatik olarak alg\u0131layabilmesi i\u00e7in bu dosyay\u0131 g\u00fcncelleyece\u011fiz. <code>env.py<\/code> i\u00e7inde <code>target_metadata = None<\/code> sat\u0131r\u0131n\u0131 bulun ve <code>target_metadata = Base.metadata<\/code> olarak de\u011fi\u015ftirin. Ayr\u0131ca, <code>Base<\/code> nesnesini <code>mywebapp.models.mymodel<\/code> dosyas\u0131ndan i\u00e7e aktarman\u0131z gerekecek.<\/p>\n<p><code>alembic\/env.py<\/code> dosyas\u0131nda yap\u0131lmas\u0131 gereken de\u011fi\u015fiklikler (sadece ilgili k\u0131s\u0131mlar):<\/p>\n<pre><code class=\"language-python\"># alembic\/env.py\n<h2>...<\/h2>\nfrom logging.config import fileConfig\n\n<h2>mywebapp projenizin k\u00f6k dizininden Base'i i\u00e7e aktar\u0131n<\/h2>\nimport os\nimport sys\nsys.path.append(os.getcwd())\nfrom mywebapp.models.mymodel import Base # Kendi model dosyan\u0131z\u0131n yolunu belirtin\n\n<h2>...<\/h2>\n<h2>target_metadata = None  # Bu sat\u0131r\u0131 silin veya yorumlay\u0131n<\/h2>\ntarget_metadata = Base.metadata # Bu sat\u0131r\u0131 ekleyin\n<h2>...<\/code><\/pre>\n<\/h2>\n<h3>Model Tan\u0131mlama<\/h3>\n<p><code>mywebapp\/models\/mymodel.py<\/code> dosyas\u0131 genellikle uygulaman\u0131z\u0131n veritaban\u0131 modellerini i\u00e7erir. Varsay\u0131lan olarak bir <code>Page<\/code> modeli i\u00e7erebilir. Biz basit bir <code>User<\/code> modeli ekleyelim.<\/p>\n<p><code>mywebapp\/models\/mymodel.py<\/code> dosyas\u0131n\u0131 d\u00fczenleyin:<\/p>\n<pre><code class=\"language-python\">from sqlalchemy import Column, Integer, Text\nfrom sqlalchemy.ext.declarative import declarative_base\nfrom sqlalchemy.orm import scoped_session, sessionmaker\nfrom zope.sqlalchemy import ZopeTransactionExtension\n\n<h2>Veritaban\u0131 oturumu ve temel s\u0131n\u0131f tan\u0131mlar\u0131<\/h2>\nDBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))\nBase = declarative_base()\n\n<h2>\u00d6rnek bir User modeli<\/h2>\nclass User(Base):\n    __tablename__ = 'users'\n    id = Column(Integer, primary_key=True)\n    username = Column(Text, unique=True)\n    email = Column(Text, unique=True)\n    password_hash = Column(Text)\n\n    def __init__(self, username, email, password_hash):\n        self.username = username\n        self.email = email\n        self.password_hash = password_hash\n\n    def __repr__(self):\n        return f\"<User(id={self.id}, username='{self.username}')>\"\n\n<h2>Veritaban\u0131 ba\u011flant\u0131s\u0131n\u0131 ba\u015flatan fonksiyon (genellikle __init__.py'den \u00e7a\u011fr\u0131l\u0131r)<\/h2>\ndef initialize_sql(engine):\n    DBSession.configure(bind=engine)\n    Base.metadata.bind = engine\n    Base.metadata.create_all(engine) # Bu sadece ilk kurulumda veya testlerde kullan\u0131lmal\u0131<\/code><\/pre>\n<p><code>initialize_sql<\/code> fonksiyonu, veritaban\u0131 ba\u011flant\u0131s\u0131n\u0131 kurmak i\u00e7in kullan\u0131l\u0131r. Bu fonksiyon genellikle <code>mywebapp\/__init__.py<\/code> i\u00e7indeki <code>main<\/code> fonksiyonunda \u00e7a\u011fr\u0131l\u0131r.<\/p>\n<p><code>mywebapp\/__init__.py<\/code> dosyas\u0131n\u0131 g\u00fcncelleyin:<\/p>\n<pre><code class=\"language-python\">from pyramid.config import Configurator\nfrom sqlalchemy import engine_from_config\nfrom .models.mymodel import initialize_sql, DBSession # DBSession'\u0131 da i\u00e7e aktar\u0131n\n\ndef main(global_config, <em><\/em>settings):\n    with Configurator(settings=settings) as config:\n        config.include('pyramid_chameleon')\n        config.include('pyramid_tm') # \u0130\u015flem y\u00f6neticisi i\u00e7in\n        config.add_static_view('static', 'static', cache_max_age=3600)\n        config.add_route('home', '\/')\n        config.add_route('hello', '\/hello\/{name}')\n        config.scan('.')\n\n        # Veritaban\u0131 ba\u011flant\u0131s\u0131n\u0131 ba\u015flat\n        engine = engine_from_config(settings, 'sqlalchemy.')\n        initialize_sql(engine)\n\n        # request nesnesine DBSession'\u0131 ekle\n        config.add_request_method(lambda request: DBSession, 'dbsession', reify=True)\n\n    return config.make_wsgi_app()<\/code><\/pre>\n<p><code>config.add_request_method<\/code> ile <code>DBSession<\/code>&#8216;\u0131 <code>request.dbsession<\/code> olarak g\u00f6r\u00fcn\u00fcmlerinize ekliyoruz. <code>pyramid_tm<\/code> (transaction manager) eklentisi, veritaban\u0131 i\u015flemlerini otomatik olarak y\u00f6netir (istek sonunda commit veya rollback).<\/p>\n<p>\u015eimdi Alembic ile veritaban\u0131 \u015femam\u0131z\u0131 olu\u015ftural\u0131m. Proje k\u00f6k dizinindeyken:<\/p>\n<pre><code class=\"language-bash\"># \u0130lk ge\u00e7i\u015f dosyas\u0131n\u0131 olu\u015fturun\nalembic revision -m \"create user table\"\n\n<h2>Ge\u00e7i\u015f dosyas\u0131n\u0131 d\u00fczenleyin (opsiyonel, Alembic otomatik olarak User tablosunu alg\u0131lamal\u0131d\u0131r)<\/h2>\n<h2>alembic\/versions\/xxxx_create_user_table.py dosyas\u0131n\u0131 a\u00e7\u0131p upgrade\/downgrade metodlar\u0131n\u0131 kontrol edin.<\/h2>\n<h2>Alembic, Base.metadata'y\u0131 tarayarak tablolar\u0131 otomatik olarak olu\u015fturmaya \u00e7al\u0131\u015facakt\u0131r.<\/h2>\n\n<h2>Veritaban\u0131 \u015femas\u0131n\u0131 uygulay\u0131n<\/h2>\nalembic upgrade head<\/code><\/pre>\n<p>Art\u0131k PostgreSQL veritaban\u0131n\u0131zda <code>users<\/code> ad\u0131nda bir tablo olmal\u0131.<\/p>\n<h3>Veritaban\u0131 \u0130\u015flemleri<\/h3>\n<p>G\u00f6r\u00fcn\u00fcmlerinizde <code>request.dbsession<\/code>&#8216;\u0131 kullanarak veritaban\u0131 i\u015flemleri yapabilirsiniz. \u00d6rne\u011fin, yeni bir kullan\u0131c\u0131 ekleyen bir g\u00f6r\u00fcn\u00fcm olu\u015ftural\u0131m:<\/p>\n<p><code>mywebapp\/views\/default.py<\/code> dosyas\u0131na ekleyin:<\/p>\n<pre><code class=\"language-python\">from pyramid.view import view_config\nfrom pyramid.response import Response\nfrom ..models.mymodel import User # User modelini i\u00e7e aktar\u0131n\n\n@view_config(route_name='add_user', renderer='json', request_method='POST')\ndef add_user_view(request):\n    username = request.json_body.get('username')\n    email = request.json_body.get('email')\n    password_hash = \"dummy_hash\" # Ger\u00e7ek uygulamada \u015fifreyi hash'lemelisiniz\n\n    if not username or not email:\n        return Response(json_body={'error': 'Username and email are required'}, status=400)\n\n    new_user = User(username=username, email=email, password_hash=password_hash)\n    request.dbsession.add(new_user)\n    # pyramid_tm sayesinde commit otomatik yap\u0131l\u0131r\n\n    return {'message': f'User {username} added successfully!', 'user_id': new_user.id}\n\n@view_config(route_name='list_users', renderer='json')\ndef list_users_view(request):\n    users = request.dbsession.query(User).all()\n    user_list = [{'id': u.id, 'username': u.username, 'email': u.email} for u in users]\n    return {'users': user_list}<\/code><\/pre>\n<p><code>mywebapp\/__init__.py<\/code> dosyas\u0131na yeni rotalar\u0131 ekleyin:<\/p>\n<pre><code class=\"language-python\"># ...\nconfig.add_route('add_user', '\/users')\nconfig.add_route('list_users', '\/users')\n<h2>...<\/code><\/pre>\n<\/h2>\n<p>Uygulaman\u0131z\u0131 yeniden ba\u015flat\u0131n (<code>pserve development.ini --reload<\/code>). Art\u0131k <code>curl<\/code> gibi bir ara\u00e7la test edebilirsiniz:<\/p>\n<pre><code class=\"language-bash\"># Yeni kullan\u0131c\u0131 ekle\ncurl -X POST -H \"Content-Type: application\/json\" -d '{\"username\": \"testuser\", \"email\": \"test@example.com\"}' http:\/\/localhost:6543\/users\n\n<h2>Kullan\u0131c\u0131lar\u0131 listele<\/h2>\ncurl http:\/\/localhost:6543\/users<\/code><\/pre>\n<p>Bu \u00f6rnekler, Pyramid&#8217;de veritaban\u0131 i\u015flemlerinin ne kadar kolay oldu\u011funu g\u00f6stermektedir.<\/p>\n<h2>Kimlik Do\u011frulama ve Yetkilendirme (\u0130ste\u011fe Ba\u011fl\u0131 ama \u00d6nemli)<\/h2>\n<p>\u00c7o\u011fu web uygulamas\u0131, kullan\u0131c\u0131lar\u0131 kimlik do\u011frulamadan ge\u00e7irme (login) ve belirli kaynaklara eri\u015fimlerini yetkilendirme (izinler) ihtiyac\u0131 duyar. Pyramid, bu konuda esnek ve g\u00fc\u00e7l\u00fc bir g\u00fcvenlik modeli sunar.<\/p>\n<h3>Pyramid&#8217;in G\u00fcvenlik Modeli<\/h3>\n<p>Pyramid&#8217;in g\u00fcvenlik modeli iki ana bile\u015fene dayan\u0131r:<br \/>\n*   <strong>Kimlik Do\u011frulama Politikas\u0131 (<code>authentication_policy<\/code>)<\/strong>: Gelen iste\u011fi inceleyerek bir kullan\u0131c\u0131n\u0131n kimli\u011fini (genellikle bir kullan\u0131c\u0131 kimli\u011fi veya bir dizi kimlik) belirler. Bu, HTTP Basic Auth, oturum tabanl\u0131 kimlik do\u011frulama veya JWT (JSON Web Token) gibi farkl\u0131 y\u00f6ntemlerle yap\u0131labilir.<br \/>\n*   <strong>Yetkilendirme Politikas\u0131 (<code>authorization_policy<\/code>)<\/strong>: Kimli\u011fi belirlenmi\u015f bir kullan\u0131c\u0131n\u0131n belirli bir kayna\u011fa veya i\u015fleme eri\u015fim izni olup olmad\u0131\u011f\u0131n\u0131 belirler. Pyramid, bu genellikle ACL&#8217;ler (Access Control Lists) veya grup tabanl\u0131 izinlerle yap\u0131l\u0131r.<\/p>\n<p>\u00d6rnek olarak, basit bir oturum tabanl\u0131 kimlik do\u011frulama i\u00e7in <code>pyramid_session<\/code> ve <code>pyramid_beaker<\/code> veya <code>pyramid_redis_sessions<\/code> gibi eklentileri kullanabiliriz. Ancak bu, makalenin kapsam\u0131n\u0131 geni\u015fletece\u011fi i\u00e7in sadece temel kavramlara de\u011finelim.<\/p>\n<p><code>mywebapp\/__init__.py<\/code> i\u00e7inde g\u00fcvenlik politikalar\u0131n\u0131 yap\u0131land\u0131rabilirsiniz:<\/p>\n<pre><code class=\"language-python\">from pyramid.authentication import AuthTktAuthenticationPolicy\nfrom pyramid.authorization import ACLAuthorizationPolicy\n<h2>...<\/h2>\n\ndef main(global_config, <em><\/em>settings):\n    # ...\n    with Configurator(settings=settings) as config:\n        # ...\n        # G\u00fcvenlik politikalar\u0131n\u0131 yap\u0131land\u0131r\u0131n\n        authn_policy = AuthTktAuthenticationPolicy(\n            settings['auth.secret'], # G\u00fc\u00e7l\u00fc bir gizli anahtar\n            callback=None, # Kullan\u0131c\u0131 kimli\u011fini d\u00f6nd\u00fcren bir callback fonksiyonu\n            hashalg='sha512'\n        )\n        authz_policy = ACLAuthorizationPolicy()\n        config.set_authentication_policy(authn_policy)\n        config.set_authorization_policy(authz_policy)\n        # ...\n    # ...<\/code><\/pre>\n<p>Daha sonra g\u00f6r\u00fcn\u00fcmlerinizde <code>@view_config(permission='edit')<\/code> gibi ifadelerle yetkilendirme gereksinimleri belirtebilir ve ACL&#8217;ler veya \u00f6zel bir callback fonksiyonu ile bu izinleri y\u00f6netebilirsiniz.<\/p>\n<h2>Test Etme<\/h2>\n<p>Testler, uygulaman\u0131z\u0131n beklendi\u011fi gibi \u00e7al\u0131\u015ft\u0131\u011f\u0131ndan emin olman\u0131n ve gelecekteki de\u011fi\u015fikliklerin mevcut i\u015flevselli\u011fi bozmad\u0131\u011f\u0131n\u0131 do\u011frulaman\u0131n anahtar\u0131d\u0131r. Pyramid, test yazmay\u0131 kolayla\u015ft\u0131ran ara\u00e7larla birlikte gelir.<\/p>\n<h3>Pyramid&#8217;in Test Yakla\u015f\u0131m\u0131<\/h3>\n<p>Pyramid projeleri genellikle <code>pytest<\/code> veya <code>unittest<\/code> ile test edilir. Starter \u015fablonu genellikle <code>pytest<\/code>&#8216;i kullan\u0131r ve <code>mywebapp\/tests\/test_mywebapp.py<\/code> i\u00e7inde \u00f6rnek testler bulunur.<\/p>\n<p><code>mywebapp\/tests\/test_mywebapp.py<\/code> dosyas\u0131na bakarsan\u0131z, \u015funa benzer testler g\u00f6receksiniz:<\/p>\n<pre><code class=\"language-python\">import unittest\nfrom pyramid import testing\n\nclass ViewTests(unittest.TestCase):\n    def setUp(self):\n        self.config = testing.setUp()\n\n    def tearDown(self):\n        testing.tearDown()\n\n    def test_my_view(self):\n        from ..views.default import my_view\n        request = testing.DummyRequest()\n        info = my_view(request)\n        self.assertEqual(info['project'], 'mywebapp')\n\nclass FunctionalTests(unittest.TestCase):\n    def setUp(self):\n        from mywebapp import main\n        app = main({})\n        from webtest import TestApp\n        self.testapp = TestApp(app)\n\n    def test_root(self):\n        res = self.testapp.get('\/', status=200)\n        self.assertIn(b'Welcome to mywebapp!', res.body)\n\n    def test_hello_view(self):\n        res = self.testapp.get('\/hello\/TestUser', status=200)\n        self.assertIn(b'Hello, TestUser!', res.body)<\/code><\/pre>\n<p>*   <strong>Birim Testleri (Unit Tests)<\/strong>: Tek tek fonksiyonlar\u0131 veya bile\u015fenleri izole bir \u015fekilde test eder. <code>testing.DummyRequest()<\/code> kullanarak sahte istek nesneleri olu\u015fturulabilir.<br \/>\n*   <strong>Fonksiyonel Testler (Functional Tests)<\/strong>: Uygulaman\u0131n bir b\u00fct\u00fcn olarak nas\u0131l \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 test eder. <code>webtest<\/code> k\u00fct\u00fcphanesi, uygulaman\u0131za HTTP istekleri g\u00f6ndermenizi ve yan\u0131tlar\u0131 kontrol etmenizi sa\u011flar.<\/p>\n<p>Testleri \u00e7al\u0131\u015ft\u0131rmak i\u00e7in sanal ortam\u0131n\u0131z etkinle\u015ftirilmi\u015fken proje k\u00f6k dizininde a\u015fa\u011f\u0131daki komutu kullan\u0131n:<\/p>\n<pre><code class=\"language-bash\">pytest<\/code><\/pre>\n<p>Bu komut, <code>tests<\/code> dizinindeki t\u00fcm testleri bulacak ve \u00e7al\u0131\u015ft\u0131racakt\u0131r. Veritaban\u0131 etkile\u015fimi olan testler i\u00e7in, ayr\u0131 bir test veritaban\u0131 veya bellek i\u00e7i SQLite veritaban\u0131 kullanmak iyi bir pratiktir.<\/p>\n<h2>Da\u011f\u0131t\u0131m (Deployment)<\/h2>\n<p>Uygulaman\u0131z geli\u015ftirme ortam\u0131nda sorunsuz \u00e7al\u0131\u015ft\u0131ktan sonra, onu canl\u0131 bir sunucuya da\u011f\u0131tma zaman\u0131 gelir. Pyramid uygulamalar\u0131n\u0131 da\u011f\u0131tmak i\u00e7in standart Python WSGI (Web Server Gateway Interface) y\u00f6ntemlerini kullan\u0131r.<\/p>\n<h3>\u00dcretim Ortam\u0131 \u0130\u00e7in Haz\u0131rl\u0131k<\/h3>\n<p><code>production.ini<\/code> dosyas\u0131, uygulaman\u0131z\u0131n \u00fcretim ortam\u0131ndaki yap\u0131land\u0131rmas\u0131n\u0131 i\u00e7erir. Bu dosya, <code>development.ini<\/code>&#8216;den farkl\u0131 olarak hata ay\u0131klama modunu kapatmal\u0131, veritaban\u0131 ba\u011flant\u0131lar\u0131n\u0131 do\u011fru \u015fekilde yap\u0131land\u0131rmal\u0131 ve g\u00fcvenlik a\u00e7\u0131s\u0131ndan hassas bilgileri (gizli anahtarlar gibi) ortam de\u011fi\u015fkenlerinden almal\u0131d\u0131r.<\/p>\n<p>\u00d6nemli ayarlar:<br \/>\n*   <code>pyramid.reload_templates = false<\/code><br \/>\n*   <code>debug_toolbar.enabled = false<\/code><br \/>\n*   Veritaban\u0131 ba\u011flant\u0131 dizeleri (genellikle <code>postgresql:\/\/myuser:MY_PROD_PASSWORD@localhost:5432\/myapp_db_prod<\/code> gibi)<\/p>\n<h3>WSGI Sunucusu: Gunicorn veya uWSGI<\/h3>\n<p>Pyramid, bir WSGI uygulamas\u0131 oldu\u011fu i\u00e7in, onu <code>Gunicorn<\/code> veya <code>uWSGI<\/code> gibi bir WSGI sunucusuyla \u00e7al\u0131\u015ft\u0131rman\u0131z gerekir. Bu sunucular, HTTP isteklerini uygulaman\u0131za y\u00f6nlendiren ve uygulaman\u0131z\u0131n e\u015fzamanl\u0131 istekleri i\u015flemesini sa\u011flayan y\u00fcksek performansl\u0131 sunuculard\u0131r.<\/p>\n<p>Gunicorn&#8217;u kural\u0131m:<\/p>\n<pre><code class=\"language-bash\">pip install gunicorn<\/code><\/pre>\n<p>Uygulaman\u0131z\u0131 Gunicorn ile \u00e7al\u0131\u015ft\u0131rmak i\u00e7in:<\/p>\n<pre><code class=\"language-bash\">gunicorn --paste production.ini<\/code><\/pre>\n<p>Bu komut, Gunicorn&#8217;u <code>production.ini<\/code> dosyas\u0131nda belirtilen ayarlarla Pyramid uygulaman\u0131z\u0131 ba\u015flatmak i\u00e7in kullan\u0131r. Varsay\u0131lan olarak 8000 portunda dinleyecektir.<\/p>\n<h3>Nginx ile Ters Proxy<\/h3>\n<p>\u00dcretim ortam\u0131nda, genellikle Gunicorn gibi bir WSGI sunucusunun \u00f6n\u00fcne Nginx gibi bir ters proxy sunucusu yerle\u015ftirilir. Nginx, statik dosyalar\u0131 do\u011frudan sunar, SSL sonland\u0131rmay\u0131 y\u00f6netir ve Gunicorn&#8217;a gelen istekleri y\u00f6nlendirir.<\/p>\n<p>Nginx&#8217;i kurun:<\/p>\n<pre><code class=\"language-bash\">sudo apt install -y nginx<\/code><\/pre>\n<p>Nginx yap\u0131land\u0131rma dosyas\u0131 olu\u015fturun (<code>\/etc\/nginx\/sites-available\/mywebapp<\/code>):<\/p>\n<pre><code class=\"language-nginx\">server {\n    listen 80;\n    server_name your_domain.com www.your_domain.com; # Kendi alan ad\u0131n\u0131z\u0131 girin\n\n    location \/static\/ {\n        alias \/path\/to\/mywebapp\/mywebapp\/static\/; # Statik dosyalar\u0131n\u0131z\u0131n yolu\n    }\n\n    location \/ {\n        proxy_pass http:\/\/127.0.0.1:8000; # Gunicorn'un dinledi\u011fi adres ve port\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}<\/code><\/pre>\n<p>Bu dosyay\u0131 etkinle\u015ftirin ve Nginx&#8217;i yeniden ba\u015flat\u0131n:<\/p>\n<pre><code class=\"language-bash\">sudo ln -s \/etc\/nginx\/sites-available\/mywebapp \/etc\/nginx\/sites-enabled\/\nsudo nginx -t # Yap\u0131land\u0131rmay\u0131 test et\nsudo systemctl restart nginx<\/code><\/pre>\n<p>Art\u0131k <code>your_domain.com<\/code> adresine gelen istekler Nginx taraf\u0131ndan kar\u015f\u0131lanacak, statik dosyalar do\u011frudan Nginx&#8217;ten sunulacak ve di\u011fer t\u00fcm istekler Gunicorn&#8217;a y\u00f6nlendirilecektir.<\/p>\n<h3>Sistem Hizmeti Olarak \u00c7al\u0131\u015ft\u0131rma (systemd)<\/h3>\n<p>Uygulaman\u0131z\u0131n sunucu yeniden ba\u015flat\u0131ld\u0131\u011f\u0131nda otomatik olarak ba\u015flamas\u0131 ve arka planda s\u00fcrekli \u00e7al\u0131\u015fmas\u0131 i\u00e7in <code>systemd<\/code> servisi olarak yap\u0131land\u0131rmak iyi bir \u00e7\u00f6z\u00fcmd\u00fcr.<\/p>\n<p><code>\/etc\/systemd\/system\/mywebapp.service<\/code> ad\u0131nda bir dosya olu\u015fturun:<\/p>\n<pre><code class=\"language-ini\">[Unit]\nDescription=Gunicorn instance to serve mywebapp\nAfter=network.target\n\n[Service]\nUser=myuser # Uygulamay\u0131 \u00e7al\u0131\u015ft\u0131racak kullan\u0131c\u0131\nGroup=www-data # \u0130ste\u011fe ba\u011fl\u0131\nWorkingDirectory=\/path\/to\/mywebapp # Projenizin k\u00f6k dizini\nEnvironment=\"PATH=\/path\/to\/mywebapp\/.venv\/bin\" # Sanal ortam\u0131n\u0131z\u0131n bin dizini\nExecStart=\/path\/to\/mywebapp\/.venv\/bin\/gunicorn --workers 3 --bind unix:\/tmp\/mywebapp.sock --timeout 120 --paste production.ini\n<h2>--bind unix:\/tmp\/mywebapp.sock yerine --bind 127.0.0.1:8000 de kullanabilirsiniz<\/h2>\nRestart=always\n\n[Install]\nWantedBy=multi-user.target<\/code><\/pre>\n<p>Servisi etkinle\u015ftirin ve ba\u015flat\u0131n:<\/p>\n<pre><code class=\"language-bash\">sudo systemctl daemon-reload\nsudo systemctl start mywebapp\nsudo systemctl enable mywebapp\nsudo systemctl status mywebapp<\/code><\/pre>\n<p>Bu ad\u0131mlarla, Pyramid uygulaman\u0131z \u00fcretim ortam\u0131nda g\u00fcvenilir bir \u015fekilde \u00e7al\u0131\u015fmaya ba\u015flayacakt\u0131r.<\/p>\n<h2>Sonu\u00e7 ve \u0130leri Ad\u0131mlar<\/h2>\n<p>Bu kapsaml\u0131 rehberde, Ubuntu \u00fczerinde bir Pyramid web uygulamas\u0131n\u0131 s\u0131f\u0131rdan kurmay\u0131, temel bile\u015fenlerini anlamay\u0131, veritaban\u0131 entegrasyonunu yapmay\u0131 ve da\u011f\u0131t\u0131m i\u00e7in gerekli ad\u0131mlar\u0131 atmay\u0131 \u00f6\u011frendiniz. Pyramid&#8217;in esnekli\u011fi, geli\u015ftiriciye tam kontrol sa\u011flamas\u0131 ve g\u00fc\u00e7l\u00fc eklenti ekosistemi, onu her boyutta proje i\u00e7in cazip bir se\u00e7enek haline getirir.<\/p>\n<p>Pyramid, karma\u015f\u0131k API&#8217;ler, mikro hizmetler veya \u00f6zel i\u015f mant\u0131\u011f\u0131 gerektiren web uygulamalar\u0131 olu\u015fturmak isteyen geli\u015ftiriciler i\u00e7in m\u00fckemmel bir ara\u00e7t\u0131r. Daha az &#8220;sihir&#8221; ve daha fazla a\u00e7\u0131kl\u0131k sunarak, uygulaman\u0131z\u0131n her katman\u0131n\u0131 tam olarak anlaman\u0131za ve kontrol etmenize olanak tan\u0131r.<\/p>\n<p>\u0130leri ad\u0131mlar olarak \u015funlar\u0131 d\u00fc\u015f\u00fcnebilirsiniz:<br \/>\n*   <strong>Kimlik Do\u011frulama ve Yetkilendirme<\/strong>: <code>pyramid_auth_toolkit<\/code>, <code>pyramid_jwt<\/code> gibi eklentileri ara\u015ft\u0131rarak uygulaman\u0131za sa\u011flam bir g\u00fcvenlik katman\u0131 ekleyin.<br \/>\n*   <strong>Form \u0130\u015fleme ve Do\u011frulama<\/strong>: <code>colander<\/code> veya <code>marshmallow<\/code> gibi k\u00fct\u00fcphanelerle form verilerini daha etkili bir \u015fekilde y\u00f6netin.<br \/>\n*   <strong>Hata Ay\u0131klama Ara\u00e7lar\u0131<\/strong>: Geli\u015ftirme s\u0131ras\u0131nda <code>pyramid_debugtoolbar<\/code> gibi ara\u00e7lar\u0131 kullanarak uygulaman\u0131z\u0131n performans\u0131n\u0131 ve davran\u0131\u015f\u0131n\u0131 izleyin.<br \/>\n*   <strong>Test Kapsam\u0131<\/strong>: Uygulaman\u0131z\u0131n t\u00fcm kritik b\u00f6l\u00fcmlerini kapsayan sa\u011flam bir test paketi olu\u015fturun.<br \/>\n*   <strong>Asenkron \u0130\u015flemler<\/strong>: Uzun s\u00fcren g\u00f6revleri (e-posta g\u00f6nderme, resim i\u015fleme) arka planda \u00e7al\u0131\u015ft\u0131rmak i\u00e7in <code>Celery<\/code> gibi bir g\u00f6rev kuyru\u011fu entegre edin.<br \/>\n*   <strong>API Geli\u015ftirme<\/strong>: Pyramid&#8217;in RESTful API&#8217;ler olu\u015fturmak i\u00e7in ne kadar uygun oldu\u011funu ke\u015ffedin.<\/p>\n<p>Pyramid toplulu\u011fu aktif ve dok\u00fcmantasyonlar\u0131 olduk\u00e7a kapsaml\u0131d\u0131r. Resmi Pyramid web sitesi ve GitHub depolar\u0131, daha fazla bilgi edinmek ve kar\u015f\u0131la\u015ft\u0131\u011f\u0131n\u0131z sorunlara \u00e7\u00f6z\u00fcm bulmak i\u00e7in harika kaynaklard\u0131r. Kendi Python web uygulamalar\u0131n\u0131z\u0131 Pyramid ile in\u015fa etme yolculu\u011funuzda ba\u015far\u0131lar dileriz!<br \/>\n<\/body><\/p>\n","protected":false},"excerpt":{"rendered":"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber\nGiri\u015f\nPython ekosistemi, web uygulamalar\u0131 gel","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":[1468],"tags":[],"class_list":{"0":"post-35955","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-ubuntu","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>Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber - 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\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber\" \/>\n<meta property=\"og:description\" content=\"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber Giri\u015f Python ekosistemi, web uygulamalar\u0131 gel\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2025-12-06T00:40:55+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=\"23 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber\",\"datePublished\":\"2025-12-06T00:40:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/\"},\"wordCount\":3065,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"articleSection\":[\"Ubuntu\"],\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/#respond\"]}],\"copyrightYear\":\"2025\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/\",\"name\":\"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2025-12-06T00:40:55+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber\"}]},{\"@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":"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber - 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\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/","og_locale":"tr_TR","og_type":"article","og_title":"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber","og_description":"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber Giri\u015f Python ekosistemi, web uygulamalar\u0131 gel","og_url":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2025-12-06T00:40:55+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"23 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber","datePublished":"2025-12-06T00:40:55+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/"},"wordCount":3065,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"articleSection":["Ubuntu"],"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/#respond"]}],"copyrightYear":"2025","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/","url":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/","name":"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2025-12-06T00:40:55+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/ubuntu-uzerinde-python-web-uygulamanizi-pyramid-cercevesi-ile-olusturmak-kapsamli-bir-rehber\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Ubuntu \u00dczerinde Python Web Uygulaman\u0131z\u0131 Pyramid \u00c7er\u00e7evesi ile Olu\u015fturmak: Kapsaml\u0131 Bir Rehber"}]},{"@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\/35955","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=35955"}],"version-history":[{"count":1,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35955\/revisions"}],"predecessor-version":[{"id":35956,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/35955\/revisions\/35956"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=35955"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=35955"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=35955"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}