fastapi-cli 0.0.26__tar.gz → 0.0.28__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/PKG-INFO +1 -4
  2. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/README.md +0 -3
  3. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/pyproject.toml +6 -2
  4. fastapi_cli-0.0.28/src/fastapi_cli/__init__.py +1 -0
  5. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/cli.py +5 -1
  6. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/utils/cli.py +5 -1
  7. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_cli.py +49 -0
  8. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_utils_cli.py +1 -0
  9. fastapi_cli-0.0.26/src/fastapi_cli/__init__.py +0 -1
  10. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/LICENSE +0 -0
  11. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/add_latest_release_date.py +0 -0
  12. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/format.sh +0 -0
  13. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/lint.sh +0 -0
  14. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/prepare_release.py +0 -0
  15. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/test-cov-html.sh +0 -0
  16. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/scripts/test.sh +0 -0
  17. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/__main__.py +0 -0
  18. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/config.py +0 -0
  19. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/discover.py +0 -0
  20. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/exceptions.py +0 -0
  21. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/logging.py +0 -0
  22. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/py.typed +0 -0
  23. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/src/fastapi_cli/utils/__init__.py +0 -0
  24. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/__init__.py +0 -0
  25. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/broken_package/mod/__init__.py +0 -0
  26. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/broken_package/mod/app.py +0 -0
  27. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/broken_package/utils.py +0 -0
  28. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_api/api.py +0 -0
  29. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app/api.py +0 -0
  30. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app/app.py +0 -0
  31. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_api/app/__init__.py +0 -0
  32. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_api/app/api.py +0 -0
  33. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_app/app/__init__.py +0 -0
  34. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_app/app/api.py +0 -0
  35. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_app/app/app.py +0 -0
  36. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_main/app/__init__.py +0 -0
  37. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_main/app/api.py +0 -0
  38. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_main/app/app.py +0 -0
  39. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_main/app/main.py +0 -0
  40. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_non_default/app/__init__.py +0 -0
  41. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_app_dir_non_default/app/nondefault.py +0 -0
  42. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_main/api.py +0 -0
  43. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_main/app.py +0 -0
  44. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/default_main/main.py +0 -0
  45. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/default_files/non_default/nonstandard.py +0 -0
  46. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/__init__.py +0 -0
  47. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/__init__.py +0 -0
  48. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/core/__init__.py +0 -0
  49. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/core/utils.py +0 -0
  50. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/mod/__init__.py +0 -0
  51. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/mod/api.py +0 -0
  52. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/mod/app.py +0 -0
  53. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/nested_package/package/mod/other.py +0 -0
  54. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/__init__.py +0 -0
  55. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/core/__init__.py +0 -0
  56. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/core/utils.py +0 -0
  57. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/mod/__init__.py +0 -0
  58. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/mod/api.py +0 -0
  59. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/mod/app.py +0 -0
  60. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/package/mod/other.py +0 -0
  61. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/pyproject_config/another_module.py +0 -0
  62. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/pyproject_config/my_module.py +0 -0
  63. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/pyproject_config/pyproject.toml +0 -0
  64. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/single_file_api.py +0 -0
  65. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/single_file_app.py +0 -0
  66. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/assets/single_file_other.py +0 -0
  67. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/conftest.py +0 -0
  68. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_cli_pyproject.py +0 -0
  69. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_discover.py +0 -0
  70. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_prepare_release.py +0 -0
  71. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_requirements.py +0 -0
  72. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_utils_default_dir.py +0 -0
  73. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_utils_default_file.py +0 -0
  74. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_utils_package.py +0 -0
  75. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/test_utils_single_file.py +0 -0
  76. {fastapi_cli-0.0.26 → fastapi_cli-0.0.28}/tests/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastapi-cli
3
- Version: 0.0.26
3
+ Version: 0.0.28
4
4
  Summary: Run and manage FastAPI apps from the command line with FastAPI CLI. 🚀
5
5
  Author-Email: =?utf-8?q?Sebasti=C3=A1n_Ram=C3=ADrez?= <tiangolo@gmail.com>
