Coverage for src\pncp\instrumentos_convocatorios\busca.py: 100%

1 from typing import Iterable

2

3 import pncp.utils

4 from pncp.tipos import Lista

5

6 from .tipos import (

7 Ano,

8 CamposDeBusca,

9 Esfera,

10 FonteOrcamentaria,

11 Id,

12 InstrumentoConvocatorio,

13 ModalidadeDeContratacao,

14 Municipio,

15 Orgao,

16 Poder,

17 Resultado,

18 Status,

19 Unidade,

20 UnidadeDaFederacao,

21)

22

23

24 class Busca:

25 _url_filtros = "https://pncp.gov.br/api/search/filters?tipos_documento=edital"

26 _url_busca = "https://pncp.gov.br/api/search"

27

28 def __init__(self):

29 self._filtros = None

30 self._campos_de_busca = CamposDeBusca()

31 self._resultados: Lista[Resultado] | None = None

32

33 def _carregar_filtros(self):

34 if self._filtros is None:

35 data = pncp.utils.get_one(self._url_filtros)

36 self._filtros = data["filters"]

37

38 def _verificar_se_existem_resultados(self) -> None:

39 if self._resultados is not None:

40 raise ValueError("Não é possível modificar uma busca já realizada.")

41

42 def listar_status(self) -> Lista[Status]:

43 return Status.listar()

44

45 def listar_instrumentos_convocatorios(self) -> Lista[InstrumentoConvocatorio]:

46 self._carregar_filtros()

47

48 if not self._filtros or "tipos" not in self._filtros:

49 return Lista()

50

51 return Lista(

52 InstrumentoConvocatorio(**instrumento_convocatorio)

53 for instrumento_convocatorio in self._filtros["tipos"]

54 )

55

56 def listar_modalidades_de_contratacao(self) -> Lista[ModalidadeDeContratacao]:

57 self._carregar_filtros()

58

59 if not self._filtros or "modalidades" not in self._filtros:

60 return Lista()

61

62 return Lista(

63 ModalidadeDeContratacao(**modalidade_de_contratacao)

64 for modalidade_de_contratacao in self._filtros["modalidades"]

65 )

66

67 def listar_orgaos(self) -> Lista[Orgao]:

68 self._carregar_filtros()

69

70 if not self._filtros or "orgaos" not in self._filtros:

71 return Lista()

72

73 return Lista(Orgao(**orgao) for orgao in self._filtros["orgaos"])

74

75 def listar_unidades(self) -> Lista[Unidade]:

76 self._carregar_filtros()

77

78 if not self._filtros or "unidades" not in self._filtros:

79 return Lista()

80

81 return Lista(Unidade(**unidade) for unidade in self._filtros["unidades"])

82

83 def listar_ufs(self) -> Lista[UnidadeDaFederacao]:

84 self._carregar_filtros()

85

86 if not self._filtros or "ufs" not in self._filtros:

87 return Lista()

88

89 return Lista(UnidadeDaFederacao(**uf) for uf in self._filtros["ufs"])

90

91 def listar_municipios(self) -> Lista[Municipio]:

92 self._carregar_filtros()

93

94 if not self._filtros or "municipios" not in self._filtros:

95 return Lista()

96

97 return Lista(Municipio(**municipio) for municipio in self._filtros["municipios"])

98

99 def listar_esferas(self) -> Lista[Esfera]:

100 self._carregar_filtros()

101

102 if not self._filtros or "esferas" not in self._filtros:

103 return Lista()

104

105 return Lista(Esfera(**esfera) for esfera in self._filtros["esferas"])

106

107 def listar_poderes(self) -> Lista[Poder]:

108 self._carregar_filtros()

109

110 if not self._filtros or "poderes" not in self._filtros:

111 return Lista()

112

113 return Lista(Poder(**poder) for poder in self._filtros["poderes"])

114

115 def listar_anos(self) -> Lista[Ano]:

