
    uif#                        U d Z ddlmZ ddlZddlZddlmZ ddlZddlm	Z	 ddl
mZ  ej        e          Zdaded<   h d	Zd
ZdZddZ G d d          ZdS )u-  
Nom du script : gitlab_client.py
Chemin : /gitlab-bridge/app/clients/gitlab_client.py
Description : Client HTTP sécurisé pour l'API GitLab utilisé par les services métiers.
              Utilise un client httpx persistant (connection pooling), supporte la
              pagination automatique et le retry sur erreurs transitoires.
Options éventuelles : Aucune.
Exemples d'utilisation : `GitLabClient().get_project_by_path(...)`.
Prérequis : Python 3.11+, httpx.
Auteur : Sylvain SCATTOLINI
Date de création / modification : 2026-03-25
Version : 1.2
    )annotationsN)quote)settings)GitLabApiErrorzhttpx.Client | None_shared_client>                g      ?returnhttpx.Clientc            
         t           t           j        rOt          j        t          j        t          j        t          j        dddt          j        ddd                    a t           S )	uD   Retourne le client httpx partagé, en le (re)créant si nécessaire.Nzapplication/json)zPRIVATE-TOKENAcceptzContent-Type   
      )max_connectionsmax_keepalive_connectionskeepalive_expiry)timeoutverifyheaderslimits)	r   	is_closedhttpxClientr   gitlab_timeoutgitlab_verify_sslgitlab_api_tokenLimits     8/var/www/html/gitlab-bridge/app/clients/gitlab_client.py_get_shared_clientr&   $   sq     !9+-!)!:, 2 
 < "*,!#  
 
 
 r$   c                      e Zd ZdZd5dZdddd6dZdddd7dZd8d9dZdddd:dZd;dZ	d<dZ
d=dZd>d!Zd?d@d$Zdd%d&dAd*ZdBd,ZdCd@d.ZdDd3ZdEd4ZdS )FGitLabClientzIClient vers l'API GitLab v4 avec connection pooling, pagination et retry.r   Nonec                h    t          t          j                                      d          | _        d S )N/)strr   gitlab_base_urlrstrip	_base_urlselfs    r%   __init__zGitLabClient.__init__<   s&    X566==cBBr$   Nparams	json_bodymethodr,   pathr4   dict | Noner5   httpx.Responsec          
        | j          d| }t                      }d}t          t                    D ]'}	 |                    ||||          }	|	j        t          v r_|t          dz
  k     rQt          d|z  z  }
t          	                    d|	j        ||dz   t          dz
  |
           t          j        |
           |	                                 |	c S # t          j        $ r  t          j        $ rf}|}|t          dz
  k     rKt          d|z  z  }
t          	                    d||dz   t          dz
  |
|           t          j        |
           Y d}~!d}~ww xY wt!          d| d	t           d
          |)uK   Exécute une requête HTTP avec retry automatique sur erreurs transitoires.z/api/v4N)r6   urlr4   json      u0   GitLab HTTP %s sur %s — retry %d/%d dans %.1fsu<   Erreur réseau GitLab sur %s — retry %d/%d dans %.1fs : %su   Erreur réseau GitLab sur u    après z tentatives)r/   r&   range_MAX_RETRIESrequeststatus_code_RETRY_STATUS_CODES_RETRY_BACKOFF_BASEloggerwarningtimesleepraise_for_statusr   HTTPStatusError	HTTPErrorr   )r1   r6   r7   r4   r5   r;   clientlast_excattemptresponsewaitexcs               r%   _request_rawzGitLabClient._request_raw?   s    ....#%%%)\** '	% '	%G&%!>>!!"	 *   '+>>>7\\]M]C]C].!w,?DNNJ ,!$q(   Jt$$$))+++(   ? % % %\A---.!w,?DNNV!$q(   Jt$$$% a$aaaaabbhpps   BC;CE1AEEdict | listc                  	 |                      ||||          }|                                S # t          j        $ r1}t	          d|j        j         d| |j        j                  |d}~wt          $ r}t	          d          |d}~ww xY w)u7   Exécute une requête et retourne le corps JSON parsé.r3   GitLab HTTP  sur )http_statusNu   Réponse JSON GitLab invalide)rR   r<   r   rJ   r   rO   rB   
ValueError)r1   r6   r7   r4   r5   rO   rQ   s          r%   _requestzGitLabClient._requestw   s    		K((fPY(ZZH==??"$ 	 	 	 Ds|7DDdDDL4     	K 	K 	K !@AAsJ	Ks    ,/ B,A**B7BB
list[dict]c                   i |pi ddd}g }	 	 |                      d||          }n7# t          j        $ r%}t          d|j        j         d|           |d	}~ww xY w|                                }t          |t                    sn~|	                    |           t          |j                            d
d                    }t          |j                            d|d                             }	|	|k    rni |d|	dz   i}|S )u   
        Récupère toutes les pages d'une ressource GitLab (pagination automatique).
        Utilise l'en-tête X-Total-Pages retourné par GitLab.
        d   r=   )per_pagepageTGETr4   rU   rV   NzX-Total-Pages1zX-Pager^   )rR   r   rJ   r   rO   rB   r<   
