fix netwo elig
This commit is contained in:
parent
3c01837ec3
commit
0c2213ce46
9 changed files with 4172 additions and 74 deletions
3672
webapp/elig.json
Normal file
3672
webapp/elig.json
Normal file
File diff suppressed because it is too large
Load diff
56
webapp/eligibility_api/api_doc.py
Normal file
56
webapp/eligibility_api/api_doc.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
from apispec.ext.marshmallow import MarshmallowPlugin
|
||||||
|
from apispec_webframeworks.flask import FlaskPlugin
|
||||||
|
|
||||||
|
from flasgger import APISpec, Schema, Swagger, fields
|
||||||
|
|
||||||
|
from eligibility_api.elig_api_exceptions import SwaggerValidationException
|
||||||
|
|
||||||
|
|
||||||
|
def _swagger_validation_error_handler(err, data, _):
|
||||||
|
print("API swagger error 400")
|
||||||
|
raise SwaggerValidationException(err, data)
|
||||||
|
|
||||||
|
|
||||||
|
def start_swagger(flask_app):
|
||||||
|
"""
|
||||||
|
Creates swagger /apidocs endpoint and adds it to flask app
|
||||||
|
"""
|
||||||
|
|
||||||
|
flask_app.config["SWAGGER"] = {
|
||||||
|
"uiversion": 3,
|
||||||
|
"ui_params": {
|
||||||
|
"apisSorter": "alpha",
|
||||||
|
"operationsSorter": "alpha",
|
||||||
|
"tagsSorter": "alpha",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create an APISpec
|
||||||
|
spec = APISpec(
|
||||||
|
title="API éligibilité",
|
||||||
|
version="0.1.0",
|
||||||
|
openapi_version="2.0",
|
||||||
|
plugins=(
|
||||||
|
FlaskPlugin(),
|
||||||
|
MarshmallowPlugin(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
template = spec.to_flasgger(
|
||||||
|
flask_app,
|
||||||
|
definitions=[
|
||||||
|
# ContributionSchema,
|
||||||
|
# PredictConfigSchema,
|
||||||
|
# VersionSchema,
|
||||||
|
# PredictInputsSchema,
|
||||||
|
# ImplementedModelSchema,
|
||||||
|
# ApiErrorSchema,
|
||||||
|
# LoggingHealthCheckSchema,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
Swagger(
|
||||||
|
flask_app,
|
||||||
|
template=template,
|
||||||
|
parse=True,
|
||||||
|
validation_error_handler=_swagger_validation_error_handler,
|
||||||
|
)
|
|
@ -23,6 +23,18 @@ class NetwoApiErrorException(Exception):
|
||||||
self.description = description
|
self.description = description
|
||||||
|
|
||||||
|
|
||||||
|
class SwaggerValidationException(Exception):
|
||||||
|
"""
|
||||||
|
Exception thrown if API misused
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, err, data):
|
||||||
|
self.code = 400
|
||||||
|
self.name = "Error from Swagger API validation"
|
||||||
|
self.description = str(err)
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
|
||||||
class FlaskExceptions:
|
class FlaskExceptions:
|
||||||
"""
|
"""
|
||||||
Manages flask custom exceptions
|
Manages flask custom exceptions
|
||||||
|
@ -61,3 +73,17 @@ class FlaskExceptions:
|
||||||
),
|
),
|
||||||
500,
|
500,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@self.flask_app.errorhandler(SwaggerValidationException)
|
||||||
|
def handle_exception(e):
|
||||||
|
return (
|
||||||
|
jsonify(
|
||||||
|
{
|
||||||
|
"code": e.code,
|
||||||
|
"name": e.name,
|
||||||
|
"description": e.description,
|
||||||
|
"data": e.data,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
400,
|
||||||
|
)
|
||||||
|
|
|
@ -2,9 +2,8 @@ from flask import Flask, request
|
||||||
|
|
||||||
from coordinates import check_coordinates_args, adapt_coordinates_to_max_area
|
from coordinates import check_coordinates_args, adapt_coordinates_to_max_area
|
||||||
from eligibility_api.elig_api_exceptions import ApiParamException
|
from eligibility_api.elig_api_exceptions import ApiParamException
|
||||||
from ipe_fetcher import NetwooEligibility, FAIEligibilityStatus
|
|
||||||
from ipe_fetcher.axione import AXIONE_MAX_AREA, Axione
|
from ipe_fetcher.axione import AXIONE_MAX_AREA, Axione
|
||||||
from netwo.netwo import Netwo
|
from netwo.netwo import Netwo, NetwooEligibility, NETWO_DEPLOYED_STATUS
|
||||||
|
|
||||||
|
|
||||||
class EligibilityApiRoutes:
|
class EligibilityApiRoutes:
|
||||||
|
@ -39,30 +38,92 @@ class EligibilityApiRoutes:
|
||||||
|
|
||||||
@self.flask_app.route("/eligibilite/netwo", methods=["GET"])
|
@self.flask_app.route("/eligibilite/netwo", methods=["GET"])
|
||||||
def get_netwo_eligibility():
|
def get_netwo_eligibility():
|
||||||
|
"""
|
||||||
|
Intérroge l'éligibilité Netwo
|
||||||
|
---
|
||||||
|
tags:
|
||||||
|
- API
|
||||||
|
description: |
|
||||||
|
Déclenche une recherche d'éligibilité chez Netwo:
|
||||||
|
- soit par une ref d'immeuble
|
||||||
|
- soit par les coordonnées d'un immeuble
|
||||||
|
La recherche est longue, l'API renvoie un event stream qui renvoie un statut toutes les secondes
|
||||||
|
Il est possible de retrouver les résultats d'une éligibilité via son ID.
|
||||||
|
Par défaut on renvoie uniquement les offres ftth, il est possible via ftto=true d'ajouter la ftto
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: ftto
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
nullable: true
|
||||||
|
allowEmptyValue: true
|
||||||
|
description: |
|
||||||
|
Si 'ftto' set alors on rajoutera les résultats FTTO à la recherche
|
||||||
|
- in: query
|
||||||
|
name: timeout_sec
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: int
|
||||||
|
nullable: false
|
||||||
|
allowEmptyValue: false
|
||||||
|
description: |
|
||||||
|
Timeout au bout du quel on retourne les offres trouvées même si la recherche n'est pas terminée
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: Retourne le statut d'éligibilité et d'éventuelles offres
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/Contribution'
|
||||||
|
examples:
|
||||||
|
application/json:
|
||||||
|
400:
|
||||||
|
description: Bad inputs
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ApiError'
|
||||||
|
examples:
|
||||||
|
application/json:
|
||||||
|
code: 400
|
||||||
|
name: Bad input parameter
|
||||||
|
description: Bad json format
|
||||||
|
500:
|
||||||
|
description: Erreur lors d'un appel à l'API de Netwo
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/ApiError'
|
||||||
|
examples:
|
||||||
|
application/json:
|
||||||
|
netwo_status_code: 404
|
||||||
|
name: Error contacting Netwo API
|
||||||
|
description: ID not found
|
||||||
|
"""
|
||||||
args = request.args
|
args = request.args
|
||||||
ref_imb = args.get("ref_imb")
|
ref_imb = args.get("ref_imb")
|
||||||
lat = args.get("lat")
|
elig_id = args.get("id")
|
||||||
lng = args.get("lng")
|
|
||||||
timeout_sec = None
|
timeout_sec = None
|
||||||
search_ftto = args.get("ftto", "False").lower() == "true"
|
search_ftto = args.get("ftto") is not None
|
||||||
|
|
||||||
|
imb_info = self.netwo.get_netwo_imb_coordinates(ref_imb)
|
||||||
|
if elig_id:
|
||||||
|
elig_offers = self.netwo.get_netwo_eligibility_results(
|
||||||
|
elig_id, search_ftto
|
||||||
|
)
|
||||||
|
return NetwooEligibility(
|
||||||
|
imb_info=imb_info,
|
||||||
|
eligOffers=elig_offers,
|
||||||
|
eligDone=True,
|
||||||
|
elig_id=elig_id,
|
||||||
|
)
|
||||||
|
|
||||||
if args.get("timeout_sec"):
|
if args.get("timeout_sec"):
|
||||||
try:
|
try:
|
||||||
timeout_sec = int(args.get("timeout_sec"))
|
timeout_sec = int(args.get("timeout_sec"))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise ApiParamException("timeout_sec param must be an integer")
|
raise ApiParamException("timeout_sec param must be an integer")
|
||||||
elig_status = (
|
|
||||||
FAIEligibilityStatus(
|
if imb_info.get("imb_status") != NETWO_DEPLOYED_STATUS:
|
||||||
isEligible=True, ftthStatus="Deployed", reasonNotEligible=""
|
|
||||||
),
|
|
||||||
)
|
|
||||||
if ref_imb:
|
|
||||||
elig_status, lat, lng = self.netwo.get_netwo_imb_coordinates(
|
|
||||||
args["ref_imb"]
|
|
||||||
)
|
|
||||||
if not elig_status.get("isEligible"):
|
|
||||||
return NetwooEligibility(
|
return NetwooEligibility(
|
||||||
eligStatus=elig_status,
|
imb_info=imb_info,
|
||||||
)
|
)
|
||||||
|
print(f"start elig with {imb_info}")
|
||||||
return self.netwo.start_netwo_eligibility(
|
return self.netwo.start_netwo_eligibility(
|
||||||
lat, lng, elig_status, search_ftto, timeout_sec
|
imb_info, search_ftto, timeout_sec
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,15 +30,3 @@ class AreaCoordinates(TypedDict):
|
||||||
swy: float
|
swy: float
|
||||||
nex: float
|
nex: float
|
||||||
ney: float
|
ney: float
|
||||||
|
|
||||||
|
|
||||||
class NetwooEligibility(TypedDict):
|
|
||||||
eligStatus: FAIEligibilityStatus
|
|
||||||
eligDone: NotRequired[bool]
|
|
||||||
nbOperatorsOk: NotRequired[int]
|
|
||||||
nbOperatorsErrors: NotRequired[int]
|
|
||||||
nbOperatorsPending: NotRequired[int]
|
|
||||||
totalOperators: NotRequired[int]
|
|
||||||
timeoutSec: NotRequired[int]
|
|
||||||
timeoutReached: NotRequired[bool]
|
|
||||||
eligOffers: NotRequired[dict]
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from typing import TypedDict
|
||||||
|
|
||||||
from flask import Flask, request, render_template, redirect
|
from flask import Flask, request, render_template, redirect
|
||||||
|
|
||||||
|
from eligibility_api.api_doc import start_swagger
|
||||||
from eligibility_api.elig_api_exceptions import FlaskExceptions
|
from eligibility_api.elig_api_exceptions import FlaskExceptions
|
||||||
from eligibility_api.elig_api_routes import EligibilityApiRoutes
|
from eligibility_api.elig_api_routes import EligibilityApiRoutes
|
||||||
from ipe_fetcher import Liazo, Axione, Arcep, AreaCoordinates
|
from ipe_fetcher import Liazo, Axione, Arcep, AreaCoordinates
|
||||||
|
@ -102,3 +103,6 @@ def testFtth():
|
||||||
liazoOk = args["liazo"]
|
liazoOk = args["liazo"]
|
||||||
pto_url = f"https://tools.aquilenet.fr/cgi-bin/recherchepto.cgi?refimmeuble={idImm}&cp={codePostal}&axione={axioneOk}&liazo={liazoOk}"
|
pto_url = f"https://tools.aquilenet.fr/cgi-bin/recherchepto.cgi?refimmeuble={idImm}&cp={codePostal}&axione={axioneOk}&liazo={liazoOk}"
|
||||||
return redirect(pto_url)
|
return redirect(pto_url)
|
||||||
|
|
||||||
|
|
||||||
|
# start_swagger(app)
|
||||||
|
|
|
@ -3,13 +3,27 @@ import requests
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
|
from typing_extensions import NotRequired, TypedDict
|
||||||
|
|
||||||
from eligibility_api.elig_api_exceptions import NetwoApiErrorException
|
from eligibility_api.elig_api_exceptions import NetwoApiErrorException
|
||||||
from ipe_fetcher import FAIEligibilityStatus, NetwooEligibility
|
from ipe_fetcher import FAIEligibilityStatus
|
||||||
|
|
||||||
NETWO_DEPLOYED_STATUS = "Deployed"
|
NETWO_DEPLOYED_STATUS = "Deployed"
|
||||||
|
|
||||||
|
|
||||||
|
class NetwooEligibility(TypedDict):
|
||||||
|
imb_info: NotRequired[dict]
|
||||||
|
eligDone: NotRequired[bool]
|
||||||
|
eligId: NotRequired[str]
|
||||||
|
nbOperatorsOk: NotRequired[int]
|
||||||
|
nbOperatorsErrors: NotRequired[int]
|
||||||
|
nbOperatorsPending: NotRequired[int]
|
||||||
|
totalOperators: NotRequired[int]
|
||||||
|
timeoutSec: NotRequired[int]
|
||||||
|
timeoutReached: NotRequired[bool]
|
||||||
|
eligOffers: NotRequired[dict]
|
||||||
|
|
||||||
|
|
||||||
class Netwo:
|
class Netwo:
|
||||||
def __init__(self, netwo_api_key: str):
|
def __init__(self, netwo_api_key: str):
|
||||||
self.netwo_api_headers = {
|
self.netwo_api_headers = {
|
||||||
|
@ -18,9 +32,7 @@ class Netwo:
|
||||||
"Accept": "application/json",
|
"Accept": "application/json",
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_netwo_imb_coordinates(
|
def get_netwo_imb_coordinates(self, ref_imb: str) -> dict:
|
||||||
self, ref_imb: str
|
|
||||||
) -> (FAIEligibilityStatus, str, str):
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param ref_imb: ARCEP ref of immeuble
|
:param ref_imb: ARCEP ref of immeuble
|
||||||
|
@ -38,21 +50,7 @@ class Netwo:
|
||||||
f"Could not GET netwo imb ref {ref_imb}", status_code
|
f"Could not GET netwo imb ref {ref_imb}", status_code
|
||||||
)
|
)
|
||||||
imb_payload = response.json()
|
imb_payload = response.json()
|
||||||
imb_status = imb_payload.get("imb_status")
|
return imb_payload
|
||||||
elig_status = FAIEligibilityStatus(
|
|
||||||
isEligible=imb_status == NETWO_DEPLOYED_STATUS,
|
|
||||||
ftthStatus=imb_status,
|
|
||||||
reasonNotEligible="",
|
|
||||||
)
|
|
||||||
|
|
||||||
if imb_status != NETWO_DEPLOYED_STATUS:
|
|
||||||
elig_status[
|
|
||||||
"reasonNotEligible"
|
|
||||||
] = f'Ftth not yet deployed in immeuble ref {ref_imb} (PM status: {imb_payload.get("pm_status")})'
|
|
||||||
|
|
||||||
lat = str(response.json().get("lat"))
|
|
||||||
lng = str(response.json().get("lng"))
|
|
||||||
return elig_status, lat, lng
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _filter_netwo_raw_elig_results(raw_elig: dict, search_ftto: bool) -> list:
|
def _filter_netwo_raw_elig_results(raw_elig: dict, search_ftto: bool) -> list:
|
||||||
|
@ -62,10 +60,8 @@ class Netwo:
|
||||||
inf_search.append("ftto")
|
inf_search.append("ftto")
|
||||||
for r in raw_elig.get("results"):
|
for r in raw_elig.get("results"):
|
||||||
inf_type = r.get("infrastructure_type")
|
inf_type = r.get("infrastructure_type")
|
||||||
print(f'{r.get("infrastructure_operator")} : {inf_type}')
|
|
||||||
if inf_type not in inf_search:
|
if inf_type not in inf_search:
|
||||||
continue
|
continue
|
||||||
elig_id = r.get("eligibility_id")
|
|
||||||
product_id = r.get("product_id")
|
product_id = r.get("product_id")
|
||||||
operator = r.get("infrastructure_operator")
|
operator = r.get("infrastructure_operator")
|
||||||
product = r.get("product_name")
|
product = r.get("product_name")
|
||||||
|
@ -78,7 +74,6 @@ class Netwo:
|
||||||
commitment_duration = offer.get("commitment_duration") or 0
|
commitment_duration = offer.get("commitment_duration") or 0
|
||||||
filtered_elig.append(
|
filtered_elig.append(
|
||||||
{
|
{
|
||||||
"eligibility_id": elig_id,
|
|
||||||
"entity_id": entity_id,
|
"entity_id": entity_id,
|
||||||
"product_id": product_id,
|
"product_id": product_id,
|
||||||
"product": f"{product} - {offer_name}",
|
"product": f"{product} - {offer_name}",
|
||||||
|
@ -98,17 +93,28 @@ class Netwo:
|
||||||
)
|
)
|
||||||
return sort_elig
|
return sort_elig
|
||||||
|
|
||||||
|
def get_netwo_eligibility_results(self, elig_id: str, search_ftto: bool):
|
||||||
|
response = requests.get(
|
||||||
|
f"https://api.netwo.io/api/v1/eligibility/{elig_id}",
|
||||||
|
headers=self.netwo_api_headers,
|
||||||
|
)
|
||||||
|
status_code = response.status_code
|
||||||
|
if status_code != 200:
|
||||||
|
raise NetwoApiErrorException(
|
||||||
|
f"Netwo API: Could not get eligibility results for ID {elig_id}",
|
||||||
|
status_code,
|
||||||
|
)
|
||||||
|
return self._filter_netwo_raw_elig_results(response.json(), search_ftto)
|
||||||
|
|
||||||
def start_netwo_eligibility(
|
def start_netwo_eligibility(
|
||||||
self,
|
self,
|
||||||
imb_lat: str,
|
imb_info: str,
|
||||||
imb_long: str,
|
|
||||||
elig_status: FAIEligibilityStatus,
|
|
||||||
search_ftto: bool,
|
search_ftto: bool,
|
||||||
timeout_sec: None,
|
timeout_sec: None,
|
||||||
):
|
):
|
||||||
def event_stream():
|
def event_stream():
|
||||||
netwo_elig = NetwooEligibility(
|
netwo_elig = NetwooEligibility(
|
||||||
eligStatus=elig_status,
|
eligId="",
|
||||||
eligDone=False,
|
eligDone=False,
|
||||||
nbOperatorsOk=0,
|
nbOperatorsOk=0,
|
||||||
nbOperatorsErrors=0,
|
nbOperatorsErrors=0,
|
||||||
|
@ -117,8 +123,11 @@ class Netwo:
|
||||||
timeoutSec=timeout_sec,
|
timeoutSec=timeout_sec,
|
||||||
eligOffers={},
|
eligOffers={},
|
||||||
)
|
)
|
||||||
json_data = {"latitude": imb_lat, "longitude": imb_long}
|
json_data = {
|
||||||
|
"latitude": str(imb_info.get("lat")),
|
||||||
|
"longitude": str(imb_info.get("lng")),
|
||||||
|
}
|
||||||
|
print(json_data)
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
"https://api.netwo.io/api/v1/eligibility/preselect",
|
"https://api.netwo.io/api/v1/eligibility/preselect",
|
||||||
headers=self.netwo_api_headers,
|
headers=self.netwo_api_headers,
|
||||||
|
@ -126,7 +135,7 @@ class Netwo:
|
||||||
)
|
)
|
||||||
status_code = response.status_code
|
status_code = response.status_code
|
||||||
if status_code != 200:
|
if status_code != 200:
|
||||||
print("raise preselect except")
|
print(f"raise preselect except {response.text}")
|
||||||
raise NetwoApiErrorException(
|
raise NetwoApiErrorException(
|
||||||
"Netwo API eligibility preselect step failed", status_code
|
"Netwo API eligibility preselect step failed", status_code
|
||||||
)
|
)
|
||||||
|
@ -134,6 +143,10 @@ class Netwo:
|
||||||
default = resp.get("default")
|
default = resp.get("default")
|
||||||
default["offer_type"] = "enterprise"
|
default["offer_type"] = "enterprise"
|
||||||
default["market"] = "service_operator"
|
default["market"] = "service_operator"
|
||||||
|
default["ftth_payload"] = {
|
||||||
|
"imb_ref": imb_info.get("imb_id"),
|
||||||
|
"pm_ref": imb_info.get("pm_id"),
|
||||||
|
}
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
"https://api.netwo.io/api/v1/eligibility",
|
"https://api.netwo.io/api/v1/eligibility",
|
||||||
headers=self.netwo_api_headers,
|
headers=self.netwo_api_headers,
|
||||||
|
@ -146,6 +159,7 @@ class Netwo:
|
||||||
"Netwo API: failed to start eligibility", status_code
|
"Netwo API: failed to start eligibility", status_code
|
||||||
)
|
)
|
||||||
id_elig = response.json().get("id")
|
id_elig = response.json().get("id")
|
||||||
|
netwo_elig["eligId"] = id_elig
|
||||||
is_done = False
|
is_done = False
|
||||||
|
|
||||||
timeout = None
|
timeout = None
|
||||||
|
@ -189,22 +203,11 @@ class Netwo:
|
||||||
else:
|
else:
|
||||||
is_done = True
|
is_done = True
|
||||||
|
|
||||||
response = requests.get(
|
netwo_elig["eligOffers"] = self.get_netwo_eligibility_results(
|
||||||
f"https://api.netwo.io/api/v1/eligibility/{id_elig}",
|
id_elig, search_ftto
|
||||||
headers=self.netwo_api_headers,
|
|
||||||
)
|
)
|
||||||
status_code = response.status_code
|
|
||||||
if status_code != 200:
|
|
||||||
print("raise elig res except")
|
|
||||||
raise NetwoApiErrorException(
|
|
||||||
f"Netwo API: Could not get eligibility results for ID {id_elig}",
|
|
||||||
status_code,
|
|
||||||
)
|
|
||||||
netwo_elig["eligOffers"] = self._filter_netwo_raw_elig_results(
|
|
||||||
response.json(), search_ftto
|
|
||||||
)
|
|
||||||
|
|
||||||
netwo_elig["eligDone"] = True
|
netwo_elig["eligDone"] = True
|
||||||
|
netwo_elig["imb_info"] = imb_info
|
||||||
yield json.dumps(netwo_elig, indent=2)
|
yield json.dumps(netwo_elig, indent=2)
|
||||||
|
|
||||||
return Response(event_stream(), mimetype="text/event-stream")
|
return Response(event_stream(), mimetype="text/event-stream")
|
||||||
|
|
285
webapp/poetry.lock
generated
285
webapp/poetry.lock
generated
|
@ -1,3 +1,66 @@
|
||||||
|
[[package]]
|
||||||
|
name = "aniso8601"
|
||||||
|
version = "9.0.1"
|
||||||
|
description = "A library for parsing ISO 8601 strings."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["black", "coverage", "isort", "pre-commit", "pyenchant", "pylint"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "apispec"
|
||||||
|
version = "6.1.0"
|
||||||
|
description = "A pluggable API specification generator. Currently supports the OpenAPI Specification (f.k.a. the Swagger specification)."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
packaging = ">=21.3"
|
||||||
|
PyYAML = {version = ">=3.10", optional = true, markers = "extra == \"yaml\""}
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["PyYAML (>=3.10)", "flake8 (==5.0.4)", "flake8-bugbear (==22.9.23)", "marshmallow (>=3.13.0)", "mypy (==0.982)", "openapi-spec-validator (<0.5)", "prance[osv] (>=0.11)", "pre-commit (>=2.4,<3.0)", "pytest", "tox", "types-PyYAML"]
|
||||||
|
docs = ["marshmallow (>=3.13.0)", "pyyaml (==6.0)", "sphinx (==5.2.3)", "sphinx-issues (==3.0.1)", "sphinx-rtd-theme (==1.0.0)"]
|
||||||
|
lint = ["flake8 (==5.0.4)", "flake8-bugbear (==22.9.23)", "mypy (==0.982)", "pre-commit (>=2.4,<3.0)", "types-PyYAML"]
|
||||||
|
marshmallow = ["marshmallow (>=3.18.0)"]
|
||||||
|
tests = ["PyYAML (>=3.10)", "marshmallow (>=3.13.0)", "openapi-spec-validator (<0.5)", "prance[osv] (>=0.11)", "pytest"]
|
||||||
|
validation = ["openapi-spec-validator (<0.5)", "prance[osv] (>=0.11)"]
|
||||||
|
yaml = ["PyYAML (>=3.10)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "apispec-webframeworks"
|
||||||
|
version = "0.5.2"
|
||||||
|
description = "Web framework plugins for apispec."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
apispec = {version = ">=2.0.0", extras = ["yaml"]}
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["Flask (==1.1.1)", "bottle (==0.12.17)", "flake8 (==3.7.9)", "flake8-bugbear (==19.8.0)", "mock", "pre-commit (>=1.18,<2.0)", "pytest", "tornado", "tox"]
|
||||||
|
lint = ["flake8 (==3.7.9)", "flake8-bugbear (==19.8.0)", "pre-commit (>=1.18,<2.0)"]
|
||||||
|
tests = ["Flask (==1.1.1)", "bottle (==0.12.17)", "mock", "pytest", "tornado"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "attrs"
|
||||||
|
version = "22.2.0"
|
||||||
|
description = "Classes Without Boilerplate"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"]
|
||||||
|
dev = ["attrs[docs,tests]"]
|
||||||
|
docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"]
|
||||||
|
tests = ["attrs[tests-no-zope]", "zope.interface"]
|
||||||
|
tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "black"
|
name = "black"
|
||||||
version = "23.1.0"
|
version = "23.1.0"
|
||||||
|
@ -56,6 +119,21 @@ category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flasgger"
|
||||||
|
version = "0.9.5"
|
||||||
|
description = "Extract swagger specs from your flask project"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
Flask = ">=0.10"
|
||||||
|
jsonschema = ">=3.0.1"
|
||||||
|
mistune = "*"
|
||||||
|
PyYAML = ">=3.0"
|
||||||
|
six = ">=1.10.0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flask"
|
name = "flask"
|
||||||
version = "2.2.2"
|
version = "2.2.2"
|
||||||
|
@ -75,6 +153,23 @@ Werkzeug = ">=2.2.2"
|
||||||
async = ["asgiref (>=3.2)"]
|
async = ["asgiref (>=3.2)"]
|
||||||
dotenv = ["python-dotenv"]
|
dotenv = ["python-dotenv"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flask-restful"
|
||||||
|
version = "0.3.9"
|
||||||
|
description = "Simple framework for creating REST APIs"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
aniso8601 = ">=0.82"
|
||||||
|
Flask = ">=0.8"
|
||||||
|
pytz = "*"
|
||||||
|
six = ">=1.3.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
docs = ["sphinx"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gunicorn"
|
name = "gunicorn"
|
||||||
version = "20.1.0"
|
version = "20.1.0"
|
||||||
|
@ -138,6 +233,22 @@ MarkupSafe = ">=2.0"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
i18n = ["Babel (>=2.7)"]
|
i18n = ["Babel (>=2.7)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jsonschema"
|
||||||
|
version = "4.17.3"
|
||||||
|
description = "An implementation of JSON Schema validation for Python"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
attrs = ">=17.4.0"
|
||||||
|
pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"]
|
||||||
|
format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markupsafe"
|
name = "markupsafe"
|
||||||
version = "2.1.1"
|
version = "2.1.1"
|
||||||
|
@ -146,6 +257,31 @@ category = "main"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "marshmallow"
|
||||||
|
version = "3.19.0"
|
||||||
|
description = "A lightweight library for converting complex datatypes to and from native Python datatypes."
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
packaging = ">=17.0"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
dev = ["flake8 (==5.0.4)", "flake8-bugbear (==22.10.25)", "mypy (==0.990)", "pre-commit (>=2.4,<3.0)", "pytest", "pytz", "simplejson", "tox"]
|
||||||
|
docs = ["alabaster (==0.7.12)", "autodocsumm (==0.2.9)", "sphinx (==5.3.0)", "sphinx-issues (==3.0.1)", "sphinx-version-warning (==1.1.2)"]
|
||||||
|
lint = ["flake8 (==5.0.4)", "flake8-bugbear (==22.10.25)", "mypy (==0.990)", "pre-commit (>=2.4,<3.0)"]
|
||||||
|
tests = ["pytest", "pytz", "simplejson"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mistune"
|
||||||
|
version = "2.0.5"
|
||||||
|
description = "A sane Markdown parser with useful plugins and renderers"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mypy-extensions"
|
name = "mypy-extensions"
|
||||||
version = "1.0.0"
|
version = "1.0.0"
|
||||||
|
@ -190,6 +326,30 @@ python-versions = ">=3.7"
|
||||||
docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
|
docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
|
||||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
|
test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyrsistent"
|
||||||
|
version = "0.19.3"
|
||||||
|
description = "Persistent/Functional/Immutable data structures"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pytz"
|
||||||
|
version = "2022.7.1"
|
||||||
|
description = "World timezone definitions, modern and historical"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pyyaml"
|
||||||
|
version = "6.0"
|
||||||
|
description = "YAML parser and emitter for Python"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests"
|
name = "requests"
|
||||||
version = "2.28.2"
|
version = "2.28.2"
|
||||||
|
@ -221,6 +381,14 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g
|
||||||
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
||||||
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "six"
|
||||||
|
version = "1.16.0"
|
||||||
|
description = "Python 2 and 3 compatibility utilities"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tomli"
|
name = "tomli"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
|
@ -279,9 +447,25 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools"
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.9"
|
python-versions = "^3.9"
|
||||||
content-hash = "1f4a05abb33873e8733b0fc1945b4c1f2ffa4792eddb7edc3dd0007fd78522af"
|
content-hash = "808253c094a03d4591f9504fee2876cfe5efe4b63ca89b47813fbc63e8cb7de7"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
|
aniso8601 = [
|
||||||
|
{file = "aniso8601-9.0.1-py2.py3-none-any.whl", hash = "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f"},
|
||||||
|
{file = "aniso8601-9.0.1.tar.gz", hash = "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973"},
|
||||||
|
]
|
||||||
|
apispec = [
|
||||||
|
{file = "apispec-6.1.0-py3-none-any.whl", hash = "sha256:937d7f11be6e80cf6d0b66c12dbc29604435302b529b3a9bdb5e2dee192d2f17"},
|
||||||
|
{file = "apispec-6.1.0.tar.gz", hash = "sha256:881d3b90bfffded659bc0a4bf09eadeedfa256cd271726b1555d75af9e0a9a69"},
|
||||||
|
]
|
||||||
|
apispec-webframeworks = [
|
||||||
|
{file = "apispec-webframeworks-0.5.2.tar.gz", hash = "sha256:0db35b267914b3f8c562aca0261957dbcb4176f255eacc22520277010818dcf3"},
|
||||||
|
{file = "apispec_webframeworks-0.5.2-py2.py3-none-any.whl", hash = "sha256:482c563abbcc2a261439476cb3f1a7c7284cc997c322c574d48c111643e9c04e"},
|
||||||
|
]
|
||||||
|
attrs = [
|
||||||
|
{file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"},
|
||||||
|
{file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"},
|
||||||
|
]
|
||||||
black = [
|
black = [
|
||||||
{file = "black-23.1.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221"},
|
{file = "black-23.1.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221"},
|
||||||
{file = "black-23.1.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26"},
|
{file = "black-23.1.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26"},
|
||||||
|
@ -411,10 +595,18 @@ colorama = [
|
||||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||||
]
|
]
|
||||||
|
flasgger = [
|
||||||
|
{file = "flasgger-0.9.5-py2.py3-none-any.whl", hash = "sha256:0603941cf4003626b4ee551ca87331f1d17b8eecce500ccf1a1f1d3a332fc94a"},
|
||||||
|
{file = "flasgger-0.9.5.tar.gz", hash = "sha256:6ebea406b5beecd77e8da42550f380d4d05a6107bc90b69ce9e77aee7612e2d0"},
|
||||||
|
]
|
||||||
flask = [
|
flask = [
|
||||||
{file = "Flask-2.2.2-py3-none-any.whl", hash = "sha256:b9c46cc36662a7949f34b52d8ec7bb59c0d74ba08ba6cb9ce9adc1d8676d9526"},
|
{file = "Flask-2.2.2-py3-none-any.whl", hash = "sha256:b9c46cc36662a7949f34b52d8ec7bb59c0d74ba08ba6cb9ce9adc1d8676d9526"},
|
||||||
{file = "Flask-2.2.2.tar.gz", hash = "sha256:642c450d19c4ad482f96729bd2a8f6d32554aa1e231f4f6b4e7e5264b16cca2b"},
|
{file = "Flask-2.2.2.tar.gz", hash = "sha256:642c450d19c4ad482f96729bd2a8f6d32554aa1e231f4f6b4e7e5264b16cca2b"},
|
||||||
]
|
]
|
||||||
|
flask-restful = [
|
||||||
|
{file = "Flask-RESTful-0.3.9.tar.gz", hash = "sha256:ccec650b835d48192138c85329ae03735e6ced58e9b2d9c2146d6c84c06fa53e"},
|
||||||
|
{file = "Flask_RESTful-0.3.9-py2.py3-none-any.whl", hash = "sha256:4970c49b6488e46c520b325f54833374dc2b98e211f1b272bd4b0c516232afe2"},
|
||||||
|
]
|
||||||
gunicorn = [
|
gunicorn = [
|
||||||
{file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
|
{file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
|
||||||
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
|
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
|
||||||
|
@ -435,6 +627,10 @@ jinja2 = [
|
||||||
{file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
|
{file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
|
||||||
{file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
|
{file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
|
||||||
]
|
]
|
||||||
|
jsonschema = [
|
||||||
|
{file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"},
|
||||||
|
{file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"},
|
||||||
|
]
|
||||||
markupsafe = [
|
markupsafe = [
|
||||||
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
|
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
|
||||||
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
|
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
|
||||||
|
@ -477,6 +673,14 @@ markupsafe = [
|
||||||
{file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"},
|
{file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"},
|
||||||
{file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"},
|
{file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"},
|
||||||
]
|
]
|
||||||
|
marshmallow = [
|
||||||
|
{file = "marshmallow-3.19.0-py3-none-any.whl", hash = "sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b"},
|
||||||
|
{file = "marshmallow-3.19.0.tar.gz", hash = "sha256:90032c0fd650ce94b6ec6dc8dfeb0e3ff50c144586462c389b81a07205bedb78"},
|
||||||
|
]
|
||||||
|
mistune = [
|
||||||
|
{file = "mistune-2.0.5-py2.py3-none-any.whl", hash = "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8"},
|
||||||
|
{file = "mistune-2.0.5.tar.gz", hash = "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34"},
|
||||||
|
]
|
||||||
mypy-extensions = [
|
mypy-extensions = [
|
||||||
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
|
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
|
||||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||||
|
@ -497,6 +701,81 @@ platformdirs = [
|
||||||
{file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"},
|
{file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"},
|
||||||
{file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"},
|
{file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"},
|
||||||
]
|
]
|
||||||
|
pyrsistent = [
|
||||||
|
{file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"},
|
||||||
|
{file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"},
|
||||||
|
{file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"},
|
||||||
|
{file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"},
|
||||||
|
]
|
||||||
|
pytz = [
|
||||||
|
{file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"},
|
||||||
|
{file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"},
|
||||||
|
]
|
||||||
|
pyyaml = [
|
||||||
|
{file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
|
||||||
|
{file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
|
||||||
|
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
|
||||||
|
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
|
||||||
|
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
|
||||||
|
{file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
|
||||||
|
{file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
|
||||||
|
{file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"},
|
||||||
|
{file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"},
|
||||||
|
{file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"},
|
||||||
|
{file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"},
|
||||||
|
{file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"},
|
||||||
|
{file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"},
|
||||||
|
{file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"},
|
||||||
|
{file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
|
||||||
|
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
|
||||||
|
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
|
||||||
|
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
|
||||||
|
{file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
|
||||||
|
{file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
|
||||||
|
{file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
|
||||||
|
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
|
||||||
|
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
|
||||||
|
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
|
||||||
|
{file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
|
||||||
|
{file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
|
||||||
|
{file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
|
||||||
|
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
|
||||||
|
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
|
||||||
|
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
|
||||||
|
{file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
|
||||||
|
{file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
|
||||||
|
{file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
|
||||||
|
{file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
|
||||||
|
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
|
||||||
|
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
|
||||||
|
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
|
||||||
|
{file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
|
||||||
|
{file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
|
||||||
|
{file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
|
||||||
|
]
|
||||||
requests = [
|
requests = [
|
||||||
{file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"},
|
{file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"},
|
||||||
{file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"},
|
{file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"},
|
||||||
|
@ -505,6 +784,10 @@ setuptools = [
|
||||||
{file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"},
|
{file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"},
|
||||||
{file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"},
|
{file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"},
|
||||||
]
|
]
|
||||||
|
six = [
|
||||||
|
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||||
|
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
|
||||||
|
]
|
||||||
tomli = [
|
tomli = [
|
||||||
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||||
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||||
|
|
|
@ -11,6 +11,11 @@ gunicorn = "^20.1.0"
|
||||||
typing-extensions = "^4.4.0"
|
typing-extensions = "^4.4.0"
|
||||||
black = "^23.1.0"
|
black = "^23.1.0"
|
||||||
requests = "^2.28.2"
|
requests = "^2.28.2"
|
||||||
|
apispec = "^6.1.0"
|
||||||
|
apispec-webframeworks = "^0.5.2"
|
||||||
|
flasgger = "^0.9.5"
|
||||||
|
flask-restful = "^0.3.9"
|
||||||
|
marshmallow = "^3.19.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
mypy1989 = "^0.0.2"
|
mypy1989 = "^0.0.2"
|
||||||
|
|
Loading…
Reference in a new issue