Spørsmål og svar

Hvordan finner jeg et Google-prosjekt sin prosjekt-ID?

Prosjekt-ID-en til et Google-prosjekt er en unik identifikator som brukes til å identifisere prosjektet i Google Cloud Platform. Prosjekt-ID-en er en streng som består av små bokstaver, tall og bindestrek. Prosjekt-ID-en er ikke det samme som prosjektnavnet, som kan inneholde store bokstaver og mellomrom.

Du finner prosjekt-ID ved logge deg inn på GCC, åpne prosjektvelgeren, søk opp ditt prosjekt, og så ser du det i høyre kolonne, slik som vist i denne sladdete kolonnen i Figur 1.

Bilde som viser prosjektvelgeren i Google Cloud Console
Figur 1: Prosjektvelgeren i Google Cloud Console

Hvordan får jeg slettet et GitHub-repo under statisticsnorway?

Hovedregelen er at vi arkiverer repoer istedenfor å slette. Det skyldes at vi kan trenge å ettergå historikken i repoer ved et senere tidspunkt. Arkivering av repoer kan du gjøre selv under Settings i repoet.

I de tilfellene der du mener at det gir mest mening å slette repoet, så må dette gjøres av en Github-administrator. Da sender du en henvendelse til Kundeservice og ber om at repoet slettes. Husk å oppgi navnet på repoet du ønsker å få slettet.

Hvordan løser jeg feilmeldinger knyttet til at data rate exceeded i Jupyter?

Når du mottar følgende melding i Jupyter:

Feilmelding:

IOPub data rate exceeded.
The Jupyter server will temporarily stop sending output
to the client in order to avoid crashing it.
To change this limit, set the config variable
`--ServerApp.iopub_data_rate_limit`.

Current values:
ServerApp.iopub_data_rate_limit=1000000.0 (bytes/sec)
ServerApp.rate_limit_window=3.0 (secs)

betyr det at mengden data som sendes fra jupyter-kernelen til jupyterlab-frontend overskrider den tillatte grensen. Selv om det er mulig å justere ServerApp.iopub_data_rate_limit og ServerApp.rate_limit_window for å endre denne grensen, ønsker vi ikke dette. Å endre disse verdiene kan ha en negativ påvirkning på Jupyterlab sin ytelse.

Her er noen løsningsforslag:

  1. Reduser datamengden: Prøv å redusere datamengden du prøver å vise. Hvis du for eksempel viser en stor pandas dataframe, kan du vise kun toppradene med df.head() eller et tilfeldig utvalg med df.sample(10).
  2. Legg til forsinkelse: Bruk time.sleep()-funksjonen i Python for å legge til en pause mellom hver utskrift. Dette kan spre utdataene over en lengre tidsperiode, noe som kan hjelpe med å unngå å overskride datagrensen.
  3. Skriv til en fil: I stedet for å skrive utdata direkte i Jupyter, kan du vurdere å skrive dataene til en fil. Dette omgår IOPub-datahastighetsgrensen, og du kan se gjennom dataene i ettertid.
  4. Unngå utskrift: Hvis du kun trenger å utføre beregninger eller operasjoner på dataene, vurder å gjøre det uten å skrive ut resultatene i Jupyter.

Hvordan kan jeg gjenopprette filer fra bøtter?

Bøttene som opprettes i featuren dapla-buckets1 har en Retention policy som gjør at slettede eller overskrevne objekter kan gjenskapes i en viss periode.

I dapla-buckets blir overskrevne og slettede filer noncurrent. En noncurrent versjon blir slettet hvis den er mer enn 180 dager gammel og det er minst 2+ eller 3+ nyere versjoner i bøtta.2

Alle dapla-teamene har objektversjon aktivert som standard på alle bøtter.

Hvis bøttene ikke er opprettet gjennom featuren dapla-buckets, men kanskje av et ekspertteam eller ekspertteam, så må man først forhøre seg med teamet om versjonering er skrudd på for bøtta. Hvis den ikke er det så blir kun soft-deleted filer tatt vare på i 7 dager.