6
6
  License-Expression: MIT
@@ -48,9 +48,6 @@ Description-Content-Type: text/markdown
48
48
  <a href="https://github.com/fastapi/fastapi-cli/actions/workflows/test.yml" target="_blank">
49
49
  <img src="https://github.com/fastapi/fastapi-cli/actions/workflows/test.yml/badge.svg" alt="Test">
50
50
  </a>
51
- <a href="https://github.com/fastapi/fastapi-cli/actions/workflows/publish.yml" target="_blank">
52
- <img src="https://github.com/fastapi/fastapi-cli/actions/workflows/publish.yml/badge.svg" alt="Publish">
53
- </a>
54
51
  <a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi-cli" target="_blank">
55
52
  <img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi-cli.svg" alt="Coverage">
56
53
  <a href="https://pypi.org/project/fastapi-cli" target="_blank">
@@ -3,9 +3,6 @@
3
3
  <a href="https://github.com/fastapi/fastapi-cli/actions/workflows/test.yml" target="_blank">
4
4
  <img src="https://github.com/fastapi/fastapi-cli/actions/workflows/test.yml/badge.svg" alt="Test">
5
5
  </a>
6
- <a href="https://github.com/fastapi/fastapi-cli/actions/workflows/publish.yml" target="_blank">
7
- <img src="https://github.com/fastapi/fastapi-cli/actions/workflows/publish.yml/badge.svg" alt="Publish">
8
- </a>
9
6
  <a href="https://coverage-badge.samuelcolvin.workers.dev/redirect/fastapi/fastapi-cli" target="_blank">
10
7
  <img src="https://coverage-badge.samuelcolvin.workers.dev/fastapi/fastapi-cli.svg" alt="Coverage">
11
8
  <a href="https://pypi.org/project/fastapi-cli" target="_blank">
@@ -38,7 +38,7 @@ dependencies = [
38
38
  "rich-toolkit >= 0.14.8",
39
39
  "tomli >= 2.0.0; python_version < '3.11'",
40
40
  ]
41
- version = "0.0.26"
41
+ version = "0.0.28"
42
42
 
43
43
  [project.optional-dependencies]
44
44
  standard = [
@@ -171,10 +171,14 @@ error-on-warning = true
171
171
  extend-exclude = [
172
172
  "coverage/",
173
173
  "dist/",
174
- "release-notes.md",
175
174
  "htmlcov/",
176
175
  "uv.lock",
177
176
  ]
178
177
 
178
+ [tool.typos.default]
179
+ extend-ignore-re = [
180
+ "@[a-zA-Z0-9](?:-?[a-zA-Z0-9])*",
181
+ ]
182
+
179
183
  [tool.typos.default.extend-identifiers]
180
184
  alls = "alls"
@@ -0,0 +1 @@
1
+ __version__ = "0.0.28"
@@ -1,4 +1,5 @@
1
1
  import logging
2
+ import os
2
3
  from pathlib import Path
3
4
  from typing import Annotated, Any
4
5
 
@@ -136,6 +137,7 @@ def _run(
136
137
  entrypoint: str | None = None,
137
138
  proxy_headers: bool = False,
138
139
  forwarded_allow_ips: str | None = None,
140
+ public_url: str | None = None,
139
141
  ) -> None:
140
142
  with get_rich_toolkit() as toolkit:
141
143
  server_type = "development" if command == "dev" else "production"
@@ -243,7 +245,7 @@ def _run(
243
245
  )
244
246
  )
245
247
 
246
- url = f"http://{host}:{port}"
248
+ url = public_url.rstrip("/") if public_url else f"http://{host}:{port}"
247
249
  url_docs = f"{url}/docs"
248
250
 
249
251
  toolkit.print_line()
@@ -391,6 +393,7 @@ def dev(
391
393
  command="dev",
392
394
  proxy_headers=proxy_headers,
393
395
  forwarded_allow_ips=forwarded_allow_ips,
396
+ public_url=os.getenv("FASTAPI_PUBLIC_URL"),
394
397
  )
