Most modern apps integrate with external services through APIs.
Większość nowoczesnych aplikacji integruje się z zewnętrznymi serwisami przez API.
Documentation:
Video:
Corey Schafer — Requests Library (0:00–30:00)
uv add requestsGET requests fetch data from a server.
Żądania GET pobierają dane z serwera.
Let's use a currency exchange rate API - useful for real apps like expense trackers or shopping carts.
Użyjmy API kursów walut - przydatne w prawdziwych aplikacjach jak trackery wydatków czy koszyki zakupowe.
Create api_demo.py:
Utwórz api_demo.py:
import requests
# Get latest exchange rates / Pobierz najnowsze kursy walut
response = requests.get("https://api.frankfurter.dev/latest?from=USD")
print(f"Status: {response.status_code}")
if response.status_code == 200:
data = response.json()
print(f"Base currency: {data['base']}")
print(f"Date: {data['date']}")
print(f"USD to EUR: {data['rates']['EUR']:.4f}")
print(f"USD to PLN: {data['rates']['PLN']:.4f}")Run:
Uruchom:
uv run python api_demo.py| Code | Meaning | Znaczenie |
|---|---|---|
| 200 | OK | Sukces |
| 404 | Not Found | Nie znaleziono |
| 500 | Server Error | Błąd serwera |
import requests
# Convert 100 USD to specific currencies / Konwertuj 100 USD na konkretne waluty
params = {
"from": "USD",
"to": "EUR,PLN,GBP",
"amount": 100
}
response = requests.get("https://api.frankfurter.dev/latest", params=params)
if response.status_code == 200:
data = response.json()
print(f"Converting {data['amount']} {data['base']}:")
for currency, rate in data['rates'].items():
print(f" {currency}: {rate:.2f}")POST sends data to create resources.
POST wysyła dane aby utworzyć zasoby.
import requests
new_post = {
"title": "My Post",
"body": "Content here",
"userId": 1
}
response = requests.post(
"https://jsonplaceholder.typicode.com/posts",
json=new_post
)
if response.status_code == 201:
created = response.json()
print(f"Created post ID: {created['id']}")Always handle network errors.
Zawsze obsługuj błędy sieciowe.
import requests
import logging
logger = logging.getLogger(__name__)
def get_exchange_rate(from_currency: str, to_currency: str) -> float | None:
try:
url = f"https://api.frankfurter.dev/latest?from={from_currency}&to={to_currency}"
response = requests.get(url, timeout=5)
response.raise_for_status()
data = response.json()
return data['rates'][to_currency]
except requests.exceptions.HTTPError:
logger.error(f"HTTP error {response.status_code}")
return None
except requests.exceptions.ConnectionError:
logger.error("Could not connect to exchange rate API")
return None
except requests.exceptions.Timeout:
logger.warning("Request timeout")
return None
except KeyError:
logger.error(f"Invalid currency: {from_currency} or {to_currency}")
return None
except Exception:
logger.exception("Unexpected error getting exchange rate")
return None
rate = get_exchange_rate("USD", "EUR")
if rate:
print(f"1 USD = {rate:.4f} EUR")This is how I wrap APIs in my projects.
Tak opakowuję API w moich projektach.
import requests
import logging
from datetime import date
logger = logging.getLogger(__name__)
class CurrencyConverter:
BASE_URL = "https://api.frankfurter.dev"
def __init__(self, timeout: int = 5):
self.timeout = timeout
def convert(self, amount: float, from_currency: str, to_currency: str) -> float | None:
"""Convert amount from one currency to another"""
try:
response = requests.get(
f"{self.BASE_URL}/latest",
params={"from": from_currency, "to": to_currency, "amount": amount},
timeout=self.timeout
)
response.raise_for_status()
data = response.json()
return data['rates'][to_currency]
except Exception:
logger.exception(f"Failed to convert {from_currency} to {to_currency}")
return None
def get_historical_rate(self, currency_from: str, currency_to: str,
date_str: str) -> float | None:
"""Get historical exchange rate for specific date"""
try:
response = requests.get(
f"{self.BASE_URL}/{date_str}",
params={"from": currency_from, "to": currency_to},
timeout=self.timeout
)
response.raise_for_status()
data = response.json()
return data['rates'][currency_to]
except Exception:
logger.exception(f"Failed to get historical rate for {date_str}")
return None
# Usage / Użycie
logging.basicConfig(level=logging.INFO)
converter = CurrencyConverter()
# Convert 100 USD to EUR / Konwertuj 100 USD na EUR
result = converter.convert(100, "USD", "EUR")
if result:
print(f"100 USD = {result:.2f} EUR")
# Get rate from last year / Pobierz kurs z zeszłego roku
rate = converter.get_historical_rate("USD", "PLN", "2023-01-01")
if rate:
print(f"USD/PLN on 2023-01-01: {rate:.4f}")Always set timeouts to avoid hanging.
Zawsze ustawiaj limity czasu aby uniknąć zawieszenia.
# Good - with timeout / Dobrze - z limitem
response = requests.get(url, timeout=5)
# Bad - can hang forever / Źle - może zawiesić się na zawsze
# response = requests.get(url)After this section you can:
Po tej sekcji potrafisz:
-
make GET requests to fetch data
wykonywać żądania GET aby pobierać dane
-
send POST requests to create resources
wysyłać żądania POST aby tworzyć zasoby
-
pass URL parameters
przekazywać parametry URL
-
handle HTTP errors and network issues
obsługiwać błędy HTTP i problemy sieciowe
-
set timeouts properly
ustawiać limity czasu poprawnie
-
build API wrapper classes
budować klasy wrapper dla API