116 self._carregar_filtros()

117

118 if not self._filtros or "anos" not in self._filtros:

119 return Lista()

120

121 return Lista(Ano(**ano) for ano in self._filtros["anos"])

122

123 def listar_fontes_orcamentarias(self) -> Lista[FonteOrcamentaria]:

124 self._carregar_filtros()

125

126 if not self._filtros or "fontes_orcamentarias" not in self._filtros:

127 return Lista()

128

129 return Lista(

130 FonteOrcamentaria(**fonte_orcamentaria)

131 for fonte_orcamentaria in self._filtros["fontes_orcamentarias"]

132 )

133

134 @property

135 def texto(self) -> str:

136 return self._campos_de_busca.q

137

138 @property

139 def pagina(self) -> int:

140 return self._campos_de_busca.pagina

141

142 @property

143 def tam_pagina(self) -> int:

144 return self._campos_de_busca.tam_pagina

145

146 @property

147 def status(self) -> Status:

148 return (

149 self.listar_status()

150 .filtrar(lambda status: status.id == self._campos_de_busca.status)

151 .pop()

152 )

153

154 @property

155 def instrumentos_convocatorios(self) -> Lista[InstrumentoConvocatorio]:

156 return Lista(

157 instrumento_convocatorio

158 for instrumento_convocatorio in self.listar_instrumentos_convocatorios()

159 if instrumento_convocatorio.id in self._campos_de_busca.tipos

160 )

161

162 @property

163 def modalidades_de_contratacao(self) -> Lista[ModalidadeDeContratacao]:

164 return Lista(

165 modalidade_de_contratacao

166 for modalidade_de_contratacao in self.listar_modalidades_de_contratacao()

167 if modalidade_de_contratacao.id in self._campos_de_busca.modalidades

168 )

169

170 @property

171 def orgaos(self) -> Lista[Orgao]:

172 return Lista(

173 orgao for orgao in self.listar_orgaos() if orgao.id in self._campos_de_busca.orgaos

174 )

175

176 @property

177 def unidades(self) -> Lista[Unidade]:

178 return Lista(

179 unidade

180 for unidade in self.listar_unidades()

181 if unidade.id in self._campos_de_busca.unidades

182 )

183

184 @property

185 def ufs(self) -> Lista[UnidadeDaFederacao]:

186 return Lista(uf for uf in self.listar_ufs() if uf.id in self._campos_de_busca.ufs)

187

188 @property

189 def municipios(self) -> Lista[Municipio]:

190 return Lista(

191 municipio

192 for municipio in self.listar_municipios()

193 if municipio.id in self._campos_de_busca.municipios

194 )

195

196 @property

197 def esferas(self) -> Lista[Esfera]:

198 return Lista(

199 esfera for esfera in self.listar_esferas() if esfera.id in self._campos_de_busca.esferas

200 )

201

202 @property

203 def poderes(self) -> Lista[Poder]:

204 return Lista(

205 poder for poder in self.listar_poderes() if poder.id in self._campos_de_busca.poderes

206 )

207

208 @property

209 def anos(self) -> Lista[Ano]:

210 return Lista(ano for ano in self.listar_anos() if ano.ano in self._campos_de_busca.anos)

211

212 @property

213 def fontes_orcamentarias(self) -> Lista[FonteOrcamentaria]:

214 return Lista(

215 fonte_orcamentaria

216 for fonte_orcamentaria in self.listar_fontes_orcamentarias()

217 if fonte_orcamentaria.id in self._campos_de_busca.fontes_orcamentarias

218 )

219

220 @property

221 def resultados(self) -> Lista[Resultado]:

222 if self._resultados is not None:

223 return self._resultados

224 data = pncp.utils.get_one(

225 self._url_busca,

226 params=self._campos_de_busca.como_dicionario(),

227 )

228 self._resultados = Lista(Resultado(**resultado) for resultado in data["items"])