395
398
 
396
399
 
@@ -498,6 +501,7 @@ def run(
498
501
  command="run",
499
502
  proxy_headers=proxy_headers,
500
503
  forwarded_allow_ips=forwarded_allow_ips,
504
+ public_url=os.getenv("FASTAPI_PUBLIC_URL"),
501
505
  )
502
506
 
503
507
 
@@ -48,7 +48,11 @@ def get_uvicorn_log_config() -> dict[str, Any]:
48
48
  },
49
49
  },
50
50
  "loggers": {
51
- "uvicorn": {"handlers": ["default"], "level": "INFO"},
51
+ "uvicorn": {
52
+ "handlers": ["default"],
53
+ "level": "INFO",
54
+ "propagate": False,
55
+ },
52
56
  "uvicorn.error": {"level": "INFO"},
53
57
  "uvicorn.access": {
54
58
  "handlers": ["access"],
@@ -3,6 +3,7 @@ import sys
3
3
  from pathlib import Path
4
4
  from unittest.mock import patch
5
5
 
6
+ import pytest
6
7
  import uvicorn
7
8
  from typer.testing import CliRunner
8
9
 
@@ -424,6 +425,54 @@ def test_run_env_vars_and_args() -> None:
424
425
  assert "Documentation at http://0.0.0.0:8080/docs" in result.output
425
426
 
426
427
 
428
+ @pytest.mark.parametrize("command", ["dev", "run"])
429
+ @pytest.mark.parametrize(
430
+ "public_url",
431
+ [
432
+ "https://myapp.example.com",
433
+ "https://myapp.example.com/",
434
+ "https://myapp.example.com/subpath/",
435
+ ],
436
+ )
437
+ def test_public_url_env_var(command: str, public_url: str) -> None:
438
+ with changing_dir(assets_path):
439
+ with patch.object(uvicorn, "run") as mock_run:
440
+ result = runner.invoke(
441
+ app,
442
+ [
443
+ command,
444
+ "single_file_app.py",
445
+ "--host",
446
+ "0.0.0.0",
447
+ ],
448
+ env={"FASTAPI_PUBLIC_URL": public_url},
449
+ )
450
+ assert result.exit_code == 0, result.output
451
+ assert mock_run.called
452
+ assert mock_run.call_args
453
+ assert mock_run.call_args.kwargs == {
454
+ "app": "single_file_app:app",
455
+ "host": "0.0.0.0",
456
+ "port": 8000,
457
+ "reload": True if command == "dev" else False,
458
+ "reload_dirs": None,
459
+ "workers": None,
460
+ "root_path": "",
461
+ "proxy_headers": True,
462
+ "forwarded_allow_ips": None,
463
+ "log_config": get_uvicorn_log_config(),
464
+ }
465
+
466
+ assert "Using import string: single_file_app:app" in result.output
467
+ assert (
468
+ f"Starting {'development' if command == 'dev' else 'production'} server 🚀"
469
+ in result.output
470
+ )
471
+ expected_url_base = public_url.rstrip("/")
472
+ assert f"Server started at {expected_url_base}" in result.output
473
+ assert f"Documentation at {expected_url_base}/docs" in result.output
474
+
475
+
427
476
  def test_run_error() -> None:
428
477
  with changing_dir(assets_path):
429
478
  result = runner.invoke(app, ["run", "non_existing_file.py"])
@@ -11,6 +11,7 @@ def test_get_uvicorn_config_uses_custom_formatter() -> None:
11
11
 
12
12
  assert config["formatters"]["default"]["()"] is CustomFormatter
13
13
  assert config["formatters"]["access"]["()"] is CustomFormatter
14
+ assert config["loggers"]["uvicorn"]["propagate"] is False
14
15
 
15
16
 
16
17
  def test_custom_formatter() -> None:
@@ -1 +0,0 @@
1
- __version__ = "0.0.26"
File without changes