maxachis commited on
Commit
0caea66
·
1 Parent(s): 1823c7c

Set up html processing logic

Browse files
.env ADDED
@@ -0,0 +1 @@
 
 
1
+ MODEL_PATH="models/logistic_regression_bag_of_words/2025-07-08_19-34-16"
.python-version CHANGED
@@ -1 +1 @@
1
- 3.13
 
1
+ 3.11
handler.py CHANGED
@@ -5,8 +5,12 @@ from environs import Env
5
  from huggingface_hub import hf_hub_download
6
  from joblib import load
7
 
8
- SPACY_MODEL = spacy.load('en_core_web_trf', disable=['parser']) # Largest, slowest, most accurate model
 
 
 
9
 
 
10
 
11
 
12
  class EndpointHandler:
@@ -20,9 +24,14 @@ class EndpointHandler:
20
  subfolder=model_path,
21
  filename="model.joblib"
22
  )
23
- self.model = load(downloaded_model_path)
 
 
 
24
 
25
  def __call__(self, inputs: Dict[str, Any]) -> Dict[str, str]:
26
- # Expecting input like: {"inputs": "<html>...</html>"}
27
  html = inputs["inputs"]
28
- return {"label": str(self.model)}
 
 
 
 
5
  from huggingface_hub import hf_hub_download
6
  from joblib import load
7
 
8
+ from src.models.bag_of_words.model import BagOfWordsModelContainer
9
+ from src.extract.core import BagOfWordsExtractor
10
+ from src.format.core import BagOfWordsFormatter
11
+ from src.predict.core import RelevancePredictor
12
 
13
+ SPACY_MODEL = spacy.load('en_core_web_trf', disable=['parser']) # Largest, slowest, most accurate model
14
 
15
 
16
  class EndpointHandler:
 
24
  subfolder=model_path,
25
  filename="model.joblib"
26
  )
27
+ self.model_container: BagOfWordsModelContainer = load(downloaded_model_path)
28
+ self.extractor = BagOfWordsExtractor(self.model_container.permitted_terms)
29
+ self.formatter = BagOfWordsFormatter(self.model_container.term_label_encoder)
30
+ self.predictor = RelevancePredictor(self.model_container.model)
31
 
32
  def __call__(self, inputs: Dict[str, Any]) -> Dict[str, str]:
 
33
  html = inputs["inputs"]
34
+ bag_of_words = self.extractor.extract_bag_of_words(html)
35
+ csr = self.formatter.format_bag_of_words(bag_of_words)
36
+ output = self.predictor.predict_relevance(csr)
37
+ return output.model_dump(mode="json")
import.py DELETED
@@ -1,25 +0,0 @@
1
- from pathlib import Path
2
-
3
- from types import FitPredictor
4
-
5
-
6
- def find_repo_root(start_path: Path = Path.cwd()) -> Path:
7
- """Finds the root of the repo by locating the nearest pyproject.toml."""
8
- current = start_path.resolve()
9
- for parent in [current] + list(current.parents):
10
- if (parent / "pyproject.toml").is_file():
11
- return parent
12
- raise FileNotFoundError("No pyproject.toml found in any parent directories.")
13
-
14
-
15
- def get_single_file(path: Path) -> Path:
16
- files = [f for f in path.iterdir() if f.is_file()]
17
- if len(files) != 1:
18
- raise ValueError(f"Expected exactly one file in {path}, found {len(files)}")
19
- return files[0]
20
-
21
- def load_model() -> FitPredictor:
22
- repo_root = find_repo_root()
23
- model_path = get_single_file(repo_root / "model")
24
- raise NotImplementedError
25
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pyproject.toml CHANGED
@@ -3,11 +3,21 @@ name = "inference-prototype-test"
3
  version = "0.1.0"
4
  description = "Add your description here"
5
  readme = "README.md"
6
- requires-python = ">=3.13"
7
  dependencies = [
 
8
  "environs>=14.2.0",
9
  "huggingface-hub>=0.33.2",
 
 
 
 
10
  "scikit-learn>=1.7.0",
11
  "spacy>=3.8.7",
12
  "spacy-huggingface-hub>=0.0.10",
13
  ]
 
 
 
 
 
 
3
  version = "0.1.0"
4
  description = "Add your description here"
5
  readme = "README.md"
6
+ requires-python = ">=3.11"
7
  dependencies = [
8
+ "beautifulsoup4>=4.13.4",
9
  "environs>=14.2.0",
10
  "huggingface-hub>=0.33.2",
11
+ "lxml>=6.0.0",
12
+ "pip>=25.1.1",
13
+ "polars>=1.31.0",
14
+ "pydantic>=2.11.7",
15
  "scikit-learn>=1.7.0",
16
  "spacy>=3.8.7",
17
  "spacy-huggingface-hub>=0.0.10",
18
  ]
19
+
20
+ [dependency-groups]
21
+ dev = [
22
+ "pytest>=8.4.1",
23
+ ]
requirements.txt CHANGED
Binary files a/requirements.txt and b/requirements.txt differ
 
