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.

1
Задача
Модуль 4: FastAPI, 17 уровень, 9 лекция
Недоступна
Использование Google Sheets API для чтения данных
Использование Google Sheets API для чтения данных
1
Задача
Модуль 4: FastAPI, 17 уровень, 9 лекция
Недоступна
Загрузка файла на Google Drive через FastAPI
Загрузка файла на Google Drive через FastAPI
3
Опрос
Асинхронная обработка запросов к Google API с FastAPI, 17 уровень, 9 лекция
Недоступен
Асинхронная обработка запросов к Google API с FastAPI
Асинхронная обработка запросов к Google API с FastAPI
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