Logo FinLensFinLens Docs

Cài đặt thư viện Python finlens và lấy khoá API

Cài finlens bằng pip trên Python 3.11+, tạo khoá API dạng flk_, đặt biến môi trường FINLENS_API_KEY và chạy truy vấn đầu tiên với client.eod.stock.ohlcv().

Trang này đi từ máy chưa có gì tới lúc bạn cầm trong tay một DataFrame giá cổ phiếu: cài gói, lấy khoá API, chạy truy vấn đầu tiên, và kiểm chứng rằng mình đã cài đúng bản.

Cài đặt

Kiểm tra phiên bản Python

Thư viện yêu cầu Python 3.11 trở lên.

python --version

Đây là ràng buộc kéo theo từ pandas 3.0 — dòng pandas này chỉ phát hành wheel cho Python 3.11 đến 3.14.

Cài từ PyPI

pip install finlens

Lệnh này kéo theo đúng ba phụ thuộc: pandas (từ 3.0), httpxpackaging. Nếu dùng môi trường ảo, nhớ kích hoạt trước khi cài.

Lấy khoá API

Đăng nhập finlens.vnCài đặt tài khoản → mục API Key → bấm Tạo API Key.

Khoá của bản 1.x có dạng flk_....

Đặt khoá vào biến môi trường

# Linux / macOS
export FINLENS_API_KEY="flk_..."
# Windows PowerShell
$env:FINLENS_API_KEY = "flk_..."

Đây là cách được khuyến nghị — nhờ nó mà mã nguồn của bạn không bao giờ chứa khoá.

Chạy truy vấn đầu tiên

import finlens

client = finlens.client()        # đọc FINLENS_API_KEY
df = client.eod.stock.ohlcv("HPG", start="2026-01-01", end="2026-01-05")
print(df)
  symbol       date   open   high    low  close      volume
0    HPG 2026-01-05  23.57  23.70  22.94  23.17  59427911.0

Giá tính bằng nghìn đồng: 23.17 nghĩa là 23.170 VND.

Khoá API chỉ hiện một lần

Sau khi tạo, khoá chỉ hiển thị đúng một lần. Sao chép và cất giữ ngay — mất thì phải tạo khoá mới. Máy chủ về sau chỉ trả lại 12 ký tự đầu của khoá (client.whoami()["key"]["prefix"]), không bao giờ trả lại khoá đầy đủ.

Ba cách đưa khoá vào client

Cấu hình được ghép từ nhiều tầng, ưu tiên từ cao xuống thấp: tham số truyền vàobiến môi trường FINLENS_*file finlens.toml → mặc định.

import finlens

# 1. Truyền thẳng — tiện khi thử nhanh, đừng commit
client = finlens.client(api_key="flk_...")

# 2. Biến môi trường FINLENS_API_KEY — khuyến nghị
client = finlens.client()

# 3. File cấu hình, khi bạn có nhiều môi trường
client = finlens.client(profile="staging")

File cấu hình được tìm ở ./finlens.toml trước, rồi tới thư mục cấu hình của người dùng (%APPDATA%\finlens\config.toml trên Windows, ~/.config/finlens/config.toml trên Linux và macOS):

[default]
api_key = "flk_..."

[profile.staging]
api_key = "flk_..."

Tên profile cũng đọc được từ biến môi trường FINLENS_PROFILE.

Thư viện không tự đọc file `.env`

Một thư viện tự nạp .env của bạn là một tác dụng phụ bất ngờ: nó đọc một file bạn không hề yêu cầu, và có thể ghi đè biến môi trường bạn đặt có chủ đích. Bản 1.x đã bỏ hẳn hành vi đó. Ai muốn nó thì tự gọi load_dotenv() trong ứng dụng của mình — một dòng, và là lựa chọn của họ.

Giữ khoá API an toàn

Đừng viết thẳng khoá vào mã nguồn rồi đẩy lên Git. Nếu buộc phải đọc khoá trong code, hãy đọc từ môi trường:

import os
import finlens

client = finlens.client(api_key=os.environ["FINLENS_API_KEY"])

Trong notebook dùng chung, finlens.client() không tham số là an toàn nhất: khoá không xuất hiện ở bất kỳ cell nào, nên nó cũng không nằm trong file .ipynb bạn gửi đi.

Nếu dùng file finlens.toml trong thư mục dự án, thêm nó vào .gitignore.

Kiểm tra cài đặt thành công

Bốn dòng dưới đây trả lời bốn câu hỏi khác nhau. Chạy hết chúng trước khi kết luận là "cài xong".

import finlens

