provide api

This commit is contained in:
0x90.space 2021-12-29 02:52:08 +01:00
parent c09d8a64f4
commit ab79366ec5
3 changed files with 79 additions and 8 deletions

View file

@ -22,6 +22,7 @@ python_requires = >=3.8
install_requires = install_requires =
aiosqlite aiosqlite
blacksheep blacksheep
pydantic
tortoise-orm tortoise-orm
uvicorn uvicorn

View file

@ -1,9 +1,23 @@
from blacksheep.client import ClientSession from blacksheep.client import ClientSession
from blacksheep.contents import Content
from blacksheep.messages import Response
from blacksheep.server import Application from blacksheep.server import Application
import json from blacksheep.server.responses import not_found
from ticketfrei3.models import Fahrt, Halt, Haltestelle from json import loads as from_json
from ticketfrei3.models import (
Fahrt,
Fahrt_Pydantic,
Fahrt_Pydantic_List,
Halt,
Halt_Pydantic,
Halt_Pydantic_List,
Haltestelle,
Haltestelle_Pydantic,
Haltestelle_Pydantic_List,
)
from tortoise import Tortoise from tortoise import Tortoise
from tortoise.transactions import in_transaction from tortoise.transactions import in_transaction
from tortoise.contrib.pydantic import PydanticModel
app = Application() app = Application()
@ -29,10 +43,10 @@ async def finalize(app: Application) -> None:
app.on_stop += finalize app.on_stop += finalize
@app.route("/fetch_haltestellen") @app.route("/api/fetch_haltestellen")
async def fetch_haltestellen(client: ClientSession) -> None: async def fetch_haltestellen(client: ClientSession) -> None:
response = await client.get("https://start.vag.de/dm/api/v1/haltestellen.json/vag") response = await client.get("https://start.vag.de/dm/api/v1/haltestellen.json/vag")
haltestellen = json.loads(await response.text()) haltestellen = from_json(await response.text())
for haltestelle in haltestellen["Haltestellen"]: for haltestelle in haltestellen["Haltestellen"]:
if await Haltestelle.exists(id=haltestelle["VGNKennung"]): if await Haltestelle.exists(id=haltestelle["VGNKennung"]):
continue continue
@ -44,13 +58,13 @@ async def fetch_haltestellen(client: ClientSession) -> None:
) )
@app.route("/fetch_fahrten") @app.route("/api/fetch_fahrten")
async def fetch_fahrten(client: ClientSession) -> None: async def fetch_fahrten(client: ClientSession) -> None:
for zweig in ("bus", "tram", "ubahn"): for zweig in ("bus", "tram", "ubahn"):
response = await client.get( response = await client.get(
"https://start.vag.de/dm/api/v1/fahrten.json/%s?timespan=120" % zweig "https://start.vag.de/dm/api/v1/fahrten.json/%s?timespan=120" % zweig
) )
fahrten = json.loads(await response.text()) fahrten = from_json(await response.text())
for fahrt in fahrten["Fahrten"]: for fahrt in fahrten["Fahrten"]:
if await Fahrt.exists(id=fahrt["Fahrtnummer"]): if await Fahrt.exists(id=fahrt["Fahrtnummer"]):
continue continue
@ -61,7 +75,7 @@ async def fetch_fahrten(client: ClientSession) -> None:
"https://start.vag.de/dm/api/v1/fahrten.json/%s/%d" "https://start.vag.de/dm/api/v1/fahrten.json/%s/%d"
% (zweig, fahrt.id) % (zweig, fahrt.id)
) )
details = json.loads(await response.text()) details = from_json(await response.text())
for halt in details["Fahrtverlauf"]: for halt in details["Fahrtverlauf"]:
haltestelle = ( haltestelle = (
await Haltestelle.filter(id=halt["VGNKennung"]) await Haltestelle.filter(id=halt["VGNKennung"])
@ -74,3 +88,49 @@ async def fetch_fahrten(client: ClientSession) -> None:
ankunft=halt.get("AnkunftszeitIst"), ankunft=halt.get("AnkunftszeitIst"),
abfahrt=halt.get("AbfahrtszeitIst"), abfahrt=halt.get("AbfahrtszeitIst"),
).save(using_db=connection) ).save(using_db=connection)
def to_json(model: PydanticModel) -> Response:
return Response(
200,
content=Content(b"application/json", model.json(ensure_ascii=False).encode()),
)
@app.router.get("/api/haltestellen")
async def haltestellen() -> Response:
return to_json(await Haltestelle_Pydantic_List.from_queryset(Haltestelle.all()))
@app.router.get("/api/haltestelle/{id}")
async def haltestelle(id: int) -> Response:
haltestelle = await Haltestelle.filter(id=id).first()
if haltestelle is None:
return not_found()
return to_json(await Haltestelle_Pydantic.from_tortoise_orm(haltestelle))
@app.router.get("/api/fahrten")
async def fahrten() -> Response:
return to_json(await Fahrt_Pydantic_List.from_queryset(Fahrt.all()))
@app.router.get("/api/fahrt/{id}")
async def fahrt(id: int) -> Response:
fahrt = await Fahrt.filter(id=id).first()
if fahrt is None:
return not_found()
return to_json(await Fahrt_Pydantic.from_tortoise_orm(fahrt))
@app.router.get("/api/halte")
async def halte() -> Response:
return to_json(await Halt_Pydantic_List.from_queryset(Halt.all()))
@app.router.get("/api/halt/{id}")
async def halt(id: int) -> Response:
halt = await Halt.filter(id=id).first()
if halt is None:
return not_found()
return to_json(await Halt_Pydantic.from_tortoise_orm(halt))

View file

@ -1,5 +1,6 @@
from tortoise.models import Model
from tortoise import fields from tortoise import fields
from tortoise.contrib.pydantic import pydantic_model_creator, pydantic_queryset_creator
from tortoise.models import Model
class Fahrt(Model): class Fahrt(Model):
@ -22,3 +23,12 @@ class Haltestelle(Model):
longitude = fields.FloatField(null=True) longitude = fields.FloatField(null=True)
latitude = fields.FloatField(null=True) latitude = fields.FloatField(null=True)
fahrten: fields.ReverseRelation["Halt"] fahrten: fields.ReverseRelation["Halt"]
Fahrt_Pydantic = pydantic_model_creator(Fahrt)
Halt_Pydantic = pydantic_model_creator(Halt)
Haltestelle_Pydantic = pydantic_model_creator(Haltestelle)
Fahrt_Pydantic_List = pydantic_queryset_creator(Fahrt)
Halt_Pydantic_List = pydantic_queryset_creator(Halt)
Haltestelle_Pydantic_List = pydantic_queryset_creator(Haltestelle)