For å gjennopprette en non-current eller soft-deleted versjon så benytte funksjonalitet fra dapla-toolbelt. For å gjenskape en versjon så må man først bruke funksjonen get_versions() liste ut ID-en til versjonen:

notebook
from dapla import FileClient

# Set bucket name and folder name(if any)
bucket = "ssb-dapla-felles-data-produkt-prod" 
folder = "restore"

FileClient.get_versions(bucket, folder)

Output

[<Blob: ssb-dapla-felles-data-produkt-prod, restore/data1.parquet, 1717762669778835>,
 <Blob: ssb-dapla-felles-data-produkt-prod, restore/data1.parquet, 1718015249969499>,
 <Blob: ssb-dapla-felles-data-produkt-prod, restore/data2.parquet, 1717762673242818>,
 <Blob: ssb-dapla-felles-data-produkt-prod, restore/data3.parquet, 1717762677832930>]

Fra output over ser vi filen data1.parquet finnes i 2 versjoner. Vi kan undersøke den nærmere med følgende kode:

notebook
files = FileClient.get_versions("ssb-dapla-felles-data-produkt-prod", "restore/data1.parquet")

for file in files:
    print("Name          : ",file.name)
    print("Generation Id : ", file.generation)
    print("Updated on    : ", file.updated)
    print("Deleted on    : ", file.time_deleted)
    print("------------------------------------------")

Output

Name          :  restore/data1.parquet
Generation Id :  1718436304922143
Updated on    :  2024-06-15 07:25:04.928000+00:00
Deleted on    :  2024-06-24 11:10:10.807000+00:00
------------------------------------------
Name          :  restore/data1.parquet
Generation Id :  1719227410801992
Updated on    :  2024-06-24 11:10:10.807000+00:00
Deleted on    :  None
------------------------------------------

Av output over ser vi at det er en fil som som har en verdi i Deleted on feltet og som kan gjenskapes. Ønsker vi å gjenskape versjonen ved å bruke restore_version()og referere til Generation ID:

notebook
FileClient.restore_version( source_bucket_name="ssb-dapla-kildomaten-data-delt-test",
                            source_file_name="restore/data3.parquet",
                            source_generation_id=1718436304922143,
                            new_name="" (optional)
                           )

Over har vi gjenopprettet en tidligere versjon av fil. Dette betyr at det nå er en ny Live-versjon av filen, og at den som tidligere var Live har blitt non-current. Ved gjenoppretting av non-current-versjoner så kan man også spesifisere nytt navn på filen med parameteret new_name= i restore_version()-funksjonen.

Man kan liste ut Live, non-current og soft-deleted versjoner fra GCC, som vist i Figur 2. Men man har ikke tilgang til Object details og kan derfor ikke hente ut ID-en til versjonen. Til dette må man benytte dapla-toolbelt fra Dapla Lab.

Bilde av hvordan man velger versjoner i GCC.
Figur 2: Hvordan liste ut versjoner fra GCC.

Hvordan sjekker jeg om Kildomaten er tilgjengelig for mitt team?

Du kan sjekke om teamet ditt har tilgang til Kildomaten ved å gå inn i teamets IaC-repo. Du finner IaC-repoet ved å søke etter team-navnet på statisticsnorway på Github. Repoet er det som heter <teamnavn>-iac. Inne i repoet går du inn filen infra/projects.yaml.

I eksemplet til høyre ser vi hvordan filen ser ut for det fiktive teamet dapla-example. For dette teamet ser vi at Kildomaten er skrudd på i prod-miljøet til teamet, men ikke test-miljøet.

dapla-example-iac/infra/projects.yaml
team_uniform_name: dapla-example

projects:
  - project_name: dapla-example
    env: test
    features:
      - dapla-buckets

  - project_name: dapla-example
    env: prod
    features:
      - dapla-buckets
      - transfer-service
      - kildomaten

Hvordan kan jeg se innholdet i mitt team sine bøtter?

For å se innholdet i ditt teams sine bøtter kan du enten gjøre dette med kode fra Jupyter, eller via Google Cloud Console (GCC). Les mer om hvordan man kan benytte GCC i SSB.

Husk at det er kun data-admins som skal kunne se innhold i kildeprosjektet til teamet. For å gjøre det må de aktivere en tilgang i JIT-applikasjonen.

Atlantis feiler når jeg skrur på en feature. Hva gjør jeg?

Når man skrur på en feature på Dapla, så er det verktøyet Atlantis som ruller ut infrastrukturen på GCP. I mange tilfeller kan det hjelpe å skrive atlantis plan i kommentarfeltet til PR’en, slik at Atlantis får kjørt planen en gang til. Hvis den da ikke viser noen feil, så kan du skrive atlantis apply i kommentarfeltet og endringene vil bli effektuert. Får du fortsatt feilmeldinger etter å ha kjørt atlantis plan på nytt, så bør du kontakte Kundeservice for hjelp.

Jeg får meldingen Account already exists når jeg prøver å logge meg inn på Dapla. Hvordan løser jeg det?

Det hender at man får melding om at Account already exists når man logger seg inn på en Dapla-tjeneste. For å løse dette gjør man følgende:

  1. Velg Add to existing account som vist i Figur 3.
  2. Velg Google slik som vist i Figur 4.

I Figur 4 skal du IKKE fylle inn Username or email og Password. Du skal kun trykke på Google-knappen.

Meldingen om at Account already exists forekommer svært sjelden, og typisk skjer det første gang man logger seg inn på en tjeneste.

Figur 3
Figur 4

Hvorfor viser git status endringer når jeg ikke har endret filene?

Dette kan noen ganger forekomme med notebooks eller ipynb-filer fordi de inneholder metadata som kan bli endret over tid. Siden ipynb-filer er et json-basert format, som inkluderer metadata som oppdaterer seg i bakgrunnen, så kan en endring i strukturen til metadataene føre til endringer i den underliggende json-fila selv om man ikke har gjort endringer i ipynb-fila. Endringene blir deretter plukket opp av git som følger med på endringer i filene.

En mulig løsning er å sjekke inn endringene i kodebasen.

I noen tilfeller viser git status at det har skjedd endringer i filer, men git diff viser ingen endring. I disse tilfellene kan det være ulike problemer i bakgrunnen. Se denne oversikten over problemer og tilhørende løsninger.

Hvordan setter jeg opp 2FA med Authenticator-appen mot GitHub etter at jeg har byttet telefon?

Første gang man begynner å jobbe med kode i SSBs GitHub-organisasjon statisticsnorway, så følger man denne oppskriften fra Dapla-manualen. Men hvis man bytter telefon eller lignende, så må man sette opp dette på nytt.

Prosessen for å bytte 2FA-metode for autentisering er beskrevet i GitHub sin dokumentasjon. Gjør følgende:

  1. Logg deg inn med din bruker på https://github.com/.
  2. Klikk på din profil, øverst til høyre på siden, og velg Settings
  3. I menyen til venstre velger du Password and authentication
  4. Skroll ned til Two-factor-authentication
  5. Under Two-factor-methods vil du se Authenticator app (Configured) hvis du har brukt dette tidligere.
  6. Trykk Edit
  7. Skann QR-koden som dukker opp med Authenticator-appen på din nye mobil.
  8. Følg instruksjonene og lagre autentiseringsmetoden når du er ferdig.

Hvorfor får jeg ikke opprettet mapper fra Google Cloud Console (GCC)?

I mars 2024 ble det gjort sikkerhetstiltak på Dapla som innebar at funksjonaliteten Download, Upload og Create folder i GCC ble skrudd av. Hvis man prøver å opprette en mappe på den måten vil man få en feilemelding som starter med
Request is prohibited by organization's policy. vpcServiceControlsUniqueIdentifier:

Hvis man skal opprette mapper i en bøtte så må man gjøre det med dapla-toolbelt, eller gjøre det fra en tjeneste som Jupyter i Dapla Lab. Sistnevnte metode betyr at man åpner tjenesten som det teamet og tilgangsgruppen som har tilgang til ønsket bøtte, og deretter kan man opprette mapper med mkdir i terminalen.

Hvor finner jeg dokumentasjonen til Dapla Lab tjenester der?

Her finner du Dokumentasjonen for Dapla Lab.

Dokumentasjon for tjenestene finner du i Dapla-manualen under Datatjenester/Dapla Lab tjenester.

Hvorfor får jeg feilmelding i Dapla Lab etter å ha vært borte fra datamaskinen min en stund?

I de fleste tilfeller vil dette løses seg ved at laster inn siden på nytt eller refresher siden.

Grunnen til at det skjer er at Dapla Lab bare er tilgjengelig for de som er logget på SSBs nettverk. Hvis du forlater maskinen med Dapla Lab åpnet i nettleseren over lang tid, så kan det være at du har falt ut av SSBs nettverk og Dapla Lab ikke oppdager at du er logget inn igjen.

Hva betyr det at tjenesten min er suspendert?

Tjenesteikon for Jupyter

At en tjeneste er suspendert betyr at tjenesten er satt på pause. I praksis vil det si at ressursene, f.eks. CPU og RAM, som tjenesten har reservert har blitt frigjort. Man kan starte tjenesten på nytt ved å trykke på Play-knappen i bildet til høyre, og man starter opp tjenesten på nytt med de samme ressursene. Alt som ble lagret i tjenestens lokale filsystem under /home/onyxia/work/blir også gjennopprettet, mens resten blir borte. Derfor bør alltid kode lagres under work-mappen.

Kan jeg jobbe med kildedata fra Dapla Lab?

Ja. Medlemmer av gruppen data-admins kan gi seg selv midlertidig tilgang til kildedata. Dette gjøres ved å bruke Just-in-Time Access (JIT) applikasjonen: https://jitaccess.dapla.ssb.no. Les manual-artikkelen om JIT for en veiledning.

Hvorfor kan jeg ikke jobbe med dataene til alle team jeg er med i fra tjenestene i Dapla Lab?

Mange ansatte i SSB er med i flere Dapla-team, og hvert av brukernes teammedlemskap gir ofte tilgang til data iht til formaålet for teamet. hver av teamene har tilgang til sine data og potensielt andres delt data. For å unngå for brede tilganger til data så innfører vi at en bruker må bestemme seg for hvilket team og tilgangsgruppe de skal representere før de starter arbeid med data i et programmeringsmiljø. Dette gjør at vi kan være sikker på at ingen kan koble data på tvers av team.

Hvordan jobber jeg med notebooks i VS Code?

For å jobbe med notebooks i VS Code kan du gjøre følgende:

  1. Åpne en ny Vscode-python
  2. Åpne en terminal under File/Terminal/New terminal
  3. Opprett et ssb-project som vanlig under mappen /home/onyxia/work/ ved å skrive ssb-project create <prosjektnavn>.
    • Dersom du allerede har et ssb-project, skriver du cd <prosjektnavn> etterfulgt av ssb-project build. Da blir prosjektets tilhørende pakker installert i en kernel med samme navn som prosjektet.
  4. Gå inn i mappen med cd <prosjektnavn>
  5. Installer ønskede pakker poetry add pandas, f.eks. Pandas.
  6. Velg prosjektmappen i filutforskeren ved å gå til File/Open folder/ og åpne prosjektmappen i boksen som vises.
  7. Opprett en notebook-fil og åpne den.
  8. Trykk Refresh på hele nettsiden for å få opp visningen av den nyopprettede kernels.
  9. Øverst til høyre i Notebooken kan du trykke på Select kernel og utforskeren velger du Jupyter kernels og deretter den som har samme navn som prosjektet ditt.
  10. Til slutt kan du teste at riktig Python-installasjon er valgt ved å importere pakken du akkurat installerte.

Du må kjøre en ssb-project build, som beskrevet over, hver gang en instans av Jupyter, eller VSCode blir startet. Hvis du isteden åpner en pauset (suspendert) instans, vil du kunne fortsette arbeidet fra forrige kjøring uten å måtte kjøre ssb-project build.

Hvordan kjører man en Dash-app?

Fra vscode-python tjenesten

Det fungerer best å kjøre Dash-apper i en egen fane i nettleseren. Inline-visning av figurer fungerer ikke enda.

Her er et eksempel på hvordan man lager en Dash-app i DaplaLab i en vscode tjeneste:

  1. Installer pandas og dash i et ssb-project.
  2. Opprett et python-script i prosjektet som f.eks. heter app.py.
  3. Kjør scriptet ved å kjøre følgende kommando fra terminalen: poetry run python ./app.py
  4. Deretter kommer det opp et dialog-vinduet hvor du velger Open in browser.

Her er et eksempel på script som fungerer i Vscode-python:

app.py
from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd

# Creating a sample dataset similar to the Gapminder dataset
data = {
    'country': ['Afghanistan', 'Afghanistan', 'Afghanistan', 'Brazil', 'Brazil', 'Brazil', 'China', 'China', 'China'],
    'continent': ['Asia', 'Asia', 'Asia', 'South America', 'South America', 'South America', 'Asia', 'Asia', 'Asia'],
    'year': [1952, 1977, 2007, 1952, 1977, 2007, 1952, 1977, 2007],
    'lifeExp': [28.801, 39.877, 43.828, 50.917, 59.504, 72.390, 44.000, 63.739, 72.961],
    'pop': [8425333, 12412311, 31889923, 56602560, 80461570, 190010647, 556263527, 862030000, 1318683096],
    'gdpPercap': [779.4453145, 786.11336, 974.5803384, 2108.944355, 5718.766744, 9065.800825, 400.448611, 1488.041713, 4959.114854]
}

# Creating DataFrame
df = pd.DataFrame(data)

# Creating the app
app = Dash(
    __name__,
    requests_pathname_prefix='/proxy/8050/', 
    serve_locally=True
)

app.layout = [
    html.H1(children='Title of Dash App', style={'textAlign':'center'}),
    dcc.Dropdown(df.country.unique(), 'Canada', id='dropdown-selection'),
    dcc.Graph(id='graph-content')
]

@callback(
    Output('graph-content', 'figure'),
    Input('dropdown-selection', 'value')
)
def update_graph(value):
    dff = df[df.country==value]
    return px.line(dff, x='year', y='pop')

if __name__ == '__main__':
    app.run(debug=True)

Fra jupyter tjenesten

Det fungerer best å kjøre Dash-apper i en egen fane i nettleseren, men inline-visning skal også være mulig i notebook.

Her er et eksempel på hvordan man lager en Dash-app i DaplaLab i en jupyter tjeneste:

  1. Installer pandas og dash i et ssb-project.
  2. Opprett en notebook i prosjektet som f.eks. heter app.ipynb.

Her er et eksempel på kode som fungerer i jupyter:

app.ipynb
# %%
# Notebook cell 1
from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd

# %%
# Notebook cell 2
# Creating a sample dataset similar to the Gapminder dataset
data = {
    'country': ['Afghanistan', 'Afghanistan', 'Afghanistan', 'Brazil', 'Brazil', 'Brazil', 'China', 'China', 'China'],
    'continent': ['Asia', 'Asia', 'Asia', 'South America', 'South America', 'South America', 'Asia', 'Asia', 'Asia'],
    'year': [1952, 1977, 2007, 1952, 1977, 2007, 1952, 1977, 2007],
    'lifeExp': [28.801, 39.877, 43.828, 50.917, 59.504, 72.390, 44.000, 63.739, 72.961],
    'pop': [8425333, 12412311, 31889923, 56602560, 80461570, 190010647, 556263527, 862030000, 1318683096],
    'gdpPercap': [779.4453145, 786.11336, 974.5803384, 2108.944355, 5718.766744, 9065.800825, 400.448611, 1488.041713, 4959.114854]
}

# Creating DataFrame
df = pd.DataFrame(data)

# Creating the app
port = 8050 # must be between 1024 and 9999
service_prefix = os.getenv('JUPYTERHUB_SERVICE_PREFIX', '/')
domain = os.getenv('JUPYTERHUB_HTTP_REFERER', None)

app = Dash(
    __name__,
    requests_pathname_prefix=f"{service_prefix}proxy/{port}/", 
    serve_locally=True
)

app.layout = [
    html.H1(children='Title of Dash App', style={'textAlign':'center'}),
    dcc.Dropdown(df.country.unique(), 'Canada', id='dropdown-selection'),
    dcc.Graph(id='graph-content')
]

@callback(
    Output('graph-content', 'figure'),
    Input('dropdown-selection', 'value')
)
def update_graph(value):
    dff = df[df.country==value]
    return px.line(dff, x='year', y='pop')

if __name__ == '__main__':
    # For jupyter_mode, choose between 'external' or 'inline'.
    # 'jupyterlab' should also be poosible, but doesn't seem to work...
    app.run(jupyter_mode="external", jupyter_server_url=domain, port=port)

Hvilke miljøvariabler er tilgjengelig i utviklingstjenestene?

Dette er miljøvariablene som alltid vil være tilgjengelig i Jupyterlab, Rstudio og VSCode:

Miljøvariabel Forklaring
DAPLA_ENVIRONMENT Hvilket dapla-lab miljø du kjører i f.eks PROD, TEST eller DEV
DAPLA_REGION Hvilket dapla miljø du kjører i f.eks. DAPLA_LAB eller BIP
DAPLA_USER Epostaddressen til den innloggede brukeren f.eks. obr@ssb.no
DAPLA_SERVICE Dapla tjenesten som er i bruk f.eks. JUPYTERLAB eller VS_CODE
STAT_TEMPLATE_DEFAULT_REFERENCE Hvilken versjon av ssb-project templatet som skal brukes f.eks. 1.1.8
PSEUDO_SERVICE_URL URL til pseudotjenesten for bruk til testing
STATBANK_BASE_URL URL til statistikkbanken
STATBANK_ENCRYPT_URL URL til ‘statbank-authenticator’ sitt krypteringsendepunkt
STATBANK_TEST_BASE_URL URL til statistikkbanken (i test)
STATBANK_TEST_ENCRYPT_URL URL til ‘statbank-authenticator (i test)’ sitt krypteringsendepunkt

Hvorfor får jeg feilmelding når jeg prøver å slette en delt-bøtte? Jeg får melding om at Error trying to delete bucket objects without ‘force destroy’ set to true når jeg prøver å slette en delt-bøtte ved å fjerne den fra shared-buckets.yaml

En delt-bøtte kan kun slettes hvis den er helt tom for data. Det betyr at:

  • Alle filer og mapper må være slettet.
  • Siden filer versjoneres i delt-bøtter må også alle gamle versjoner av filer også være slettet (såkalt non-current objekter).

Hvis man har prøvd å slette en delt-bøtte ved fjerne bøtten fra shared-buckets.yaml, kjøre atlantis apply og deretter fått feilmeldingen Error trying to delete bucket <bøttenavn> objects without 'force destroy' set to true, så betyr det at det fortsatt ligger data i bøtta. Da kan du gjøre følgende for å få slettet bøtta:

  1. Legg til delt-bøtta i buckets-shared.yaml igjen og kjør atlantis apply etter å ha fått godkjenning.

  2. Kjør følgende Python-script i en tjeneste på Dapla Lab som er startet med teamets developers-gruppe og google-cloud-storage er installert:

Notebook
import google.cloud.storage as storage

client = storage.Client()

for blob in client.list_blobs("FULLT NAVN PÅ DELT-BØTTE", versions=True):
    blob.delete()
  1. Fjern delt-bøtta fra buckets-shared.yaml igjen og kjør atlantis apply etter godkjenning.

Fungerer ikke det så kan man ta kontakt med Kundeservice og få hjelp.

Fotnoter

  1. Featuren dapla-buckets inkluderer produkt- og kildebøtta i henholdsvis standard- og kildeprosjektet som de fleste statistikkproduserende team får ved opprettelse.↩︎

  2. I produktbøtta blir noncurrent versjoner slettet hvis det er mer enn 2 nyere versjoner, mens for kildebøtta er grensen på 3 nyere versjoner↩︎