src/extract/README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ Directory for extracting data from raw HTML files
src/extract/__init__.py ADDED
File without changes
src/extract/core.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from bs4 import BeautifulSoup
3
+ import spacy
4
+ import polars as pl
5
+
6
+ class BagOfWordsExtractor:
7
+
8
+ def __init__(
9
+ self,
10
+ permitted_words: list[str],
11
+ ):
12
+ self.nlp = spacy.load('en_core_web_trf', disable=['parser']) # Largest, slowest, most accurate model
13
+ self.permitted_words = permitted_words
14
+
15
+ def extract_bag_of_words(self, html: str) -> dict[str, int]:
16
+ soup = BeautifulSoup(html, "lxml")
17
+ text = soup.get_text(separator=' ', strip=True)
18
+ spacy_doc = self.nlp(text)
19
+ bag_of_words = {word: 0 for word in self.permitted_words}
20
+ for token in spacy_doc:
21
+ if token.is_stop:
22
+ continue
23
+ if not token.is_alpha:
24
+ continue
25
+ if len(token.text) < 2:
26
+ continue
27
+ text = token.lemma_.lower()
28
+ if text not in self.permitted_words:
29
+ continue
30
+ bag_of_words[text] = 1
31
+ return bag_of_words
32
+
33
+ def format_bag_of_words(
34
+ self,
35
+ bag_of_words: dict[str, int]
36
+ ) -> pl.DataFrame:
37
+ raise NotImplementedError
38
+
39
+
src/format/__init__.py ADDED
File without changes
src/format/core.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from scipy.sparse import csr_matrix
3
+ from sklearn.preprocessing import LabelEncoder
4
+ import polars as pl
5
+
6
+ class BagOfWordsFormatter:
7
+ def __init__(
8
+ self,
9
+ term_encoder: LabelEncoder
10
+ ):
11
+ self.term_encoder = term_encoder
12
+
13
+ def _convert_to_polars(self, bag_of_words: dict[str, int]) -> pl.DataFrame:
14
+ return pl.DataFrame(
15
+ {
16
+ "term": list(bag_of_words.keys()),
17
+ "exists": list(bag_of_words.values())
18
+ }
19
+ )
20
+
21
+ def _apply_label_encoder(self, df: pl.DataFrame) -> pl.DataFrame:
22
+ term_indices = pl.Series(
23
+ name="term_idx",
24
+ values=self.term_encoder.transform(df["term"].to_numpy())
25
+ )
26
+ # Return new dataframe with exists and term_idx columns
27
+ return df.with_columns(term_indices)
28
+
29
+ def _convert_to_sparse_matrix(self, df: pl.DataFrame) -> csr_matrix:
30
+ row_indices = np.zeros(len(df), dtype=int) # all zero, since it's row 0
31
+ col_indices = df["term_idx"].to_numpy()
32
+ data = df["exists"].to_numpy()
33
+
34
+ return csr_matrix(
35
+ (data, (row_indices, col_indices)),
36
+ shape=(1, len(self.term_encoder.classes_))
37
+ )
38
+ def format_bag_of_words(
39
+ self,
40
+ bag_of_words: dict[str, int]
41
+ ) -> csr_matrix:
42
+
43
+ df = self._convert_to_polars(bag_of_words)
44
+ df = self._apply_label_encoder(df)
45
+ return self._convert_to_sparse_matrix(df)
src/models/__init__.py ADDED
File without changes
src/models/bag_of_words/__init__.py ADDED
File without changes
src/models/bag_of_words/model.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+ from sklearn.linear_model import LogisticRegression
3
+ from sklearn.preprocessing import LabelEncoder
4
+
5
+
6
+ class BagOfWordsModelContainer(BaseModel):
7
+ class Config:
8
+ arbitrary_types_allowed = True
9
+
10
+ model: LogisticRegression
11
+ term_label_encoder: LabelEncoder
12
+ permitted_terms: list[str]
src/predict/__init__.py ADDED
File without changes
src/predict/core.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from scipy.sparse import csr_matrix
2
+
3
+ from src.predict.output import PredictionOutput
4
+ from types_ import FitPredictor
5
+
6
+
7
+ class RelevancePredictor:
8
+
9
+ def __init__(
10
+ self,
11
+ model: FitPredictor
12
+ ):
13
+ self.model = model
14
+
15
+ def predict_relevance(self, csr: csr_matrix) -> PredictionOutput:
16
+ y_pred = self.model.predict(csr)
17
+ probability_estimates = self.model.predict_proba(csr)[:, 1]
18
+ return PredictionOutput(
19
+ is_relevant=y_pred[0] == 1,
20
+ probability=probability_estimates[0]
21
+ )
src/predict/output.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+
3
+
4
+ class PredictionOutput(BaseModel):
5
+ is_relevant: bool
6
+ probability: float
tests/__init__.py ADDED
File without changes
tests/data/test.html ADDED
@@ -0,0 +1,1192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+
4
+ <!DOCTYPE html>
5
+ <html class="no-js" lang="en" itemscope itemtype="https://schema.org/Product">
6
+ <head>
7
+ <meta charset="utf-8" />
8
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
9
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
10
+ <meta name="robots" content="noindex, nofollow" />
11
+ <meta property="og:image" content="/contentassets/cecbb0b8ce784604a3d81b786aeb7d8e/longbeachfacebook200.jpg" />
12
+
13
+ <title>City of Long Beach</title>
14
+
15
+ <link rel="shortcut icon" href="/favicon.png" type="image/x-icon" />
16
+ <script type="text/javascript" src="//www.trumba.com/scripts/spuds.js"></script>
17
+ <script>
18
+ var $buoop = { vs: { i: 10, f: 25, o: 12.1, s: 6 }, c: 2, reminder: 0 };
19
+ function $buo_f() {
20
+ var e = document.createElement("script");
21
+ e.src = "//browser-update.org/update.min.js";
22
+ e.async = true;
23
+ document.body.appendChild(e);
24
+ };
25
+ try { document.addEventListener("DOMContentLoaded", $buo_f, false) }
26
+ catch (e) { window.attachEvent("onload", $buo_f) }
27
+ </script>
28
+
29
+ <!-- Main Responsive & Mobile Framework -->
30
+ <!--[if (!IE)|(gt IE 8)]><!-->
31
+ <script src="/common/js/jquery.min.js"></script>
32
+ <!--<![endif]-->
33
+ <script src="/common/js/bootstrap.min.js"></script>
34
+ <link rel="stylesheet" type="text/css" href="/common/css/bootstrap.min.css" media="screen" />
35
+
36
+ <!-- Main Navigation Styles & Functionality -->
37
+ <link rel="stylesheet" type="text/css" href="/common/css/wayoutmenu.css" />
38
+ <!-- Customized -->
39
+ <link rel="stylesheet" type="text/css" href="/common/css/wayoutmenuboxed.css" />
40
+ <link rel="stylesheet" type="text/css" href="/common/css/wayoutmenueffects.css" />
41
+ <link rel="stylesheet" type="text/css" href="/common/css/wayoutmenustyle.css" />
42
+ <link rel="stylesheet" type="text/css" href="/common/css/wayoutmenuresponsive.css" />
43
+ <!-- Customized -->
44
+ <script src="/common/js/wayoutmenu.boxed.js"></script>
45
+ <!--[if lt IE 10]>
46
+ <script type="text/javascript">
47
+ $(document).ready(function() {
48
+ $('.hidden-menu').css('display','none')
49
+ });
50
+ </script>
51
+ <![endif]-->
52
+ <!-- Main Site Styles and Functionality -->
53
+ <link rel="stylesheet" type="text/css" href="/common/css/style.css">
54
+ <link rel="stylesheet" type="text/css" href="/common/css/interior.css">
55
+ <link href='https://fonts.googleapis.com/css?family=Raleway:200,300,400,500,600,700' rel='stylesheet' type='text/css'>
56
+ <link href='https://fonts.googleapis.com/css?family=Open+Sans:400,600,700' rel='stylesheet' type='text/css'>
57
+
58
+ <link rel="stylesheet" type="text/css" href="/common/css/print.css">
59
+ <!-- Hovers For Desktop Only (removed for all other devices) -->
60
+ <link rel="stylesheet" type="text/css" href="/common/css/desktop-hovers.css">
61
+
62
+ <!--[if lte IE 8]>
63
+ <link rel="stylesheet" type="text/css" href="/common/css/ie8-column-support.css" />
64
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" async></script>
65
+ <script type="text/javascript">
66
+ $('html').addClass('ie8') // used in easyresponsivetabs.js
67
+ </script>
68
+ <![endif]-->
69
+ <meta name="google-site-verification" content="b9cY4UhbLwI_5MH_jBbhLaQ8KpA2g14lyxBgLVo-T30" />
70
+ <meta name="google-translate-customization" content="d2cbd2840da8c7aa-8ea378d4ca2a8e55-g7034799490fa3805-11" />
71
+
72
+
73
+
74
+ <!-- Google Tag Manager -->
75
+ <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
76
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
77
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
78
+ 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
79
+ })(window,document,'script','dataLayer','GTM-T3CM3WC');</script>
80
+ <!-- End Google Tag Manager -->
81
+
82
+
83
+
84
+
85
+
86
+
87
+ </head>
88
+ <body style="background-image: url('/globalassets/pages/interior_bg.jpg');">
89
+
90
+
91
+ <div>
92
+ <script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5568e42a7bfaf196" async></script>
93
+
94
+ <div id="main-container" class="container-fluid relative overflow-hidden full-height">
95
+ <div class="wrapper relative full-height">
96
+ <!-- ST-CONTENT -->
97
+ <div class="st-content relative full-height">
98
+ <!-- ST-CONTENT-INNER -->
99
+ <div class="st-content-inner relative">
100
+ <!-- MAIN -->
101
+ <div class="main" style="position: relative">
102
+ <!-- MENU-BG -->
103
+ <div class="container-fluid menu-bg-boxed">
104
+ <!-- BM-CONTAINER -->
105
+ <div class="row-fluid site-width-boxed bm-container">
106
+ <div class="font-language">
107
+ <div class="row">
108
+ <!-- Start Google Translate Code -->
109
+ <div id="google_translate_element"></div>
110
+ <script type="text/javascript">
111
+ function googleTranslateElementInit() {
112
+ new google.translate.TranslateElement({ pageLanguage: 'en', includedLanguages: 'es,km,tl', layout: google.translate.TranslateElement.InlineLayout.SIMPLE, autoDisplay: false }, 'google_translate_element');
113
+ }
114
+ </script>
115
+ <script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit" async></script>
116
+ <!-- /End Google Translate Code -->
117
+
118
+
119
+ <div class="font-size-selector">
120
+ <div class="btn-group">
121
+ <button class="btn btn-default btn-xs dropdown-toggle" type="button" data-toggle="dropdown" aria-expanded="false">
122
+ <!-- <span class="caret"></span>-->
123
+ </button>
124
+ <ul id="text-resizer" class="dropdown-menu" role="menu">
125
+ <li><a href="#" name="rvfs-5">Extra Large</a></li>
126
+ <li><a href="#" name="rvfs-4">Large</a></li>
127
+ <li><a href="#" name="rvfs-3">Normal</a></li>
128
+ <li><a href="#" name="rvfs-2">Small</a></li>
129
+ </ul>
130
+ </div>
131
+ </div>
132
+ </div>
133
+ </div>
134
+ <div class="shadow"></div>
135
+ <div class="slidemenu-toggler">
136
+ <button id="main-mobile-toggle" class="side-menu-toggle">MENU</button>
137
+ <div class="search">
138
+ <a href="#" class="mobile-search-toggle"></a>
139
+ <input type="text" id="txtSearch" placeholder="SEARCH YOUR CITY" /><input type="button" value="Search" id="btnSearch" />
140
+ </div>
141
+ </div>
142
+
143
+ <script type="text/javascript">
144
+ <!--
145
+ $(document).ready(function () {
146
+ $('.official-details').first().addClass('active').show();
147
+
148
+ $('a.official-hover').hover(function () {
149
+ var id = $(this).attr('rel');
150
+ var $elem = $('#official-info-' + id)
151
+ if ($elem.hasClass('active')) {
152
+ return false;
153
+ } else {
154
+ $('.official-details.active').removeClass('active');
155
+ $('.official-details').css("z-index", "1").fadeOut(100);
156
+ $('#official-info-' + id).css("z-index", "2").addClass('active').delay(100).fadeIn(100);
157
+ }
158
+ });
159
+ $('.top-nav .fw').last().addClass('lastItem');
160
+ });
161
+
162
+ //-->
163
+ </script>
164
+
165
+
166
+ <!-- Wayout Menu - TOP NAV -->
167
+ <div id="top-nav" class="top-nav hidden-phone">
168
+ <ul class="content-container">
169
+ <li class="branding">
170
+ <a href="/">
171
+ <img src="/globalassets/logo-small-city-long-beach.png">
172
+ </a>
173
+ </li>
174
+ <!-- Menu Item and Mega Menu (layout 1) -->
175
+ <li class="top-nav-mega fw"><a href="/officials/" title="City Officials" class="">City Officials</a></li>
176
+
177
+ <div class="top-nav-mega-full-width city-officials">
178
+ <div class="row-fluid">
179
+ <div id="ctl00_ucNav_rNavMenu_ctl00_pCityOfficals">
180
+ <div class="col-md-5">
181
+ <h3>Mayor</h3>
182
+ <ul>
183
+ <li><a href="/mayor/" title="Rex Richardson" rel="66" class="official-hover">Rex Richardson</a></li>
184
+ </ul>
185
+ <h3>City Council</h3>
186
+ <ul>
187
+ <li><a href="/district1/" title="Mary Zendejas" rel="67" class="official-hover">Mary Zendejas</a><span>1st District</span></li>
188
+ <li><a href="/district2/" title="Cindy Allen" rel="68" class="official-hover">Cindy Allen</a><span>2nd District</span></li>
189
+ <li><a href="/district3/" title="Kristina Duggan" rel="69" class="official-hover">Kristina Duggan</a><span>3rd District</span></li>
190
+ <li><a href="/district4/" title="Daryl Supernaw" rel="70" class="official-hover">Daryl Supernaw</a><span>4th District</span></li>
191
+ <li><a href="/district5/" title="Megan Kerr" rel="71" class="official-hover">Megan Kerr</a><span>5th District</span></li>
192
+ <li><a href="/district6/" title="Suely Saro" rel="72" class="official-hover">Suely Saro</a><span>6th District</span></li>
193
+ <li><a href="/district7/" title="Roberto Uranga" rel="73" class="official-hover">Roberto Uranga</a><span>7th District</span></li>
194
+ <li><a href="/district8/" title="Tunua Thrash-Ntuk" rel="74" class="official-hover">Tunua Thrash-Ntuk</a><span>8th District</span></li>
195
+ <li><a href="/district9/" title="Dr. Joni Ricks-Oddie" rel="75" class="official-hover">Dr. Joni Ricks-Oddie</a><span>9th District</span></li>
196
+ </ul>
197
+ </div>
198
+ <div class="col-md-3">
199
+ <div class="official-details" id="official-info-66" style="display: none;">
200
+ <div class="official-title">
201
+ <h3>Rex Richardson</h3>
202
+ <h4></h4>
203
+ </div>
204
+ <img src="/globalassets/officials/media-library/images/mayorrichardson185x200.jpg">
205
+ <div class="official-contact">
206
+ <a href="tel:562-570-6801">562-570-6801</a>
207
+ <a href="mailto:mayor@longbeach.gov">Send Email</a>
208
+ </div>
209
+ </div>
210
+
211
+ <div class="official-details" id="official-info-67" style="display: none;">
212
+ <div class="official-title">
213
+ <h3>Mary Zendejas</h3>
214
+ <h4>1st District</h4>
215
+ </div>
216
+ <img src="/globalassets/officials/media-library/images/maryzendejas185x200.jpg">
217
+ <div class="official-contact">
218
+ <a href="tel:562-570-6919">562-570-6919</a>
219
+ <a href="mailto:district1@longbeach.gov">Send Email</a>
220
+ </div>
221
+ </div>
222
+ <div class="official-details" id="official-info-68" style="display: none;">
223
+ <div class="official-title">
224
+ <h3>Cindy Allen</h3>
225
+ <h4>2nd District</h4>
226
+ </div>
227
+ <img src="/globalassets/officials/media-library/images/allen185x200.jpg">
228
+ <div class="official-contact">
229
+ <a href="tel:562-570-2222">562-570-2222</a>
230
+ <a href="mailto:district2@longbeach.gov">Send Email</a>
231
+ </div>
232
+ </div>
233
+ <div class="official-details" id="official-info-69" style="display: none;">
234
+ <div class="official-title">
235
+ <h3>Kristina Duggan</h3>
236
+ <h4>3rd District</h4>
237
+ </div>
238
+ <img src="/globalassets/officials/media-library/images/duggan_185x200.jpg">
239
+ <div class="official-contact">
240
+ <a href="tel:562-570-6300">562-570-6300</a>
241
+ <a href="mailto:district3@longbeach.gov">Send Email</a>
242
+ </div>
243
+ </div>
244
+ <div class="official-details" id="official-info-70" style="display: none;">
245
+ <div class="official-title">
246
+ <h3>Daryl Supernaw</h3>
247
+ <h4>4th District</h4>
248
+ </div>
249
+ <img src="/globalassets/officials/media-library/images/supernaw185x200.jpg">
250
+ <div class="official-contact">
251
+ <a href="tel:562-570-4444">562-570-4444</a>
252
+ <a href="mailto:district4@longbeach.gov">Send Email</a>
253
+ </div>
254
+ </div>
255
+ <div class="official-details" id="official-info-71" style="display: none;">
256
+ <div class="official-title">
257
+ <h3>Megan Kerr</h3>
258
+ <h4>5th District</h4>
259
+ </div>
260
+ <img src="/globalassets/officials/media-library/images/kerr185x200.jpg">
261
+ <div class="official-contact">
262
+ <a href="tel:562-570-5555">562-570-5555</a>
263
+ <a href="mailto:district5@longbeach.gov">Send Email</a>
264
+ </div>
265
+ </div>
266
+ <div class="official-details" id="official-info-72" style="display: none;">
267
+ <div class="official-title">
268
+ <h3>Suely Saro</h3>
269
+ <h4>6th District</h4>
270
+ </div>
271
+ <img src="/globalassets/officials/media-library/images/saro185x200.jpg">
272
+ <div class="official-contact">
273
+ <a href="tel:562-570-6816">562-570-6816</a>
274
+ <a href="mailto:district6@longbeach.gov">Send Email</a>
275
+ </div>
276
+ </div>
277
+ <div class="official-details" id="official-info-73" style="display: none;">
278
+ <div class="official-title">
279
+ <h3>Roberto Uranga</h3>
280
+ <h4>7th District</h4>
281
+ </div>
282
+ <img src="/globalassets/officials/media-library/images/uranga-2025.jpg">
283
+ <div class="official-contact">
284
+ <a href="tel:562-570-7777">562-570-7777</a>
285
+ <a href="mailto:district7@longbeach.gov">Send Email</a>
286
+ </div>
287
+ </div>
288
+ <div class="official-details" id="official-info-74" style="display: none;">
289
+ <div class="official-title">
290
+ <h3>Tunua Thrash-Ntuk</h3>
291
+ <h4>8th District</h4>
292
+ </div>
293
+ <img src="/globalassets/officials/media-library/images/tunua185x200.jpg">
294
+ <div class="official-contact">
295
+ <a href="tel:562-570-6685">562-570-6685</a>
296
+ <a href="mailto:district8@longbeach.gov">Send Email</a>
297
+ </div>
298
+ </div>
299
+ <div class="official-details" id="official-info-75" style="display: none;">
300
+ <div class="official-title">
301
+ <h3>Dr. Joni Ricks-Oddie</h3>
302
+ <h4>9th District</h4>
303
+ </div>
304
+ <img src="/globalassets/officials/media-library/images/ricks-oddie185x200.jpg">
305
+ <div class="official-contact">
306
+ <a href="tel:562-570-6137">562-570-6137</a>
307
+ <a href="mailto:district9@longbeach.gov">Send Email</a>
308
+ </div>
309
+ </div>
310
+ <div class="official-details" id="official-info-76" style="display: none;">
311
+ <div class="official-title">
312
+ <h3>Dawn McIntosh</h3>
313
+ <h4>City Attorney</h4>
314
+ </div>
315
+ <img src="/globalassets/officials/media-library/images/mcintosh185x200.jpg">
316
+ <div class="official-contact">
317
+ <a href="tel:562-570-2200">562-570-2200</a>
318
+ <a href="mailto:cityattorney@longbeach.gov">Send Email</a>
319
+ </div>
320
+ </div>
321
+ <div class="official-details" id="official-info-77" style="display: none;">
322
+ <div class="official-title">
323
+ <h3>Laura L. Doud</h3>
324
+ <h4>City Auditor</h4>
325
+ </div>
326
+ <img src="/globalassets/officials/media-library/images/doud185x200.jpg">
327
+ <div class="official-contact">
328
+ <a href="tel:562-570-6751">562-570-6751</a>
329
+ <a href="mailto:auditor@longbeach.gov">Send Email</a>
330
+ </div>
331
+ </div>
332
+ <div class="official-details" id="official-info-78" style="display: none;">
333
+ <div class="official-title">
334
+ <h3>Doug Haubert</h3>
335
+ <h4>City Prosecutor</h4>
336
+ </div>
337
+ <img src="/globalassets/officials/media-library/images/haubert185x200.jpg">
338
+ <div class="official-contact">
339
+ <a href="tel:562-570-5600">562-570-5600</a>
340
+ <a href="mailto:prosecutor@longbeach.gov">Send Email</a>
341
+ </div>
342
+ </div>
343
+ <div class="official-details" id="official-info-79" style="display: none;">
344
+ <div class="official-title">
345
+ <h3>Tom Modica</h3>
346
+ <h4>City Manager</h4>
347
+ </div>
348
+ <img src="/globalassets/officials/media-library/images/tom-modica-185x200.jpg">
349
+ <div class="official-contact">
350
+ <a href="tel:562-570-5091">562-570-5091</a>
351
+ <a href="mailto:citymanager@longbeach.gov">Send Email</a>
352
+ </div>
353
+ </div>
354
+ <div class="official-details" id="official-info-80" style="display: none;">
355
+ <div class="official-title">
356
+ <h3>Monique DeLaGarza</h3>
357
+ <h4>City Clerk</h4>
358
+ </div>
359
+ <img src="/globalassets/officials/media-library/images/delagarza185x200.jpg">
360
+ <div class="official-contact">
361
+ <a href="tel:562-570-6101">562-570-6101</a>
362
+ <a href="mailto:cityclerk@longbeach.gov">Send Email</a>
363
+ </div>
364
+ </div>
365
+ </div>
366
+ <div class="col-md-4">
367
+ <h3>City-Wide Elected Officials</h3>
368
+ <ul>
369
+ <li><a href="/attorney/" title="Dawn McIntosh" rel="76" class="official-hover">Dawn McIntosh</a><span>City Attorney</span></li>
370
+ <li><a href="http://www.cityauditorlauradoud.com/" title="Laura L. Doud" rel="77" class="official-hover">Laura L. Doud</a><span>City Auditor</span></li>
371
+ <li><a href="http://cityprosecutordoughaubert.com/" title="Doug Haubert" rel="78" class="official-hover">Doug Haubert</a><span>City Prosecutor</span></li>
372
+ </ul>
373
+ <h3>Appointed Officials</h3>
374
+ <ul>
375
+ <li><a href="/citymanager/" title="Tom Modica" rel="79" class="official-hover">Tom Modica</a><span>City Manager</span></li>
376
+ <li><a href="/cityclerk/" title="Monique DeLaGarza" rel="80" class="official-hover">Monique DeLaGarza</a><span>City Clerk</span></li>
377
+ </ul>
378
+ <ul class="no-header">
379
+
380
+ <li><a href="/mayor/administration/commissions-boards-committees/" title="Commissions and Committees">Commissions and Committees</a></li>
381
+
382
+ <li><a href="/cityclerk/meetings/" title="City Council Meetings &amp; Agendas" target="_blank">City Council Meetings &amp; Agendas</a></li>
383
+
384
+ </ul>
385
+ </div>
386
+
387
+ </div>
388
+
389
+ </div>
390
+ </div>
391
+ <li class="top-nav-mega fw">
392
+ <a href="/services/" title="Services">Services</a>
393
+ </li>
394
+ <div class="top-nav-mega-full-width">
395
+ <div class="row-fluid">
396
+ <div>
397
+
398
+
399
+ <div class="col-md-4">
400
+ <a href="/services/#onlinepayments" title="Online Payments"><h3>Online Payments</h3></a>
401
+ <ul>
402
+ <li>
403
+ <a href="/utilityservices/" title="Utility Billing">Utility Billing</a>
404
+ </li>
405
+ <li>
406
+ <a href="/parking/citations/" title="Parking Citations">Parking Citations</a>
407
+ </li>
408
+ <li>
409
+ <a href="/finance/business-info/business-licenses/business-licenses/" title="Business Licenses">Business Licenses</a>
410
+ </li>
411
+ <li>
412
+ <a href="/finance/services-and-permits/ambulance-services/" title="Ambulance Services">Ambulance Services</a>
413
+ </li>
414
+ <li>
415
+ <a href="https://customer.marinago.com/lzmqhb6d/account/login" title="Marina Payments">Marina Payments</a>
416
+ </li>
417
+ <li>
418
+ <a href="/finance/services-and-permits/alarm-permits-and-false-alarms/" title="False Alarms">False Alarms</a>
419
+ </li>
420
+ <li>
421
+ <a href="/services/#onlinepayments" title="More &#187;">More &#187;</a>
422
+ </li>
423
+ </ul>
424
+ </div>
425
+
426
+
427
+ <div class="col-md-4">
428
+ <a href="/services/#onlineservices" title="Online Services"><h3>Online Services</h3></a>
429
+ <ul>
430
+ <li>
431
+ <a href="/lbcd/enforcement/" title="Code Enforcement">Code Enforcement</a>
432
+ </li>
433
+ <li>
434
+ <a href="https://www.p3tips.com/TipForm.aspx?ID=365#googtrans(en|en)" title="Report a Crime">Report a Crime</a>
435
+ </li>
436
+ <li>
437
+ <a href="/pw/services/potholes/" title="Report a Pothole">Report a Pothole</a>
438
+ </li>
439
+ <li>
440
+ <a href="https://apm.activecommunities.com/lbparks/Home" title="Recreation Class Registration">Recreation Class Registration</a>
441
+ </li>
442
+ <li>
443
+ <a href="/lbcd/forms/" title="Planning Forms">Planning Forms</a>
444
+ </li>
445
+ <li>
446
+ <a href="/lbcd/planning/current/permit/" title="Planning Permits">Planning Permits</a>
447
+ </li>
448
+ <li>
449
+ <a href="/services/#onlineservices" title="More &#187;">More &#187;</a>
450
+ </li>
451
+ </ul>
452
+ </div>
453
+
454
+
455
+ <div class="col-md-4">
456
+ <a href="/services/#inperson" title="In-Person Services"><h3>In-Person Services</h3></a>
457
+ <ul>
458
+ <li>
459
+ <a href="/lbcd/building/permit-center/" title="Building Permits">Building Permits</a>
460
+ </li>
461
+ <li>
462
+ <a href="/health/services/directory/records/" title="Obtain a Birth Certificate">Obtain a Birth Certificate</a>
463
+ </li>
464
+ <li>
465
+ <a href="/health/services/directory/records/#death_certificate" title="Obtain a Death Certificate">Obtain a Death Certificate</a>
466
+ </li>
467
+ <li>
468
+ <a href="http://registertovote.ca.gov/" title="Voter Registration">Voter Registration</a>
469
+ </li>
470
+ <li>
471
+ <a href="/acs/programs-services/Pet-licensing/" title="Pet Licensing">Pet Licensing</a>
472
+ </li>
473
+ <li>
474
+ <a href="/finance/services-and-permits/towing-and-lien-sales/" title="Towing &amp; Lien Sales">Towing &amp; Lien Sales</a>
475
+ </li>
476
+ <li>
477
+ <a href="/services/#inperson" title="More &#187;">More &#187;</a>
478
+ </li>
479
+ </ul>
480
+ </div>
481
+
482
+ </div>
483
+ </div>
484
+ </div>
485
+ <li class="top-nav-mega fw">
486
+ <a href="/businesses/" title="Businesses">Businesses</a>
487
+ </li>
488
+ <div class="top-nav-mega-full-width">
489
+ <div class="row-fluid">
490
+ <div>
491
+
492
+
493
+ <div class="col-md-4">
494
+ <a href="/businesses/#openingbusiness" title="Opening a Business"><h3>Opening a Business</h3></a>
495
+ <ul>
496
+ <li>
497
+ <a href="/finance/business-info/business-licenses/business-licenses/" title="Business License">Business License</a>
498
+ </li>
499
+ <li>
500
+ <a href="/lbcd/building/permit-center/" title="Permit Center">Permit Center</a>
501
+ </li>
502
+ <li>
503
+ <a href="/lbcd/planning/" title="Planning">Planning</a>
504
+ </li>
505
+ <li>
506
+ <a href="/lbcd/building/" title="Building">Building</a>
507
+ </li>
508
+ <li>
509
+ <a href="/health/inspections-and-reporting/forms/environmental-health/" title="Health Forms">Health Forms</a>
510
+ </li>
511
+ <li>
512
+ <a href="/lbcd/forms/" title="Planning &amp; Building Forms">Planning &amp; Building Forms</a>
513
+ </li>
514
+ <li>
515
+ <a href="/businesses/#openingbusiness" title="More &#187;">More &#187;</a>
516
+ </li>
517
+ </ul>
518
+ </div>
519
+
520
+
521
+ <div class="col-md-4">
522
+ <a href="/businesses/#doingbusiness" title="Doing Business With The City"><h3>Doing Business With The City</h3></a>
523
+ <ul>
524
+ <li>
525
+ <a href="https://longbeachbuys.buyspeed.com/bso/" title="Register as a Vendor">Register as a Vendor</a>
526
+ </li>
527
+ <li>
528
+ <a href="/economicdevelopment/business-support/" title="Business Development">Business Development</a>
529
+ </li>
530
+ <li>
531
+ <a href="/finance/services-and-permits/fees-and-charges/" title="Fees &amp; Charges">Fees &amp; Charges</a>
532
+ </li>
533
+ <li>
534
+ <a href="/economicdevelopment/business-support/city-loan-programs/" title="Financial Assistance">Financial Assistance</a>
535
+ </li>
536
+ <li>
537
+ <a href="https://longbeachbuys.buyspeed.com/bso/" title="Bids/RFPs">Bids/RFPs</a>
538
+ </li>
539
+ <li>
540
+ <a href="/health/services/directory/tobacco-permits/" title="Tobacco Permits">Tobacco Permits</a>
541
+ </li>
542
+ <li>
543
+ <a href="/businesses/#doingbusiness" title="More &#187;">More &#187;</a>
544
+ </li>
545
+ </ul>
546
+ </div>
547
+
548
+
549
+ <div class="col-md-4">
550
+ <a href="/businesses/#resources" title="Resources"><h3>Resources</h3></a>
551
+ <ul>
552
+ <li>
553
+ <a href="http://www.pacific-gateway.org/" title="Workforce Development">Workforce Development</a>
554
+ </li>
555
+ <li>
556
+ <a href="http://www.pacific-gateway.org/business" title="Business Assistance">Business Assistance</a>
557
+ </li>
558
+ <li>
559
+ <a href="~/link/495299e6fe5e4fe78f9fb4e030244902.aspx" title="Commercial Improvement Rebate">Commercial Improvement Rebate</a>
560
+ </li>
561
+ <li>
562
+ <a href="/economicdevelopment/" title="Economic Development">Economic Development</a>
563
+ </li>
564
+ <li>
565
+ <a href="https://greenbusinessca.org/cityoflongbeach" title="Green Business">Green Business</a>
566
+ </li>
567
+ <li>
568
+ <a href="/businesses/#resources" title="More &#187;">More &#187;</a>
569
+ </li>
570
+ </ul>
571
+ </div>
572
+
573
+ </div>
574
+ </div>
575
+ </div>
576
+ <li class="top-nav-mega fw">
577
+ <a href="/residents/" title="Residents">Residents</a>
578
+ </li>
579
+ <div class="top-nav-mega-full-width">
580
+ <div class="row-fluid">
581
+ <div>
582
+
583
+
584
+ <div class="col-md-4">
585
+ <a href="/residents/#popular" title="Most Popular"><h3>Most Popular</h3></a>
586
+ <ul>
587
+ <li>
588
+ <a href="/parking/" title="Parking">Parking</a>
589
+ </li>
590
+ <li>
591
+ <a href="/disasterpreparedness/alert-long-beach/" title="Alert Long Beach">Alert Long Beach</a>
592
+ </li>
593
+ <li>
594
+ <a href="/cityclerk/meetings/" title="Calendar/Agendas &amp; Minutes">Calendar/Agendas &amp; Minutes</a>
595
+ </li>
596
+ <li>
597
+ <a href="/whodoicall/" title="Who Do I Call?">Who Do I Call?</a>
598
+ </li>
599
+ <li>
600
+ <a href="/openlb/" title="OpenLB">OpenLB</a>
601
+ </li>
602
+ <li>
603
+ <a href="/finance/services-and-permits/towing-and-lien-sales/" title="Towing &amp; Lien Sales">Towing &amp; Lien Sales</a>
604
+ </li>
605
+ <li>
606
+ <a href="/residents/#popular" title="More &#187;">More &#187;</a>
607
+ </li>
608
+ </ul>
609
+ </div>
610
+
611
+
612
+ <div class="col-md-4">
613
+ <a href="/residents/#onlineresources" title="Online Resources"><h3>Online Resources</h3></a>
614
+ <ul>
615
+ <li>
616
+ <a href="/utilityservices/" title="Utility Services">Utility Services</a>
617
+ </li>
618
+ <li>
619
+ <a href="/openlb/maplb/" title="GIS Mapping">GIS Mapping</a>
620
+ </li>
621
+ <li>
622
+ <a href="/ti/resources/go-long-beach-apps/" title="GO Long Beach Apps">GO Long Beach Apps</a>
623
+ </li>
624
+ <li>
625
+ <a href="/finance/services-and-permits/garage-sales/" title="Garage Sale Permits">Garage Sale Permits</a>
626
+ </li>
627
+ <li>
628
+ <a href="/parking/preferential-permits/" title="Preferential Parking Permits">Preferential Parking Permits</a>
629
+ </li>
630
+ <li>
631
+ <a href="/lbcd/enforcement/" title="Code Enforcement">Code Enforcement</a>
632
+ </li>
633
+ <li>
634
+ <a href="/residents/#onlineresources" title="More &#187;">More &#187;</a>
635
+ </li>
636
+ </ul>
637
+ </div>
638
+
639
+
640
+
641
+ </div>
642
+ </div>
643
+ </div>
644
+ <li class="top-nav-mega fw">
645
+ <a href="/visitors/" title="Visitors">Visitors</a>
646
+ </li>
647
+ <div class="top-nav-mega-full-width">
648
+ <div class="row-fluid">
649
+ <div>
650
+
651
+
652
+ <div class="col-md-4">
653
+ <a href="/visitors/#attractions" title="Attractions"><h3>Attractions</h3></a>
654
+ <ul>
655
+ <li>
656
+ <a href="http://www.aquariumofpacific.org/" title="Aquarium of the Pacific">Aquarium of the Pacific</a>
657
+ </li>
658
+ <li>
659
+ <a href="/park/park-and-facilities/parks-centers-pier/el-dorado-nature-center/" title="El Dorado Nature Center">El Dorado Nature Center</a>
660
+ </li>
661
+ <li>
662
+ <a href="/park/marine/marinas/rainbow-harbor-rainbow-marina/" title="Rainbow Harbor &amp; Marina">Rainbow Harbor &amp; Marina</a>
663
+ </li>
664
+ <li>
665
+ <a href="http://www.rancholosalamitos.com/" title="Rancho Los Alamitos">Rancho Los Alamitos</a>
666
+ </li>
667
+ <li>
668
+ <a href="http://www.rancholoscerritos.org/" title="Rancho Los Cerritos">Rancho Los Cerritos</a>
669
+ </li>
670
+ <li>
671
+ <a href="/visitors/#attractions" title="More &#187;">More &#187;</a>
672
+ </li>
673
+ </ul>
674
+ </div>
675
+
676
+
677
+ <div class="col-md-4">
678
+ <a href="/visitors/#associations" title="Business Associations"><h3>Business Associations</h3></a>
679
+ <ul>
680
+ <li>
681
+ <a href="http://www.belmontshore.org/" title="Belmont Shore">Belmont Shore</a>
682
+ </li>
683
+ <li>
684
+ <a href="http://4thstreetlongbeach.com/" title="4th St. (Retro Row)">4th St. (Retro Row)</a>
685
+ </li>
686
+ <li>
687
+ <a href="http://bixbyknollsinfo.com/" title="Bixby Knolls">Bixby Knolls</a>
688
+ </li>
689
+ <li>
690
+ <a href="http://www.zaferia.org/" title="East Anaheim (Zaferia)">East Anaheim (Zaferia)</a>
691
+ </li>
692
+ <li>
693
+ <a href="http://www.neighborhoodlink.com/Magnolia_Industrial_Group" title="Magnolia Industrial Group">Magnolia Industrial Group</a>
694
+ </li>
695
+ <li>
696
+ <a href="http://www.uptownvillagemarket.com/" title="Uptown">Uptown</a>
697
+ </li>
698
+ <li>
699
+ <a href="/visitors/#associations" title="More &#187;">More &#187;</a>
700
+ </li>
701
+ </ul>
702
+ </div>
703
+
704
+
705
+ <div class="col-md-4">
706
+ <a href="/visitors/#travel" title="Travel Resources"><h3>Travel Resources</h3></a>
707
+ <ul>
708
+ <li>
709
+ <a href="http://www.visitlongbeach.com/" title="Convention Visitors Bureau">Convention Visitors Bureau</a>
710
+ </li>
711
+ <li>
712
+ <a href="/openlb/maplb/" title="GIS Maps &amp; Data">GIS Maps &amp; Data</a>
713
+ </li>
714
+ <li>
715
+ <a href="/lgb/" title="Long Beach Airport (LGB)">Long Beach Airport (LGB)</a>
716
+ </li>
717
+ <li>
718
+ <a href="http://www.lbtransit.com/" title="Long Beach Transit">Long Beach Transit</a>
719
+ </li>
720
+ <li>
721
+ <a href="/parking/" title="Parking Services">Parking Services</a>
722
+ </li>
723
+ <li>
724
+ <a href="/visitors/#travel" title="More &#187;">More &#187;</a>
725
+ </li>
726
+ </ul>
727
+ </div>
728
+
729
+ </div>
730
+ </div>
731
+ </div>
732
+ <li class="top-nav-mega fw">
733
+ <a href="/departments/" title="Departments">Departments</a>
734
+ </li>
735
+ <div class="top-nav-mega-full-width">
736
+ <div class="row-fluid">
737
+ <div>
738
+
739
+ <h3>Departments</h3>
740
+
741
+ <div class="col-md-4">
742
+ <ul class="no-header">
743
+ <li>
744
+ <a href="/attorney/" title="City Attorney">City Attorney</a>
745
+ </li>
746
+ <li>
747
+ <a href="http://www.cityauditorlauradoud.com/" title="City Auditor">City Auditor</a>
748
+ </li>
749
+ <li>
750
+ <a href="/cityclerk/" title="City Clerk">City Clerk</a>
751
+ </li>
752
+ <li>
753
+ <a href="/citymanager/" title="City Manager">City Manager</a>
754
+ </li>
755
+ <li>
756
+ <a href="http://cityprosecutordoughaubert.com/" title="City Prosecutor">City Prosecutor</a>
757
+ </li>
758
+ <li>
759
+ <a href="/civilservice/" title="Civil Service">Civil Service</a>
760
+ </li>
761
+ <li>
762
+ <a href="/lbcd/" title="Community Development">Community Development</a>
763
+ </li>
764
+ <li>
765
+ <a href="/disasterpreparedness/" title="Disaster Preparedness">Disaster Preparedness</a>
766
+ </li>
767
+ </ul>
768
+ </div>
769
+
770
+
771
+ <div class="col-md-4">
772
+ <ul class="no-header">
773
+ <li>
774
+ <a href="/economicdevelopment/" title="Economic Development">Economic Development</a>
775
+ </li>
776
+ <li>
777
+ <a href="/energyresources/" title="Energy Resources">Energy Resources</a>
778
+ </li>
779
+ <li>
780
+ <a href="/finance/" title="Financial Management">Financial Management</a>
781
+ </li>
782
+ <li>
783
+ <a href="/fire/" title="Fire">Fire</a>
784
+ </li>
785
+ <li>
786
+ <a href="http://www.polb.com/" title="Harbor">Harbor</a>
787
+ </li>
788
+ <li>
789
+ <a href="/health/" title="Health &amp; Human Services">Health &amp; Human Services</a>
790
+ </li>
791
+ <li>
792
+ <a href="/hr/" title="Human Resources">Human Resources</a>
793
+ </li>
794
+ <li>
795
+ <a href="/library/" title="Library">Library</a>
796
+ </li>
797
+ </ul>
798
+ </div>
799
+
800
+
801
+ <div class="col-md-4">
802
+ <ul class="no-header">
803
+ <li>
804
+ <a href="/lgb/" title="Long Beach Airport (LGB)">Long Beach Airport (LGB)</a>
805
+ </li>
806
+ <li>
807
+ <a href="https://www.lbutilities.org/" title="Long Beach Utilities">Long Beach Utilities</a>
808
+ </li>
809
+ <li>
810
+ <a href="/officials/" title="Mayor &amp; City Council">Mayor &amp; City Council</a>
811
+ </li>
812
+ <li>
813
+ <a href="/park/" title="Parks, Recreation &amp; Marine">Parks, Recreation &amp; Marine</a>
814
+ </li>
815
+ <li>
816
+ <a href="/police/" title="Police">Police</a>
817
+ </li>
818
+ <li>
819
+ <a href="/policeoversight/" title="Police Oversight">Police Oversight</a>
820
+ </li>
821
+ <li>
822
+ <a href="/pw/" title="Public Works">Public Works</a>
823
+ </li>
824
+ <li>
825
+ <a href="/ti/" title="Technology &amp; Innovation">Technology &amp; Innovation</a>
826
+ </li>
827
+ </ul>
828
+ </div>
829
+
830
+ </div>
831
+ </div>
832
+ </div>
833
+ <li class="top-nav-mega fw">
834
+ <a href="/jobs/" title="Jobs">Jobs</a>
835
+ </li>
836
+ <div class="top-nav-mega-full-width">
837
+ <div class="row-fluid">
838
+ <div>
839
+
840
+
841
+ <div class="col-md-4">
842
+ <a href="/jobs/" title="Job Opportunities"><h3>Job Opportunities</h3></a>
843
+ <ul>
844
+ <li>
845
+ <a href="https://www.governmentjobs.com/careers/longbeach" title="Current Openings">Current Openings</a>
846
+ </li>
847
+ <li>
848
+ <a href="https://www.governmentjobs.com/careers/longbeach/promotionaljobs" title="City Employees Only">City Employees Only</a>
849
+ </li>
850
+ <li>
851
+ <a href="/jobs/internships/" title="Internships">Internships</a>
852
+ </li>
853
+ <li>
854
+ <a href="/jobs/map/management-assistant-program/" title="Management Assistant Program">Management Assistant Program</a>
855
+ </li>
856
+ <li>
857
+ <a href="/jobs/volunteer-opportunities/" title="Volunteer Opportunities">Volunteer Opportunities</a>
858
+ </li>
859
+ <li>
860
+ <a href="http://www.polb.com/jobs" title="Port of Long Beach">Port of Long Beach</a>
861
+ </li>
862
+ <li>
863
+ <a href="https://www.lbutilities.org/about-us/employment" title="Utilities Department">Utilities Department</a>
864
+ </li>
865
+ <li>
866
+ <a href="http://www.pacific-gateway.org/" title="Local Non-City Jobs">Local Non-City Jobs</a>
867
+ </li>
868
+ </ul>
869
+ </div>
870
+
871
+
872
+ <div class="col-md-4">
873
+ <a href="/jobs/" title="Information"><h3>Information</h3></a>
874
+ <ul>
875
+ <li>
876
+ <a href="/hr/city-employees/employee-benefits/" title="Employee Benefits">Employee Benefits</a>
877
+ </li>
878
+ <li>
879
+ <a href="/hr/about-us/labor-relations/" title="Labor Relations">Labor Relations</a>
880
+ </li>
881
+ <li>
882
+ <a href="/hr/jobs/descriptions-and-compensation/" title="Job Descriptions and Compensation">Job Descriptions and Compensation</a>
883
+ </li>
884
+ <li>
885
+ <a href="/civilservice/civil-service-commission/rules-and-regulations/" title="Rules &amp; Regulations">Rules &amp; Regulations</a>
886
+ </li>
887
+ <li>
888
+ <a href="/jobs/contact/" title="Contact Us">Contact Us</a>
889
+ </li>
890
+ </ul>
891
+ </div>
892
+
893
+
894
+
895
+ </div>
896
+ </div>
897
+ </div>
898
+
899
+ </ul>
900
+ </div>
901
+
902
+ </div>
903
+ </div>
904
+ </div>
905
+
906
+ <div class="interior-header">
907
+ <div class="img-title content-container">
908
+
909
+
910
+
911
+
912
+
913
+ <h2>Page Not Found</h2>
914
+ </div>
915
+ </div>
916
+ <div class="breadcrumbs-wrap">
917
+ <div class="breadcrumbs content-container">
918
+ <span>
919
+ <a target="_self" href="/" title="Home">Home</a> &raquo; Page Not Found
920
+ </span>
921
+ </div>
922
+ </div>
923
+ <div class="container-fluid content-container main-content-wrap">
924
+
925
+ <div class="row">
926
+ <div class="col-md-12 col-sm-12 main-content full-width">
927
+ <div class="col-md-12 col-sm-12">
928
+ <link href="/globalassets/pages/services.css" rel="stylesheet" type="text/css" />
929
+ <style type="text/css"><!--
930
+ .bold-header {
931
+ font-size: 22px;
932
+ font-weight: 700;
933
+ font-family: 'Raleway';
934
+ width: 100%;
935
+ text-align: center;
936
+ margin: auto;
937
+ padding-left: 0%;
938
+ padding-right: 0%;
939
+ padding-top: 3%;
940
+ }
941
+ .main-content-wrap {
942
+ padding-top: 28px;
943
+ padding-bottom: 0px;
944
+ position: relative;
945
+ background: #fff;
946
+ padding-left: 0%;
947
+ padding-right: 0%;
948
+ }
949
+ @media (max-width: 599px) {
950
+ .main-content.full-width {
951
+ padding-left: 0%;
952
+ }
953
+ .main-content {
954
+ padding-right: 0%;
955
+ }
956
+ .main-content input[type="button"], .main-content input[type="submit"], .main-content input[type="reset"] {
957
+ width: 100%;
958
+
959
+ }
960
+ --></style>
961
+ <div class="bold-header"><span style="font-size: 40px; display: block;">We're sorry.</span>The page you are trying to reach cannot be found.</div>
962
+ <div style="display: block; width: 100%; text-align: center; overflow: hidden; padding: 3%;">
963
+ <div style="overflow: hidden; display: inline-block;"><input id="ctl00_ContentPlaceHolder1_btnAgree" onclick="location.href='/pages/search.aspx/';" type="button" value="Site Search" name="ctl00$ContentPlaceHolder1$btnAgree" /><input id="ctl00_ContentPlaceHolder1_btnAgree" onclick="location.href='/';" type="button" value="Return Home" name="ctl00$ContentPlaceHolder1$btnAgree" /></div>
964
+ </div>
965
+ <div style="display: block; padding: 0% 3%; background: #eef3f6;"><img alt="" title="Online Services" src="/globalassets/services/online_services.png" />
966
+ <div class="row-label"><a name="onlineservices"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Online Services</div>
967
+ <div class="links-wrapper">
968
+ <div id="column-a">
969
+ <ul>
970
+ <li><a href="http://www.lbds.info/building/">Building Permits</a></li>
971
+ <li><a title="Code Enforcement" href="http://www.lbds.info/neighborhood_services/code_enforcement/default.asp" target="_blank">Code Enforcement</a></li>
972
+ <li><a title="Commercial Improvement Rebate" href="http://www.lbds.info/neighborhood_services/corridor_beautification/default.asp" target="_blank">Commercial Improvement Rebate</a></li>
973
+ <li><a href="http://www.lbds.info/building/development_services_center.asp">Development Permit Center</a></li>
974
+ <li><a title="Fire Recertification Forms" href="/fire/fire-prevention/hazardous-materials-recertification-forms/">Fire Recertification Forms</a></li>
975
+ <li><a title="Fire Station Locations" href="/fire/about-us/station-locations/">Fire Station Locations</a></li>
976
+ <li><a title="Garage Sales" href="/finance/services-and-permits/garage-sales/">Garage Sales</a></li>
977
+ <li><a title="GIS Maps &amp;amp; Data" href="/openlb/maplb/">GIS Maps &amp; Data</a></li>
978
+ <li><a title="GO Long Beach" href="http://www.golbcity.com/" target="_blank">Go Long Beach</a></li>
979
+ <li><a title="Go Long Beach Apps" href="/ti/resources/go-long-beach-apps/">Go Long Beach Apps</a></li>
980
+ <li><a title="Green Building" href="http://www.lbds.info/planning/advance_planning/green_building/default.asp" target="_blank">Green Building</a></li>
981
+ <li><a title="Hazardous Waste" href="/lbrecycles/hazardous-waste-101/">Hazardous Waste</a></li>
982
+ <li><a title="Health" href="/health/">Health</a></li>
983
+ </ul>
984
+ </div>
985
+ <div id="column-b">
986
+ <ul>
987
+ <li><a title="Job Seekers and Business" href="https://www.caljobs.ca.gov/vosnet/Default.aspx" target="_blank">Job Seekers and Business</a></li>
988
+ <li><a title="LinkLB" href="/linklb/">LinkLB</a></li>
989
+ <li><a title="LBTV" href="http://www.lbtv3.com" target="_blank">LBTV</a></li>
990
+ <li><a title="Long Beach Airport (LGB)" href="http://www.lgb.org/" target="_blank">Long Beach Airport (LGB)</a></li>
991
+ <li><a title="Long Beach CUPA" href="/health/inspections-and-reporting/inspections/hazardous-materials-management/">Long Beach CUPA</a></li>
992
+ <li><a title="Long Beach Drug Card" href="http://longbeachdrugcard.com/index.php" target="_blank">Long Beach Drug Card</a></li>
993
+ <li><a title="Long Beach Transit" href="http://www.lbtransit.com/" target="_blank">Long Beach Transit</a></li>
994
+ <li><a title="Natural Gas" href="/energyresources/about-us/natural-gas/">Natural Gas</a></li>
995
+ <li><a title="Neighborhood Resource Center" href="http://www.lbds.info/neighborhood_services/neighborhood_resource_center/default.asp" target="_blank">Neighborhood Resource Center</a></li>
996
+ <li><a title="Neighborhood Services" href="http://www.lbds.info/neighborhood_services/default.asp" target="_blank">Neighborhood Services</a></li>
997
+ <li><a title="Pacific Gateway" href="http://www.pacific-gateway.org/" target="_blank">Pacific Gateway</a></li>
998
+ <li><a title="Parks, Recreation &amp;amp; Marine" href="/park/">Parks, Recreation &amp; Marine</a></li>
999
+ <li><a title="Plan Check Requirements" href="http://www.lbds.info/building/engineering_n_development_services/plan_review_requirements.asp" target="_blank">Plan Check Requirements</a></li>
1000
+ </ul>
1001
+ </div>
1002
+ <div id="column-c">
1003
+ <ul>
1004
+ <li><a title="Planning Maps &amp;amp; Demographics" href="http://www.lbds.info/planning/advance_planning/maps_n_demographics.asp" target="_blank">Planning Maps &amp; Demographics</a></li>
1005
+ <li><a title="Planning Permits" href="http://www.lbds.info/planning/current_planning/planning_permit_information.asp" target="_blank">Planning Permits</a></li>
1006
+ <li><a title="Police Permits and Licensing" href="/police/how-do-i/permits-fees-and-licensing/">Police Permits and Licensing</a></li>
1007
+ <li><a title="Preferential Parking Permits" href="/parking/preferential-permits/">Preferential Parking Permits</a></li>
1008
+ <li><a title="Recreation Class Registration" href="https://apm.activecommunities.com/lbparks/Home" target="_blank">Recreation Class Registration</a></li>
1009
+ <li><a title="Recycling" href="/lbrecycles/recycling/recycling-guidelines/">Recycling</a></li>
1010
+ <li><a title="Refuse" href="/lbrecycles/refuse/curbside-collection/refuse-collection-101/">Refuse</a></li>
1011
+ <li><a title="Report a Crime" href="/police/">Report a Crime</a></li>
1012
+ <li><a title="Report a Pothole" href="/pw/services/potholes/">Report a Pothole</a></li>
1013
+ <li><a title="Resident" href="/pw/services/">Public Works Services Directory</a></li>
1014
+ <li><a title="Sewer" href="http://www.lbwater.org/sanitary-sewers" target="_blank">Sewer</a></li>
1015
+ <li><a title="Tobacco Permits" href="/health/services/directory/tobacco-permits/">Tobacco Permits</a></li>
1016
+ <li><a title="Water" href="http://www.lbwater.org/" target="_blank">Water</a></li>
1017
+ </ul>
1018
+ </div>
1019
+ </div>
1020
+ </div>
1021
+
1022
+
1023
+
1024
+ </div>
1025
+ </div>
1026
+ </div>
1027
+ </div>
1028
+
1029
+ <div id="footer" class="clearfix">
1030
+ <div class="row">
1031
+ <div class="col-md-2 col-sm-4 col-xs-12 ie-foot">
1032
+ <h3>Do.</h3>
1033
+ <ul>
1034
+ <li>
1035
+ <a href="/utilityservices/billing-and-payments/payment-options/">Pay Utility Bills</a>
1036
+ </li>
1037
+ <li>
1038
+ <a href="/services/">Get Licenses and Permits</a>
1039
+ </li>
1040
+ <li>
1041
+ <a href="/lbrecycles/">Reduce. Reuse. Recycle.</a>
1042
+ </li>
1043
+ <li>
1044
+ <a href="https://longbeach.primegov.com/public/portal?fromiframe=true">Meetings Live</a>
1045
+ </li>
1046
+ </ul>
1047
+ </div>
1048
+ <div class="col-md-2 col-sm-4 col-xs-12 ie-foot">
1049
+ <h3>Discover.</h3>
1050
+ <ul>
1051
+ <li>
1052
+ <a href="https://gis.longbeach.gov/MapIt/" target="_blank">Information Near You</a>
1053
+ </li>
1054
+ <li>
1055
+ <a href="/openlb/">OpenLB</a>
1056
+ </li>
1057
+ <li>
1058
+ <a href="/events/">City Calendar</a>
1059
+ </li>
1060
+ <li>
1061
+ <a href="/cityclerk/meetings/">Meetings &amp; Agendas</a>
1062
+ </li>
1063
+ </ul>
1064
+ </div>
1065
+ <div class="col-md-2 col-sm-4 col-xs-12 ie-foot">
1066
+ <h3>Connect.</h3>
1067
+ <ul>
1068
+ <li>
1069
+ <a href="/socialmedia/">Social Media</a>
1070
+ </li>
1071
+ <li>
1072
+ <a href="/ti/resources/go-long-beach-apps/">Mobile Apps</a>
1073
+ </li>
1074
+ <li>
1075
+ <a href="/linklb/">LinkLB</a>
1076
+ </li>
1077
+ </ul>
1078
+ </div>
1079
+ <div class="col-md-2 col-sm-4 col-xs-12 ie-foot">
1080
+ <h3>Ask.</h3>
1081
+ <ul>
1082
+ <li>
1083
+ <a href="/whodoicall/">Who Do I Call</a>
1084
+ </li>
1085
+ <li>
1086
+ <a href="/officials/">Your City Officials</a>
1087
+ </li>
1088
+ <li>
1089
+ <a href="/privacy/">Privacy Policy</a>
1090
+ </li>
1091
+ <li>
1092
+ <a href="/social-media-tc/">Social Media TC</a>
1093
+ </li>
1094
+ </ul>
1095
+ </div>
1096
+ <div class="col-md-2 col-sm-8 col-xs-12 ie-foot">
1097
+ <div class="social-icons">
1098
+ <a href="/link/93119c7cb20247389de1b2796f618c46.aspx" target="_blank">
1099
+ <img src="/globalassets/social-fb1.png" alt="Social Media" title="Social Media" />
1100
+ </a>
1101
+ <a href="/link/93119c7cb20247389de1b2796f618c46.aspx" target="_blank">
1102
+ <img src="/globalassets/social-ig.png" alt="Social Media" title="Social Media" />
1103
+ </a>
1104
+ <a href="/link/93119c7cb20247389de1b2796f618c46.aspx" target="_blank">
1105
+ <img src="/globalassets/social-twrt.png" alt="Social Media" title="Social Media" />
1106
+ </a>
1107
+ <a href="/link/93119c7cb20247389de1b2796f618c46.aspx" target="_blank">
1108
+ <img src="/globalassets/social-threads.png" alt="Social Media" title="Social Media" />
1109
+ </a>
1110
+ <a href="/link/93119c7cb20247389de1b2796f618c46.aspx" target="_blank">
1111
+ <img src="/globalassets/social-yt1.png" alt="Social Media" title="Social Media" />
1112
+ </a>
1113
+ </div>
1114
+ <a href="/">
1115
+ <img src="/globalassets/footer-logo.png" />
1116
+ </a>
1117
+ </div>
1118
+ </div>
1119
+ </div>
1120
+
1121
+ </div>
1122
+ </div>
1123
+ </div>
1124
+ </div>
1125
+ <script src="/common/js/master.js"></script>
1126
+
1127
+
1128
+
1129
+ <script type="text/javascript">
1130
+ $(document).ready(function() {
1131
+ // to initiate new dropdown menu, call both functions on the container id
1132
+ // wayoutmenu requires the #container, #button
1133
+ wayoutMenu('#top-nav', '#main-mobile-toggle');
1134
+ resizeMenu('#top-nav');
1135
+
1136
+ $('.mobile-search-toggle').click(function() {
1137
+ $('.search').toggleClass('expand');
1138
+ return false;
1139
+ });
1140
+ $("#btnSearch").click(function() {
1141
+ window.location.href = "/search/?searchtext=" + encodeURIComponent($("#txtSearch").val());
1142
+ });
1143
+ $("#txtSearch").keypress(function(e) {
1144
+ if (e.which == 13) {
1145
+ $("#btnSearch").click();
1146
+ }
1147
+ });
1148
+ });
1149
+ </script>
1150
+
1151
+ <!-- Scripts and styles used for font size feature -->
1152
+ <script src="/common/js/store.min.js"></script>
1153
+ <script src="/common/js/custom-rv-fontsize.js"></script>
1154
+ <script type="text/javascript">
1155
+ $(function () {
1156
+ $.rvFontsize({
1157
+ targetSection: 'body',
1158
+ store: true, // store.min.js required!
1159
+ variations: 7,
1160
+ controllers: {
1161
+ append: true,
1162
+ appendTo: '#text-resizer',
1163
+ showResetButton: true
1164
+ }
1165
+
1166
+ });
1167
+
1168
+ if (typeof $$epiforms !== 'undefined') {
1169
+ $$epiforms(".EPiServerForms").on("formsStepValidating", function (event) {
1170
+ if (event.isValid) return;
1171
+ var eventTarget = $(event.target);
1172
+ var errorElementName = eventTarget.find('.Form__Element__ValidationError:visible:first').attr('data-epiforms-linked-name');
1173
+ if (!errorElementName) return;
1174
+ var errorElement = eventTarget.find('[name="' + errorElementName + '"]');
1175
+ if (errorElement) errorElement.focus();
1176
+ });
1177
+ }
1178
+ });
1179
+
1180
+ </script>
1181
+
1182
+ <!--[if IE 8]>
1183
+ <link rel="stylesheet" type="text/css" href="~/common/css/ie8.css"/>
1184
+ <![endif]-->
1185
+ </div>
1186
+ <script type="text/javascript" src="https://dl.episerver.net/12.4.1/epi-util/find.js"></script>
1187
+ <script type="text/javascript">
1188
+ if(FindApi){var api = new FindApi();api.setApplicationUrl('/');api.setServiceApiBaseUrl('/find_v2/');api.processEventFromCurrentUri();api.bindWindowEvents();api.bindAClickEvent();api.sendBufferedEvents();}
1189
+ </script>
1190
+
1191
+ </body>
1192
+ </html>
tests/test_call.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pytest
2
+
3
+ from handler import EndpointHandler
4
+
5
+ @pytest.fixture
6
+ def html() -> str:
7
+ with open("data/test.html", "r") as f:
8
+ return f.read()
9
+
10
+ def test_call(html):
11
+ eh = EndpointHandler(
12
+ path="/"
13
+ )
14
+ output = eh({"inputs": html})
15
+ print(output)
types.py → types_.py RENAMED
File without changes
uv.lock CHANGED
The diff for this file is too large to render. See raw diff