Skip to content

Commit 0022b1c

Browse files
committed
steps
1 parent 8f02822 commit 0022b1c

File tree

1 file changed

+108
-118
lines changed

1 file changed

+108
-118
lines changed

source/integrations/fastapi-integration.txt

Lines changed: 108 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -56,162 +56,152 @@ Prerequisites
5656
<https://docs.atlas.mongodb.com/getting-started/>`__ guide to create your
5757
account and MongoDB cluster.
5858

59-
Set-up
60-
~~~~~~
59+
.. step:: Set-up
6160

62-
1. Clone the example code from the `mongodb-with-fastapi repository <https://github.com/mongodb-developer/mongodb-with-fastapi>`__:
61+
.. step:: Clone the example code from the `mongodb-with-fastapi repository <https://github.com/mongodb-developer/mongodb-with-fastapi>`__:
6362

64-
.. code-block:: shell
63+
.. code-block:: shell
6564

66-
git clone [email protected]:mongodb-developer/mongodb-with-fastapi.git
65+
git clone [email protected]:mongodb-developer/mongodb-with-fastapi.git
6766

68-
#. Install the required dependencies listed in the ``requirements.txt`` file:
67+
.. step:: Install the required dependencies listed in the ``requirements.txt`` file:
6968

70-
.. tip:: Use a Virtual environment
69+
.. tip:: Use a Virtual environment
7170

72-
Installing your Python dependencies in a `virtualenv
73-
<https://docs.python.org/3/tutorial/venv.html>`__ with allow for versions
74-
of the libraries to be install for individual projects. Before running
75-
pip, ensure your ``virtualenv`` is active.
71+
Installing your Python dependencies in a `virtualenv
72+
<https://docs.python.org/3/tutorial/venv.html>`__ with allow for versions
73+
of the libraries to be install for individual projects. Before running
74+
pip, ensure your ``virtualenv`` is active.
7675

77-
.. code-block:: shell
76+
.. code-block:: shell
7877

79-
cd mongodb-with-fastapi
80-
pip install -r requirements.txt
78+
cd mongodb-with-fastapi
79+
pip install -r requirements.txt
8180

82-
It may take a few moments to download and install your dependencies.
81+
It may take a few moments to download and install your dependencies.
8382

84-
#. Create an environment variable for your MongoDB connection string:
83+
.. step:: Create an environment variable for your MongoDB connection string:
8584

86-
.. code-block:: shell
85+
.. code-block:: shell
8786

88-
export MONGODB_URL="mongodb+srv://<username>:<password>@<url>/<db>?retryWrites=true&w=majority"
87+
export MONGODB_URL="mongodb+srv://<username>:<password>@<url>/<db>?retryWrites=true&w=majority"
8988

90-
.. tip:: Reset Environment Variables
89+
.. tip:: Reset Environment Variables
9190

92-
Anytime you start a new terminal session, you will need to reset this
93-
environment variable. You can use `direnv <https://direnv.net/>`__ to make
94-
this process easier.
91+
Anytime you start a new terminal session, you will need to reset this
92+
environment variable. You can use `direnv <https://direnv.net/>`__ to make
93+
this process easier.
9594

96-
#. Start your FastAPI server:
95+
.. step:: Start your FastAPI server:
9796

98-
.. code-block:: shell
97+
.. code-block:: shell
9998

100-
uvicorn app:app --reload
99+
uvicorn app:app --reload
101100

102-
.. image:: /includes/integrations/fastapi-terminal.png
103-
:alt: Screenshot of terminal running FastAPI
101+
.. image:: /includes/integrations/fastapi-terminal.png
102+
:alt: Screenshot of terminal running FastAPI
104103

105-
Once the application has started, you can view it in your browser at http://127.0.0.1:8000/docs.
104+
Once the application has started, you can view it in your browser at http://127.0.0.1:8000/docs.
106105

107-
.. image:: /includes/integrations/fastapi-browser.png
108-
:alt: Screenshot of browser and swagger UI
106+
.. image:: /includes/integrations/fastapi-browser.png
107+
:alt: Screenshot of browser and swagger UI
109108

110-
Create Your Application
111-
~~~~~~~~~~~~~~~~~~~~~~~
109+
.. step:: Create Your Application
112110

