JavaRush /Курси /Модуль 4: FastAPI /Повна реалізація системи взаємодії з Google API

Повна реалізація системи взаємодії з Google API

Модуль 4: FastAPI
Рівень 17 , Лекція 9
Відкрита

Коли ми проєктуємо систему, що взаємодіє з кількома API, важливо враховувати:

  1. Безпека:
    • Використання OAuth2 для аутентифікації та оновлення токенів.
    • Обмеження прав доступу за допомогою ролей та сервісних акаунтів.
  2. Структура проєкту:
    • Розділення на модулі для роботи з різними API.
    • Конфігурація для зберігання ключів API, токенів та конфіденційних даних.
  3. Асинхронність:
    • Використання 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

Приклади запитів:

  1. Отримання даних з таблиці Google Sheets:
    GET /sheets/Sheet1!A1:D10
    
  2. Завантаження файлу на Google Drive:
    POST /drive/upload?file_name=example.pdf&mime_type=application/pdf
    
  3. Отримання координат за адресою:
    GET /maps/?address=New+York
    

Цей проєкт — відмінний спосіб показати свої навички на співбесіді або реально використати інтеграцію з Google API у реальних застосунках. Від автоматизації документації до керування картами та геоданими — можливості безмежні! Не забудь враховувати ліміти запитів, обробляти помилки і стежити за оновленням токенів для використання OAuth2.

3
Опитування
Асинхронна обробка запитів до Google API з FastAPI, рівень 17, лекція 9
Недоступний
Асинхронна обробка запитів до Google API з FastAPI
Асинхронна обробка запитів до Google API з FastAPI
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