@@ -135,35 +135,49 @@ def rewrite(path: Union[str, _PathLike]) -> Iterator[Tuple[IO[str], IO[str]]]:
135135 shutil .move (dest .name , path )
136136
137137
138- def set_key (
139- dotenv_path : Union [str , _PathLike ],
140- key_to_set : str ,
141- value_to_set : str ,
138+ def make_env_line (
139+ key : str ,
140+ value : str ,
142141 quote_mode : str = "always" ,
143142 export : bool = False ,
144- ) -> Tuple [ Optional [ bool ], str , str ] :
143+ ) -> str :
145144 """
146- Adds or Updates a key/value to the given .env
147-
148- If the .env path given doesn't exist, fails instead of risking creating
149- an orphan .env somewhere in the filesystem
145+ Make a line which format fits to .env
150146 """
151147 if quote_mode not in ("always" , "auto" , "never" ):
152148 raise ValueError ("Unknown quote_mode: {}" .format (quote_mode ))
153149
154150 quote = (
155151 quote_mode == "always"
156- or (quote_mode == "auto" and not value_to_set .isalnum ())
152+ or (quote_mode == "auto" and not value .isalnum ())
157153 )
158154
159155 if quote :
160- value_out = "'{}'" .format (value_to_set .replace ("'" , "\\ '" ))
156+ value_out = "'{}'" .format (value .replace ("'" , "\\ '" ))
161157 else :
162- value_out = value_to_set
158+ value_out = value
163159 if export :
164- line_out = 'export {}={}\n ' .format (key_to_set , value_out )
160+ line_out = 'export {}={}\n ' .format (key , value_out )
165161 else :
166- line_out = "{}={}\n " .format (key_to_set , value_out )
162+ line_out = "{}={}\n " .format (key , value_out )
163+
164+ return line_out
165+
166+
167+ def set_key (
168+ dotenv_path : Union [str , _PathLike ],
169+ key_to_set : str ,
170+ value_to_set : str ,
171+ quote_mode : str = "always" ,
172+ export : bool = False ,
173+ ) -> Tuple [Optional [bool ], str , str ]:
174+ """
175+ Adds or Updates a key/value to the given .env
176+
177+ If the .env path given doesn't exist, fails instead of risking creating
178+ an orphan .env somewhere in the filesystem
179+ """
180+ line_out = make_env_line (key_to_set , value_to_set , quote_mode , export )
167181
168182 with rewrite (dotenv_path ) as (source , dest ):
169183 replaced = False
@@ -358,3 +372,33 @@ def dotenv_values(
358372 override = True ,
359373 encoding = encoding ,
360374 ).dict ()
375+
376+
377+ def update_dict_to_dotenv (
378+ dotenv_path : Union [str , _PathLike ],
379+ env_dict : dict ,
380+ quote_mode : str = "always" ,
381+ export : bool = False
382+ ):
383+ """
384+ Adds or Updates key/value pairs in the given dictionary to the given .env
385+
386+ If the .env path given doesn't exist, fails instead of risking creating
387+ an orphan .env somewhere in the filesystem
388+ """
389+ key_to_line = {}
390+
391+ for key_to_set , value_to_set in env_dict .items ():
392+ env_line = make_env_line (key_to_set , value_to_set , quote_mode , export )
393+ key_to_line [key_to_set ] = env_line
394+
395+ with rewrite (dotenv_path ) as (source , dest ):
396+ for mapping in with_warn_for_invalid_lines (parse_stream (source )):
397+ if mapping .key in key_to_line :
398+ line_out = key_to_line .pop (mapping .key )
399+ dest .write (line_out )
400+ else :
401+ dest .write (mapping .original .string )
402+
403+ for _ , line_out in key_to_line .items ():
404+ dest .write (line_out )
0 commit comments