Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

How can I pass the configuration in the app?#8056

Answeredbydmontagu
Anti-user asked this question inQuestions
Discussion options

How can I pass the configuration in the app? Can I do it in some way like it was in Flask with app.config, or this framework manages it differently?

You must be logged in to vote

@sandys does pydanticBaseSettings not work for you? It allows you to pass values at instantiation time or via environment variable (and is type safe to boot!).

A more complete example:

fromfunctoolsimportlru_cachefromtypingimportListfrompydanticimportBaseSettingsclassAPISettings(BaseSettings):api_v1_route:str="/api/v1"openapi_route:str="/api/v1/openapi.json"backend_cors_origins_str:str=""# Should be a comma-separated list of originsdebug:bool=Falsedebug_exceptions:bool=Falsedisable_superuser_dependency:bool=Falseinclude_admin_routes:bool=False@propertydefbackend_cors_origins(self)->List[str]:

Replies: 29 comments 1 reply

Comment options

You will be able to pass anything you want to app.state I've starlette ison 0.12.9Le jeu. 5 sept. 2019 à 5:14 PM, Artsiom Dolatau <notifications@github.com>a écrit :
How can I pass the configuration in the app? Can I do it in some simple way like it was in Flask with app.config, or this framework doesn't support even this? — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub <#508>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAINSPQ5XZ73CSBHDJMJSPTQIEO3PANCNFSM4IT7DHBA> .
You must be logged in to vote
0 replies
Comment options

dmontagu
Sep 5, 2019
Collaborator

I typically use a subclass ofpydantic.BaseSettings so I can read config from the environment, then create anlru_cached function that returns a config instance, then wherever I need access to a config setting I just call thelru_cached function to get the config and read the setting off of it.

You must be logged in to vote
0 replies
Comment options

i have the same question here - what is the equivalent of app.config in flask ?https://flask.palletsprojects.com/en/1.1.x/config/

to specific, are there any convenience functions similar to

app.config.from_object('yourapplication.default_settings')app.config.from_envvar('YOURAPPLICATION_SETTINGS')

we need to load different configurations based on production or staging environment.

You must be logged in to vote
0 replies
Comment options

No there are no convenience functions like that.Le mar. 17 sept. 2019 à 7:53 PM, Sandeep Srinivasa <notifications@github.com>a écrit :
i have the same question here - what is the equivalent of app.config in flask ?https://flask.palletsprojects.com/en/1.1.x/config/ to specific, are there any convenience functions similar to app.config.from_object('yourapplication.default_settings') app.config.from_envvar('YOURAPPLICATION_SETTINGS') — You are receiving this because you commented. Reply to this email directly, view it on GitHub <#508>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAINSPQKZC5QSJGFW5YRFKDQKEKQFANCNFSM4IT7DHBA> .
You must be logged in to vote
0 replies
Comment options

@sandys does pydanticBaseSettings not work for you? It allows you to pass values at instantiation time or via environment variable (and is type safe to boot!).

A more complete example:

fromfunctoolsimportlru_cachefromtypingimportListfrompydanticimportBaseSettingsclassAPISettings(BaseSettings):api_v1_route:str="/api/v1"openapi_route:str="/api/v1/openapi.json"backend_cors_origins_str:str=""# Should be a comma-separated list of originsdebug:bool=Falsedebug_exceptions:bool=Falsedisable_superuser_dependency:bool=Falseinclude_admin_routes:bool=False@propertydefbackend_cors_origins(self)->List[str]:return [x.strip()forxinself.backend_cors_origins_str.split(",")ifx]classConfig:env_prefix=""@lru_cache()defget_api_settings()->APISettings:returnAPISettings()# reads variables from environment

If you want something more fundamentally different as a function of the production vs. staging vs. testing environment (e.g., rather than setting each environment variable differently), you could just put some logic insideget_api_settings based on the environment variable value.

Accessing the config in your app is then as simple as, for example,debug = get_api_settings().debug.

You must be logged in to vote
0 replies
Answer selected byKludex
Comment options

thanks for replying.im not sure how to use it. i read on other issues by@tiangolo thatapp.state should be used. So I'm not entirely sure what is the right way toconfigure and setup a global configuration object in fastapi.
On Wed, Sep 18, 2019 at 12:40 AM dmontagu ***@***.***> wrote:@sandys <https://github.com/sandys> does pydantic BaseSettings not work for you? It allows you to pass values at instantiation time or via environment variable (and is type safe to boot!). — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#508>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAASYU65KG3K4DPGXPRGVU3QKETRHANCNFSM4IT7DHBA> .
You must be logged in to vote
0 replies
Comment options

