I'm trying to use pydantic to scrape an api endpoint. These endpoints are a little tricky to scrape in one go, so I need some identifier to merge them together. I decided to use ab_number (at-bat number) to be that unique identifier. The issue I'm having is incrementing it through the list of each at-bats. Here's my code:
import requests
from pydantic import BaseModel, Field
from typing import List
url = "https://statsapi.mlb.com/api/v1.1/game/745707/feed/live/diffPatch"
response = requests.get(url).json()
class AtBat(BaseModel):
ab_number: int = Field(None) # Ideally I don't want this here, but it's there to bypass the missing error
_counter: int = 1
def __init__(self, **data):
super().__init__(**data)
self.ab_number = AtBat._counter
AtBat._counter += 1
print(self.ab_number) # Can use this as a debugging check
class Plays(BaseModel):
allPlays: List[AtBat]
data = Plays(**response['liveData']['plays'])
The error I run into with this code is:
TypeError: unsupported operand type(s) for +=: 'ModelPrivateAttr' and 'int'
What I want it to return:
allPlays = [AtBat(ab_number=1), AtBat(ab_number=2), AtBat(ab_number=3), ..., ]
I tried looking into the docs on if you can access the value of private attribute, but there doesn't appear to be so I'm not sure if there are other ways to do this. I just want something that increments as simple as how a primary key would auto increment in mysql.
I used the ClassVar type cast then created a reset class method to reset the counter if there are multiple games being scraped so it doesn't keep incrementing to n plays.
import requests
from pydantic import BaseModel
from typing import List, ClassVar
url = "https://statsapi.mlb.com/api/v1.1/game/745707/feed/live/diffPatch"
response = requests.get(url).json()
class AtBat(BaseModel):
ab_number: int = None
_counter: ClassVar[int] = 1
def __init__(self, **data):
super().__init__(**data)
self.ab_number = AtBat._counter
AtBat._counter += 1
@classmethod
def reset_count(cls):
cls._counter = 1
class Plays(BaseModel):
allPlays: List[AtBat]
def __init__(self, **data):
super().__init__(**data)
AtBat.reset_count()
data = Plays(**response['liveData']['plays'])
print(data)
Appreciate the help.