mikhailemv

Untitled

Jul 29th, 2023
1,344
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.53 KB | None | 0 0
  1. # crud.py
  2.  
  3. from datetime import datetime
  4.  
  5. from sqlalchemy.orm import Session
  6.  
  7. from . import models, schemas
  8.  
  9.  
  10. def get_price(db: Session, price_id: int):
  11.     return db.query(models.Price).filter(models.Price.id == price_id).first()
  12.  
  13.  
  14. def get_price_by_name(db: Session, name: str):
  15.     return db.query(models.Price).filter(models.Price.name == name).first()
  16.  
  17.  
  18. def update_price(db: Session, item: schemas.PriceCreate, price_id: int):
  19.     db_item = get_price(db, price_id=price_id)
  20.     db_item.name = item.name
  21.     db_item.price = item.price
  22.     db.add(db_item)
  23.     db.commit()
  24.     db.refresh(db_item)
  25.     return db_item
  26.  
  27.  
  28. def delete_price(db: Session, price_id: int):
  29.     db_item = get_price(db, price_id=price_id)
  30.     db.delete(db_item)
  31.     db.commit()
  32.     db.refresh(db_item)
  33.     return db_item
  34.  
  35.  
  36. def get_prices(db: Session, skip: int = 0, limit: int = 100):
  37.     return db.query(models.Price).offset(skip).limit(limit).all()
  38.  
  39.  
  40. def create_price(db: Session, item: schemas.PriceCreate):
  41.     db_price = models.Price(
  42.         name=item.name,
  43.         price=item.price,
  44.         datetime=datetime.now()
  45.     )
  46.     db.add(db_price)
  47.     db.commit()
  48.     db.refresh(db_price)
  49.     return db_price
  50.  
  51.  
  52. # database.py
  53.  
  54. from sqlalchemy import create_engine
  55. from sqlalchemy.ext.declarative import declarative_base
  56. from sqlalchemy.orm import sessionmaker
  57.  
  58. SQLALCHEMY_DATABASE_URL = "sqlite:///./db_price.sqlite"
  59.  
  60. engine = create_engine(
  61.     SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
  62. )
  63. SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
  64.  
  65. Base = declarative_base()
  66.  
  67.  
  68. # main.py
  69.  
  70. import asyncio
  71. from typing import List
  72.  
  73. from fastapi import Depends, FastAPI, HTTPException
  74. from sqlalchemy.orm import Session
  75.  
  76. from . import crud, models, schemas
  77. from .database import SessionLocal, engine
  78.  
  79. from rocketry import Rocketry
  80.  
  81. from app.db.session import db
  82.  
  83. from .price_parser import start_parser
  84.  
  85.  
  86. app_rocketry = Rocketry(execution="async")
  87.  
  88.  
  89. @app_rocketry.task('every 15 seconds')
  90. async def do_things():
  91.     print('Parser is started')
  92.  
  93.     name, price = start_parser()
  94.  
  95.     import requests
  96.  
  97.     def blocking_task():
  98.         print('Test')
  99.  
  100.         print(name, price)
  101.  
  102.         headers = {
  103.             'accept': 'application/json',
  104.             'Content-Type': 'application/json',
  105.         }
  106.  
  107.         json_data = {
  108.             'name': name,
  109.             'price': price,
  110.         }
  111.  
  112.         response = requests.post(
  113.             'http://127.0.0.1:8000/prices/create', headers=headers, json=json_data
  114.         )
  115.  
  116.         print(response, json_data)
  117.  
  118.     loop = asyncio.get_running_loop()
  119.     loop.run_in_executor(None, blocking_task)
  120.  
  121.  
  122. models.Base.metadata.create_all(bind=engine)
  123.  
  124. app = FastAPI()
  125.  
  126.  
  127. def get_db():
  128.     db = SessionLocal()
  129.     try:
  130.         yield db
  131.     finally:
  132.         db.close()
  133.  
  134.  
  135. @app.on_event("startup")
  136. async def startup_event():
  137.  
  138.     @app.on_event("startup")
  139.     async def startup():
  140.         await db.connect()
  141.  
  142.     @app.on_event("shutdown")
  143.     async def startup():
  144.         await db.disconnect()
  145.        
  146.     asyncio.create_task(app_rocketry.serve())
  147.  
  148.  
  149. @app.get("/prices", response_model=List[schemas.Price])
  150. def read_prices(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
  151.     prices = crud.get_prices(db, skip=skip, limit=limit)
  152.     return prices
  153.  
  154.  
  155. @app.get("/prices/{price_id}", response_model=schemas.Price)
  156. def read_price(price_id: int, db: Session = Depends(get_db)):
  157.     db_price = crud.get_price(db, price_id=price_id)
  158.     if db_price is None:
  159.         raise HTTPException(status_code=404, detail="This record is missing")
  160.     return db_price
  161.  
  162.  
  163. @app.post("/prices/create", response_model=schemas.Price)
  164. def create_price(item: schemas.PriceCreate, db: Session = Depends(get_db)):
  165.     db_price = crud.get_price_by_name(db, name=item.name)
  166.     if db_price and db_price.price == item.price:
  167.         raise HTTPException(status_code=400, detail="The table contains this name")
  168.     return crud.create_price(db=db, item=item)
  169.  
  170.  
  171. @app.put("/prices/{price_id}", response_model=schemas.Price)
  172. def update_price(price_id: int, item: schemas.PriceCreate, db: Session = Depends(get_db)):
  173.     db_price = crud.get_price(db, price_id=price_id)
  174.     if not db_price:
  175.         raise HTTPException(status_code=404, detail="This record is missing")
  176.     return crud.update_price(db=db, item=item, price_id=price_id)
  177.  
  178.  
  179. @app.delete("/prices/{price_id}", response_model=dict)
  180. def delete_price(price_id: int, db: Session = Depends(get_db)):
  181.     db_price = crud.get_price(db, price_id=price_id)
  182.     if not db_price:
  183.         raise HTTPException(status_code=404, detail="This record is missing")
  184.     crud.delete_price(db=db, price_id=price_id)
  185.     return {"status": "ok"}
  186.  
  187.  
  188.  
  189. # models.py
  190.  
  191. from sqlalchemy import Boolean, Column, ForeignKey, Integer, String, DateTime
  192. from sqlalchemy.orm import relationship
  193.  
  194. from .database import Base
  195.  
  196.  
  197. class Price(Base):
  198.     __tablename__ = "prices"
  199.  
  200.     id = Column(Integer, primary_key=True)
  201.     name = Column(String)
  202.     price = Column(Integer)
  203.     datetime = Column(DateTime)
  204.  
  205.  
  206.  
  207. # price_parser.py
  208.  
  209. import requests
  210. from bs4 import BeautifulSoup as bs
  211. from sqlalchemy.orm import declarative_base
  212.  
  213. Base = declarative_base()
  214.  
  215. PRODUCT_URL = 'https://ekaterinburg.lifemebel.ru/catalog/stoly/dlya_komnat/servirovochnye/' \
  216.               'model/cervirovochnyy_stol_trolly_oak/'
  217.  
  218. headers = {
  219.     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 '
  220.                   'YaBrowser/23.7.0.2526 Yowser/2.5 Safari/537.36',
  221.     'Cookie': 'FTID=2oBjMf1U4C2J:1690619148:3245294:::; path=/; expires=Mon, 29-Jul-24 08:25:48 GMT; domain=.mail.ru; '
  222.               'HttpOnly; SameSite=None; Secure'
  223. }
  224.  
  225.  
  226. def start_parser():
  227.     page = requests.get(url=PRODUCT_URL, headers=headers)
  228.     html = page.text
  229.  
  230.     soup = bs(html, 'lxml')
  231.     title = soup.find('div', class_='new-product-title').find('h2', itemprop="name")
  232.     title = title.get_text().strip()
  233.  
  234.     price = soup.find('div', class_='nowrap new-product-price-new')
  235.     price = int(price.get_text().strip()[:-5])
  236.  
  237.     return title, price
  238.  
  239.  
  240. start_parser()
  241.  
  242.  
  243.  
  244. # schemas.py
  245.  
  246. from typing import List, Union
  247. from pydantic import BaseModel
  248. from datetime import datetime
  249.  
  250.  
  251. class PriceBase(BaseModel):
  252.     name: str
  253.     price: int
  254.  
  255.  
  256. class PriceCreate(PriceBase):
  257.     pass
  258.  
  259.  
  260. class Price(PriceBase):
  261.     id: int
  262.     datetime: datetime
  263.  
  264.     class Config:
  265.         orm_mode = True
  266.  
Advertisement
Add Comment
Please, Sign In to add comment