You should not useapp.state yet -- I don't think it's even supported currently (@euri10 has a pull request to add support).

However, even if itwere supported, I would advise against usingapp.state forconfiguration if possible -- it is intended for storing applicationstate, which may change over time, and was created so that thatstate could be accessed and modified from requests. I am having a hard time imagining a scenario in which accessing/modifying the applicationconfiguration in that way is a good idea -- I think in most cases it would be an anti-pattern.

Also, it is not mypy / completion-friendly, which I think is especially useful for config settings.

You must be logged in to vote
0 replies
Comment options

Thanks. That's super super helpful to know.In that case, is there an example to show the right way to use pydantic inthis way
On Wed, 18 Sep, 2019, 00:57 dmontagu, ***@***.***> wrote: You should not use app.state yet -- I don't think it's even supported currently ***@***.*** <https://github.com/euri10> has a pull request to add support). However, even if it *were* supported, I would advise against using app.state for *configuration* if possible -- it is intended for storing application *state*, which may change over time. Also, it is not mypy / completion-friendly, which I think is especially useful for config settings. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#508>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAASYU4FTIM6CV5V7GGLYX3QKEVR3ANCNFSM4IT7DHBA> .
You must be logged in to vote
0 replies
Comment options

Is the example I posted above not clear enough?

Without going into all the nuances of everything my utility functions are doing, this is roughly what it looks like when I'm creating my server using configuration:

defget_app()->FastAPI:app_settings=get_app_settings()api_settings=get_api_settings()# see example aboveserver=FastAPI(title=app_settings.project_name,openapi_url=api_settings.openapi_route,debug=api_settings.debug)server.include_router(get_api_router(),prefix=api_settings.api_v1_route)@server.get("/",include_in_schema=False)defredirect_to_docs()->RedirectResponse:returnRedirectResponse("/docs")@server.on_event("startup")asyncdefconnect_to_database()->None:database=get_database()ifnotdatabase.is_connected:awaitdatabase.connect()@server.on_event("shutdown")asyncdefshutdown()->None:database=get_database()ifdatabase.is_connected:awaitdatabase.disconnect()static_files_app=StaticFiles(directory=str(app_settings.static_dir))server.mount(path=app_settings.static_mount_path,app=static_files_app,name="static")setup_api(server,api_settings,use_session_middleware=app_settings.use_session_middleware)setup_openapi_schemas(server)add_timing_middleware(server,exclude="StaticFiles")returnserverapp=get_app()

(Placing the setup in a function like this makes it easy to modify the configuration and re-instantiate the app with the new configuration in tests.)

You must be logged in to vote
1 reply
@Maxwilson1101
Comment options

Thanks for your detailed example! Can I conclude that using aclosure toinject the app configuration context is a recommended approach?

Comment options

Also, pydantic hasdocs about using BaseSettings that you might find useful.

You must be logged in to vote
0 replies
Comment options

Classy and very elegant example of leveraging pydantic@dmontagu as always (I think the checks on whether the db is connected are unnecessary 😉)!
Another option is to use Starlette Config.

You must be logged in to vote
0 replies
Comment options

@dmontagu@euri10 which one would you both recommend ? Starlette Config or Pydantic ? Since fastapi is fundamentally based on Starlette, would Starlette Config be the more long-term safer way of doing this ?

You must be logged in to vote
0 replies
Comment options

@dmontagu@euri10 which one would you both recommend ? Starlette Config or Pydantic ? Since fastapi is fundamentally based on Starlette, would Starlette Config be the more long-term safer way of doing this ?

I wouldn't recommendConfig based only on the fact that FastAPI is based on Starlette since theBaseSettings class is from pydantic and FastAPI relies on it at least as much as it does on Starlette.

FastAPI is not opinionated, find what works best for you, if the real question about safety is : do you think one or the other has more or less chances to be maintained over a long period of time, then I think both have equal chances, if not more for pydantic BaseSettings, but that's pure guess.

You must be logged in to vote
0 replies
Comment options

@sandys I personally think pydantic's is more flexible, powerful, plays better with autocompletion/IDEs, and the list goes on. If you are already using fastapi, I'd definitely recommend it; might as well take advantage of the dependencies you are already including.

I now use pydantic in most of my projects (even if they aren't based on fastapi) because of how usefulBaseModel (andBaseSettings) are.

The starlette config has no nice way of handling type-safety or autocompletion. It's not an unreasonable choice, and if you were only using pydantic for the settings I might drop it in favor of fewer dependencies (then again, I might not, but I'm biased :D). But I think pydantic has a lot to offer here.