113-
All the code for the example application is stored in ``app.py``.
111+
All the code for the example application is stored in ``app.py``.
114112

115-
1. Connect to your MongoDB Atlas cluster using the asynchronous `Pymongo Driver
116-
<https://www.mongodb.com/docs/languages/python/pymongo-driver/current>`__,
117-
then specify the database named ``college``:
113+
Connect to your MongoDB Atlas cluster using the asynchronous `Pymongo Driver <https://www.mongodb.com/docs/languages/python/pymongo-driver/current>`__, then specify the database named ``college``:
118114

119115
.. code-block:: python
120116

121117
client = AsyncMongoClient(MONGODB_URL, server_api=pymongo.server_api.ServerApi(version="1", strict=True, deprecation_errors=True))
122118
db = client.get_database("college")
123119
student_collection = db.get_collection("students")
124120

125-
The _id Attribute and ObjectIds
126-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
127-
128-
.. code-block:: python
129-
130-
# Represents an ObjectId field in the database.
131-
# It will be represented as a `str` on the model so that it can be serialized to JSON.
132-
PyObjectId = Annotated[str, BeforeValidator(str)]
133-
134-
135-
136-
Database Models
137-
~~~~~~~~~~~~~~~
138-
Our application has three models, the ``StudentModel``, the ``UpdateStudentModel``, and the ``StudentCollection``.
121+
.. step:: Define Your Database Models
122+
123+
Our application has three models, the ``StudentModel``, the ``UpdateStudentModel``, and the ``StudentCollection``.
139124

140-
.. code-block:: python
125+
.. code-block:: python
141126

142-
class StudentModel(BaseModel):
143-
"""
144-
Container for a single student record.
145-
"""
146-
147-
# The primary key for the StudentModel, stored as a `str` on the instance.
148-
# This will be aliased to ``_id`` when sent to MongoDB,
149-
# but provided as ``id`` in the API requests and responses.
150-
id: Optional[PyObjectId] = Field(alias="_id", default=None)
151-
name: str = Field(...)
152-
email: EmailStr = Field(...)
153-
course: str = Field(...)
154-
gpa: float = Field(..., le=4.0)
155-
model_config = ConfigDict(
156-
populate_by_name=True,
157-
arbitrary_types_allowed=True,
158-
json_schema_extra={
159-
"example": {
160-
"name": "Jane Doe",
161-
"email": "[email protected]",
162-
"course": "Experiments, Science, and Fashion in Nanophotonics",
163-
"gpa": 3.0,
164-
}
165-
},
166-
)
167-
168-
This is the primary model we use as the `response model <https://fastapi.tiangolo.com/tutorial/response-model/>`__ for the majority of our endpoints.
169-
170-
I want to draw attention to the ``id`` field on this model. MongoDB uses ``_id``, but in Python, underscores at the start of attributes have special meaning. If you have an attribute on your model that starts with an underscore, `pydantic <https://pydantic-docs.helpmanual.io/>`__—the data validation framework used by FastAPI—will assume that it is a private variable, meaning you will not be able to assign it a value! To get around this, we name the field ``id`` but give it an alias of ``_id``. You also need to set ``populate_by_name`` to ``True`` in the model's ``model_config``
171-
172-
We set this ``id`` value automatically to ``None``, so you do not need to supply it when creating a new student.
127+
# Represents an ObjectId field in the database.
128+
# It will be represented as a `str` on the model so that it can be
129+
serialized to JSON.
130+
PyObjectId = Annotated[str, BeforeValidator(str)]
131+
132+
class StudentModel(BaseModel):
133+
"""
134+
Container for a single student record.
135+
"""
136+
137+
# The primary key for the StudentModel, stored as a `str` on the instance.
138+
# This will be aliased to ``_id`` when sent to MongoDB,
139+
# but provided as ``id`` in the API requests and responses.
140+
id: Optional[PyObjectId] = Field(alias="_id", default=None)
141+
name: str = Field(...)
142+
email: EmailStr = Field(...)
143+
course: str = Field(...)
144+
gpa: float = Field(..., le=4.0)
145+
model_config = ConfigDict(
146+
populate_by_name=True,
147+
arbitrary_types_allowed=True,
148+
json_schema_extra={
149+
"example": {
150+
"name": "Jane Doe",
151+
"email": "[email protected]",
152+
"course": "Experiments, Science, and Fashion in Nanophotonics",
153+
"gpa": 3.0,
154+
}
155+
},
156+
)
157+
158+
This is the primary model we use as the `response model <https://fastapi.tiangolo.com/tutorial/response-model/>`__ for the majority of our endpoints.
159+
160+
I want to draw attention to the ``id`` field on this model. MongoDB uses ``_id``, but in Python, underscores at the start of attributes have special meaning. If you have an attribute on your model that starts with an underscore, `pydantic <https://pydantic-docs.helpmanual.io/>`__—the data validation framework used by FastAPI—will assume that it is a private variable, meaning you will not be able to assign it a value! To get around this, we name the field ``id`` but give it an alias of ``_id``. You also need to set ``populate_by_name`` to ``True`` in the model's ``model_config``
161+
162+
We set this ``id`` value automatically to ``None``, so you do not need to supply it when creating a new student.
173163

