/webguesser.py Secret
Created
January 26, 2024 22:13
Python playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from flask import Flask, request, jsonify | |
from flask_sqlalchemy import SQLAlchemy | |
from datetime import datetime, timedelta | |
from functools import wraps | |
import secrets, random, os, logging | |
from logging.handlers import RotatingFileHandler | |
from flasgger import Swagger | |
from flask_apscheduler import APScheduler | |
app = Flask(__name__) | |
app.config['SECRET_KEY'] = 'YY3_5BdticAM6E1k_3vYpg' | |
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' | |
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False | |
db = SQLAlchemy(app) | |
class Config: | |
SCHEDULER_API_ENABLED = True | |
app.config.from_object(Config()) | |
scheduler = APScheduler() | |
scheduler.init_app(app) | |
scheduler.start() | |
def deactivate_expired_api_keys(): | |
with app.app_context(): | |
now = datetime.now() | |
expired_keys = ApiKey.query.filter(ApiKey.expires_at < now, ApiKey.active == True).all() | |
for key in expired_keys: | |
key.active = False | |
db.session.commit() | |
scheduler.add_job(id='Deactivate Expired Keys', func=deactivate_expired_api_keys, trigger='interval', minutes=15) | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
handler = RotatingFileHandler('moja_aplikacja.log', maxBytes=10000, backupCount=3) | |
logger.addHandler(handler) | |
class Game(db.Model): | |
id = db.Column(db.Integer, primary_key = True) | |
number_to_guess = db.Column(db.Integer) | |
def __init__(self, number_to_guess): | |
self.number_to_guess = number_to_guess | |
class ApiKey(db.Model): | |
id = db.Column(db.Integer, primary_key=True) | |
key = db.Column(db.String(80), unique=True, nullable=False) | |
user_name = db.Column(db.String(100)) | |
expires_at = db.Column(db.DateTime) | |
active = db.Column(db.Boolean, default=True) | |
def __init__(self, key, user_name, expires_at=None, active=True): | |
self.key = key | |
self.user_name = user_name | |
self.expires_at = datetime.now() + timedelta(minutes=15) | |
self.active = active | |
def require_api_key(f): | |
@wraps(f) | |
def decorated_function(*args, **kwargs): | |
api_key = request.headers.get('API-Key') | |
api_key_record = ApiKey.query.filter_by(key=api_key).first() | |
if not api_key or not api_key_record or not api_key_record.active or api_key_record.expires_at < datetime.now(): | |
logger.warning(f"Błędny lub wygasły klucz API: {api_key}") | |
return jsonify({'message': 'Brak ważnego klucza API lub klucz wygasł'}), 401 | |
return f(*args, **kwargs) | |
return decorated_function | |
@app.route('/generate-api-key', methods=['POST']) | |
def generate_api_key(): | |
""" | |
Generuje nowy klucz API | |
--- | |
tags: | |
- API Key Management | |
responses: | |
200: | |
description: Wygenerowany klucz API | |
schema: | |
id: api_key | |
properties: | |
api_key: | |
type: string | |
description: Wygenerowany klucz API | |
""" | |
new_key = secrets.token_urlsafe(16) | |
expires_at = datetime.now() + timedelta(minutes=15) | |
logger.info(f"Generowanie nowego klucza API dla użytkownika: NazwaUzytkownika") | |
api_key = ApiKey(key=new_key, user_name="NazwaUzytkownika", expires_at=expires_at) | |
db.session.add(api_key) | |
db.session.commit() | |
return jsonify({'api_key': new_key}) | |
@app.route('/guess', methods=['POST']) | |
@require_api_key | |
def guess_number(): | |
""" | |
Zgaduje liczbę | |
--- | |
tags: | |
- Game | |
consumes: | |
- application/json | |
produces: | |
- application/json | |
parameters: | |
- in: body | |
name: body | |
description: Zgadywana liczba | |
required: true | |
schema: | |
type: object | |
required: | |
- guess | |
properties: | |
guess: | |
type: integer | |
format: int32 | |
example: 25 | |
responses: | |
200: | |
description: Wynik zgadywania | |
schema: | |
type: object | |
properties: | |
message: | |
type: string | |
success: | |
type: boolean | |
""" | |
game = Game.query.first() | |
if not game or request.json.get('new game', False): | |
if game: | |
db.session.delete(game) | |
game = Game(random.randint(1,100)) | |
try: | |
db.session.add(game) | |
db.session.commit() | |
except Exception as e: | |
logger.error(f"Błąd przy zapisywaniu do bazy danych: {e}") | |
guess = request.json.get('guess') | |
if not isinstance(guess, int): | |
return jsonify({'message': 'Nieprawidłowe dane. Proszę podać liczbę.'}), 400 | |
if guess == game.number_to_guess: | |
try: | |
db.session.delete(game) | |
db.session.commit() | |
except Exception as e: | |
logger.error(f"Błąd przy usuwaniu z bazy danych: {e}") | |
return jsonify({'message': 'Gratulacje, zgadłeś!', 'success': True}) | |
elif guess < game.number_to_guess: | |
return jsonify({'message': 'Za mało.', 'success': False}) | |
else: | |
return jsonify({'message': 'Za dużo.', 'success': False}) | |
Swagger(app) | |
if __name__ == '__main__': | |
with app.app_context(): | |
db.create_all() | |
app.run(debug=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment