2013-06-12 24 views
7

Tôi đang phát triển một ứng dụng cho OS X. Ứng dụng này liên quan đến việc liên lạc với máy chủ thông qua các yêu cầu python, sử dụng kết nối an toàn.SSLError trong Yêu cầu khi đóng gói dưới dạng OS X .app

Tôi có thể chạy tệp python mà tôi dự định đóng gói và thành công với kết nối SSL. Tuy nhiên, khi tôi đóng gói tệp bằng py2app và cố gắng chạy nó, tôi nhận được lỗi sau:

Traceback (most recent call last): 
File "/Users/yossi/Documents/repos/drunken-octo-nemesis/dist/drunken-octo.app/Contents/Resources/__boot__.py", line 338, in <module> 
    _run() 
File "/Users/yossi/Documents/repos/drunken-octo-nemesis/dist/drunken-octo.app/Contents/Resources/__boot__.py", line 333, in _run 
    exec(compile(source, path, 'exec'), globals(), globals()) 
File "/Users/yossi/Documents/repos/drunken-octo-nemesis/dist/drunken-octo.app/Contents/Resources/media_test.py", line 16, in <module> 
    cmpbl.syncWithCloud() 
File "src/compare_book_lists.pyc", line 172, in syncWithCloud 
File "src/compare_book_lists.pyc", line 64, in checkMediaOnCloud 
File "src/get_cloud_book_list.pyc", line 26, in getCloudFulfilledBookList 
File "requests/api.pyc", line 55, in get 
File "requests/api.pyc", line 44, in request 
File "requests/sessions.pyc", line 354, in request 
File "requests/sessions.pyc", line 460, in send 
File "requests/adapters.pyc", line 250, in send 
requests.exceptions.SSLError: [Errno 185090050] _ssl.c:340: error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib 
2013-06-12 11:39:49.119 drunken-octo[1656:707] drunken-octo Error 

Tôi có thể đóng gói một phần đơn đăng ký của mình thành công. Sự cố bắt đầu khi tệp đích phụ thuộc, ở đâu đó trong chuỗi, trên Yêu cầu.

Tôi đang sử dụng zc.buildout để tổ chức nhập khẩu của mình. Vì vậy, tôi đang chạy trong một trình thông dịch python cục bộ được tạo bởi bản dựng, do đó, bất kỳ bản sửa lỗi, thật không may, sẽ dễ thực hiện hơn nếu chúng không liên quan đến việc sửa đổi hệ thống Python. Tuy nhiên, tất cả các đề xuất đều được chào đón và tôi sẽ cố gắng hết sức để sửa đổi chúng cho các chi tiết cụ thể của tôi.

Điều này chỉ xảy ra khi tôi chạy ứng dụng đóng gói. Bất kỳ ý tưởng?

Trả lời

6

Các easiests workaround là thêm một lựa chọn cho py2app đến tập tin setup.py của bạn:

setup(
    ... 
    options={ 
     'py2app':{ 
      'packages': [ 'requests' ] 
     } 
    } 
) 

này bao gồm toàn bộ gói vào gói ứng dụng, bao gồm các bó giấy chứng nhận.

Tôi đã gửi issue for this in my py2app tracker, phiên bản tương lai của py2app sẽ bao gồm logic để phát hiện việc sử dụng thư viện yêu cầu và sẽ tự động sao chép gói chứng chỉ.

+0

Xin chào Ronald, cách giải quyết này dường như không còn hoạt động. Có tin tức nào về bản cập nhật cho py2app không? Cảm ơn! –

3

Yêu cầu sử dụng một nhóm chứng chỉ để xác minh danh tính máy chủ. Gói này được lưu giữ (nó phải là) trong một tệp độc lập. Thông thường yêu cầu các tàu có gói riêng của nó, nhưng nếu được đóng gói thành một tệp duy nhất thì gói bị mất. Bạn có thể gửi một gói mới cùng với ứng dụng của mình hoặc yêu cầu sử dụng chứng chỉ trên toàn hệ thống. (Tôi không biết, nơi OS X giữ tập tin này, nhưng trên hộp linux của tôi nó /etc/ssl/certs/ca-certificates.crt)

