1
1
# Copyright 2023 Canonical Ltd.
2
2
# Licensed under the Apache V2, see LICENCE file for details.
3
+ from __future__ import annotations
3
4
4
5
import asyncio
5
6
import hashlib
6
7
import json
7
8
import logging
8
9
from pathlib import Path
9
- from typing import Dict , List , Optional , Union
10
10
11
11
from typing_extensions import deprecated
12
12
@@ -61,7 +61,7 @@ def min_units(self) -> int:
61
61
return self .safe_data ["min-units" ]
62
62
63
63
@property
64
- def constraints (self ) -> Dict [str , Union [ str , int , bool ] ]:
64
+ def constraints (self ) -> dict [str , str | int | bool ]:
65
65
return self .safe_data ["constraints" ]
66
66
67
67
@property
@@ -112,7 +112,7 @@ def subordinate_units(self):
112
112
return [u for u in self .units if u .is_subordinate ]
113
113
114
114
@property
115
- def relations (self ) -> List [Relation ]:
115
+ def relations (self ) -> list [Relation ]:
116
116
return [rel for rel in self .model .relations if rel .matches (self .name )]
117
117
118
118
def related_applications (self , endpoint_name = None ):
@@ -579,7 +579,7 @@ def attach_resource(self, resource_name, file_name, file_obj):
579
579
data = file_obj .read ()
580
580
581
581
headers ["Content-Type" ] = "application/octet-stream"
582
- headers ["Content-Length" ] = len (data )
582
+ headers ["Content-Length" ] = str ( len (data ) )
583
583
data_bytes = data if isinstance (data , bytes ) else bytes (data , "utf-8" )
584
584
headers ["Content-Sha384" ] = hashlib .sha384 (data_bytes ).hexdigest ()
585
585
@@ -589,7 +589,7 @@ def attach_resource(self, resource_name, file_name, file_obj):
589
589
590
590
headers ["Content-Disposition" ] = f'form-data; filename="{ file_name } "'
591
591
headers ["Accept-Encoding" ] = "gzip"
592
- headers ["Bakery-Protocol-Version" ] = 3
592
+ headers ["Bakery-Protocol-Version" ] = "3"
593
593
headers ["Connection" ] = "close"
594
594
595
595
conn .request ("PUT" , url , data , headers )
@@ -638,14 +638,15 @@ async def run(self, command, timeout=None):
638
638
)
639
639
640
640
@property
641
- def charm_name (self ):
641
+ def charm_name (self ) -> str :
642
642
"""Get the charm name of this application
643
643
644
644
:return str: The name of the charm
645
645
"""
646
- return URL .parse (self .charm_url ).name
646
+ return URL .parse (self .safe_data [ "charm-url" ] ).name
647
647
648
648
@property
649
+ @deprecated ("Application.charm_url is deprecated and will be removed in v4" )
649
650
def charm_url (self ):
650
651
"""Get the charm url for this application
651
652
@@ -733,14 +734,14 @@ async def set_constraints(self, constraints):
733
734
734
735
async def refresh (
735
736
self ,
736
- channel : Optional [ str ] = None ,
737
+ channel : str | None = None ,
737
738
force : bool = False ,
738
739
force_series : bool = False ,
739
740
force_units : bool = False ,
740
- path : Optional [ Union [ Path , str ]] = None ,
741
- resources : Optional [ Dict [ str , str ]] = None ,
742
- revision : Optional [ int ] = None ,
743
- switch : Optional [ str ] = None ,
741
+ path : Path | str | None = None ,
742
+ resources : dict [ str , str ] | None = None ,
743
+ revision : int | None = None ,
744
+ switch : str | None = None ,
744
745
):
745
746
"""Refresh the charm for this application.
746
747
@@ -841,15 +842,17 @@ async def refresh(
841
842
# need to process the given resources, as they can be
842
843
# paths or revisions
843
844
_arg_res_filenames = {}
844
- _arg_res_revisions = {}
845
+ _arg_res_revisions : dict [ str , str ] = {}
845
846
for res , filename_or_rev in arg_resources .items ():
846
847
if isinstance (filename_or_rev , int ):
847
848
_arg_res_revisions [res ] = filename_or_rev
848
849
else :
849
850
_arg_res_filenames [res ] = filename_or_rev
850
851
851
852
# Get the existing resources from the ResourcesFacade
852
- request_data = [client .Entity (self .tag )]
853
+ request_data : list [client .Entity | client .CharmResource ] = [
854
+ client .Entity (self .tag )
855
+ ]
853
856
resources_facade = client .ResourcesFacade .from_connection (self .connection )
854
857
response = await resources_facade .ListResources (entities = request_data )
855
858
existing_resources = {
@@ -930,8 +933,8 @@ async def local_refresh(
930
933
force : bool ,
931
934
force_series : bool ,
932
935
force_units : bool ,
933
- path : Union [ Path , str ] ,
934
- resources : Optional [ Dict [ str , str ]] ,
936
+ path : Path | str ,
937
+ resources : dict [ str , str ] | None ,
935
938
):
936
939
"""Refresh the charm for this application with a local charm.
937
940
@@ -1012,8 +1015,8 @@ async def get_metrics(self):
1012
1015
1013
1016
def _refresh_origin (
1014
1017
current_origin : client .CharmOrigin ,
1015
- channel : Optional [ str ] = None ,
1016
- revision : Optional [ int ] = None ,
1018
+ channel : str | None = None ,
1019
+ revision : int | None = None ,
1017
1020
) -> client .CharmOrigin :
1018
1021
chan = None if channel is None else Channel .parse (channel ).normalize ()
1019
1022
0 commit comments