Şəxsi API-də Requests ProxyError? Əvvəlcə mühiti yoxlayın
Requests proksi, auth və CA parametrlərini mühitdən birləşdirir. Prosesin gördüyünü oxuyun, şəxsi hostu istisna edin və TLS yoxlamasını açıq saxlayın.
VPN işləyir, daxili panel brauzerdə açılır, amma Python skripti yenə proksi xətası verir. Bu mənzərədə tuneldə heç bir problem yoxdur: interpretator öz mühitindən proksi ünvanı oxuyur və sorğunu ora göndərir. Bu təlimat prosesin həqiqətən gördüyü mühiti oxuyur, ən dar istisnanı tətbiq edir və yalnız ondan sonra açıq sessiya siyasətini nəzərdən keçirir. Hər addım çıxışı davam edib-etməyəcəyinizi müəyyən edən bir əmrlə bitir.
Prosesin həqiqətən gördüyü mühiti oxuyun
Masaüstü proksi parametrləri, shell eksportları və systemd unit-inin Environment= sətirləri üç fərqli mənbədir və Requests yalnız miras aldığı sonuncunu oxuyur. Aşağıdakı diaqnostikanı uğursuz skripti işlədən eyni shell, konteyner və ya unit-də işlədin, interaktiv terminalınızda yox. Giriş shell-inizdə eksport edilən dəyişən konteyner prosesi üçün görünməzdir və bu boşluq heç yerdən peyda olan proksi barədə bir çox hesabatı izah edir. İki əmr eyni məlumatı fərqli detallılıq səviyyələrində çap edir.
env | grep -i -E 'proxy|requests_ca_bundle|curl_ca_bundle'
python3 -c "import os;[print(k,'=',v) for k,v in sorted(os.environ.items()) if 'proxy' in k.lower()]"
Hər dəyişənin hər iki yazılışı oxunur və təkrar qeydlər prosesin onları aldığı sıra ilə tətbiq olunur, buna görə köhnə HTTP_PROXY indicə eksport etdiyiniz dəyəri üstələyə bilər. CA-bundle dəyişənləri burada da vacibdir, çünki onlar kodda heç yerdə görünmədən verify-ün nəyə həll olunduğunu dəyişir. Əgər çıxış boşdursa, mühit sizin probleminiz deyil və bu bölməni oxumağı dayandıra bilərsiniz. Əgər tanımadığınız bir proksi sadalayırsa, hər hansı dəyişiklik etməzdən əvvəl onu təyin edən faylı və ya unit-i tapın.
Requests-dən müəyyən bir URL ilə nə edəcəyini soruşun. Bu çağırış paket göndərmədən həmin sorğu üçün birləşdirilmiş proksi, verify və cert dəyərlərini göstərir.
python3 -c "import requests;s=requests.Session();print(s.merge_environment_settings('https://api.corp.example/status',{},None,None,None))"
Şəxsi host üçün boş olmayan proxies qeydi sizin cavabınızdır və çap olunan verify dəyəri sorğunun hansı CA-bundle-a etibar edəcəyini söyləyir. Əgər hər ikisi düzgün görünürsə, uğursuzluq yığında daha sonradır və yoxlama bölməsinə keçməlisiniz. Koddan təxmin etməyin: birləşmə hər sorğu üçün baş verir, buna görə bir sessiya iki host üçün fərqli davrana bilər.
Heç nəyi söndürməzdən əvvəl şəxsi hostu istisna edin
Proksi həqiqətən digər təyinatlar üçün tələb olunduqda, dar düzəliş bu host üçün istisnadır. Mövcud siyahıya əlavə edin, onu əvəz etməyin, çünki NO_PROXY-i silmək ona güvənən bütün digər daxili təyinatları pozur. Aşağıdakı əmrlər qeydi əlavə edir və sonra Requests-dən bypass-ın tətbiq olunub-olunmadığını soruşur.
export NO_PROXY="${NO_PROXY:+$NO_PROXY,}api.corp.example,.corp.example"
python3 -c "import requests;print(requests.utils.should_bypass_proxies('https://api.corp.example/status',None))"
Uyğunlaşdırma host suffiksi ilədir, buna görə .corp.example bütün domeni, api.corp.example isə bir adı əhatə edir. Tək ulduz hər host üçün proksini söndürür və demək olar ki, heç vaxt istehsal işinin istədiyi şey deyil. CIDR qeydinin qəbul edilib-edilməməsi imicdəki Requests və urllib3 versiyalarından asılıdır, buna görə işlədiyini fərz etmək əvəzinə dəqiq qeydi sınayın. should_bypass_proxies nəticəsini yaddaşdan yazdığınız host adı üçün deyil, real URL üçün yoxlayın.
İki qatı beyninizdə ayrı saxlayın. HTTP proksisini keçmək VPN-i keçmir, çünki proksi qərarı kitabxanada, tunel qərarı isə nüvənin marşrut cədvəlində baş verir.
trust_env-i yalnız qəsdən sessiya siyasəti kimi söndürün
Əgər bütün iş ətraf mühit konfiqurasiyasına məhəl qoymamalıdırsa, sessiyanı açıq şəkildə qurun və qərarı kodda qeyd edin. Bu, bir siyasətdir, iş dövrəsi deyil və rəyçinin görə biləcəyi bir diff-ə aiddir. Aşağıdakı nümunə timeout, açıq CA yolu və status yoxlamasını saxlayır.
import requests
with requests.Session() as session:
session.trust_env = False
response = session.get(
"https://api.corp.example/status",
timeout=(5, 20),
verify="/etc/ssl/certs/corp-ca.pem",
)
response.raise_for_status()
trust_env-ü söndürmək eyni anda üç davranışı dəyişir və onlardan yalnız biri proksi ilə bağlıdır. Requests .netrc etimad məlumatlarını oxumağı dayandırır və REQUESTS_CA_BUNDLE ilə CURL_CA_BUNDLE dəyişənləri verify-ə təsir etməyi dayandırır, o da sonra paketdə gələn sertifikat anbarına qayıdır. Əgər təşkilatınız TLS-i öz CA-sı ilə sonlandırırsa, bu geri dönüş indicə etdiyiniz dəyişikliklə əlaqəsiz görünən yoxlama xətası yaradır. verify-i açıq şəkildə ötürmək iki effekti ayrı saxlayan şeydir.
Etməməli olduğunuz şey, yaranan xətanı susdurmaq üçün verify=False qurmaqdır. Bu, proksi səhv konfiqurasiyasını yoxlanılmamış bağlantı ilə dəyişir və istisnanın aşkar etməli olduğu sertifikat problemini gizlədir.
Uğursuz qatı yoxlayın və geri qaytarma imkanını saxlayın
Üç nasazlıq jurnalda oxşar görünür və heç bir ortaqlığı yoxdur: təyinata çata bilməyən proksi ProxyError atır və ya 502 qaytarır, etimad problemi SSLError atır, tətbiq rəddi isə 401 və ya 403 qaytarır. Hansının olduğunu görmək üçün sorğunu Requests-dən kənarda təkrarlayın. Aşağıdakı əmrlər proksini çıxarır, sertifikat zəncirini sınayır və sonra çağırışı kitabxana vasitəsilə təkrarlayır.
curl -sv --noproxy '*' https://api.corp.example/status -o /dev/null
openssl s_client -connect api.corp.example:443 -servername api.corp.example </dev/null
python3 -c "import requests;r=requests.get('https://api.corp.example/status',timeout=10);print(r.status_code)"
Əgər curl çağırışı uğurlu olur və Python çağırışı uğursuz olursa, fərq hələ də mühitdir. Əgər hər ikisi TLS mərhələsində uğursuz olursa, proksi heç vaxt problem deyildi və problem sertifikat zənciridir. Əgər hər ikisi 401 qaytarırsa, sorğu tətbiqə çatıb və qalan iş autentifikasiyadır. Üçündən hansını müşahidə etdiyinizi qeyd etmək növbəti adama bir saat qazandırır.
Geri qaytarma hər iki istiqamətdə bir sətirdir: istisnanı silin və ya trust_env-ü geri çevirin. NO_PROXY dəyərini ona əlavə etməzdən əvvəl saxlayın və yalnız terminal tarixçənizdə yaşayan eksport əvəzinə sarğı skriptinə və ya unit səviyyəsində Environment= qeydinə üstünlük verin. Hər iki dəyişiklik proses mühitində görünür, buna görə yenidən başlatma adətən sizi köhnə davranışa qaytarır.
Dörd şeyi təsdiqləyərək bitirin: şəxsi URL üçün birləşdirilmiş parametrlər heç bir proksi göstərmir, sertifikat nəzərdə tutulan CA-ya qarşı doğrulanır, sorğu gözlədiyiniz statusu qaytarır və dəyişiklik təkrarlana bilən bir yerdə qeydə alınıb. İzahsız mühitlə yaşıl skript növbəti maşında yenidən pozulan düzəlişdir. Bu təlimatdakı əmrlər bilete yapışdıracağınız əmrlərdir.