@ -0,0 +1,298 @@ |
|||
# এনভায়রনমেন্ট ভেরিয়েবলস |
|||
|
|||
/// tip |
|||
|
|||
আপনি যদি "এনভায়রনমেন্ট ভেরিয়েবলস" কী এবং সেগুলো কীভাবে ব্যবহার করতে হয় সেটা জানেন, তাহলে এই অংশটি স্কিপ করে যেতে পারেন। |
|||
|
|||
/// |
|||
|
|||
এনভায়রনমেন্ট ভেরিয়েবল (সংক্ষেপে "**env var**" নামেও পরিচিত) হলো এমন একটি ভেরিয়েবল যা পাইথন কোডের **বাইরে**, **অপারেটিং সিস্টেমে** থাকে এবং আপনার পাইথন কোড (বা অন্যান্য প্রোগ্রাম) দ্বারা যাকে রিড করা যায়। |
|||
|
|||
এনভায়রনমেন্ট ভেরিয়েবলস অ্যাপ্লিকেশনের **সেটিংস** পরিচালনা করতে, পাইথনের **ইনস্টলেশন** প্রক্রিয়ার অংশ হিসেবে, ইত্যাদি কাজে উপযোগী হতে পারে। |
|||
|
|||
## Env Vars তৈরী এবং ব্যবহার |
|||
|
|||
আপনি **শেল (টার্মিনাল)**-এ, পাইথনের প্রয়োজন ছাড়াই, এনভায়রনমেন্ট ভেরিয়েবলস **তৈরি** এবং ব্যবহার করতে পারবেনঃ |
|||
|
|||
//// tab | লিনাক্স, ম্যাকওএস, উইন্ডোজ Bash |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
// আপনি চাইলে MY_NAME নামে একটি env var তৈরি করতে পারেন |
|||
$ export MY_NAME="Wade Wilson" |
|||
|
|||
// তারপরে এটিকে চাইলে অন্যান্য প্রোগ্রামে ব্যবহার করতে পারেন |
|||
$ echo "Hello $MY_NAME" |
|||
|
|||
Hello Wade Wilson |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | উইন্ডোজ পাওয়ারশেল |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
// MY_NAME নামে env var তৈরি |
|||
$ $Env:MY_NAME = "Wade Wilson" |
|||
|
|||
// অন্যান্য প্রোগ্রামে এটিকে ব্যবহার |
|||
$ echo "Hello $Env:MY_NAME" |
|||
|
|||
Hello Wade Wilson |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
## পাইথনে env vars রিড করা |
|||
|
|||
আপনি চাইলে পাইথনের **বাইরে**, টার্মিনালে (বা অন্য কোনো উপায়ে) এনভায়রনমেন্ট ভেরিয়েবলস তৈরি করতে পারেন, এবং পরে সেগুলো **পাইথনে রিড** (অ্যাক্সেস করতে) পারেন। |
|||
|
|||
উদাহরণস্বরূপ, আপনার `main.py` নামে একটি ফাইল থাকতে পারেঃ |
|||
|
|||
```Python hl_lines="3" |
|||
import os |
|||
|
|||
name = os.getenv("MY_NAME", "World") |
|||
print(f"Hello {name} from Python") |
|||
``` |
|||
|
|||
/// tip |
|||
|
|||
<a href="https://docs.python.org/3.8/library/os.html#os.getenv" class="external-link" target="_blank">`os.getenv()`</a> এর দ্বিতীয় আর্গুমেন্টটি হলো এর ডিফল্ট ভ্যালু যা রিটার্ন করা হবে। |
|||
|
|||
যদি এটি দেওয়া না হয়, ডিফল্টভাবে `None` ব্যবহৃত হবে, এখানে আমরা ডিফল্ট ভ্যালু হিসেবে `"World"` ব্যবহার করেছি। |
|||
|
|||
/// |
|||
|
|||
তারপরে পাইথন প্রোগ্রামটিকে নিম্নোক্তভাবে কল করা যাবেঃ |
|||
|
|||
//// tab | লিনাক্স, ম্যাকওএস, উইন্ডোজ Bash |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
// এখনো আমরা এনভায়রনমেন্ট ভেরিয়েবল সেট করিনি |
|||
$ python main.py |
|||
|
|||
// যেহেতু env var সেট করা হয়নি, তাই আমরা ডিফল্ট ভ্যালু পাচ্ছি |
|||
|
|||
Hello World from Python |
|||
|
|||
// কিন্তু আমরা প্রথমে যদি একটা এনভায়রনমেন্ট ভারিয়েবল তৈরি করে নেই |
|||
$ export MY_NAME="Wade Wilson" |
|||
|
|||
// এবং তারপর আবার প্রোগ্রাটিকে কল করি |
|||
$ python main.py |
|||
|
|||
// এখন এটি এনভায়রনমেন্ট ভেরিয়েবল রিড করতে পারবে |
|||
|
|||
Hello Wade Wilson from Python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | উইন্ডোজ পাওয়ারশেল |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
// এখনো আমরা এনভায়রনমেন্ট ভেরিয়েবল সেট করিনি |
|||
$ python main.py |
|||
|
|||
// যেহেতু env var সেট করা হয়নি, তাই আমরা ডিফল্ট ভ্যালু পাচ্ছি |
|||
|
|||
Hello World from Python |
|||
|
|||
// কিন্তু আমরা প্রথমে যদি একটা এনভায়রনমেন্ট ভারিয়েবল তৈরি করে নেই |
|||
$ $Env:MY_NAME = "Wade Wilson" |
|||
|
|||
// এবং তারপর আবার প্রোগ্রাটিকে কল করি |
|||
$ python main.py |
|||
|
|||
// এখন এটি এনভায়রনমেন্ট ভেরিয়েবল রিড করতে পারবে |
|||
|
|||
Hello Wade Wilson from Python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
যেহেতু এনভায়রনমেন্ট ভেরিয়েবলস কোডের বাইরে সেট করা যায়, কিন্তু পরবর্তীতে কোড দ্বারা রিড করা যায়, এবং বাকি ফাইলগুলোর সাথে রাখতে (`git` এ কমিট) হয় না, তাই কনফিগারেশনস বা **সেটিংস** এর জন্য এগুলো সাধারণত ব্যবহৃত হয়ে থাকে। |
|||
|
|||
আপনি একটি এনভায়রনমেন্ট ভেরিয়েবল শুধুমাত্র একটি **নির্দিষ্ট প্রোগ্রাম ইনভোকেশনের** জন্যও তৈরি করতে পারেন, যা শুধুমাত্র সেই প্রোগ্রামের জন্যই এভেইলেবল থাকবে এবং শুধুমাত্র তার চলাকালীন সময় পর্যন্তই সক্রিয় থাকবে। |
|||
|
|||
এটি করতে, প্রোগ্রামটি রান করার ঠিক আগেই, একই লাইনে এনভায়রনমেন্ট ভেরিয়েবল তৈরি করুন: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
// প্রোগ্রামটি কল করার সময় একই লাইনে MY_NAME এনভায়রনমেন্ট ভেরিয়েবল তৈরি করুন |
|||
$ MY_NAME="Wade Wilson" python main.py |
|||
|
|||
// এখন এটি এনভায়রনমেন্ট ভ্যরিয়েবলটিকে রিড করতে পারবে |
|||
|
|||
Hello Wade Wilson from Python |
|||
|
|||
// পরবর্তীতে এনভায়রনমেন্ট ভেরিয়েবলটিকে আর ব্যবহার করা যাচ্ছে না |
|||
$ python main.py |
|||
|
|||
Hello World from Python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
/// tip |
|||
|
|||
এটি নিয়ে আরো বিস্তারিত পড়তে পারেন এখানে <a href="https://12factor.net/config" class="external-link" target="_blank">The Twelve-Factor App: Config</a>। |
|||
|
|||
/// |
|||
|
|||
## টাইপস এবং ভ্যালিডেশন |
|||
|
|||
এই এনভায়রনমেন্ট ভেরিয়েবলগুলো শুধুমাত্র **টেক্সট স্ট্রিংস** হ্যান্ডেল করতে পারে, যেহেতু এগুলো পাইথনের বাইরে অবস্থিত এবং অন্যান্য প্রোগ্রাম এবং সিস্টেমের বাকি অংশের (এমনকি বিভিন্ন অপারেটিং সিস্টেম যেমন লিনাক্স, উইন্ডোজ, ম্যাকওএস) সাথে সামঞ্জস্যপূর্ণ হতে হয়। |
|||
|
|||
এর অর্থ হচ্ছে পাইথনে এনভায়রনমেন্ট ভেরিয়েবল থেকে রিড করা **যেকোনো ভ্যালু** একটি `str` হবে, এবং অন্য কোনো টাইপে কনভার্সন বা যেকোনো ভেলিডেশন কোডে আলাদাভাবে করতে হবে। |
|||
|
|||
এনভায়রনমেন্ট ভেরিয়েবল ব্যবহার করে **এপ্লিকেশন সেটিংস** হ্যান্ডেল করা নিয়ে আরো বিস্তারিত জানা যাবে [Advanced User Guide - Settings and Environment Variables](./advanced/settings.md){.internal-link target=_blank}. |
|||
|
|||
## `PATH` এনভায়রনমেন্ট ভেরিয়েবল |
|||
|
|||
**`PATH`** নামে একটি **বিশেষ** এনভায়রনমেন্ট ভেরিয়েবল রয়েছে, যেটি প্রোগ্রাম রান করার জন্য অপারেটিং সিস্টেমস (লিনাক্স, ম্যাকওএস, উইন্ডোজ) দ্বারা ব্যবহৃত হয়। |
|||
|
|||
`PATH` ভেরিয়েবল এর ভ্যালু হচ্ছে একটি বিশাল স্ট্রিং যা ডিরেক্টরিকে কোলন `:` দিয়ে আলাদা করার মাধ্যমে লিনাক্সে ও ম্যাকওএস এ, এবং সেমিকোলন `;` এর মাধ্যমে উইন্ডোজ এ তৈরি করা থাকে। |
|||
|
|||
উদাহরণস্বরূপ, `PATH` ভেরিয়েবল নিচের মতো দেখতে হতে পারেঃ |
|||
|
|||
//// tab | লিনাক্স, ম্যাকওএস |
|||
|
|||
```plaintext |
|||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin |
|||
``` |
|||
|
|||
তারমানে হলো সিস্টেম প্রোগ্রামগুলোকে নিচের ডিরেক্টরিগুলোতে খুঁজবেঃ |
|||
|
|||
* `/usr/local/bin` |
|||
* `/usr/bin` |
|||
* `/bin` |
|||
* `/usr/sbin` |
|||
* `/sbin` |
|||
|
|||
//// |
|||
|
|||
//// tab | উইন্ডোজ |
|||
|
|||
```plaintext |
|||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32 |
|||
``` |
|||
|
|||
তারমানে হলো সিস্টেম প্রোগ্রামগুলোকে নিচের ডিরেক্টরিগুলোতে খুঁজবেঃ |
|||
|
|||
* `C:\Program Files\Python312\Scripts` |
|||
* `C:\Program Files\Python312` |
|||
* `C:\Windows\System32` |
|||
|
|||
//// |
|||
|
|||
যখন আপনি টার্মিনালে কোনো **কমান্ড** লিখবেন, অপারেটিং সিস্টেম **প্রত্যেকটি ডিরেক্টরিতে** প্রোগ্রামটি **খুঁজবে** যেগুলো `PATH` এনভায়রনমেন্ট ভেরিয়েবল এ লিস্ট করা আছে। |
|||
|
|||
উদাহরণস্বরূপ, যখন আপনি টার্মিনালে `python` টাইপ করবেন, অপারেটিং সিস্টেম এই লিস্ট এর **প্রথম ডিরেক্টরিতে** `python` নামের একটি প্রোগ্রাম খুঁজবে। |
|||
|
|||
যদি এটি খুঁজে পায়, তাহলে এটি প্রোগ্রামটিকে ব্যবহার করবে। অন্যথায় এটি **অন্যান্য ডিরেক্টরিগুলোতে** এটিকে খুঁজতে থাকবে। |
|||
|
|||
### পাইথন ইনস্টল এবং `PATH` আপডেট |
|||
|
|||
যখন আপনি পাইথন ইনস্টল করেন, আপনি `PATH` এনভায়রনমেন্ট ভেরিয়েবল আপডেট করতে চান কিনা সেটা জিজ্ঞেস করা হতে পারে। |
|||
|
|||
//// tab | লিনাক্স, ম্যাকওএস |
|||
|
|||
ধরা যাক আপনি পাইথন ইনস্টল করলেন এবং এটি `/opt/custompython/bin` ডিরেক্টরিতে ইনস্টল হচ্ছে। |
|||
|
|||
যদি আপনি "Yes" সিলেক্ট করে `PATH` এনভায়রনমেন্ট ভেরিয়েবল আপডেট করতে চান, তাহলে ইনস্টলার `/opt/custompython/bin` কে `PATH` এনভায়রনমেন্ট ভেরিয়েবল এ এড করে দিবে। |
|||
|
|||
এটা দেখতে এমনটা হতে পারেঃ |
|||
|
|||
```plaintext |
|||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/custompython/bin |
|||
``` |
|||
|
|||
এইভাবে, আপনি যখন টার্মিনালে `python` টাইপ করেন, সিস্টেম পাইথন প্রোগ্রামটিকে `/opt/custompython/bin` (সর্বশেষ ডিরেক্টরি) তে খুঁজে পাবে এবং এটাকে ব্যবহার করবে। |
|||
|
|||
//// |
|||
|
|||
//// tab | উইন্ডোজ |
|||
|
|||
ধরা যাক আপনি পাইথন ইনস্টল করলেন এবং এটি `C:\opt\custompython\bin` ডিরেক্টরিতে ইনস্টল হচ্ছে। |
|||
|
|||
যদি আপনি "Yes" সিলেক্ট করে `PATH` এনভায়রনমেন্ট ভেরিয়েবল আপডেট করতে চান, তাহলে ইনস্টলার `C:\opt\custompython\bin` কে `PATH` এনভায়রনমেন্ট ভেরিয়েবল এ এড করে দিবে। |
|||
|
|||
```plaintext |
|||
C:\Program Files\Python312\Scripts;C:\Program Files\Python312;C:\Windows\System32;C:\opt\custompython\bin |
|||
``` |
|||
|
|||
এইভাবে, আপনি যখন টার্মিনালে `python` টাইপ করেন, সিস্টেম পাইথন প্রোগ্রামটিকে `C:\opt\custompython\bin` (সর্বশেষ ডিরেক্টরি) তে খুঁজে পাবে এবং এটাকে ব্যবহার করবে। |
|||
|
|||
//// |
|||
|
|||
তাই, আপনি যদি টাইপ করেনঃ |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// tab | লিনাক্স, ম্যাকওএস |
|||
|
|||
সিস্টেম `python` প্রোগ্রামকে `/opt/custompython/bin` এ **খুঁজে পাবে** এবং এটাকে রান করবে। |
|||
|
|||
এটা মোটামুটিভাবে নিচের মতো করে লেখার সমান হবেঃ |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ /opt/custompython/bin/python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | উইন্ডোজ |
|||
|
|||
সিস্টেম `python` প্রোগ্রামকে `C:\opt\custompython\bin\python` এ **খুঁজে পাবে** এবং এটাকে রান করবে। |
|||
|
|||
এটা মোটামুটিভাবে নিচের মতো করে লেখার সমান হবেঃ |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ C:\opt\custompython\bin\python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
এই তথ্যগুলো [ভার্চুয়াল এনভায়রনমেন্টস](virtual-environments.md){.internal-link target=_blank} শেখার ক্ষেত্রে সহায়ক হবে। |
|||
|
|||
## উপসংহার |
|||
|
|||
এর মাধ্যমে আপনি **এনভায়রনমেন্ট ভেরিয়েবলস** কি এবং এটিকে পাইথনে কিভাবে ব্যবহার করতে হয় তার সম্পর্কে বেসিক ধারনা পেলেন। |
|||
|
|||
চাইলে এই সম্পর্কে আরো বিস্তারিত পড়তে পারেন <a href="https://en.wikipedia.org/wiki/Environment_variable" class="external-link" target="_blank">Wikipedia for Environment Variable</a> এ। |
|||
|
|||
অনেক ক্ষেত্রে, দেখা মাত্রই এনভায়রনমেন্ট ভেরিয়েবল কীভাবে প্রয়োজন হবে তা স্পষ্ট হয় না। কিন্তু ডেভেলপমেন্টের সময় আপনি নানা রকম পরিস্থিতিতে এগুলোর সম্মুখীন হবেন, তাই এগুলো সম্পর্কে জেনে রাখা ভালো। |
|||
|
|||
উদাহরণস্বরূপ, আপনার এই ইনফরমেশনটি পরবর্তী, [ভার্চুয়াল এনভায়রনমেন্টস](virtual-environments.md) অংশে দরকার হবে। |
@ -1,106 +0,0 @@ |
|||
<mxfile host="65bd71144e"> |
|||
<diagram id="BkDNbdtn8_9fWQybnc8v" name="Page-1"> |
|||
<mxGraphModel dx="741" dy="1167" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="420" y="280" width="920" height="670" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="3" value="<font face="Roboto"><span style="font-size: 24px">Server</span></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="755" y="290" width="300" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="6" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="1110" y="410" width="190" height="500" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="7" value="<font style="font-size: 24px" face="Roboto">RAM<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="1166.92" y="420" width="76.16" height="30" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="9" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="470" y="410" width="250" height="500" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="10" value="<font style="font-size: 24px" face="Roboto">CPU<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="554.61" y="420" width="80.77" height="30" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;exitX=0.092;exitY=1.01;exitDx=0;exitDy=0;dashed=1;exitPerimeter=0;" parent="1" source="11" target="12" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="521"/> |
|||
<mxPoint x="800" y="560"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;" parent="1" source="11" target="13" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="820" y="525" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="680"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;endArrow=none;endFill=0;" parent="1" source="11" target="17" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="20" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="11" target="18" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="11" value="<font face="roboto"><span style="font-size: 24px">Process&nbsp;</span></font><span style="font-family: &#34;roboto&#34; ; font-size: 24px">Manager</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1"> |
|||
<mxGeometry x="780" y="420" width="250" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="12" target="23" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="12" value="<font face="roboto"><span style="font-size: 24px">Worker Process</span></font>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> |
|||
<mxGeometry x="840" y="540" width="240" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="26" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="13" target="24" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="13" target="22" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="775" y="710"/> |
|||
<mxPoint x="775" y="688"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="13" value="<font face="roboto"><span style="font-size: 24px">Worker Process</span></font>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1"> |
|||
<mxGeometry x="840" y="660" width="240" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="16" target="27" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="31" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="16" target="30" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="16" value="<font face="roboto"><span style="font-size: 24px">Another Process</span></font>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="780" y="790" width="250" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="17" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=3;fillColor=#d5e8d4;strokeColor=#82b366;dashed=1;" parent="1" vertex="1"> |
|||
<mxGeometry x="480" y="458" width="230" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="18" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=3;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1"> |
|||
<mxGeometry x="1130" y="460" width="150" height="20" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="21" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=3;fillColor=#fff2cc;strokeColor=#d6b656;dashed=1;" parent="1" vertex="1"> |
|||
<mxGeometry x="480" y="508" width="230" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="22" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=3;fillColor=#e1d5e7;strokeColor=#9673a6;dashed=1;" parent="1" vertex="1"> |
|||
<mxGeometry x="480" y="618" width="230" height="140" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="23" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">1 GB</font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=3;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> |
|||
<mxGeometry x="1130" y="490" width="150" height="150" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="24" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">1 GB</font>" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=3;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1"> |
|||
<mxGeometry x="1130" y="650" width="150" height="150" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="27" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=3;dashed=1;" parent="1" vertex="1"> |
|||
<mxGeometry x="480" y="768" width="230" height="50" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="30" value="" style="rounded=0;whiteSpace=wrap;html=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="1130" y="810" width="150" height="50" as="geometry"/> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 16 KiB |
@ -1,277 +0,0 @@ |
|||
<mxfile host="65bd71144e"> |
|||
<diagram id="jyERGzDynktFHFRGN0ph" name="Page-1"> |
|||
<mxGraphModel dx="3321" dy="2867" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" vertex="1" parent="1"> |
|||
<mxGeometry x="450" y="-50" width="820" height="970" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="3" value="<font face="Roboto"><span style="font-size: 24px">Server(s)</span></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" vertex="1" parent="1"> |
|||
<mxGeometry x="710" y="-50" width="300" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;exitX=0.092;exitY=1.01;exitDx=0;exitDy=0;dashed=1;exitPerimeter=0;" edge="1" parent="1" target="14"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="521"/> |
|||
<mxPoint x="800" y="560"/> |
|||
</Array> |
|||
<mxPoint x="803" y="521" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;" edge="1" parent="1" target="17"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="800" y="520" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="680"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="33" value="" style="group" vertex="1" connectable="0" parent="1"> |
|||
<mxGeometry x="-140" y="-75" width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="29" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">https://someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" vertex="1" parent="33"> |
|||
<mxGeometry x="60" y="27" width="380" height="250" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="32" value="" style="pointerEvents=1;shadow=0;dashed=0;html=1;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.devices.laptop;strokeColor=none;" vertex="1" parent="33"> |
|||
<mxGeometry width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" edge="1" parent="1" source="101" target="32"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="390" y="-190" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-132"/> |
|||
<mxPoint x="280" y="-132"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="34" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">DNS Servers</font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" vertex="1" parent="1"> |
|||
<mxGeometry x="-60" y="-540" width="330" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="6" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"> |
|||
<mxGeometry x="495" y="320" width="355" height="440" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="7" value="<font style="font-size: 24px" face="Roboto">TLS Termination Proxy<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" vertex="1" parent="1"> |
|||
<mxGeometry x="525" y="330" width="280" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="56" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;" edge="1" parent="1" source="55" target="49"> |
|||
<mxGeometry relative="1" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="58" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;startArrow=none;" edge="1" parent="1" source="102" target="57"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="410" y="400" as="targetPoint"/> |
|||
<mxPoint x="585" y="1050" as="sourcePoint"/> |
|||
<Array as="points"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="55" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal">Cert Renovation Program</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"> |
|||
<mxGeometry x="515" y="780" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="59" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeWidth=3;startArrow=none;" edge="1" parent="1" source="103" target="55"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="875" y="1030" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="790" y="930"/> |
|||
<mxPoint x="790" y="930"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="57" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">Let's Encrypt</font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" vertex="1" parent="1"> |
|||
<mxGeometry x="500" y="1150" width="330" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="73" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" edge="1" parent="1" source="85" target="6"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="82" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" edge="1" parent="1" source="62" target="78"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="920" y="770"/> |
|||
<mxPoint x="920" y="770"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="62" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">FastAPI</font><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal"> app for: someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"> |
|||
<mxGeometry x="890" y="650" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="65" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal">Another app</font><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal">: another.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"> |
|||
<mxGeometry x="890" y="50" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="66" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal">One more app</font><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal">: onemore.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"> |
|||
<mxGeometry x="890" y="180" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="78" value="<font face="Roboto"><span style="font-size: 24px ; font-weight: 400">A Database</span></font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1"> |
|||
<mxGeometry x="890" y="780" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="80" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;strokeWidth=3;endArrow=none;" edge="1" parent="1" source="57" target="103"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="480" y="1090" as="sourcePoint"/> |
|||
<mxPoint x="875" y="1110" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="915" y="1250"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="81" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;endArrow=none;" edge="1" parent="1" source="55" target="102"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="525" y="970" as="targetPoint"/> |
|||
<mxPoint x="550" y="880" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="525" y="930"/> |
|||
<mxPoint x="525" y="930"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="85" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Plain response from: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#9673a6;strokeWidth=3;fillColor=#e1d5e7;" vertex="1" parent="1"> |
|||
<mxGeometry x="890" y="500" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="86" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" edge="1" parent="1" source="62" target="85"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="1030.0000000000005" y="649.9999999999995" as="sourcePoint"/> |
|||
<mxPoint x="850" y="540.0000000000005" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="1030" y="540"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="87" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" edge="1" parent="1" source="84" target="62"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="1240" y="390"/> |
|||
<mxPoint x="1240" y="700"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="88" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;dashed=1;" edge="1" parent="1" source="100" target="34"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="65.05882352941171" y="-220" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;dashed=1;" edge="1" parent="1" source="32" target="100"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="110" y="-75" as="sourcePoint"/> |
|||
<mxPoint x="-4.941176470588289" y="-139.99999999999955" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-5" y="-80"/> |
|||
<mxPoint x="-5" y="-80"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="91" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" edge="1" parent="1" source="34" target="101"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="105" y="-280" as="sourcePoint"/> |
|||
<mxPoint x="390" y="-260" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-430"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="109" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" edge="1" parent="1" source="97" target="32"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="340" y="480"/> |
|||
<mxPoint x="340" y="480"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="36" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">Port 443 (HTTPS)</font>" style="ellipse;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" vertex="1" parent="1"> |
|||
<mxGeometry x="330" y="680" width="170" height="120" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="92" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" edge="1" parent="1" source="96" target="36"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="50" y="500" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="50" y="740"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="93" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" edge="1" parent="1" source="32" target="96"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="300" y="350" as="sourcePoint"/> |
|||
<mxPoint x="55" y="330" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="160" y="340"/> |
|||
<mxPoint x="160" y="340"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="96" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Encrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" vertex="1" parent="1"> |
|||
<mxGeometry x="-10" y="400" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="100" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Who is: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" vertex="1" parent="1"> |
|||
<mxGeometry x="-110" y="-210" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="101" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">IP:</span><br style="font-family: &#34;roboto&#34;"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">123.124.125.126</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" vertex="1" parent="1"> |
|||
<mxGeometry x="270" y="-290" width="240" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="102" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Renew HTTPS cert for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" vertex="1" parent="1"> |
|||
<mxGeometry x="430" y="960" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="103" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">New HTTPS cert for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" vertex="1" parent="1"> |
|||
<mxGeometry x="750" y="1070" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=0;strokeWidth=3;" edge="1" parent="1" source="104" target="36"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="770"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="104" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">TLS Handshake</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" vertex="1" parent="1"> |
|||
<mxGeometry x="-110" y="300" width="230" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" edge="1" parent="1" source="32" target="104"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="-40" y="275" as="sourcePoint"/> |
|||
<mxPoint x="341.38784067832285" y="770" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="290"/> |
|||
<mxPoint x="-40" y="290"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="97" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Encrypted response from: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#9673a6;strokeWidth=3;fillColor=#e1d5e7;" vertex="1" parent="1"> |
|||
<mxGeometry x="90" y="500" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="110" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" edge="1" parent="1" source="36" target="97"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="415" y="680" as="sourcePoint"/> |
|||
<mxPoint x="110" y="275" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="245" y="710"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="49" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1"> |
|||
<mxGeometry x="510" y="400" width="310" height="320" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="50" value="<font style="font-size: 24px" face="Roboto">HTTPS certificates<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" vertex="1" parent="1"> |
|||
<mxGeometry x="550.9" y="410" width="228.21" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="51" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" vertex="1" parent="1"> |
|||
<mxGeometry x="530" y="465" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="52" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" vertex="1" parent="1"> |
|||
<mxGeometry x="530" y="545" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="53" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" vertex="1" parent="1"> |
|||
<mxGeometry x="530" y="625" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="42" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br><span style="font-size: 24px">123.124.125.126</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" vertex="1" parent="1"> |
|||
<mxGeometry x="290" y="600" width="220" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="84" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Decrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" vertex="1" parent="1"> |
|||
<mxGeometry x="885" y="350" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="111" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" edge="1" parent="1" source="6" target="84"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="850" y="390" as="sourcePoint"/> |
|||
<mxPoint x="1190" y="700" as="targetPoint"/> |
|||
<Array as="points"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 647 KiB |
Before Width: | Height: | Size: 40 KiB |
@ -1,78 +0,0 @@ |
|||
<mxfile host="65bd71144e"> |
|||
<diagram id="jyERGzDynktFHFRGN0ph" name="Page-1"> |
|||
<mxGraphModel dx="2738" dy="2173" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;exitX=0.092;exitY=1.01;exitDx=0;exitDy=0;dashed=1;exitPerimeter=0;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="521"/> |
|||
<mxPoint x="800" y="560"/> |
|||
</Array> |
|||
<mxPoint x="803" y="521" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="800" y="520" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="680"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="33" value="" style="group" parent="1" vertex="1" connectable="0"> |
|||
<mxGeometry x="-140" y="-75" width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="29" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">https://someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="33" vertex="1"> |
|||
<mxGeometry x="60" y="27" width="380" height="250" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="32" value="" style="pointerEvents=1;shadow=0;dashed=0;html=1;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.devices.laptop;strokeColor=none;" parent="33" vertex="1"> |
|||
<mxGeometry width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="101" target="32" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="390" y="-190" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-132"/> |
|||
<mxPoint x="280" y="-132"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="34" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">DNS Servers</font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-60" y="-540" width="330" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="88" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="100" target="34" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="65.05882352941171" y="-220" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="32" target="100" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="110" y="-75" as="sourcePoint"/> |
|||
<mxPoint x="-4.941176470588289" y="-139.99999999999955" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-10" y="-120"/> |
|||
<mxPoint x="-10" y="-120"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="91" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="34" target="101" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="105" y="-280" as="sourcePoint"/> |
|||
<mxPoint x="390" y="-260" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-430"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="100" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Who is: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="-210" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="101" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">IP:</span><br style="font-family: &#34;roboto&#34;"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">123.124.125.126</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="270" y="-290" width="240" height="80" as="geometry"/> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 10 KiB |
@ -1,110 +0,0 @@ |
|||
<mxfile host="65bd71144e"> |
|||
<diagram id="jyERGzDynktFHFRGN0ph" name="Page-1"> |
|||
<mxGraphModel dx="2481" dy="1867" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="450" y="-50" width="820" height="970" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="3" value="<font face="Roboto"><span style="font-size: 24px">Server(s)</span></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="710" y="-50" width="300" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;exitX=0.092;exitY=1.01;exitDx=0;exitDy=0;dashed=1;exitPerimeter=0;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="521"/> |
|||
<mxPoint x="800" y="560"/> |
|||
</Array> |
|||
<mxPoint x="803" y="521" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="800" y="520" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="680"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="33" value="" style="group" parent="1" vertex="1" connectable="0"> |
|||
<mxGeometry x="-140" y="-75" width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="29" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">https://someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="33" vertex="1"> |
|||
<mxGeometry x="60" y="27" width="380" height="250" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="32" value="" style="pointerEvents=1;shadow=0;dashed=0;html=1;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.devices.laptop;strokeColor=none;" parent="33" vertex="1"> |
|||
<mxGeometry width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="101" target="32" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="390" y="-190" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-132"/> |
|||
<mxPoint x="280" y="-132"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="34" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">DNS Servers</font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-60" y="-540" width="330" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="88" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="100" target="34" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="65.05882352941171" y="-220" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="32" target="100" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="110" y="-75" as="sourcePoint"/> |
|||
<mxPoint x="-4.941176470588289" y="-139.99999999999955" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-5" y="-90"/> |
|||
<mxPoint x="-5" y="-90"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="91" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="34" target="101" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="105" y="-280" as="sourcePoint"/> |
|||
<mxPoint x="390" y="-260" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-430"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="36" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">Port 443 (HTTPS)</font>" style="ellipse;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="330" y="680" width="170" height="120" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="42" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br><span style="font-size: 24px">123.124.125.126</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="290" y="600" width="220" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="100" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Who is: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="-210" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="101" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">IP:</span><br style="font-family: &#34;roboto&#34;"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">123.124.125.126</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="270" y="-290" width="240" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="104" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="770"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="104" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">TLS Handshake</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="300" width="230" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="104" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="-40" y="275" as="sourcePoint"/> |
|||
<mxPoint x="341.38784067832285" y="770" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="290"/> |
|||
<mxPoint x="-40" y="290"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 15 KiB |
@ -1,131 +0,0 @@ |
|||
<mxfile host="65bd71144e"> |
|||
<diagram id="jyERGzDynktFHFRGN0ph" name="Page-1"> |
|||
<mxGraphModel dx="2481" dy="1867" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="450" y="-50" width="820" height="970" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="3" value="<font face="Roboto"><span style="font-size: 24px">Server(s)</span></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="710" y="-50" width="300" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;exitX=0.092;exitY=1.01;exitDx=0;exitDy=0;dashed=1;exitPerimeter=0;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="521"/> |
|||
<mxPoint x="800" y="560"/> |
|||
</Array> |
|||
<mxPoint x="803" y="521" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="800" y="520" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="680"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="33" value="" style="group" parent="1" vertex="1" connectable="0"> |
|||
<mxGeometry x="-140" y="-75" width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="29" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">https://someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="33" vertex="1"> |
|||
<mxGeometry x="60" y="27" width="380" height="250" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="32" value="" style="pointerEvents=1;shadow=0;dashed=0;html=1;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.devices.laptop;strokeColor=none;" parent="33" vertex="1"> |
|||
<mxGeometry width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="101" target="32" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="390" y="-190" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-132"/> |
|||
<mxPoint x="280" y="-132"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="34" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">DNS Servers</font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-60" y="-540" width="330" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="6" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="495" y="320" width="355" height="440" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="7" value="<font style="font-size: 24px" face="Roboto">TLS Termination Proxy<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="525" y="330" width="280" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="88" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="100" target="34" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="65.05882352941171" y="-220" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="32" target="100" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="110" y="-75" as="sourcePoint"/> |
|||
<mxPoint x="-4.941176470588289" y="-139.99999999999955" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-5" y="-90"/> |
|||
<mxPoint x="-5" y="-90"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="91" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="34" target="101" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="105" y="-280" as="sourcePoint"/> |
|||
<mxPoint x="390" y="-260" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-430"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="36" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">Port 443 (HTTPS)</font>" style="ellipse;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="330" y="680" width="170" height="120" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="100" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Who is: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="-210" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="101" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">IP:</span><br style="font-family: &#34;roboto&#34;"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">123.124.125.126</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="270" y="-290" width="240" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="104" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="770"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="104" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">TLS Handshake</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="300" width="230" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="104" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="-40" y="275" as="sourcePoint"/> |
|||
<mxPoint x="341.38784067832285" y="770" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="290"/> |
|||
<mxPoint x="-40" y="290"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="49" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> |
|||
<mxGeometry x="510" y="400" width="310" height="320" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="50" value="<font style="font-size: 24px" face="Roboto">HTTPS certificates<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="550.9" y="410" width="228.21" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="51" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="465" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="52" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="545" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="53" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="625" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="42" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br><span style="font-size: 24px">123.124.125.126</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="290" y="600" width="220" height="70" as="geometry"/> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 1.2 MiB |
Before Width: | Height: | Size: 21 KiB |
@ -1,152 +0,0 @@ |
|||
<mxfile host="65bd71144e"> |
|||
<diagram id="jyERGzDynktFHFRGN0ph" name="Page-1"> |
|||
<mxGraphModel dx="2312" dy="1667" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="450" y="-50" width="820" height="970" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="3" value="<font face="Roboto"><span style="font-size: 24px">Server(s)</span></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="710" y="-50" width="300" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;exitX=0.092;exitY=1.01;exitDx=0;exitDy=0;dashed=1;exitPerimeter=0;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="521"/> |
|||
<mxPoint x="800" y="560"/> |
|||
</Array> |
|||
<mxPoint x="803" y="521" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="800" y="520" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="680"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="33" value="" style="group" parent="1" vertex="1" connectable="0"> |
|||
<mxGeometry x="-140" y="-75" width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="29" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">https://someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="33" vertex="1"> |
|||
<mxGeometry x="60" y="27" width="380" height="250" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="32" value="" style="pointerEvents=1;shadow=0;dashed=0;html=1;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.devices.laptop;strokeColor=none;" parent="33" vertex="1"> |
|||
<mxGeometry width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="101" target="32" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="390" y="-190" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-132"/> |
|||
<mxPoint x="280" y="-132"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="34" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">DNS Servers</font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-60" y="-540" width="330" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="6" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="495" y="320" width="355" height="440" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="7" value="<font style="font-size: 24px" face="Roboto">TLS Termination Proxy<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="525" y="330" width="280" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="88" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="100" target="34" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="65.05882352941171" y="-220" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="32" target="100" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="110" y="-75" as="sourcePoint"/> |
|||
<mxPoint x="-4.941176470588289" y="-139.99999999999955" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-5" y="-90"/> |
|||
<mxPoint x="-5" y="-90"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="91" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="34" target="101" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="105" y="-280" as="sourcePoint"/> |
|||
<mxPoint x="390" y="-260" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-430"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="36" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">Port 443 (HTTPS)</font>" style="ellipse;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="330" y="680" width="170" height="120" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="92" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="96" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="50" y="500" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="50" y="740"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="93" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="96" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="300" y="350" as="sourcePoint"/> |
|||
<mxPoint x="55" y="330" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="160" y="340"/> |
|||
<mxPoint x="160" y="340"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="96" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Encrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" parent="1" vertex="1"> |
|||
<mxGeometry x="-10" y="400" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="100" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Who is: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="-210" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="101" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">IP:</span><br style="font-family: &#34;roboto&#34;"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">123.124.125.126</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="270" y="-290" width="240" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="104" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="770"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="104" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">TLS Handshake</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="300" width="230" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="104" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="-40" y="275" as="sourcePoint"/> |
|||
<mxPoint x="341.38784067832285" y="770" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="290"/> |
|||
<mxPoint x="-40" y="290"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="49" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> |
|||
<mxGeometry x="510" y="400" width="310" height="320" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="50" value="<font style="font-size: 24px" face="Roboto">HTTPS certificates<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="550.9" y="410" width="228.21" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="51" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="465" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="52" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="545" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="53" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="625" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="42" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br><span style="font-size: 24px">123.124.125.126</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="290" y="600" width="220" height="70" as="geometry"/> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 23 KiB |
@ -1,166 +0,0 @@ |
|||
<mxfile host="65bd71144e"> |
|||
<diagram id="jyERGzDynktFHFRGN0ph" name="Page-1"> |
|||
<mxGraphModel dx="5190" dy="5090" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="450" y="-50" width="820" height="970" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="3" value="<font face="Roboto"><span style="font-size: 24px">Server(s)</span></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="710" y="-50" width="300" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;exitX=0.092;exitY=1.01;exitDx=0;exitDy=0;dashed=1;exitPerimeter=0;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="521"/> |
|||
<mxPoint x="800" y="560"/> |
|||
</Array> |
|||
<mxPoint x="803" y="521" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="800" y="520" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="680"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="33" value="" style="group" parent="1" vertex="1" connectable="0"> |
|||
<mxGeometry x="-140" y="-75" width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="29" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">https://someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="33" vertex="1"> |
|||
<mxGeometry x="60" y="27" width="380" height="250" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="32" value="" style="pointerEvents=1;shadow=0;dashed=0;html=1;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.devices.laptop;strokeColor=none;" parent="33" vertex="1"> |
|||
<mxGeometry width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="101" target="32" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="390" y="-190" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-132"/> |
|||
<mxPoint x="280" y="-132"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="34" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">DNS Servers</font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-60" y="-540" width="330" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="6" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="495" y="320" width="355" height="440" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="7" value="<font style="font-size: 24px" face="Roboto">TLS Termination Proxy<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="525" y="330" width="280" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="62" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">FastAPI</font><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal"> app for: someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="895" y="640" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="87" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="6" target="62" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="1240" y="390"/> |
|||
<mxPoint x="1240" y="700"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="84" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Decrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" parent="1" vertex="1"> |
|||
<mxGeometry x="890" y="350" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="88" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="100" target="34" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="65.05882352941171" y="-220" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="32" target="100" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="110" y="-75" as="sourcePoint"/> |
|||
<mxPoint x="-4.941176470588289" y="-139.99999999999955" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-5" y="-80"/> |
|||
<mxPoint x="-5" y="-80"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="91" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="34" target="101" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="105" y="-280" as="sourcePoint"/> |
|||
<mxPoint x="390" y="-260" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-430"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="36" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">Port 443 (HTTPS)</font>" style="ellipse;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="330" y="680" width="170" height="120" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="92" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="96" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="50" y="500" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="50" y="740"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="93" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="96" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="300" y="350" as="sourcePoint"/> |
|||
<mxPoint x="55" y="330" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="160" y="340"/> |
|||
<mxPoint x="160" y="340"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="96" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Encrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" parent="1" vertex="1"> |
|||
<mxGeometry x="-10" y="400" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="100" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Who is: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="-210" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="101" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">IP:</span><br style="font-family: &#34;roboto&#34;"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">123.124.125.126</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="270" y="-290" width="240" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="104" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="770"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="104" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">TLS Handshake</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="300" width="230" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="104" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="-40" y="275" as="sourcePoint"/> |
|||
<mxPoint x="341.38784067832285" y="770" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="290"/> |
|||
<mxPoint x="-40" y="290"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="49" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> |
|||
<mxGeometry x="510" y="400" width="310" height="320" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="50" value="<font style="font-size: 24px" face="Roboto">HTTPS certificates<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="550.9" y="410" width="228.21" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="51" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="465" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="52" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="545" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="53" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="625" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="42" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br><span style="font-size: 24px">123.124.125.126</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="290" y="600" width="220" height="70" as="geometry"/> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 624 KiB |
Before Width: | Height: | Size: 26 KiB |
@ -1,183 +0,0 @@ |
|||
<mxfile host="65bd71144e"> |
|||
<diagram id="jyERGzDynktFHFRGN0ph" name="Page-1"> |
|||
<mxGraphModel dx="3321" dy="2867" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="450" y="-50" width="820" height="970" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="3" value="<font face="Roboto"><span style="font-size: 24px">Server(s)</span></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="710" y="-50" width="300" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;exitX=0.092;exitY=1.01;exitDx=0;exitDy=0;dashed=1;exitPerimeter=0;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="521"/> |
|||
<mxPoint x="800" y="560"/> |
|||
</Array> |
|||
<mxPoint x="803" y="521" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="800" y="520" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="680"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="33" value="" style="group" parent="1" vertex="1" connectable="0"> |
|||
<mxGeometry x="-140" y="-75" width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="29" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">https://someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="33" vertex="1"> |
|||
<mxGeometry x="60" y="27" width="380" height="250" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="32" value="" style="pointerEvents=1;shadow=0;dashed=0;html=1;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.devices.laptop;strokeColor=none;" parent="33" vertex="1"> |
|||
<mxGeometry width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="101" target="32" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="390" y="-190" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-132"/> |
|||
<mxPoint x="280" y="-132"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="34" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">DNS Servers</font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-60" y="-540" width="330" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="6" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="495" y="320" width="355" height="440" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="7" value="<font style="font-size: 24px" face="Roboto">TLS Termination Proxy<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="525" y="330" width="280" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="73" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="85" target="6" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="62" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">FastAPI</font><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal"> app for: someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="895" y="650" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="85" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Plain response from: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#9673a6;strokeWidth=3;fillColor=#e1d5e7;" parent="1" vertex="1"> |
|||
<mxGeometry x="890" y="500" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="86" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="62" target="85" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="1030.0000000000005" y="649.9999999999995" as="sourcePoint"/> |
|||
<mxPoint x="850" y="540.0000000000005" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="1030" y="540"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="87" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="6" target="62" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="1240" y="390"/> |
|||
<mxPoint x="1240" y="700"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="84" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Decrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" parent="1" vertex="1"> |
|||
<mxGeometry x="890" y="350" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="88" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="100" target="34" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="65.05882352941171" y="-220" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="32" target="100" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="110" y="-75" as="sourcePoint"/> |
|||
<mxPoint x="-4.941176470588289" y="-139.99999999999955" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-5" y="-90"/> |
|||
<mxPoint x="-5" y="-90"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="91" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="34" target="101" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="105" y="-280" as="sourcePoint"/> |
|||
<mxPoint x="390" y="-260" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-430"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="36" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">Port 443 (HTTPS)</font>" style="ellipse;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="330" y="680" width="170" height="120" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="92" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="96" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="50" y="500" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="50" y="740"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="93" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="96" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="300" y="350" as="sourcePoint"/> |
|||
<mxPoint x="55" y="330" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="160" y="340"/> |
|||
<mxPoint x="160" y="340"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="96" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Encrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" parent="1" vertex="1"> |
|||
<mxGeometry x="-10" y="400" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="100" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Who is: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="-210" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="101" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">IP:</span><br style="font-family: &#34;roboto&#34;"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">123.124.125.126</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="270" y="-290" width="240" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="104" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="770"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="104" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">TLS Handshake</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="300" width="230" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="104" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="-40" y="275" as="sourcePoint"/> |
|||
<mxPoint x="341.38784067832285" y="770" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="290"/> |
|||
<mxPoint x="-40" y="290"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="49" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> |
|||
<mxGeometry x="510" y="400" width="310" height="320" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="50" value="<font style="font-size: 24px" face="Roboto">HTTPS certificates<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="550.9" y="410" width="228.21" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="51" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="465" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="52" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="545" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="53" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="625" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="42" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br><span style="font-size: 24px">123.124.125.126</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="290" y="600" width="220" height="70" as="geometry"/> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 627 KiB |
Before Width: | Height: | Size: 27 KiB |
@ -1,203 +0,0 @@ |
|||
<mxfile host="65bd71144e"> |
|||
<diagram id="jyERGzDynktFHFRGN0ph" name="Page-1"> |
|||
<mxGraphModel dx="3321" dy="2867" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="450" y="-50" width="820" height="970" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="3" value="<font face="Roboto"><span style="font-size: 24px">Server(s)</span></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="710" y="-50" width="300" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;exitX=0.092;exitY=1.01;exitDx=0;exitDy=0;dashed=1;exitPerimeter=0;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="521"/> |
|||
<mxPoint x="800" y="560"/> |
|||
</Array> |
|||
<mxPoint x="803" y="521" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="800" y="520" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="680"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="33" value="" style="group" parent="1" vertex="1" connectable="0"> |
|||
<mxGeometry x="-140" y="-75" width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="29" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">https://someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="33" vertex="1"> |
|||
<mxGeometry x="60" y="27" width="380" height="250" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="32" value="" style="pointerEvents=1;shadow=0;dashed=0;html=1;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.devices.laptop;strokeColor=none;" parent="33" vertex="1"> |
|||
<mxGeometry width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="101" target="32" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="390" y="-190" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-132"/> |
|||
<mxPoint x="280" y="-132"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="34" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">DNS Servers</font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-60" y="-540" width="330" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="6" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="495" y="320" width="355" height="440" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="7" value="<font style="font-size: 24px" face="Roboto">TLS Termination Proxy<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="525" y="330" width="280" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="73" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="85" target="6" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="62" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">FastAPI</font><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal"> app for: someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="895" y="650" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="85" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Plain response from: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#9673a6;strokeWidth=3;fillColor=#e1d5e7;" parent="1" vertex="1"> |
|||
<mxGeometry x="890" y="500" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="86" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="62" target="85" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="1030.0000000000005" y="649.9999999999995" as="sourcePoint"/> |
|||
<mxPoint x="850" y="540.0000000000005" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="1030" y="540"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="87" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="6" target="62" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="1240" y="390"/> |
|||
<mxPoint x="1240" y="700"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="84" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Decrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" parent="1" vertex="1"> |
|||
<mxGeometry x="890" y="350" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="88" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="100" target="34" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="65.05882352941171" y="-220" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="32" target="100" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="110" y="-75" as="sourcePoint"/> |
|||
<mxPoint x="-4.941176470588289" y="-139.99999999999955" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-5" y="-90"/> |
|||
<mxPoint x="-5" y="-90"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="91" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="34" target="101" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="105" y="-280" as="sourcePoint"/> |
|||
<mxPoint x="390" y="-260" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-430"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="109" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="97" target="32" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="340" y="480"/> |
|||
<mxPoint x="340" y="480"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="36" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">Port 443 (HTTPS)</font>" style="ellipse;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="330" y="680" width="170" height="120" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="92" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="96" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="50" y="500" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="50" y="740"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="93" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="96" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="300" y="350" as="sourcePoint"/> |
|||
<mxPoint x="55" y="330" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="160" y="340"/> |
|||
<mxPoint x="160" y="340"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="96" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Encrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" parent="1" vertex="1"> |
|||
<mxGeometry x="-10" y="400" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="100" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Who is: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="-210" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="101" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">IP:</span><br style="font-family: &#34;roboto&#34;"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">123.124.125.126</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="270" y="-290" width="240" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="104" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="770"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="104" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">TLS Handshake</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="300" width="230" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="104" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="-40" y="275" as="sourcePoint"/> |
|||
<mxPoint x="341.38784067832285" y="770" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="290"/> |
|||
<mxPoint x="-40" y="290"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="97" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Encrypted response from: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#9673a6;strokeWidth=3;fillColor=#e1d5e7;" parent="1" vertex="1"> |
|||
<mxGeometry x="90" y="500" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="110" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="36" target="97" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="415" y="680" as="sourcePoint"/> |
|||
<mxPoint x="110" y="275" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="245" y="710"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="49" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> |
|||
<mxGeometry x="510" y="400" width="310" height="320" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="50" value="<font style="font-size: 24px" face="Roboto">HTTPS certificates<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="550.9" y="410" width="228.21" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="51" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="465" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="52" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="545" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="53" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="625" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="42" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br><span style="font-size: 24px">123.124.125.126</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="290" y="600" width="220" height="70" as="geometry"/> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 29 KiB |
@ -1,217 +0,0 @@ |
|||
<mxfile host="65bd71144e"> |
|||
<diagram id="jyERGzDynktFHFRGN0ph" name="Page-1"> |
|||
<mxGraphModel dx="3321" dy="2867" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="450" y="-50" width="820" height="970" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="3" value="<font face="Roboto"><span style="font-size: 24px">Server(s)</span></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="710" y="-50" width="300" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;exitX=0.092;exitY=1.01;exitDx=0;exitDy=0;dashed=1;exitPerimeter=0;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="521"/> |
|||
<mxPoint x="800" y="560"/> |
|||
</Array> |
|||
<mxPoint x="803" y="521" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;strokeWidth=3;dashed=1;" parent="1" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="800" y="520" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="800" y="680"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="33" value="" style="group" parent="1" vertex="1" connectable="0"> |
|||
<mxGeometry x="-140" y="-75" width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="29" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">https://someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="33" vertex="1"> |
|||
<mxGeometry x="60" y="27" width="380" height="250" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="32" value="" style="pointerEvents=1;shadow=0;dashed=0;html=1;fillColor=#505050;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.devices.laptop;strokeColor=none;" parent="33" vertex="1"> |
|||
<mxGeometry width="500" height="350" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="90" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="101" target="32" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="390" y="-190" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-132"/> |
|||
<mxPoint x="280" y="-132"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="34" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">DNS Servers</font>" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-60" y="-540" width="330" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="6" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="495" y="320" width="355" height="440" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="7" value="<font style="font-size: 24px" face="Roboto">TLS Termination Proxy<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="525" y="330" width="280" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="73" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="85" target="6" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="82" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;entryX=0.073;entryY=0.01;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.075;exitY=0.998;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="62" target="78" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="917" y="754" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="62" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">FastAPI</font><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal"> app for: someapp.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="895" y="650" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="65" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal">Another app</font><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal">: another.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="895" y="50" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="66" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal">One more app</font><font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px ; font-weight: normal">: onemore.example.com</font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="895" y="180" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="78" value="<font face="Roboto"><span style="font-size: 24px ; font-weight: 400">A Database</span></font>" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#dae8fc;strokeColor=#6c8ebf;" parent="1" vertex="1"> |
|||
<mxGeometry x="895" y="780" width="300" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="85" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Plain response from: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#9673a6;strokeWidth=3;fillColor=#e1d5e7;" parent="1" vertex="1"> |
|||
<mxGeometry x="890" y="500" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="86" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="62" target="85" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="1030.0000000000005" y="649.9999999999995" as="sourcePoint"/> |
|||
<mxPoint x="850" y="540.0000000000005" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="1030" y="540"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="87" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="6" target="62" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="1240" y="390"/> |
|||
<mxPoint x="1240" y="700"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="84" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Decrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" parent="1" vertex="1"> |
|||
<mxGeometry x="890" y="350" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="88" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="100" target="34" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="65.05882352941171" y="-220" as="sourcePoint"/> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="89" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;dashed=1;" parent="1" source="32" target="100" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="110" y="-75" as="sourcePoint"/> |
|||
<mxPoint x="-4.941176470588289" y="-139.99999999999955" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-5" y="-90"/> |
|||
<mxPoint x="-5" y="-90"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="91" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="34" target="101" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="105" y="-280" as="sourcePoint"/> |
|||
<mxPoint x="390" y="-260" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="390" y="-430"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="109" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="97" target="32" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="340" y="480"/> |
|||
<mxPoint x="340" y="480"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="36" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto" style="font-size: 24px">Port 443 (HTTPS)</font>" style="ellipse;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="330" y="680" width="170" height="120" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="92" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=classic;endFill=1;strokeWidth=3;" parent="1" source="96" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="50" y="500" as="sourcePoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="50" y="740"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="93" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="96" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="300" y="350" as="sourcePoint"/> |
|||
<mxPoint x="55" y="330" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="160" y="340"/> |
|||
<mxPoint x="160" y="340"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="96" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Encrypted request for: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#82b366;strokeWidth=3;fillColor=#d5e8d4;" parent="1" vertex="1"> |
|||
<mxGeometry x="-10" y="400" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="100" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Who is: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="-210" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="101" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">IP:</span><br style="font-family: &#34;roboto&#34;"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">123.124.125.126</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="270" y="-290" width="240" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="106" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=0;strokeWidth=3;" parent="1" source="104" target="36" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="770"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="104" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">TLS Handshake</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="-110" y="300" width="230" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="107" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="32" target="104" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="-40" y="275" as="sourcePoint"/> |
|||
<mxPoint x="341.38784067832285" y="770" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="-40" y="290"/> |
|||
<mxPoint x="-40" y="290"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="97" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Encrypted response from: someapp.example.com</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeColor=#9673a6;strokeWidth=3;fillColor=#e1d5e7;" parent="1" vertex="1"> |
|||
<mxGeometry x="90" y="500" width="310" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="110" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;dashed=1;startArrow=none;startFill=0;endArrow=none;endFill=1;strokeWidth=3;" parent="1" source="36" target="97" edge="1"> |
|||
<mxGeometry relative="1" as="geometry"> |
|||
<mxPoint x="415" y="680" as="sourcePoint"/> |
|||
<mxPoint x="110" y="275" as="targetPoint"/> |
|||
<Array as="points"> |
|||
<mxPoint x="245" y="710"/> |
|||
</Array> |
|||
</mxGeometry> |
|||
</mxCell> |
|||
<mxCell id="49" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1"> |
|||
<mxGeometry x="510" y="400" width="310" height="320" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="50" value="<font style="font-size: 24px" face="Roboto">HTTPS certificates<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="550.9" y="410" width="228.21" height="40" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="51" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">someapp.example.com</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="465" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="52" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">another.example.net</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="545" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="53" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">onemore.example.org</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#666666;strokeWidth=3;fillColor=#f5f5f5;fontColor=#333333;" parent="1" vertex="1"> |
|||
<mxGeometry x="530" y="625" width="270" height="70" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="42" value="<font face="Roboto" data-font-src="https://fonts.googleapis.com/css?family=Roboto"><span style="font-size: 24px">IP:</span><br><span style="font-size: 24px">123.124.125.126</span><br></font>" style="rounded=0;whiteSpace=wrap;html=1;strokeColor=#000000;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="290" y="600" width="220" height="70" as="geometry"/> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 7.4 KiB |
@ -1,43 +0,0 @@ |
|||
<mxfile host="65bd71144e" modified="2020-11-28T18:13:19.199Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Code/1.51.1 Chrome/83.0.4103.122 Electron/9.3.3 Safari/537.36" etag="KPHuXUeExV3PdWouu_3U" version="13.6.5"> |
|||
<diagram id="zB4-QXJZ7ScUzHSLnJ1i" name="Page-1"> |
|||
<mxGraphModel dx="1154" dy="780" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1920" pageHeight="1200" math="0" shadow="0" extFonts="Roboto^https://fonts.googleapis.com/css?family=Roboto|Roboto Mono, mono^https://fonts.googleapis.com/css?family=Roboto+Mono%2C+mono"> |
|||
<root> |
|||
<mxCell id="0"/> |
|||
<mxCell id="1" parent="0"/> |
|||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="110" y="280" width="1350" height="620" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="3" value="<font style="font-size: 24px" face="Roboto">Package app<br>app/__init__.py</font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="635" y="310" width="300" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="15" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Module app.main</span><br style="font-family: &#34;roboto&#34; ; font-size: 24px"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">app/main.py</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="140" y="430" width="360" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="16" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Module app.dependencies</span><br style="font-family: &#34;roboto&#34; ; font-size: 24px"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">app/dependencies.py</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="130" y="565" width="370" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="5" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="1030" y="430" width="400" height="260" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="8" value="<font style="font-size: 24px" face="Roboto">Subpackage app.internal<br></font><span style="font-family: &#34;roboto&#34; ; font-size: 24px">app/internal/__init__.py</span><font style="font-size: 24px" face="Roboto"><br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="1083.8438461538462" y="460" width="292.3076923076923" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="19" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Module app.internal.admin</span><br style="font-family: &#34;roboto&#34; ; font-size: 24px"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">app/internal/admin.py</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="1050" y="570" width="360" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="4" value="" style="rounded=0;whiteSpace=wrap;html=1;fontStyle=1;strokeWidth=4;" parent="1" vertex="1"> |
|||
<mxGeometry x="540" y="430" width="440" height="410" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="7" value="<font style="font-size: 24px" face="Roboto">Subpackage app.routers<br>app/routers/__init__.py<br></font>" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;strokeWidth=3;fontFamily=Roboto Mono, mono;FType=g;" parent="1" vertex="1"> |
|||
<mxGeometry x="599.2307692307693" y="460" width="321.53846153846155" height="80" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="17" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Module app.routers.items</span><br style="font-family: &#34;roboto&#34; ; font-size: 24px"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">app/routers/items.py</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="580" y="570" width="360" height="100" as="geometry"/> |
|||
</mxCell> |
|||
<mxCell id="18" value="<span style="font-family: &#34;roboto&#34; ; font-size: 24px">Module app.routers.users</span><br style="font-family: &#34;roboto&#34; ; font-size: 24px"><span style="font-family: &#34;roboto&#34; ; font-size: 24px">app/routers/users.py</span>" style="shape=hexagon;perimeter=hexagonPerimeter2;whiteSpace=wrap;html=1;fixedSize=1;strokeWidth=3;" parent="1" vertex="1"> |
|||
<mxGeometry x="580" y="700" width="360" height="100" as="geometry"/> |
|||
</mxCell> |
|||
</root> |
|||
</mxGraphModel> |
|||
</diagram> |
|||
</mxfile> |
After Width: | Height: | Size: 604 KiB |
Before Width: | Height: | Size: 14 KiB |
@ -0,0 +1,831 @@ |
|||
# 仮想環境 |
|||
|
|||
Pythonプロジェクトの作業では、**仮想環境**(または類似の仕組み)を使用し、プロジェクトごとにインストールするパッケージを分離するべきでしょう。 |
|||
|
|||
/// info | 情報 |
|||
|
|||
もし、仮想環境の概要や作成方法、使用方法について既にご存知なら、このセクションをスキップすることができます。🤓 |
|||
|
|||
/// |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
**仮想環境**は、**環境変数**とは異なります。 |
|||
|
|||
**環境変数**は、プログラムが使用できるシステム内の変数です。 |
|||
|
|||
**仮想環境**は、ファイルをまとめたディレクトリのことです。 |
|||
|
|||
/// |
|||
|
|||
/// info | 情報 |
|||
このページでは、**仮想環境**の使用方法と、そのはたらきについて説明します。 |
|||
|
|||
もし**すべてを管理するツール**(Pythonのインストールも含む)を導入する準備ができているなら、<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> をお試しください。 |
|||
|
|||
/// |
|||
|
|||
## プロジェクトの作成 |
|||
|
|||
まず、プロジェクト用のディレクトリを作成します。 |
|||
|
|||
私は通常 home/user ディレクトリの中に `code` というディレクトリを用意していて、プロジェクトごとに1つのディレクトリをその中に作成しています。 |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
// Go to the home directory |
|||
$ cd |
|||
// Create a directory for all your code projects |
|||
$ mkdir code |
|||
// Enter into that code directory |
|||
$ cd code |
|||
// Create a directory for this project |
|||
$ mkdir awesome-project |
|||
// Enter into that project directory |
|||
$ cd awesome-project |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
## 仮想環境の作成 |
|||
|
|||
Pythonプロジェクトでの**初めての**作業を開始する際には、**<abbr title="他の選択肢もありますが、これはシンプルなガイドラインです">プロジェクト内</abbr>**に仮想環境を作成してください。 |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
これを行うのは、**プロジェクトごとに1回だけ**です。作業のたびに行う必要はありません。 |
|||
|
|||
/// |
|||
|
|||
//// tab | `venv` |
|||
|
|||
仮想環境を作成するには、Pythonに付属している `venv` モジュールを使用できます。 |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ python -m venv .venv |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
/// details | このコマンドの意味 |
|||
|
|||
- `python` : `python` というプログラムを呼び出します |
|||
- `-m` : モジュールをスクリプトとして呼び出します。どのモジュールを呼び出すのか、この次に指定します |
|||
- `venv` : 通常Pythonに付随してインストールされる `venv`モジュールを使用します |
|||
- `.venv` : 仮想環境を`.venv`という新しいディレクトリに作成します |
|||
|
|||
/// |
|||
|
|||
//// |
|||
|
|||
//// tab | `uv` |
|||
|
|||
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> をインストール済みなら、仮想環境を作成するために `uv` を使うこともできます。 |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ uv venv |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
デフォルトでは、 `uv` は `.venv` というディレクトリに仮想環境を作成します。 |
|||
|
|||
ただし、追加の引数にディレクトリ名を与えてカスタマイズすることもできます。 |
|||
|
|||
/// |
|||
|
|||
//// |
|||
|
|||
このコマンドは `.venv` というディレクトリに新しい仮想環境を作成します。 |
|||
|
|||
/// details | `.venv` またはその他の名前 |
|||
|
|||
仮想環境を別のディレクトリに作成することも可能ですが、 `.venv` と名付けるのが一般的な慣習です。 |
|||
|
|||
/// |
|||
|
|||
## 仮想環境の有効化 |
|||
|
|||
実行されるPythonコマンドやインストールされるパッケージが新しく作成した仮想環境を使用するよう、その仮想環境を有効化しましょう。 |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
そのプロジェクトの作業で**新しいターミナルセッション**を開始する際には、**毎回**有効化が必要です。 |
|||
|
|||
/// |
|||
|
|||
//// tab | Linux, macOS |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ source .venv/bin/activate |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows PowerShell |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ .venv\Scripts\Activate.ps1 |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows Bash |
|||
|
|||
もしWindowsでBashを使用している場合 (<a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>など): |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ source .venv/Scripts/activate |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
**新しいパッケージ**を仮想環境にインストールするときには、再度**有効化**してください。 |
|||
|
|||
こうすることで、そのパッケージがインストールした**ターミナル(<abbr title="command line interface">CLI</abbr>)プログラム**を使用する場合に、仮想環境内のものが確実に使われ、グローバル環境にインストールされている別のもの(おそらく必要なものとは異なるバージョン)を誤って使用することを防ぎます。 |
|||
|
|||
/// |
|||
|
|||
## 仮想環境が有効であることを確認する |
|||
|
|||
仮想環境が有効である(前のコマンドが正常に機能した)ことを確認します。 |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
これは**任意**ですが、すべてが期待通りに機能し、意図した仮想環境を使用していることを**確認する**良い方法です。 |
|||
|
|||
/// |
|||
|
|||
//// tab | Linux, macOS, Windows Bash |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ which python |
|||
|
|||
/home/user/code/awesome-project/.venv/bin/python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
`.venv/bin/python` にある `python` バイナリが、プロジェクト(この場合は `awesome-project` )内に表示されていれば、正常に動作しています 🎉。 |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows PowerShell |
|||
|
|||
<div class="termy"> |
|||
|
|||
``` console |
|||
$ Get-Command python |
|||
|
|||
C:\Users\user\code\awesome-project\.venv\Scripts\python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
`.venv\Scripts\python` にある `python` バイナリが、プロジェクト(この場合は `awesome-project` )内に表示されていれば、正常に動作しています 🎉。 |
|||
|
|||
//// |
|||
|
|||
## `pip` をアップグレードする |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用している場合は、 `pip` の代わりに `uv` を使ってインストールを行うため、 `pip` をアップグレードする必要はありません 😎。 |
|||
|
|||
/// |
|||
|
|||
もしパッケージのインストールに `pip`(Pythonに標準で付属しています)を使用しているなら、 `pip` を最新バージョンに**アップグレード**しましょう。 |
|||
|
|||
パッケージのインストール中に発生する想定外のエラーの多くは、最初に `pip` をアップグレードしておくだけで解決されます。 |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
通常、これは仮想環境を作成した直後に**一度だけ**実行します。 |
|||
|
|||
/// |
|||
|
|||
仮想環境が有効であることを(上で説明したコマンドで)確認し、アップグレードを実行しましょう: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ python -m pip install --upgrade pip |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
## `.gitignore` を追加する |
|||
|
|||
**Git**を使用している場合(使用するべきでしょう)、 `.gitignore` ファイルを追加して、 `.venv` 内のあらゆるファイルをGitの管理対象から除外します。 |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用して仮想環境を作成した場合、すでにこの作業は済んでいるので、この手順をスキップできます 😎。 |
|||
|
|||
/// |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
これも、仮想環境を作成した直後に**一度だけ**実行します。 |
|||
|
|||
/// |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ echo "*" > .venv/.gitignore |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
/// details | このコマンドの意味 |
|||
|
|||
- `echo "*"` : ターミナルに `*` というテキストを「表示」しようとします。(次の部分によってその動作が少し変わります) |
|||
- `>` : `>` の左側のコマンドがターミナルに表示しようとする内容を、ターミナルには表示せず、 `>` の右側のファイルに書き込みます。 |
|||
- `.gitignore` : `*` を書き込むファイル名。 |
|||
|
|||
ここで、Gitにおける `*` は「すべて」を意味するので、このコマンドによって `.venv` ディレクトリ内のすべてがGitに無視されるようになります。 |
|||
|
|||
このコマンドは以下のテキストを持つ `.gitignore` ファイルを作成します: |
|||
|
|||
```gitignore |
|||
* |
|||
``` |
|||
|
|||
/// |
|||
|
|||
## パッケージのインストール |
|||
|
|||
仮想環境を有効化した後、その中でパッケージをインストールできます。 |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
プロジェクトに必要なパッケージをインストールまたはアップグレードする場合、これを**一度**実行します。 |
|||
|
|||
もし新しいパッケージを追加したり、バージョンをアップグレードする必要がある場合は、もう**一度この手順を繰り返し**ます。 |
|||
|
|||
/// |
|||
|
|||
### パッケージを直接インストールする |
|||
|
|||
急いでいて、プロジェクトのパッケージ要件を宣言するファイルを使いたくない場合、パッケージを直接インストールできます。 |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
プログラムが必要とするパッケージとバージョンをファイル(例えば `requirements.txt` や `pyproject.toml` )に記載しておくのは、(とても)良い考えです。 |
|||
|
|||
/// |
|||
|
|||
//// tab | `pip` |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "fastapi[standard]" |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | `uv` |
|||
|
|||
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用できるなら: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ uv pip install "fastapi[standard]" |
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
### `requirements.txt` からインストールする |
|||
|
|||
もし `requirements.txt` があるなら、パッケージのインストールに使用できます。 |
|||
|
|||
//// tab | `pip` |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install -r requirements.txt |
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | `uv` |
|||
|
|||
もし <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a> を使用できるなら: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ uv pip install -r requirements.txt |
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
/// details | `requirements.txt` |
|||
|
|||
パッケージが記載された `requirements.txt` は以下のようになっています: |
|||
|
|||
```requirements.txt |
|||
fastapi[standard]==0.113.0 |
|||
pydantic==2.8.0 |
|||
``` |
|||
|
|||
/// |
|||
|
|||
## プログラムを実行する |
|||
|
|||
仮想環境を有効化した後、プログラムを実行できます。この際、仮想環境内のPythonと、そこにインストールしたパッケージが使用されます。 |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ python main.py |
|||
|
|||
Hello World |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
## エディタの設定 |
|||
|
|||
プロジェクトではおそらくエディタを使用するでしょう。コード補完やインラインエラーの表示ができるように、作成した仮想環境をエディタでも使えるよう設定してください。(多くの場合、自動検出されます) |
|||
|
|||
設定例: |
|||
|
|||
* <a href="https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment" class="external-link" target="_blank">VS Code</a> |
|||
* <a href="https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html" class="external-link" target="_blank">PyCharm</a> |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
この設定は通常、仮想環境を作成した際に**一度だけ**行います。 |
|||
|
|||
/// |
|||
|
|||
## 仮想環境の無効化 |
|||
|
|||
プロジェクトの作業が終了したら、その仮想環境を**無効化**できます。 |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ deactivate |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
これにより、 `python` コマンドを実行しても、そのプロジェクト用(のパッケージがインストールされた)仮想環境から `python` プログラムを呼び出そうとはしなくなります。 |
|||
|
|||
## 作業準備完了 |
|||
|
|||
ここまでで、プロジェクトの作業を始める準備が整いました。 |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
上記の内容を理解したいですか? |
|||
|
|||
もしそうなら、以下を読み進めてください。👇🤓 |
|||
|
|||
/// |
|||
|
|||
## なぜ仮想環境? |
|||
|
|||
FastAPIを使った作業をするには、 [Python](https://www.python.org/) のインストールが必要です。 |
|||
|
|||
それから、FastAPIや、使用したいその他の**パッケージ**を**インストール**する必要があります。 |
|||
|
|||
パッケージをインストールするには、通常、Python に付属する `pip` コマンド (または同様の代替コマンド) を使用します。 |
|||
|
|||
ただし、`pip` を直接使用すると、パッケージは**グローバルなPython環境**(OS全体にインストールされたPython環境)にインストールされます。 |
|||
|
|||
### 問題点 |
|||
|
|||
では、グローバルPython環境にパッケージをインストールすることの問題点は何でしょうか? |
|||
|
|||
ある時点で、あなたは**異なるパッケージ**に依存する多くのプログラムを書くことになるでしょう。そして、これらの中には同じパッケージの**異なるバージョン**に依存するものも出てくるでしょう。😱 |
|||
|
|||
例えば、 `philosophers-stone` (賢者の石)というプロジェクトを作成するとします。このプログラムは **`harry` (ハリー)というパッケージのバージョン `1`**に依存しています。そのため、 `harry` (ハリー)をインストールする必要があります。 |
|||
|
|||
```mermaid |
|||
flowchart LR |
|||
stone(philosophers-stone) -->|requires| harry-1[harry v1] |
|||
``` |
|||
|
|||
それから、 `prisoner-of-azkaban` (アズカバンの囚人)という別のプロジェクトを作成したとします。このプロジェクトも `harry` (ハリー)に依存していますが、**`harry` (ハリー)のバージョン `3`**が必要です。 |
|||
|
|||
```mermaid |
|||
flowchart LR |
|||
azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3] |
|||
``` |
|||
|
|||
しかし、ここで問題になるのは、もしローカルの**仮想環境**ではなくグローバル(環境)にパッケージをインストールするなら、 `harry` (ハリー)のどのバージョンをインストールするか選ばないといけないことです。 |
|||
|
|||
例えば、 `philosophers-stone` (賢者の石)を実行するには、まず `harry` (ハリー)のバージョン `1` をインストールする必要があります: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "harry==1" |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
これにより、`harry` (ハリー)バージョン1がグローバルなPython環境にインストールされます。 |
|||
|
|||
```mermaid |
|||
flowchart LR |
|||
subgraph global[global env] |
|||
harry-1[harry v1] |
|||
end |
|||
subgraph stone-project[philosophers-stone project] |
|||
stone(philosophers-stone) -->|requires| harry-1 |
|||
end |
|||
``` |
|||
|
|||
しかし、 `prisoner-of-azkaban` (アズカバンの囚人)を実行したい場合は、`harry` (ハリー)のバージョン `1` をアンインストールし、`harry` (ハリー)のバージョン `3` をインストールし直す必要があります。(あるいは、単に`harry` (ハリー)のバージョン `3` をインストールすることで、自動的にバージョン `1` がアンインストールされます) |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "harry==3" |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
このようにして、グローバル環境への `harry` (ハリー)のバージョン `3` のインストールが完了します。 |
|||
|
|||
それから、 `philosophers-stone` (賢者の石)を再び実行しようとすると、このプログラムは `harry` (ハリー)のバージョン `1` が必要なため、**動作しなくなる**可能性があります。 |
|||
|
|||
```mermaid |
|||
flowchart LR |
|||
subgraph global[global env] |
|||
harry-1[<strike>harry v1</strike>] |
|||
style harry-1 fill:#ccc,stroke-dasharray: 5 5 |
|||
harry-3[harry v3] |
|||
end |
|||
subgraph stone-project[philosophers-stone project] |
|||
stone(philosophers-stone) -.-x|⛔️| harry-1 |
|||
end |
|||
subgraph azkaban-project[prisoner-of-azkaban project] |
|||
azkaban(prisoner-of-azkaban) --> |requires| harry-3 |
|||
end |
|||
``` |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
Pythonのパッケージでは、**新しいバージョン**で**互換性を損なう変更を避ける**よう努めるのが一般的ですが、それでも注意が必要です。すべてが正常に動作することをテストで確認してから、意図的に指定して新しいバージョンをインストールするのが良いでしょう。 |
|||
|
|||
/// |
|||
|
|||
あなたのすべての**プロジェクトが依存している**、**多数の**他の**パッケージ**が上記の問題を抱えていると想像してください。これは管理が非常に困難です。そして、**互換性のないバージョン**のパッケージを使ってプロジェクトを実行し、なぜ動作しないのか分からなくなるでしょう。 |
|||
|
|||
また、使用しているOS(Linux、Windows、macOS など)によっては、Pythonがすでにインストールされていることがあります。この場合、特定のバージョンのパッケージが**OSの動作に必要である**ことがあります。グローバル環境にパッケージをインストールすると、OSに付属するプログラムを**壊してしまう**可能性があります。 |
|||
|
|||
## パッケージのインストール先 |
|||
|
|||
Pythonをインストールしたとき、ファイルを含んだいくつかのディレクトリが作成されます。 |
|||
|
|||
これらの中には、インストールされたパッケージを保存するためのものもあります。 |
|||
|
|||
以下のコマンドを実行したとき: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
// Don't run this now, it's just an example 🤓 |
|||
$ pip install "fastapi[standard]" |
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
FastAPIのコードを含む圧縮ファイルが、通常は [PyPI](https://pypi.org/project/fastapi/) からダウンロードされます。 |
|||
|
|||
また、FastAPIが依存する他のパッケージも**ダウンロード**されます。 |
|||
|
|||
それから、これらのファイルは**解凍**され、コンピュータのあるディレクトリに配置されます。 |
|||
|
|||
デフォルトでは、これらのファイルはPythonのインストール時に作成されるディレクトリ、つまり**グローバル環境**に配置されます。 |
|||
|
|||
## 仮想環境とは |
|||
|
|||
すべてのパッケージをグローバル環境に配置することによって生じる問題の解決策は、作業する**プロジェクトごとの仮想環境**を使用することです。 |
|||
|
|||
仮想環境は**ディレクトリ**であり、グローバル環境と非常に似ていて、一つのプロジェクトで使う特定のパッケージ群をインストールできる場所です。 |
|||
|
|||
このようにして、それぞれのプロジェクトが独自の仮想環境(`.venv` ディレクトリ)に独自のパッケージ群を持つことができます。 |
|||
|
|||
```mermaid |
|||
flowchart TB |
|||
subgraph stone-project[philosophers-stone project] |
|||
stone(philosophers-stone) --->|requires| harry-1 |
|||
subgraph venv1[.venv] |
|||
harry-1[harry v1] |
|||
end |
|||
end |
|||
subgraph azkaban-project[prisoner-of-azkaban project] |
|||
azkaban(prisoner-of-azkaban) --->|requires| harry-3 |
|||
subgraph venv2[.venv] |
|||
harry-3[harry v3] |
|||
end |
|||
end |
|||
stone-project ~~~ azkaban-project |
|||
``` |
|||
|
|||
## 仮想環境の有効化とは |
|||
|
|||
仮想環境を有効にしたとき、例えば次のコマンドを実行した場合を考えます: |
|||
|
|||
//// tab | Linux, macOS |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ source .venv/bin/activate |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows PowerShell |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ .venv\Scripts\Activate.ps1 |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows Bash |
|||
|
|||
あるいは、WindowsでBashを使用している場合 (<a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>など): |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ source .venv/Scripts/activate |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
これによって、いくつかの [環境変数](environment-variables.md){.internal-link target=_blank} が作成・修正され、次に実行されるコマンドで使用できるようになります。 |
|||
|
|||
これらの環境変数のひとつに、 `PATH` 変数があります。 |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
`PATH` 変数についての詳細は [環境変数](environment-variables.md#path環境変数){.internal-link target=_blank} を参照してください。 |
|||
|
|||
/// |
|||
|
|||
仮想環境を有効にすると、その仮想環境のパス `.venv/bin` (LinuxとmacOS)、あるいは `.venv\Scripts` (Windows)が `PATH` 変数に追加されます。 |
|||
|
|||
その環境を有効にする前の `PATH` 変数が次のようになっているとします。 |
|||
|
|||
//// tab | Linux, macOS |
|||
|
|||
```plaintext |
|||
/usr/bin:/bin:/usr/sbin:/sbin |
|||
``` |
|||
|
|||
これは、OSが以下のディレクトリ中でプログラムを探すことを意味します: |
|||
|
|||
* `/usr/bin` |
|||
* `/bin` |
|||
* `/usr/sbin` |
|||
* `/sbin` |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows |
|||
|
|||
```plaintext |
|||
C:\Windows\System32 |
|||
``` |
|||
|
|||
これは、OSが以下のディレクトリ中でプログラムを探すことを意味します: |
|||
|
|||
* `C:\Windows\System32` |
|||
|
|||
//// |
|||
|
|||
仮想環境を有効にすると、 `PATH` 変数は次のようになります。 |
|||
|
|||
//// tab | Linux, macOS |
|||
|
|||
```plaintext |
|||
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin |
|||
``` |
|||
|
|||
これは、OSが他のディレクトリを探すより前に、最初に以下のディレクトリ中でプログラムを探し始めることを意味します: |
|||
|
|||
```plaintext |
|||
/home/user/code/awesome-project/.venv/bin |
|||
``` |
|||
|
|||
そのため、ターミナルで `python` と入力した際に、OSはPythonプログラムを以下のパスで発見し、使用します。 |
|||
|
|||
```plaintext |
|||
/home/user/code/awesome-project/.venv/bin/python |
|||
``` |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows |
|||
|
|||
```plaintext |
|||
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32 |
|||
``` |
|||
|
|||
これは、OSが他のディレクトリを探すより前に、最初に以下のディレクトリ中でプログラムを探し始めることを意味します: |
|||
|
|||
```plaintext |
|||
C:\Users\user\code\awesome-project\.venv\Scripts |
|||
``` |
|||
|
|||
そのため、ターミナルで `python` と入力した際に、OSはPythonプログラムを以下のパスで発見し、使用します。 |
|||
|
|||
```plaintext |
|||
C:\Users\user\code\awesome-project\.venv\Scripts\python |
|||
``` |
|||
|
|||
//// |
|||
|
|||
重要な点は、仮想環境のパスを `PATH` 変数の**先頭**に配置することです。OSは利用可能な他のPythonを見つけるより**前に**、この仮想環境のPythonを見つけるようになります。このようにして、 `python` を実行したときに、他の `python` (例えばグローバル環境の `python` )ではなく、**その仮想環境の**Pythonを使用するようになります。 |
|||
|
|||
仮想環境を有効にして変更されることは他にもありますが、これが最も重要な変更のひとつです。 |
|||
|
|||
## 仮想環境の確認 |
|||
|
|||
仮想環境が有効かどうか、例えば次のように確認できます。: |
|||
|
|||
//// tab | Linux, macOS, Windows Bash |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ which python |
|||
|
|||
/home/user/code/awesome-project/.venv/bin/python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows PowerShell |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ Get-Command python |
|||
|
|||
C:\Users\user\code\awesome-project\.venv\Scripts\python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
これは、使用される `python` プログラムが**その仮想環境の**ものであることを意味します。 |
|||
|
|||
LinuxやmacOSでは `which` を、Windows PowerShellでは `Get-Command` を使用します。 |
|||
|
|||
このコマンドの動作は、 `PATH`変数に設定された**それぞれのパスを順に**確認していき、呼ばれている `python` プログラムを探します。そして、見つかり次第そのプログラムへの**パスを表示します**。 |
|||
|
|||
最も重要なことは、 `python` が呼ばれたときに、まさにこのコマンドで確認した "`python`" が実行されることです。 |
|||
|
|||
こうして、自分が想定通りの仮想環境にいるかを確認できます。 |
|||
|
|||
/// tip | 豆知識 |
|||
|
|||
ある仮想環境を有効にし、そのPythonを使用したまま**他のプロジェクトに移動して**しまうことは簡単に起こり得ます。 |
|||
|
|||
そして、その第二のプロジェクトは動作しないでしょう。なぜなら別のプロジェクトの仮想環境の**誤ったPython**を使用しているからです。 |
|||
|
|||
そのため、どの `python` が使用されているのか確認できることは役立ちます。🤓 |
|||
|
|||
/// |
|||
|
|||
## なぜ仮想環境を無効化するのか |
|||
|
|||
例えば、`philosophers-stone` (賢者の石)というプロジェクトで作業をしていて、**その仮想環境を有効にし**、必要なパッケージをインストールしてその環境内で作業を進めているとします。 |
|||
|
|||
それから、**別のプロジェクト**、 `prisoner-of-azkaban` (アズカバンの囚人)に取り掛かろうとします。 |
|||
|
|||
そのプロジェクトディレクトリへ移動します: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ cd ~/code/prisoner-of-azkaban |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
もし `philosophers-stone` (賢者の石)の仮想環境を無効化していないと、`python` を実行したとき、 ターミナルは `philosophers-stone` (賢者の石)のPythonを使用しようとします。 |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ cd ~/code/prisoner-of-azkaban |
|||
|
|||
$ python main.py |
|||
|
|||
// Error importing sirius, it's not installed 😱 |
|||
Traceback (most recent call last): |
|||
File "main.py", line 1, in <module> |
|||
import sirius |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
しかし、その仮想環境を無効化し、 `prisoner-of-azkaban` (アズカバンの囚人)のための新しい仮想環境を有効にすれば、 `python` を実行したときに `prisoner-of-azkaban` (アズカバンの囚人)の仮想環境の Python が使用されるようになります。 |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ cd ~/code/prisoner-of-azkaban |
|||
|
|||
// You don't need to be in the old directory to deactivate, you can do it wherever you are, even after going to the other project 😎 |
|||
$ deactivate |
|||
|
|||
// Activate the virtual environment in prisoner-of-azkaban/.venv 🚀 |
|||
$ source .venv/bin/activate |
|||
|
|||
// Now when you run python, it will find the package sirius installed in this virtual environment ✨ |
|||
$ python main.py |
|||
|
|||
I solemnly swear 🐺 |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
## 代替手段 |
|||
|
|||
これは、あらゆる仕組みを**根本から**学ぶためのシンプルな入門ガイドです。 |
|||
|
|||
仮想環境、パッケージの依存関係(requirements)、プロジェクトの管理には、多くの**代替手段**があります。 |
|||
|
|||
準備が整い、パッケージの依存関係、仮想環境など**プロジェクト全体の管理**ツールを使いたいと考えたら、<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a> を試してみることをおすすめします。 |
|||
|
|||
`uv` では以下のような多くのことができます: |
|||
|
|||
* 異なるバージョンも含めた**Python のインストール** |
|||
* プロジェクトごとの**仮想環境**の管理 |
|||
* **パッケージ**のインストール |
|||
* プロジェクトのパッケージの**依存関係やバージョン**の管理 |
|||
* パッケージとそのバージョンの、依存関係を含めた**厳密な**組み合わせを保持し、これによって、本番環境で、開発環境と全く同じようにプロジェクトを実行できる(これは**locking**と呼ばれます) |
|||
* その他のさまざまな機能 |
|||
|
|||
## まとめ |
|||
|
|||
ここまで読みすべて理解したなら、世間の多くの開発者と比べて、仮想環境について**あなたはより多くのことを知っています**。🤓 |
|||
|
|||
これらの詳細を知ることは、将来、複雑に見える何かのデバッグにきっと役立つでしょう。しかし、その頃には、あなたは**そのすべての動作を根本から**理解しているでしょう。😎 |
@ -1,53 +1,165 @@ |
|||
# 이벤트: startup과 shutdown |
|||
# Lifespan 이벤트 |
|||
|
|||
필요에 따라 응용 프로그램이 시작되기 전이나 종료될 때 실행되는 이벤트 핸들러(함수)를 정의할 수 있습니다. |
|||
애플리케이션 **시작 전**에 실행되어야 하는 로직(코드)을 정의할 수 있습니다. 이는 이 코드가 **한 번**만 실행되며, **애플리케이션이 요청을 받기 시작하기 전**에 실행된다는 의미입니다. |
|||
|
|||
이 함수들은 `async def` 또는 평범하게 `def`으로 선언할 수 있습니다. |
|||
마찬가지로, 애플리케이션이 **종료될 때** 실행되어야 하는 로직(코드)을 정의할 수 있습니다. 이 경우, 이 코드는 **한 번**만 실행되며, **여러 요청을 처리한 후**에 실행됩니다. |
|||
|
|||
이 코드가 애플리케이션이 **요청을 받기 시작하기 전에** 실행되고, 요청 처리가 끝난 후 **종료 직전에** 실행되기 때문에 전체 애플리케이션의 **수명(Lifespan)**을 다룹니다. (잠시 후 "수명"이라는 단어가 중요해집니다 😉) |
|||
|
|||
이 방법은 전체 애플리케이션에서 사용해야 하는 **자원**을 설정하거나 요청 간에 **공유되는** 자원을 설정하고, 또는 그 후에 **정리**하는 데 매우 유용할 수 있습니다. 예를 들어, 데이터베이스 연결 풀 또는 공유되는 머신러닝 모델을 로드하는 경우입니다. |
|||
|
|||
|
|||
## 사용 사례 |
|||
|
|||
먼저 **사용 사례**를 예로 들어보고, 이를 어떻게 해결할 수 있는지 살펴보겠습니다. |
|||
|
|||
우리가 요청을 처리하기 위해 사용하고 싶은 **머신러닝 모델**이 있다고 상상해 봅시다. 🤖 |
|||
|
|||
이 모델들은 요청 간에 공유되므로, 요청마다 모델이 하나씩 있는 것이 아니라, 여러 요청에서 동일한 모델을 사용합니다. |
|||
|
|||
모델을 로드하는 데 **상당한 시간이 걸린다고 상상해 봅시다**, 왜냐하면 모델이 **디스크에서 많은 데이터를 읽어야** 하기 때문입니다. 따라서 모든 요청에 대해 모델을 매번 로드하고 싶지 않습니다. |
|||
|
|||
모듈/파일의 최상위에서 모델을 로드할 수도 있지만, 그러면 **모델을 로드하는데** 시간이 걸리기 때문에, 단순한 자동화된 테스트를 실행할 때도 모델이 로드될 때까지 기다려야 해서 **테스트 속도가 느려집니다**. |
|||
|
|||
이 문제를 해결하려고 하는 것입니다. 요청을 처리하기 전에 모델을 로드하되, 애플리케이션이 요청을 받기 시작하기 직전에만 로드하고, 코드가 로드되는 동안은 로드하지 않도록 하겠습니다. |
|||
|
|||
## Lifespan |
|||
|
|||
`FastAPI` 애플리케이션의 `lifespan` 매개변수와 "컨텍스트 매니저"를 사용하여 *시작*과 *종료* 로직을 정의할 수 있습니다. (컨텍스트 매니저가 무엇인지 잠시 후에 설명드리겠습니다.) |
|||
|
|||
예제를 통해 시작하고, 그 후에 자세히 살펴보겠습니다. |
|||
|
|||
우리는 `yield`를 사용하여 비동기 함수 `lifespan()`을 다음과 같이 생성합니다: |
|||
|
|||
{* ../../docs_src/events/tutorial003.py hl[16,19] *} |
|||
|
|||
여기서 우리는 모델을 로드하는 비싼 *시작* 작업을 시뮬레이션하고 있습니다. `yield` 앞에서 (가짜) 모델 함수를 머신러닝 모델이 담긴 딕셔너리에 넣습니다. 이 코드는 **애플리케이션이 요청을 받기 시작하기 전**, *시작* 동안에 실행됩니다. |
|||
|
|||
그리고 `yield` 직후에는 모델을 언로드합니다. 이 코드는 **애플리케이션이 요청 처리 완료 후**, *종료* 직전에 실행됩니다. 예를 들어, 메모리나 GPU와 같은 자원을 해제하는 작업을 할 수 있습니다. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
`shutdown`은 애플리케이션을 **종료**할 때 발생합니다. |
|||
|
|||
새로운 버전을 시작해야 하거나, 그냥 실행을 멈추고 싶을 수도 있습니다. 🤷 |
|||
|
|||
/// |
|||
|
|||
### Lifespan 함수 |
|||
|
|||
먼저 주목할 점은, `yield`를 사용하여 비동기 함수(async function)를 정의하고 있다는 것입니다. 이는 `yield`를 사용한 의존성과 매우 유사합니다. |
|||
|
|||
{* ../../docs_src/events/tutorial003.py hl[14:19] *} |
|||
|
|||
함수의 첫 번째 부분, 즉 `yield` 이전의 코드는 애플리케이션이 시작되기 **전에** 실행됩니다. |
|||
|
|||
그리고 `yield` 이후의 부분은 애플리케이션이 완료된 후 **나중에** 실행됩니다. |
|||
|
|||
### 비동기 컨텍스트 매니저 |
|||
|
|||
함수를 확인해보면, `@asynccontextmanager`로 장식되어 있습니다. |
|||
|
|||
이것은 함수를 "**비동기 컨텍스트 매니저**"라고 불리는 것으로 변환시킵니다. |
|||
|
|||
{* ../../docs_src/events/tutorial003.py hl[1,13] *} |
|||
|
|||
파이썬에서 **컨텍스트 매니저**는 `with` 문에서 사용할 수 있는 것입니다. 예를 들어, `open()`은 컨텍스트 매니저로 사용할 수 있습니다: |
|||
|
|||
```Python |
|||
with open("file.txt") as file: |
|||
file.read() |
|||
``` |
|||
최근 버전의 파이썬에서는 **비동기 컨텍스트 매니저**도 있습니다. 이를 `async with`와 함께 사용합니다: |
|||
|
|||
```Python |
|||
async with lifespan(app): |
|||
await do_stuff() |
|||
``` |
|||
|
|||
컨텍스트 매니저나 위와 같은 비동기 컨텍스트 매니저를 만들면, `with` 블록에 들어가기 전에 `yield` 이전의 코드가 실행되고, `with` 블록을 벗어난 후에는 `yield` 이후의 코드가 실행됩니다. |
|||
|
|||
위의 코드 예제에서는 직접 사용하지 않고, FastAPI에 전달하여 사용하도록 합니다. |
|||
|
|||
`FastAPI` 애플리케이션의 `lifespan` 매개변수는 **비동기 컨텍스트 매니저**를 받기 때문에, 새로운 `lifespan` 비동기 컨텍스트 매니저를 FastAPI에 전달할 수 있습니다. |
|||
|
|||
{* ../../docs_src/events/tutorial003.py hl[22] *} |
|||
|
|||
## 대체 이벤트 (사용 중단) |
|||
|
|||
/// warning | 경고 |
|||
|
|||
이벤트 핸들러는 주 응용 프로그램에서만 작동합니다. [하위 응용 프로그램 - 마운트](./sub-applications.md){.internal-link target=_blank}에서는 작동하지 않습니다. |
|||
*시작*과 *종료*를 처리하는 권장 방법은 위에서 설명한 대로 `FastAPI` 애플리케이션의 `lifespan` 매개변수를 사용하는 것입니다. `lifespan` 매개변수를 제공하면 `startup`과 `shutdown` 이벤트 핸들러는 더 이상 호출되지 않습니다. `lifespan`을 사용할지, 모든 이벤트를 사용할지 선택해야 하며 둘 다 사용할 수는 없습니다. |
|||
|
|||
이 부분은 건너뛰셔도 좋습니다. |
|||
|
|||
/// |
|||
|
|||
## `startup` 이벤트 |
|||
*시작*과 *종료* 동안 실행될 이 로직을 정의하는 대체 방법이 있습니다. |
|||
|
|||
애플리케이션이 시작되기 전에 또는 종료될 때 실행해야 하는 이벤트 핸들러(함수)를 정의할 수 있습니다. |
|||
|
|||
응용 프로그램을 시작하기 전에 실행하려는 함수를 "startup" 이벤트로 선언합니다: |
|||
이 함수들은 `async def` 또는 일반 `def`로 선언할 수 있습니다. |
|||
|
|||
### `startup` 이벤트 |
|||
|
|||
애플리케이션이 시작되기 전에 실행되어야 하는 함수를 추가하려면, `"startup"` 이벤트로 선언합니다: |
|||
|
|||
{* ../../docs_src/events/tutorial001.py hl[8] *} |
|||
|
|||
이 경우 `startup` 이벤트 핸들러 함수는 단순히 몇 가지 값으로 구성된 `dict` 형식의 "데이터베이스"를 초기화합니다. |
|||
이 경우, `startup` 이벤트 핸들러 함수는 "database"라는 항목(단지 `dict`)을 일부 값으로 초기화합니다. |
|||
|
|||
하나 이상의 이벤트 핸들러 함수를 추가할 수도 있습니다. |
|||
여러 개의 이벤트 핸들러 함수를 추가할 수 있습니다. |
|||
|
|||
그리고 응용 프로그램은 모든 `startup` 이벤트 핸들러가 완료될 때까지 요청을 받지 않습니다. |
|||
애플리케이션은 모든 `startup` 이벤트 핸들러가 완료될 때까지 요청을 받기 시작하지 않습니다. |
|||
|
|||
## `shutdown` 이벤트 |
|||
### `shutdown` 이벤트 |
|||
|
|||
응용 프로그램이 종료될 때 실행하려는 함수를 추가하려면 `"shutdown"` 이벤트로 선언합니다: |
|||
애플리케이션이 종료될 때 실행되어야 하는 함수를 추가하려면, `"shutdown"` 이벤트로 선언합니다: |
|||
|
|||
{* ../../docs_src/events/tutorial002.py hl[6] *} |
|||
|
|||
이 예제에서 `shutdown` 이벤트 핸들러 함수는 `"Application shutdown"`이라는 텍스트가 적힌 `log.txt` 파일을 추가할 것입니다. |
|||
여기서, `shutdown` 이벤트 핸들러 함수는 `"Application shutdown"`이라는 텍스트를 `log.txt` 파일에 기록합니다. |
|||
|
|||
/// info | 정보 |
|||
|
|||
`open()` 함수에서 `mode="a"`는 "추가"를 의미합니다. 따라서 이미 존재하는 파일의 내용을 덮어쓰지 않고 새로운 줄을 추가합니다. |
|||
`open()` 함수에서 `mode="a"`는 "추가"를 의미하므로, 파일에 있는 기존 내용은 덮어쓰지 않고 새로운 줄이 추가됩니다. |
|||
|
|||
/// |
|||
|
|||
/// tip | 팁 |
|||
|
|||
이 예제에서는 파일과 상호작용 하기 위해 파이썬 표준 함수인 `open()`을 사용하고 있습니다. |
|||
이 경우, 우리는 표준 파이썬 `open()` 함수를 사용하여 파일과 상호작용하고 있습니다. |
|||
|
|||
따라서 디스크에 데이터를 쓰기 위해 "대기"가 필요한 I/O (입력/출력) 작업을 수행합니다. |
|||
따라서 I/O(입출력) 작업이 포함되어 있어 디스크에 기록되는 것을 "기다리는" 과정이 필요합니다. |
|||
|
|||
그러나 `open()`은 `async`와 `await`을 사용하지 않기 때문에 이벤트 핸들러 함수는 `async def`가 아닌 표준 `def`로 선언하고 있습니다. |
|||
하지만 `open()`은 `async`와 `await`를 사용하지 않습니다. |
|||
|
|||
그래서 우리는 이벤트 핸들러 함수를 `async def` 대신 일반 `def`로 선언합니다. |
|||
|
|||
/// |
|||
|
|||
### `startup`과 `shutdown`을 함께 사용 |
|||
|
|||
*시작*과 *종료* 로직이 연결될 가능성이 높습니다. 예를 들어, 무언가를 시작한 후 끝내거나, 자원을 획득한 후 해제하는 등의 작업을 할 수 있습니다. |
|||
|
|||
이러한 작업을 별도의 함수로 처리하면 서로 로직이나 변수를 공유하지 않기 때문에 더 어려워집니다. 값들을 전역 변수에 저장하거나 비슷한 트릭을 사용해야 할 수 있습니다. |
|||
|
|||
그렇기 때문에 위에서 설명한 대로 `lifespan`을 사용하는 것이 권장됩니다. |
|||
|
|||
## 기술적 세부사항 |
|||
|
|||
호기심 많은 분들을 위한 기술적인 세부사항입니다. 🤓 |
|||
|
|||
ASGI 기술 사양에 따르면, 이는 <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">Lifespan Protocol</a>의 일부이며, `startup`과 `shutdown`이라는 이벤트를 정의합니다. |
|||
|
|||
/// info | 정보 |
|||
|
|||
이벤트 핸들러에 관한 내용은 <a href="https://www.starlette.io/events/" class="external-link" target="_blank">Starlette 이벤트 문서</a>에서 추가로 확인할 수 있습니다. |
|||
Starlette의 `lifespan` 핸들러에 대해 더 읽고 싶다면 <a href="https://www.starlette.io/lifespan/" class="external-link" target="_blank">Starlette의 Lifespan 문서</a>에서 확인할 수 있습니다. |
|||
|
|||
이 문서에는 코드의 다른 영역에서 사용할 수 있는 lifespan 상태를 처리하는 방법도 포함되어 있습니다. |
|||
|
|||
/// |
|||
|
|||
## 서브 애플리케이션 |
|||
|
|||
🚨 이 lifespan 이벤트(`startup`과 `shutdown`)는 메인 애플리케이션에 대해서만 실행되며, [서브 애플리케이션 - Mounts](sub-applications.md){.internal-link target=_blank}에는 실행되지 않음을 유의하세요. |
|||
|
@ -0,0 +1,223 @@ |
|||
# 추가 모델 |
|||
|
|||
지난 예제에 이어서, 연관된 모델을 여러개 갖는 것은 흔한 일입니다. |
|||
|
|||
특히 사용자 모델의 경우에 그러한데, 왜냐하면: |
|||
|
|||
* **입력 모델** 은 비밀번호를 가져야 합니다. |
|||
* **출력 모델** 은 비밀번호를 가지면 안됩니다. |
|||
* **데이터베이스 모델** 은 해시처리된 비밀번호를 가질 것입니다. |
|||
|
|||
/// danger | 위험 |
|||
|
|||
절대 사용자의 비밀번호를 평문으로 저장하지 마세요. 항상 이후에 검증 가능한 "안전한 해시(secure hash)"로 저장하세요. |
|||
|
|||
만약 이게 무엇인지 모르겠다면, [security chapters](security/simple-oauth2.md#password-hashing){.internal-link target=_blank}.에서 비밀번호 해시에 대해 배울 수 있습니다. |
|||
|
|||
/// |
|||
|
|||
## 다중 모델 |
|||
|
|||
아래는 비밀번호 필드와 해당 필드가 사용되는 위치를 포함하여, 각 모델들이 어떤 형태를 가질 수 있는지 전반적인 예시입니다: |
|||
|
|||
{* ../../docs_src/extra_models/tutorial001_py310.py hl[7,9,14,20,22,27:28,31:33,38:39] *} |
|||
|
|||
|
|||
/// info | 정보 |
|||
|
|||
Pydantic v1에서는 해당 메서드가 `.dict()`로 불렸으며, Pydantic v2에서는 `.model_dump()`로 이름이 변경되었습니다. `.dict()`는 여전히 지원되지만 더 이상 권장되지 않습니다. |
|||
|
|||
여기에서 사용하는 예제는 Pydantic v1과의 호환성을 위해 `.dict()`를 사용하지만, Pydantic v2를 사용할 수 있다면 `.model_dump()`를 사용하는 것이 좋습니다. |
|||
|
|||
/// |
|||
|
|||
### `**user_in.dict()` 에 대하여 |
|||
|
|||
#### Pydantic의 `.dict()` |
|||
|
|||
`user_in`은 Pydantic 모델 클래스인 `UserIn`입니다. |
|||
|
|||
Pydantic 모델은 모델 데이터를 포함한 `dict`를 반환하는 `.dict()` 메서드를 제공합니다. |
|||
|
|||
따라서, 다음과 같이 Pydantic 객체 `user_in`을 생성할 수 있습니다: |
|||
|
|||
```Python |
|||
user_in = UserIn(username="john", password="secret", email="john.doe@example.com") |
|||
``` |
|||
|
|||
그 다음, 다음과 같이 호출합니다: |
|||
|
|||
```Python |
|||
user_dict = user_in.dict() |
|||
``` |
|||
|
|||
이제 변수 `user_dict`에 데이터가 포함된 `dict`를 가지게 됩니다(이는 Pydantic 모델 객체가 아닌 `dict`입니다). |
|||
|
|||
그리고 다음과 같이 호출하면: |
|||
|
|||
```Python |
|||
print(user_dict) |
|||
``` |
|||
|
|||
Python의 `dict`가 다음과 같이 출력됩니다: |
|||
|
|||
```Python |
|||
{ |
|||
'username': 'john', |
|||
'password': 'secret', |
|||
'email': 'john.doe@example.com', |
|||
'full_name': None, |
|||
} |
|||
``` |
|||
|
|||
#### `dict` 언패킹(Unpacking) |
|||
|
|||
`user_dict`와 같은 `dict`를 함수(또는 클래스)에 `**user_dict`로 전달하면, Python은 이를 "언팩(unpack)"합니다. 이 과정에서 `user_dict`의 키와 값을 각각 키-값 인자로 직접 전달합니다. |
|||
|
|||
따라서, 위에서 생성한 `user_dict`를 사용하여 다음과 같이 작성하면: |
|||
|
|||
```Python |
|||
UserInDB(**user_dict) |
|||
``` |
|||
|
|||
다음과 같은 결과를 생성합니다: |
|||
|
|||
```Python |
|||
UserInDB( |
|||
username="john", |
|||
password="secret", |
|||
email="john.doe@example.com", |
|||
full_name=None, |
|||
) |
|||
``` |
|||
|
|||
혹은 더 정확히 말하자면, `user_dict`를 직접 사용하는 것은, 나중에 어떤 값이 추가되더라도 아래와 동일한 효과를 냅니다: |
|||
|
|||
```Python |
|||
UserInDB( |
|||
username = user_dict["username"], |
|||
password = user_dict["password"], |
|||
email = user_dict["email"], |
|||
full_name = user_dict["full_name"], |
|||
) |
|||
``` |
|||
|
|||
#### 다른 모델 데이터로 새 Pydantic 모델 생성 |
|||
|
|||
위의 예제에서 `user_in.dict()`로부터 `user_dict`를 생성한 것처럼, 아래 코드는: |
|||
|
|||
```Python |
|||
user_dict = user_in.dict() |
|||
UserInDB(**user_dict) |
|||
``` |
|||
|
|||
다음과 동일합니다: |
|||
|
|||
```Python |
|||
UserInDB(**user_in.dict()) |
|||
``` |
|||
|
|||
...왜냐하면 `user_in.dict()`는 `dict`이며, 이를 `**`로 Python이 "언팩(unpack)"하도록 하여 `UserInDB`에 전달하기 때문입니다. |
|||
|
|||
따라서, 다른 Pydantic 모델의 데이터를 사용하여 새로운 Pydantic 모델을 생성할 수 있습니다. |
|||
|
|||
#### `dict` 언패킹(Unpacking)과 추가 키워드 |
|||
|
|||
그리고 다음과 같이 추가 키워드 인자 `hashed_password=hashed_password`를 추가하면: |
|||
|
|||
```Python |
|||
UserInDB(**user_in.dict(), hashed_password=hashed_password) |
|||
``` |
|||
|
|||
다음과 같은 결과를 생성합니다: |
|||
|
|||
```Python |
|||
UserInDB( |
|||
username = user_dict["username"], |
|||
password = user_dict["password"], |
|||
email = user_dict["email"], |
|||
full_name = user_dict["full_name"], |
|||
hashed_password = hashed_password, |
|||
) |
|||
``` |
|||
|
|||
/// warning | 경고 |
|||
|
|||
추가적으로 제공된 함수 `fake_password_hasher`와 `fake_save_user`는 데이터 흐름을 시연하기 위한 예제일 뿐이며, 실제 보안을 제공하지 않습니다. |
|||
|
|||
/// |
|||
|
|||
## 중복 줄이기 |
|||
|
|||
코드 중복을 줄이는 것은 **FastAPI**의 핵심 아이디어 중 하나입니다. |
|||
|
|||
코드 중복은 버그, 보안 문제, 코드 비동기화 문제(한 곳은 업데이트되었지만 다른 곳은 업데이트되지 않는 문제) 등의 가능성을 증가시킵니다. |
|||
|
|||
그리고 이 모델들은 많은 데이터를 공유하면서 속성 이름과 타입을 중복하고 있습니다. |
|||
|
|||
더 나은 방법이 있습니다. |
|||
|
|||
`UserBase` 모델을 선언하여 다른 모델들의 기본(base)으로 사용할 수 있습니다. 그런 다음 이 모델을 상속받아 속성과 타입 선언(유형 선언, 검증 등)을 상속하는 서브클래스를 만들 수 있습니다. |
|||
|
|||
모든 데이터 변환, 검증, 문서화 등은 정상적으로 작동할 것입니다. |
|||
|
|||
이렇게 하면 각 모델 간의 차이점만 선언할 수 있습니다(평문 `password`가 있는 경우, `hashed_password`만 있는 경우, 혹은 비밀번호가 없는 경우): |
|||
|
|||
{* ../../docs_src/extra_models/tutorial002_py310.py hl[7,13:14,17:18,21:22] *} |
|||
|
|||
## `Union` 또는 `anyOf` |
|||
|
|||
두 가지 이상의 타입을 포함하는 `Union`으로 응답을 선언할 수 있습니다. 이는 응답이 그 중 하나의 타입일 수 있음을 의미합니다. |
|||
|
|||
OpenAPI에서는 이를 `anyOf`로 정의합니다. |
|||
|
|||
이를 위해 표준 Python 타입 힌트인 <a href="https://docs.python.org/3/library/typing.html#typing.Union" class="external-link" target="_blank">`typing.Union`</a>을 사용할 수 있습니다: |
|||
|
|||
/// note | 참고 |
|||
|
|||
<a href="https://docs.pydantic.dev/latest/concepts/types/#unions" class="external-link" target="_blank">`Union`</a>을 정의할때는 더 구체적인 타입을 먼저 포함하고, 덜 구체적인 타입을 그 뒤에 나열해야합니다. 아래 예제에서는 `Union[PlaneItem, CarItem]` 를 보면, 더 구체적인 `PlaneItem`이 `CarItem`보다 앞에 위치합니다. |
|||
|
|||
/// |
|||
|
|||
{* ../../docs_src/extra_models/tutorial003_py310.py hl[1,14:15,18:20,33] *} |
|||
|
|||
|
|||
### Python 3.10에서 `Union` |
|||
|
|||
위의 예제에서는 `response_model` 인자 값으로 `Union[PlaneItem, CarItem]`을 전달합니다. |
|||
|
|||
이 경우, 이를 **타입 어노테이션(type annotation)** 이 아닌 **인자 값(argument value)** 으로 전달하고 있기 때문에 Python 3.10에서도 `Union`을 사용해야 합니다. |
|||
|
|||
만약 타입 어노테이션에 사용한다면, 다음과 같이 수직 막대(|)를 사용할 수 있습니다: |
|||
|
|||
```Python |
|||
some_variable: PlaneItem | CarItem |
|||
``` |
|||
|
|||
하지만 이를 `response_model=PlaneItem | CarItem`과 같이 할당하면 에러가 발생합니다. 이는 Python이 이를 타입 어노테이션으로 해석하지 않고, `PlaneItem`과 `CarItem` 사이의 **잘못된 연산(invalid operation)**을 시도하기 때문입니다 |
|||
|
|||
## 모델 리스트 |
|||
|
|||
마찬가지로, 객체 리스트 형태의 응답을 선언할 수도 있습니다. |
|||
|
|||
이를 위해 표준 Python의 `typing.List`를 사용하세요(또는 Python 3.9 이상에서는 단순히 `list`를 사용할 수 있습니다): |
|||
|
|||
{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *} |
|||
|
|||
|
|||
## 임의의 `dict` 응답 |
|||
|
|||
Pydantic 모델을 사용하지 않고, 키와 값의 타입만 선언하여 평범한 임의의 `dict`로 응답을 선언할 수도 있습니다. |
|||
|
|||
이는 Pydantic 모델에 필요한 유효한 필드/속성 이름을 사전에 알 수 없는 경우에 유용합니다. |
|||
|
|||
이 경우, `typing.Dict`를 사용할 수 있습니다(또는 Python 3.9 이상에서는 단순히 `dict`를 사용할 수 있습니다): |
|||
|
|||
{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *} |
|||
|
|||
|
|||
## 요약 |
|||
|
|||
여러 Pydantic 모델을 사용하고, 각 경우에 맞게 자유롭게 상속하세요. |
|||
|
|||
엔터티가 서로 다른 "상태"를 가져야 하는 경우, 엔터티당 단일 데이터 모델을 사용할 필요는 없습니다. 예를 들어, 사용자 "엔터티"가 `password`, `password_hash`, 또는 비밀번호가 없는 상태를 포함할 수 있는 경우처럼 말입니다. |
@ -0,0 +1,273 @@ |
|||
# 패스워드 해싱을 이용한 OAuth2, JWT 토큰을 사용하는 Bearer 인증 |
|||
|
|||
모든 보안 흐름을 구성했으므로, 이제 <abbr title="JSON Web Tokens">JWT</abbr> 토큰과 패스워드 해싱을 사용해 애플리케이션을 안전하게 만들 것입니다. |
|||
|
|||
이 코드는 실제로 애플리케이션에서 패스워드를 해싱하여 DB에 저장하는 등의 작업에 활용할 수 있습니다. |
|||
|
|||
이전 장에 이어서 시작해 봅시다. |
|||
|
|||
## JWT |
|||
|
|||
JWT 는 "JSON Web Tokens" 을 의미합니다. |
|||
|
|||
JSON 객체를 공백이 없는 긴 문자열로 인코딩하는 표준이며, 다음과 같은 형태입니다: |
|||
|
|||
``` |
|||
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c |
|||
``` |
|||
|
|||
JWT는 암호화되지 않아 누구든지 토큰에서 정보를 복원할 수 있습니다. |
|||
|
|||
하지만 JWT는 서명되어 있습니다. 그래서 자신이 발급한 토큰을 받았을 때, 실제로 자신이 발급한게 맞는지 검증할 수 있습니다. |
|||
|
|||
만료 기간이 일주일인 토큰을 발행했다고 가정해 봅시다. 다음 날 사용자가 토큰을 가져왔을 때, 그 사용자가 시스템에 여전히 로그인되어 있다는 것을 알 수 있습니다. |
|||
|
|||
일주일 뒤에는 토큰이 만료될 것이고, 사용자는 인가되지 않아 새 토큰을 받기 위해 다시 로그인해야 할 것입니다. 만약 사용자(또는 제3자)가 토큰을 수정하거나 만료일을 변경하면, 서명이 일치하지 않기 때문에 알아챌 수 있을 것입니다. |
|||
|
|||
만약 JWT 토큰을 다뤄보고, 작동 방식도 알아보고 싶다면 <a href="https://jwt.io/" class="external-link" target="_blank">https://jwt.io</a> 을 확인하십시오. |
|||
|
|||
## `PyJWT` 설치 |
|||
|
|||
파이썬으로 JWT 토큰을 생성하고 검증하려면 `PyJWT` 를 설치해야 합니다. |
|||
|
|||
[가상환경](../../virtual-environments.md){.internal-link target=_blank} 을 만들고 활성화한 다음 `pyjwt` 를 설치하십시오: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install pyjwt |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
/// info | 참고 |
|||
|
|||
RSA나 ECDSA 같은 전자 서명 알고리즘을 사용하려면, `pyjwt[crypto]`라는 암호화 라이브러리 의존성을 설치해야 합니다. |
|||
|
|||
더 자세한 내용은 <a href="https://pyjwt.readthedocs.io/en/latest/installation.html" class="external-link" target="_blank">PyJWT 설치</a> 에서 확인할 수 있습니다. |
|||
|
|||
/// |
|||
|
|||
## 패스워드 해싱 |
|||
|
|||
"해싱(Hashing)"은 어떤 내용(여기서는 패스워드)을 해석할 수 없는 일련의 바이트 집합(단순 문자열)으로 변환하는 것을 의미합니다. |
|||
|
|||
동일한 내용(똑같은 패스워드)을 해싱하면 동일한 문자열을 얻습니다. |
|||
|
|||
하지만 그 문자열을 다시 패스워드로 되돌릴 수는 없습니다. |
|||
|
|||
### 패스워드를 해싱하는 이유 |
|||
|
|||
데이터베이스를 탈취당하더라도, 침입자는 사용자의 평문 패스워드 대신 해시 값만 얻을 수 있습니다. |
|||
|
|||
따라서 침입자는 훔친 사용자 패스워드를 다른 시스템에서 활용할 수 없습니다. (대다수 사용자가 여러 시스템에서 동일한 패스워드를 사용하기 때문에 평문 패스워드가 유출되면 위험합니다.) |
|||
|
|||
## `passlib` 설치 |
|||
|
|||
PassLib는 패스워드 해시를 다루는 훌륭한 파이썬 패키지입니다. |
|||
|
|||
많은 안전한 해시 알고리즘과 도구들을 지원합니다. |
|||
|
|||
추천하는 알고리즘은 "Bcrypt"입니다. |
|||
|
|||
[가상환경](../../virtual-environments.md){.internal-link target=_blank} 을 만들고 활성화한 다음 PassLib와 Bcrypt를 설치하십시오: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "passlib[bcrypt]" |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
/// tip | 팁 |
|||
|
|||
`passlib`를 사용하여, **Django**, **Flask** 의 보안 플러그인이나 다른 도구로 생성한 패스워드를 읽을 수 있도록 설정할 수도 있습니다. |
|||
|
|||
예를 들자면, FastAPI 애플리케이션과 Django 애플리케이션이 같은 데이터베이스에서 데이터를 공유할 수 있습니다. 또는 같은 데이터베이스를 사용하여 Django 애플리케이션을 점진적으로 마이그레이션 할 수도 있습니다. |
|||
|
|||
그리고 사용자는 FastAPI 애플리케이션과 Django 애플리케이션에 동시에 로그인할 수 있습니다. |
|||
|
|||
/// |
|||
|
|||
## 패스워드의 해시와 검증 |
|||
|
|||
필요한 도구를 `passlib`에서 임포트합니다. |
|||
|
|||
PassLib "컨텍스트(context)"를 생성합니다. 이것은 패스워드를 해싱하고 검증하는데 사용합니다. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
PassLib 컨텍스트는 다양한 해싱 알고리즘을 사용할 수 있는 기능을 제공하며, 더 이상 사용이 권장되지 않는 오래된 해싱 알고리즘을 검증하는 기능도 포함되어 있습니다. |
|||
|
|||
예를 들어, 다른 시스템(Django 같은)에서 생성한 패스워드를 읽고 검증할 수 있으며, 새로운 패스워드를 Bcrypt 같은 다른 알고리즘으로 해싱할 수도 있습니다. |
|||
|
|||
그리고 동시에 그런 모든 알고리즘과 호환성을 유지합니다. |
|||
|
|||
/// |
|||
|
|||
사용자로부터 받은 패스워드를 해싱하는 유틸리티 함수를 생성합니다. |
|||
|
|||
그리고 받은 패스워드가 저장된 해시와 일치하는지 검증하는 또 다른 유틸리티 함수도 생성합니다. |
|||
|
|||
그리고 사용자를 인증하고 반환하는 또 다른 함수도 생성합니다. |
|||
|
|||
{* ../../docs_src/security/tutorial004_an_py310.py hl[8,49,56:57,60:61,70:76] *} |
|||
|
|||
/// note |
|||
|
|||
새로운 (가짜) 데이터베이스 `fake_users_db`를 확인하면, 해시 처리된 패스워드가 어떻게 생겼는지 볼 수 있습니다: `"$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3vjPGga31lW"`. |
|||
|
|||
/// |
|||
|
|||
## JWT 토큰 처리 |
|||
|
|||
설치된 모듈을 임포트 합니다. |
|||
|
|||
JWT 토큰 서명에 사용될 임의의 비밀키를 생성합니다. |
|||
|
|||
안전한 임의의 비밀키를 생성하려면 다음 명령어를 사용하십시오: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ openssl rand -hex 32 |
|||
|
|||
09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7 |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
그리고 생성한 비밀키를 복사해 변수 `SECRET_KEY`에 대입합니다. (이 예제의 변수 값을 그대로 사용하지 마십시오.) |
|||
|
|||
JWT 토큰을 서명하는 데 사용될 알고리즘을 위한 변수 `ALGORITHM` 을 생성하고 `"HS256"` 으로 설정합니다. |
|||
|
|||
토큰 만료 기간을 위한 변수를 생성합니다. |
|||
|
|||
응답을 위한 토큰 엔드포인트에 사용될 Pydantic 모델을 정의합니다. |
|||
|
|||
새 액세스 토큰을 생성하기 위한 유틸리티 함수를 생성합니다. |
|||
|
|||
{* ../../docs_src/security/tutorial004_an_py310.py hl[4,7,13:15,29:31,79:87] *} |
|||
|
|||
## 의존성 수정 |
|||
|
|||
`get_current_user` 함수를 이전과 동일한 토큰을 받도록 수정하되, 이번에는 JWT 토큰을 사용하도록 합니다. |
|||
|
|||
받은 토큰을 디코딩하여 검증한 후 현재 사용자를 반환합니다. |
|||
|
|||
토큰이 유효하지 않다면 HTTP 오류를 반환합니다. |
|||
|
|||
{* ../../docs_src/security/tutorial004_an_py310.py hl[90:107] *} |
|||
|
|||
## `/token` 경로 작업 수정 |
|||
|
|||
토큰의 만료 시각을 설정하기 위해 `timedelta` 를 생성합니다. |
|||
|
|||
실제 JWT 액세스 토큰을 생성하여 반환합니다. |
|||
|
|||
{* ../../docs_src/security/tutorial004_an_py310.py hl[118:133] *} |
|||
|
|||
### JWT "주체(subject)" `sub`에 대한 기술 세부 사항 |
|||
|
|||
JWT 명세에 따르면 토큰의 주체를 포함하는 `sub`라는 키가 있습니다. |
|||
|
|||
사용 여부는 선택사항이지만, 사용자의 식별 정보를 저장할 수 있으므로 여기서는 이를 사용합니다. |
|||
|
|||
JWT는 사용자를 식별하고 사용자가 API를 직접 사용할 수 있도록 허용하는 것 외에도 다른 용도로 사용될 수도 있습니다. |
|||
|
|||
예를 들어 "자동차"나 "블로그 게시물"을 식별하는 데 사용할 수 있습니다. |
|||
|
|||
그리고 "자동차를 운전하다"나 "블로그 게시물을 수정하다"처럼 해당 엔터티에 대한 권한을 추가할 수 있습니다. |
|||
|
|||
그 후 이 JWT 토큰을 사용자(또는 봇)에게 제공하면, 그들은 계정을 따로 만들 필요 없이 API가 생성한 JWT 토큰만으로 작업(자동차 운전 또는 블로그 게시물 편집)을 수행할 수 있습니다. |
|||
|
|||
이러한 개념을 활용하면 JWT는 훨씬 더 복잡한 시나리오에도 사용할 수 있습니다. |
|||
|
|||
이 경우 여러 엔터티가 동일한 ID를 가질 수 있습니다. 예를 들어 foo라는 ID를 가진 사용자, 자동차, 블로그 게시물이 있을 수 있습니다. |
|||
|
|||
그래서 ID 충돌을 방지하기 위해, 사용자의 JWT 토큰을 생성할 때 접두사로 `sub` 키를 추가할 수 있습니다. 예를 들어 `username:` 을 붙이는 방식입니다. 이 예제에서는 `sub` 값이 `username:johndoe`이 될 수 있습니다. |
|||
|
|||
가장 중요한 점은 `sub` 키는 전체 애플리케이션에서 고유한 식별자가 되어야 하며 문자열이어야 한다는 점입니다. |
|||
|
|||
## 확인해봅시다 |
|||
|
|||
서버를 실행하고 문서로 이동하십시오: <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>. |
|||
|
|||
다음과 같은 사용자 인터페이스를 볼 수 있습니다: |
|||
|
|||
<img src="/img/tutorial/security/image07.png"> |
|||
|
|||
이전과 같은 방법으로 애플리케이션에 인증하십시오. |
|||
|
|||
다음 인증 정보를 사용하십시오: |
|||
|
|||
Username: `johndoe` |
|||
Password: `secret` |
|||
|
|||
/// check |
|||
|
|||
코드 어디에도 평문 패스워드 "`secret`" 이 없다는 점에 유의하십시오. 해시된 버전만 있습니다. |
|||
|
|||
/// |
|||
|
|||
<img src="/img/tutorial/security/image08.png"> |
|||
|
|||
`/users/me/` 를 호출하면 다음과 같은 응답을 얻을 수 있습니다: |
|||
|
|||
```JSON |
|||
{ |
|||
"username": "johndoe", |
|||
"email": "johndoe@example.com", |
|||
"full_name": "John Doe", |
|||
"disabled": false |
|||
} |
|||
``` |
|||
|
|||
<img src="/img/tutorial/security/image09.png"> |
|||
|
|||
개발자 도구를 열어보면 전송된 데이터에 토큰만 포함된 것을 확인할 수 있습니다. 패스워드는 사용자를 인증하고 액세스 토큰을 받기 위한 첫 번째 요청에만 전송되며, 이후에는 전송되지 않습니다: |
|||
|
|||
<img src="/img/tutorial/security/image10.png"> |
|||
|
|||
/// note |
|||
|
|||
`Bearer `로 시작하는 `Authorization` 헤더에 주목하십시오. |
|||
|
|||
/// |
|||
|
|||
## `scopes` 의 고급 사용법 |
|||
|
|||
OAuth2는 "스코프(scopes)" 라는 개념을 갖고 있습니다. |
|||
|
|||
이를 사용하여 JWT 토큰에 특정 권한 집합을 추가할 수 있습니다. |
|||
|
|||
그 후 이 토큰을 사용자에게 직접 제공하거나 제3자에게 제공하여, 특정 제한사항 하에있는 API와 통신하도록 할 수 있습니다. |
|||
|
|||
**FastAPI** 에서의 사용 방법과 통합 방식은 **심화 사용자 안내서** 에서 자세히 배울 수 있습니다. |
|||
|
|||
## 요약 |
|||
|
|||
지금까지 살펴본 내용을 바탕으로, OAuth2와 JWT 같은 표준을 사용하여 안전한 **FastAPI** 애플리케이션을 만들 수 있습니다. |
|||
|
|||
거의 모든 프레임워크에서 보안 처리는 상당히 복잡한 주제입니다. |
|||
|
|||
이를 단순화하는 많은 패키지는 데이터 모델, 데이터베이스, 사용 가능한 기능들에 대해 여러 제약이 있습니다. 그리고 지나치게 단순화하는 일부 패키지들은 심각한 보안 결함을 가질 수도 있습니다. |
|||
|
|||
--- |
|||
|
|||
**FastAPI** 는 어떤 데이터베이스, 데이터 모델, 도구도 강요하지 않습니다. |
|||
|
|||
프로젝트에 가장 적합한 것을 선택할 수 있는 유연성을 제공합니다. |
|||
|
|||
그리고 `passlib` 와 `PyJWT` 처럼 잘 관리되고 널리 사용되는 패키지들을 바로 사용할 수 있습니다. **FastAPI** 는 외부 패키지 통합을 위해 복잡한 메커니즘이 필요하지 않기 때문입니다. |
|||
|
|||
그러나 유연성, 견고성, 보안성을 해치지 않으면서 과정을 단순화할 수 있는 도구들을 제공합니다. |
|||
|
|||
그리고 OAuth2와 같은 표준 프로토콜을 비교적 간단한 방법으로 구현하고 사용할 수 있습니다. |
|||
|
|||
더 세분화된 권한 체계를 위해 OAuth2의 "스코프"를 사용하는 방법은 **심화 사용자 안내서**에서 더 자세히 배울 수 있습니다. OAuth2의 스코프는 제3자 애플리케이션이 사용자를 대신해 그들의 API와 상호작용하도록 권한을 부여하기 위해, Facebook, Google, GitHub, Microsoft, Twitter 등의 많은 대형 인증 제공업체들이 사용하는 메커니즘입니다. |
@ -0,0 +1,846 @@ |
|||
# 가상 환경 |
|||
|
|||
Python 프로젝트를 작업할 때는 **가상 환경** (또는 이와 유사한 도구)을 사용하는 것이 좋습니다. 각 프로젝트 마다 설치하는 패키지를 분리하여 관리할 수 있습니다. |
|||
|
|||
/// info | 정보 |
|||
|
|||
이미 가상 환경에 대해 잘 알고 있다면, 이 섹션은 건너 뛰어도 괜찮습니다. 🤓 |
|||
|
|||
/// |
|||
|
|||
/// tip | 팁 |
|||
|
|||
**가상 환경(Virtual Environment)** 은 **환경 변수(Environment Variable)** 와 다릅니다. |
|||
|
|||
**환경 변수**는 시스템에 존재하며, 프로그램이 사용할 수 있는 변수입니다. |
|||
|
|||
**가상 환경**은 몇몇 파일로 구성된 하나의 디렉터리입니다. |
|||
|
|||
/// |
|||
|
|||
/// info | 정보 |
|||
|
|||
이 페이지에서는 **가상 환경**의 사용 방법과 작동 방식을 설명합니다. |
|||
|
|||
만약 **모든 것을 관리해주는 도구** (Python 설치까지 포함)를 사용하고 싶다면 <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>를 사용해보세요. |
|||
|
|||
/// |
|||
|
|||
## 프로젝트 생성 |
|||
|
|||
먼저, 프로젝트를 위한 디렉터리를 하나 생성합니다. |
|||
|
|||
보통 사용자 홈 디렉터리 안에 `code`라는 디렉터리를 만들고, 그 안에 프로젝트마다 하나씩 디렉터리를 만들어 관리합니다. |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
// 홈 디렉터리로 이동 |
|||
$ cd |
|||
// 모든 코드 프로젝트를 위한 디렉터리 생성 |
|||
$ mkdir code |
|||
// code 디렉터리로 이동 |
|||
$ cd code |
|||
// 이번 프로젝트를 위한 디렉터리 생성 |
|||
$ mkdir awesome-project |
|||
// 해당 프로젝트 디렉터리로 이동 |
|||
$ cd awesome-project |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
## 가상 환경 생성 |
|||
|
|||
Python 프로젝트를 **처음 시작할 때**, 가상 환경을 **<abbr title="다른 방법들도 있지만, 이건 간단한 가이드라인입니다">프로젝트 내부</abbr>**에 생성합니다. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
이 작업은 **프로젝트를 처음 설정할 때 한번만** 해주면 됩니다. 이후 작업할 때 반복할 필요는 없습니다. |
|||
|
|||
/// |
|||
|
|||
//// tab | `venv` |
|||
|
|||
Python 표준 라이브러리에 포함된 venv 모듈을 사용해 가상 환경을 생성할 수 있습니다. |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ python -m venv .venv |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
/// details | 명령어 상세 설명 |
|||
|
|||
* `python`: `python` 프로그램을 실행합니다. |
|||
* `-m`: 특정 모듈을 스크립트처럼 실행합니다. 대상 모듈을 바로 뒤에 지정합니다. |
|||
* `venv`: Python 표준 라이브러리에 포함된 `venv` 모듈을 실행합니다. |
|||
* `.venv`: 가상 환경을 `.venv` 디렉터리에 생성합니다. |
|||
|
|||
/// |
|||
|
|||
//// |
|||
|
|||
//// tab | `uv` |
|||
|
|||
<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>가 설치되어 있다면, uv를 통해 가상 환경을 생성할 수 있습니다. |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ uv venv |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
/// tip | 팁 |
|||
|
|||
`uv`는 기본적으로 `.venv` 디렉터리에 가상 환경을 생성합니다. |
|||
|
|||
별도로 디렉터리 이름을 추가 인자로 넘겨 주면 경로를 지정 할 수 있습니다. |
|||
|
|||
/// |
|||
|
|||
//// |
|||
|
|||
해당 명령어는 `.venv` 디렉터리에 새로운 가상 환경을 생성합니다. |
|||
|
|||
/// details | `.venv` 또는 다른 이름 |
|||
|
|||
가상 환경을 다른 디렉터리에 생성할 수도 있지만, 관례적으로 `.venv` 디렉터리 이름을 사용합니다. |
|||
|
|||
/// |
|||
|
|||
## 가상 환경 활성화 |
|||
|
|||
이후 실행하는 Python 명령어와 패키지 설치가 가상 환경을 따르도록, 가상 환경을 활성화하세요. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
**터미널을 새로 열고** 프로젝트 작업을 시작할 때는, **항상 이 작업을** 해주세요. |
|||
|
|||
/// |
|||
|
|||
//// tab | Linux, macOS |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ source .venv/bin/activate |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows PowerShell |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ .venv\Scripts\Activate.ps1 |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows Bash |
|||
|
|||
Windows에서 Bash(예: <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>)를 사용하는 경우: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ source .venv/Scripts/activate |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
/// tip | 팁 |
|||
|
|||
가상 환경에 새로운 패키지를 설치할 때마다, 해당 환경을 다시 활성화하세요. |
|||
|
|||
이렇게 하면 해당 패키지로 설치된 **터미널(<abbr title="command line interface">CLI</abbr>) 프로그램**을 사용할 때, 전역에 설치된 다른 버전이 아니라, 가상 환경 안에 설치된 정확한 버전을 사용합니다. |
|||
|
|||
/// |
|||
|
|||
## 가상 환경이 활성화 여부 확인 |
|||
|
|||
가상 환경이 활성화되었는지 확인합니다. (이전 명령어가 제대로 작동했는지 확인합니다). |
|||
|
|||
/// tip | 팁 |
|||
|
|||
이 단계는 **선택 사항**이지만, 모든 것이 예상대로 작동하고 있는지, 그리고 의도한 가상 환경이 활성화 되었는 지 **확인**하는 좋은 방법입니다. |
|||
|
|||
/// |
|||
|
|||
//// tab | Linux, macOS, Windows Bash |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ which python |
|||
|
|||
/home/user/code/awesome-project/.venv/bin/python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
`python` 위치가 프로젝트 내부(이 예시에서는 `awesome-project`)의 `.venv/bin/python` 경로로 표시된다면 성공입니다. 🎉 |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows PowerShell |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ Get-Command python |
|||
|
|||
C:\Users\user\code\awesome-project\.venv\Scripts\python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
`python` 위치가 프로젝트 내부(이 예시에서는 `awesome-project`)의 `.venv\bin\python` 경로로 표시된다면 성공입니다. 🎉 |
|||
|
|||
//// |
|||
|
|||
## pip 업그레이드 |
|||
|
|||
/// tip | 팁 |
|||
|
|||
<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>를 사용한다면, `pip` 대신 `uv`로 패키지를 설치하게 되므로 `pip`을 업그레이드할 필요가 없습니다. 😎 |
|||
|
|||
/// |
|||
|
|||
`pip`을 사용하여 패키지를 설치하는 경우 (Python 표준 라이브러리에 포함되어 있습니다), **최신 버전으로 업그레이드**하는 것이 좋습니다. |
|||
|
|||
패키지 설치 중 발생하는 다양하고 특이한 에러들은 `pip` 업그레이드로 쉽게 해결되는 경우가 많습니다. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
이 작업은 보통 가상 환경을 생성한 **직후 한 번만** 하면 됩니다. |
|||
|
|||
/// |
|||
|
|||
가상 환경이 활성화된 상태인지 확인한 후(앞서 설명한 명령어 사용), 아래 명령어를 실행하세요: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ python -m pip install --upgrade pip |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
## `.gitignore` 추가하기 |
|||
|
|||
**Git**을 사용하고 있다면 (사용하는 것이 좋습니다), `.gitignore` 파일을 추가해서 `.venv` 디렉터리 전체를 Git에서 제외하세요. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>를 사용해 가상 환경을 생성했다면, 이미 이 작업이 자동으로 처리되어 있으므로 이 단계는 건너뛰어도 됩니다. 😎 |
|||
|
|||
/// |
|||
|
|||
/// tip | 팁 |
|||
|
|||
이 작업도 마찬가지로, 가상 환경을 생성한 **직후 한 번만** 하면 됩니다. |
|||
|
|||
/// |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ echo "*" > .venv/.gitignore |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
/// details | 명령어 상세 설명 |
|||
|
|||
* `echo "*"`: 터미널에 `*` 텍스트를 "출력"합니다 (다음 설명에서 조금 바뀝니다) |
|||
* `>`: 왼쪽 명령어의 출력 내용을 터미널에 출력하지 않고, 오른쪽에 지정된 파일로 **기록(write)** 하라는 의미입니다. |
|||
* `.gitignore`: 출력된 텍스트가 기록될 파일 이름입니다. |
|||
|
|||
그리고 Git에서 `*`는 "모든 것"을 의미합니다. 따라서 `.venv` 디렉터리 안의 모든 것을 무시하게 됩니다. |
|||
|
|||
이 명령어는 다음과 같은 내용을 가진 `.gitignore` 파일을 생성합니다: |
|||
|
|||
|
|||
```gitignore |
|||
* |
|||
``` |
|||
|
|||
/// |
|||
|
|||
## 패키지 설치 |
|||
|
|||
가상 환경을 활성화한 후, 그 안에 필요한 패키지들을 설치할 수 있습니다. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
프로젝트에서 필요한 패키지를 설치하거나 업그레이드할 때는 이 작업을 **한 번만** 하면 됩니다. |
|||
|
|||
만약 특정 패키지의 버전을 업그레이드하거나, 새로운 패키지를 추가할 필요가 생기면 **다시 이 작업을 반복**하면 됩니다. |
|||
|
|||
/// |
|||
|
|||
### 패키지 직접 설치 |
|||
|
|||
급하게 작업하거나, 프로젝트에 필요한 패키지 목록을 따로 파일로 관리하고 싶지 않은 경우, 패키지를 직접 설치할 수도 있습니다. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
패키지 이름과 버전 정보를 파일에 정리해두는 것(예: `requirements.txt` 또는 `pyproject.toml`)은 (매우) 좋은 생각입니다. |
|||
|
|||
/// |
|||
|
|||
//// tab | `pip` |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "fastapi[standard]" |
|||
|
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | `uv` |
|||
|
|||
<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>를 사용하는 경우: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ uv pip install "fastapi[standard]" |
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
### `requirements.txt`에서 설치 |
|||
|
|||
`requirements.txt` 파일이 있다면, 그 안에 명시된 패키지들을 한 번에 설치할 수 있습니다. |
|||
|
|||
//// tab | `pip` |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install -r requirements.txt |
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | `uv` |
|||
|
|||
<a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">`uv`</a>를 사용하는 경우: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ uv pip install -r requirements.txt |
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
/// details | `requirements.txt` |
|||
|
|||
다음은 몇 가지 패키지를 포함한 `requirements.txt`의 예시입니다: |
|||
|
|||
```requirements.txt |
|||
fastapi[standard]==0.113.0 |
|||
pydantic==2.8.0 |
|||
``` |
|||
|
|||
/// |
|||
|
|||
## 프로그램 실행 |
|||
|
|||
가상 환경을 활성화한 후에는 프로그램을 실행할 수 있습니다. 이때 해당 가상 환경에 설치된 Python과 패키지들이 사용됩니다. |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ python main.py |
|||
|
|||
Hello World |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
## 에디터 설정 |
|||
|
|||
에디터를 사용할 경우, 앞서 만든 가상 환경을 사용하도록 설정하는 것이 좋습니다. (대부분의 에디터는 자동으로 감지하기도 합니다.) |
|||
이렇게 하면 자동 완성 기능이나 코드 내 오류 표시 기능을 제대로 사용할 수 있습니다. |
|||
|
|||
예시: |
|||
|
|||
* <a href="https://code.visualstudio.com/docs/python/environments#_select-and-activate-an-environment" class="external-link" target="_blank">VS Code</a> |
|||
* <a href="https://www.jetbrains.com/help/pycharm/creating-virtual-environment.html" class="external-link" target="_blank">PyCharm</a> |
|||
|
|||
/// tip | 팁 |
|||
|
|||
이 설정은 보통 가상 환경을 **처음 만들었을 때 한 번만** 해주면 됩니다. |
|||
|
|||
/// |
|||
|
|||
## 가상 환경 비활성화 |
|||
|
|||
프로젝트 작업이 끝났다면, 가상 환경을 **비활성화**할 수 있습니다. |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ deactivate |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
이렇게 하면 이후에 `python` 명령어를 실행했을 때, 가상 환경의 Python이나 그 안에 설치된 패키지들을 사용하지 않게 됩니다. |
|||
|
|||
## 이제 작업할 준비가 되었습니다 |
|||
|
|||
이제 프로젝트 작업을 시작할 준비가 완료되었습니다. |
|||
|
|||
|
|||
/// tip | 팁 |
|||
|
|||
위 내용을 더 깊이 이해하고 싶으신가요? |
|||
|
|||
그렇다면 계속 읽어 주세요. 👇🤓 |
|||
|
|||
/// |
|||
|
|||
## 가상 환경을 왜 사용하는가 |
|||
|
|||
FastAPI를 사용하려면 먼저 <a href="https://www.python.org/" class="external-link" target="_blank">Python</a>을 설치해야 합니다. |
|||
|
|||
그 후에는 FastAPI와 함께 사용할 **기타 패키지들**을 **설치**해야 합니다. |
|||
|
|||
패키지를 설치할 때 보통 Python에 기본 포함된 `pip` 명령어(또는 유사한 도구)를 사용합니다. |
|||
|
|||
하지만 `pip`을 그냥 직접 사용하면, 해당 패키지들은 **전역 Python 환경**(시스템 전체에 설치된 Python)에 설치됩니다. |
|||
|
|||
### 문제점 |
|||
|
|||
그렇다면, 전역 Python 환경에 패키지를 설치하면 어떤 문제가 발생할까요? |
|||
|
|||
어느 시점이 되면, **서로 다른 패키지들**에 의존하는 여러 개의 프로그램을 작성하게 될 것입니다. 그리고 이들 중 일부는 **같은 패키지의 서로 다른 버전**을 필요로 할 수 있습니다. 😱 |
|||
|
|||
예를 들어, `마법사의 돌(philosophers-stone)` 프로젝트를 만들었다고 가정해봅시다. 이 프로그램은 `해리 포터(harry)`라는 패키지의 `v1` 버전을 **의존**합니다. 따라서 `harry`를 설치해야 합니다. |
|||
|
|||
```mermaid |
|||
flowchart LR |
|||
stone(philosophers-stone) -->|requires| harry-1[harry v1] |
|||
``` |
|||
|
|||
그런데 나중에 `아즈카반의 죄수(prisoner-of-azkaban)`이라는 또 다른 프로젝트를 만들게 되었고, 이 프로젝트도 역시 `harry` 패키지를 사용합니다. 그런데 이 프로젝트는 `harry`의 `v3` 버전이 필요합니다. |
|||
|
|||
```mermaid |
|||
flowchart LR |
|||
azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3] |
|||
``` |
|||
|
|||
하지만 이제 문제가 생깁니다. 로컬 가상 환경 대신에 전역 환경에 패키지를 설치하게 되면, 어떤 버전의 `harry`를 설치할지를 선택해야 하기 때문입니다. |
|||
|
|||
예를 들어, `마법사의 돌(philosophers-stone)`을 실행하고 싶다면 먼저 `harry` `v1` 버전을 다음과 같이 설치 해야 합니다: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "harry==1" |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
그러면 결국 전역 Python 환경에는 `harry` `v1`버전이 설치된 상태가 됩니다. |
|||
|
|||
```mermaid |
|||
flowchart LR |
|||
subgraph global[global env] |
|||
harry-1[harry v1] |
|||
end |
|||
subgraph stone-project[philosophers-stone project] |
|||
stone(philosophers-stone) -->|requires| harry-1 |
|||
end |
|||
``` |
|||
|
|||
하지만 이제 `아즈카반의 죄수(prisoner-of-azkaban)`을 실행하고 싶다면, `harry` `v1`버전을 제거하고 `harry` `v3`버전을 설치해야 합니다. (또는 단순히 `v3`버전을 설치하는 것만으로도 기존의 `v1`버전이 자동으로 제거됩니다.) |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ pip install "harry==3" |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
그렇게 하면 이제 전역 Python 환경에는 `harry` `v3`버전이 설치된 상태가 됩니다. |
|||
|
|||
그리고 다시 `마법사의 돌(philosophers-stone)`을 실행하려고 하면, **작동하지** 않을 수 있습니다. 왜냐하면 이 프로그램은 `harry` `v1`버전을 필요로 하기 때문입니다. |
|||
|
|||
```mermaid |
|||
flowchart LR |
|||
subgraph global[global env] |
|||
harry-1[<strike>harry v1</strike>] |
|||
style harry-1 fill:#ccc,stroke-dasharray: 5 5 |
|||
harry-3[harry v3] |
|||
end |
|||
subgraph stone-project[philosophers-stone project] |
|||
stone(philosophers-stone) -.-x|⛔️| harry-1 |
|||
end |
|||
subgraph azkaban-project[prisoner-of-azkaban project] |
|||
azkaban(prisoner-of-azkaban) --> |requires| harry-3 |
|||
end |
|||
``` |
|||
|
|||
/// tip | 팁 |
|||
|
|||
Python 패키지들은 **새 버전**에서 **호환성 문제(breaking changes)**가 발생하지 않도록 최대한 노력하는 것이 일반적입니다. 하지만 그래도 안전하게 작업하려면, 테스트를 실행해보면서 새 버전을 의도적으로 설치하는 것이 좋습니다. |
|||
|
|||
/// |
|||
|
|||
이제, 이런 일이 여러분의 **모든 프로젝트**가 사용하는 **수많은 패키지들**에서 동시에 발생한다고 상상해보세요. 이는 매우 관리하기 어려우며, 결국 **서로 호환되지 않는 버전**의 패키지로 프로젝트를 실행하게 될 가능성이 높고, 그로 인해 어떤 문제가 왜 발생하는지 알 수 없게 될 수 있습니다. |
|||
|
|||
또한 사용하는 운영체제(Linux, Windows, macOS 등)에 따라 Python이 **미리 설치되어 있을 수도** 있습니다. 이런 경우에는 운영체제의 동작에 필요한 특정 버전의 패키지들이 함께 설치되어 있을 수 있습니다. 이 상태에서 전역 Python 환경에 임의의 패키지를 설치하면, 운영체제에 포함된 프로그램 일부가 **깨질 위험**도 있습니다. |
|||
|
|||
## 패키지들은 어디에 설치되는가 |
|||
|
|||
Python을 설치하면, 컴퓨터에 여러 디렉터리와 파일들이 생성됩니다. |
|||
|
|||
이 중 일부 디렉터리는 사용자가 설치한 패키지들을 보관하는 역할을 합니다. |
|||
|
|||
예를 들어, 아래 명령어를 실행하면: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
// 지금 실행하지 않아도 됩니다, 그냥 예제일 뿐이에요 🤓 |
|||
$ pip install "fastapi[standard]" |
|||
---> 100% |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
해당 명령어는 FastAPI 코드를 포함한 압축 파일을 다운로드합니다. 이 파일은 보통 <a href="https://pypi.org/project/fastapi/" class="external-link" target="_blank">PyPI</a>에서 받아옵니다. |
|||
|
|||
또한 FastAPI가 의존하는 다른 패키지들도 함께 **다운로드**됩니다. |
|||
|
|||
그리고 그 모든 파일들을 **압축 해제**한 뒤, 컴퓨터의 특정 디렉터리에 저장합니다. |
|||
|
|||
기본적으로 이 파일들은 Python이 설치된 디렉터리 안, 즉 **전역 환경**에 내의 디렉터리에 저장됩니다. |
|||
|
|||
## 가상 환경이란 |
|||
|
|||
전역 환경에 모든 패키지를 설치하면서 발생하는 문제에 대한 해결책은, 작업하는 **각 프로젝트마다 가상 환경**을 사용하는 것입니다. |
|||
|
|||
가상 환경은 전역 환경과 매우 유사한 하나의 **디렉터리**이며, 그 안에 해당 프로젝트를 위한 패키지들을 설치할 수 있습니다. |
|||
|
|||
이렇게 하면 각 프로젝트는 자체적인 가상 환경(`.venv` 디렉터리)을 가지게 되며, 그 안에 해당 프로젝트 전용 패키지들을 보유하게 됩니다. |
|||
|
|||
|
|||
```mermaid |
|||
flowchart TB |
|||
subgraph stone-project[philosophers-stone project] |
|||
stone(philosophers-stone) --->|requires| harry-1 |
|||
subgraph venv1[.venv] |
|||
harry-1[harry v1] |
|||
end |
|||
end |
|||
subgraph azkaban-project[prisoner-of-azkaban project] |
|||
azkaban(prisoner-of-azkaban) --->|requires| harry-3 |
|||
subgraph venv2[.venv] |
|||
harry-3[harry v3] |
|||
end |
|||
end |
|||
stone-project ~~~ azkaban-project |
|||
``` |
|||
|
|||
## 가상 환경 활성화 의미 |
|||
|
|||
가상 환경을 활성화한다는 것은, 예를 들어 다음과 같은 명령어를 실행하는 것을 의미합니다: |
|||
|
|||
//// tab | Linux, macOS |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ source .venv/bin/activate |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows PowerShell |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ .venv\Scripts\Activate.ps1 |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows Bash |
|||
|
|||
Windows에서 Bash(예: <a href="https://gitforwindows.org/" class="external-link" target="_blank">Git Bash</a>)를 사용하는 경우: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ source .venv/Scripts/activate |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
이 명령어는 이후에 실행될 명령어에서 사용될 [환경 변수](environment-variables.md){.internal-link target=_blank} 몇 개를 생성하거나 수정합니다. |
|||
|
|||
이 변수들 중 하나가 바로 `PATH` 변수입니다. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
`PATH` 환경 변수에 대해 더 알고 싶다면 [환경 변수 문서의 PATH 환경 변수 섹션](environment-variables.md#path-environment-variable){.internal-link target=_blank}을 참고하세요. |
|||
|
|||
/// |
|||
|
|||
가상 환경을 활성화하면, 가상 환경의 경로인 `.venv/bin` (Linux와 macOS) 또는 `.venv\Scripts`(Windows)를 `PATH` 환경 변수에 추가됩니다. |
|||
|
|||
예를 들어, 가상 환경을 활성화하기 전의 `PATH` 변수는 다음과 같았다고 가정해봅시다: |
|||
|
|||
//// tab | Linux, macOS |
|||
|
|||
```plaintext |
|||
/usr/bin:/bin:/usr/sbin:/sbin |
|||
``` |
|||
|
|||
시스템은 다음 경로들에서 프로그램을 찾게 됩니다: |
|||
|
|||
* `/usr/bin` |
|||
* `/bin` |
|||
* `/usr/sbin` |
|||
* `/sbin` |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows |
|||
|
|||
```plaintext |
|||
C:\Windows\System32 |
|||
``` |
|||
|
|||
시스템은 다음 경로들에서 프로그램을 찾게 됩니다: |
|||
|
|||
* `C:\Windows\System32` |
|||
|
|||
//// |
|||
|
|||
가상 환경을 활성화한 후에는, `PATH` 변수는 다음과 같은 형태가 됩니다: |
|||
|
|||
//// tab | Linux, macOS |
|||
|
|||
```plaintext |
|||
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin |
|||
``` |
|||
|
|||
시스템은 가장 먼저 다음 경로에서 프로그램을 찾기 시작합니다: |
|||
|
|||
```plaintext |
|||
/home/user/code/awesome-project/.venv/bin |
|||
``` |
|||
|
|||
그 후에 다른 디렉터리들을 탐색합니다. |
|||
|
|||
따라서 터미널에 `python`을 입력하면, 시스템은 다음 위치에 있는 Python 프로그램을 찾게 됩니다: |
|||
|
|||
```plaintext |
|||
/home/user/code/awesome-project/.venv/bin/python |
|||
``` |
|||
|
|||
그리고 해당 Python을 사용하게 됩니다. |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows |
|||
|
|||
```plaintext |
|||
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32 |
|||
``` |
|||
|
|||
시스템은 가장 먼저 다음 경로에서 프로그램을 찾기 시작합니다: |
|||
|
|||
```plaintext |
|||
C:\Users\user\code\awesome-project\.venv\Scripts |
|||
``` |
|||
|
|||
그 후에 다른 디렉터리들을 탐색합니다. |
|||
|
|||
따라서 터미널에 `python`을 입력하면, 시스템은 다음 경로에 있는 Python 프로그램을 찾게 됩니다: |
|||
|
|||
```plaintext |
|||
C:\Users\user\code\awesome-project\.venv\Scripts\python |
|||
``` |
|||
|
|||
그리고 해당 Python을 사용하게 됩니다. |
|||
|
|||
//// |
|||
|
|||
중요한 세부 사항 중 하나는, 가상 환경의 경로가 `PATH` 변수의 가장 **앞**에 추가된다는 점입니다. 시스템은 사용 가능한 다른 Python들보다 **먼저** 이 경로를 찾습니다. 그래서 터미널에서 `python`을 실행하면, 전역 환경의 Python이 아닌 **가상 환경에 있는** Python이 사용됩니다. (예: 전역 환경에 설치된 `python`이 있더라도 그보다 우선합니다.) |
|||
|
|||
가상 환경을 활성화하면 이 외에도 몇 가지 다른 것들이 변경되지만, 이는 그중에서도 가장 중요한 변화 중 하나입니다. |
|||
|
|||
## 가상 환경 확인하기 |
|||
|
|||
가상 환경이 활성화 되었는지 확인하려면, 아래 명령어를 사용할 수 있습니다: |
|||
|
|||
//// tab | Linux, macOS, Windows Bash |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ which python |
|||
|
|||
/home/user/code/awesome-project/.venv/bin/python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
//// tab | Windows PowerShell |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ Get-Command python |
|||
|
|||
C:\Users\user\code\awesome-project\.venv\Scripts\python |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
//// |
|||
|
|||
즉, 현재 사용되는 `python` 프로그램은 **가상 환경 내부에 있는 것**입니다. |
|||
|
|||
Linux와 macOS에서는 `which`, Windows PowerShell에서는 `Get-Command` 명령어를 사용합니다. |
|||
|
|||
이 명령어는 `PATH` 환경 변수에 지정된 경로들을 **순서대로 탐색**하면서 `python`이라는 이름의 프로그램을 찾습니다. |
|||
찾는 즉시, 해당 프로그램의 **경로를 출력**합니다. |
|||
|
|||
중요한 점은 터미널에서 `python`을 실행했을 때, 실제로 실행되는 "`python`"이 어떤 것인지 정확히 알 수 있다는 것입니다. |
|||
|
|||
따라서 현재 올바른 가상 환경에 있는지 확인할 수 있습니다. |
|||
|
|||
/// tip | 팁 |
|||
|
|||
하나의 가상 환경을 활성화한 뒤, 해당 Python을 가진 상태에서 **또 다른 프로젝트**로 이동하는 것은 흔히 발생합니다. |
|||
|
|||
하지만 이때 이전 프로젝트의 가상 환경에 있는 **잘못된 Python 실행 파일**을 사용하게 되어 새 프로젝트가 **정상 작동하지 않을 수 있습니다.** |
|||
|
|||
그래서 현재 어떤 `python`이 사용되고 있는지 확인할 수 있는 능력은 매우 유용합니다. 🤓 |
|||
|
|||
/// |
|||
|
|||
## 가상 환경을 비활성화하는 이유 |
|||
|
|||
예를 들어 `마법사의 돌(philosophers-stone)`이라는 프로젝트에서 작업 중이라고 해보겠습니다. 이때 해당 **가상 환경을 활성화**하고, 필요한 패키지를 설치하며 작업을 진행합니다. |
|||
|
|||
그런데 이제는 **다른 프로젝트**인 `아즈카반의 죄수(prisoner-of-azkaban)`을 작업하고 싶어졌습니다. |
|||
|
|||
그래서 그 프로젝트 디렉터리로 이동합니다: |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ cd ~/code/prisoner-of-azkaban |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
만약 `마법사의 돌(philosophers-stone)`의 가상 환경을 비활성화하지 않았다면, 터미널에서 `python`을 실행할 때 여전히 `마법사의 돌(philosophers-stone)` 가상 환경의 Python을 사용하게 됩니다. |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ cd ~/code/prisoner-of-azkaban |
|||
|
|||
$ python main.py |
|||
|
|||
// sirius를 임포트하는 데 실패했습니다. 설치되어 있지 않아요 😱 |
|||
Traceback (most recent call last): |
|||
File "main.py", line 1, in <module> |
|||
import sirius |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
하지만 `마법사의 돌(philosophers-stone)`의 가상 환경을 비활성화한 다음, `아즈카반의 죄수(prisoner-of-azkaban)` 프로젝트의 가상 환경을 활성화하면, 이제 `python` 명령어는 `아즈카반의 죄수(prisoner-of-azkaban)` 가상 환경의 Python을 사용하게 됩니다. |
|||
|
|||
<div class="termy"> |
|||
|
|||
```console |
|||
$ cd ~/code/prisoner-of-azkaban |
|||
|
|||
// 이전 디렉터리에 있을 필요 없이, 어디서든 가상 환경을 비활성화할 수 있습니다. 다른 프로젝트 디렉터리로 이동한 후에도 괜찮아요 😎 |
|||
$ deactivate |
|||
|
|||
// prisoner-of-azkaban/.venv 가상 환경을 활성화합니다 🚀 |
|||
$ source .venv/bin/activate |
|||
|
|||
// 이제 python을 실행하면, 이 가상 환경에 설치된 sirius 패키지를 찾게 됩니다 ✨ |
|||
$ python main.py |
|||
|
|||
못된 짓을 꾸미고 있음을 엄숙히 맹세합니다.🧙 |
|||
ImportError는 이제 없습니다. 🐺 |
|||
``` |
|||
|
|||
</div> |
|||
|
|||
## 대안들 |
|||
|
|||
이 문서는 여러분이 Python 프로젝트를 시작하고, **그 내부에서** 어떻게 돌아가는지 알려주는 간단한 가이드입니다. |
|||
|
|||
가상 환경, 패키지 의존성(Requirements), 프로젝트를 관리하는 방법에는 이 외에도 다양한 **대안**들이 존재합니다. |
|||
|
|||
만약 준비가 되었다면, **프로젝트 전체**, 패키지 의존성, 가상 환경 등을 통합적으로 **관리**할 수 있는 도구를 써보는 것도 좋습니다. 그럴 때 추천하는 도구가 바로 <a href="https://github.com/astral-sh/uv" class="external-link" target="_blank">uv</a>입니다. |
|||
|
|||
`uv`는 다양한 기능을 지원합니다: |
|||
|
|||
* 다양한 버전의 **Python 설치** |
|||
* 각 프로젝트 별 **가상 환경 관리** |
|||
* **패키지 설치** |
|||
* 프로젝트의 **의존성과 버전** 관리 |
|||
* 설치된 패키지들과 그 버전을 **정확히 고정(lock)**해서,개발 환경과 운영 환경이 완전히 동일하게 작동할 수 있도록 보장 |
|||
* 이 외에도 다양한 기능을 지원 |
|||
|
|||
## 결론 |
|||
|
|||
여기까지 모두 읽고 이해했다면, 이제 많은 개발자들보다 가상 환경을 **훨씬 더 깊이 있게 이해**하게 되셨습니다. 🤓 |
|||
|
|||
이런 세부적인 내용을 알고 있으면, 언젠가 복잡해 보이는 문제를 디버깅할 때 분명히 큰 도움이 될 것입니다. 이제는 **이 모든 것들이 내부에서 어떻게 작동하는지** 알고 있기 때문입니다. 😎 |