174-
.. code-block:: python
164+
.. code-block:: python
175165

176-
class UpdateStudentModel(BaseModel):
177-
"""
178-
A set of optional updates to be made to a document in the database.
179-
"""
180-
181-
name: Optional[str] = None
182-
email: Optional[EmailStr] = None
183-
course: Optional[str] = None
184-
gpa: Optional[float] = None
185-
model_config = ConfigDict(
186-
arbitrary_types_allowed=True,
187-
json_encoders={ObjectId: str},
188-
json_schema_extra={
189-
"example": {
190-
"name": "Jane Doe",
191-
"email": "[email protected]",
192-
"course": "Experiments, Science, and Fashion in Nanophotonics",
193-
"gpa": 3.0,
194-
}
195-
},
196-
)
197-
198-
The ``UpdateStudentModel`` has two key differences from the ``StudentModel``:
199-
200-
- It does not have an ``id`` attribute as this cannot be modified.
201-
- All fields are optional, so you only need to supply the fields you wish to update.
202-
203-
Finally, ``StudentCollection`` is defined to encapsulate a list of ``StudentModel`` instances. In theory, the endpoint could return a top-level list of StudentModels, but there are some vulnerabilities associated with returning JSON responses with top-level lists.
166+
class UpdateStudentModel(BaseModel):
167+
"""
168+
A set of optional updates to be made to a document in the database.
169+
"""
170+
171+
name: Optional[str] = None
172+
email: Optional[EmailStr] = None
173+
course: Optional[str] = None
174+
gpa: Optional[float] = None
175+
model_config = ConfigDict(
176+
arbitrary_types_allowed=True,
177+
json_encoders={ObjectId: str},
178+
json_schema_extra={
179+
"example": {
180+
"name": "Jane Doe",
181+
"email": "[email protected]",
182+
"course": "Experiments, Science, and Fashion in Nanophotonics",
183+
"gpa": 3.0,
184+
}
185+
},
186+
)
187+
188+
The ``UpdateStudentModel`` has two key differences from the ``StudentModel``:
189+
190+
- It does not have an ``id`` attribute as this cannot be modified.
191+
- All fields are optional, so you only need to supply the fields you wish to update.
192+
193+
Finally, ``StudentCollection`` is defined to encapsulate a list of ``StudentModel`` instances. In theory, the endpoint could return a top-level list of StudentModels, but there are some vulnerabilities associated with returning JSON responses with top-level lists.
204194

205-
.. code-block:: python
195+
.. code-block:: python
206196

207-
class StudentCollection(BaseModel):
208-
"""
209-
A container holding a list of `StudentModel` instances.
197+
class StudentCollection(BaseModel):
198+
"""
199+
A container holding a list of `StudentModel` instances.
210200

211-
This exists because providing a top-level array in a JSON response can be a `vulnerability <https://haacked.com/archive/2009/06/25/json-hijacking.aspx/>`__
212-
"""
201+
This exists because providing a top-level array in a JSON response can be a `vulnerability <https://haacked.com/archive/2009/06/25/json-hijacking.aspx/>`__
202+
"""
213203

214-
students: List[StudentModel]
204+
students: List[StudentModel]
215205

216206
Application Routes
217207
~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)