a
    r˜Ûi³(  ã                   @   sþ  d Z ddlZddlZddlZddlZddlZddlm	Z	 ddl
m
Z
 dZdeiZe	dƒZed Zed	 Zed
 Zed ZdZdZdd„ Zdd„ Zdd„ Zdd„ Zedƒ ede› d�ƒ e e¡Zedeeƒd›�ƒ eed  ¡  ¡ ƒ eƒ Ze  ¡ �r>e!eƒ�*Z"edd„ e" #¡  $¡ D ƒƒZW d  ƒ n1 �s40    Y  eed  %e¡  j&dd �Z'ed!ƒ ed"ee'ƒd›d#eeƒd›d�ƒ ee'ƒdk�ržed$ƒ �nüeƒ \Z(Z)ed%e(› d&e)› d'e)e( › d(�ƒ e  ¡ �rÜe e¡ne *¡ Z+g Z,e(Z-dZ.e /d¡ 0d)¡Z1e' 2¡ D �]\Z3Z4e5e4d ƒZ6e-ek�r`e
 7¡ Z7e7j8d* d+ d* Z9e:dd*e7j8 d, e7j;d-  e7j< d- ƒZ=e=d, Z>e=d, d- Z?ed.e.› d/�ƒ e,�ræe *e,¡Z@ee+ƒ�rºejAe+e@gdd0�ne@ZBeBjCed1d2� ed3eeBƒd›d4e› �ƒ e!ed5ƒ�Z"W d  ƒ n1 �s0    Y  ed6e>› d7e?› d8�ƒ e De=¡ eƒ \Z(Z)e(Z-ed%e(› d&e)› d'e)e( › d(�ƒ dZEeEd9k�r�z,ee6ƒZFe-d+7 Z-e.d+7 Z.eF�rªee6e1e6 eFƒZGe, HeG¡ e!ed5ƒ� Z"e" Ie6› d:�¡ W d  ƒ n1 �sÜ0    Y  e Je6¡ e.e dk�rˆe *e,¡Z@ee+ƒ�r$ejAe+e@gdd0�ne@ZBeBjCed1d2� eBZ+g Z,ed;ee+ƒd›d<e-› d/�ƒ eƒ \ZKZLeKZ-ed%e-› d&e)› d'e)e- › d(�ƒ e Dd+¡ W �qW �qd ejMjN�yÂ ZO �zeOjFdu�rÈeOjFjPndZPePd=k�rd>d?eE  ZQed@eQ› dAeEd+ › dB�ƒ e DeQ¡ eEd+7 ZEnžePdCk�r‚e!ed5ƒ� Z"e" Ie6› d:�¡ W d  ƒ n1 �sL0    Y  e Je6¡ e.d+7 Z.e Dd+¡ W Y dZO[O�qn,edDe6› dEeO› �ƒ e Dd?¡ W Y dZO[O�qW Y dZO[OnZdZO[O0  eR�y ZO z8edDe6› dEeO› �ƒ e Dd?¡ W Y dZO[O�qW Y dZO[On
dZO[O0 0 �qd�qe,�rve *e,¡Z@ee+ƒ�rHejAe+e@gdd0�ne@ZBeBjCed1d2� ed3eeBƒd›d4e› �ƒ n$ee+ƒ�ršed:ee+ƒd›dFe› �ƒ edGƒ e e¡ZSeeSƒZTeTjCed1d2� dHdI„ eTjUD ƒZVedJeeTƒd›dKe› �ƒ edLeV› �ƒ dS )Muº   
API-Football data pull â€” fetches match statistics for all fixtures.
Saves to E:\socceraw_api\ (never OneDrive, avoids disk-full eviction).
Resumes from done_fixtures.txt on restart.
é    N)ÚPath)ÚdatetimeZ 81b487be73030f5dec980d2a1ef2c406zx-apisports-keyzE:\soccer\raw_apizmatch_stats.csvzdone_fixtures.txtzfixtures_index.csvzmatch_features.csviè  iô  c                  C   sZ   d} zBt j| tdd�}| ¡ }|d d d }|d d d }||fW S    Y dS 0 d S )	Nz(https://v3.football.api-sports.io/statusé
   )ÚheadersÚtimeoutÚresponseÚrequestsZcurrentZ	limit_day)r   iL  )r   ÚgetÚHEADERSÚjson)ÚurlÚrÚdataÚusedÚlimit© r   ú#E:\soccer\misc\pull_api_football.pyÚget_requests_used   s    
r   c                 C   s2   d}t j|td| idd�}| ¡  | ¡  dg ¡S )Nz5https://v3.football.api-sports.io/fixtures/statisticsZfixtureé   )r   Úparamsr   r   )r   r	   r
   Zraise_for_statusr   )Ú
fixture_idr   r   r   r   r   Úfetch_stats!   s    r   c                    sê   g }|D ]Ü}|d d }||d k}dd„ |d D ƒ‰ d ‡ fdd„	}|  | |d	 |d
 |d |t|ƒ|d |d |d |d |dƒ|dƒ|dƒ|dƒ|dƒ|dƒ|dƒ|dƒ|dƒ|dƒ|dƒ|dƒ|dƒ|dƒ|dƒ|dƒdœ¡ q|S )!NÚteamÚnameÚ	home_teamc                 S   s   i | ]}|d  |d “qS )ÚtypeÚvaluer   )Ú.0Úsr   r   r   Ú
