Коли ми проєктуємо систему, що взаємодіє з кількома API, важливо враховувати:
- Безпека:
- Використання OAuth2 для аутентифікації та оновлення токенів.
- Обмеження прав доступу за допомогою ролей та сервісних акаунтів.
- Структура проєкту:
- Розділення на модулі для роботи з різними API.
- Конфігурація для зберігання ключів API, токенів та конфіденційних даних.
- Асинхронність:
- Використання
httpxдля виконання асинхронних запитів. - Оптимізація обробки даних для підвищення продуктивності.
- Використання
Ось як виглядатиме наша система:
- Google Sheets: зберігання та оновлення даних таблиць.
- Google Drive: завантаження та керування файлами.
- Google Maps: отримання геоданих про користувачів та місцезнаходження об'єктів.
Розділимо логіку на три модулі:
sheets_service.py: для роботи з Google Sheets API.drive_service.py: для взаємодії з Google Drive API.maps_service.py: для роботи з Google Maps API.
Налаштування проєкту
Спочатку переконайся, що в тебе встановлені необхідні бібліотеки. Це можна зробити за допомогою pip:
pip install fastapi uvicorn google-api-python-client google-auth httpx
Конфігурація проєкту
Створимо файл .env, де зберігатимемо конфіденційні дані:
GOOGLE_API_CLIENT_ID=<твій client_id>
GOOGLE_API_CLIENT_SECRET=<твій client_secret>
GOOGLE_SHEETS_ID=<ID твоєї таблиці>
GOOGLE_DRIVE_FOLDER_ID=<ID папки на Google Диску>
GOOGLE_MAPS_API_KEY=<твій API-ключ для Google Maps>
Додамо обробку .env в код за допомогою python-dotenv:
pip install python-dotenv
Тепер створимо файл config.py:
from dotenv import load_dotenv
import os
load_dotenv()
GOOGLE_CLIENT_ID = os.getenv("GOOGLE_API_CLIENT_ID")
GOOGLE_CLIENT_SECRET = os.getenv("GOOGLE_API_CLIENT_SECRET")
GOOGLE_SHEETS_ID = os.getenv("GOOGLE_SHEETS_ID")
GOOGLE_DRIVE_FOLDER_ID = os.getenv("GOOGLE_DRIVE_FOLDER_ID")
GOOGLE_MAPS_API_KEY = os.getenv("GOOGLE_MAPS_API_KEY")
Реалізація модулів
Створи файл sheets_service.py:
from googleapiclient.discovery import build
from google.oauth2.service_account import Credentials
from config import GOOGLE_SHEETS_ID
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
credentials = Credentials.from_service_account_file("service_account.json", scopes=SCOPES)
service = build('sheets', 'v4', credentials=credentials)
def read_data(range_name):
sheet = service.spreadsheets()
result = sheet.values().get(spreadsheetId=GOOGLE_SHEETS_ID, range=range_name).execute()
return result.get('values', [])
def write_data(range_name, values):
sheet = service.spreadsheets()
body = {
'values': values
}
result = sheet.values().update(spreadsheetId=GOOGLE_SHEETS_ID, range=range_name,
valueInputOption="RAW", body=body).execute()
return result
Робота з Google Drive API
Створи файл drive_service.py:
from googleapiclient.http import MediaFileUpload
from googleapiclient.discovery import build
from google.oauth2.service_account import Credentials
from config import GOOGLE_DRIVE_FOLDER_ID
SCOPES = ['https://www.googleapis.com/auth/drive']
credentials = Credentials.from_service_account_file("service_account.json", scopes=SCOPES)
service = build('drive', 'v3', credentials=credentials)
def upload_file(file_name, mime_type):
file_metadata = {
'name': file_name,
'parents': [GOOGLE_DRIVE_FOLDER_ID]
}
media = MediaFileUpload(file_name, mimetype=mime_type)
file = service.files().create(body=file_metadata, media_body=media, fields='id').execute()
return file.get('id')
Робота з Google Maps API
Створи файл maps_service.py:
import httpx
from config import GOOGLE_MAPS_API_KEY
async def get_coordinates(address):
url = f"https://maps.googleapis.com/maps/api/geocode/json"
params = {"address": address, "key": GOOGLE_MAPS_API_KEY}
async with httpx.AsyncClient() as client:
response = await client.get(url, params=params)
response.raise_for_status()
data = response.json()
return data['results'][0]['geometry']['location']
Інтеграція в FastAPI
Тепер створимо файл main.py:
from fastapi import FastAPI, HTTPException
from sheets_service import read_data, write_data
from drive_service import upload_file
from maps_service import get_coordinates
app = FastAPI()
@app.get("/sheets/{range_name}")
async def get_sheet_data(range_name: str):
try:
data = read_data(range_name)
return {"data": data}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/sheets/{range_name}")
async def add_sheet_data(range_name: str, values: list):
try:
result = write_data(range_name, values)
return {"updated_cells": result.get("updatedCells")}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.post("/drive/upload")
async def upload(file_name: str, mime_type: str):
try:
file_id = upload_file(file_name, mime_type)
return {"file_id": file_id}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
@app.get("/maps/")
async def get_location(address: str):
try:
coords = await get_coordinates(address)
return {"coordinates": coords}
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
Тестування застосунку
Тепер ти можеш запустити застосунок, використовуючи Uvicorn:
uvicorn main:app --reload
Приклади запитів:
- Отримання даних з таблиці Google Sheets:
GET /sheets/Sheet1!A1:D10 - Завантаження файлу на Google Drive:
POST /drive/upload?file_name=example.pdf&mime_type=application/pdf - Отримання координат за адресою:
GET /maps/?address=New+York
Цей проєкт — відмінний спосіб показати свої навички на співбесіді або реально використати інтеграцію з Google API у реальних застосунках. Від автоматизації документації до керування картами та геоданими — можливості безмежні! Не забудь враховувати ліміти запитів, обробляти помилки і стежити за оновленням токенів для використання OAuth2.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