Coverage for src\pncp\instrumentos_convocatorios\busca.py: 100%
212 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-07-22 21:34 -0300
« prev ^ index » next coverage.py v7.8.0, created at 2025-07-22 21:34 -0300
1from typing import Iterable
3import pncp.utils
4from pncp.tipos import Lista
6from .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)
24class Busca:
25 _url_filtros = "https://pncp.gov.br/api/search/filters?tipos_documento=edital"
26 _url_busca = "https://pncp.gov.br/api/search"
28 def __init__(self):
29 self._filtros = None
30 self._campos_de_busca = CamposDeBusca()
31 self._resultados: Lista[Resultado] | None = None
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"]
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.")
42 def listar_status(self) -> Lista[Status]:
43 return Status.listar()
45 def listar_instrumentos_convocatorios(self) -> Lista[InstrumentoConvocatorio]:
46 self._carregar_filtros()
48 if not self._filtros or "tipos" not in self._filtros:
49 return Lista()
51 return Lista(
52 InstrumentoConvocatorio(**instrumento_convocatorio)
53 for instrumento_convocatorio in self._filtros["tipos"]
54 )
56 def listar_modalidades_de_contratacao(self) -> Lista[ModalidadeDeContratacao]:
57 self._carregar_filtros()
59 if not self._filtros or "modalidades" not in self._filtros:
60 return Lista()
62 return Lista(
63 ModalidadeDeContratacao(**modalidade_de_contratacao)
64 for modalidade_de_contratacao in self._filtros["modalidades"]
65 )
67 def listar_orgaos(self) -> Lista[Orgao]:
68 self._carregar_filtros()
70 if not self._filtros or "orgaos" not in self._filtros:
71 return Lista()
73 return Lista(Orgao(**orgao) for orgao in self._filtros["orgaos"])
75 def listar_unidades(self) -> Lista[Unidade]:
76 self._carregar_filtros()
78 if not self._filtros or "unidades" not in self._filtros:
79 return Lista()
81 return Lista(Unidade(**unidade) for unidade in self._filtros["unidades"])
83 def listar_ufs(self) -> Lista[UnidadeDaFederacao]:
84 self._carregar_filtros()
86 if not self._filtros or "ufs" not in self._filtros:
87 return Lista()
89 return Lista(UnidadeDaFederacao(**uf) for uf in self._filtros["ufs"])
91 def listar_municipios(self) -> Lista[Municipio]:
92 self._carregar_filtros()
94 if not self._filtros or "municipios" not in self._filtros:
95 return Lista()
97 return Lista(Municipio(**municipio) for municipio in self._filtros["municipios"])
99 def listar_esferas(self) -> Lista[Esfera]:
100 self._carregar_filtros()
102 if not self._filtros or "esferas" not in self._filtros:
103 return Lista()
105 return Lista(Esfera(**esfera) for esfera in self._filtros["esferas"])
107 def listar_poderes(self) -> Lista[Poder]:
108 self._carregar_filtros()
110 if not self._filtros or "poderes" not in self._filtros:
111 return Lista()
113 return Lista(Poder(**poder) for poder in self._filtros["poderes"])
115 def listar_anos(self) -> Lista[Ano]:
116 self._carregar_filtros()
118 if not self._filtros or "anos" not in self._filtros:
119 return Lista()
121 return Lista(Ano(**ano) for ano in self._filtros["anos"])
123 def listar_fontes_orcamentarias(self) -> Lista[FonteOrcamentaria]:
124 self._carregar_filtros()
126 if not self._filtros or "fontes_orcamentarias" not in self._filtros:
127 return Lista()
129 return Lista(
130 FonteOrcamentaria(**fonte_orcamentaria)
131 for fonte_orcamentaria in self._filtros["fontes_orcamentarias"]
132 )
134 @property
135 def texto(self) -> str:
136 return self._campos_de_busca.q
138 @property
139 def pagina(self) -> int:
140 return self._campos_de_busca.pagina
142 @property
143 def tam_pagina(self) -> int:
144 return self._campos_de_busca.tam_pagina
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 )
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 )
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 )
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 )
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 )
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)
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 )
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 )
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 )
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)
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 )
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
231 @texto.setter
232 def texto(self, texto: str):
233 self._verificar_se_existem_resultados()
234 self._campos_de_busca.q = texto
236 @pagina.setter
237 def pagina(self, pagina: int):
238 self._verificar_se_existem_resultados()
239 self._campos_de_busca.pagina = pagina
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
246 @status.setter
247 def status(self, status: Id | Status):
248 self._verificar_se_existem_resultados()
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}")
255 self._campos_de_busca.status = status_id
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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 )
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)
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 )
334 def preencher_texto(self, texto: str):
335 self.texto = texto
337 def preencher_pagina(self, pagina: int):
338 self.pagina = pagina
340 def preencher_tam_pagina(self, tam_pagina: int):
341 self.tam_pagina = tam_pagina
343 def preencher_status(self, status: Id | Status):
344 self.status = status
346 def preencher_instrumentos_convocatorios(
347 self, instrumentos_convocatorios: Iterable[Id] | Iterable[InstrumentoConvocatorio]
348 ):
349 self.instrumentos_convocatorios = instrumentos_convocatorios
351 def preencher_modalidades_de_contratacao(
352 self, modalidades_de_contratacao: Iterable[Id] | Iterable[ModalidadeDeContratacao]
353 ):
354 self.modalidades_de_contratacao = modalidades_de_contratacao
356 def preencher_orgaos(self, orgaos: Iterable[Id] | Iterable[Orgao]):
357 self.orgaos = orgaos
359 def preencher_unidades(self, unidades: Iterable[Id] | Iterable[Unidade]):
360 self.unidades = unidades
362 def preencher_ufs(self, ufs: Iterable[Id] | Iterable[UnidadeDaFederacao]):
363 self.ufs = ufs
365 def preencher_municipios(self, municipios: Iterable[Id] | Iterable[Municipio]):
366 self.municipios = municipios
368 def preencher_esferas(self, esferas: Iterable[Id] | Iterable[Esfera]):
369 self.esferas = esferas
371 def preencher_poderes(self, poderes: Iterable[Id] | Iterable[Poder]):
372 self.poderes = poderes
374 def preencher_anos(self, anos: Iterable[Id] | Iterable[Ano]):
375 self.anos = anos
377 def preencher_fontes_orcamentarias(
378 self, fontes_orcamentarias: Iterable[Id] | Iterable[FonteOrcamentaria]
379 ):
380 self.fontes_orcamentarias = fontes_orcamentarias
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)
403 def buscar(self):
404 return self.resultados