Skip to content

Instantly share code, notes, and snippets.

@xhc0re
Created January 26, 2024 22:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xhc0re/36bd9691d093be16d10e46520fc11bee to your computer and use it in GitHub Desktop.
Save xhc0re/36bd9691d093be16d10e46520fc11bee to your computer and use it in GitHub Desktop.
Python playground
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