Slide 1

Slide 1 text

࣮ફStreamlit & Flask Shinichi Nakagawa(@shinyorke) PyCon JP 2021 10/16 AIϓϩδΣΫτͷϓϩτλΠϐϯά͔Βຊ൪ӡ༻·ͰΛ͍͍ײ͡ʹ͢ΔPythonicͳ΍Γ͔ͨ

Slide 2

Slide 2 text

͜ͷ͓࿩͸ • ʮAIͰ͍͍ײ͡ʹͯ͘͠Εʯʮ࠶དྷ݄ʹ͸ϓϩμΫτ͕ཉ͍͠ʯ 
 ͱ͔ݴΘΕͨΒɺ͋ͳͨͳΒͲ͏͠·͔͢?΋ͪΖΜ࢓ࣄͰ. • ͔͠΋ͦͷϓϩμΫτ͕͋Δ೔ಥવTVʹग़ΔʢͦΕ΋શࠃ۠ʣ 
 …ͬͯɺෛՙରࡦͱ͔τϥϒϧ͕ා͍Ͱ͢ΑͶ😇 • ͱ͔͍͏࣮࿩ʹج͖ͮɺࢲʢshinyorkeʣ͕Python࢖͍ͱͯ͠ 
 ͲͷΑ͏ʹPythonicʹղܾ͔ͨ͠?ͱ͍͏ͷ͕͜ͷൃදʹͳΓ·͢

Slide 3

Slide 3 text

͜ͷ࿩ͷείʔϓʢ࿩͢͜ͱ&ର৅ऀʣ • JX௨৴ࣾʮNewsDigestʯͷظؒݶఆίϯςϯπͱͯ͠ग़͍ͯͨ͠ 
 ʮAIϫΫνϯ઀छ༧ଌʯͷ։ൃ͔Βӡ༻ͷ࣮࿩Λݩʹ • Streamlit΍FlaskͳͲΛ࢖ͬͯ೗ԿʹPython࢖͍Β͘͠΍͔ͬͨ?Λ࿩͠·͢ • ͳ͓, طʹAIϫΫνϯ઀छ༧ଌͷαʔϏε͸ऴ͍ྃͯ͠ΔͨΊ, 
 αϯϓϧͱͳΔΑ͏ͳΞϓϦΛ࡞͖ͬͯ·ͨ͠&ͦΕΛݩʹղઆ • WebΞϓϦ։ൃऀ͔ΒσʔλαΠΤϯςΟετ·Ͱָ͓͠Έ͍͚ͨͩ·͢ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ ㅟ

Slide 4

Slide 4 text

Who am I ?ʢ͓લ୭Αʣ • Shinichi Nakagawaʢத઒ ৳Ұʣ • େ఍ͷSNSͰʮshinyorkeʢ͠ΜΑʔ͘ʣʯͱ໊৐͍ͬͯ·͢ • Software Engineer & Data ScientistʢؚΉ⽁ʣ • ݩɾJX௨৴ࣾγχΞΤϯδχΞ 
 ※9݄·Ͱ, 10݄͔Βస৬͠·ͨ͠ • #Python #DataScience #Baseball⚾ #SABRmetrics

Slide 5

Slide 5 text

ࠓ೔ͷ͓౔࢈ • AIϓϩδΣΫτΛ੒ޭͤ͞ΔͨΊʹඞཁͳߟ͑ํͱελϯε • PoCʢ֓೦࣮ূʣͷ͸ͳ͠ - StreamlitͰ͍͍ײ͡ʹ΍Δ • ϓϩμΫτ։ൃ͔Βϩʔϯν, ӡ༻·ͰΛPythonicʹ΍Δ • ͪΐͬͱͨ͠খωλ - ΞΠΩϟονը૾ੜ੒ͱCIपΓ ͜ΕΒΛJX௨৴ࣾ࣌୅ͷ࢓ࣄʢͷެ։৘ใʣ͓Αͼݸਓ։ൃͨ͠಺༰͔Β঺հ

Slide 6

Slide 6 text

ຊ೔࿩͞ͳ͍͜ͱʢ౴͑ͳ͍͜ͱʣ • ݱ৬ͷ࿩ʢͲ͜Ͱಇ͍͍ͯΔɾ࢓ࣄԿͯ͠Δͱ͔ʣ 
 ask the speakerؚΊͯҰ੾࿩͠·ͤΜ🙇ʢḨࡧ΋φγͰʣ • લ৬ʢJX௨৴ࣾʣͷࠓͷ࿩ɾ࠾༻ͷ࿩ɾެ։͞Εͯͳ͍৘ใ 
 JX௨৴ࣾͷࣄ͸εϙϯαʔϒʔεͰதͷਓʹฉ͍ͯʂ 
 ͍͍࿩Λͯ͘͠ΕΔͱࢥ͏ͷͰ👍 • ͦͷଞ, ࢲʢshinyorkeʣ͕ෆద੾ͱ൑அͨ͠಺༰

Slide 7

Slide 7 text

AIϓϩδΣΫτʹඞཁͳελϯε • ෆ࣮֬ͳϓϩδΣΫτ͸Agileͳ΍ΓํͰղܾ͍ͯ͘͠ • σʔλαΠΤϯςΟετͱΤϯδχΞ͸ҧ͏ੜଶܥͷੜ͖෺ 
 νʔϜϫʔΫΛେ੾ʹʂ ͜ͷൃදͰҰ؏͍ͯ͠Δߟ͑ํɾେ੾ʹͯ͠ΔࣄͷએݴͰ͢ 
 ʢҟ࿦͸ೝΊΔʣ

Slide 8

Slide 8 text

ෆ࣮֬ੑͱ޲͖߹͏ͨΊͷAgile • ෆ࣮֬ੑ͕ߴ͍, AIɾػցֶशͳϓϩδΣΫτͦ͜ 
 ʮಈ͘ιϑτ΢ΣΞʯΛݩʹ։ൃ͢ΔΞϓϩʔν͕େࣄ • PoCͱ͸͍͑, ͳΔ΂͘ຊ൪͕ΠϝʔδͰ͖Δಈ͘ 
 ΞϓϦέʔγϣϯͰձ࿩͢Δͷ͕͍͍ͱࢥ͏ʢೝࣝҧ͍ͷ๷ࢭʣ • Ұํ, खΛൈ͚Δॴ͸खΛൈ͖·͘Δ΂͖ʢ㲈࡞Βͳ͍ɾ΍Βͳ͍ʣ 
 υΩϡϝϯτ΍ςετΑΓٞ࿦Ͱ͖ΔΞϓϦ͕ඞཁͳ࣌΋͋Δ

Slide 9

Slide 9 text

ΞδϟΠϧϚχϑΣετͦͷ΋ͷͰ͢ ࢲͨͪ͸ɺιϑτ΢ΣΞ։ൃͷ࣮ફ ͋Δ͍͸࣮ફΛखॿ͚Λ͢Δ׆ಈΛ௨ͯ͡ɺ ΑΓΑ͍։ൃํ๏Λݟ͚ͭͩͦ͏ͱ͍ͯ͠Δɻ ͜ͷ׆ಈΛ௨ͯ͠ɺࢲͨͪ͸ҎԼͷՁ஋ʹࢸͬͨɻ ϓϩηε΍πʔϧΑΓ΋ݸਓͱର࿩Λɺ แׅతͳυΩϡϝϯτΑΓ΋ಈ͘ιϑτ΢ΣΞΛɺ ܖ໿ަবΑΓ΋ސ٬ͱͷڠௐΛɺ ܭըʹै͏͜ͱΑΓ΋มԽ΁ͷରԠΛɺ Ձ஋ͱ͢Δɻ͢ͳΘͪɺࠨهͷ͜ͱ͕ΒʹՁ஋͕͋Δ͜ͱΛ ೝΊͳ͕Β΋ɺࢲͨͪ͸ӈهͷ͜ͱ͕ΒʹΑΓՁ஋Λ͓͘ɻ https://agilemanifesto.org/iso/ja/manifesto.html

Slide 10

Slide 10 text

େࣄʹ͢ΔϙΠϯτ͕ͪΌ͏Μ΍Ͱ, ͱཧղͯ͠΋Β͑Ε͹. https://shinyorke.hatenablog.com/entry/ml-ops-and-engineering ΤϯδχΞͱσʔλαΠΤϯςΟετͷҧ͍

Slide 11

Slide 11 text

ࣗ෼ͳΒͲ͏͢Δ͔🤔ɹ˞࣮ࡍ΍ͬͨ͜ͱ • ΤϯδχΞ΋σʔλαΠΤϯςΟετ΋ 
 ʮͦͷ৔Ͱಈ͘ΞϓϦέʔγϣϯʯΛϕʔεʹձ࿩Λ͢Δ • ࣮ݧίʔυͱϓϩμΫτίʔυͷҠߦΛεϜʔζʹ΍Δ࢓૊Έ • ΤϯδχΞͱσʔλαΠΤϯςΟετ͸ 
 ʮҧ͏ੜଶܥͰੜ͖͍ͯΔϓϩϑΣογϣφϧͰ͋Δʯ 
 ͱೝࣝʢ֮ࣗʣ͠, ૬खΛϦεϖΫτ͢Δʢ͓ؾ࣋ͪͱͯ͠ʣ

Slide 12

Slide 12 text

Python࢖͍͕Pythonicʹ΍Δʹ͸🤔 • PoCɾϓϩτλΠϐϯάͷखஈͱͯ͠ͷStreamlit • ʮͦͷ৔Ͱಈ͘ΞϓϦέʔγϣϯʯΛͬ͞͞ͱखʹೖΕΔ • νʔϜϝΠτͱձ࿩͢Δखஈ΋͍͍ײ͡ʹ͢Δ • PoC͔Βຊ൪ϓϩμΫτ΁ͷڮ౉͠ͱͯ͠ͷPythonͳWeb APIʢࠓճ͸Flaskʣ • ʮ࣮ݧίʔυͱϓϩμΫτίʔυͷҠߦΛεϜʔζʹʯΛલఏʹ։ൃ • ڮ౉͠ʹඞཁͳ޻෉Λఴ͑Δʢύοέʔδߏ੒͓ΑͼςετɾCIͷ४උʣ

Slide 13

Slide 13 text

???ʮ࣮ࡍͲ͏΍ͬͯ΍ΔΜ͡Ό🤔ʯ ͱ͍͏࿩Λ͜Ε͔Β΍Γ·͢

Slide 14

Slide 14 text

PoCʢ֓೦࣮ূʣͷ͸ͳ͠ - StreamlitͰ͍͍ײ͡ʹ΍Δ StreamlitΛ࢖ͬͨϓϩτλΠϐϯάͱਓ΁ͷݟͤํʢັͤํʣ

Slide 15

Slide 15 text

ࠓճͷ͓୊ʮAIΦΦλχαϯຊྥଧ༧ଌʯ ౤खͷϘʔϧʢར͖࿹ɾٿ଎ɾมԽٿʣ͔ΒʮΦΦλχαϯ͕ϗʔϜϥϯΛଧͯΔ͔ʁʯΛ༧ଌ͢Δ, ࡶͳAIαʔϏεͷ։ൃࣄྫΛݩʹ঺հ͠·͢ 
 ※ʲิ଍ʳ͜ͷൃදͷͨΊʹ։ൃͨ͠΋ͷͰ͢&ͿͬͪΌ͚ਫ਼౓͸βϧͰ͢ʢ͓΋ͪΌͰ͢ɺຊؾʹ͠ͳ͍ͰͶʣ

Slide 16

Slide 16 text

ਏ͘ͳ͍Streamlitɹ - ͻͱ·ͣೖ໳͠Α͏ ㅟ ㅟ ㅟ ㅟ • ͻͱ·ͣಈ͔͢ • ͻͱ·ͣݟͤΔʢProxy͢ΔɾΫϥ΢υʹUp͢Δʣ • WebΞϓϦέʔγϣϯͬΆ͘࢓্͛Δ

Slide 17

Slide 17 text

ͻͱ·ͣಈ͔͢ $ pip install streamli t $ streamlit hello • ಋೖ͸ී௨ʹpip installͰ͍͚·͢ • ʮstreamlit helloʯͱ͔ଧͭͱ, αϯϓϧ্ཱ͕͕ͪΔ • ↑ͷαϯϓϧͷίʔυ΋͙͢ಡΊ·͢, ͜ΕͰงғؾ͸௫ΊΔ https://streamlit.io/

Slide 18

Slide 18 text

ͻͱ·ͣݟͤΔ - ϩʔΧϧ؀ڥ͔Β $ ngrok http 8501 • streamlitͷਖ਼ମ͸WebΞϓϦέʔγϣϯͳͷͰ, Կ͔͠ΒͷखஈͰProxyͯ͋͛͠Ε͹ྑ͍ • ࣗ෼ͷϚγϯʢϩʔΧϧʣͰಈ͔͢ͳΒngrok౳ͰProxyͰߦ͚Δ 
 ʢࣾ಺ͷηΩϡϦςΟϧʔϧͱ͔Ͱ໰୊ͳ͚Ε͹ʣ • ײ֮తʹ͸Slack Botͷ։ൃʹ͍ۙʢngrokͰProxyͬͯΑ͘΍ΔͰ͠ΐʣ

Slide 19

Slide 19 text

ϩʔΧϧ͡Όͪΐͬͱ 🤔ͬͯ࣌͸ • ࣗલͷ؀ڥͰ΍Δ • ContainerʢDockerʣ΍Virtual MaschineతͳIaaSʢGCE΍AWS EC2ͳͲʣΛ४උ • ४උͨ͠؀ڥʹσϓϩΠ • StreamlitͷΫϥ΢υαʔϏεΛ࢖͏ • https://streamlit.io/cloud • શੈքʹࡽͯ͠OKͳΒ͜ΕͰ΋ྑ͍͔΋ʢͨͩ͠βతͳαʔϏεͬΆ͍ʣ

Slide 20

Slide 20 text

AIΦΦλχαϯͷdeployϑϩʔ mainϒϥϯνʹpushͨ͠த਎͕Ϗϧυ͞ΕͯCloud Runʹdeploy͞ΕΔ࢓૊Έ ޙͷεϥΠυͰܰ͘ղઆ͠·͢

Slide 21

Slide 21 text

WebΞϓϦέʔγϣϯͱͯ͠࢓্͛Δ • HTMLͰॻ͘Α͏ͳϨϕϧͷUIίϯϙʔωϯτ͸αΫοͱॻ͚·͢ • Form෦඼ఔ౓͸Pythonίʔυ1, 2ߦͰ͍͚Δ • άϥϑ΍ՄࢹԽ͸PythonͰ࢖͍׳ΕͨϥΠϒϥϦ͕ͦͷ··࢖͑·͢ • matplotlib • plotly • etc… • ͋Δఔ౓ͷϖʔδભҠʹ΋ରԠ

Slide 22

Slide 22 text

ʲྫʳαΠυόʔʹFormΛදࣔ͢Δ import streamlit as s t # PITCH_TYPES, THROWS͸DictionaryͰ͢ from interfaces.view.label import PITCH_TYPES, THROW S st.sidebar.markdown ( "" " # ϘʔϧΛܾΊΔ "" " ) # valueΛselectboxͷϥϕϧʹ͍ͨ࣌͠͸lambdaؔ਺ΛڬΉ p_throw = st.sidebar.selectbox ( "ར͖࿹" , THROWS.keys() , format_func=lambda x: THROWS[x ] ) pitch_speed = st.sidebar.slider ( 'ٿ଎ʢkm/hʣ', 70, 170, 150, 5 ) pitch_type = st.sidebar.selectbox ( "ٿछ" , PITCH_TYPES.keys() , format_func=lambda x: PITCH_TYPES[x ] )

Slide 23

Slide 23 text

͜͜·ͰͰ͖Δͱ • νʔϜϝΠτ, Ғ͍ਓͱ͍ͬͨεςʔΫϗϧμʔʹ੒ՌΛ 
 ݟͤΔ͜ͱ͕͍͍ײ͡ʹͰ͖Δ • Jupyter notebook΍ColabͰݟͤΔҎ্ʹΞϓϦͬΆ͍ 
 UIͱಈ͖ͰϓϩτλΠϓΛ։ൃͰ͖Δ • ͜͜·Ͱ͍͚͹, ٞ࿦͠ͳ͕ΒϑΟʔυόοΫ΋Βͬͯ 
 ख௚͠Ͱ͖ΔͰ͠ΐ͏👍

Slide 24

Slide 24 text

ϓϩτλΠϐϯά͔Β։ൃ΁ͷότϯ౉͠ σʔλαΠΤϯςΟετ͕ॻ͍ͨίʔυ͸͍ͣΕΤϯδχΞ͕ղऍ͠ϓϩμΫτίʔυʹͳΔ ͦͷલʹͪΐͬͱͨ͠ʮͻͱ޻෉ʯΛΤϯδχΞͳਓͱҰॹʹ΍ͬͯΈΔͱ͍͍Ͱ͠ΐ͏👍

Slide 25

Slide 25 text

ϓϩτλΠϓͱίʔυΛ͍͍ײ͡ʹ౉͢ • ίʔυΛ෼ׂ͢Δ • ςετΛॻ͘ • ʢՄೳͳΒʣϦϑΝΫλϦϯάΛ͢Δ

Slide 26

Slide 26 text

ίʔυΛ෼ׂ͢Δ • Jupyter notebook΍StreamlitͰॻ͍ͨίʔυΛҙຯ͋Δ୯Ґʹ෼͚Δ • σʔλͷॲཧʢೖग़ྗ, લॲཧʣ • Ϟσϧͷॲཧʢֶशɾ༧ଌʣ • ༧ଌ݁Ռͷ֬ೝɾςετ • ී௨ͷpythonεΫϦϓτͰߏΘͳ͍ʢΦϒδΣΫτࢦ޲͡Όͳ͍͍ͯ͘ʣ 
 ଞͷਓʢίʔυΛ΋Βͬͨਓʣ͕ࣗྗͰಈ͔ͤΔ͜ͱ͕ॏཁ

Slide 27

Slide 27 text

ςετΛॻ͘ • READMEͳςΩετʹՃ͑ͯςετΛॻ͘ɾಈ͔ͤΔΑ͏ʹ͢Δ • ࡞ͬͨϞσϧͷ࢓༷Λ࠷௿ݶ୲อͰ͖Ε͹OK • ඪ४Ϟδϡʔϧͷunittest, αʔυύʔςΟʔͳΒpytest͋ͨΓ 
 Ͱॻ͍ͯಈ͔ͤΔͱྑ͍Ͱ͠ΐ͏ • ϓϩμΫτίʔυʹ͢Δͱ͖, ͏͔ͬΓյ͢ɾಈ͔ͳ͍తͳ 
 ࣄނΛ๷͙ͨΊʹ΋ઈରʹઈରʹ΍ͬͨ΄͏͕͍͍

Slide 28

Slide 28 text

ϦϑΝΫλϦϯάʢ౒ྗ໨ඪʣ • ίʔυ෼ׂͱςετ͕͋Ε͹, ࢓༷Λม͑ͳ͍ʢյ͞ͳ͍ʣ༷, 
 ؾΛ͚ͭͳ͕Β͖Ε͍ͳίʔυʹॻ͖௚͢͜ͱ͕Ͱ͖Δ • ͦ͏, ͍ΘΏΔʮϦϑΝΫλϦϯάʯ͕Ͱ͖Δʂ • ϚετͰ͸ͳ͍͕, ϓϩμΫτίʔυʹ͢Δͱ͖ʹԿ͔͠Β΍Δ 
 ͱࢥΘΕΔͷͰ, ڞಉ࡞ۀͱͯ͜͠ͷλΠϛϯάͰ΍Δͷ͸ΞϦ

Slide 29

Slide 29 text

ʲਤʳϓϩτλΠϓͱϓϩμΫτͷύοέʔδߏ੒ ࠨ͕StreamlitͷϓϩτλΠϓ, ӈ͕ͦͷޙAPIԽͨ͠ϞϊͦΕͧΕͷύοέʔδߏ੒ 
 ׬શʹҰॹ͡Όͳͯ͘΋, ϧʔϧͷҰ؏ੑΛ΋ͨͤΔ͜ͱͰίϛϡχέʔγϣϯ͠΍͘͢ͳΔ͸ͣ

Slide 30

Slide 30 text

ʮίʔυ෼ׂʯʮςετʯͱ͍͏όέπϦϨʔ …͕, ্ख͘ճΔΑ͏ʹ͢ΔͨΊʹ͸?ͱߟ͑ͯίʔυΛॻ͘ͱ͍͍ͱࢥ͏ ಉ͡Python࢖͍ͳΒ͜ͷลͰίϛϡχέʔγϣϯऔΕΔͱࢥ͍·͢͠

Slide 31

Slide 31 text

ϓϩμΫτ։ൃ͔Βϩʔϯν, ӡ༻·ͰΛPythonicʹ΍Δ ϓϩτλΠϓ͔ΒຊϓϩμΫτͷ։ൃ, ͦͯ͠TV๒ʹଧͪউͭ·Ͱ

Slide 32

Slide 32 text

࠷ऴతͳϓϩμΫτ͕͜͏ͳͬͨͱԾఆͯ͠ ϑϩϯτΤϯυͱόοΫΤϯυ͕෼͔ΕΔࠓͲ͖ͷߏ੒Ͱ࡞Γ·͢ʂ͍ͬͯ͏ମͰ ޙ൒ύʔτ͸ʮJSONΛฦ͢RESTfulͳAPIʯͷ෦෼Λத৺ʹ࿩͠·͢ ϑϩϯτΤϯυ όοΫΤϯυ

Slide 33

Slide 33 text

͜͏͍͏ΞʔΩςΫνϟʹͳͬͨͱ͠·͢ Google App EngineͰ͸͡ΊΔ, Β͘Β͘TV๒ରࡦ - AIϫΫνϯ઀छ༧ଌͷ෣୆ཪ https://tech.jxpress.net/entry/vaccine-gae

Slide 34

Slide 34 text

FlaskͰAPIԽ͔ͯ͠ΒͷGCP΁ͷdeploy • ΞʔΩςΫνϟΛߟ͑Δ - GCPͷ͹͍͋ • CloudͰϑϧϚωʔδυͳαʔϏεΛલఏͱͨ͠Flaskͷ࢖͍ํ • GAEͰͷߴෛՙରࡦ

Slide 35

Slide 35 text

ΞʔΩςΫνϟબͼͷࡶͳجຊ • εέʔϦϯάͷཁ݅ • ϦΫΤετ਺ɾτϥϑΟοΫʹ೾͕͋Δ࣌͸App EngineΈ͍ͨͳϑϧϚωʔδυͳαʔϏε͕͍͍ײ͡ • ϦΫΤετ਺͕ൺֱత҆ఆʢ㲈αʔόʔͷ୆਺͕ܾ·ͬͯΔʣͦ͠͏ͳ࣌͸ଞͷཁ݅࣍ୈͰࣗલͰαʔόʔ؅ཧ͍͍͔ͯ͠΋? • ࢖͍͍ͨϥΠϒϥϦɾFramework͕࢖͑Δ؀ڥ͔Ͳ͏͔ • ඪ४తͳϥΠϒϥϦɾFrameworkͰࡁΉ৔߹͸ϑϧϚωʔδυͳΫϥ΢υαʔϏε͕ಘҙͳͷͰͦͬͪʹدͤͨ΄͏͕޾ͤ. • ͨͩ͠, ϑϧϚωʔδυͳΫϥ΢υαʔϏε͸ϥΠϒϥϦɾFrameworkʹ͋Δఔ౓੍໿͕͋ΔͷͰ஫ҙ͕ඞཁ, ಛघͳཁ͕݅͋Δ࣌͸ಛʹ. • ྉۚ💰 • ϑϧϚωʔδυͳαʔϏεͱͦ͏͡Όͳ͍ͷ, Ͳ͕ͬͪඒຯ͍͔͠ݟۃΊΔʢଛӹ෼ذ఺΋ؚΊͯʣ • Ծ૝ϚγϯܥͷαʔϏεͳΒ֬໿ར༻ׂҾʢϦβʔϒυΠϯελϯεͳͲʣΛ࢖͑ΔαʔϏεʹ͢Δ͜ͱ΋ݕ౼

Slide 36

Slide 36 text

Google App EngineʢGAEʣΛ૝ఆͨ͠FlaskΞϓϦ։ൃ AIΦΦλχαϯຊྥଧ༧ଌ͓ΑͼJX௨৴ࣾͷʮAIϫΫνϯ઀छ༧ଌʯ͸GAE + FlaskͰ΍Γ·ͨ͠ 
 ͦͷ࣌ͷצॴΛ঺հ͠·͢

Slide 37

Slide 37 text

ͻͱ·ͣಈ͔͢ - ελϯμʔυ؀ڥฤ • ͸͡ΊͯGAEΛ৮Δʢorٱ͠ͿΓʹ৮Δʣํ͸Google CloudͷΫΠοΫελʔτΛࢀߟʹ΍Δͱ ྑ͍Ͱ͠ΐ͏, ࣸܦͯ͠ਅࣅΔͷ͕ͪΐ͏ͲΑ͍͔΋. • https://cloud.google.com/appengine/docs/standard/python3/quickstart?hl=ja • ্هΛ௨͠Ͱ΍ΔͱFlask੡ͷhello world͕ര஀, ࢓૊Έ΋ཧղͰ͖Δ͸ͣ. • ͋ͱ͸࡞Γ͍ͨϞϊͷ࢓༷ʹ߹ΘͤͯFlaskͷίʔυΛ͍͡Ε͹OK • ྫ͑͹RESTfulʹ͢ΔͳΒResponseΛJSONʹม͑Δͱ͔ • FastAPIͳͲ, ଞͷFWΛ࢖͏࣌͸ͦ͜ʹ߹Θͤͯ࡞Γ௚ͤ͹

Slide 38

Slide 38 text

ϥΠϒϥϦ΁ͷґଘΛݮΒ͢ # AIΦΦλχαϯຊྥଧ༧ଌͷύοέʔδߏ੒ʢΠϝʔδʣ app / !"" entities / !"" interfaces/ # FlaskҎ֎ͷαʔυύʔςΟʔɾϥΠϒϥϦΛimportͯ͠OKͳॴ !"" tests / # !"" dataset / # !"" interfaces / # $"" usecase / !"" usecase / main.py # Flaskʹґଘͯ͠OKͳͱ͜Ζ • αʔυύʔςΟʔͷϥΠϒϥϦɾFramework΁ͷґଘ͸ہॴతʹ͢Δͱྑ͍ • Կ͔ͷ౎߹Ͱ࡞Γม͑Δʢྫ͑͹GAEҎ֎Ͱಈ͔͢ʣΈ͍ͨͳ࣌ʹมߋՕॴ͕গͳͯ͘ࡁΉ • ΫϦʔϯɾΞʔΩςΫνϟͳͲ͕ͦͷΑ͏ͳߟ͑ํͩͬͨΓ͢ΔͷͰਅࣅ͢Δͱ͍͍͔΋͠Εͳ͍

Slide 39

Slide 39 text

ͱͭͥΜͷߴτϥϑΟοΫରࡦ📺 ໌೔TVʹग़·͢ʂʂʂ...ͬͯͳͬͨΒتͼͱෆ͕҆͋Γ·͢ΑͶ ͦ͜ʹରͯ͠Ͳ͏΍ͬͯ΍͍͔ͬͯͬͨ?

Slide 40

Slide 40 text

ݩωλʢJX௨৴ࣾΤϯδχΞϒϩάʣ Google App EngineͰ͸͡ΊΔ, Β͘Β͘TV๒ରࡦ - AIϫΫνϯ઀छ༧ଌͷ෣୆ཪ https://tech.jxpress.net/entry/vaccine-gae

Slide 41

Slide 41 text

ߴෛՙରࡦʢapp.yamlهड़ྫʣ runtime: python3 9 automatic_scaling : max_instances: 33 # ࠷େͷΠϯελϯε਺ʢ͜ΕҎ্૿͑ͳ͍ʣ min_instances: 4 # ࠷খͷΠϯελϯε਺ʢ͜ΕҎ্ݮΒͳ͍ʣ • app.yamlͷΦϓγϣϯΛ͍ͬͯ͡deployͨ͠Β͍͍ײ͡ʹ͍͚·͢ʢ্هͷྫ͸ελϯμʔυ؀ڥʣ • TVʹग़Δ, SNSͰόζΔ౳͕༧૝͞ΕΔ࣌͸ࣄલʹύϥϝʔλΛ͍ͬͯ͡σϓϩΠͯ͠ղܾ 
 ͪͳΈʹ૿͑ͨΠϯελϯε͸app.yamlΛ௚ͯ͠࠶σϓϩΠ or GCPͷίϯιʔϧͰखಈͰফ͢౳ͰରԠͰ͖·͢ • min_instancesΛ0ʹͨ͠ΒʮϦΫΤετ͕͖ͨΒ্ཱͪ͛ΔʯΈ͍ͨͳײ͡ʹ 
 ʢϨεϙϯε͕དྷΔ·Ͱ࣌ؒ͸͔͔Δ͕ྉۚ͸અ໿Ͱ͖Δʣ • max_instancesΛ0ʹͨ͠Βύϥϝʔλ͕ແޮʹͳΓ·͢…͕͓͢͢Ί͸͠·ͤΜ 
 ࣄ্࣮࠷େ஋Λఆٛ͢Δ͜ͱʹͳΔͨΊʢ㲈ͳʹ͔ͷΞΫγσϯτͰΠϯελϯε͕૿͑Δʣ

Slide 42

Slide 42 text

࣮ࡍ΍ͬͯΈͨײ૝ • JX௨৴ࣾ࣌୅ͷ࢓ࣄʮAIϫΫνϯ઀छ༧ଌʯͰ͸, 
 TVͳͲ͍͔ͭ͘ͷཧ༝Ͱߴෛՙ͕༧૝͞ΕΔ࣌ʹapp.yamlΛมߋͯ͠ରԠ • αʔϏεͷ฼ମͱͳΔNewsDigestʢͪ͜Β͸ผͷํ๏Ͱߴෛՙରࡦʣ 
 ؚΊ, αʔϏε͸ͳΜͯ͜ͱແ҆͘ఆՔಇͯͨ͠👍 • App Engineͷ͓͔͛ͰWBS΋News ZERO΋Ί͟·͠ςϨϏͷ 
 ΞΫηε͔Β଱͑, Ϣʔβʔ͞ΜʹମݧΛఏڙͰ͖·ͨ͠ʢײँʣ

Slide 43

Slide 43 text

ʲখᄉʳಈతͳը૾ੜ੒ͱCIपΓ ϓϩτλΠϓ͔ΒຊϓϩμΫτͷ։ൃ, ͦͯ͠TV๒ʹଧͪউͭ·Ͱ

Slide 44

Slide 44 text

αʔόʔαΠυͰαΫοͱը૾Λͭ͘Δ # ࣮ࡍͷίʔυͱ͸ҟͳΓ·͢ʢ͋͘·ͰαϯϓϧͰ͢ʣ import cairosv g def convert_ogp(area: str, age: int, period: str) : # Կ͔͠Βͷํ๏ͰSVGϑΥʔϚοτͳςΩετΛೖख ogp_context = 'TODO: ͜͜ʹSVGͷத਎͕ೖΔ ' # TemporaryFileͱͯ͠ॻ͖ग़ͯ͠ޙbyteͰ΋Β͏ with NamedTemporaryFile('w') as f : f.write(ogp_context ) f.flush( ) image_bytes = svg2png(url=f.name, write_to=None ) return image_byte s image = convert_ogp('౦ژ౎', 40, '10݄Լ०ʙ2্݄०') ↑͜͏͍͏ը૾Λͭ͘Δํ๏ʢαϯϓϧίʔυ→ʣ • σβΠϯΛSVGͰىͯ͜͠cairosvgͰpngʹม׵ 
 SVGΛJinja2ͱ͔ͰςϯϓϨʹͨ͠Βಈతʹߦ͚Δ • ಈ͔͢؀ڥ͸஫ҙ͕ඞཁ. GAEͰϑΥϯτͷΠϯετʔϧ͸Ͱ͖ͳ͍. 
 ͦ͜ͰϋϚͬͨͷͰDockerԽͯ͠Cloud RunͰӡ༻͠·ͨ͠. 
 ৄ͘͠͸, https://tech.jxpress.net/entry/ogp-generator

Slide 45

Slide 45 text

ʲখᄉʳCIपΓ • ϓϩτλΠϓͷஈ֊Ͱʮpushͷ౓ʹςετ࣮ߦʯతͳCI͸༧Ί४උ. • deployλεΫ͸ϓϩμΫτͷϦϦʔεස౓Λݟͯ։ൃɾ౤ೖΛ൑அ. 
 ݸਓతʹ͸ຖ೔ϦϦʔε͕ൃੜ͢Δ༧ஹ͕ݟ͑ͨΒ੔͑Δ༻ʹ͍ͯ͠Δ. • ͜ͷลͷԘക͸ࢥ૝ɾߟ͑ํɾ޷Έ΋͋ΔͷͰask the speaker͋ͨΓͰ 
 ձ࿩͍͔ͨ͠΋, ͦΕͳΓʹτϨʔυΦϑ΋͋Δͱࢥ͏ͷͰ. • ͪͳΈʹࠓճͷAIΦΦλχαϯ͸Github ActionsͰςετ->deploy·Ͱ༻ҙͨ͠

Slide 46

Slide 46 text

AIΦΦλχαϯͷdeployϑϩʔ mainϒϥϯνʹpushͨ͠த਎͕Ϗϧυ͞ΕͯCloud Runʹdeploy͞ΕΔ࢓૊Έ ޙͷεϥΠυͰܰ͘ղઆ͠·͢

Slide 47

Slide 47 text

͜Μͳײ͡ʢงғؾʣ name: C I on: pus h jobs : test : name: tes t runs-on: ubuntu-lates t steps : - uses: actions/checkout@maste r - name: Instal l uses: abatilo/[email protected]. 0 with : python_version: 3.9. 7 poetry_version: 1.1. 7 args: instal l - name: Run pytes t uses: abatilo/[email protected]. 0 with : python_version: 3.9. 7 poetry_version: 1.1. 7 args: run python -m pytest . deploy : name: Deplo y needs: tes t if: github.ref == 'refs/heads/main ' runs-on: ubuntu-lates t steps : - uses: actions/checkout@maste r - name: Deploy a Cloud Run servic e id: deploy-servic e uses: google-github-actions/deploy-cloudrun@mai n with : image: asia.gcr.io/${{ secrets.GCP_PROJECT_ID }}/ohtani-hr-predic t service: ohtani-hr-predic t region: asia-northeast 1 project_id: ${{ secrets.GCP_PROJECT_ID } } credentials: ${{ secrets.GCP_SA_KEY }}

Slide 48

Slide 48 text

݁ͼ

Slide 49

Slide 49 text

ʲ࠶ܝʳAIϓϩδΣΫτʹඞཁͳελϯε • ෆ࣮֬ͳϓϩδΣΫτ͸Agileͳ΍ΓํͰղܾ͍ͯ͘͠ • σʔλαΠΤϯςΟετͱΤϯδχΞ͸ҧ͏ੜଶܥͷੜ͖෺ 
 νʔϜϫʔΫΛେ੾ʹʂ ͜Ε͕େࣄ΍Ͱʂͬͯ࿩Λ࠷ॳʹ͠·ͨ͠

Slide 50

Slide 50 text

ʲֆʳAIϓϩδΣΫτ͕ੈʹग़Δ·Ͱ গͳ͘ͱ΋اը͔Β࠷ॳʹग़Δ·Ͱ͸͜ΜͳϊϦ͔ͳ?

Slide 51

Slide 51 text

͓Θ͔Γ͍͚ͨͩͨͩΖ͏͔? σʔλαΠΤϯςΟετͱΤϯδχΞͷʮؿਫҬʯΛ੍͢Δ΋ͷ͕ ϓϩδΣΫτΛ੍͢Δʢͱࢲ͸৴͍ͯ͡·͢ʣ

Slide 52

Slide 52 text

खஈͱϓϩηε, ྆ํͰAgilityΛߴΊΔ • ࠷ॳ͸ࡶͰ΋͍͍͔Βͬ͞͞ͱಈ͘΋ͷΛ࡞ͬͯݟͤΔ • MVP͔ΒຊϓϩμΫτ΁ͷҠߦ…ͷલʹςετͱϦϑΝΫλϦϯά 
 ͜͜Ͱ͍͍ײ͡ʹͰ͖Δ͔Ͳ͏͔͕͜ͷઌͷAgilityʹӨڹ͢Δ • ϦϦʔε΍ߴෛՙରࡦͳͲ, ܁Γฦ͠΍Δ΋ͷΛCIʹͨ͠Γ࢓૊Έʹ৐͔ͬͬͨΓ 
 ͜Ε͸ΤϯδχΞͳࢹ఺Ͱͷ࿹ͷݟͤͲ͜Ζ💪 • ͜ΕΒΛ͢΂ͯͷϑΣʔζΛҰ؏ͯ͠ಉ͡ݴޠͰ΍ΕΔPython͸, 
 ࠷ॳʹϓϩδΣΫτΛ࢝ΊΔͱ͖ͷखஈͱͯ͠ྑ͍ؾ͕͢Δ. 
 ʢͨͩ͠, ͦͷޙผݴޠͰ࡞Γ௚͢ͳͲͳͲ͸શવ͋Γʣ

Slide 53

Slide 53 text

αΫοͱಈ͘Ϟϊ࡞ͬͯมԽʹରԠ͢Δ ࢲͨͪ͸ɺιϑτ΢ΣΞ։ൃͷ࣮ફ ͋Δ͍͸࣮ફΛखॿ͚Λ͢Δ׆ಈΛ௨ͯ͡ɺ ΑΓΑ͍։ൃํ๏Λݟ͚ͭͩͦ͏ͱ͍ͯ͠Δɻ ͜ͷ׆ಈΛ௨ͯ͠ɺࢲͨͪ͸ҎԼͷՁ஋ʹࢸͬͨɻ ϓϩηε΍πʔϧΑΓ΋ݸਓͱର࿩Λɺ แׅతͳυΩϡϝϯτΑΓ΋ಈ͘ιϑτ΢ΣΞΛɺ ܖ໿ަবΑΓ΋ސ٬ͱͷڠௐΛɺ ܭըʹै͏͜ͱΑΓ΋มԽ΁ͷରԠΛɺ Ձ஋ͱ͢Δɻ͢ͳΘͪɺࠨهͷ͜ͱ͕ΒʹՁ஋͕͋Δ͜ͱΛ ೝΊͳ͕Β΋ɺࢲͨͪ͸ӈهͷ͜ͱ͕ΒʹΑΓՁ஋Λ͓͘ɻ https://agilemanifesto.org/iso/ja/manifesto.html

Slide 54

Slide 54 text

ΤϯδχΞͱσʔλαΠΤϯςΟετͷҧ͍ • ϓϩμΫτΛ։ൃʢӡ༻ʣ͢ΔΤϯδχΞͱ, AIͳ࢓ࣄΛ͢ΔσʔλαΠΤϯςΟετ͸ಘҙෆಘҙ͕ҧ͏ 
 ಉ͡Pythonͱ͍͏ݴޠΛૢ͍ͬͯͯ΋ҧ͏ੜଶܥͰੜ͖͍ͯΔੜ͖෺Ͱ͋Δʢͱࢥ͓ͬͯ͘΂͖ʣ • ྫ͑͹ΤϯδχΞ͸όʔδϣϯ؅ཧɾςετɾCIΛίπίπͱ΍Δʢ΍Δ΂͖ͩʣ͕ 
 σʔλαΠΤϯςΟετ͸Ͱ͖Δਓ΋͍Ε͹Ͱ͖ͳ͍ਓ΋͍Δ 
 ʢͳ͓, ྆ํͰ͖ΔԽ͚෺͸গ਺Ͱ͕͢ଘࡏ͢Δʣ • ྫ͑͹σʔλαΠΤϯςΟετ͸਺ֶɾ਺ࣜʹڧ͍ʢڧ͘ͳ͍ͱ͍͚ͳ͍ʣ 
 ͕, ΤϯδχΞ͸ผʹͦ͜·ͰٻΊΒΕͳ͍ʢͳ͓྆ํͰ͖ΔԽ͚෺͸গ਺͕ͩҎԼུʣ • ͭ·Δͱ͜Ζɺ྆ऀʹٻΊΒΕΔεΩϧηοτɾελϯε͸ڞ௨఺͸͋ΕͲ༏ઌ౓͕શ͘ҟͳΔ 
 ಉ͡PythonΛಡΈॻ͖͢Δʹͯ͠΋ࢲʢ͋ͳͨʣ͕େ੾ʹ͢Δॱং͸͋ͳͨʢࢲʣͱશવҧ͏ͱ৺ಘΔ΂͖

Slide 55

Slide 55 text

ʮ࢓ࣄͰ͸͡ΊΔػցֶश ୈ2൛ʯΛಡΜͰࢥͬͨʮιϑτ΢ΣΞΤϯδχΞͱσʔλαΠΤϯςΟετ, ML Opsʯͷ͜ͱ https://shinyorke.hatenablog.com/entry/ml-ops-and-engineering ʲ࠶ܝʳΤϯδχΞͱσʔλαΠΤϯςΟετͷҧ͍

Slide 56

Slide 56 text

৭ʑ࿩͠·͕ͨ͠ ݁ہԿ͕ݴ͍͍͔ͨͱ͍͏ͱ

Slide 57

Slide 57 text

ʮ͍͍͔Μ͡ʹ͢ΔPythonicͳ΍Γ͔ͨʯ 
 is ʮαΫοͱಈ͘΋ͷΛ࡞ͬͯ΍ͬͯ͜💪ʯ ΨϯΨϯͱσϦόϦʔ͍ͯ͜͠͏ʂ

Slide 58

Slide 58 text

ँࣙ • JX௨৴ࣾͰ৭ʑ΍Βͤͯ΋Βͬͨܦݧ͕ࠓճͷൃදʹ׆͖ͨ • ௅ઓͱֶͼͷػձΛ͘ΕͨJX௨৴ࣾʹ͸ϗϯτʹຊ౰ʹ͓ੈ࿩ʹͳΓ·ͨ͠🙇 • ςοΫϒϩά https://tech.jxpress.net/ Έͯ΍͍ͬͯͩ͘͞📝 
 ͋ͱ, εϙϯαʔϒʔε΋ͥͻ༡ͼʹߦͬͯ΋Β͑Δͱ👍 • ͳ͓ຊ೔16:20͔ΒαʔόʔαΠυΤϯδχΞ @TatchNicolas ͕ 
 ʮLocust࣮ફฤʯͱ͍͏τʔΫ͢ΔͷͰؾʹͳΔํ͸νΣοΫΛʂ

Slide 59

Slide 59 text

ήʔϜηοτ⚾ ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠. Shinichi Nakagawa(Twitter/Facebook/etc… @shinyorke)

Slide 60

Slide 60 text

ʲAppendixʳࢀߟจݙɾϒϩά • JX௨৴ࣾΤϯδχΞϒϩά • https://tech.jxpress.net/entry/data-app-for-streamlit • https://tech.jxpress.net/entry/vaccine-gae • https://tech.jxpress.net/entry/ogp-generator • Lean Baseball • https://shinyorke.hatenablog.com/entry/ fl ask-and-gae-and-github-actions • https://shinyorke.hatenablog.com/entry/engineer-and-datascientist • https://shinyorke.hatenablog.com/entry/jupyter-to-streamlit • Agile Manifest • https://agilemanifesto.org/iso/ja/manifesto.html • ࢓ࣄͰ͸͡ΊΔػցֶश ୈ2൛ • https://www.oreilly.co.jp/books/9784873119472/