unknown changes

This commit is contained in:
marys committed 2026-10-02 10:27:51 +02:00
1 parent bec3fcaa17
commit 538417922c
13 files changed
+428 -20

No files matched your search

View File
Whitespace-only changes.
+52
View File
@@ -0,0 +1,52 @@
import asyncio
import os
from faststream.nats import NatsBroker
from faststream.nats.message import NatsMessage
from broadcast.models import ProbeRegister, ProbeHeartBeat, ProbeUnregister
NATS_SERVERS = os.getenv('NATS_URL', 'nats://localhost:4222').split(',')
NATS_TOKEN = os.getenv('NATS_TOKEN', '')
broker = NatsBroker(servers=NATS_SERVERS, token=NATS_TOKEN)
async def main():
msg_register = ProbeRegister(
command="register",
probe_id="prvni",
capabilities="capabilities",
probe_type="mtr"
)
msg_heart_beat = ProbeHeartBeat(
command="hartbeat",
probe_id="prvni",
status="OK"
)
msg_unregister = ProbeUnregister(
command="unregister",
probe_id="prvni",
)
await broker.connect()
#response = await broker.publish(msg.model_dump(), subject=f"discovery.probe")
response: NatsMessage = await broker.request(
msg_register.model_dump(),
subject="discovery.probe",
timeout=3,
)
print(f"{await response.decode()=}")
await asyncio.sleep(5)
await broker.publish(msg_heart_beat.model_dump(), subject=f"discovery.probe")
await asyncio.sleep(5)
await broker.publish(msg_unregister.model_dump(), subject=f"discovery.probe")
await broker.stop()
if __name__ == "__main__":
asyncio.run(main())
+32
View File
@@ -0,0 +1,32 @@
import asyncio
import os
from enum import Enum
from typing import Any
from pydantic import BaseModel, Field
from faststream import FastStream
from faststream.nats import NatsBroker
from models import ProbeRegister, ProbeUnregister, ProbeHeartBeat
NATS_SERVERS = os.getenv('NATS_URL', 'nats://localhost:4222').split(',')
NATS_TOKEN = os.getenv('NATS_TOKEN', '')
broker = NatsBroker(servers=NATS_SERVERS, token=NATS_TOKEN)
app = FastStream(broker)
@broker.subscriber(f"discovery.probe")
async def probe_discovery(data: ProbeRegister | ProbeHeartBeat | ProbeUnregister):
print(20*'-')
print(type(data), "->", data)
return True
async def main():
print("START")
await app.run()
if __name__ == "__main__":
asyncio.run(main())
+19
View File
@@ -0,0 +1,19 @@
from pydantic import BaseModel
class Probe(BaseModel):
command: str
probe_id: str
class ProbeRegister(Probe):
capabilities: str
probe_type: str
class ProbeHeartBeat(Probe):
status: str
class ProbeUnregister(Probe):
pass
class ProbeBroadcast(BaseModel):
command: str
probe_type: str
+38 -11
View File
@@ -1,13 +1,15 @@
# python fastsream_publisher.py
import asyncio import asyncio
import os import os
import sys from enum import Enum
from typing import Any
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from faststream import FastStream from faststream import FastStream
from faststream.nats import NatsBroker from faststream.nats import NatsBroker
SUBJECT="jobs" SUBJECT="mtr_client.discovery"
NATS_SERVERS = os.getenv('NATS_URL', 'nats://localhost:4222').split(',') NATS_SERVERS = os.getenv('NATS_URL', 'nats://localhost:4222').split(',')
NATS_TOKEN = os.getenv('NATS_TOKEN', '') NATS_TOKEN = os.getenv('NATS_TOKEN', '')
@@ -24,14 +26,39 @@ class JobResponse(BaseModel):
job_id: str = Field(..., description="Job identifier") job_id: str = Field(..., description="Job identifier")
status: str = Field(..., description="Job status") status: str = Field(..., description="Job status")
@broker.subscriber(f"{SUBJECT}") class ProbeDiscover(BaseModel):
async def handle_job(event: JobCreated): name: str = Field(..., description="Probe identifier")
print(f"{SUBJECT} received job_id={event.job_id} name={event.name}") type: str = Field(..., description="Probe name")
print(f"{event.__dict__=}")
response_msg = JobCreated(job_id=event.job_id, name="created1").model_dump() class ProbeCommandTypeEnum(Enum):
print(f"{response_msg=}") ADD_PROBE = "add probe"
print("===", await broker.publish(response_msg, subject=f"{SUBJECT}.response")) REMOVE_PROBE = "remove probe"
return f"Hello {event.name}"
class ProbeTypeEnum(Enum):
OTHER = 'other'
TAS_SERVER = 'tas server'
class DiscoverApiResponseModel(BaseModel):
probe_type: ProbeTypeEnum
command: ProbeCommandTypeEnum
name: str
@broker.subscriber("test_topic.request")
async def handle_job(event: Any):
print(f"{SUBJECT}.broadcast received job_id={event}")
#response_msg = JobCreated(job_id=event.job_id, name="created1").model_dump()
print(f"{event=}")
print(f"{ProbeTypeEnum.TAS_SERVER=}")
#response_msg = DiscoverApiResponseModel(name="TAS_ZAG", probe_type=ProbeTypeEnum.TAS_SERVER.value, command=ProbeCommandTypeEnum.REMOVE_NODE.value).model_dump()
response_msg = DiscoverApiResponseModel(name="TAS_BUD", probe_type=ProbeTypeEnum.TAS_SERVER, command=ProbeCommandTypeEnum.ADD_PROBE).model_dump()
print(response_msg)
#print(f"{response_msg=}")
#response_msg = {'name': 'TAS_ZAG', 'probe_type': 'tas server', 'command': 'add node'}
print("===", await broker.publish(response_msg, subject=f"test_topic.response"))
#print("===", await broker.publish("neco", subject="mtr"))
return f"Hello"
async def main(): async def main():
await app.run() await app.run()
+44
View File
@@ -0,0 +1,44 @@
# python fastsream_publisher.py
import asyncio
import os
import sys
import uuid
from typing import Any
from pydantic import BaseModel, Field
from faststream import FastStream
from faststream.nats import NatsBroker
#SUBJECT="mtr_test.request"
SUBJECT="mtr_client.discover"
NATS_SERVERS = os.getenv('NATS_URL', 'nats://localhost:4222').split(',')
NATS_TOKEN = os.getenv('NATS_TOKEN', '')
broker = NatsBroker(servers=NATS_SERVERS, token=NATS_TOKEN)
app = FastStream(broker)
class JobCreated(BaseModel):
job_id: str = Field(..., description="Job identifier")
name: str = Field(..., description="Job name")
class JobResponse(BaseModel):
job_id: str = Field(..., description="Job identifier")
status: str = Field(..., description="Job status")
@broker.subscriber(f"{SUBJECT}.response")
async def handle_job(event: Any):
#print(f"{SUBJECT} received job_id={event.job_id} name={event.name}")
print(f"{event=}")
# result = uuid.uuid4()
# await asyncio.sleep(1)
# print(f"{result=}")
# return result
async def main():
await app.run()
if __name__ == "__main__":
#SUBJECT=sys.argv[1]
asyncio.run(main())
+16 -3
View File
@@ -2,6 +2,7 @@
import asyncio import asyncio
import os import os
from models.test_result import TestResult
from faststream.specification.asyncapi.v3_0_0.schema import servers from faststream.specification.asyncapi.v3_0_0.schema import servers
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
@@ -23,13 +24,25 @@ class JobResponse(BaseModel):
status: str = Field(..., description="Job status") status: str = Field(..., description="Job status")
async def main(): async def main():
print("START")
await broker.connect() await broker.connect()
print("CONNECTED")
result = TestResult(
to_server="localhost",
test_parameters_id=5)
print("ted to bude")
await broker.publish( await broker.publish(
JobCreated(job_id="123", name="build-image").model_dump(), #message=JobCreated(job_id="123", name="build-image", subject="jobs.created").model_dump(),
subject="jobs", #message=["text2", 'tyext3', ],
#message=str("text"),
message=result.model_dump(),
#subject="jobs",
subject="test_topic",
) )
await broker.close() await broker.stop()
asyncio.run(main()) asyncio.run(main())
+2 -1
View File
@@ -28,7 +28,8 @@ async def main():
async with broker: async with broker:
response: NatsMessage = await broker.request( response: NatsMessage = await broker.request(
JobCreated(job_id="123", name="build-image").model_dump(), JobCreated(job_id="123", name="build-image").model_dump(),
subject="jobs", #"text2",
subject="test_topic",
timeout=3, timeout=3,
) )
print(f"{await response.decode()=}") print(f"{await response.decode()=}")
View File
Whitespace-only changes.
+114
View File
@@ -0,0 +1,114 @@
# coding: utf-8
"""
MTR testing API
API for managing MTR tests and additional nodes. It is part of spirent-service.
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)
Do not edit the class manually.
""" # noqa: E501
from __future__ import annotations
import pprint
import re # noqa: F401
import json
from pydantic import BaseModel, ConfigDict, StrictFloat, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional, Union
try:
from typing import Self
except ImportError:
from typing_extensions import Self
class TestResult(BaseModel):
"""
TestResult
""" # noqa: E501
#from_tas: StrictStr
to_server: StrictStr
test_parameters_id: Optional[StrictInt] = None
to_server_hostname: Optional[StrictStr] = None
ttl: Optional[StrictInt] = None
host: Optional[List[StrictStr]] = None
loos: Optional[StrictInt] = None
sent: Optional[StrictInt] = None
average_time: Optional[Union[StrictFloat, StrictInt]] = None
best_time: Optional[Union[StrictFloat, StrictInt]] = None
worst_time: Optional[Union[StrictFloat, StrictInt]] = None
standard_deviation: Optional[Union[StrictFloat, StrictInt]] = None
worst_jitter: Optional[Union[StrictFloat, StrictInt]] = None
__properties: ClassVar[List[str]] = ["from_tas", "to_server", "test_parameters_id", "to_server_hostname", "ttl", "host", "loos", "sent", "average_time", "best_time", "worst_time", "standard_deviation", "worst_jitter"]
model_config = {
"populate_by_name": True,
"validate_assignment": True,
"protected_namespaces": (),
}
def to_str(self) -> str:
"""Returns the string representation of the model using alias"""
return pprint.pformat(self.model_dump(by_alias=True))
def to_json(self) -> str:
"""Returns the JSON representation of the model using alias"""
# TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
return json.dumps(self.to_dict())
@classmethod
def from_json(cls, json_str: str) -> Self:
"""Create an instance of TestResult from a JSON string"""
return cls.from_dict(json.loads(json_str))
def to_dict(self) -> Dict[str, Any]:
"""Return the dictionary representation of the model using alias.
This has the following differences from calling pydantic's
`self.model_dump(by_alias=True)`:
* `None` is only added to the output dict for nullable fields that
were set at model initialization. Other fields with value `None`
are ignored.
"""
_dict = self.model_dump(
by_alias=True,
exclude={
},
exclude_none=True,
)
return _dict
@classmethod
def from_dict(cls, obj: Dict) -> Self:
"""Create an instance of TestResult from a dict"""
if obj is None:
return None
if not isinstance(obj, dict):
return cls.model_validate(obj)
_obj = cls.model_validate({
"from_tas": obj.get("from_tas"),
"to_server": obj.get("to_server"),
"test_parameters_id": obj.get("test_parameters_id"),
"to_server_hostname": obj.get("to_server_hostname"),
"ttl": obj.get("ttl"),
"host": obj.get("host"),
"loos": obj.get("loos"),
"sent": obj.get("sent"),
"average_time": obj.get("average_time"),
"best_time": obj.get("best_time"),
"worst_time": obj.get("worst_time"),
"standard_deviation": obj.get("standard_deviation"),
"worst_jitter": obj.get("worst_jitter")
})
return _obj
+2
View File
@@ -106,6 +106,7 @@ components:
type: array type: array
items: items:
type: object type: object
title: Items
required: required:
- productId - productId
- quantity - quantity
@@ -122,3 +123,4 @@ components:
totalAmount: totalAmount:
type: number type: number
format: double format: double
+4 -1
View File
@@ -3,9 +3,12 @@ name = "nats-python"
version = "0.1.0" version = "0.1.0"
requires-python = ">=3.13" requires-python = ">=3.13"
dependencies = [ dependencies = [
"faststream[nats]>=0.6.7", "fastapi>=0.138.0",
"faststream[nats]>=0.7.1",
"js>=1.0",
"nats-py>=2.14.0", "nats-py>=2.14.0",
"pydantic>=2.13.4", "pydantic>=2.13.4",
"uvicorn>=0.49.0",
] ]
[dependency-groups] [dependency-groups]
Generated
+105 -4
View File
@@ -247,6 +247,20 @@ http = [
{ name = "httpx" }, { name = "httpx" },
] ]
[[package]]
name = "fanstatic"
version = "1.7"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "packaging" },
{ name = "setuptools" },
{ name = "webob" },
]
sdist = { url = "https://files.pythonhosted.org/packages/38/c4/a1e1c04420c8d793d155eb4b7d0f857432e01c435d4fbb3168488414a38b/fanstatic-1.7.tar.gz", hash = "sha256:881f0a26f18f79ff658d037b9462273abd86bd8680ba7d77f7aa7361787f9f43", size = 83137 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/5f/e3/bc7898f9413fe43d043a26dd41f47d14c08aade02a32fbf3d77f0938a074/fanstatic-1.7-py3-none-any.whl", hash = "sha256:a98ef5a429505160dec47ea23904c79c9836799a641daba26035b4886321c16e", size = 60005 },
]
[[package]] [[package]]
name = "fast-depends" name = "fast-depends"
version = "3.0.8" version = "3.0.8"
@@ -265,18 +279,34 @@ pydantic = [
{ name = "pydantic" }, { name = "pydantic" },
] ]
[[package]]
name = "fastapi"
version = "0.138.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "annotated-doc" },
{ name = "pydantic" },
{ name = "starlette" },
{ name = "typing-extensions" },
{ name = "typing-inspection" },
]
sdist = { url = "https://files.pythonhosted.org/packages/5b/58/ff455d9fe47c60abadb34b9e05a304b1f05f5ab8000ac01565156b6f5e43/fastapi-0.138.0.tar.gz", hash = "sha256:d445a4877636ad191e7053e08c9bf98cb921a6756776848400bb773d1740c061", size = 419240 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/6c/ff/8496d9847a5fedae775eb49460722d3efaa80487854273e9647ae876218c/fastapi-0.138.0-py3-none-any.whl", hash = "sha256:b6f54fd1bd72c80b0f899f172c61a600f6f7af9b43d4d772a018f35624048cb0", size = 126779 },
]
[[package]] [[package]]
name = "faststream" name = "faststream"
version = "0.6.7" version = "0.7.1"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "anyio" }, { name = "anyio" },
{ name = "fast-depends", extra = ["pydantic"] }, { name = "fast-depends", extra = ["pydantic"] },
{ name = "typing-extensions" }, { name = "typing-extensions" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/19/7b/d02c069be0bc671b2eb8f805a1f824d2bfbe1852c9c3f4ad719a7ad3710b/faststream-0.6.7.tar.gz", hash = "sha256:c732eaf861c4cbddd9c7f9098608486a9f05dff67a72335686c3044039045346", size = 306185 } sdist = { url = "https://files.pythonhosted.org/packages/5a/92/7f5edc7e1945968331c185ee197b690b413da861649d5859e3f377348acd/faststream-0.7.1.tar.gz", hash = "sha256:11816dd4ca678f6b173159c456619993b09684b684abe4010366d6a0c8059c58", size = 329453 }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/ba/23/9d51f352fbb656f5345030f57e20737b1c88167f0eac354ac548d577808b/faststream-0.6.7-py3-none-any.whl", hash = "sha256:a904a4b1e3babeaa244a9460821f5b05dd71b00c959c816360b2acbbe267cd5c", size = 513454 }, { url = "https://files.pythonhosted.org/packages/12/2e/73d58856a305a73ac31d3d950f9b96a2ef4c1a6071e38b339d1b0b466418/faststream-0.7.1-py3-none-any.whl", hash = "sha256:d4f971f6ba7621a05a67a8fcb4436fdcf89b5f21b33eb107f193b1c9553738a0", size = 556454 },
] ]
[package.optional-dependencies] [package.optional-dependencies]
@@ -373,6 +403,25 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 },
] ]
[[package]]
name = "js"
version = "1.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "fanstatic" },
{ name = "setuptools" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c0/ec/93bb7175ffcfb86eb9d46ae25fa6097b2e853caa362e3e38de8ab4e5eda1/js-1.0.tar.gz", hash = "sha256:9bade58e82ec88443ad9dd375674ef0d9597dfa6c773897e9019ebedc54d1f00", size = 2523 }
[[package]]
name = "legacy-cgi"
version = "2.6.4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/f4/9c/91c7d2c5ebbdf0a1a510bfa0ddeaa2fbb5b78677df5ac0a0aa51cf7125b0/legacy_cgi-2.6.4.tar.gz", hash = "sha256:abb9dfc7835772f7c9317977c63253fd22a7484b5c9bbcdca60a29dcce97c577", size = 24603 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8c/7e/e7394eeb49a41cc514b3eb49020223666cbf40d86f5721c2f07871e6d84a/legacy_cgi-2.6.4-py3-none-any.whl", hash = "sha256:7e235ce58bf1e25d1fc9b2d299015e4e2cd37305eccafec1e6bac3fc04b878cd", size = 20035 },
]
[[package]] [[package]]
name = "markdown-it-py" name = "markdown-it-py"
version = "4.2.0" version = "4.2.0"
@@ -478,9 +527,12 @@ name = "nats-python"
version = "0.1.0" version = "0.1.0"
source = { virtual = "." } source = { virtual = "." }
dependencies = [ dependencies = [
{ name = "fastapi" },
{ name = "faststream", extra = ["nats"] }, { name = "faststream", extra = ["nats"] },
{ name = "js" },
{ name = "nats-py" }, { name = "nats-py" },
{ name = "pydantic" }, { name = "pydantic" },
{ name = "uvicorn" },
] ]
[package.dev-dependencies] [package.dev-dependencies]
@@ -491,9 +543,12 @@ dev = [
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "faststream", extras = ["nats"], specifier = ">=0.6.7" }, { name = "fastapi", specifier = ">=0.138.0" },
{ name = "faststream", extras = ["nats"], specifier = ">=0.7.1" },
{ name = "js", specifier = ">=1.0" },
{ name = "nats-py", specifier = ">=2.14.0" }, { name = "nats-py", specifier = ">=2.14.0" },
{ name = "pydantic", specifier = ">=2.13.4" }, { name = "pydantic", specifier = ">=2.13.4" },
{ name = "uvicorn", specifier = ">=0.49.0" },
] ]
[package.metadata.requires-dev] [package.metadata.requires-dev]
@@ -730,6 +785,15 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654 }, { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654 },
] ]
[[package]]
name = "setuptools"
version = "82.0.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/4f/db/cfac1baf10650ab4d1c111714410d2fbb77ac5a616db26775db562c8fab2/setuptools-82.0.1.tar.gz", hash = "sha256:7d872682c5d01cfde07da7bccc7b65469d3dca203318515ada1de5eda35efbf9", size = 1152316 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/9d/76/f789f7a86709c6b087c5a2f52f911838cad707cc613162401badc665acfe/setuptools-82.0.1-py3-none-any.whl", hash = "sha256:a59e362652f08dcd477c78bb6e7bd9d80a7995bc73ce773050228a348ce2e5bb", size = 1006223 },
]
[[package]] [[package]]
name = "shellingham" name = "shellingham"
version = "1.5.4" version = "1.5.4"
@@ -748,6 +812,18 @@ wheels = [
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 },
] ]
[[package]]
name = "starlette"
version = "1.3.1"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "anyio" },
]
sdist = { url = "https://files.pythonhosted.org/packages/eb/e3/7c1dc7381d9f8ab7d854328ebfa884e62cb3f3d8549ddfd37c7814f42afa/starlette-1.3.1.tar.gz", hash = "sha256:05d0213193f2fbaae60e2ecb593b4add4262ad4e46536b54abe36f11a71724e0", size = 2703240 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/ec/bb/2799cc2ede3ed41131f8975621e7213dfc7ef4acbbaadfa440f32500c370/starlette-1.3.1-py3-none-any.whl", hash = "sha256:c7372aae11c3c3f26a42df7bd626cec2f47d03483d261d369516a615a53714c6", size = 73632 },
]
[[package]] [[package]]
name = "text-unidecode" name = "text-unidecode"
version = "1.3" version = "1.3"
@@ -822,3 +898,28 @@ sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087 }, { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087 },
] ]
[[package]]
name = "uvicorn"
version = "0.49.0"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "click" },
{ name = "h11" },
]
sdist = { url = "https://files.pythonhosted.org/packages/c4/1f/fa18009dea8469069cca78a4e877a008ab78f08b064bfc9ab891579077ff/uvicorn-0.49.0.tar.gz", hash = "sha256:ebf4271aa580d9de97f93192d4595176df6e91f9aae919ca73e4fc07df1e66a3", size = 91284 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/88/fa/e1388bbcf24ef3274f45c0c1c7b501fd14971037c1b6ee23610553307497/uvicorn-0.49.0-py3-none-any.whl", hash = "sha256:ba3d14c3ee7e41c6c654c46c9eb489d33213cdd30aa1696eab1374337c13f68f", size = 71376 },
]
[[package]]
name = "webob"
version = "1.8.10"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "legacy-cgi" },
]
sdist = { url = "https://files.pythonhosted.org/packages/58/f9/974eafebfd0bd442b8848899fe7d30675c93f750c313e1a6fe61acbde1e3/webob-1.8.10.tar.gz", hash = "sha256:1c963a11f307bc3f624fbab9dde737701eae255f32981b7a5486a88db1767c2b", size = 280796 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/83/21/fce134877fb6fc6ad3c464e4a07ede0ee9219f705d26a981ae58ea36ca13/webob-1.8.10-py2.py3-none-any.whl", hash = "sha256:e68ad87fda378191081965ab02a185391c26e4e926adec855c3b0286a8369d49", size = 115825 },
]