Hướng dẫn python config file for passwords - tập tin cấu hình python cho mật khẩu

Tôi đã giải quyết chính xác cùng một câu hỏi và thực sự kết thúc với cùng một giải pháp như Kecer đề xuất. Vì tôi cần sử dụng nó trong hàng tá tập lệnh, tôi đã tạo thư viện riêng. Hãy để tôi chia sẻ giải pháp này với bạn.kecer suggested. Since I need to use it in dozens of scripts, I've created own library. Let me share this solution with you.

Credlib.py - Thư viện phổ quát để xử lý thông tin đăng nhập -- universal library to handle credentials

class credential:
    def __init__(self, hostname, username, password):
        self.hostname = hostname
        self.username = username
        self.password = password

mycredentials.py - tệp địa phương của tôi để lưu trữ tất cả thông tin đăng nhập -- my local file to store all credentials

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")

MySystemLib.py - Đây là một thư viện chung để truy cập hệ thống của tôi (cả hệ thống thông tin mới và di sản đều được hỗ trợ) -- this is a general library to access my system (both new credential system and legacy is supported)

from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call

main.py - tập lệnh chính kết hợp thông tin đăng nhập và hệ thống libs -- main script that combines credentials and system libs

from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)

Xin lưu ý rằng tên máy chủ/tên người dùng/mật khẩu Legacy vẫn hoạt động để nó không ảnh hưởng đến các tập lệnh cũ:

mysystemlib.system_login("srv02", "user", "pass")

Điều này có rất nhiều lợi ích:

  • Cùng một hệ thống thông tin xác thực trên tất cả các tập lệnh Python của chúng tôi
  • Các tệp có mật khẩu được phân tách (các tệp có thể có các quyền nghiêm ngặt hơn)
  • Các tệp không được lưu trữ trong kho Git của chúng tôi (được loại trừ qua
    from credlib import credential
    
    def system_login(*args): # this is new function definition
    #def system_login(hostname, username, password): # this was previous function definition
    
        if len(args) == 1 and isinstance(args[0], credential):
            hostname = args[0].hostname
            username = args[0].username
            password = args[0].password
        elif len(args) == 3:
            hostname = args[0]
            username = args[1]
            password = args[2]
        else:
            raise ValueError('Invalid arguments')
    
        do_login(hostname, username, password) # this is original system login call
    
    2) để có thể chia sẻ các tập lệnh/lib Python của chúng tôi với những người khác mà không cần hiển thị thông tin đăng nhập (mọi người xác định thông tin đăng nhập của họ trong các tệp cục bộ của họ)
  • Nếu một mật khẩu cần được thay đổi, chúng tôi chỉ làm điều đó ở một nơi duy nhất

Hướng dẫn python config file for passwords - tập tin cấu hình python cho mật khẩu
Hình ảnh từ Wikimedia Commons

11 tháng 1 năm 2022

Mục lục

  • Tệp cấu hình Python
  • Biến môi trường
  • Python dotenv
  • Ký hiệu đối tượng JavaScript (JSON)
  • Tuy nhiên, một ngôn ngữ đánh dấu khác (YAML)
  • Sử dụng trình phân tích cú pháp cấu hình
  • Phân tích các tùy chọn dòng lệnh
  • Sự kết luận
  • Tài nguyên

Khi viết các chương trình, thường có một tập hợp lớn các cấu hình và thông tin đăng nhập không nên được mã hóa khó khăn trong chương trình. Điều này cũng làm cho việc tùy chỉnh chương trình dễ dàng hơn và áp dụng chung hơn nhiều. Có nhiều cách khác nhau để xử lý cấu hình và thông tin đăng nhập và bạn sẽ thấy ở đây một vài cách phổ biến và phổ biến để làm điều đó với Python.

Một lưu ý quan trọng ngay từ đầu: khi sử dụng kiểm soát phiên bản luôn đảm bảo không cam kết thông tin đăng nhập và cấu hình vào kho lưu trữ vì điều này có thể trở thành một vấn đề bảo mật nghiêm trọng. Bạn có thể thêm chúng vào .gitignore để tránh đẩy các tệp đó vào kiểm soát phiên bản. Đôi khi rất hữu ích để có cấu hình chung trong kiểm soát phiên bản, nhưng điều đó phụ thuộc vào trường hợp sử dụng của bạn. When using version control always make sure to not commit credentials and configuration into the repository as this could become a serious security issue. You can add those to .gitignore to avoid pushing those files to version control. Sometimes is useful to have general configuration also in version control, but that depends on your use case.

Tệp cấu hình Python

Cách đầu tiên và có lẽ thẳng nhất là có tệp

from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call
3 ở đâu đó trong thư mục dự án mà bạn thêm vào tệp
from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call
2 của mình. Một mẫu tương tự có thể được tìm thấy trong bình, nơi bạn cũng có thể cấu trúc cấu hình dựa trên các bối cảnh khác nhau như phát triển, sản xuất và thử nghiệm.
from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call
3 sẽ trông giống như:

host = 'localhost',
port = 8080,
username = 'user'
password = 'password'

Bạn chỉ cần nhập nó và sử dụng nó như thế này:

import config

host = config.host
port = config.port
username = config.username
password = config.password

Biến môi trường

Bạn có thể truy cập các biến môi trường với OS.Envir:

import os

os.environ['SHELL']

Điều này sẽ ném

from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call
6 nếu biến không tồn tại. Bạn có thể kiểm tra xem biến có tồn tại với
from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call
7 không. Đôi khi nó thanh lịch hơn để nhận được
from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call
8 hoặc giá trị mặc định thay vì gặp lỗi khi không tồn tại một biến. Điều này có thể được thực hiện như thế này:

# return None if VAR does not exists
os.environ.get('VAR')

# return "default" if VAR does not exists
os.environ.get('VAR', "default")  

Bạn có thể kết hợp điều này với cách trước để có

from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call
3 với các nội dung sau:

import os

host = os.environ.get('APP_HOST', 'localhost')
port = os.environ.get('APP_PORT', 8080)
username = os.environ.get('APP_USERNAME')
password = os.environ.get('APP_PASSWORD')

Python dotenv

Thông thường, bạn muốn có các biến môi trường trong một tệp

from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
0 chuyên dụng bên ngoài điều khiển phiên bản. Một cách là tải tệp trước đó với:

Điều này đôi khi dễ bị lỗi hoặc không thể tùy thuộc vào thiết lập, do đó, đôi khi tốt hơn là tải tệp động với Python-DOTENV. Bạn có thể cài đặt gói với:

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
0

Tải tệp

from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
0 trong chương trình của bạn với:

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
1

Nếu tệp môi trường của bạn được đặt ở một nơi khác, bạn có thể tải nó với:

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
2

Bây giờ, bạn có thể sử dụng tệp môi trường như bạn đã thấy trước đây.

Ký hiệu đối tượng JavaScript (JSON)

JSON là một định dạng tệp tiện dụng khác để lưu trữ cấu hình của bạn vì nó có hỗ trợ gốc. Nếu bạn đang làm việc với Frontend Code, bạn đã quen thuộc với tính hữu dụng và phổ biến của nó.

Bạn có thể chuẩn bị cấu hình của mình dưới dạng JSON (ký hiệu đối tượng JavaScript) trong một

from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
2 với cấu hình ví dụ sau:

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
3

Bạn có thể tải cấu hình này sau đó với gói

from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
3 tích hợp:

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
4

Điều này trả về dữ liệu dưới dạng từ điển và danh sách mà bạn có thể truy cập theo cách bạn đã quen (

from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
4 hoặc
from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
5).

Tuy nhiên, một ngôn ngữ đánh dấu khác (YAML)

Một cách phổ biến khác để lưu trữ cấu hình và thông tin đăng nhập là định dạng YAML nổi tiếng (ở). Nó đơn giản hơn nhiều để sử dụng nhưng có một số kỳ quặc nhỏ khi sử dụng định dạng phức tạp hơn. Đây là cấu hình trước đây dưới dạng tệp yaml:

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
5

Có nhiều gói khác nhau mà bạn có thể sử dụng. Phổ biến nhất là pyyaml. Bạn có thể cài đặt nó với:

Để tải cấu hình, bạn có thể nhập:

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
6

from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
6 có thể được sử dụng như trước đây với ví dụ JSON.

Lưu ý rằng bạn cần thêm

from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
7 trong
from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
8 vì lỗ hổng. Đọc thêm về nó ở đây. Một giải pháp thay thế phổ biến khác cho
from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)
9 là Omegaconf, bao gồm nhiều trình phân tích cú pháp hữu ích khác cho các loại tệp khác nhau.

Sử dụng trình phân tích cú pháp cấu hình

Thư viện tiêu chuẩn Python bao gồm mô -đun ConfigParser có thể hoạt động với các tệp cấu hình tương tự như các tệp Microsoft Windows Ini. Bạn có thể chuẩn bị cấu hình trong

mysystemlib.system_login("srv02", "user", "pass")
0 với các nội dung sau:

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
7

Cấu hình được phân tách thành các phần như

mysystemlib.system_login("srv02", "user", "pass")
1 và trong các phần đó, cấu hình được lưu trữ dưới dạng các cặp giá trị khóa như
mysystemlib.system_login("srv02", "user", "pass")
2.

Bạn có thể tải và sử dụng cấu hình trước như sau:

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
8

Như bạn có thể thấy, để truy cập các giá trị bạn phải nhập

mysystemlib.system_login("srv02", "user", "pass")
3. Để có được tất cả các phần làm danh sách, bạn có thể nhập
mysystemlib.system_login("srv02", "user", "pass")
4. Để biết thêm thông tin, hãy xem tài liệu.

Phân tích các tùy chọn dòng lệnh

Cũng có thể nhận được thông tin đăng nhập và cấu hình thông qua các đối số bằng cách sử dụng mô-đun Argparse tích hợp.

Bạn có thể khởi tạo trình phân tích cú pháp đối số với:

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")
9

Bây giờ, bạn có thể phân tích các đối số với:

from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call
0

Nếu bạn lưu chương trình này trong

mysystemlib.system_login("srv02", "user", "pass")
5 và nhập
mysystemlib.system_login("srv02", "user", "pass")
6, bạn sẽ nhận được mô tả trợ giúp sau:

from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call
1

Một giải pháp khác cho

mysystemlib.system_login("srv02", "user", "pass")
7 là Typer giúp một số phân tích cú pháp dễ dàng hơn đối với các công cụ CLI phức tạp.

Sự kết luận

Ở đây bạn đã thấy một vài cách phổ biến và phổ biến để tải cấu hình và thông tin đăng nhập trong Python, nhưng có nhiều cách nữa nếu chúng không đủ cho USECase của bạn. Bạn luôn có thể dùng đến XML nếu bạn thực sự mong muốn. Nếu bạn bỏ lỡ một số cách mà bạn đặc biệt thấy hữu ích, hãy thêm nó vào các bình luận dưới đây.

Tài nguyên

  • 2014 - Các tệp cấu hình trong Python
  • Cách đọc và đặt các biến môi trường và vỏ trên Linux VPS
  • Github - Theskumar/Python -Dotenv
  • Github - Omry/Omegaconf
  • Github - Tiangolo/Typer