<dictcomp>,   ó    zparse_stats.<locals>.<dictcomp>Z
statisticsc                    sn   ˆ   | |¡}|d u r|S t|tƒrN| d¡rNzt| d¡ƒW S    | Y S 0 z
t|ƒW S    | Y S 0 d S )Nú%)r	   Ú
isinstanceÚstrÚendswithÚfloatÚrstrip)ÚkeyÚdefaultÚv©Zstatsr   r   r	   -   s    zparse_stats.<locals>.getÚdateÚdivÚseasonÚ	away_teamÚ
home_goalsÚ
away_goalszShots on GoalzShots off GoalzTotal ShotszBlocked ShotszShots insideboxzShots outsideboxZFoulszCorner KicksZOffsideszBall PossessionzYellow Cardsz	Red CardszGoalkeeper SaveszTotal passeszPasses accuratezPasses %)r   r+   r,   r-   r   Úis_homer   r.   r/   r0   Úshots_on_goalÚshots_off_goalÚtotal_shotsÚblocked_shotsÚshots_insideÚshots_outsideÚfoulsÚcornersÚoffsidesÚ
possessionÚyellow_cardsÚ	red_cardsÚsavesÚtotal_passesÚaccurate_passesÚpass_pct)N)ÚappendÚint)r   Zfixture_rowr   ZrowsZ	team_dataZ	team_namer1   r	   r   r*   r   Úparse_stats'   sF    æ
rD   c              	      sª  ˆ   ¡ ‰ t ˆ d ¡ˆ d< ˆ  ddg¡jdd�‰ g d¢}dˆ d< ˆ d d	kˆ d
 ˆ d k@ ˆ d dkˆ d ˆ d
 k@ B }ˆ d
 ˆ d k}dˆ j|df< d	ˆ j|df< ˆ jdd„ d	d�ˆ d< ˆ jdd„ d	d�ˆ d< g d¢‡ fdd„|D ƒ }g }ˆ  d¡D ]t\}}| d¡jdd�}dD ]J}|D ]>}	|	|jv �r||	  	d	¡j
|d	d� ¡ |d|	› d|› �< �q�q| |¡ qøtj|dd�‰g d¢dd„ ˆjD ƒ }
ˆ‡fdd„|
D ƒ S )Nr+   r   T©Zdrop)r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   r   Úptsr1   é   r/   r0   é   c                 S   s   | d r| d S | d S )Nr1   r/   r0   r   ©r   r   r   r   Ú<lambda>b   r    z build_features.<locals>.<lambda>)ZaxisÚgfc                 S   s   | d r| d S | d S )Nr1   r0   r/   r   rI   r   r   r   rJ   c   r    Úga)rF   rK   rL   c                    s   g | ]}|ˆ j v r|‘qS r   ©Úcolumns©r   Úc)Údfr   r   Ú
<listcomp>d   r    z"build_features.<locals>.<listcomp>)é   r   )Zmin_periodsÚapi_Z_w©Zignore_index)
r   r+   r,   r-   r   r1   r   r.   r/   r0   c                 S   s   g | ]}|  d ¡r|‘qS ©rT   ©Ú
startswithrO   r   r   r   rR   p   r    c                    s   g | ]}|ˆ j v r|‘qS r   rM   rO   )Úfeat_dfr   r   rR   q   r    )ÚcopyÚpdZto_datetimeZsort_valuesÚreset_indexZlocZapplyÚgroupbyrN   ÚshiftZrollingZmeanrB   Úconcat)rQ   Z	stat_colsZwin_maskZ	draw_maskZ	roll_colsZ	feat_rowsr   ZgrpÚwÚcolÚ	feat_colsr   )rQ   rY   r   Úbuild_featuresS   s6    ÿ4þrc   z=== API-Football Data Pull ===
z Loading existing fixture index (ú)z
Total fixtures in index: ú,r,   c                 c   s   | ]}|  ¡ rt|ƒV  qd S )N)ÚstriprC   )r   Úxr   r   r   Ú	<genexpr>   r    rh   r   TrE   z"
=== Pulling match statistics ===
zFixtures to process: z (already done: zAll fixtures already pulled!z  API requests today: ú/z (z remaining)Úindexé   rG   i  é<   u(   Approaching daily limit â€” stopping at z requests todayrU   F)rj   z
Saved z team-match rows to Úaz   Daily limit reached. Sleeping zh zm until quota resets...rH   Ú
z  Checkpoint: z rows saved, i­  é   é   u     429 rate limit â€” sleeping z	s (retry z/3)i“  z  Error fixture z: z team-match rows already in z"
=== Building rolling features ===c                 C   s   g | ]}|  d ¡r|‘qS rV   rW   rO   r   r   r   rR   î   r    rR   zFeatures saved: z	 rows -> z	Columns: )WÚ__doc__r   Zpandasr[   ZnumpyZnpÚtimeÚosÚpathlibr   r   ZAPI_KEYr
   ZOUT_DIRZ	STATS_CSVZ	DONE_FILEZFIXTURES_CSVZFEATURES_CSVZDAILY_LIMITZ
CHECKPOINTr   r   rD   rc   ÚprintZread_csvZindex_dfÚlenZvalue_countsZ	to_stringÚsetZdoneÚexistsÚopenÚfÚreadÚsplitZisinr\   Ztodor   r   Z	DataFrameÚexistingZnew_rowsZrequests_todayZdone_this_runZ	set_indexZto_dictZfixture_lookupZiterrowsÚiÚrowrC   ZfidZnowZhourZ
reset_hourÚmaxZminuteÚsecondZ	wait_secsZhrsZminsÚchunkr_   ZcombinedZto_csvÚsleepZretriesr   ZparsedÚextendÚwriteÚaddZused2Ú_Ú
exceptionsZ	HTTPErrorÚeZstatus_codeÚwaitÚ	ExceptionZstats_dfrY   rN   rb   r   r   r   r   Ú<module>   sè   (,!


:"
 
(
  

 

0

 
 




0


"
,
 