isinstancelistextendintr   get)
r1   r7   r4   base_paramsresultsrO   rQ   	page_datatotal_pagescurrent_pages
             r%   _list_all_pageszGitLabClient._list_all_pages   sJ   
 E&,BDS!DDD 	Dd,,UD,MM( d d d$%YCL4L%Y%YSW%Y%YZZ`ccd !Ii.. NN9%%%h.22?CHHIIKx/33Hk&>QRRSSL{**C[C&,2BCCK!	D$ s   ) A AA)emailusernamerm   
str | Nonern   c               T    i }|r||d<   n|r||d<   |                      dd|          S )Nsearchrn   r_   z/usersr`   rY   )r1   rm   rn   r4   s       r%   search_userszGitLabClient.search_users   sF    !# 	*$F8 	*!)F:}}UHV}<<<r$   project_pathdictc                V    t          |d          }|                     dd|           S )N )safer_   
/projects/)r   rY   )r1   rt   encoded_paths      r%   get_project_by_pathz GitLabClient.get_project_by_path   s1    \333}}U$?$?$?@@@r$   
project_idre   user_idc                :    |                      dd| d|           S )Nr_   ry   z/members/all/rr   )r1   r|   r}   s      r%   get_project_memberzGitLabClient.get_project_member   s'    }}U$S$S$S'$S$STTTr$   c                @    |                      d| ddddd          S )Nry   /issuesopened
updated_atdescstateorder_bysortr`   rl   )r1   r|   s     r%   list_open_issueszGitLabClient.list_open_issues   s:    ##,,,,%<PP $ 
 
 	
r$   closed_after_isoc                B    |                      d| dd|ddd          S )Nry   r   closedr   r   )r   updated_afterr   r   r`   r   )r1   r|   r   s      r%   list_closed_issues_sincez%GitLabClient.list_closed_issues_since   sC    ##,,,,!!1(	  $ 
 
 	
r$   allr   c                @    |                      d| d|ddd          S )u?   Retourne toutes les issues (toutes pages) dans un état donné.ry   r   r   r   r   r`   r   r1   r|   r   s      r%   list_all_issueszGitLabClient.list_all_issues   s:    ##,,,,"fMM $ 
 
 	
r$   T)rq   all_availablerq   r   boolc               F    d|i}|r||d<   |                      d|          S )z5Retourne tous les groupes accessibles (toutes pages).r   rq   z/groupsr`   r   )r1   rq   r   r4   s       r%   list_groupszGitLabClient.list_groups   s7    '7 	&%F8##If#===r$   group_idc                <    |                      d| dddi          S )z5Retourne tous les projets d'un groupe (toutes pages).z/groups/z	/projectssimpleTr`   r   )r1   r   s     r%   list_group_projectsz GitLabClient.list_group_projects   s-    ##$Bx$B$B$BHVZK[#\\\r$   activec                <    |                      d| dd|i          S )z)Retourne tous les milestones d'un projet.ry   z/milestonesr   r`   r   r   s      r%   list_milestoneszGitLabClient.list_milestones   s5    ##0000U# $ 
 
 	
r$   titledescriptionlabels	list[str]c                l    ||d                     |          d}|                     dd| d|          S )N,)r   r   r   POSTry   r   )r5   )joinrY   )r1   r|   r   r   r   payloads         r%   create_issuezGitLabClient.create_issue   sJ    &hhv&&
 

 }}V%E*%E%E%EQX}YYYr$   c                .    |                      dd          S )u?   Vérifie la connectivité à GitLab en récupérant la version.r_   z/versionrr   r0   s    r%   check_versionzGitLabClient.check_version   s    }}UJ///r$   )r   r)   )
r6   r,   r7   r,   r4   r8   r5   r8   r   r9   )
r6   r,   r7   r,   r4   r8   r5   r8   r   rS   )N)r7   r,   r4   r8   r   rZ   )rm   ro   rn   ro   r   rZ   )rt   r,   r   ru   )r|   re   r}   re   r   ru   )r|   re   r   rZ   )r|   re   r   r,   r   rZ   )r   )r|   re   r   r,   r   rZ   )rq   ro   r   r   r   rZ   )r   re   r   rZ   )r   )
r|   re   r   r,   r   r,   r   r   r   ru   )r   ru   )__name__
__module____qualname____doc__r2   rR   rY   rl   rs   r{   r   r   r   r   r   r   r   r   r   r#   r$   r%   r(   r(   9   s       SSC C C C #!%6q 6q 6q 6q 6q 6qz #!%K K K K K K(    @ 37t = = = = = =A A A AU U U U
 
 
 
	
 	
 	
 	

 
 
 
 
 37d > > > > > >] ] ] ]
 
 
 
 
Z Z Z Z0 0 0 0 0 0r$   r(   )r   r   )r   
__future__r   loggingrG   urllib.parser   r   app.core.configr   app.core.exceptionsr   	getLoggerr   rE   r   __annotations__rC   r@   rD   r&   r(   r#   r$   r%   <module>r      s     # " " " " "          $ $ $ $ $ $ . . . . . .		8	$	$ '+ * * * *///     *u0 u0 u0 u0 u0 u0 u0 u0 u0 u0r$   