finlens.__version__          # '1.1.1' — phải bắt đầu bằng số 1
client = finlens.client()    # khoá có đúng định dạng không (không chạm mạng)
client.status()              # service có sống không
client.whoami()              # khoá có thật sự dùng được không

client.whoami() là lời gọi đầu tiên thật sự đi ra mạng. Nó trả về gói dịch vụ, tình trạng khoá và hạn mức:

client.whoami()["account"]["tier"]        # 'pro'
client.limits()["requests_remaining"]     # 4783
client.limits()["max_symbols_per_request"]

Kiểm `finlens.__version__` chứ đừng tin lệnh cài

Trên Python 3.10 hoặc cũ hơn, pip install finlens không báo lỗi — nó lặng lẽ lùi về một bản 0.1.x cũ, vốn còn nhận Python 3.10. Bản đó có tên hàm khác, tên cột khác và đơn vị khác, nên mọi ví dụ trong bộ tài liệu này sẽ hỏng theo những cách khó đoán.

Nếu finlens.__version__ không bắt đầu bằng 1., hãy nâng Python lên 3.11+ rồi cài lại bằng pip install -U finlens.

client.status() không cần khoá hợp lệ — nó vẫn trả lời khi khoá sai hoặc đã hết hạn, nên đây là cách phân biệt "service đang có vấn đề" với "khoá của tôi có vấn đề".

Tạo client không chạm mạng

finlens.client() chỉ kiểm định dạng khoá tại chỗ; việc xác thực thật xảy ra ở lời gọi dữ liệu đầu tiên. Nhờ vậy đặt nó ở cell đầu notebook hay trong __init__ của một lớp không bao giờ hỏng vì một trục trặc mạng.

Muốn phát hiện khoá sai ngay lúc khởi động ứng dụng thì gọi connect() — nó chủ động chạy handshake:

client = finlens.client()
client.connect()             # ném lỗi ngay tại đây nếu khoá hỏng

Đóng client đúng cách

Client giữ một pool kết nối và một event loop chạy nền. Cả hai được đóng tự động lúc thoát interpreter, nên phần lớn script không phải làm gì. Khi muốn giải phóng sớm, dùng context manager:

import finlens

with finlens.client() as client:
    df = client.eod.stock.ohlcv(["HPG", "VCB"], start="2026-01-01")

# Đã đóng, không cần gọi client.close()

Bản bất đồng bộ bắt buộc dùng async with (hoặc await client.connect() trước lời gọi đầu tiên), vì engine phải được tạo trên chính event loop của bạn:

import finlens

async def main():
    async with finlens.AsyncClient() as client:
        df = await client.eod.stock.ohlcv("HPG")

Tuỳ chỉnh client

Mọi tham số đều bỏ trống được, và mỗi cái đều có biến môi trường tương ứng.

Tham sốBiến môi trườngÝ nghĩa
api_keyFINLENS_API_KEYKhoá API
timeoutFINLENS_TIMEOUTThời gian chờ tối đa của một request HTTP, tính bằng giây
deadlineFINLENS_DEADLINENgân sách thời gian cho cả lời gọi, kể cả các lần thử lại
max_concurrencyFINLENS_MAX_CONCURRENCYSố request song song tối đa
max_retriesFINLENS_MAX_RETRIESSố lần thử lại tối đa cho mỗi request
profileFINLENS_PROFILEProfile trong finlens.toml
ca_bundleFINLENS_CA_BUNDLEĐường dẫn tới CA bundle của tổ chức bạn

max_concurrency bị kẹp xuống theo giới hạn của gói dịch vụ sau lần handshake đầu tiên: sự thật của server thắng phỏng đoán của client.

deadline tồn tại vì một lý do rất cụ thể — không có nó, 50 mã × 3 lần thử × backoff có thể treo hàng chục phút trong một cell notebook.

Khi có gì đó không chạy

Triệu chứngNguyên nhân thường gặpCách xử lý
ConfigurationError: Thiếu API keyChưa đặt FINLENS_API_KEY, hoặc đã đặt nhưng chưa mở lại terminalTruyền finlens.client(api_key=...) để kiểm chứng nhanh
ConfigurationError: API key chứa khoảng trắngSao chép khoá từ email hoặc terminal bị ngắt dòngDán lại khoá, bỏ mọi khoảng trắng
InvalidApiKeyErrorKhoá sai hoặc đã bị thu hồiTạo khoá mới trong tài khoản
ApiKeyExpiredError / AccountExpiredErrorKhoá hoặc gói dịch vụ hết hạnKiểm client.whoami()["account"]["expires_at"]
TlsVerificationErrorMáy nằm sau proxy kiểm tra TLS hoặc phần mềm diệt virusTrỏ tới CA bundle của tổ chức: finlens.client(ca_bundle="/đường/dẫn/ca.pem") hoặc đặt FINLENS_CA_BUNDLE
AttributeErrorclient.eod.marketĐang làm theo tài liệu 0.1.xNamespace chỉ số nay tên là client.eod.index
KeyError: 'Date'Đang làm theo tài liệu 0.1.xTên cột nay viết thường: date