229 return self._resultados

230

231 @texto.setter

232 def texto(self, texto: str):

233 self._verificar_se_existem_resultados()

234 self._campos_de_busca.q = texto

235

236 @pagina.setter

237 def pagina(self, pagina: int):

238 self._verificar_se_existem_resultados()

239 self._campos_de_busca.pagina = pagina

240

241 @tam_pagina.setter

242 def tam_pagina(self, tam_pagina: int):

243 self._verificar_se_existem_resultados()

244 self._campos_de_busca.tam_pagina = tam_pagina

245

246 @status.setter

247 def status(self, status: Id | Status):

248 self._verificar_se_existem_resultados()

249

250 status_id = status.id if isinstance(status, Status) else status

251 valid_ids = [s.id for s in self.listar_status()]

252 if status_id not in valid_ids:

253 raise ValueError(f"Status inválido: {status}")

254

255 self._campos_de_busca.status = status_id

256

257 @instrumentos_convocatorios.setter

258 def instrumentos_convocatorios(

259 self, instrumentos_convocatorios: Iterable[Id] | Iterable[InstrumentoConvocatorio]

260 ):

261 self._verificar_se_existem_resultados()

262 self._campos_de_busca.tipos = Lista(

263 instrumento.id if isinstance(instrumento, InstrumentoConvocatorio) else instrumento

264 for instrumento in instrumentos_convocatorios

265 )

266

267 @modalidades_de_contratacao.setter

268 def modalidades_de_contratacao(

269 self, modalidades_de_contratacao: Iterable[Id] | Iterable[ModalidadeDeContratacao]

270 ):

271 self._verificar_se_existem_resultados()

272 self._campos_de_busca.modalidades = Lista(

273 modalidade.id if isinstance(modalidade, ModalidadeDeContratacao) else modalidade

274 for modalidade in modalidades_de_contratacao

275 )

276

277 @orgaos.setter

278 def orgaos(self, orgaos: Iterable[Id] | Iterable[Orgao]):

279 self._verificar_se_existem_resultados()

280 self._campos_de_busca.orgaos = Lista(

281 orgao.id if isinstance(orgao, Orgao) else orgao for orgao in orgaos

282 )

283

284 @unidades.setter

285 def unidades(self, unidades: Iterable[Id] | Iterable[Unidade]):

286 self._campos_de_busca.unidades = Lista(

287 unidade.id if isinstance(unidade, Unidade) else unidade for unidade in unidades

288 )

289

290 @ufs.setter

291 def ufs(self, ufs: Iterable[Id] | Iterable[UnidadeDaFederacao]):

292 self._verificar_se_existem_resultados()

293 self._campos_de_busca.ufs = Lista(

294 uf.id if isinstance(uf, UnidadeDaFederacao) else uf for uf in ufs

295 )

296

297 @municipios.setter

298 def municipios(self, municipios: Iterable[Id] | Iterable[Municipio]):

299 self._verificar_se_existem_resultados()

300 self._campos_de_busca.municipios = Lista(

301 municipio.id if isinstance(municipio, Municipio) else municipio

302 for municipio in municipios

303 )

304

305 @esferas.setter

306 def esferas(self, esferas: Iterable[Id] | Iterable[Esfera]):

307 self._verificar_se_existem_resultados()

308 self._campos_de_busca.esferas = Lista(

309 esfera.id if isinstance(esfera, Esfera) else esfera for esfera in esferas

310 )

311

312 @poderes.setter

313 def poderes(self, poderes: Iterable[Id] | Iterable[Poder]):

314 self._verificar_se_existem_resultados()

315 self._campos_de_busca.poderes = Lista(

316 poder.id if isinstance(poder, Poder) else poder for poder in poderes

317 )

318

319 @anos.setter

320 def anos(self, anos: Iterable[Id] | Iterable[Ano]):

321 self._verificar_se_existem_resultados()

