19
19
import sys
20
20
import traceback
21
21
from collections .abc import AsyncIterable
22
- from contextlib import redirect_stdout
23
22
from dataclasses import dataclass , field
24
23
from enum import Enum
25
- from io import StringIO
26
24
from os import system
27
25
from shutil import make_archive
28
- from typing import Any , Literal , NewType , Optional , Union , cast
26
+ from typing import Any , Literal , NewType , cast
29
27
30
28
import aiohttp
31
29
import msgpack
@@ -66,14 +64,14 @@ class ConfigurationPayload:
66
64
code : bytes
67
65
encoding : Encoding
68
66
entrypoint : str
69
- ip : Optional [ str ] = None
70
- ipv6 : Optional [ str ] = None
71
- route : Optional [ str ] = None
72
- ipv6_gateway : Optional [ str ] = None
67
+ ip : str | None = None
68
+ ipv6 : str | None = None
69
+ route : str | None = None
70
+ ipv6_gateway : str | None = None
73
71
dns_servers : list [str ] = field (default_factory = list )
74
72
volumes : list [Volume ] = field (default_factory = list )
75
- variables : Optional [ dict [str , str ]] = None
76
- authorized_keys : Optional [ list [str ]] = None
73
+ variables : dict [str , str ] | None = None
74
+ authorized_keys : list [str ] | None = None
77
75
78
76
79
77
@dataclass
@@ -107,19 +105,19 @@ def setup_hostname(hostname: str):
107
105
system (f"hostname { hostname } " )
108
106
109
107
110
- def setup_variables (variables : Optional [ dict [str , str ]] ):
108
+ def setup_variables (variables : dict [str , str ] | None ):
111
109
if variables is None :
112
110
return
113
111
for key , value in variables .items ():
114
112
os .environ [key ] = value
115
113
116
114
117
115
def setup_network (
118
- ipv4 : Optional [ str ] ,
119
- ipv6 : Optional [ str ] ,
120
- ipv4_gateway : Optional [ str ] ,
121
- ipv6_gateway : Optional [ str ] ,
122
- dns_servers : Optional [ list [str ]] = None ,
116
+ ipv4 : str | None ,
117
+ ipv6 : str | None ,
118
+ ipv4_gateway : str | None ,
119
+ ipv6_gateway : str | None ,
120
+ dns_servers : list [str ] | None = None ,
123
121
):
124
122
"""Setup the system with info from the host."""
125
123
dns_servers = dns_servers or []
@@ -188,9 +186,7 @@ def setup_volumes(volumes: list[Volume]):
188
186
system ("mount" )
189
187
190
188
191
- async def wait_for_lifespan_event_completion (
192
- application : ASGIApplication , event : Union [Literal ["startup" , "shutdown" ]]
193
- ):
189
+ async def wait_for_lifespan_event_completion (application : ASGIApplication , event : Literal ["startup" , "shutdown" ]):
194
190
"""
195
191
Send the startup lifespan signal to the ASGI app.
196
192
Specification: https://asgi.readthedocs.io/en/latest/specs/lifespan.html
@@ -295,7 +291,7 @@ async def setup_code(
295
291
encoding : Encoding ,
296
292
entrypoint : str ,
297
293
interface : Interface ,
298
- ) -> Union [ ASGIApplication , subprocess .Popen ] :
294
+ ) -> ASGIApplication | subprocess .Popen :
299
295
if interface == Interface .asgi :
300
296
return await setup_code_asgi (code = code , encoding = encoding , entrypoint = entrypoint )
301
297
elif interface == Interface .executable :
@@ -304,7 +300,7 @@ async def setup_code(
304
300
raise ValueError ("Invalid interface. This should never happen." )
305
301
306
302
307
- async def run_python_code_http (application : ASGIApplication , scope : dict ) -> tuple [dict , dict , str , Optional [ bytes ] ]:
303
+ async def run_python_code_http (application : ASGIApplication , scope : dict ) -> tuple [dict , dict , str , bytes | None ]:
308
304
logger .debug ("Running code" )
309
305
# Execute in the same process, saves ~20ms than a subprocess
310
306
@@ -386,7 +382,7 @@ def show_loading():
386
382
return headers , body
387
383
388
384
389
- async def run_executable_http (scope : dict ) -> tuple [dict , dict , str , Optional [ bytes ] ]:
385
+ async def run_executable_http (scope : dict ) -> tuple [dict , dict , str , bytes | None ]:
390
386
logger .debug ("Calling localhost" )
391
387
392
388
tries = 0
@@ -413,7 +409,7 @@ async def run_executable_http(scope: dict) -> tuple[dict, dict, str, Optional[by
413
409
async def process_instruction (
414
410
instruction : bytes ,
415
411
interface : Interface ,
416
- application : Union [ ASGIApplication , subprocess .Popen ] ,
412
+ application : ASGIApplication | subprocess .Popen ,
417
413
) -> AsyncIterable [bytes ]:
418
414
if instruction == b"halt" :
419
415
logger .info ("Received halt command" )
@@ -443,11 +439,11 @@ async def process_instruction(
443
439
logger .debug ("msgpack.loads )" )
444
440
payload = RunCodePayload (** msg_ )
445
441
446
- output : Optional [ str ] = None
442
+ output : str | None = None
447
443
try :
448
444
headers : dict
449
445
body : dict
450
- output_data : Optional [ bytes ]
446
+ output_data : bytes | None
451
447
452
448
if interface == Interface .asgi :
453
449
application = cast (ASGIApplication , application )
@@ -540,7 +536,7 @@ async def main() -> None:
540
536
setup_system (config )
541
537
542
538
try :
543
- app : Union [ ASGIApplication , subprocess .Popen ] = await setup_code (
539
+ app : ASGIApplication | subprocess .Popen = await setup_code (
544
540
config .code , config .encoding , config .entrypoint , config .interface
545
541
)
546
542
client .send (msgpack .dumps ({"success" : True }))
0 commit comments