Không có tuỳ chọn tắt xác thực TLS, và đó là chủ ý: tắt nó để sửa một lỗi cấu hình là đổi một phút phiền phức lấy một lỗ hổng vĩnh viễn — trong khi chính khoá API của bạn đi qua đúng kết nối đó.

Danh sách đầy đủ các lớp ngoại lệ và mã lỗi FL_* nằm ở Xử lý lỗi.

Tiếp theo

Khi báo lỗi, gửi kèm kết quả của finlens.build_info() — phần lớn thư viện được biên dịch, nên số phiên bản một mình không đủ để dựng lại đúng bản build bạn đang chạy.

>>> finlens.build_info()
{'version': '1.1.1', 'commit': 'a1b2c3d', 'built_at': '...', 'cython': '3.2.9',
 'python': '3.12', 'platform': 'windows-amd64'}

Câu hỏi thường gặp

Cài đặt thư viện Python finlens bằng lệnh nào?

Cài từ PyPI bằng `pip install finlens`. Thư viện yêu cầu Python từ 3.11 trở lên, kiểm bằng `python --version` trước khi cài — ràng buộc này kéo theo từ pandas 3.0, dòng pandas chỉ phát hành wheel cho Python 3.11 đến 3.14. Lệnh cài chỉ thêm ba phụ thuộc: `pandas`, `httpx` và `packaging`. Nếu dùng môi trường ảo thì kích hoạt trước khi cài. Cài xong, kiểm `finlens.__version__` — nó phải bắt đầu bằng `1.`.

Khoá API của FinLens lấy ở đâu và có dạng như thế nào?

Đăng nhập finlens.vn, vào Cài đặt tài khoản, mở mục API Key rồi bấm Tạo API Key. Khoá của bản 1.x có tiền tố `flk_`. Khoá chỉ hiển thị đúng một lần sau khi tạo nên phải sao chép và cất giữ ngay; làm mất thì tạo khoá mới. Về sau máy chủ chỉ trả lại 12 ký tự đầu của khoá, đọc bằng `client.whoami()["key"]["prefix"]`, chứ không bao giờ trả lại khoá đầy đủ.

Nên lưu khoá API thế nào cho an toàn khi viết code Python?

Đừng viết thẳng khoá vào mã nguồn rồi đẩy lên Git. Với thư viện Python finlens, cách được khuyến nghị là đặt khoá vào biến môi trường `FINLENS_API_KEY` rồi gọi `finlens.client()` không tham số — khoá không xuất hiện ở cell nào nên cũng không nằm trong file `.ipynb` bạn gửi đi. Trên Linux và macOS dùng `export FINLENS_API_KEY="flk_..."`, trên Windows PowerShell dùng `$env:FINLENS_API_KEY = "flk_..."`. Nếu dùng file `finlens.toml` trong thư mục dự án thì thêm nó vào `.gitignore`.

Làm sao kiểm tra đã cài đúng bản và khoá API còn dùng được?

Chạy bốn dòng của thư viện Python finlens, mỗi dòng trả lời một câu hỏi khác nhau: `finlens.__version__` phải bắt đầu bằng `1.`; `finlens.client()` kiểm định dạng khoá tại chỗ mà không chạm mạng; `client.status()` cho biết dịch vụ có sống không và trả lời được cả khi khoá sai hoặc hết hạn; `client.whoami()` là lời gọi thật đầu tiên, trả về gói dịch vụ, tình trạng khoá và hạn mức. Hạn mức còn lại đọc bằng `client.limits()["requests_remaining"]`.

Vì sao pip lại cài về một bản finlens 0.1.x cũ?

Vì máy đang chạy Python 3.10 hoặc cũ hơn. Bản 1.x khai `requires-python >= 3.11`, nên trên Python cũ `pip install finlens` không báo lỗi mà lặng lẽ lùi về một bản 0.1.x — bản đó có tên hàm khác, tên cột khác và đơn vị khác, nên mọi ví dụ trong bộ tài liệu này sẽ hỏng theo những cách khó đoán. Kiểm bằng `finlens.__version__`; nếu nó không bắt đầu bằng `1.` thì nâng Python lên 3.11+ rồi chạy `pip install -U finlens`.

Cập nhật lần cuối

Nội dung trang