322 self._campos_de_busca.anos = Lista(ano.ano if isinstance(ano, Ano) else ano for ano in anos)

323

324 @fontes_orcamentarias.setter

325 def fontes_orcamentarias(

326 self, fontes_orcamentarias: Iterable[Id] | Iterable[FonteOrcamentaria]

327 ):

328 self._verificar_se_existem_resultados()

329 self._campos_de_busca.fontes_orcamentarias = Lista(

330 fonte.id if isinstance(fonte, FonteOrcamentaria) else fonte

331 for fonte in fontes_orcamentarias

332 )

333

334 def preencher_texto(self, texto: str):

335 self.texto = texto

336

337 def preencher_pagina(self, pagina: int):

338 self.pagina = pagina

339

340 def preencher_tam_pagina(self, tam_pagina: int):

341 self.tam_pagina = tam_pagina

342

343 def preencher_status(self, status: Id | Status):

344 self.status = status

345

346 def preencher_instrumentos_convocatorios(

347 self, instrumentos_convocatorios: Iterable[Id] | Iterable[InstrumentoConvocatorio]

348 ):

349 self.instrumentos_convocatorios = instrumentos_convocatorios

350

351 def preencher_modalidades_de_contratacao(

352 self, modalidades_de_contratacao: Iterable[Id] | Iterable[ModalidadeDeContratacao]

353 ):

354 self.modalidades_de_contratacao = modalidades_de_contratacao

355

356 def preencher_orgaos(self, orgaos: Iterable[Id] | Iterable[Orgao]):

357 self.orgaos = orgaos

358

359 def preencher_unidades(self, unidades: Iterable[Id] | Iterable[Unidade]):

360 self.unidades = unidades

361

362 def preencher_ufs(self, ufs: Iterable[Id] | Iterable[UnidadeDaFederacao]):

363 self.ufs = ufs

364

365 def preencher_municipios(self, municipios: Iterable[Id] | Iterable[Municipio]):

366 self.municipios = municipios

367

368 def preencher_esferas(self, esferas: Iterable[Id] | Iterable[Esfera]):

369 self.esferas = esferas

370

371 def preencher_poderes(self, poderes: Iterable[Id] | Iterable[Poder]):

372 self.poderes = poderes

373

374 def preencher_anos(self, anos: Iterable[Id] | Iterable[Ano]):

375 self.anos = anos

376

377 def preencher_fontes_orcamentarias(

378 self, fontes_orcamentarias: Iterable[Id] | Iterable[FonteOrcamentaria]

379 ):

380 self.fontes_orcamentarias = fontes_orcamentarias

381

382 def preencher(

383 self,

384 texto: str | None = None,

385 pagina: int | None = None,

386 tam_pagina: int | None = None,

387 status: Id | Status | None = None,

388 instrumentos_convocatorios: Iterable[Id] | Iterable[InstrumentoConvocatorio] | None = None,

389 modalidades_de_contratacao: Iterable[Id] | Iterable[ModalidadeDeContratacao] | None = None,

390 orgaos: Iterable[Id] | Iterable[Orgao] | None = None,

391 unidades: Iterable[Id] | Iterable[Unidade] | None = None,

392 ufs: Iterable[Id] | Iterable[UnidadeDaFederacao] | None = None,

393 municipios: Iterable[Id] | Iterable[Municipio] | None = None,

394 esferas: Iterable[Id] | Iterable[Esfera] | None = None,

395 poderes: Iterable[Id] | Iterable[Poder] | None = None,

396 anos: Iterable[Id] | Iterable[Ano] | None = None,

397 fontes_orcamentarias: Iterable[Id] | Iterable[FonteOrcamentaria] | None = None,

398 ):

399 kwargs = {k: v for k, v in locals().items() if k != "self" and v is not None}

400 for key, value in kwargs.items():

401 setattr(self, key, value)

402

403 def buscar(self):

404 return self.resultados