Pydantic is very close to a 1.0 release right now (I think the target is some time in the next month); I think it will be safe to depend on pydantic in the long term.

You must be logged in to vote
0 replies
Comment options

@tiangolo@euri10 Any chance to getapp.state pull request#502 fixed and merged? Thanks!

You must be logged in to vote
0 replies
Comment options

I've got no merge powers, nor any powers at all, I could make use of thisfor sure too instead of having to install my fork, that said@tiangoloseems to be very busy at the moment and wishing him the best is all we cando !
On Thu, Oct 3, 2019 at 1:36 AM Dmitry ***@***.***> wrote:@tiangolo <https://github.com/tiangolo>@euri10 <https://github.com/euri10> Any chance to get app.state pull request#502 <#502> fixed and merged? Thanks! — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#508>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAINSPVZP2P5VIS2EZDK3JDQMUV75ANCNFSM4IT7DHBA> .
You must be logged in to vote
0 replies
Comment options

dmontagu
Oct 3, 2019
Collaborator

For what it's worth, in the interim you can easily subclass FastAPI and add your ownstate class:

classState(object):"""    Straight out of Starlette    """def__init__(self,state:typing.Dict=None):ifstateisNone:state= {}super(State,self).__setattr__("_state",state)def__setattr__(self,key:typing.Any,value:typing.Any)->None:self._state[key]=valuedef__getattr__(self,key:typing.Any)->typing.Any:try:returnself._state[key]exceptKeyError:message="'{}' object has no attribute '{}'"raiseAttributeError(message.format(self.__class__.__name__,key))def__delattr__(self,key:typing.Any)->None:delself._state[key]classMyFastAPI(FastAPI):ifnottyping.TYPE_CHECKING:# ensures you still get init-signature type checking from mypydef__init__(self,*args,**kwargs):super().__init__(*args,**kwargs)self.state=State()

(I have done this myself.)

You must be logged in to vote
0 replies
Comment options

@dmontagu Good idea! I guess I would subclass FastAPI and then just reusestarlette.datastructures.State directly.

UPD:starlette.requests.State for order version

You must be logged in to vote
0 replies
Comment options

About config, you don't need to useapp.state, you are not limited by that. You can use pure Python, and any package that you want. You can use it, it's available since some versions ago, but you don't have to use it.

You could use Starlette's config or PydanticBaseSettings. Or even justos.getenv(). I would suggest PydanticBaseSettings, we'll soon have docs with it.

I would also advise against usingapp.state for anything, the mentioned PR is already merged and youcan useapp.state if you want. But anAPIRouter wouldn't have access to that state. And I don't really have a use case for anything inapp.state yet that is not solvable in a simpler way.

Also, by not having to put anything throughapp.state makes your logic more independent of FastAPI. That way you could be able to use the same logic and configs in other environments. For example, in a task queue, that doesn't need to have FastAPI installed, but could still read settings from a PydanticBaseSettings object to connect to a DB, etc.

You must be logged in to vote
0 replies
Comment options

Thanks for your reply!This is very helpful.Just one request - could you make this using Starlette instead of Pydantic? It is more useful for us being in the base framework of Starlette itselfand maintaining compatibility with how Starlette will do it in the longterm
On Mon, 10 Feb, 2020, 23:16 Sebastián Ramírez, ***@***.***> wrote: About config, you don't need to use app.state, you are not limited by that. You can use pure Python, and any package that you want. You can use it, it's available since some versions ago, but you don't have to use it. You could use Starlette's config or Pydantic BaseSettings. Or even just os.getenv(). I would suggest Pydantic BaseSettings, we'll soon have docs with it. I would also advise against using app.state for anything, the mentioned PR is already merged and you *can* use app.state if you want. But an APIRouter wouldn't have access to that state. And I don't really have a use case for anything in app.state yet that is not solvable in a simpler way. Also, by not having to put anything through app.state makes your logic more independent of FastAPI. That way you could be able to use the same logic and configs in other environments. For example, in a task queue, that doesn't need to have FastAPI installed, but could still read settings from a Pydantic BaseSettings object to connect to a DB, etc. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#508>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAASYU6XPQYDR7R26X22RQDRCGHGPANCNFSM4IT7DHBA> .
You must be logged in to vote
0 replies
Comment options

Hmm. Reading through here, I'm getting the sense that it's safe to assume that if I needed access to the settings, say usingBaseSettings, I'd need to call my settings method or useDepends to be able to use the app's settings throughout the life of the a request on the relevant endpoints?

You must be logged in to vote
0 replies
Comment options