Để xem, nơi yêu cầu mong muốn các tập tin bạn có thể làm điều này:

import requests 
print(requests.certs.where()) 

Để thay đổi vị trí, nơi yêu cầu tìm kiếm bó bạn có thể vượt qua verify -parameter với một giá trị chuỗi:

import requests 
requests.get("https://httpbin.org/", verify="path/to/your/bundle") 

Nếu bạn không muốn vượt qua các tham số mọi thời gian, tạo ra một phiên và cấu hình nó để sử dụng bó của bạn :

import requests 
s = requests.Session() 
s.verify = "path/to/your/bundle" 
s.get("https://httpbin.org") 
3

Câu trả lời được chấp nhận trước đó không có tác dụng đối với tôi - có thể cách các yêu cầu tác phẩm đã thay đổi.

Để giải quyết này tôi đã thay đổi tùy chọn setup.py tôi để bao gồm các gói certifi nơi tệp giấy chứng nhận pem sống:

OPTIONS = {'argv_emulation': True,'packages': ['certifi']} 

Sau đó thêm vào này để yêu cầu python gọi:

is_py2app = hasattr(sys, "frozen") 
pem_path = "lib/python2.7/certifi/cacert.pem" if is_py2app else None 

... 

requests.get(..., verify=pem_path) 

này có thể khác trên các phiên bản Python khác.

+0

Vâng, đây cũng là một bước quan trọng cho gói của tôi. Cảm ơn eAi – Jon

+0

FYI theo mặc định gói yêu cầu của tôi đã sử dụng gói 'certifi' cho' cacert.pem' thay vì gói 'certert'' của riêng nó, nhưng' certifi' nằm trong site-package.zip chứ không phải trong một thư mục mở. Một thay thế có thể là '' 'pem_path = "lib/python2.7/yêu cầu/CAcert.pem" nếu is_py2app khác Không ' '' sử dụng một đóng gói với yêu cầu (không cần certifi sẽ được bổ sung). Nhưng nó tạo ra sự khác biệt nhỏ mà tôi tưởng tượng. – Jon

+0

Hi @eAi Tôi xin lỗi nếu đây là một câu hỏi ngớ ngẩn. Nhưng 'sys' trong dòng' is_py2app = hasattr (sys, "frozen") 'là gì? –

0

Tôi đã gặp phải sự cố tương tự và phải phân phối ứng dụng của mình cho những người dùng có thể chưa cài đặt gói Python hoặc gói chứng chỉ trên máy Mac của họ. Dựa trên nguồn cảm hứng từ các câu trả lời ở đây, tôi đã đưa ra giải pháp sau.

Bước 1: Tải xuống gói OpenSSL từ https://www.openssl.org/source/. Tìm số /openssl-1.0.2n/certs/demo/ca-cert.pem và đặt nó trong cùng thư mục với chương trình Python của bạn (ví dụ: main.py).

Bước 2: Tạo setup.py như thường lệ, nhưng bao gồm ca-cert.pem trong danh sách DATA_FILES. Vì vậy, setup.py bạn nên tìm một cái gì đó như thế này:

from setuptools import setup 

APP = ['main.py'] 
DATA_FILES = ['ca-cert.pem'] 
OPTIONS = {'argv_emulation': False} 

setup(
    app=APP, 
    data_files=DATA_FILES, 
    options={'py2app': OPTIONS}, 
    setup_requires=['py2app'], 
) 

Bước 3: Sử dụng tham số verify có yêu cầu sẽ sử dụng file chứng chỉ mà bạn cung cấp.

import requests 
requests.get("https://httpbin.org/", verify="ca-cert.pem") 

Ngoài ra, bạn cũng có thể tạo phiên để bạn không phải chỉ định verify mỗi lần.

import requests 
s = requests.Session() 
s.verify = "ca-cert.pem" 
s.get("https://httpbin.org") 

Bước 4: Đóng gói ứng dụng bằng py2app như bình thường. Ứng dụng kết quả sẽ có thể chạy bình thường.

python setup.py py2app 
Các vấn đề liên quan