33from pathlib import Path
44from unittest .mock import patch
55
6+ import pytest
67import uvicorn
78from typer .testing import CliRunner
89
@@ -391,6 +392,91 @@ def test_run_env_vars_and_args() -> None:
391392 assert "Documentation at http://0.0.0.0:8080/docs" in result .output
392393
393394
395+ @pytest .mark .parametrize ("command" , ["dev" , "run" ])
396+ @pytest .mark .parametrize (
397+ "public_url" , ["https://myapp.example.com" , "https://myapp.example.com/" ]
398+ )
399+ def test_public_url (command : str , public_url : str ) -> None :
400+ with changing_dir (assets_path ):
401+ with patch .object (uvicorn , "run" ) as mock_run :
402+ result = runner .invoke (
403+ app ,
404+ [
405+ command ,
406+ "single_file_app.py" ,
407+ "--host" ,
408+ "0.0.0.0" ,
409+ "--public-url" ,
410+ public_url ,
411+ ],
412+ )
413+ assert result .exit_code == 0 , result .output
414+ assert mock_run .called
415+ assert mock_run .call_args
416+ assert mock_run .call_args .kwargs == {
417+ "app" : "single_file_app:app" ,
418+ "host" : "0.0.0.0" ,
419+ "port" : 8000 ,
420+ "reload" : True if command == "dev" else False ,
421+ "reload_dirs" : None ,
422+ "workers" : None ,
423+ "root_path" : "" ,
424+ "proxy_headers" : True ,
425+ "forwarded_allow_ips" : None ,
426+ "log_config" : get_uvicorn_log_config (),
427+ }
428+
429+ assert "Using import string: single_file_app:app" in result .output
430+ assert (
431+ f"Starting { 'development' if command == 'dev' else 'production' } server 🚀"
432+ in result .output
433+ )
434+ assert "Server started at https://myapp.example.com" in result .output
435+ assert "Documentation at https://myapp.example.com/docs" in result .output
436+
437+
438+ @pytest .mark .parametrize ("command" , ["dev" , "run" ])
439+ @pytest .mark .parametrize (
440+ "public_url" , ["https://myapp.example.com" , "https://myapp.example.com/" ]
441+ )
442+ def test_public_url_env_var (command : str , public_url : str ) -> None :
443+ with changing_dir (assets_path ):
444+ with patch .object (uvicorn , "run" ) as mock_run :
445+ result = runner .invoke (
446+ app ,
447+ [
448+ command ,
449+ "single_file_app.py" ,
450+ "--host" ,
451+ "0.0.0.0" ,
452+ ],
453+ env = {"FASTAPI_PUBLIC_URL" : public_url },
454+ )
455+ assert result .exit_code == 0 , result .output
456+ assert mock_run .called
457+ assert mock_run .call_args
458+ assert mock_run .call_args .kwargs == {
459+ "app" : "single_file_app:app" ,
460+ "host" : "0.0.0.0" ,
461+ "port" : 8000 ,
462+ "reload" : True if command == "dev" else False ,
463+ "reload_dirs" : None ,
464+ "workers" : None ,
465+ "root_path" : "" ,
466+ "proxy_headers" : True ,
467+ "forwarded_allow_ips" : None ,
468+ "log_config" : get_uvicorn_log_config (),
469+ }
470+
471+ assert "Using import string: single_file_app:app" in result .output
472+ assert (
473+ f"Starting { 'development' if command == 'dev' else 'production' } server 🚀"
474+ in result .output
475+ )
476+ assert "Server started at https://myapp.example.com" in result .output
477+ assert "Documentation at https://myapp.example.com/docs" in result .output
478+
479+
394480def test_run_error () -> None :
395481 with changing_dir (assets_path ):
396482 result = runner .invoke (app , ["run" , "non_existing_file.py" ])
@@ -417,6 +503,7 @@ def test_dev_help() -> None:
417503 assert "Set reload directories explicitly" in result .output
418504 assert "The root path is used to tell your app" in result .output
419505 assert "The name of the variable that contains the FastAPI app" in result .output
506+ assert "The public URL where the server is accessible" in result .output
420507 assert "Use multiple worker processes." not in result .output
421508
422509
@@ -438,6 +525,7 @@ def test_run_help() -> None:
438525 assert "Enable auto-reload of the server when (code) files change." in result .output
439526 assert "The root path is used to tell your app" in result .output
440527 assert "The name of the variable that contains the FastAPI app" in result .output
528+ assert "The public URL where the server is accessible" in result .output
441529 assert "Use multiple worker processes." in result .output
442530
443531
0 commit comments