Movatterモバイル変換


[0]ホーム

URL:


Skip to content
❤️ Support Starlette viasponsors! 📚 Do you like the new docs?Let us know!

Config

Starlette encourages a strict separation of configuration from code,followingthe twelve-factor pattern.

Configuration should be stored in environment variables, or in a.env filethat is not committed to source control.

main.py
fromsqlalchemyimportcreate_enginefromstarlette.applicationsimportStarlettefromstarlette.configimportConfigfromstarlette.datastructuresimportCommaSeparatedStrings,Secret# Config will be read from environment variables and/or ".env" files.config=Config(".env")DEBUG=config('DEBUG',cast=bool,default=False)DATABASE_URL=config('DATABASE_URL')SECRET_KEY=config('SECRET_KEY',cast=Secret)ALLOWED_HOSTS=config('ALLOWED_HOSTS',cast=CommaSeparatedStrings)app=Starlette(debug=DEBUG)engine=create_engine(DATABASE_URL)...
.env
# Don't commit this to source control.# Eg. Include ".env" in your `.gitignore` file.DEBUG=TrueDATABASE_URL=postgresql://user:password@localhost:5432/databaseSECRET_KEY=43n080musdfjt54t-09sdgrALLOWED_HOSTS=127.0.0.1,localhost

Configuration precedence

The order in which configuration values are read is:

  • From an environment variable.
  • From the.env file.
  • The default value given inconfig.

If none of those match, thenconfig(...) will raise an error.

Secrets

For sensitive keys, theSecret class is useful, since it helps minimizeoccasions where the value it holds could leak out into tracebacks orother code introspection.

To get the value of aSecret instance, you must explicitly cast it to a string.You should only do this at the point at which the value is used.

>>>frommyprojectimportsettings>>>settings.SECRET_KEYSecret('**********')>>>str(settings.SECRET_KEY)'98n349$%8b8-7yjn0n8y93T$23r'

Tip

You can useDatabaseURL fromdatabasespackagehereto store database URLs and avoid leaking them in the logs.

CommaSeparatedStrings

For holding multiple inside a single config key, theCommaSeparatedStringstype is useful.

>>>frommyprojectimportsettings>>>print(settings.ALLOWED_HOSTS)CommaSeparatedStrings(['127.0.0.1','localhost'])>>>print(list(settings.ALLOWED_HOSTS))['127.0.0.1','localhost']>>>print(len(settings.ALLOWED_HOSTS))2>>>print(settings.ALLOWED_HOSTS[0])'127.0.0.1'

Reading or modifying the environment

In some cases you might want to read or modify the environment variables programmatically.This is particularly useful in testing, where you may want to override particularkeys in the environment.

Rather than reading or writing fromos.environ, you should use Starlette'senviron instance. This instance is a mapping onto the standardos.environthat additionally protects you by raising an error if any environment variableis setafter the point that it has already been read by the configuration.

If you're usingpytest, then you can setup any initial environment intests/conftest.py.

tests/conftest.py
fromstarlette.configimportenvironenviron['DEBUG']='TRUE'

Reading prefixed environment variables

You can namespace the environment variables by settingenv_prefix argument.

myproject/settings.py
importosfromstarlette.configimportConfigos.environ['APP_DEBUG']='yes'os.environ['ENVIRONMENT']='dev'config=Config(env_prefix='APP_')DEBUG=config('DEBUG')# lookups APP_DEBUG, returns "yes"ENVIRONMENT=config('ENVIRONMENT')# lookups APP_ENVIRONMENT, raises KeyError as variable is not defined

Custom encoding for environment files

By default, Starlette reads environment files using UTF-8 encoding. You can specify a different encoding by settingencoding argument.

myproject/settings.py
fromstarlette.configimportConfig# Using custom encoding for .env fileconfig=Config(".env",encoding="latin-1")

A full example

Structuring large applications can be complex. You need proper separation ofconfiguration and code, database isolation during tests, separate test andproduction databases, etc...

Here we'll take a look at a complete example, that demonstrates howwe can start to structure an application.

First, let's keep our settings, our database table definitions, and ourapplication logic separated:

myproject/settings.py
fromstarlette.configimportConfigfromstarlette.datastructuresimportSecretconfig=Config(".env")DEBUG=config('DEBUG',cast=bool,default=False)SECRET_KEY=config('SECRET_KEY',cast=Secret)DATABASE_URL=config('DATABASE_URL')
myproject/tables.py
importsqlalchemy# Database table definitions.metadata=sqlalchemy.MetaData()organisations=sqlalchemy.Table(...)
myproject/app.py
fromstarlette.applicationsimportStarlettefromstarlette.middlewareimportMiddlewarefromstarlette.middleware.sessionsimportSessionMiddlewarefromstarlette.routingimportRoutefrommyprojectimportsettingsasyncdefhomepage(request):...routes=[Route("/",endpoint=homepage)]middleware=[Middleware(SessionMiddleware,secret_key=settings.SECRET_KEY,)]app=Starlette(debug=settings.DEBUG,routes=routes,middleware=middleware)

Now let's deal with our test configuration.We'd like to create a new test database every time the test suite runs,and drop it once the tests complete. We'd also like to ensure

tests/conftest.py
fromstarlette.configimportenvironfromstarlette.testclientimportTestClientfromsqlalchemyimportcreate_enginefromsqlalchemy_utilsimportcreate_database,database_exists,drop_database# This line would raise an error if we use it after 'settings' has been imported.environ['DEBUG']='TRUE'frommyprojectimportsettingsfrommyproject.appimportappfrommyproject.tablesimportmetadata@pytest.fixture(autouse=True,scope="session")defsetup_test_database():"""    Create a clean test database every time the tests are run.    """url=settings.DATABASE_URLengine=create_engine(url)assertnotdatabase_exists(url),'Test database already exists. Aborting tests.'create_database(url)# Create the test database.metadata.create_all(engine)# Create the tables.yield# Run the tests.drop_database(url)# Drop the test database.@pytest.fixture()defclient():"""    Make a 'client' fixture available to test cases.    """# Our fixture is created within a context manager. This ensures that# application lifespan runs for every test case.withTestClient(app)astest_client:yieldtest_client

[8]ページ先頭

©2009-2026 Movatter.jp