You could use Starlette's config or PydanticBaseSettings. Or even justos.getenv(). I would suggest PydanticBaseSettings, we'll soon have docs with it.
Also, by not having to put anything through app.state makes your logic more independent of FastAPI. That way you could be able to use the same logic and configs in other environments. For example, in a task queue, that doesn't need to have FastAPI installed, but could still read settings from a Pydantic BaseSettings object to connect to a DB, etc.

@tiangolo did you have the chance to update docs (or alternatively - "full-stack-fastapi-postgresql") ? would love to use Starlette config system in fastapi (especially in the task-queue usecase ?

it seems that there is a pull-request for pydantic basesettings (fastapi/full-stack-fastapi-template#87), however was wondering if Starlette config is equally viable .

You must be logged in to vote
0 replies
Comment options

Here are the new docs for using Pydantic settings for handling configurations in FastAPI:https://fastapi.tiangolo.com/advanced/settings/ 🎉

@Shackelford-Arden yeah, you could do that. Check the new docs for examples.

@sandys yeah, you could use Starlette's config too, but I recommend Pydantic's Settings. And also it would be the suggested config system for FastAPI as it works the same way as Pydantic models, that FastAPI users already know how to use. 🤓

You must be logged in to vote
0 replies
Comment options

Thanks for the new docs !!
On Sun, 5 Apr, 2020, 01:22 Sebastián Ramírez, ***@***.***> wrote: Here are the new docs for using Pydantic settings for handling configurations in FastAPI:https://fastapi.tiangolo.com/advanced/settings/ 🎉@Shackelford-Arden <https://github.com/Shackelford-Arden> yeah, you could do that. Check the new docs for examples.@sandys <https://github.com/sandys> yeah, you could use Starlette's config too, but I recommend Pydantic's Settings. And also it would be the suggested config system for FastAPI as it works the same way as Pydantic models, that FastAPI users already know how to use. 🤓 — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#508 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAASYU2U75HZMZ66ZDNA7QLRK6FWDANCNFSM4IT7DHBA> .
You must be logged in to vote
0 replies
Comment options

Really though, thanks@tiangolo ! I did already make the move to Pydantic but thank you for adding it here as well!

You must be logged in to vote
0 replies
Comment options

One request - if you haven't, please update yourhttps://github.com/tiangolo/full-stack-fastapi-postgresql/ repoThat is the golden repo for a new project template for us.
On Sun, 5 Apr, 2020, 01:56 Arden Shackelford, ***@***.***> wrote: Really though, thanks@tiangolo <https://github.com/tiangolo> ! I did already make the move to Pydantic but thank you for adding it here as well! — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#508 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/AAASYU2Y4AY3664UNKK44E3RK6JZBANCNFSM4IT7DHBA> .
You must be logged in to vote
0 replies
Comment options

Great!@Shackelford-Arden

@sandys yeah, of course that's on the backlog 🤓 . I have several things to update there as soon as I can, but I also have a lot of things to handle in FastAPI itself, and a lot of issues to answer... 😰

So, for now, I think this specific issue is solved... ✔️

You must be logged in to vote
0 replies
Comment options

Assuming the original issue was solved, it will be automatically closed now. But feel free to add more comments or create new issues.

You must be logged in to vote
0 replies
Comment options

I have to disagree with the use oflru_cache for settings. Normally when testing, you want to use application factories with different configurations:

defcreate_app(**custom_parameters)->FastAPI:settings=get_settings(**custom_parameters)app=FastAPI(title=settings.project_name, ...)    ...returnapp

The problem with this is thatlru_cache caches according to the imput, so if in the dependency it callsget_settings() with different arguments, the settings may not be the correct ones.

For example, in some cases I change the database uri:

@test_framework.fixturedefmy_app(custom_settings):returncreate_app(db_uri="db://somewhere_testing",**custom_settings)

It does never reaches the db dependency:

defget_db(settings:Settings=Depends(get_settings), ...):    ...returnDBSession(settings.db_uri, ...)

In this casesettings might not havedb_uri="db://somewhere_testing" but whatwever other uri was configured whenget_settings() is called (without arguments).

For those who do not want to rely inlru_cache you can userequest.app.state.config, see#8239 (comment).

You must be logged in to vote
0 replies
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Labels
questionQuestion or problemquestion-migrate
9 participants
@Anti-user@sandys@euri10@tiangolo@Shackelford-Arden@imsedim@dmontagu@Maxwilson1101@BorjaEst
Converted from issue

This discussion was converted from issue #508 on February 28, 2023 11:55.


[8]ページ先頭

©2009-2025 Movatter.jp