app.py 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import struct
  2. import asyncio
  3. from typing import Annotated
  4. import redis.asyncio as aioredis
  5. from fastapi import FastAPI, Path
  6. from fastapi.responses import Response
  7. from config import Config
  8. config = Config('config.hjson')
  9. redis = None
  10. app = FastAPI()
  11. @app.get(
  12. '/counter/{name}',
  13. responses = {
  14. 200: {
  15. 'content': {'image/png': {}}
  16. }
  17. },
  18. response_class=Response
  19. )
  20. async def get_counter(
  21. name: Annotated[
  22. str,
  23. Path(
  24. min_length=1,
  25. max_length=50,
  26. pattern=r'^[a-zA-Z0-9А-Яа-я\-\.,_@#:]+$'
  27. )
  28. ]
  29. ):
  30. if await redis.exists(name):
  31. number = await redis.get(name)
  32. number = int(number) + 1
  33. else:
  34. number = 1
  35. await redis.set(name, str(number))
  36. proc = await asyncio.create_subprocess_exec(
  37. config.CounterPath,
  38. stdin=asyncio.subprocess.PIPE,
  39. stdout=asyncio.subprocess.PIPE
  40. )
  41. stdout, _ = await proc.communicate(
  42. input=struct.pack('L', number)
  43. )
  44. return Response(
  45. content=stdout,
  46. media_type='image/png'
  47. )
  48. @app.on_event('startup')
  49. async def startup_event():
  50. global redis
  51. redis = await aioredis.from_url(
  52. config.RedisURL
  53. )
  54. @app.on_event('shutdown')
  55. async def shutdown_event():
  56. if redis is not None:
  57. await redis.close()